2026-05-29 4:39 AM
Hello everyone,
I am developing a custom UART bootloader and I am facing a systematic NACK (0x1F) response from the MCU on my first incoming commands, even though the physical connection is active.
1. Part Number:STM32L475VGT6 (B-L475E-IOT01A Discovery board)
2. [Environment]
- Toolchain: STM32CubeIDE v1.18
- Host Side: Python 3.10 script using 'pyserial' and 'struct'
3. [Details & Symptoms]
The host script communicates over USART1 (115200 baud, 8N1).
- When the Python script sends the 'Get Version' command, the ST-LINK communication LED turns yellow(sometimes but the most of times the colour is red)
- However, the STM32 firmware consistently hits the default case or sub-function validation and returns a NACK (0x1F).
4. [Frame Protocol & Implementation]
My protocol uses a 2-step UART reception to handle variable sizes:
Step 1: Read 1 byte for length.
Step 2: Read [length] bytes for Command ID + Payload.
Here is the exact dispatcher implementation running outside the main function:
void bootloader_uart_read_data(void)
{
uint8_t rcv_len = 0;
while (1)
{
memset(bl_rx_buffer, 0, 200);
HAL_UART_Receive(&huart1, bl_rx_buffer, 1, HAL_MAX_DELAY);
rcv_len = bl_rx_buffer[0];
HAL_UART_Receive(&huart1, &bl_rx_buffer[1], rcv_len, HAL_MAX_DELAY);
switch(bl_rx_buffer[1])
{
case 0x01: // bl_get_ver
bootloader_handle_getver_cmd(bl_rx_buffer);
break;
case 0x03: // bl_flashpage_erase
bootloader_handle_flash_erase_cmd(bl_rx_buffer);
break;
default:
uint8_t nack = 0x1F;
HAL_UART_Transmit(&huart1, &nack, 1, 100);
break;
}
}
}
5. [Sanity Checks Performed]
- Clock configuration (SystemClock_Config) is called properly at startup.
- USART1 is bound to PB6 (TX) and PB7 (RX) which matches the Virtual COM Port routing of the board.
- The Python host code does NOT include the checksum for Get Version (0x01) and Erase (0x03), it sends exact packet length. Checksum is reserved for the Write command.
- The C code loop for the checksum starts at index i = 1 (ignoring length).
Could this be related to an index shifting issue during the 2-step HAL_UART_Receive, or an issue with the internal USART clock timing preventing correct byte alignment?
Any insights or recommendations on how to debug this framing issue would be highly appreciated.
Thank you!