cancel
Showing results for 
Search instead for 
Did you mean: 

STM32L031, cannot connect to ROM bootloader

anotherandrew
Senior

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)

9 REPLIES 9
Javier1
Principal

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

we dont need to firmware by ourselves, lets talk

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;
}

we dont need to firmware by ourselves, lets talk

My enter bootloader function is just a NVIC_SystemReset()

we dont need to firmware by ourselves, lets talk
TDK
Guru

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?

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

I appreciate your taking so much time to write such a thorough response, but unfortunately the STM32L031 does not have a remappable vector table. It looks like your deinitEverything() function does the hard way what setting a flag in RAM, NVIC_SystemReset()ing, and then checking for that flag and then setting MSP to the value in 0x1ff00000 and jumping to the value in 0x1ff00004 would do. Am I missing something?

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.

I just laid out what i did hoping something clicks for you.

You said you tried the builtin stm32 uart bootloaders and also dont work?

we dont need to firmware by ourselves, lets talk

Yes - all my work here is trying to get the built-in ROM bootloader to work over PA9/10 on STM32L031. Even with BOOT0=1, PA2/3 and PA9/10 pulled up to 3.3V with 10k resistors, and PA5 (SCK) pulled down with 10k as per 2606, I can't get it to respond to a 96008E1 0x7f character. Also tried 57600 and 115200 baud.

TDK
Guru

> 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.

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