cancel
Showing results for 
Search instead for 
Did you mean: 

Bootloader Commands

mohite25
Associate III

 

UART2 configUART2 config

 

.ioc config.ioc config 

mohite25_2-1741339355460.png

 

UART3 configUART3 configConnectionsConnectionsconnectionsconnections

output herculesoutput hercules

 

 

 

Project Overview:

I'm working on a communication setup between two STM32 boards: a master board (STM32F446RE) and a slave board (STM32F401RE). The goal is for the master to send the bootloader command 0x7F to the slave, and then capture the acknowledgment (ACK) sent back by the slave. This acknowledgment will be displayed on the Hercules Serial Monitor for debugging and verification.

Connections:

  • UART Connections:

    • The master's UART2_TX is connected to the slave's UART1_RX.
    • The master's UART2_RX is connected to the slave's UART1_TX.
    • A common GND connection is ensured between both boards.
  • Master Board Debugging:

    • I’m using UART3 on the master for debugging purposes. This UART is isolated from UART2, which is used exclusively for sending bootloader commands to the slave.
    • For the UART3 connection to the PC, I've connected an FTDI USB-to-Serial adapter:
      • FTDI RX to master's UART3_TX
      • FTDI TX to master's UART3_RX
      • FTDI GND to the master’s GND
  • Reset Mechanism:

    • To reset the slave before sending commands, I've connected PC9 of the master to the NRST pin of the slave board.
    • In the .ioc file, I have configured PC9 as a GPIO output to control the reset signal.

Bootloader Command:

The command I’m trying to send to the slave is 0x7F, which is typically used in bootloader communication to trigger a response from the slave. I’m expecting the slave to send an acknowledgment (ACK) back to the master once it receives this command. I have also make sure that my slave is in the bootloader mode by setting the BOOT0 pin to high as you can see in the connections snapshot.

Code Snippet (Miniature Version):

Here’s a simplified version of the code for reference:

/* Function prototype */
void Reset_Slave(void);
int __io_putchar(int ch);
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart);
/* ---------------------- */
/* Global variables */
uint8_t tx_data = 0x7f;
uint8_t rx_data;
int main() {
 /* Debug Message */
printf("\n--- Bootloader Test Started ---\n");
/* Reset the Slave Board */
Reset_Slave();
printf("enabling ACK reception...\n");
if (HAL_UART_Receive_IT(&huart2, &rx_data, 1) == HAL_OK) {
printf("UART2 Reception Started Successfully\n");
} else {
printf("UART2 Reception FAILED!\n");
}
/* Send Bootloader Sync Command */
printf("Sending Bootloader Sync: 0x7F\n");
HAL_UART_Transmit(&huart2, &tx_data, 1, HAL_MAX_DELAY);
printf("Command Sent. Waiting for ACK...\n");
}  
int __io_putchar(int ch) {
HAL_UART_Transmit(&huart3, (uint8_t *)&ch, 1, HAL_MAX_DELAY);
return ch;
}
void Reset_Slave(void) {
printf("Resetting Slave... Pulling NRST LOW\n");
HAL_GPIO_WritePin(NRST_PORT, NRST_PIN, GPIO_PIN_RESET);
HAL_Delay(100); // Hold Reset for 100ms
HAL_GPIO_WritePin(NRST_PORT, NRST_PIN, GPIO_PIN_SET);
HAL_Delay(500); // Allow Bootloader to Start
printf("Slave Reset Complete. Ready to send bootloader command.\n");
}
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart) {
if (huart->Instance == USART2) {
printf("ACK Received: 0x%02X\n", rx_data);

// Re-enable interrupt for future responses
HAL_UART_Receive_IT(&huart2, &rx_data, 1);
}
}

Issue:

Despite setting everything up correctly, I'm not receiving the acknowledgment (ACK) from the slave board after sending the bootloader command 0x7F. I’ve added debug messages in the code to track the progress and help pinpoint where the issue may lie, but the ACK still isn't showing up in the Hercules Serial Monitor.

Debugging:

The output from the serial monitor isn't showing the expected response, and I suspect the issue may be with the communication between the boards or how the slave is handling the bootloader command. Could you please help me figure out what might be going wrong?

2 REPLIES 2
Mike_ST
ST Employee

Hello,

Please check carefully this application note:

AN2606 Section 32 or 33 for the F401.

Make sure you're using PA9/PA10 on the slave.

Check section 93 for the timings / baudrate. Don't glitch the UART to avoid baurate confusion.

Edit: Fixed Section Numbers

TDK
Guru

8 bits + even parity = 9 bits (including parity) word length. You have 8 bits set.

TDK_0-1741405841595.png

 

 

Other stuff if that's not it:

Hook up PA2 to PA3 on the middle board. Do you receive a 0x7F? Now change it to send 0x79 instead, do you get a 0x79?

Put a program on the slave board that blinks an LED so you know when it's in the user program vs in the bootloader.

Logic analyzer would be helpful here.

 

You can connect to the slave board over STM32CubeProgrammer and examine the PC register to see where it's at. Should be in the bootloader somewhere (0x1FFFxxxx). Connecting will halt the cpu but it'll show where it was just before connecting.

 

If you feel a post has answered your question, please click "Accept as Solution".