Part Number: TMS320F28388D
Hello everyone,
I set up a configuration for the watchdog timer on the CM. The good thing is that the watchdog gets triggered, but the bad thing is the NMI Handler in the startup_cm.c gets called instead of my own interrupt.
I tried to do the same as in the example code of the SDK watchdog_ex1_nmi_handling.
Configuration of watchdog
void Reset::resetInit()
{
// We want a timer of 100ms
// Watchdog counter = 8bit = 256
// 10 MHz oscillator clk => ticks = 100ns
// 100ns * 256 = 25,6µs
// 100ms / 25,6µs = 3906,25 = needed clock divider
// We take the nearest divider = 4096 => 3906,25 / 4096 = 0,95367431640625
// The timeout is = 1 / 0,95367431640625 * 100 ~= 104,858 ms
// TODO: find a way to calculate this automatically and for a variable clk frequency
Interrupt_registerHandler(FAULT_NMI, &cmnmiISR);
Interrupt_enable(FAULT_NMI);
SysCtl_setWatchdogPredivider(SYSCTL_WD_PREDIV_4096);
SysCtl_setWatchdogPrescaler(SYSCTL_WD_PRESCALE_1);
SysCtl_clearAllNMIFlags();
}
__attribute__((section(".TI.ramfunc"))) __attribute__((interrupt)) void cmnmiISR(void)
{
//
// Get the WWD status and clear it
//
SysCtl_getWatchdogStatus();
SysCtl_clearWatchdogStatus();
//
// NMI was handled after the WWD expired
//
SysCtl_getNMIFlagStatus();
SysCtl_clearAllNMIFlags();
}startup_cm.c :
#include <stdint.h>
#define ISR __attribute__((section(".TI.ramfunc"))) __attribute__((interrupt))
static inline void BreakPoint()
{
__asm (" bkpt #0");
}
//
// Forward declaration of the default fault handlers.
//
void resetISR(void);
ISR static void nmiISR(void);
ISR static void faultISR(void);
ISR void Interrupt_defaultHandler(void); // Used by TI driver lib
extern void vPortSVCHandler(void);
extern void xPortPendSVHandler(void);
extern void xPortSysTickHandler(void);
//
// External declaration for the reset handler that is to be called when the
// processor is started
//
extern void _c_int00(void);
//
// Linker variable that marks the top of the stack.
//
extern unsigned long __STACK_END;
// External declarations for the interrupt handlers used by the application.
// To be added by user
//
// Interrupt vector table. In the RAM variant, the vectorTableRAM is used and
// in the Flash variant, the vectorTableFlash is used. The Flash variant can be
// be used when memory is a concern and the RAM variant can be used when
// speed is a concern.
//
#define _FLASH
#ifdef _FLASH
__attribute__((aligned(1024U)))
__attribute__((section(".vtable")))
void (* const vectorTableRAM[])(void); // This needed in driverlib to switch the vector table into RAM while adding int handler at runtime.
__attribute__((aligned(1024U)))
__attribute__((section(".vftable")))
void (* const vectorTableFlash[])(void) =
#else
__attribute__((aligned(1024U)))
__attribute__((section(".vtable")))
void (* const vectorTableRAM[])(void) =
#endif
{
(void (*)(void))((uint32_t)&__STACK_END),
/* The initial stack pointer */
resetISR, /* The reset handler */
nmiISR, /* The NMI handler */
faultISR, /* The hard fault handler */
Interrupt_defaultHandler, /* The MPU fault handler */
Interrupt_defaultHandler, /* The bus fault handler */
Interrupt_defaultHandler, /* The usage fault handler */
0, /* Reserved */
0, /* Reserved */
0, /* Reserved */
0, /* Reserved */
vPortSVCHandler, /* SVCall handler */
Interrupt_defaultHandler, /* Debug monitor handler */
0, /* Reserved */
xPortPendSVHandler, /* The PendSV handler */
xPortSysTickHandler, /* The SysTick handler */
Interrupt_defaultHandler, /* MCANSS_0 handler */
Interrupt_defaultHandler, /* MCANSS_1 handler */
Interrupt_defaultHandler, /* MCANSS_WAKE_AND_TS_PLS ISR*/
Interrupt_defaultHandler, /* MCANSS_ECC_CORR_PLS ISR */
Interrupt_defaultHandler, /* Reserved */
Interrupt_defaultHandler, /* ECAT ISR */
Interrupt_defaultHandler, /* ECAT_SYNC0 ISR */
Interrupt_defaultHandler, /* ECAT_SYNC1 ISR */
Interrupt_defaultHandler, /* ECAT_RST ISR ISR */
Interrupt_defaultHandler, /* CANA0 ISR */
Interrupt_defaultHandler, /* CANA1 ISR */
Interrupt_defaultHandler, /* CANB0 ISR */
Interrupt_defaultHandler, /* CANB1 ISR */
Interrupt_defaultHandler, /* EMAC ISR */
Interrupt_defaultHandler, /* EMAC_TX0 ISR */
Interrupt_defaultHandler, /* EMAC_TX1 ISR */
Interrupt_defaultHandler, /* EMAC_RX0 ISR */
Interrupt_defaultHandler, /* EMAC_RX1 ISR */
Interrupt_defaultHandler, /* UART0 ISR */
Interrupt_defaultHandler, /* Reserved */
Interrupt_defaultHandler, /* SSI0 ISR */
Interrupt_defaultHandler, /* Reserved */
Interrupt_defaultHandler, /* I2C0 ISR */
Interrupt_defaultHandler, /* Reserved */
Interrupt_defaultHandler, /* USB ISR */
Interrupt_defaultHandler, /* UDMA_SW ISR */
Interrupt_defaultHandler, /* UDMA_ERR ISR */
Interrupt_defaultHandler, /* Reserved */
Interrupt_defaultHandler, /* Reserved */
Interrupt_defaultHandler, /* CPU1TOCMIPC0 ISR */
Interrupt_defaultHandler, /* CPU1TOCMIPC1 ISR */
Interrupt_defaultHandler, /* CPU1TOCMIPC2 ISR */
Interrupt_defaultHandler, /* CPU1TOCMIPC3 ISR */
Interrupt_defaultHandler, /* CPU1TOCMIPC4 ISR */
Interrupt_defaultHandler, /* CPU1TOCMIPC5 ISR */
Interrupt_defaultHandler, /* CPU1TOCMIPC6 ISR */
Interrupt_defaultHandler, /* CPU1TOCMIPC7 ISR */
Interrupt_defaultHandler, /* CPU2TOCMIPC0 ISR */
Interrupt_defaultHandler, /* CPU2TOCMIPC1 ISR */
Interrupt_defaultHandler, /* CPU2TOCMIPC2 ISR */
Interrupt_defaultHandler, /* CPU2TOCMIPC3 ISR */
Interrupt_defaultHandler, /* CPU2TOCMIPC4 ISR */
Interrupt_defaultHandler, /* CPU2TOCMIPC5 ISR */
Interrupt_defaultHandler, /* CPU2TOCMIPC6 ISR */
Interrupt_defaultHandler, /* CPU2TOCMIPC7 ISR */
Interrupt_defaultHandler, /* FMC ISR */
Interrupt_defaultHandler, /* FMC_CORR_ERR ISR */
Interrupt_defaultHandler, /* AES Interrupt ISR */
Interrupt_defaultHandler, /* TIMER0 ISR */
Interrupt_defaultHandler, /* TIMER1 ISR */
Interrupt_defaultHandler, /* TIMER2 ISR */
Interrupt_defaultHandler, /* CMRAM_TESTERROR_LOG ISR */
Interrupt_defaultHandler, /* Reserved 52 */
Interrupt_defaultHandler, /* Reserved 53 */
Interrupt_defaultHandler, /* Reserved 54 */
Interrupt_defaultHandler, /* Reserved 55 */
Interrupt_defaultHandler, /* Reserved 56 */
Interrupt_defaultHandler, /* Reserved 57 */
Interrupt_defaultHandler, /* Reserved 58 */
Interrupt_defaultHandler, /* Reserved 59 */
Interrupt_defaultHandler, /* Reserved 60 */
Interrupt_defaultHandler, /* Reserved 61 */
Interrupt_defaultHandler, /* Reserved 62 */
Interrupt_defaultHandler /* Reserved 63 */
};
//
// This is the code that gets called when the processor first starts execution
// following a reset event.
// Any actions (such as making decisions based on the reset cause register,
// and resetting the bits in that register) are left solely in the hands of
// the application.
//
__attribute__((section(".resetisr")))
void resetISR(void)
{
//
// Jump to the CCS C Initialization Routine.
//
__asm(" .global _c_int00\n"
" b.w _c_int00");
}
//
// This is the code that gets called when the processor receives a NMI. This
// simply enters an infinite loop, preserving the system state for examination
// by a debugger.
//
static void nmiISR(void)
{
BreakPoint;
while( 1 )
{
}
}
//
// This is the code that gets called when the processor receives a fault
// interrupt. This simply enters an infinite loop, preserving the system state
// for examination by a debugger.
//
static void faultISR(void)
{
//
// Enter an infinite loop.
//
BreakPoint();
while( 1 )
{
}
}
//
// This is the code that gets called when the processor receives an unexpected
// interrupt. This simply enters an infinite loop, preserving the system state
// for examination by a debugger.
//
void Interrupt_defaultHandler(void)
{
//
// Enter an infinite loop.
//
BreakPoint();
while( 1 )
{
}
}
The Watchdog and the global NMI are enabled in a task. Before I service the Watchdog I placed a while loop which checks a global. After starting the program set the global to true to initiate an endless loop to trigger the watchdog. At this moment the NMI Handler nmiISR gets called. What can I do that my interrupt cmnmiISR gets called instead