From 1cfd265dbd1a2ff224dfdccdb0610599e1da66f5 Mon Sep 17 00:00:00 2001 From: Nathael Pajani Date: Tue, 26 Aug 2014 01:24:21 +0200 Subject: [PATCH] Implement timer interrupt callbacks --- drivers/timers.c | 35 +++++++++++++++++++++++++++++------ include/drivers/timers.h | 5 ++++- 2 files changed, 33 insertions(+), 7 deletions(-) diff --git a/drivers/timers.c b/drivers/timers.c index 544ffe3..ae9d621 100644 --- a/drivers/timers.c +++ b/drivers/timers.c @@ -39,6 +39,7 @@ struct timer_device struct lpc_timer* regs; uint32_t power_bit; uint32_t irq; + void (*callback)(uint8_t); /* Possible RX callback */ }; static struct timer_device timer_devices[NUM_TIMERS] = { { LPC_TMR16B0, LPC_SYS_ABH_CLK_CTRL_CT16B0, TIMER0_IRQ }, @@ -49,15 +50,34 @@ static struct timer_device timer_devices[NUM_TIMERS] = { -/* FIXME : Add callbacks and implement all handlers ! */ /* Handlers */ -void TIMER_0_Handler(void) +void TIMER_Handler(struct timer_device* timer) { - struct lpc_timer* timer = timer_devices[0].regs; - uint32_t intr_flags = timer->int_reg; + struct lpc_timer* regs = timer->regs; + uint32_t intr_flags = regs->int_reg; /* Backup the flags */ /* Clear the interrupt */ - timer->int_reg = 0xFF; + regs->int_reg = 0xFF; + /* And call the user routine if one has been registered */ + if (timer->callback != NULL) { + timer->callback(intr_flags); + } +} +void TIMER_0_Handler(void) +{ + TIMER_Handler(&timer_devices[0]); +} +void TIMER_1_Handler(void) +{ + TIMER_Handler(&timer_devices[1]); +} +void TIMER_2_Handler(void) +{ + TIMER_Handler(&timer_devices[2]); +} +void TIMER_3_Handler(void) +{ + TIMER_Handler(&timer_devices[3]); } @@ -245,7 +265,7 @@ static void timer_pins_setup(uint32_t timer_num) * the prescaler value. * Set clkrate to 0 to disable the prescaler. */ -void timer_on(uint32_t timer_num, uint32_t clkrate) +void timer_on(uint32_t timer_num, uint32_t clkrate, void (*callback)(uint8_t)) { struct timer_device* timer = NULL; uint32_t prescale; /* The clock divider for the counter */ @@ -260,6 +280,9 @@ void timer_on(uint32_t timer_num, uint32_t clkrate) /* Reset counter on next PCLK positive edge, and disable counter */ timer->regs->timer_ctrl = LPC_TIMER_COUNTER_RESET; + /* Store the callback, OK even if none given */ + timer->callback = callback; + /* Set the prescaler value */ if (clkrate == 0) { prescale = 0; diff --git a/include/drivers/timers.h b/include/drivers/timers.h index 7e883c2..fcce461 100644 --- a/include/drivers/timers.h +++ b/include/drivers/timers.h @@ -106,8 +106,11 @@ int timer_setup(uint32_t timer_num, struct timer_config* conf); * for your application as it will be used to divide the main clock to get * the prescaler value. * Set clkrate to 0 to disable the prescaler. + * calback is used for all the possible timer interrupts (activated using the + * config field in timer_config struct upon timer setup) + * The interrupt flags are passed to the interrupt routine as argument. */ -void timer_on(uint32_t timer_num, uint32_t clkrate); +void timer_on(uint32_t timer_num, uint32_t clkrate, void (*callback)(uint8_t)); /* Removes the main clock from the selected timer block */ void timer_off(uint32_t timer_num); -- 2.43.0