Why is my interrupt hard faulting?

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

Why is my interrupt hard faulting?

2,774 Views
umlengineer
Contributor I

Hi,

I have a TPM counter that is interrupting and then hard faulting.  I can see the counter increment, I can see the modulous is set correctly, I can see that the interrupt is enabled and that the overflow flag has triggered.  However the interrupt never makes it into the interrupt routine.  I also checked the NVIC ISER and ICER and I can see that bit 17 is set in both.  The interrupt per the KL17 user manual for TPM0 is IRQ17, so that seems correct. 

How can I track down where the fault it coming from?  I am using a PE Micro debugger with MCUxpresso on a MKL17Z64VDA4.

Some of my code:

#define BOARD_TPM TPM0
#define BOARD_TPM_IRQ_NUM TPM0_IRQn
#define BOARD_TPM_HANDLER TPM0_IRQHandler
//#define TPM_SOURCE_CLOCK (CLOCK_GetFreq(kCLOCK_McgIrc48MClk)/4)
#define TPM_SOURCE_CLOCK (CLOCK_GetFreq(kCLOCK_McgInternalRefClk))

void TPM0_IRQHandler(void)
{
    /* Clear interrupt flag.*/
    TPM_ClearStatusFlags(BOARD_TPM, kTPM_TimeOverflowFlag);
    tpmIsrFlag = true;
    __DSB();
    //__ISB();  //Needed?
}

void initializeTPM()
{
    tpm_config_t tpmInfo;

    //CLOCK_SetTpmClock(3U);
    TPM_GetDefaultConfig(&tpmInfo);

    //tpmInfo.prescale = TPM_PRESCALER;      /* TPM clock divide by TPM_PRESCALER */
    TPM_Init(BOARD_TPM, &tpmInfo);        /* Initialize TPM module */
    TPM_SetTimerPeriod(BOARD_TPM, USEC_TO_COUNT(1000U, TPM_SOURCE_CLOCK));    /* Set timer period. */
    TPM_EnableInterrupts(BOARD_TPM, kTPM_TimeOverflowInterruptEnable);
    //TPM_EnableInterrupts(BOARD_TPM, kTPM_Chnl0InterruptEnable);
    EnableIRQ(BOARD_TPM_IRQ_NUM);
}

Thanks!

0 Kudos
21 Replies

2,219 Views
Robin_Shen
NXP TechSupport
NXP TechSupport

#define TPM_SOURCE_CLOCK (CLOCK_GetFreq(kCLOCK_McgInternalRefClk))

Seems that you want to use MCGIRCLK clock for TPM.

Would you please configure SIM_SOPT2[TPMSRC]?

for example:

CLOCK_SetTpmClock(3U);

Best Regards,

Robin

 

-----------------------------------------------------------------------------------------------------------------------
Note: If this post answers your question, please click the Correct Answer button. Thank you!
-----------------------------------------------------------------------------------------------------------------------

0 Kudos

2,219 Views
umlengineer
Contributor I

Hi,

I am setting the clocks via the clock tool, this alters some of the boot up functions.  I am setting the TPM clock via:

BOARD_InitBootClocks(); 

which points to:   BOARD_BootClockRUN();

which calls:   CLOCK_SetTpmClock(SIM_TPM_CLK_SEL_MCGIRCLK_CLK);

which is defined as:  #define SIM_TPM_CLK_SEL_MCGIRCLK_CLK                      3U  /*!< TPM clock select: MCGIRCLK clock */

Thanks!

0 Kudos

2,219 Views
umlengineer
Contributor I

Also here is a screenshot of what I see when I pause the debug: 

Capture.PNG

Thanks!

0 Kudos

2,219 Views
mjbcswitzerland
Specialist V

Hi

Your call stack suggests that there is a hard fault taking place in your routine tpmDelay().

You need to show the code involved because it may be faulty.

Also download the uTasker project from GitHub and configure it for the KL27 (equivalent to KL17) and test its TPM references - documentation at http://www.utasker.com/docs/uTasker/uTaskerHWTimers.PDF
This allows the KLx7, the TPM and its interrupts to be tested in its simulator and the solutions copied where needed.

Regards

Mark

0 Kudos

2,219 Views
umlengineer
Contributor I

Hi,

Thanks for the reply.  I thought it was the interrupt based off of research, but are you saying that it is the delay, because that is the subroutine that shows beneath the issue?  I would like to know how to read that debug info for the future. 

As for the subroutine in question:

volatile uint8_t tpmCounter = 0U;   Declared at the top

volatile bool tpmIsrFlag = false;   Decared at the top

uint8_t tpmDelay(volatile uint8_t delayTime)
{
    tpmCounter = 0;
    TPM_StartTimer(BOARD_TPM, kTPM_SystemClock);
       while(tpmCounter <= delayTime)
    {
        if(tpmIsrFlag == true)
            tpmCounter++;
        __WFI();
    }
    TPM_StopTimer(BOARD_TPM);
    return 0;
}

Thanks for all the help!

0 Kudos

2,219 Views
Robin_Shen
NXP TechSupport
NXP TechSupport

If you can attach project, we are able to help you more easily.

0 Kudos

2,219 Views
umlengineer
Contributor I

Hi,

I am unable to post a full project to a public forum, sorry.  However I am now trying to run a GPIO interupt and having the same issue.  There is something wrong somewhere with the NVIC and pointing, but I can not track it down.  I am unsure what is going on, as I have implemented almost identical code on other Kinetis MCUs without issue.  There is something wonky here.

Thanks!

0 Kudos

2,219 Views
Robin_Shen
NXP TechSupport
NXP TechSupport

You don't need to upload the full project to here.

Would you please create simple test project that only include TPM interrupt related codes?

0 Kudos

2,219 Views
umlengineer
Contributor I

Hi,

I just learned you can run the KL27 SDK examples directly on a KL17 MCU without changing the MCU to KL17 in the setup tools, so I tried that.  Nice feature, but I did not know you could do it as in the past I have always designed around the MCU on a freedom and not a variant. 

Anyway, when I run the TPM example code I get the same behavior as my custom code.  This is leading me to believe that I have an issue maybe with NMI, watchdog or Reset_b. 

Let me know if that makes sense to you and if you have any recommendations.

Someday this will work. 

Thanks for all the help, I really appreciate it!

0 Kudos

2,219 Views
mjbcswitzerland
Specialist V

Evan

What is your Vector Table Offset Register setting?

Regards

Mark

uTasker: supporting >1'000 registered Kinetis users get products faster and cheaper to market
Request Free emergency remote desk-top consulting at http://www.utasker.com/services.html

0 Kudos

2,219 Views
umlengineer
Contributor I

Hi,

As I keep reading I keep learning new stuff, this is much more of a deep dive into ARM than I have had to do in the past, so thank you for your patience. 

When I looked at the SCB -> VTOR setting I see 0x0 and the TBLOFF  is 0x0.

I hope this is what you are looking for, but I will keep hunting and posting.

Thanks again!

0 Kudos

2,219 Views
mjbcswitzerland
Specialist V

Evan

It is best to run the code and check the VTOR value in the debugger when you set a breakpoint just before when you know that it fails.

If it pints to 0 it means that it expects the interrupt vectors at the start of Flash. If it points to an address in SRAM they should be (copied to) there.

In either case you a memory dump of the first 256 long words form this address and show them in a screen shot.
The reason for either an unitialised vector or lack of hard fault handler will be visible in the screen shot.

Regards

Mark

0 Kudos

2,219 Views
umlengineer
Contributor I

Hi,

Here is the memory dump and how I acquired it.

Thanks!

memDump.png

data2.PNG

0 Kudos

2,219 Views
mjbcswitzerland
Specialist V

Evan

If you VTOR register is set to 0 it all looks good:

pastedImage_1.png

There is a hard fault handler and also a TPM0 handler in the interrupt vectors in flash at this location.

Another possibility is that you are seeing the return from the exception in your call stack (the interrupt may have executed - did you try a break point in it?) but the saved PC (on stack) has been corrupted by the handler code and so it is jumping back to an invalid address.

Regards

Mark

P.S See Exception Return behavior in the ARM Corex M4 User's Guide, where 0xfffffff9 is the EXC_RETURN value.

0 Kudos

2,219 Views
umlengineer
Contributor I

Hi,

Thank you so much for all the help!

This has lead me to believe that I have a hardware issue, and killed in my mind the idea that there is an issue somewhere in the code. 

I have run example code from the KL27 SDK and I get the same issues as my own code.  Also I can only run my custom board when I use the debugger, when I use my recently validated DC/DC power supply to run the code without a debugger, the MCU does not seem to boot.  This has led me to looking at NMI, watchdog and Reset_b.  Somewhere I am not being kind enough to my MCU I feel. 

Thanks again for all the help. 

0 Kudos

2,219 Views
umlengineer
Contributor I

Hi,

I have been digging around looking for it.  I am unsure what you mean by setting. 

When I poke around in the code I am able to find a bunch of things that could be reference its location or its setting, I have attached a bunch of stuff in case some of it is helpful.  That said my guess is the top two in green are what you are looking for.  Its also odd that they have different values and both exist in the project. 

Thanks for the help!

Per the core_armv8mbl.h

#if defined (__VTOR_PRESENT) && (__VTOR_PRESENT == 1U)
/* SCB Vector Table Offset Register Definitions */
#define SCB_VTOR_TBLOFF_Pos                 7U                                            /*!< SCB VTOR: TBLOFF Position */
#define SCB_VTOR_TBLOFF_Msk                (0x1FFFFFFUL << SCB_VTOR_TBLOFF_Pos)           /*!< SCB VTOR: TBLOFF Mask */

Per core_cm0plus.h

#if defined (__VTOR_PRESENT) && (__VTOR_PRESENT == 1U)
/* SCB Interrupt Control State Register Definitions */
#define SCB_VTOR_TBLOFF_Pos                 8U                                            /*!< SCB VTOR: TBLOFF Position */
#define SCB_VTOR_TBLOFF_Msk                (0xFFFFFFUL << SCB_VTOR_TBLOFF_Pos)            /*!< SCB VTOR: TBLOFF Mask */
#endif

Other stuff: 

Per startup_mkl17z644.h:

NOTE:  __USE_CMSIS is set.

#if !defined (__USE_CMSIS)
// Assume that if __USE_CMSIS defined, then CMSIS SystemInit code
// will setup the VTOR register

    // Check to see if we are running the code from a non-zero
    // address (eg RAM, external flash), in which case we need
    // to modify the VTOR register to tell the CPU that the
    // vector table is located at a non-0x0 address.
    unsigned int * pSCB_VTOR = (unsigned int *) 0xE000ED08;
    if ((unsigned int *)g_pfnVectors!=(unsigned int *) 0x00000000) {
        *pSCB_VTOR = (unsigned int)g_pfnVectors;
    }
#endif // (__USE_CMSIS)

#if defined (__cplusplus)
    //
    // Call C++ library initialisation
    //
    __libc_init_array();
#endif


Per the .cproject File:

&lt;peripheralInstance derived_from="NVIC" determined="infoFile" id="NVIC" location="0xE000E100"/&gt;&#13;

Per the core_cm0plus.h file:


#if defined (__VTOR_PRESENT) && (__VTOR_PRESENT == 1U)
  __IOM uint32_t VTOR;                   /*!< Offset: 0x008 (R/W)  Vector Table Offset Register */
#else
        uint32_t RESERVED0;
#endif

0 Kudos

2,219 Views
umlengineer
Contributor I

Hi,

I can clean up my other project for release, but I am having the same issue in another project with GPIOs.  I can see that the GPIOs are triggering an interrupt and then the program is hanging because there is no handler.

I have attached that project here:  https://eink.sharefile.com/d-s89681da26d248998

Thanks!

0 Kudos

2,219 Views
Robin_Shen
NXP TechSupport
NXP TechSupport

Hi Evan,

I have checked your GPIO interrupt project, hardfault is caused by GPIO_PortClearInterruptFlags(GPIOB, 0xFFFFFFFF).
You didn't enable the Clock Gate of GPIOB and GPIOC, why you clear the ISFR of GPIOB and GPIOC in PORTB_PORTC_PORTD_PORTE_IRQHandler?
According to your project, only PTD4 and PTE23 are configured as GPIO interrupt.
GPIO_PortClearInterruptFlags(GPIOD, 1U << 4); is able to clear ISFR of PTD4.
You can test it on PTD4, it will not caused hardfault anymore.

GPIO interrupt.png

Best Regards,

Robin

 

-----------------------------------------------------------------------------------------------------------------------
Note: If this post answers your question, please click the Correct Answer button. Thank you!
-----------------------------------------------------------------------------------------------------------------------

0 Kudos

2,219 Views
umlengineer
Contributor I

Hi,

Sorry for the confusion, I was working with someone internally and they suggested I try clearing all flags to see if that was causing an issue.  Previously I was using only the commented out line:  GPIO_PortClearInterruptFlags(GPIOD, 1U << 4);

Also I was only using pin PTD4 as my interrupt.

When I run the base code as follows I do not get a hard fault, I just do not get an interrupt.  I do however see an interrupt flag in the PORTD as indicated by the attached image. 

void PORTB_PORTC_PORTD_PORTE_IRQHandler(void)
{
    //printf("In Handler\r\n");
    GPIO_PortClearInterruptFlags(GPIOD, 1U << 4);
    //GPIO_PinWrite(GPIOD, 4U, 1);    //VNegBBottomLogic
    localEraseFlag = 1;

}

int main(void) {
      /* Init board hardware. */
    BOARD_InitBootPins();
    BOARD_InitBootClocks();
    BOARD_InitBootPeripherals();

    EnableIRQ(PORTB_PORTC_PORTD_PORTE_IRQn);
    printf("Starting While\r\n");
    while(1)
    {
        //printf("Pin Value is: %d\r\n", GPIO_PinRead(GPIOD, 4));

        if(localEraseFlag == 1)
        {
            printf("Received local erase\r\n");
            localEraseFlag = 0;
        }
        //__WFI();
    }
    return 0 ;
}

I hope this is more clear.

Capture2.PNG

Capture.PNG

Thanks!

0 Kudos

2,219 Views
mjbcswitzerland
Specialist V

Hi

How have you entered your interrupt handler? Do you do it via the interrupt vectors in Flash or do you add it to interrupt vectors in RAM?
Do you have a default interrupt handler in place in case you haven't added your handler correctly?

Regards

Mark


Complete KLx7 solutions for professional needs, training and support:http://www.utasker.com/kinetis.html
Kinetis K27:
- http://www.utasker.com/kinetis/FRDM-KL27Z.html
- http://www.utasker.com/kinetis/Capuccino-KL27.html


Complete Kinetis solutions for professional needs, training and support:http://www.utasker.com/kinetis.html
uTasker: supporting >1'000 registered Kinetis users get products faster and cheaper to market

0 Kudos