Cannot get into the factory ST bootloader from AN2606 for programming over SPI.
Hi, I am using a Nucleo-144 STM32H743ZI2 to validate some functions identified in STM’s documentation.
Unfortunately, I am unable to properly enter the ST bootloader which I would like to utilize for firmware updates over SPI or CAN when installed so end customers don’t need to disassemble our product to attach a JTAG connector.
I am using the same code from this link, https://community.st.com/s/article/STM32H7-bootloader-jump-from-application to jump to the ST bootloader.
I believe I am in the ST bootloader because if I plug a USB cord into the computer on the bottom USB (not the top ST-Link USB), DFU FS Mode shows up in the device manager. I am performing a power cycle between each iteration of testing for trying to enter the SPI Bootloader mode to prevent testing SPI sequences and accidently entering the wrong mode.
I am using a FT232H that I have tested in loopback to verify my SPI send and receive work on my computer.
SPI Settings: 19200 Baud, CPOL Low, CPHA Low, 8 bits, MSB first Ground from SPI master to CN10 pin 5 on the Nucleo.


After power cycling and waiting more than 2-3 seconds (watching for the 1 second of yellow LED flashing I have added before the jump the bootloader) I start the following SPI communication:
MOSI MISO
0x5A 0xAA
200ms Delay
0x00 0xAA
200ms Delay
0x5A 0xAA
0xAA 0xAA
0x55 0xAA
0x00 0xAA
My physical connection for the SPI is the same as Figure 4 in AN2606 Rev 46:
I am using two 22kOhm resistors in parallel measured to be 10.8kOhm for the pull down resistor on the SCK line.
I have triple checked the connections and I am even using the same color coded breadboard jumper wires to verify everything is connected as represented below.
Connected to PE11, PE12, PE13, PE14 located on CN10. CN10 pins 6, 8, 10, 26.
CS | PE11 |CN10 Pin 6 | Channel 0
SCLK | PE12 |CN10 Pin 26 | Channel 3
MISO | PE13 |CN10 Pin 10 | Channel 2
MOSI | PE14 |CN10 Pin 8 | Channel 1
GND | GND |CN10 Pin 5 | Connected to FT232H ground
My Stack size is 0x4000 and Heap is 0x2000 and I am using STMCube to generate my MCU code for uVision in Keil.
I am running my code without any debugger because if I attempt to follow with the built in STLink the MCU goes into Hard Fault when stepping though the code
void HardFault_Handler(void)
{
/* USER CODE BEGIN HardFault_IRQn 0 */
/* USER CODE END HardFault_IRQn 0 */
while (1)
{
/* USER CODE BEGIN W1_HardFault_IRQn 0 */
/* USER CODE END W1_HardFault_IRQn 0 */
}
}
/* Main.c */
/* Includes ------------------------------------------------------------------*/
#include "main.h"
#include "Bootloader.h" // this is where the JumpToSTMBootloader function lives
PCD_HandleTypeDef hpcd_USB_OTG_FS;
/* Private function prototypes -----------------------------------------------*/
void SystemClock_Config(void);
static void MX_GPIO_Init(void);
static void MX_USB_OTG_FS_PCD_Init(void);
int main(void)
{
/* Reset of all peripherals, Initializes the Flash interface and the Systick. */
HAL_Init();
/* Configure the system clock */
SystemClock_Config();
/* Initialize all configured peripherals */
MX_GPIO_Init();
// MX_USB_OTG_FS_PCD_Init(); // not initializing the USB since I don't need it. I was originally using STM cube to start in the stock Nucleo state.
int i = 0;
while (1)
{
HAL_Delay(100);
HAL_GPIO_TogglePin(LD2_GPIO_Port, LD2_Pin);
i++;
if (i==10) {
JumpToSTMBootloader();
}
}
}
/* JumpToSTMBootloader in Bootloader.c */
void JumpToSTMBootloader(void)
{
uint32_t i=0;
void (*SysMemBootJump)(void);
/* Set the address of the entry point to bootloader */
volatile uint32_t BootAddr = 0x1FF09800;
/* Disable all interrupts */
__disable_irq();
/* Disable Systick timer */
SysTick->CTRL = 0;
/* Set the clock to the default state */
HAL_RCC_DeInit();
/* Clear Interrupt Enable Register & Interrupt Pending Register */
for (i=0;i<5;i++)
{
NVIC->ICER[i]=0xFFFFFFFF;
NVIC->ICPR[i]=0xFFFFFFFF;
}
/* Re-enable all interrupts */
__enable_irq();
/* Set up the jump to booloader address + 4 */
SysMemBootJump = (void (*)(void)) (*((uint32_t *) ((BootAddr + 4))));
/* Set the main stack pointer to the bootloader stack */
__set_MSP(*(uint32_t *)BootAddr);
/* Call the function to jump to bootloader location */
SysMemBootJump();
/* Jump successful, does not perform here, users can add code here */
while (1) {
HAL_GPIO_TogglePin(LD2_GPIO_Port, LD2_Pin);
HAL_Delay(500);
}
}
