STM32L031, cannot connect to ROM bootloader
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 correctI 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)
