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

cpus: adapted timer implementations to API changes

This commit is contained in:
Hauke Petersen 2016-02-17 12:18:24 +01:00
parent 2b97513637
commit b11a3ad74b
21 changed files with 159 additions and 208 deletions

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -38,23 +38,17 @@
#define MR3_FLAG (0x08) /**< match for channel 3 */ #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 * @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) { if (dev == TIMER_0) {
/* save callback */ /* save callback */
config[TIMER_0].cb = callback; config[TIMER_0].cb = cb;
config[TIMER_0].arg = arg;
/* enable power for timer */ /* enable power for timer */
TIMER_0_CLKEN(); TIMER_0_CLKEN();
/* set to timer mode */ /* set to timer mode */
@ -155,22 +149,22 @@ void TIMER_0_ISR(void)
if (TIMER_0_DEV->IR & MR0_FLAG) { if (TIMER_0_DEV->IR & MR0_FLAG) {
TIMER_0_DEV->IR |= (MR0_FLAG); TIMER_0_DEV->IR |= (MR0_FLAG);
TIMER_0_DEV->MCR &= ~(1 << 0); 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) { if (TIMER_0_DEV->IR & MR1_FLAG) {
TIMER_0_DEV->IR |= (MR1_FLAG); TIMER_0_DEV->IR |= (MR1_FLAG);
TIMER_0_DEV->MCR &= ~(1 << 3); 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) { if (TIMER_0_DEV->IR & MR2_FLAG) {
TIMER_0_DEV->IR |= (MR2_FLAG); TIMER_0_DEV->IR |= (MR2_FLAG);
TIMER_0_DEV->MCR &= ~(1 << 6); 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) { if (TIMER_0_DEV->IR & MR3_FLAG) {
TIMER_0_DEV->IR |= (MR3_FLAG); TIMER_0_DEV->IR |= (MR3_FLAG);
TIMER_0_DEV->MCR &= ~(1 << 9); 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) { if (sched_context_switch_request) {
thread_yield(); thread_yield();

View File

@ -38,23 +38,17 @@
#define MR3_FLAG (0x08) /**< match for channel 3 */ #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 * @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) { if (dev == TIMER_0) {
/* save callback */ /* save callback */
config[TIMER_0].cb = callback; config[TIMER_0].cb = cb;
config[TIMER_0].arg = arg;
/* enable power for timer */ /* enable power for timer */
TIMER_0_CLKEN(); TIMER_0_CLKEN();
/* let timer run with full frequency */ /* let timer run with full frequency */
@ -158,22 +152,22 @@ void TIMER_0_ISR(void)
if (TIMER_0_DEV->IR & MR0_FLAG) { if (TIMER_0_DEV->IR & MR0_FLAG) {
TIMER_0_DEV->IR |= (MR0_FLAG); TIMER_0_DEV->IR |= (MR0_FLAG);
TIMER_0_DEV->MCR &= ~(1 << 0); 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) { if (TIMER_0_DEV->IR & MR1_FLAG) {
TIMER_0_DEV->IR |= (MR1_FLAG); TIMER_0_DEV->IR |= (MR1_FLAG);
TIMER_0_DEV->MCR &= ~(1 << 3); 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) { if (TIMER_0_DEV->IR & MR2_FLAG) {
TIMER_0_DEV->IR |= (MR2_FLAG); TIMER_0_DEV->IR |= (MR2_FLAG);
TIMER_0_DEV->MCR &= ~(1 << 6); 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) { if (TIMER_0_DEV->IR & MR3_FLAG) {
TIMER_0_DEV->IR |= (MR3_FLAG); TIMER_0_DEV->IR |= (MR3_FLAG);
TIMER_0_DEV->MCR &= ~(1 << 9); 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) { if (sched_context_switch_request) {
thread_yield(); 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 */ /* get the timers base register */
lpc23xx_timer_t *dev = get_dev(tim); 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 */ /* 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 */ /* enable power, config periph clock and install ISR vector */
pwr_clk_and_isr(tim); pwr_clk_and_isr(tim);
/* reset timer configuration (sets the timer to timer mode) */ /* 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)) { if (dev->IR & (1 << i)) {
dev->IR |= (1 << i); dev->IR |= (1 << i);
dev->MCR &= ~(1 << (i * 3)); 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 */ /* we must not forget to acknowledge the handling of the interrupt */

View File

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

View File

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

View File

@ -40,7 +40,8 @@
* @brief struct for keeping track of a timer's state * @brief struct for keeping track of a timer's state
*/ */
typedef struct { typedef struct {
void (*cb)(int); timer_cb_t cb;
void *arg;
uint8_t flags; uint8_t flags;
} timer_conf_t; } timer_conf_t;
@ -64,14 +65,15 @@ static NRF_TIMER_Type *const timer[] = {
#endif #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) { if (dev >= TIMER_NUMOF) {
return -1; return -1;
} }
/* save callback */ /* save callback */
timer_config[dev].cb = callback; timer_config[dev].cb = cb;
timer_config[dev].arg = arg;
/* power on timer */ /* power on timer */
timer[dev]->POWER = 1; timer[dev]->POWER = 1;
@ -285,7 +287,7 @@ void TIMER_0_ISR(void)
if (timer_config[TIMER_0].flags & (1 << i)) { if (timer_config[TIMER_0].flags & (1 << i)) {
timer_config[TIMER_0].flags &= ~(1 << i); timer_config[TIMER_0].flags &= ~(1 << i);
TIMER_0_DEV->INTENCLR = (1 << (16 + 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)) { if (timer_config[TIMER_1].flags & (1 << i)) {
timer_config[TIMER_1].flags &= ~(1 << i); timer_config[TIMER_1].flags &= ~(1 << i);
TIMER_1_DEV->INTENCLR = (1 << (16 + 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)) { if (timer_config[TIMER_2].flags & (1 << i)) {
timer_config[TIMER_2].flags &= ~(1 << i); timer_config[TIMER_2].flags &= ~(1 << i);
TIMER_2_DEV->INTENCLR = (1 << (16 + 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 * @brief struct for keeping track of a timer's state
*/ */
typedef struct { typedef struct {
void (*cb)(int); timer_cb_t cb;
void *arg;
uint8_t flags; uint8_t flags;
} timer_conf_t; } timer_conf_t;
@ -64,14 +65,15 @@ static NRF_TIMER_Type *const timer[] = {
#endif #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) { if (dev >= TIMER_NUMOF) {
return -1; return -1;
} }
/* save callback */ /* save callback */
timer_config[dev].cb = callback; timer_config[dev].cb = cb;
timer_config[dev].arg = arg;
/* power on timer */ /* power on timer */
/* timer[dev]->POWER = 1; */ /* timer[dev]->POWER = 1; */
@ -308,7 +310,7 @@ void TIMER_0_ISR(void)
if (timer_config[TIMER_0].flags & (1 << i)) { if (timer_config[TIMER_0].flags & (1 << i)) {
timer_config[TIMER_0].flags &= ~(1 << i); timer_config[TIMER_0].flags &= ~(1 << i);
TIMER_0_DEV->INTENCLR = (1 << (16 + 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)) { if (timer_config[TIMER_1].flags & (1 << i)) {
timer_config[TIMER_1].flags &= ~(1 << i); timer_config[TIMER_1].flags &= ~(1 << i);
TIMER_1_DEV->INTENCLR = (1 << (16 + 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)) { if (timer_config[TIMER_2].flags & (1 << i)) {
timer_config[TIMER_2].flags &= ~(1 << i); timer_config[TIMER_2].flags &= ~(1 << i);
TIMER_2_DEV->INTENCLR = (1 << (16 + 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 * For each timer, channel 1 is used to implement a prescaler. Channel 1 is
* driven by the MCK / 2 (42MHz) (TIMER_CLOCK1). * 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 */ /* check if device is valid */
if (tim >= TIMER_NUMOF) { if (tim >= TIMER_NUMOF) {
@ -87,7 +87,8 @@ int timer_init(tim_t tim, unsigned long freq, void (*callback)(int))
clk_en(tim); clk_en(tim);
/* save callback */ /* 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 */ /* configure the timer block by connecting TIOA1 to XC0 */
dev(tim)->TC_BMR = TC_BMR_TC0XC0S_TIOA1; 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++) { for (int i = 0; i < TIMER_CHANNELS; i++) {
if (status & (TC_SR_CPAS << i)) { if (status & (TC_SR_CPAS << i)) {
dev(tim)->TC_CHANNEL[0].TC_IDR = (TC_IDR_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) #define ENABLE_DEBUG (0)
#include "debug.h" #include "debug.h"
typedef struct {
void (*cb)(int);
} timer_conf_t;
/** /**
* @brief Timer state memory * @brief Timer state memory
*/ */
timer_conf_t config[TIMER_NUMOF]; static timer_isr_ctx_t config[TIMER_NUMOF];
/** /**
* @brief Setup the given timer * @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 */ /* at the moment, the timer can only run at 1MHz */
if (freq != 1000000ul) { if (freq != 1000000ul) {
@ -123,7 +118,8 @@ int timer_init(tim_t dev, unsigned long freq, void (*callback)(int))
} }
/* save callback */ /* save callback */
config[dev].cb = callback; config[dev].cb = cb;
config[dev].arg = arg;
/* enable interrupts for given timer */ /* enable interrupts for given timer */
timer_irq_enable(dev); timer_irq_enable(dev);
@ -339,14 +335,14 @@ void TIMER_0_ISR(void)
if(config[TIMER_0].cb) { if(config[TIMER_0].cb) {
TIMER_0_DEV.INTFLAG.bit.MC0 = 1; TIMER_0_DEV.INTFLAG.bit.MC0 = 1;
TIMER_0_DEV.INTENCLR.reg = TC_INTENCLR_MC0; 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) { else if (TIMER_0_DEV.INTFLAG.bit.MC1 && TIMER_0_DEV.INTENSET.bit.MC1) {
if(config[TIMER_0].cb) { if(config[TIMER_0].cb) {
TIMER_0_DEV.INTFLAG.bit.MC1 = 1; TIMER_0_DEV.INTFLAG.bit.MC1 = 1;
TIMER_0_DEV.INTENCLR.reg = TC_INTENCLR_MC1; 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) { if (config[TIMER_1].cb) {
TIMER_1_DEV.INTFLAG.bit.MC0 = 1; TIMER_1_DEV.INTFLAG.bit.MC0 = 1;
TIMER_1_DEV.INTENCLR.reg = TC_INTENCLR_MC0; 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) { else if (TIMER_1_DEV.INTFLAG.bit.MC1 && TIMER_1_DEV.INTENSET.bit.MC1) {
if(config[TIMER_1].cb) { if(config[TIMER_1].cb) {
TIMER_1_DEV.INTFLAG.bit.MC1 = 1; TIMER_1_DEV.INTFLAG.bit.MC1 = 1;
TIMER_1_DEV.INTENCLR.reg = TC_INTENCLR_MC1; 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) #define ENABLE_DEBUG (0)
#include "debug.h" #include "debug.h"
typedef struct {
void (*cb)(int);
} timer_conf_t;
/** /**
* @brief Timer state memory * @brief Timer state memory
*/ */
timer_conf_t config[TIMER_NUMOF]; static timer_isr_ctx_t config[TIMER_NUMOF];
/** /**
* @brief Setup the given timer * @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*/; /* configure GCLK0 to feed TC0 & TC1*/;
GCLK->PCHCTRL[TC0_GCLK_ID].reg |= GCLK_PCHCTRL_CHEN | GCLK_PCHCTRL_GEN_GCLK0; 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 */ /* save callback */
config[dev].cb = callback; config[dev].cb = cb;
config[dev].arg = arg;
/* enable interrupts for given timer */ /* enable interrupts for given timer */
timer_irq_enable(dev); timer_irq_enable(dev);
@ -232,14 +229,14 @@ void TIMER_0_ISR(void)
if(config[TIMER_0].cb) { if(config[TIMER_0].cb) {
TIMER_0_DEV.INTFLAG.bit.MC0 = 1; TIMER_0_DEV.INTFLAG.bit.MC0 = 1;
TIMER_0_DEV.INTENCLR.reg = TC_INTENCLR_MC0; 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) { else if (TIMER_0_DEV.INTFLAG.bit.MC1 && TIMER_0_DEV.INTENSET.bit.MC1) {
if(config[TIMER_0].cb) { if(config[TIMER_0].cb) {
TIMER_0_DEV.INTFLAG.bit.MC1 = 1; TIMER_0_DEV.INTFLAG.bit.MC1 = 1;
TIMER_0_DEV.INTENCLR.reg = TC_INTENCLR_MC1; 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); static inline void irq_handler(tim_t timer, TIM_TypeDef *dev);
typedef struct {
void (*cb)(int);
} timer_conf_t;
/** /**
* Timer state memory * 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; TIM_TypeDef *timer;
@ -73,7 +69,8 @@ int timer_init(tim_t dev, unsigned long freq, void (*callback)(int))
} }
/* set callback function */ /* set callback function */
config[dev].cb = callback; config[dev].cb = cb;
config[dev].arg = arg;
/* set timer to run in counter mode */ /* set timer to run in counter mode */
timer->CR1 |= TIM_CR1_URS; 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) { if (dev->SR & TIM_SR_CC1IF) {
dev->DIER &= ~TIM_DIER_CC1IE; dev->DIER &= ~TIM_DIER_CC1IE;
dev->SR &= ~TIM_SR_CC1IF; dev->SR &= ~TIM_SR_CC1IF;
config[timer].cb(0); config[timer].cb(config[timer].arg, 0);
} }
else if (dev->SR & TIM_SR_CC2IF) { else if (dev->SR & TIM_SR_CC2IF) {
dev->DIER &= ~TIM_DIER_CC2IE; dev->DIER &= ~TIM_DIER_CC2IE;
dev->SR &= ~TIM_SR_CC2IF; dev->SR &= ~TIM_SR_CC2IF;
config[timer].cb(1); config[timer].cb(config[timer].arg, 1);
} }
else if (dev->SR & TIM_SR_CC3IF) { else if (dev->SR & TIM_SR_CC3IF) {
dev->DIER &= ~TIM_DIER_CC3IE; dev->DIER &= ~TIM_DIER_CC3IE;
dev->SR &= ~TIM_SR_CC3IF; dev->SR &= ~TIM_SR_CC3IF;
config[timer].cb(2); config[timer].cb(config[timer].arg, 2);
} }
else if (dev->SR & TIM_SR_CC4IF) { else if (dev->SR & TIM_SR_CC4IF) {
dev->DIER &= ~TIM_DIER_CC4IE; dev->DIER &= ~TIM_DIER_CC4IE;
dev->SR &= ~TIM_SR_CC4IF; dev->SR &= ~TIM_SR_CC4IF;
config[timer].cb(3); config[timer].cb(config[timer].arg, 3);
} }
if (sched_context_switch_request) { if (sched_context_switch_request) {
thread_yield(); thread_yield();

View File

@ -36,16 +36,12 @@
static inline void irq_handler(tim_t timer, TIM_TypeDef *dev0, TIM_TypeDef *dev1); 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 * 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 *timer0;
TIM_TypeDef *timer1; TIM_TypeDef *timer1;
@ -84,7 +80,8 @@ int timer_init(tim_t dev, unsigned long freq, void (*callback)(int))
} }
/* set callback function */ /* set callback function */
config[dev].cb = callback; config[dev].cb = cb;
config[dev].arg = arg;
/* set timer to run in counter mode */ /* set timer to run in counter mode */
timer0->CR1 = (TIM_CR1_ARPE | TIM_CR1_URS); 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 higher 16bit also match */
if (dev1->CNT >= dev1->CCR1) { if (dev1->CNT >= dev1->CCR1) {
dev0->DIER &= ~TIM_DIER_CC1IE; 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))); 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 higher 16bit also match */
if (dev1->CNT >= dev1->CCR2) { if (dev1->CNT >= dev1->CCR2) {
dev0->DIER &= ~TIM_DIER_CC2IE; 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))); 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 higher 16bit also match */
if (dev1->CNT >= dev1->CCR3) { if (dev1->CNT >= dev1->CCR3) {
dev0->DIER &= ~TIM_DIER_CC3IE; 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))); 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 higher 16bit also match */
if (dev1->CNT >= dev1->CCR4) { if (dev1->CNT >= dev1->CCR4) {
dev0->DIER &= ~TIM_DIER_CC4IE; 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))); DEBUG("channel 4 CCR: %08x\n", ((dev1->CCR4<<16) | (0xffff & dev0->CCR4)));
} }

View File

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

View File

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

View File

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