From dac54a68e3a95a1078d0e920ff966c04896c945d Mon Sep 17 00:00:00 2001 From: klassents Date: Mon, 9 Sep 2024 14:33:37 +0700 Subject: [PATCH 1/2] =?UTF-8?q?=D0=B4=D0=BE=D0=B1=D0=B0=D0=B2=D0=B8=D0=BB?= =?UTF-8?q?=D0=B0=20=D1=84=D0=B0=D0=B9=D0=BB=20=D0=B8=D0=B3=D0=BD=D0=BE?= =?UTF-8?q?=D1=80=D0=B0,=20=D0=B2=D0=BA=D0=BB=D1=8E=D1=87=D0=B0=D1=8E=20?= =?UTF-8?q?=D0=BF=D1=80=D0=B8=D1=82=D1=8F=D0=B6=D0=BA=D1=83=20=D0=BA=20?= =?UTF-8?q?=D0=BF=D0=B8=D1=82=D0=B0=D0=BD=D0=B8=D1=8E=20=D0=BD=D0=B0=20rx?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitignore | 6 ++++++ src/bootloader.c | 22 +++++++++------------- 2 files changed, 15 insertions(+), 13 deletions(-) create mode 100644 .gitignore diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..8d6d49b --- /dev/null +++ b/.gitignore @@ -0,0 +1,6 @@ +.pio +.vscode/.browse.c_cpp.db* +.vscode/c_cpp_properties.json +.vscode/launch.json +.vscode/ipch +.vscode/ diff --git a/src/bootloader.c b/src/bootloader.c index ac05a7c..94c8a4e 100644 --- a/src/bootloader.c +++ b/src/bootloader.c @@ -60,7 +60,10 @@ void Bootloader_UART_Init() { PM->CLK_APB_P_SET = PM_CLOCK_APB_P_UART_0_M; // Включение тактирования UART0 - PAD_CONFIG->PORT_0_CFG |= (0b01 << (5 << 1)) | (0b01 << (6 << 1)); // Настройка выводов PORT0.5 и PORT0.6 + // Настройка выводов PORT0.5 и PORT0.6 на последовательный интерфейс + PAD_CONFIG->PORT_0_CFG |= (0b01 << (5 << 1)) | (0b01 << (6 << 1)); + // Включение притяжки к питанию на линии rx + PAD_CONFIG->PORT_0_PUPD |= (0b01 << (5 << 1)); /* * Настройки USART: @@ -89,7 +92,10 @@ void Bootloader_UART_Deinit() UART_0->FLAGS = 0xFFFFFFFF; // сброс всех флагов UART_0->TXDATA = 0x00; - PAD_CONFIG->PORT_0_CFG &= ~((0b11 << (5 << 1)) | (0b11 << (6 << 1))); // Настройка выводов PORT0.5 и PORT0.6 + // Настройка выводов PORT0.5 и PORT0.6 на порт общего назначения + PAD_CONFIG->PORT_0_CFG &= ~((0b11 << (5 << 1)) | (0b11 << (6 << 1))); + // Отключение притяжки на линии rx + PAD_CONFIG->PORT_0_PUPD &= ~(0b01 << (5 << 1)); PM->CLK_APB_P_SET &= !PM_CLOCK_APB_P_UART_0_M; // Выключение тактирования UART0 } @@ -156,17 +162,7 @@ uint8_t erase_chip(SPIFI_HandleTypeDef *spifi) /* Загрузить данные пакета в RAM */ #define SIZE_4K 4096 -void Bootloader_LoadArrayInRam(uint8_t uart_data[]) -{ - static uint32_t relative_write_address; - if ((relative_write_address % SIZE_4K) == 0) - HAL_SPIFI_W25_SectorErase4K(&spifi, relative_write_address); - - HAL_SPIFI_W25_PageProgram(&spifi, (uint32_t)hBootloader.address, hBootloader.size_package, uart_data); - hBootloader.address += hBootloader.size_package; - relative_write_address += hBootloader.size_package; -} // разметка строки в хекс-файле #define BYTE_COUNT_POS 0 // индекс счетчика байт данных @@ -217,7 +213,7 @@ void Bootloader_parseHexAndLoadInMemory(uint8_t rx_data[]) switch (rec_type) { case REC_TYPE_EXT_LIN_ADDR: - // если так получилось, что нам слали данные, буфер на 256 не заполнился, а тут прилетела команда смены адреса, то пишем сколько есть + // если так получилось, что нам слали данные, буфер на 256 не заполнился, а тут прилетела команда смены адреса, то пишем сколько есть if (page_fill_size != 0) mem_write(); // собираем адрес, с которого начинаем писать из данных команды смены адреса. нам присылают только 2 старших байта адреса -- 2.43.0 From fbe1a5a3ce6dc66ec7d5621ad1fe808f1d820930 Mon Sep 17 00:00:00 2001 From: klassents Date: Tue, 10 Sep 2024 15:31:12 +0700 Subject: [PATCH 2/2] =?UTF-8?q?=D0=B8=D0=B7=D0=BC=D0=B5=D0=BD=D0=B5=D0=BD?= =?UTF-8?q?=D0=B0=20=D0=BB=D0=BE=D0=B3=D0=B8=D0=BA=D0=B0=20=D0=BE=D0=B6?= =?UTF-8?q?=D0=B8=D0=B4=D0=B0=D0=BD=D0=B8=D1=8F=20=D0=BF=D0=BE=D1=81=D1=8B?= =?UTF-8?q?=D0=BB=D0=BE=D0=BA=20=D0=BF=D0=BE=20uart.=20=D1=82=D0=B5=D0=BF?= =?UTF-8?q?=D0=B5=D1=80=D1=8C=20=D1=80=D0=B5=D0=B0=D0=B3=D0=B8=D1=80=D1=83?= =?UTF-8?q?=D0=B5=D0=BC=20=D1=82=D0=BE=D0=BB=D1=8C=D0=BA=D0=BE=20=D0=BD?= =?UTF-8?q?=D0=B0=20=D0=B2=D0=B0=D0=BB=D0=B8=D0=B4=D0=BD=D1=8B=D0=B5=20?= =?UTF-8?q?=D0=BA=D0=BE=D0=BC=D0=B0=D0=BD=D0=B4=D1=8B,=20=D0=B0=20=D0=BF?= =?UTF-8?q?=D1=80=D0=B8=20=D0=BF=D0=BE=D0=BB=D1=83=D1=87=D0=B5=D0=BD=D0=B8?= =?UTF-8?q?=D0=B8=20=D0=BC=D1=83=D1=81=D0=BE=D1=80=D0=BD=D1=8B=D1=85=20?= =?UTF-8?q?=D0=B1=D0=B0=D0=B9=D1=82=20=D0=BD=D0=B5=20=D1=80=D0=B5=D0=B0?= =?UTF-8?q?=D0=B3=D0=B8=D1=80=D1=83=D0=B5=D0=BC=20=D0=B8=20=D0=B2=20=D0=BA?= =?UTF-8?q?=D0=BE=D0=BD=D1=86=D0=B5=20=D0=BA=D0=BE=D0=BD=D1=86=D0=BE=D0=B2?= =?UTF-8?q?=20=D0=B2=D1=8B=D1=85=D0=BE=D0=B4=D0=B8=D0=BC.=20=D0=BA=D0=BE?= =?UTF-8?q?=D0=BC=D0=B0=D0=BD=D0=B4=D0=B0=20=D0=B4=D0=BB=D1=8F=20full=20er?= =?UTF-8?q?ase=20=D1=81=D1=82=D0=B0=D0=BB=D0=B0=20=D0=B1=D0=BE=D0=BB=D0=B5?= =?UTF-8?q?=D0=B5=20=D1=81=D0=BB=D0=BE=D0=B6=D0=BD=D0=BE=D0=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/bootloader.c | 114 ++++++++++++++++++++++++----------------------- 1 file changed, 58 insertions(+), 56 deletions(-) diff --git a/src/bootloader.c b/src/bootloader.c index 94c8a4e..b6e055a 100644 --- a/src/bootloader.c +++ b/src/bootloader.c @@ -24,11 +24,12 @@ #define TIMEOUT_VALUE 1000000 /* Время ожидания загрузчика до прыжка по умолчанию в RAM 1000000 */ /* Виды команд */ +#define FULL_ERASE_CMD_LEN 4 typedef enum { PACKAGE_SIZE = 0x30, /* Команда размера пакета */ SEND_PACKAGE = 0x60, /* Команда отправить пакет */ - FULL_ERASE = 0xFE /* Команда стирания spifi */ + FULL_ERASE = 0xBADC0FEE /* Команда стирания spifi */ } BotloaderComand; typedef enum @@ -51,8 +52,11 @@ typedef struct uint8_t command; // Текущая принятая загрузчиком команда } Bootloader_attributes; -Bootloader_attributes hBootloader = {(uint8_t*) SPIFI_ADDRESS, MAX_PACKAGE_SIZE, ERROR_NONE, 0}; +Bootloader_attributes hBootloader = {(uint8_t*) SPIFI_ADDRESS, 0, ERROR_NONE, 0}; uint32_t timeout = 0; +uint32_t validCommandsTimeout = 0; + +void go_to_spifi(); /* Инициализация UART */ @@ -116,6 +120,7 @@ uint16_t Bootloader_UART_ReadByte() while ((!(UART_0->FLAGS & UART_FLAGS_RXNE_M)) && (timeout != TIMEOUT_VALUE)) { timeout++; + validCommandsTimeout++; // Увеличить таймаут валидных команд } if (timeout == TIMEOUT_VALUE) @@ -129,19 +134,17 @@ uint16_t Bootloader_UART_ReadByte() /* Обработчик ошибок */ void Bootloader_ErrorHandler() { + switch (hBootloader.error) + { + case ERROR_TIMEOUT: + if (UART_0->FLAGS & UART_FLAGS_ORE_M) + UART_0->FLAGS |= UART_FLAGS_ORE_M; - switch (hBootloader.error) - { - case ERROR_TIMEOUT: - Bootloader_UART_WriteByte(NACK); - if (UART_0->FLAGS & UART_FLAGS_ORE_M) - { - UART_0->FLAGS |= UART_FLAGS_ORE_M; - } - break; - } + go_to_spifi(); // переход в основную программу, если в течение TIMEOUT_VALUE нет принятых данных + break; + } - hBootloader.error = ERROR_NONE; + hBootloader.error = ERROR_NONE; } SPIFI_HandleTypeDef spifi = {.Instance = SPIFI_CONFIG}; @@ -163,7 +166,6 @@ uint8_t erase_chip(SPIFI_HandleTypeDef *spifi) /* Загрузить данные пакета в RAM */ #define SIZE_4K 4096 - // разметка строки в хекс-файле #define BYTE_COUNT_POS 0 // индекс счетчика байт данных #define ADDRES_POS 1 // индекс адреса @@ -171,7 +173,7 @@ uint8_t erase_chip(SPIFI_HandleTypeDef *spifi) #define RECORD_TYPE_POS 3 // индекс типа записи #define DATA_POS 4 // индекс начала данных в команде -// типы записей в хекс-фйле +// типы записей в хекс-файле #define REC_TYPE_DATA 0x00 #define REC_TYPE_EOF 0x01 #define REC_TYPE_EXT_LIN_ADDR 0x04 @@ -182,8 +184,6 @@ uint32_t rel_addr = 0; // адрес от начала области spifi, п uint8_t page_data[MAX_PACKAGE_SIZE + TAIL_SIZE] = {0}; // сюда собираем распарсенные данные из хекса uint16_t page_fill_size = 0; // счетчик, сколько заполнно в page_data. когда page_data заполнена до конца - будем записывать в spifi -void go_to_spifi(); - void mem_write() { // если адрес дошел до начала нового сектора, стираем новый сектор @@ -270,47 +270,63 @@ void Bootloader_UART_ReadPackage() } } +uint8_t eraseChipBufferIndex = 0; // Индекс для накопления команды erase chip void Bootloader_Commands() { while (1) { hBootloader.command = Bootloader_UART_ReadByte(); // Ожидание и считывание команды + + // если долго не приходили валидные команды, переход в основную программу + if (validCommandsTimeout >= TIMEOUT_VALUE) + go_to_spifi(); + if (hBootloader.error) - { Bootloader_ErrorHandler(); // Обработчик ошибок - } - else + else { switch (hBootloader.command) { case PACKAGE_SIZE: - Bootloader_UART_WriteByte(ACK); // Подтвердить команду + validCommandsTimeout = 0; // Сброс таймаута валидных команд + eraseChipBufferIndex = 0; + Bootloader_UART_WriteByte(ACK); // Подтвердить команду hBootloader.size_package = Bootloader_UART_ReadByte() + 1; // Прочитать размер пакета - Bootloader_UART_WriteByte(ACK); // Подтвердить - + Bootloader_UART_WriteByte(ACK); // Подтвердить break; case SEND_PACKAGE: - Bootloader_UART_WriteByte(ACK); // Подтвердить команду - Bootloader_UART_ReadPackage(); // Получить пакет и скопировать его в RAM - + validCommandsTimeout = 0; // Сброс таймаута валидных команд + eraseChipBufferIndex = 0; + Bootloader_UART_WriteByte(ACK); // Подтвердить команду + Bootloader_UART_ReadPackage(); // Получить пакет и скопировать его в RAM if (hBootloader.error) - { - Bootloader_ErrorHandler(); // Обработчик ошибок - } + Bootloader_ErrorHandler(); // Обработчик ошибок else - { Bootloader_UART_WriteByte(ACK); // Подтвердить считывание и копирования пакета в RAM - } - - break; - - case FULL_ERASE: - if (erase_chip(&spifi) != HAL_OK) - Bootloader_UART_WriteByte(NACK); - else - Bootloader_UART_WriteByte(ACK); break; default: + // Вычислить ожидаемый байт команды FULL_ERASE на основе текущего индекса + uint8_t expectedByte = (FULL_ERASE >> ((FULL_ERASE_CMD_LEN - eraseChipBufferIndex - 1) * 8)) & 0xFF; + // Если полученный байт совпадает с ожидаемым байтом команды FULL_ERASE + if (hBootloader.command == expectedByte) + { + // Переход к следующему байту + eraseChipBufferIndex++; + // Если команда FULL_ERASE полностью получена + if (eraseChipBufferIndex == FULL_ERASE_CMD_LEN) + { + Bootloader_UART_WriteByte(ACK); // Подтвердить получение команды + // Очистка чипа + if (erase_chip(&spifi) != HAL_OK) + Bootloader_UART_WriteByte(NACK); + else + Bootloader_UART_WriteByte(ACK); // Подтвердить успешную очистку + eraseChipBufferIndex = 0; // Сброс индекса для следующего приема + } + validCommandsTimeout = 0; // Сброс таймаута валидных команд + } + else // Если байт не совпал ни с какими валидными командами + eraseChipBufferIndex = 0; // Сброс индекса команды FULL_ERASE break; } } @@ -320,7 +336,6 @@ void Bootloader_Commands() void SystemClock_Config(); - int main() { SystemClock_Config(); @@ -352,23 +367,10 @@ int main() HAL_SPIFI_SendCommand_LL(&spifi, cmd_qpi_disable, 0, 0, 0, 0, 0, HAL_SPIFI_TIMEOUT); #endif - Bootloader_UART_Init(); // Инициализация UART. НАстройка выводов и тактирования - - timeout = 0; - while ((!(UART_0->FLAGS & UART_FLAGS_RXNE_M)) && (timeout != TIMEOUT_VALUE)) // Загрузчик ожидает команду - { - timeout++; - } + Bootloader_UART_Init(); // Инициализация UART. Настройка выводов и тактирования + + Bootloader_Commands(); // Обработка и ожидание команд - if (timeout == TIMEOUT_VALUE) - { - go_to_spifi(); - } - else - { - Bootloader_Commands(); // Обработка и ожидания команд - } - while (1) { /* code */ -- 2.43.0