Skip to main content
Explorer
June 7, 2021
Question

STM32L031, cannot connect to ROM bootloader

  • June 7, 2021
  • 3 replies
  • 2060 views

I'm trying to invoke the ROM bootloader from my application (for firmware upgrade over USART2). I understand that only Category 1 devices (STM32L011) can use the FLASH_OPTR bits to do this, so I'm trying to load SP from 0x1ff00000 and jump to the value stored at 0x1ff00004.

I know that the STM32 needs to be configured as it would from power-on reset so I'm using NVIC_SystemReset() and catching my "jump to bootloader" condition in my startup.S code (before main()), where RCC is not configured, HAL not started, etc.

I can see that I'm executing code in the system memory address range, but if I look at USART2's configuration (USART2_CR1 at 0x40004400), it is all-zeroes. In fact, almost all of the USART2 registers are zeroed. UART2 is clearly not configured.

If I pull BOOT0 high and use the physical reset pin, I get the same behaviour, so I'm pretty sure it's not my code.

How can I properly invoke the ROM bootloader from software on the STM32L031 part?

Edit: performing some additional testing with BOOT=1, which should "just work":

  • PA2/3 (alternative USART2 TXD/RXD) is connected to a mosfet gate and analog input steady at 2.5V (even at power-on), respectively)
  • PA9 is connected to the RS422 transceiver TXD input, measured at 3.3V
  • PA10 is connected to the RS422 transceiver RXD input, measured at 3.3V
  • SPI MOSI (PA7) is reading 0, connected to my SPI slave
  • SPI SCK (PA5) is reading 0, connected to my SPI slave
  • SPI CS# (PA4) is reading 0, connected to my SPI slave
  • memory location 0x1ff00ffe (bootloader ID) reads 0xc0, which is correct for this part

From what I can gather, this should not cause the ROM bootloader to become confused, but I cannot get it to respond even with the BOOT0 pin tied to 3.3v and the main Flash erased.

With a scope hooked up to PA10 (USART2 RXD), and using STM32CubeProgrammer at 57600,E81, I can see the following waveform:

  • 17.36us low (start bit)
  • 121us high, followed by 17.36us low (8 data bits, LSB first, so 0x7f)
  • the line remains high until the next transmission (high for parity, high for stop)

If I tell STM32CubeProgrammer to use Odd parity instead of Even, the waveform has two low bit times at the end, for the MSB and odd parity, so it seems to be correct. I'm testing with two different-mfg FT232RL based USB-RS422 dongles.

edit #2: verifying that BOOT0 pin is at 3.3v, I do not appear to be in the correct mode:

  • reading SYSCFG_CFGR1 (0x40010000) returns 0x00000000, which is not correct
  • I am using Rev X silicon (0x40015800 returns 0x20186425 which is Rev X Category 2)

The errata says that the SYSCFG_CFGR1 returning the wrong boot mode was fixed in this revision. Stranger and stranger...

(I did not have SYSCFG enabled in RCC, it correctly shows 0x0101 when BOOT0=1)

    This topic has been closed for replies.

    3 replies

    Graduate II
    June 7, 2021

    I dont know if this is your problem but:

    In my case the bootloader is located at the beginning of my flash so is executed after reset, and after 1 second of no booting action it jumps to my programm code.

    0693W00000BaF6kQAF.png 

    Does STM32L031 familly have a dynamically allocated vector table?

    found in my file system_stm32f1xx.c :

    /* Note: Following vector table addresses must be defined in line with linker
     configuration. */
    /*!< Uncomment the following line if you need to relocate the vector table
     anywhere in Flash or Sram, else the vector table is kept at the automatic
     remap of boot address selected */
    #define USER_VECT_TAB_ADDRESS

    #define VECT_TAB_BASE_ADDRESS FLASH_BASE /*!< Vector Table base address field.
     This value must be a multiple of 0x200. */
    #define VECT_TAB_OFFSET 0x00004800 /*!< Vector Table base offset field.
     This value must be a multiple of 0x200. */
    //my program code starts at flash addr 0x80004800

    Graduate II
    June 7, 2021

    My jumptoAPP function from the bootlodaer looks like this;

    void jumpToApp(const uint32_t address) {
    	const JumpStruct *vector_p = (JumpStruct*) address;
     
    	deinitEverything();
     
    	/* let's do The Jump! */
    	/* Jump, used asm to avoid stack optimization */
    	asm("msr msp, %0; bx %1;" : : "r"(vector_p->stack_addr), "r"(vector_p->func_p));
    }
     
    void deinitEverything() {
    	//-- reset peripherals to guarantee flawless start of user application
    	//	HAL_GPIO_DeInit(LED_GPIO_Port, LED_Pin);
    	HAL_GPIO_DeInit(CAN1_TX_BOOTLOADER_GPIO_Port, CAN1_TX_BOOTLOADER_Pin);
    	HAL_GPIO_DeInit(CAN1_RX_BOOTLOADER_GPIO_Port, CAN1_RX_BOOTLOADER_Pin);
    	HAL_CAN_DeInit(_hcan);
    	HAL_RCC_DeInit();
    	HAL_DeInit();
    	SysTick->CTRL = 0;
    	SysTick->LOAD = 0;
    	SysTick->VAL = 0;
    }

    Graduate II
    June 7, 2021

    My enter bootloader function is just a NVIC_SystemReset()

    Super User
    June 7, 2021

    I wouldn't expect it to be configured until you send data on that line. Did you do so? Ignoring the CR1 register value, does it work okay?

    Explorer
    June 7, 2021

    I'm verifying that but it would be very unusual to be able to receive data on USART2 if USART2 is not configured...

    edit: checked with two different USB-UART cables (both FT232RL-based) with same results. Using STM32CubeProgrammer, 57600,8E1 I see a 17.36us start bit (low), 121us (7 bits) of high, and another 17.36us low (MSB) before going back to high again until the next transmission from the PC.

    If I read that correctly, I have start (low), 1 1 1 1 1 1 1 0 (data word, LSB first so 0x7f), then high for parity and high again for stop. If I select odd parity instead of even parity, I see a low for parity and high for stop.

    I've updated my original question to include more data about how the chip is connected, but in a nutshell:

    * PA2/3 (alternative USART2 TXD/RXD) is connected to a mosfet gate and analog input at 2.5V, respectively)

    * PA9 is connected to the RS422 transceiver TXD input, measured at 3.3V

    * PA10 is connected to the RS422 transeiver RXD input, measured at 3.3V

    * SPI MOSI (PA7) is reading 0, connected to my SPI slave

    * SPI SCK (PA5) is reading 0, connected to my SPI slave

    * SPI CS# (PA4) is reading 0, connected to my SPI slave

    From what I can gather, this should not cause the ROM bootloader to become confused, but I cannot get it to respond.

    Super User
    June 8, 2021

    > I'm verifying that but it would be very unusual to be able to receive data on USART2 if USART2 is not configured...

    The bootloader looks for activity on a number of different lines and configures them after activity is detected. In other words, those pins may be in GPIO mode prior/during the 0x7F sync byte being sent.

    Looks like you're checking the right things. Not sure what the issue is.