Sure, this is the gist:
#define LP_LED_TIMER_CHANNEL (1U)
// Enable timer
LPIT_DRV_StartTimerChannels(INST_LPIT1, (1 << LP_LED_TIMER_CHANNEL));
// Some other ops
// Disable timer
LPIT_DRV_StopTimerChannels(INST_LPIT1, (1 << LP_LED_TIMER_CHANNEL));
LPIT_DRV_ClearInterruptFlagTimerChannels(INST_LPIT1, (1 << LP_LED_TIMER_CHANNEL));
// Re-enable timer
LPIT_DRV_StartTimerChannels(INST_LPIT1, (1 << LP_LED_TIMER_CHANNEL));
The issue is that when I re-enable timer, it invokes ISR a few times before slowing down (instead of 100 ms, it invokes it once every 4-6 seconds). It does that a few times (between 0 to 20) before eventually hard faulting. I have root caused the instruction to be
static inline void LPIT_ClearInterruptFlagTimerChannels(LPIT_Type * const base, uint32_t mask)
{
/* Write 1 to clear the interrupt flag. */
base->MSR = mask; // Accessing base->MSR is invalid for some reason and returns a precise bus error at 0x4003_700C
...
}
How can I debug this further? Thanks.
Config and ISR follows:
The LPIT_DRV functions are from S32_SDK_RTM_3.0.1/platform/drivers/src/lpit/lpit_driver.c.
I do a Preinit of the timer and channel (I do not use channel 0, only channel 1 for my purpose of toggling LED) in the main RTOS task:
void LP_LED_TIMER_Preinit(void) {
lpit1_ChnConfig1.period = 100000U;
lpit1_ChnConfig1.periodUnits = LPIT_PERIOD_UNITS_MICROSECONDS;
lpit1_ChnConfig1.enableReloadOnTrigger = true;
lpit1_ChnConfig1.enableStopOnInterrupt = false;
lpit1_ChnConfig1.timerMode = LPIT_PERIODIC_COUNTER;
LPIT_DRV_Init(INST_LPIT1, &lpit1_InitConfig);
/* Initialize LPIT channel 1 */
(void)LPIT_DRV_InitChannel(INST_LPIT1, LP_LED_TIMER_CHANNEL, &lpit1_ChnConfig1);
/* Install LPIT_ISR as LPIT interrupt handler */
INT_SYS_InstallHandler(LPIT0_Ch1_IRQn, &sLPITIsr_1, (isr_t *)0);
INT_SYS_SetPriority(LPIT0_Ch1_IRQn, 1);
}
I used DS to generate timer configuration as follows:
#include "lpit1.h"
/*! Global configuration of lpit1 */
const lpit_user_config_t lpit1_InitConfig =
{
.enableRunInDebug = true, /*!< true: LPIT run in debug mode; false: LPIT stop in debug mode */
.enableRunInDoze = true /*!< true: LPIT run in doze mode; false: LPIT stop in doze mode */
};
/*! User channel configuration 1 */
lpit_user_channel_config_t lpit1_ChnConfig1 =
{
.timerMode = LPIT_PERIODIC_COUNTER,
.periodUnits = LPIT_PERIOD_UNITS_MICROSECONDS,
.period = 100000U,
.triggerSource = LPIT_TRIGGER_SOURCE_EXTERNAL,
.triggerSelect = 0U,
.enableReloadOnTrigger = true,
.enableStopOnInterrupt = false,
.enableStartOnTrigger = false,
.chainChannel = false,
.isInterruptEnabled = true
};
My ISR looks like:
void sLPITIsr_1(void) {
LP_LED_TIMER_ClearInterruptFlag();
// Toggle LED
DRV_IO_WriteOutput(g_pBlinkLedPin, !g_blinkLedIsOn);
g_blinkLedIsOn = !g_blinkLedIsOn;
}