cancel
Showing results for 
Search instead for 
Did you mean: 

stm32wle5xx interrupt failure

SWagn.1
Associate II

Hello,

I am having problems with stm32wle5xx interrupt servicing. When an interrupt occurs, the M4 seems to jump to an arbitrary location and not the location in the vector table. I observe this only on the stm32wle5xx (on a RAK31772 module), and not on the stm32wl55xx (on a nucleo-wl55jc development board).

Specifically, I wrote a very simple STM32CubeIDE project which loops waiting for an EXTI15_10_IRQ interrupt when PA15 is pulled low. The loop waits 10 seconds after reset before enabling EXTI15_10_IRQ. If I do not pull PA15 low, the loop runs forever. If I pull PA15 low, before EXTI15_10_IRQ is enabled, the loop runs until the interrupt is enabled at 10 seconds, then jumps to a nonsense location. If I pull PA15 low after the interrupt is enabled, then the processor jumps immediately to the nonsense location.

I have verified that the interrupt vector table is correct (specifically, address 0x080000E4, the address of the EXTI15_10 vector) has the correct address for the handler.

Note that this behaviour occurs with ANY interrupt, not only the EXTI15_10 interrupt. I just chose this one to work on because it was very simple.

Any ideas? Remember, the exact same code (.bin file) works properly on the STM32WL55xx on the nucleo-wl55jc but fails on the STM32WLE5xx on the RAK3172.

Thank you!

1 REPLY 1
SWagn.1
Associate II

The root cause of my issue is that the RAK3172 does in fact set the BOOT0 pin HIGH, which means the device likes to boot from system ROM.

Eventually the user Flash code at 0x08000000 gets invoked from the ROM code, but since the ROM memory is mapped at 0x00000000 when BOOT0 is HIGH, any interrupt by default uses the ROM interrupt vector table and goes off into the weeds.

There are a few ways to address the issue, including setting SCB->VTOR to 0x08000000 or setting the nSWBOOT0 nonvolatile option bit to 0 and the nonvolatile nBOOT0 option bit to 1, forcing User (main) flash boot.

I chose to force the memory mapping to User(main) flash very early in boot by setting SYSCFG->MEMRMP to 0 in the startup.s code as follows:

/*
 * Set memory map to main (user) FLASH :SYSCFG->MEMRMP = 0
 * Bits 2:0 MEM_MODE[2:0]: memory mapping selection
 * These bits control the memory internal mapping at address 0x0000 0000. These bits are
 * used to select the physical remap by software and so, bypass the BOOT mode setting. 
 * After reset, these bits take the value selected by BOOT0 (pin or option bit depending on 
 * nSWBOOT0 option bit) and BOOT1 option bit. 
 *     000: Main Flash memory mapped at CPU 0x00000000 
 *     001: System Flash memory mapped at CPU 0x00000000 
 *     010: Reserved 
 *     011: SRAM1 mapped at CPU 0x00000000 
 *     100: Reserved
 *     101: Reserved
 *     110: Reserved
 *     111: Reserved
 */
  ldr     r3, =0x40010000   /* SYSCFG MEMRMP (Memory Remap) register address */
  movs    r2, #0            /* Main Flash memory mapped at CPU 0x00000000 */
  str     r2, [r3, #0]      /* Write MEMRMP register */
  dsb            /* Data Synchronization Barrier - force memory sync */