|
|
@@ -86,81 +86,102 @@ int __io_putchar(int ch)
|
|
|
return(ch);
|
|
|
}
|
|
|
|
|
|
+#define UART_CHUNK_SIZE 256
|
|
|
+#define FILE_SIZE_BYTES 2
|
|
|
|
|
|
-#define RX_DATA_SIZE 4096
|
|
|
-#define RC_DATA_SIZE 256
|
|
|
+extern UART_HandleTypeDef huart2;
|
|
|
+extern SPI_HandleTypeDef hspi2;
|
|
|
|
|
|
-typedef struct Packet {
|
|
|
- uint8_t header[2];
|
|
|
- uint8_t data[RC_DATA_SIZE];
|
|
|
-} Packet;
|
|
|
+static uint8_t rx_size_buf[FILE_SIZE_BYTES];
|
|
|
+static uint8_t rx_data[UART_CHUNK_SIZE];
|
|
|
|
|
|
-#define CHUNK_SIZE 256
|
|
|
+static uint16_t total_size = 0;
|
|
|
+static uint16_t received = 0;
|
|
|
+static uint16_t current_page = 0;
|
|
|
|
|
|
-typedef enum {
|
|
|
- STATE_WAITING = 0,
|
|
|
- STATE_DOWNLOADING
|
|
|
-} State;
|
|
|
+void uart_receive_file(void);
|
|
|
+void print_hex_dump(uint8_t *data, uint32_t length, uint32_t offset);
|
|
|
|
|
|
-static State state = STATE_WAITING;
|
|
|
+void print_hex_dump(uint8_t *data, uint32_t length, uint32_t offset) {
|
|
|
+ const uint32_t bytes_per_line = 16;
|
|
|
|
|
|
-static uint32_t expected_file_size = 0;
|
|
|
-static uint32_t received_size = 0;
|
|
|
+ for (uint32_t i = 0; i < length; i += bytes_per_line) {
|
|
|
+ // Печатаем адрес
|
|
|
+ printf("%08lX: ", offset + i);
|
|
|
|
|
|
-static uint8_t rx_size_buf[2]; // буфер для длины
|
|
|
-static uint8_t rx_file_buf[256]; // буфер для данных
|
|
|
+ // Печатаем hex байты
|
|
|
+ for (uint32_t j = 0; j < bytes_per_line; j++) {
|
|
|
+ if (i + j < length) {
|
|
|
+ printf("%02X ", data[i + j]);
|
|
|
+ } else {
|
|
|
+ printf(" "); // Пробелы для выравнивания
|
|
|
+ }
|
|
|
|
|
|
-void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
|
|
|
-{
|
|
|
- if (huart->Instance != USART2) return;
|
|
|
+ // Разделитель посередине
|
|
|
+ if (j == 7) {
|
|
|
+ printf(" ");
|
|
|
+ }
|
|
|
+ }
|
|
|
|
|
|
- switch (state)
|
|
|
- {
|
|
|
- case STATE_WAITING: {
|
|
|
- expected_file_size = (uint16_t)rx_size_buf[0]
|
|
|
- | ((uint16_t)rx_size_buf[1] << 8);
|
|
|
+ printf("\r\n");
|
|
|
+ }
|
|
|
+}
|
|
|
|
|
|
- printf("File size: %u bytes\n", expected_file_size);
|
|
|
+void uart_receive_file(void)
|
|
|
+{
|
|
|
+ // 1️⃣ Сначала получаем длину файла (2 байта)
|
|
|
+ HAL_UART_Receive(&huart2, rx_size_buf, FILE_SIZE_BYTES, HAL_MAX_DELAY);
|
|
|
+ total_size = (rx_size_buf[1] << 8) | rx_size_buf[0];
|
|
|
|
|
|
- received_size = 0;
|
|
|
- state = STATE_DOWNLOADING;
|
|
|
+ printf("File size: %u bytes\n", total_size);
|
|
|
|
|
|
- // вычисляем первый блок
|
|
|
- uint16_t chunk = (expected_file_size - received_size > CHUNK_SIZE)
|
|
|
- ? CHUNK_SIZE
|
|
|
- : (expected_file_size - received_size);
|
|
|
+ // 2️⃣ Принимаем и сразу записываем на флеш
|
|
|
+ received = 0;
|
|
|
+ current_page = 0;
|
|
|
|
|
|
- HAL_UART_Receive_DMA(&huart2, rx_file_buf, chunk);
|
|
|
- break;
|
|
|
+ while (received < total_size)
|
|
|
+ {
|
|
|
+ uint16_t remaining = total_size - received;
|
|
|
+ uint16_t chunk = (remaining >= UART_CHUNK_SIZE) ? UART_CHUNK_SIZE : remaining;
|
|
|
+ printf("Page (%u bytes)\n", chunk);
|
|
|
+
|
|
|
+ // Получаем кусок файла
|
|
|
+ if (HAL_UART_Receive(&huart2, rx_data, chunk, HAL_MAX_DELAY) == HAL_OK)
|
|
|
+ {
|
|
|
+ // Если меньше 256 байт, добиваем нулями
|
|
|
+ if (chunk < UART_CHUNK_SIZE)
|
|
|
+ memset(rx_data + chunk, 0xFF, UART_CHUNK_SIZE - chunk);
|
|
|
+
|
|
|
+ // Пишем на флеш в текущую страницу
|
|
|
+ at45db_write_page(current_page, rx_data);
|
|
|
+ printf("Page %u written (%u bytes)\n", current_page, chunk);
|
|
|
+
|
|
|
+ received += chunk;
|
|
|
+ current_page++;
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ printf("UART receive error\n");
|
|
|
+ break;
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
- case STATE_DOWNLOADING: {
|
|
|
- received_size += huart->RxXferSize;
|
|
|
-
|
|
|
- printf("Received: %u / %u\n", received_size, expected_file_size);
|
|
|
+ printf("✅ File received and written to flash!\n");
|
|
|
|
|
|
- if (received_size >= expected_file_size) {
|
|
|
- state = STATE_WAITING;
|
|
|
- expected_file_size = 0;
|
|
|
- received_size = 0;
|
|
|
- memset(rx_size_buf, 0, sizeof(rx_size_buf));
|
|
|
- memset(rx_file_buf, 0, sizeof(rx_file_buf));
|
|
|
+ uint8_t at45db_buffer[256] = {0};
|
|
|
|
|
|
- HAL_UART_Receive_DMA(&huart2, rx_size_buf, 2);
|
|
|
+ printf("Data read from flash:\r\n");
|
|
|
+ for (int page = 0; page < current_page; page++) {
|
|
|
+ at45db_wait_ready();
|
|
|
+ at45db_read(page, at45db_buffer, sizeof(at45db_buffer));
|
|
|
+ at45db_wait_ready();
|
|
|
|
|
|
- printf("Download finished!\n");
|
|
|
- } else {
|
|
|
- // вычисляем следующий блок
|
|
|
- uint16_t remaining = expected_file_size - received_size;
|
|
|
- uint16_t chunk = (remaining > CHUNK_SIZE) ? CHUNK_SIZE : remaining;
|
|
|
-
|
|
|
- HAL_UART_Receive_DMA(&huart2, rx_file_buf, chunk);
|
|
|
- }
|
|
|
- break;
|
|
|
+ printf("\r\n=== Page %d ===\r\n", page);
|
|
|
+ print_hex_dump(at45db_buffer, sizeof(at45db_buffer), page * 256);
|
|
|
}
|
|
|
- }
|
|
|
-}
|
|
|
+ printf("\r\n");
|
|
|
|
|
|
+}
|
|
|
|
|
|
/* USER CODE END 0 */
|
|
|
|
|
|
@@ -198,10 +219,8 @@ int main(void)
|
|
|
MX_TIM1_Init();
|
|
|
/* USER CODE BEGIN 2 */
|
|
|
|
|
|
- HAL_UART_Receive_DMA(&huart2, rx_size_buf, 2);
|
|
|
-
|
|
|
-// at45db_init();
|
|
|
-// uart_receive_loop();
|
|
|
+ at45db_init();
|
|
|
+ uart_receive_file();
|
|
|
|
|
|
/* USER CODE END 2 */
|
|
|
|