SAMD20 interrupt vector table is correct but dummy_handler gets called

Go To Last Post
6 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hi,

 

In my SAMD20 app that is launched from a bootloader my interrupt vector table is correctly setup at 0x1000 (the start address of the app). I have verified this by printing the address of the functions in the app and comparing it with the .bin file. Inspite of this, when an interrupt occurs the Dummy_Handler() gets called. My SCB->VTOR is correctly set to the start of the app, 0x1000.

 

I'm obviously doing something wrong because there seems to be an alignment issue somewhere but I just don't see it. Can someone provide some guidance on how to debug this issue?

 

This is a hexdump of the interrupt vector table in my bin file. The 11dd 0000 is the address of the Dummy_Handler routine.

3a70 2000 stack
1119 0000 reset handler
11dd 0000 nmi handler
11dd 0000 hard fault
0000 0000 
0000 0000 
0000 0000 
0000 0000
0000 0000 
0000 0000 
0000 0000 
11dd 0000 svc handler
0000 0000 
0000 0000 
11dd 0000 pendSV handler
11dd 0000 systick
11dd 0000 pm handler
11dd 0000 sysctrl
11dd 0000 wdt
2e35 0000 rtc
11dd 0000 eic
2d89 0000 nvmctrl
11dd 0000 evsys
11dd 0000 sercom0
30a1 0000 sercom1
11dd 0000 sercom2
11dd 0000 sercom3
31c1 0000 sercom4
11dd 0000 sercom5
11dd 0000 TC0
11dd 0000 TC1
11dd 0000 TC2
11dd 0000 TC3
11dd 0000 TC4
11dd 0000 TC5
0000 0000 TC6
0000 0000 TC7
11dd 0000 ADC
11dd 0000 AC
11dd 0000 DAC
11dd 0000 PTC

thanks for your help

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Take a look at the register NVIC->NVICISPR to see which peripheral caused the interrupt, you can see the bit number for each peripheral in the datasheet, in the chapter about the processor architecture. Check if the interrupt handler is implemented in your code (I got this error in my code on a SAMD21 and searched for hours) If it's not implemented, then it jumps into Dummy_Handler()

Jerry

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Replace the hard fault handler routing to the dummy handler with a dedicated handler instead, with a forever loop inside.  Hard faults can be common especially when first bringing a board up.  Then set a break point in the handler, or better yet ASSERT(0);.  Once you get stuck in any handler, even the dummy handler, check the call stack inside the debugger.  It will often give you clues to where the code was at the time of the fault.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Thank you Scott and Jerry for your help.

 

Hardfault_handler is indeed getting called. I was unable to attach AS 7 to my running app after it was started by bootloader. But by using prints I arrived at the following:

 

this function gets called:

usart_async_register_callback(&USART_1, USART_ASYNC_RXC_CB, rx_cb_icpup_uart);

 

and eventually, this gets called, which causes the hardfault

((Sercom *)hw)->USART.INTENSET.reg = SERCOM_USART_INTENSET_RXC; 

 

Before the call, the value of ((Sercom *)hw)->USART.INTENSET.reg is 0x04.  SERCOM_USART_INTENSET_RXC resolves to 4. So I don't understand why writing 4 to a reg that already contains 4 is causing a hard fault.

 

My bootloader uses USART1 for FW upgrade. And main app hardfaults when setting up USART1, so there must be something in common here.

 

thanks for your help

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

What does hw point to? If the pointer is invalid, this will cause a hard fault.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

yeah, you are right. hw is 0 hence the hard fault. It turns out that USART1 init is failing, hence it is not setting hw. Since bootloader and main app are using USART1 I probably need to reset USART1 before launching main app.

 

thanks for your help