1
0
mirror of https://github.com/RIOT-OS/RIOT.git synced 2024-12-29 04:50:03 +01:00

Merge pull request #4838 from haukepetersen/fix_periph_timerarg

drivers/timer: added callback argument
This commit is contained in:
Peter Kietzmann 2016-03-01 08:55:54 +01:00
commit c8829a49b8
24 changed files with 177 additions and 215 deletions

View File

@ -33,20 +33,16 @@
#define IRQ_DISABLED 0x00
typedef struct {
void (*cb)(int);
} timer_conf_t;
/**
* @brief Timer state memory
*/
timer_conf_t config[TIMER_NUMOF];
static timer_isr_ctx_t config[TIMER_NUMOF];
/**
* @brief Setup the given timer
*
*/
int timer_init(tim_t dev, unsigned long freq, void (*callback)(int))
int timer_init(tim_t dev, unsigned long freq, timer_cb_t cb, void *arg)
{
/* reject impossible freq values
* todo: Add support for 2 MHz and 16 MHz */
@ -85,7 +81,8 @@ int timer_init(tim_t dev, unsigned long freq, void (*callback)(int))
}
/* save callback */
config[dev].cb = callback;
config[dev].cb = cb;
config[dev].arg = arg;
return 0;
}
@ -422,7 +419,7 @@ static inline void _isr(int timer, int chan)
__enter_isr();
timer_clear(timer, chan);
config[timer].cb(chan);
config[timer].cb(config[timer].arg, chan);
if (sched_context_switch_request) {
thread_yield();

View File

@ -30,21 +30,17 @@
#define USEC_PER_SEC 1000000 /**< Conversion factor between seconds and microseconds */
typedef struct {
void (*cb)(int);
} timer_conf_t;
/**
* @brief Timer state memory
*/
timer_conf_t config[TIMER_NUMOF];
static timer_isr_ctx_t config[TIMER_NUMOF];
/**
* @brief Setup the given timer
*
*/
int timer_init(tim_t dev, unsigned long freq, void (*callback)(int))
int timer_init(tim_t dev, unsigned long freq, timer_cb_t cb, void *arg)
{
cc2538_gptimer_t *gptimer;
unsigned int gptimer_num;
@ -80,7 +76,8 @@ int timer_init(tim_t dev, unsigned long freq, void (*callback)(int))
gptimer_num = ((uintptr_t)gptimer - (uintptr_t)GPTIMER0) / 0x1000;
/* Save the callback function: */
config[dev].cb = callback;
config[dev].cb = cb;
config[dev].arg = arg;
/* Enable the clock for this timer: */
SYS_CTRL_RCGCGPT |= (1 << gptimer_num);
@ -380,90 +377,60 @@ void timer_irq_disable(tim_t dev)
}
}
#if TIMER_0_EN
void TIMER_0_ISR_1(void)
static inline void irq_handler(int tim, int chan)
{
if (config[0].cb != NULL) config[0].cb(0);
if (config[tim].cb != NULL) {
config[tim].cb(config[tim].arg, chan);
}
if (sched_context_switch_request) {
thread_yield();
}
}
#if TIMER_0_EN
void TIMER_0_ISR_1(void)
{
irq_handler(0, 0);
}
void TIMER_0_ISR_2(void)
{
if (config[0].cb != NULL) config[0].cb(1);
if (sched_context_switch_request) {
thread_yield();
}
irq_handler(0, 1);
}
#endif /* TIMER_0_EN */
#if TIMER_1_EN
void TIMER_1_ISR_1(void)
{
if (config[1].cb != NULL) config[1].cb(0);
if (sched_context_switch_request) {
thread_yield();
}
irq_handler(1, 0);
}
void TIMER_1_ISR_2(void)
{
if (config[1].cb != NULL) config[1].cb(1);
if (sched_context_switch_request) {
thread_yield();
}
irq_handler(1, 1);
}
#endif /* TIMER_1_EN */
#if TIMER_2_EN
void TIMER_2_ISR_1(void)
{
if (config[2].cb != NULL) config[2].cb(0);
if (sched_context_switch_request) {
thread_yield();
}
irq_handler(2, 0);
}
void TIMER_2_ISR_2(void)
{
if (config[2].cb != NULL) config[2].cb(1);
if (sched_context_switch_request) {
thread_yield();
}
irq_handler(2, 1);
}
#endif /* TIMER_2_EN */
#if TIMER_3_EN
void TIMER_3_ISR_1(void)
{
if (config[3].cb != NULL) config[3].cb(0);
if (sched_context_switch_request) {
thread_yield();
}
irq_handler(3, 0);
}
void TIMER_3_ISR_2(void)
{
if (config[3].cb != NULL) config[3].cb(1);
if (sched_context_switch_request) {
thread_yield();
}
irq_handler(3, 1);
}
#endif /* TIMER_3_EN */

View File

@ -32,10 +32,15 @@
/**
* @brief Save reference to the timer callback
*/
static void (*isr_cb)(int chan);
static timer_cb_t isr_cb;
/**
* @brief Save argument for the callback
*/
static void *isr_arg;
int timer_init(tim_t dev, unsigned long freq, void (*callback)(int))
int timer_init(tim_t dev, unsigned long freq, timer_cb_t cb, void *arg)
{
/* using fixed TIMER_BASE for now */
if (dev != 0) {
@ -49,7 +54,8 @@ int timer_init(tim_t dev, unsigned long freq, void (*callback)(int))
/* reset the timer A configuration */
TIMER_BASE->CTL = CTL_CLR;
/* save callback */
isr_cb = callback;
isr_cb = cb;
isr_arg = arg;
/* configure timer to use the SMCLK with prescaler of 8 */
TIMER_BASE->CTL = (CTL_TASSEL_SMCLK | CTL_ID_DIV8);
/* configure CC channels */
@ -124,7 +130,7 @@ ISR(TIMER_ISR_CC0, isr_timer_a_cc0)
__enter_isr();
TIMER_BASE->CCTL[0] &= ~(CCTL_CCIE);
isr_cb(0);
isr_cb(isr_arg, 0);
__exit_isr();
}
@ -135,7 +141,7 @@ ISR(TIMER_ISR_CCX, isr_timer_a_ccx_isr)
int chan = (int)(TIMER_BASE->IV >> 1);
TIMER_BASE->CCTL[chan] &= ~(CCTL_CCIE);
isr_cb(chan);
isr_cb(isr_arg, chan);
__exit_isr();
}

View File

@ -38,7 +38,7 @@
static timer_isr_ctx_t isr_ctx[TIMER_NUMOF];
int timer_init(tim_t dev, unsigned long freq, void (*callback)(int))
int timer_init(tim_t dev, unsigned long freq, timer_cb_t cb, void *arg)
{
TIMER_TypeDef *pre, *tim;
@ -48,7 +48,8 @@ int timer_init(tim_t dev, unsigned long freq, void (*callback)(int))
}
/* save callback */
isr_ctx[dev].cb = callback;
isr_ctx[dev].cb = cb;
isr_ctx[dev].arg = arg;
/* get timers */
pre = timer_config[dev].prescaler;
@ -152,7 +153,7 @@ void TIMER_0_ISR(void)
if (tim->IF & (TIMER_IF_CC0 << i)) {
tim->CC[i].CTRL = _TIMER_CC_CTRL_MODE_OFF;
tim->IFC = (TIMER_IFC_CC0 << i);
isr_ctx[0].cb(i);
isr_ctx[0].cb(isr_ctx[0].arg, i);
}
}
if (sched_context_switch_request) {

View File

@ -35,16 +35,11 @@
#if TIMER_NUMOF
/** Type for timer state */
typedef struct {
void (*cb)(int);
} timer_conf_t;
/* Virtual count up timer */
static uint32_t cu_timer[TIMER_NUMOF];
/** Timer state memory */
static timer_conf_t config[TIMER_NUMOF];
static timer_isr_ctx_t config[TIMER_NUMOF];
inline static void pit_timer_start(uint8_t ch)
{
@ -84,7 +79,7 @@ inline static void pit_timer_set_max(uint8_t ch)
pit_timer_start(ch);
}
int timer_init(tim_t dev, unsigned long freq, void (*callback)(int))
int timer_init(tim_t dev, unsigned long freq, timer_cb_t cb, void *arg)
{
/* enable timer peripheral clock */
TIMER_CLKEN();
@ -116,7 +111,8 @@ int timer_init(tim_t dev, unsigned long freq, void (*callback)(int))
}
/* set callback function */
config[dev].cb = callback;
config[dev].cb = cb;
config[dev].arg = arg;
cu_timer[dev] = 0;
/* enable the timer's interrupt */
@ -317,7 +313,7 @@ inline static void pit_timer_irq_handler(tim_t dev, uint8_t ch)
pit_timer_set_max(ch);
if (config[dev].cb != NULL) {
config[dev].cb(dev);
config[dev].cb(config[dev].arg, dev);
}
TIMER_BASE->CHANNEL[ch].TFLG = PIT_TFLG_TIF_MASK;

View File

@ -38,7 +38,8 @@
* @{
*/
typedef struct {
void (*cb)(int); /**< timeout callback */
timer_cb_t cb; /**< timeout callback */
void *arg; /**< argument to the callback */
unsigned int divisor; /**< software clock divisor */
} timer_conf_t;
@ -66,13 +67,14 @@ static inline unsigned int _llvalue_to_scaled_value(unsigned long long corrected
return scaledv;
}
int timer_init(tim_t dev, unsigned long freq, void (*callback)(int))
int timer_init(tim_t dev, unsigned long freq, timer_cb_t cb, void *arg)
{
if (dev >= TIMER_NUMOF){
return -1;
}
config[dev].cb = callback; /* User Function */
config[dev].cb = cb;
config[dev].arg = arg;
config[dev].divisor = ROM_SysCtlClockGet() / freq;
unsigned int sysctl_timer;
@ -368,7 +370,7 @@ void isr_wtimer0a(void)
{
/* Clears both IT */
ROM_TimerIntClear(WTIMER0_BASE, TIMER_TIMA_TIMEOUT | TIMER_TIMA_MATCH);
config[TIMER_0].cb(0);
config[TIMER_0].cb(config[TIMER_0].arg, 0);
if (sched_context_switch_request){
thread_yield();
}
@ -380,7 +382,7 @@ void isr_wtimer1a(void)
{
ROM_TimerIntClear(WTIMER1_BASE, TIMER_TIMA_TIMEOUT | TIMER_TIMA_MATCH);
config[TIMER_1].cb(0);
config[TIMER_1].cb(config[TIMER_0].arg, 0);
if (sched_context_switch_request){
thread_yield();
}

View File

@ -38,23 +38,17 @@
#define MR3_FLAG (0x08) /**< match for channel 3 */
/** @} */
/**
* @brief Struct holding the configuration data for a UART device
*/
typedef struct {
void (*cb)(int); /**< timeout callback */
} timer_conf_t;
/**
* @brief UART device configurations
*/
static timer_conf_t config[TIMER_NUMOF];
static timer_isr_ctx_t config[TIMER_NUMOF];
int timer_init(tim_t dev, unsigned long freq, void (*callback)(int))
int timer_init(tim_t dev, unsigned long freq, timer_cb_t cb, void *arg)
{
if (dev == TIMER_0) {
/* save callback */
config[TIMER_0].cb = callback;
config[TIMER_0].cb = cb;
config[TIMER_0].arg = arg;
/* enable power for timer */
TIMER_0_CLKEN();
/* set to timer mode */
@ -155,22 +149,22 @@ void TIMER_0_ISR(void)
if (TIMER_0_DEV->IR & MR0_FLAG) {
TIMER_0_DEV->IR |= (MR0_FLAG);
TIMER_0_DEV->MCR &= ~(1 << 0);
config[TIMER_0].cb(0);
config[TIMER_0].cb(config[TIMER_0].arg, 0);
}
if (TIMER_0_DEV->IR & MR1_FLAG) {
TIMER_0_DEV->IR |= (MR1_FLAG);
TIMER_0_DEV->MCR &= ~(1 << 3);
config[TIMER_0].cb(1);
config[TIMER_0].cb(config[TIMER_0].arg, 1);
}
if (TIMER_0_DEV->IR & MR2_FLAG) {
TIMER_0_DEV->IR |= (MR2_FLAG);
TIMER_0_DEV->MCR &= ~(1 << 6);
config[TIMER_0].cb(2);
config[TIMER_0].cb(config[TIMER_0].arg, 2);
}
if (TIMER_0_DEV->IR & MR3_FLAG) {
TIMER_0_DEV->IR |= (MR3_FLAG);
TIMER_0_DEV->MCR &= ~(1 << 9);
config[TIMER_0].cb(3);
config[TIMER_0].cb(config[TIMER_0].arg, 3);
}
if (sched_context_switch_request) {
thread_yield();

View File

@ -38,23 +38,17 @@
#define MR3_FLAG (0x08) /**< match for channel 3 */
/** @} */
/**
* @brief Struct holding the configuration data for a UART device
*/
typedef struct {
void (*cb)(int); /**< timeout callback */
} timer_conf_t;
/**
* @brief UART device configurations
*/
static timer_conf_t config[TIMER_NUMOF];
static timer_isr_ctx_t config[TIMER_NUMOF];
int timer_init(tim_t dev, unsigned long freq, void (*callback)(int))
int timer_init(tim_t dev, unsigned long freq, timer_cb_t cb, void *arg)
{
if (dev == TIMER_0) {
/* save callback */
config[TIMER_0].cb = callback;
config[TIMER_0].cb = cb;
config[TIMER_0].arg = arg;
/* enable power for timer */
TIMER_0_CLKEN();
/* let timer run with full frequency */
@ -158,22 +152,22 @@ void TIMER_0_ISR(void)
if (TIMER_0_DEV->IR & MR0_FLAG) {
TIMER_0_DEV->IR |= (MR0_FLAG);
TIMER_0_DEV->MCR &= ~(1 << 0);
config[TIMER_0].cb(0);
config[TIMER_0].cb(config[TIMER_0].arg, 0);
}
if (TIMER_0_DEV->IR & MR1_FLAG) {
TIMER_0_DEV->IR |= (MR1_FLAG);
TIMER_0_DEV->MCR &= ~(1 << 3);
config[TIMER_0].cb(1);
config[TIMER_0].cb(config[TIMER_0].arg, 1);
}
if (TIMER_0_DEV->IR & MR2_FLAG) {
TIMER_0_DEV->IR |= (MR2_FLAG);
TIMER_0_DEV->MCR &= ~(1 << 6);
config[TIMER_0].cb(2);
config[TIMER_0].cb(config[TIMER_0].arg, 2);
}
if (TIMER_0_DEV->IR & MR3_FLAG) {
TIMER_0_DEV->IR |= (MR3_FLAG);
TIMER_0_DEV->MCR &= ~(1 << 9);
config[TIMER_0].cb(3);
config[TIMER_0].cb(config[TIMER_0].arg, 3);
}
if (sched_context_switch_request) {
thread_yield();

View File

@ -108,7 +108,7 @@ static inline void pwr_clk_and_isr(tim_t tim)
}
}
int timer_init(tim_t tim, unsigned long freq, void (*callback)(int))
int timer_init(tim_t tim, unsigned long freq, timer_cb_t cb, void *arg)
{
/* get the timers base register */
lpc23xx_timer_t *dev = get_dev(tim);
@ -119,7 +119,8 @@ int timer_init(tim_t tim, unsigned long freq, void (*callback)(int))
}
/* save the callback */
isr_ctx[tim].cb = callback;
isr_ctx[tim].cb = cb;
isr_ctx[tim].arg = arg;
/* enable power, config periph clock and install ISR vector */
pwr_clk_and_isr(tim);
/* reset timer configuration (sets the timer to timer mode) */
@ -192,7 +193,7 @@ static inline void isr_handler(lpc23xx_timer_t *dev, int tim_num)
if (dev->IR & (1 << i)) {
dev->IR |= (1 << i);
dev->MCR &= ~(1 << (i * 3));
isr_ctx[tim_num].cb(i);
isr_ctx[tim_num].cb(isr_ctx[tim_num].arg, i);
}
}
/* we must not forget to acknowledge the handling of the interrupt */

View File

@ -32,10 +32,15 @@
/**
* @brief Save reference to the timer callback
*/
static void (*isr_cb)(int chan);
static timer_cb_t isr_cb;
/**
* @brief Save argument for the ISR callback
*/
static void *isr_arg;
int timer_init(tim_t dev, unsigned long freq, void (*callback)(int))
int timer_init(tim_t dev, unsigned long freq, timer_cb_t cb, void *arg)
{
/* using fixed TIMER_BASE for now */
if (dev != 0) {
@ -49,7 +54,8 @@ int timer_init(tim_t dev, unsigned long freq, void (*callback)(int))
/* reset the timer A configuration */
TIMER_BASE->CTL = TIMER_CTL_CLR;
/* save callback */
isr_cb = callback;
isr_cb = cb;
isr_arg = arg;
/* configure timer to use the SMCLK with prescaler of 8 */
TIMER_BASE->CTL = (TIMER_CTL_TASSEL_SMCLK | TIMER_CTL_ID_DIV8);
/* configure CC channels */
@ -124,7 +130,7 @@ ISR(TIMER_ISR_CC0, isr_timer_a_cc0)
__enter_isr();
TIMER_BASE->CCTL[0] &= ~(TIMER_CCTL_CCIE);
isr_cb(0);
isr_cb(isr_arg, 0);
__exit_isr();
}
@ -135,7 +141,7 @@ ISR(TIMER_ISR_CCX, isr_timer_a_ccx)
int chan = (int)(TIMER_IVEC->TAIV >> 1);
TIMER_BASE->CCTL[chan] &= ~(TIMER_CCTL_CCIE);
isr_cb(chan);
isr_cb(isr_arg, chan);
__exit_isr();
}

View File

@ -49,7 +49,8 @@
static unsigned long time_null;
static void (*_callback)(int);
static timer_cb_t _callback;
static void *_cb_arg;
static struct itimerval itv;
@ -71,10 +72,10 @@ void native_isr_timer(void)
{
DEBUG("%s\n", __func__);
_callback(0);
_callback(_cb_arg, 0);
}
int timer_init(tim_t dev, unsigned long freq, void (*callback)(int))
int timer_init(tim_t dev, unsigned long freq, timer_cb_t cb, void *arg)
{
(void)freq;
DEBUG("%s\n", __func__);
@ -90,7 +91,8 @@ int timer_init(tim_t dev, unsigned long freq, void (*callback)(int))
time_null = timer_read(0);
timer_irq_disable(dev);
_callback = callback;
_callback = cb;
_cb_arg = arg;
timer_irq_enable(dev);
return 0;

View File

@ -40,7 +40,8 @@
* @brief struct for keeping track of a timer's state
*/
typedef struct {
void (*cb)(int);
timer_cb_t cb;
void *arg;
uint8_t flags;
} timer_conf_t;
@ -64,14 +65,15 @@ static NRF_TIMER_Type *const timer[] = {
#endif
};
int timer_init(tim_t dev, unsigned long freq, void (*callback)(int))
int timer_init(tim_t dev, unsigned long freq, timer_cb_t cb, void *arg)
{
if (dev >= TIMER_NUMOF) {
return -1;
}
/* save callback */
timer_config[dev].cb = callback;
timer_config[dev].cb = cb;
timer_config[dev].arg = arg;
/* power on timer */
timer[dev]->POWER = 1;
@ -285,7 +287,7 @@ void TIMER_0_ISR(void)
if (timer_config[TIMER_0].flags & (1 << i)) {
timer_config[TIMER_0].flags &= ~(1 << i);
TIMER_0_DEV->INTENCLR = (1 << (16 + i));
timer_config[TIMER_0].cb(i);
timer_config[TIMER_0].cb(timer_config[TIMER_0].arg, i);
}
}
}
@ -304,7 +306,7 @@ void TIMER_1_ISR(void)
if (timer_config[TIMER_1].flags & (1 << i)) {
timer_config[TIMER_1].flags &= ~(1 << i);
TIMER_1_DEV->INTENCLR = (1 << (16 + i));
timer_config[TIMER_1].cb(i);
timer_config[TIMER_1].cb(timer_config[TIMER_1].arg, i);
}
}
}
@ -323,7 +325,7 @@ void TIMER_2_ISR(void)
if (timer_config[TIMER_2].flags & (1 << i)) {
timer_config[TIMER_2].flags &= ~(1 << i);
TIMER_2_DEV->INTENCLR = (1 << (16 + i));
timer_config[TIMER_2].cb(i);
timer_config[TIMER_2].cb(timer_config[TIMER_2].arg, i);
}
}
}

View File

@ -40,7 +40,8 @@
* @brief struct for keeping track of a timer's state
*/
typedef struct {
void (*cb)(int);
timer_cb_t cb;
void *arg;
uint8_t flags;
} timer_conf_t;
@ -64,14 +65,15 @@ static NRF_TIMER_Type *const timer[] = {
#endif
};
int timer_init(tim_t dev, unsigned long freq, void (*callback)(int))
int timer_init(tim_t dev, unsigned long freq, timer_cb_t cb, void *arg)
{
if (dev >= TIMER_NUMOF) {
return -1;
}
/* save callback */
timer_config[dev].cb = callback;
timer_config[dev].cb = cb;
timer_config[dev].arg = arg;
/* power on timer */
/* timer[dev]->POWER = 1; */
@ -308,7 +310,7 @@ void TIMER_0_ISR(void)
if (timer_config[TIMER_0].flags & (1 << i)) {
timer_config[TIMER_0].flags &= ~(1 << i);
TIMER_0_DEV->INTENCLR = (1 << (16 + i));
timer_config[TIMER_0].cb(i);
timer_config[TIMER_0].cb(timer_config[TIMER_0].arg, i);
}
}
}
@ -329,7 +331,7 @@ void TIMER_1_ISR(void)
if (timer_config[TIMER_1].flags & (1 << i)) {
timer_config[TIMER_1].flags &= ~(1 << i);
TIMER_1_DEV->INTENCLR = (1 << (16 + i));
timer_config[TIMER_1].cb(i);
timer_config[TIMER_1].cb(timer_config[TIMER_1].arg, i);
}
}
}
@ -350,7 +352,7 @@ void TIMER_2_ISR(void)
if (timer_config[TIMER_2].flags & (1 << i)) {
timer_config[TIMER_2].flags &= ~(1 << i);
TIMER_2_DEV->INTENCLR = (1 << (16 + i));
timer_config[TIMER_2].cb(i);
timer_config[TIMER_2].cb(timer_config[TIMER_2].arg, i);
}
}
}

View File

@ -76,7 +76,7 @@ static inline Tc *dev(tim_t tim)
* For each timer, channel 1 is used to implement a prescaler. Channel 1 is
* driven by the MCK / 2 (42MHz) (TIMER_CLOCK1).
*/
int timer_init(tim_t tim, unsigned long freq, void (*callback)(int))
int timer_init(tim_t tim, unsigned long freq, timer_cb_t cb, void *arg)
{
/* check if device is valid */
if (tim >= TIMER_NUMOF) {
@ -87,7 +87,8 @@ int timer_init(tim_t tim, unsigned long freq, void (*callback)(int))
clk_en(tim);
/* save callback */
isr_ctx[tim].cb = callback;
isr_ctx[tim].cb = cb;
isr_ctx[tim].arg = arg;
/* configure the timer block by connecting TIOA1 to XC0 */
dev(tim)->TC_BMR = TC_BMR_TC0XC0S_TIOA1;
@ -182,7 +183,7 @@ static inline void isr_handler(tim_t tim)
for (int i = 0; i < TIMER_CHANNELS; i++) {
if (status & (TC_SR_CPAS << i)) {
dev(tim)->TC_CHANNEL[0].TC_IDR = (TC_IDR_CPAS << i);
isr_ctx[tim].cb(i);
isr_ctx[tim].cb(isr_ctx[tim].arg, i);
}
}

View File

@ -32,21 +32,16 @@
#define ENABLE_DEBUG (0)
#include "debug.h"
typedef struct {
void (*cb)(int);
} timer_conf_t;
/**
* @brief Timer state memory
*/
timer_conf_t config[TIMER_NUMOF];
static timer_isr_ctx_t config[TIMER_NUMOF];
/**
* @brief Setup the given timer
*/
int timer_init(tim_t dev, unsigned long freq, void (*callback)(int))
int timer_init(tim_t dev, unsigned long freq, timer_cb_t cb, void *arg)
{
/* at the moment, the timer can only run at 1MHz */
if (freq != 1000000ul) {
@ -123,7 +118,8 @@ int timer_init(tim_t dev, unsigned long freq, void (*callback)(int))
}
/* save callback */
config[dev].cb = callback;
config[dev].cb = cb;
config[dev].arg = arg;
/* enable interrupts for given timer */
timer_irq_enable(dev);
@ -339,14 +335,14 @@ void TIMER_0_ISR(void)
if(config[TIMER_0].cb) {
TIMER_0_DEV.INTFLAG.bit.MC0 = 1;
TIMER_0_DEV.INTENCLR.reg = TC_INTENCLR_MC0;
config[TIMER_0].cb(0);
config[TIMER_0].cb(config[TIMER_0].arg, 0);
}
}
else if (TIMER_0_DEV.INTFLAG.bit.MC1 && TIMER_0_DEV.INTENSET.bit.MC1) {
if(config[TIMER_0].cb) {
TIMER_0_DEV.INTFLAG.bit.MC1 = 1;
TIMER_0_DEV.INTENCLR.reg = TC_INTENCLR_MC1;
config[TIMER_0].cb(1);
config[TIMER_0].cb(config[TIMER_0].arg, 1);
}
}
@ -364,14 +360,14 @@ void TIMER_1_ISR(void)
if (config[TIMER_1].cb) {
TIMER_1_DEV.INTFLAG.bit.MC0 = 1;
TIMER_1_DEV.INTENCLR.reg = TC_INTENCLR_MC0;
config[TIMER_1].cb(0);
config[TIMER_1].cb(config[TIMER_1].arg, 0);
}
}
else if (TIMER_1_DEV.INTFLAG.bit.MC1 && TIMER_1_DEV.INTENSET.bit.MC1) {
if(config[TIMER_1].cb) {
TIMER_1_DEV.INTFLAG.bit.MC1 = 1;
TIMER_1_DEV.INTENCLR.reg = TC_INTENCLR_MC1;
config[TIMER_1].cb(1);
config[TIMER_1].cb(config[TIMER_1].arg, 1);
}
}

View File

@ -36,19 +36,15 @@
#define ENABLE_DEBUG (0)
#include "debug.h"
typedef struct {
void (*cb)(int);
} timer_conf_t;
/**
* @brief Timer state memory
*/
timer_conf_t config[TIMER_NUMOF];
static timer_isr_ctx_t config[TIMER_NUMOF];
/**
* @brief Setup the given timer
*/
int timer_init(tim_t dev, unsigned long freq, void (*callback)(int))
int timer_init(tim_t dev, unsigned long freq, timer_cb_t cb, void *arg)
{
/* configure GCLK0 to feed TC0 & TC1*/;
GCLK->PCHCTRL[TC0_GCLK_ID].reg |= GCLK_PCHCTRL_CHEN | GCLK_PCHCTRL_GEN_GCLK0;
@ -79,7 +75,8 @@ int timer_init(tim_t dev, unsigned long freq, void (*callback)(int))
}
/* save callback */
config[dev].cb = callback;
config[dev].cb = cb;
config[dev].arg = arg;
/* enable interrupts for given timer */
timer_irq_enable(dev);
@ -232,14 +229,14 @@ void TIMER_0_ISR(void)
if(config[TIMER_0].cb) {
TIMER_0_DEV.INTFLAG.bit.MC0 = 1;
TIMER_0_DEV.INTENCLR.reg = TC_INTENCLR_MC0;
config[TIMER_0].cb(0);
config[TIMER_0].cb(config[TIMER_0].arg, 0);
}
}
else if (TIMER_0_DEV.INTFLAG.bit.MC1 && TIMER_0_DEV.INTENSET.bit.MC1) {
if(config[TIMER_0].cb) {
TIMER_0_DEV.INTFLAG.bit.MC1 = 1;
TIMER_0_DEV.INTENCLR.reg = TC_INTENCLR_MC1;
config[TIMER_0].cb(1);
config[TIMER_0].cb(config[TIMER_0].arg, 1);
}
}

View File

@ -32,17 +32,13 @@
static inline void irq_handler(tim_t timer, TIM_TypeDef *dev);
typedef struct {
void (*cb)(int);
} timer_conf_t;
/**
* Timer state memory
*/
static timer_conf_t config[TIMER_NUMOF];
static timer_isr_ctx_t config[TIMER_NUMOF];
int timer_init(tim_t dev, unsigned long freq, void (*callback)(int))
int timer_init(tim_t dev, unsigned long freq, timer_cb_t cb, void *arg)
{
TIM_TypeDef *timer;
@ -73,7 +69,8 @@ int timer_init(tim_t dev, unsigned long freq, void (*callback)(int))
}
/* set callback function */
config[dev].cb = callback;
config[dev].cb = cb;
config[dev].arg = arg;
/* set timer to run in counter mode */
timer->CR1 |= TIM_CR1_URS;
@ -292,22 +289,22 @@ static inline void irq_handler(tim_t timer, TIM_TypeDef *dev)
if (dev->SR & TIM_SR_CC1IF) {
dev->DIER &= ~TIM_DIER_CC1IE;
dev->SR &= ~TIM_SR_CC1IF;
config[timer].cb(0);
config[timer].cb(config[timer].arg, 0);
}
else if (dev->SR & TIM_SR_CC2IF) {
dev->DIER &= ~TIM_DIER_CC2IE;
dev->SR &= ~TIM_SR_CC2IF;
config[timer].cb(1);
config[timer].cb(config[timer].arg, 1);
}
else if (dev->SR & TIM_SR_CC3IF) {
dev->DIER &= ~TIM_DIER_CC3IE;
dev->SR &= ~TIM_SR_CC3IF;
config[timer].cb(2);
config[timer].cb(config[timer].arg, 2);
}
else if (dev->SR & TIM_SR_CC4IF) {
dev->DIER &= ~TIM_DIER_CC4IE;
dev->SR &= ~TIM_SR_CC4IF;
config[timer].cb(3);
config[timer].cb(config[timer].arg, 3);
}
if (sched_context_switch_request) {
thread_yield();

View File

@ -36,16 +36,12 @@
static inline void irq_handler(tim_t timer, TIM_TypeDef *dev0, TIM_TypeDef *dev1);
typedef struct {
void (*cb)(int);
} timer_conf_t;
/**
* Timer state memory
*/
static timer_conf_t config[TIMER_NUMOF];
static timer_isr_ctx_t config[TIMER_NUMOF];
int timer_init(tim_t dev, unsigned long freq, void (*callback)(int))
int timer_init(tim_t dev, unsigned long freq, timer_cb_t cb, void *arg)
{
TIM_TypeDef *timer0;
TIM_TypeDef *timer1;
@ -84,7 +80,8 @@ int timer_init(tim_t dev, unsigned long freq, void (*callback)(int))
}
/* set callback function */
config[dev].cb = callback;
config[dev].cb = cb;
config[dev].arg = arg;
/* set timer to run in counter mode */
timer0->CR1 = (TIM_CR1_ARPE | TIM_CR1_URS);
@ -363,7 +360,7 @@ static inline void irq_handler(tim_t timer, TIM_TypeDef *dev0, TIM_TypeDef *dev1
/* if higher 16bit also match */
if (dev1->CNT >= dev1->CCR1) {
dev0->DIER &= ~TIM_DIER_CC1IE;
config[timer].cb(0);
config[timer].cb(config[timer].arg, 0);
}
DEBUG("channel 1 CCR: %08x\n", ((dev1->CCR1<<16) | (0xffff & dev0->CCR1)));
}
@ -373,7 +370,7 @@ static inline void irq_handler(tim_t timer, TIM_TypeDef *dev0, TIM_TypeDef *dev1
/* if higher 16bit also match */
if (dev1->CNT >= dev1->CCR2) {
dev0->DIER &= ~TIM_DIER_CC2IE;
config[timer].cb(1);
config[timer].cb(config[timer].arg, 1);
}
DEBUG("channel 2 CCR: %08x\n", ((dev1->CCR2<<16) | (0xffff & dev0->CCR2)));
}
@ -383,7 +380,7 @@ static inline void irq_handler(tim_t timer, TIM_TypeDef *dev0, TIM_TypeDef *dev1
/* if higher 16bit also match */
if (dev1->CNT >= dev1->CCR3) {
dev0->DIER &= ~TIM_DIER_CC3IE;
config[timer].cb(2);
config[timer].cb(config[timer].arg, 2);
}
DEBUG("channel 3 CCR: %08x\n", ((dev1->CCR3<<16) | (0xffff & dev0->CCR3)));
}
@ -393,7 +390,7 @@ static inline void irq_handler(tim_t timer, TIM_TypeDef *dev0, TIM_TypeDef *dev1
/* if higher 16bit also match */
if (dev1->CNT >= dev1->CCR4) {
dev0->DIER &= ~TIM_DIER_CC4IE;
config[timer].cb(3);
config[timer].cb(config[timer].arg, 3);
}
DEBUG("channel 4 CCR: %08x\n", ((dev1->CCR4<<16) | (0xffff & dev0->CCR4)));
}

View File

@ -30,16 +30,11 @@
/** Unified IRQ handler for all timers */
static inline void irq_handler(tim_t timer, TIM_TypeDef *dev);
/** Type for timer state */
typedef struct {
void (*cb)(int);
} timer_conf_t;
/** Timer state memory */
timer_conf_t config[TIMER_NUMOF];
static timer_isr_ctx_t config[TIMER_NUMOF];
int timer_init(tim_t dev, unsigned long freq, void (*callback)(int))
int timer_init(tim_t dev, unsigned long freq, timer_cb_t cb, void *arg)
{
TIM_TypeDef *timer;
@ -60,7 +55,8 @@ int timer_init(tim_t dev, unsigned long freq, void (*callback)(int))
}
/* set callback function */
config[dev].cb = callback;
config[dev].cb = cb;
config[dev].arg = arg;
/* set timer to run in counter mode */
timer->CR1 = 0;
@ -240,22 +236,22 @@ static inline void irq_handler(tim_t timer, TIM_TypeDef *dev)
if (dev->SR & TIM_SR_CC1IF) {
dev->DIER &= ~TIM_DIER_CC1IE;
dev->SR &= ~TIM_SR_CC1IF;
config[timer].cb(0);
config[timer].cb(config[timer].arg, 0);
}
else if (dev->SR & TIM_SR_CC2IF) {
dev->DIER &= ~TIM_DIER_CC2IE;
dev->SR &= ~TIM_SR_CC2IF;
config[timer].cb(1);
config[timer].cb(config[timer].arg, 1);
}
else if (dev->SR & TIM_SR_CC3IF) {
dev->DIER &= ~TIM_DIER_CC3IE;
dev->SR &= ~TIM_SR_CC3IF;
config[timer].cb(2);
config[timer].cb(config[timer].arg, 2);
}
else if (dev->SR & TIM_SR_CC4IF) {
dev->DIER &= ~TIM_DIER_CC4IE;
dev->SR &= ~TIM_SR_CC4IF;
config[timer].cb(3);
config[timer].cb(config[timer].arg, 3);
}
if (sched_context_switch_request) {
thread_yield();

View File

@ -30,16 +30,11 @@
/** Unified IRQ handler for all timers */
static inline void irq_handler(tim_t timer, TIM_TypeDef *dev);
/** Type for timer state */
typedef struct {
void (*cb)(int);
} timer_conf_t;
/** Timer state memory */
timer_conf_t config[TIMER_NUMOF];
static timer_isr_ctx_t config[TIMER_NUMOF];
int timer_init(tim_t dev, unsigned long freq, void (*callback)(int))
int timer_init(tim_t dev, unsigned long freq, timer_cb_t cb, void *arg)
{
TIM_TypeDef *timer;
@ -72,7 +67,8 @@ int timer_init(tim_t dev, unsigned long freq, void (*callback)(int))
}
/* set callback function */
config[dev].cb = callback;
config[dev].cb = cb;
config[dev].arg = arg;
/* set timer to run in counter mode */
timer->CR1 = 0;
@ -290,22 +286,22 @@ static inline void irq_handler(tim_t timer, TIM_TypeDef *dev)
if (dev->SR & TIM_SR_CC1IF) {
dev->DIER &= ~TIM_DIER_CC1IE;
dev->SR &= ~TIM_SR_CC1IF;
config[timer].cb(0);
config[timer].cb(config[timer].arg, 0);
}
else if (dev->SR & TIM_SR_CC2IF) {
dev->DIER &= ~TIM_DIER_CC2IE;
dev->SR &= ~TIM_SR_CC2IF;
config[timer].cb(1);
config[timer].cb(config[timer].arg, 1);
}
else if (dev->SR & TIM_SR_CC3IF) {
dev->DIER &= ~TIM_DIER_CC3IE;
dev->SR &= ~TIM_SR_CC3IF;
config[timer].cb(2);
config[timer].cb(config[timer].arg, 2);
}
else if (dev->SR & TIM_SR_CC4IF) {
dev->DIER &= ~TIM_DIER_CC4IE;
dev->SR &= ~TIM_SR_CC4IF;
config[timer].cb(3);
config[timer].cb(config[timer].arg, 3);
}
if (sched_context_switch_request) {
thread_yield();

View File

@ -43,7 +43,7 @@ static inline TIM_TypeDef *_tim(tim_t dev)
return timer_config[dev].dev;
}
int timer_init(tim_t dev, unsigned long freq, void (*callback)(int))
int timer_init(tim_t dev, unsigned long freq, timer_cb_t cb, void *arg)
{
TIM_TypeDef *tim;
@ -55,7 +55,8 @@ int timer_init(tim_t dev, unsigned long freq, void (*callback)(int))
/* get base register */
tim = _tim(dev);
/* save callback */
isr_ctx[dev].cb = callback;
isr_ctx[dev].cb = cb;
isr_ctx[dev].cb = arg;
/* enable peripheral clock */
RCC->APB1ENR |= (1 << timer_config[dev].rcc);
/* reset timer and configure to up-counting mode */
@ -139,7 +140,7 @@ static inline void irq_handler(tim_t num, TIM_TypeDef *tim)
if ((tim->SR & bit) && (tim->DIER & bit)) {
tim->SR &= ~(bit);
tim->DIER &= ~(bit);
isr_ctx[num].cb(i);
isr_ctx[num].cb(isr_ctx[num].arg, i);
}
}
if (sched_context_switch_request) {

View File

@ -55,13 +55,21 @@ extern "C" {
typedef unsigned int tim_t;
#endif
/**
* @brief Signature of event callback functions triggered from interrupts
*
* @param[in] arg optional context for the callback
* @param[in] channel timer channel that triggered the interrupt
*/
typedef void (*timer_cb_t)(void *arg, int channel);
/**
* @brief Default interrupt context entry holding callback and argument
* @{
*/
#ifndef HAVE_TIMER_ISR_CTX_T
typedef struct {
void (*cb)(int); /**< callback executed from timer interrupt */
timer_cb_t cb; /**< callback executed from timer interrupt */
void *arg; /**< optional argument given to that callback */
} timer_isr_ctx_t;
#endif
@ -82,11 +90,12 @@ typedef struct {
* @param[in] freq requested number of ticks per second
* @param[in] callback this callback is called in interrupt context, the
* emitting channel is passed as argument
* @param[in] arg argument to the callback
*
* @return 0 on success
* @return -1 if speed not applicable or unknown device given
*/
int timer_init(tim_t dev, unsigned long freq, void (*callback)(int));
int timer_init(tim_t dev, unsigned long freq, timer_cb_t cb, void *arg);
/**
* @brief Set a given timer channel for the given timer device

View File

@ -44,7 +44,7 @@ static inline void _lltimer_set(uint32_t target);
static uint32_t _time_left(uint32_t target, uint32_t reference);
static void _timer_callback(void);
static void _periph_timer_callback(int chan);
static void _periph_timer_callback(void *arg, int chan);
static inline int _this_high_period(uint32_t target);
@ -56,7 +56,7 @@ static inline int _is_set(xtimer_t *timer)
void xtimer_init(void)
{
/* initialize low-level timer */
timer_init(XTIMER, (1000000ul >> XTIMER_SHIFT), _periph_timer_callback);
timer_init(XTIMER, (1000000ul >> XTIMER_SHIFT), _periph_timer_callback, NULL);
/* register initial overflow tick */
_lltimer_set(0xFFFFFFFF);
@ -131,8 +131,9 @@ void xtimer_set(xtimer_t *timer, uint32_t offset)
}
}
static void _periph_timer_callback(int chan)
static void _periph_timer_callback(void *arg, int chan)
{
(void)arg;
(void)chan;
_timer_callback();
}

View File

@ -39,8 +39,9 @@ static volatile int fired;
static volatile uint32_t sw_count;
static volatile uint32_t timeouts[MAX_CHANNELS];
static void cb(int chan)
static void cb(void *arg, int chan)
{
(void)arg;
timeouts[chan] = sw_count;
fired++;
}
@ -57,7 +58,7 @@ static int test_timer(unsigned num)
}
/* initialize and halt timer */
if (timer_init(TIMER_DEV(num), TIM_SPEED, cb) < 0) {
if (timer_init(TIMER_DEV(num), TIM_SPEED, cb, NULL) < 0) {
printf("TIMER_%u: ERROR on initialization - skipping\n\n", num);
return 0;
}