cancel
Showing results for 
Search instead for 
Did you mean: 

Cannot get into the factory ST bootloader from AN2606 for programming over SPI.

Hopeful Programmer
Associate II

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.

0693W000006FBY8QAO.pngI 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.

0693W000006FBZ6QAO.png0693W000006FBYrQAO.png0693W000006FBZGQA4.pngAfter 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:

0693W000006FBZVQA4.pngI 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);

               }

 }

6 REPLIES 6
TDK
Guru

If you're connected to the bootloader over USB, the SPI connection will not work. Only one interface can be active at one time.

To get in through SPI, ensure no other interfaces are active during the initialization.

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

I have only plugged in the USB cable to see if DFU mode shows. For the SPI testing I only have the pins outlined above connected.

Here is my setup.

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

0693W000006FCmaQAG.jpg

Hopeful Programmer
Associate II

Also, I am power cycling the STM32H743 between each attempt to reach the SPI bootloader.

TDK
Guru

Seems like you're trying the right things. I've used the SPI bootloader before and never ran into issues.

One thing you could check is to use a different SPI port to see if you can get it working that way.

Edit:

Also, you're not following the proper protocol. You need to read a dummy byte between sending/receiving, see AN4286. But this would not explain the problem.

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

My next step is taking every pin that is an input while in the bootloader mode and using a pullup or pulldown resistor to fix it to verify no noise is tickling a pin to cause it to go into the wrong mode.

I am skeptical that this will fix anything as the USB DFU mode is the last thing to get checked as per Figure 56 in AN2606 Rev 46.

0693W000006FCwLQAW.png

Hopeful Programmer
Associate II

Disabling the STLink V3 on the Nucleo doesn't help.

Powering the board using 3.3V from a PSU with the onboard STLink jumpered to reset doesn't work.

SP1 using PA4, PA5, PA6 and PA7 just returns 0x00 instead of 0xAA.

Using a different board for the above items is the same.

The only things I have yet to try is testing SPI2 and SPI3 as outlined in Table 95 of AN2606 as well as connecting pulldown resistors to every unused input pin outlined in the same table.