Skip to main content
Associate II
July 23, 2026
Solved

STM32G4 stuck on interrupt call

  • July 23, 2026
  • 9 replies
  • 109 views

Hello everyone,

I’m currently working with an STSPIN32G4 MCU on a custom board.

Two version of this board exist: version A and version B.

When I upload the firmware to the MCU on board A everything works correctly. The exact same firmware on version B doesn’t work.

What happens:

  1. Board B is powered on and the MCU is still fabric new (no firmware uploaded)
  2. The custom fw is uploaded using the “Debug” feature of STM32CUBEIDE via JTAG
  3. The code is executed succesfully by the MCU
  4. Board B is powered off
  5. After repowering on board B the issue starts to present: the firmware gets stuck as soon as any interrupt is called

Here’s an image of where the program points at when I press stop on the debugger after an interrupt call

What has already been tried:

  1. Performing a full chip erase on the MCU and redownloading the firmware, but it still gets stuck on interrupt call
  2. Removing the interrupt that was causing the firmware to get stuck (UART1 interrupt), but it still gets stuck as soon as TIM2 interrupt gets called
  3. Removing all the interrupts and the firmware runs fine
  4. Trying programming another board B, but the same issue is present
  5. Comparing the OB of board B and board A and they are all the same. Both MCUs have boot mode set as software only, ignoring BOOT0’s pin value 

     

  6. Verifying the stability of the power supply on board B
  7. Veryfing the correct frequency of the external crystal resonator
Best answer by Favand

Thank you everybody for the help!

in the end the cause was VTOR pointing at the wrong address.

Adding this line of code

SCB->VTOR = FLASH_BASE;

as first instruction in main solved the issue

9 replies

Ozone
Principal
July 23, 2026

I think there is too little context to identify the issue immediately, but the crucial interrupt handler code is missing.

Have you checked you handled all interrupt causes, including (UART) error interrupts. TxE and RxNE are cleared with accessing TDR, but other flags (like error interrupt flags) must be reset explicitely. Otherwise the core will immediately reenter the handler.

Second, make sure no other interrupt takes precedence and causes “overflows” in the UART handler.

Your image suggests the TxE interrupt is responsible for this effect.
I hope you are aware that you need to disable the TxE interrupt when writing the last byte of a “string” to TDR.
I use to do that in the TxE section of the handler itself, directly before writing this last byte.

Associate II
July 23, 2026

It seems version A and version B is same with same hardware as well as MCU. So how does the version B come from, Any reason to use version B instead of version A? Look confused about the custom board design idea...

Andrew Neil
Super User
July 23, 2026

Two version of this board exist: version A and version B.

So what are the differences between the two versions?

Are they just different instances of the same design, or different iterations of the design?

Add instrumentation to your code to see what's happening in each case - and where they differ

 

As ​@Ozone said, more details required:

 

A complex system that works is invariably found to have evolved from a simple system that worked.A complex system designed from scratch never works and cannot be patched up to make it work.
waclawek.jan
Super User
July 23, 2026

Without trying to understand the description you’ve provided, the 0x1fffXXXX address means, that you most probably have VTOR=0 and the boot memory mapped for whatever reason (boot pin floating?) at address 0.

JW

FavandAuthor
Associate II
July 24, 2026

​@db16122  Version A and version B are two different design. The only differences are the power rail the signals connected to pin PB6, PB7 have been swapped. The component placement and traces layout changes aswell.

 

​@waclawek.jan VTOR=0, but the option byte are set so that the boot0 pin is ignored (nSWBOOT0 = 0, nBOOT0 = 0) I also tried enabling the internal pull down, but nothing changed. What’s weird is that VTOR=0 in version A aswell, but this board works fine

 

​@Ozone I created a simplified version of the program that I’m attaching here (test_easy.zip).

When adding a breakpoint at line 220 the program never reaches it. It gets stuck before calling the interrupt callback

As a reminder this isn’t linked to a specific interrupt. I tried removing the UART communication and the program gets stuck as soon as TIM2’s interrupt fires.

Ozone
Principal
July 24, 2026

> The only differences are the power rail the signals connected to pin PB6, PB7 have been swapped.

And what functionality is assigned to PB6 and PB7 ?
This might be important here.

> When adding a breakpoint at line 220 the program never reaches it. It gets stuck before calling the interrupt callback

I think you misinterpret the messages by the debugger as shown in your first post.
I very rarely worked with (directlx) GDB-based debuggers lately, but this tool comes from the Unix/Linux world.
And the term “signal handler” does not refer to interrupts in this context, but to other events like access violations or abort requests.
I think you run into a fault handler from within your UART transmit handler routine.

Andrew Neil
Super User
July 24, 2026

I think you run into a fault handler from within your UART transmit handler routine.

Good point.

 

​@db16122 for debugging Hard Faults, see this.

A complex system that works is invariably found to have evolved from a simple system that worked.A complex system designed from scratch never works and cannot be patched up to make it work.
FavandAuthorBest answer
Associate II
July 24, 2026

Thank you everybody for the help!

in the end the cause was VTOR pointing at the wrong address.

Adding this line of code

SCB->VTOR = FLASH_BASE;

as first instruction in main solved the issue

Associate II
July 27, 2026

congratulation! it seems the issue has nothing related to the version A and Version B according to your information

The PB6 and PB7 function could be possible reason anyway...