2025-03-07 1:37 AM - last edited on 2025-03-07 2:58 AM by mƎALLEm
UART2 config
.ioc config
UART3 config
Connections
connections
output hercules
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.
UART Connections:
Master Board Debugging:
Reset Mechanism:
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.
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);
}
}
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.
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?
2025-03-07 2:53 AM - edited 2025-03-07 4:55 AM
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
2025-03-07 7:51 PM
8 bits + even parity = 9 bits (including parity) word length. You have 8 bits set.
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.