From d72d374242c90334455ac8cf66abd3f715b62263 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Joakim=20Nohlg=C3=A5rd?= Date: Fri, 25 Sep 2015 12:56:22 +0200 Subject: [PATCH] kinetis: periph/timer Use separate channel for counting timer_read() --- boards/mulle/include/periph_conf.h | 9 +- cpu/kinetis_common/timer.c | 127 ++++++++++------------------- 2 files changed, 45 insertions(+), 91 deletions(-) diff --git a/boards/mulle/include/periph_conf.h b/boards/mulle/include/periph_conf.h index b4572d5c9e3e..70285938ffd4 100644 --- a/boards/mulle/include/periph_conf.h +++ b/boards/mulle/include/periph_conf.h @@ -62,7 +62,6 @@ extern "C" */ #define TIMER_NUMOF (1U) #define TIMER_0_EN 1 -#define TIMER_1_EN 0 #define TIMER_IRQ_PRIO 1 #define TIMER_BASE PIT #define TIMER_MAX_VALUE (0xffffffff) @@ -76,10 +75,10 @@ extern "C" #define TIMER_0_IRQ_CHAN PIT1_IRQn /* Timer 1 configuration */ -#define TIMER_1_PRESCALER_CH 2 -#define TIMER_1_COUNTER_CH 3 -#define TIMER_1_ISR isr_pit3 -#define TIMER_1_IRQ_CHAN PIT3_IRQn +#define TIME_PRESCALER_CH 2 +#define TIME_COUNTER_CH 3 +#define TIME_ISR isr_pit3 +#define TIME_IRQ_CHAN PIT3_IRQn /** @} */ diff --git a/cpu/kinetis_common/timer.c b/cpu/kinetis_common/timer.c index 0982615e1727..33c5850d8fa1 100644 --- a/cpu/kinetis_common/timer.c +++ b/cpu/kinetis_common/timer.c @@ -40,14 +40,6 @@ typedef struct { void (*cb)(int); } timer_conf_t; -/** Type for virtual count up timer */ -typedef struct { - uint32_t counter32b; - uint32_t diff; -} count_up_timer_t; - -static count_up_timer_t cu_timer[TIMER_NUMOF]; - /** Timer state memory */ static timer_conf_t config[TIMER_NUMOF]; @@ -62,57 +54,45 @@ inline static void pit_timer_stop(uint8_t ch) } /** use channel n-1 as prescaler */ -inline static void timer_set_prescaler(uint8_t ch, unsigned int ticks_per_us) +inline static void pit_set_prescaler(uint8_t ch, unsigned int ticks_per_us) { TIMER_BASE->CHANNEL[ch].TCTRL = 0x0; TIMER_BASE->CHANNEL[ch].LDVAL = (TIMER_CLOCK / 1e6) / ticks_per_us; TIMER_BASE->CHANNEL[ch].TCTRL = (PIT_TCTRL_TEN_MASK); } -inline static void timer_set_counter(uint8_t ch) +inline static void pit_set_counter(uint8_t ch, uint32_t timeout) { TIMER_BASE->CHANNEL[ch].TCTRL = 0x0; - TIMER_BASE->CHANNEL[ch].LDVAL = TIMER_MAX_VALUE; + TIMER_BASE->CHANNEL[ch].LDVAL = timeout; TIMER_BASE->CHANNEL[ch].TCTRL = (PIT_TCTRL_TIE_MASK | PIT_TCTRL_CHN_MASK); } -inline static uint32_t pit_timer_read(tim_t dev, uint8_t ch) +inline static uint32_t pit_timer_read(uint8_t ch) { - return cu_timer[dev].counter32b + (TIMER_BASE->CHANNEL[ch].LDVAL - - TIMER_BASE->CHANNEL[ch].CVAL); -} - -inline static void pit_timer_set_max(uint8_t ch) -{ - pit_timer_stop(ch); - TIMER_BASE->CHANNEL[ch].LDVAL = TIMER_MAX_VALUE; - pit_timer_start(ch); + return (TIMER_BASE->CHANNEL[ch].LDVAL - TIMER_BASE->CHANNEL[ch].CVAL); } int timer_init(tim_t dev, unsigned int ticks_per_us, void (*callback)(int)) { - PIT_Type *timer = TIMER_BASE; - /* enable timer peripheral clock */ TIMER_CLKEN(); - timer->MCR = PIT_MCR_FRZ_MASK; + TIMER_BASE->MCR = PIT_MCR_FRZ_MASK; switch (dev) { #if TIMER_0_EN case TIMER_0: NVIC_SetPriority(TIMER_0_IRQ_CHAN, TIMER_IRQ_PRIO); - timer_set_prescaler(TIMER_0_PRESCALER_CH, ticks_per_us); - timer_set_counter(TIMER_0_COUNTER_CH); + pit_set_prescaler(TIMER_0_PRESCALER_CH, ticks_per_us); break; #endif #if TIMER_1_EN case TIMER_1: NVIC_SetPriority(TIMER_1_IRQ_CHAN, TIMER_IRQ_PRIO); - timer_set_prescaler(TIMER_1_PRESCALER_CH, ticks_per_us); - timer_set_counter(TIMER_1_COUNTER_CH); + pit_set_prescaler(TIMER_1_PRESCALER_CH, ticks_per_us); break; #endif @@ -120,65 +100,61 @@ int timer_init(tim_t dev, unsigned int ticks_per_us, void (*callback)(int)) default: return -1; } + pit_set_prescaler(TIME_PRESCALER_CH, ticks_per_us); + pit_set_counter(TIME_COUNTER_CH, TIMER_MAX_VALUE); + /* Disable interrupts on the time counter */ + TIMER_BASE->CHANNEL[TIME_COUNTER_CH].TCTRL &= ~(PIT_TCTRL_TIE_MASK); + pit_timer_start(TIME_COUNTER_CH); /* set callback function */ config[dev].cb = callback; - cu_timer[dev].counter32b = 0; - cu_timer[dev].diff = 0; /* enable the timer's interrupt */ timer_irq_enable(dev); - /* start the timer */ - timer_start(dev); - return 0; } int timer_set(tim_t dev, int channel, unsigned int timeout) -{ - unsigned int now = timer_read(dev); - - return timer_set_absolute(dev, channel, now + timeout); -} - -int timer_set_absolute(tim_t dev, int channel, unsigned int value) { /* we only support one channel */ if (channel != 0) { return -1; } + switch (dev) { #if TIMER_0_EN case TIMER_0: - cu_timer[dev].counter32b = pit_timer_read(dev, TIMER_0_COUNTER_CH); - pit_timer_stop(TIMER_0_COUNTER_CH); - cu_timer[dev].diff = value - cu_timer[dev].counter32b; - TIMER_BASE->CHANNEL[TIMER_0_COUNTER_CH].LDVAL = cu_timer[dev].diff; + pit_set_counter(TIMER_0_COUNTER_CH, timeout); pit_timer_start(TIMER_0_COUNTER_CH); break; #endif #if TIMER_1_EN case TIMER_1: - cu_timer[dev].counter32b = pit_timer_read(dev, TIMER_1_COUNTER_CH); - pit_timer_stop(TIMER_1_COUNTER_CH); - cu_timer[dev].diff = value - cu_timer[dev].counter32b; - TIMER_BASE->CHANNEL[TIMER_1_COUNTER_CH].LDVAL = cu_timer[dev].diff; + pit_set_counter(TIMER_1_COUNTER_CH, timeout); pit_timer_start(TIMER_1_COUNTER_CH); break; #endif - - case TIMER_UNDEFINED: default: return -1; } - DEBUG("cntr: %lu, value: %u, diff: %lu\n", - cu_timer[dev].counter32b, value, cu_timer[dev].diff); + return 1; +} - return 0; +int timer_set_absolute(tim_t dev, int channel, unsigned int value) +{ + uint32_t now; + + /* we only support one channel */ + if (channel != 0) { + return -1; + } + + now = pit_timer_read(TIME_COUNTER_CH); + return timer_set(dev, channel, value - now); } int timer_clear(tim_t dev, int channel) @@ -191,21 +167,16 @@ int timer_clear(tim_t dev, int channel) #if TIMER_0_EN case TIMER_0: - cu_timer[dev].counter32b = timer_read(dev); - cu_timer[dev].diff = 0; - pit_timer_set_max(TIMER_0_COUNTER_CH); + pit_timer_stop(TIMER_0_COUNTER_CH); break; #endif #if TIMER_1_EN case TIMER_1: - cu_timer[dev].counter32b = timer_read(dev); - cu_timer[dev].diff = 0; - pit_timer_set_max(TIMER_1_COUNTER_CH); + pit_timer_stop(TIMER_1_COUNTER_CH); break; #endif - case TIMER_UNDEFINED: default: return -1; } @@ -217,24 +188,7 @@ int timer_clear(tim_t dev, int channel) unsigned int timer_read(tim_t dev) { - switch (dev) { -#if TIMER_0_EN - - case TIMER_0: - return pit_timer_read(dev, TIMER_0_COUNTER_CH); - break; -#endif -#if TIMER_1_EN - - case TIMER_1: - return pit_timer_read(dev, TIMER_1_COUNTER_CH); - break; -#endif - - case TIMER_UNDEFINED: - default: - return 0; - } + return pit_timer_read(TIME_COUNTER_CH); } void timer_start(tim_t dev) @@ -327,13 +281,15 @@ void timer_reset(tim_t dev) #if TIMER_0_EN case TIMER_0: - pit_timer_set_max(TIMER_0_COUNTER_CH); + pit_timer_stop(TIMER_0_COUNTER_CH); + pit_timer_start(TIMER_0_COUNTER_CH); break; #endif #if TIMER_1_EN case TIMER_1: - pit_timer_set_max(TIMER_1_COUNTER_CH); + pit_timer_stop(TIMER_1_COUNTER_CH); + pit_timer_start(TIMER_1_COUNTER_CH); break; #endif @@ -344,14 +300,13 @@ void timer_reset(tim_t dev) inline static void pit_timer_irq_handler(tim_t dev, uint8_t ch) { - cu_timer[dev].counter32b += TIMER_BASE->CHANNEL[ch].LDVAL; - + /* Stop timer */ + pit_timer_stop(ch); + /* Clear interrupt flag */ TIMER_BASE->CHANNEL[ch].TFLG = PIT_TFLG_TIF_MASK; - if (cu_timer[dev].diff) { - if (config[dev].cb != NULL) { - config[dev].cb(0); - } + if (config[dev].cb != NULL) { + config[dev].cb(0); } if (sched_context_switch_request) {