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!
#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!
-----------------------------------------------------------------------------------------------------------------------
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!
Also here is a screenshot of what I see when I pause the debug:
Thanks!
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
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!
If you can attach project, we are able to help you more easily.
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!
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?
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!
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
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!
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
Hi,
Here is the memory dump and how I acquired it.
Thanks!
Evan
If you VTOR register is set to 0 it all looks good:
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.
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.
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:
<peripheralInstance derived_from="NVIC" determined="infoFile" id="NVIC" location="0xE000E100"/>
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
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!
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.
Best Regards,
Robin
-----------------------------------------------------------------------------------------------------------------------
Note: If this post answers your question, please click the Correct Answer button. Thank you!
-----------------------------------------------------------------------------------------------------------------------
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.
Thanks!
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