Hello everyone,
I am currently working on a timer library(timer.h, timer.c) for the MK60D10 microcontroller, using its Periodic Interrupt Timer (PIT). My goal is to implement a scheduler-like functionality using a single channel of the PIT, but I'm facing some challenges, particularly with the PIT0_IRQHandler not being triggered as expected.
For example, I'd like to turn toggle the led every 5 seconds.
Here's a brief overview of what I've done:
I have confirmed that simple PIT interrupt is working properly in main.c.
However, the PIT0_IRQHandler does not seem to be called at all. I've checked and double-checked the NVIC settings and ensured that the PIT is properly configured and enabled.
I would appreciate it if you could let me know what I might have missed.
Below is a snippet of my initialization code and the ISR setup:
// Timer.c
#include "timer.h"
// Timer for multiple task
static Timer timers[MAX_TIMERS];
/* PERIODIC TIMER HANDLER */
void PIT0_IRQHandler(void) {
PRINTF("Periodic timer Interrupt");
for (uint8_t i = 0; i < MAX_TIMERS; i++) {
if (timers[i].active && (timers[i].ticks > 0U)) {
timers[i].ticks--;
if (timers[i].ticks == 0U) {
if (timers[i].callback != NULL) {
timers[i].callback();
}
timers[i].ticks = timers[i].period; /* 리셋 */
}
}
}
PIT_ClearStatusFlags(PIT, kPIT_Chnl_0, kPIT_TimerFlag);
}
void Timers_Init(void) {
PRINTF("Init PIT\r\n");
/* Get PIT Default Config and Initialize PIT */
pit_config_t pitCfg ={0};
PIT_GetDefaultConfig(&pitCfg);
PIT_Init(PIT, &pitCfg);
PIT_SetTimerPeriod(PIT, kPIT_Chnl_0, GET_MSEC_COUNT(1000));
PRINTF("%d\r\n",GET_MSEC_COUNT(1000));
PIT_EnableInterrupts(PIT, kPIT_Chnl_0, kPIT_TimerInterruptEnable);
NVIC_EnableIRQ(PIT0_IRQn);
for ( uint8_t i = 0; i < MAX_TIMERS; i++) {
timers[i].active = false;
timers[i].ticks = 0U;
timers[i].period = 0U;
timers[i].callback = NULL;
}
}
TimerError Timer_Set(uint8_t timer_id, uint32_t period, void (*callback)(void)) {
PRINTF("tIMERsET\r\n");
if (timer_id >= MAX_TIMERS) {
return TIMER_ERROR_INVALID_ID;
}
if (callback == NULL) {
return TIMER_ERROR_NULL_POINTER;
}
timers[timer_id].period = period;
timers[timer_id].ticks = period;
timers[timer_id].callback = callback;
timers[timer_id].active = false; /* 초기 상태는 비활성화 */
return TIMER_SUCCESS;
}
TimerError Timer_Start(uint8_t timer_id) {
PRINTF("tIMERsTART\r\n");
if (timer_id >= MAX_TIMERS) {
return TIMER_ERROR_INVALID_ID;
}
timers[timer_id].active = true;
timers[timer_id].ticks = timers[timer_id].period;
PRINTF("TimerStart\r\n");
return TIMER_SUCCESS;
}
TimerError Timer_Stop(uint8_t timer_id) {
if (timer_id >= MAX_TIMERS) {
return TIMER_ERROR_INVALID_ID;
}
timers[timer_id].active = false;
return TIMER_SUCCESS;
}
// Timer.h
/* timer.h */
#ifndef TIMER_H
#define TIMER_H
#include "fsl_pit.h"
#include "fsl_debug_console.h"
#include <stdint.h>
#include <stdbool.h>
#include "clock_config.h"
#define MAX_TIMERS 3 /* Timer Max Num */
#define GET_MSEC_COUNT(x) (CLOCK_GetBusClkFreq()/1000 * x) // Periodic Timer[Ms]
typedef struct {
bool active; /* sub Timer Active Status */
uint32_t ticks; /* Tick */
uint32_t period; /* Timer Period(unit-tick) */
void (*callback)(void); /* Callback */
} Timer;
/* Periodic Timer Status */
typedef enum {
TIMER_SUCCESS = 0,
TIMER_ERROR_INVALID_ID = 1,
TIMER_ERROR_NULL_POINTER = 2
} TimerError;
void Timers_Init(void);
TimerError Timer_Set(uint8_t timer_id, uint32_t period, void (*callback)(void));
TimerError Timer_Start(uint8_t timer_id);
TimerError Timer_Stop(uint8_t timer_id);
#endif /* TIMER_H */
Main.c
void Timeout(void) {
PRINTF("Timeout!\n");
}
int main(void) {
BOARD_InitBootPins();
BOARD_InitBootClocks();
BOARD_InitBootPeripherals();
BOARD_InitDebugConsole();
Timers_Init(); // PIT0 INIT - TImer.h
Timer_Set(0, 100, Timeout); //
Timer_Start(0);
while(1){
// ...
}
}
Hi,
I suppose that the work of PIT0_IRQHandler(void) is overloaded.
Pls try to set the PIT period for example 0.5S so that the core can have enough time to finish the work in PIT ISR.
Secondly, pls try to reduce the work in PIT0_IRQHandler(void), for example only try toggle a GPIO.
Hope it can help you
BR
XiangJun Rong