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

Merge pull request #4130 from jfischer-phytec-iot/fix@pit-xtimer

kinetis_common: cleanup and fix the (pit) timer
This commit is contained in:
Joakim Nohlgård 2015-10-23 20:51:17 +02:00
commit cb95954a15

View File

@ -1,6 +1,6 @@
/*
* Copyright (C) 2014 Freie Universität Berlin
* Copyright (C) 2014 PHYTEC Messtechnik GmbH
* Copyright (C) 2015 PHYTEC Messtechnik GmbH
*
* This file is subject to the terms and conditions of the GNU Lesser General
* Public License v2.1. See the file LICENSE in the top level directory for more
@ -40,13 +40,8 @@ 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];
/* Virtual count up timer */
static uint32_t cu_timer[TIMER_NUMOF];
/** Timer state memory */
static timer_conf_t config[TIMER_NUMOF];
@ -65,7 +60,7 @@ inline static void pit_timer_stop(uint8_t ch)
inline static void timer_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].LDVAL = (TIMER_CLOCK / 1e6) / ticks_per_us - 1;
TIMER_BASE->CHANNEL[ch].TCTRL = (PIT_TCTRL_TEN_MASK);
}
@ -78,8 +73,8 @@ inline static void timer_set_counter(uint8_t ch)
inline static uint32_t pit_timer_read(tim_t dev, uint8_t ch)
{
return cu_timer[dev].counter32b + (TIMER_BASE->CHANNEL[ch].LDVAL
- TIMER_BASE->CHANNEL[ch].CVAL);
return cu_timer[dev] + (TIMER_BASE->CHANNEL[ch].LDVAL
- TIMER_BASE->CHANNEL[ch].CVAL);
}
inline static void pit_timer_set_max(uint8_t ch)
@ -91,12 +86,11 @@ inline static void pit_timer_set_max(uint8_t ch)
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 = 0;
TIMER_BASE->MCR = PIT_MCR_FRZ_MASK;
switch (dev) {
#if TIMER_0_EN
@ -123,8 +117,7 @@ int timer_init(tim_t dev, unsigned int ticks_per_us, void (*callback)(int))
/* set callback function */
config[dev].cb = callback;
cu_timer[dev].counter32b = 0;
cu_timer[dev].diff = 0;
cu_timer[dev] = 0;
/* enable the timer's interrupt */
timer_irq_enable(dev);
@ -144,6 +137,8 @@ int timer_set(tim_t dev, int channel, unsigned int timeout)
int timer_set_absolute(tim_t dev, int channel, unsigned int value)
{
uint32_t diff = 0;
/* we only support one channel */
if (channel != 0) {
return -1;
@ -152,20 +147,20 @@ int timer_set_absolute(tim_t dev, int channel, unsigned int value)
#if TIMER_0_EN
case TIMER_0:
cu_timer[dev].counter32b = pit_timer_read(dev, TIMER_0_COUNTER_CH);
cu_timer[dev] = 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;
diff = value - cu_timer[dev];
TIMER_BASE->CHANNEL[TIMER_0_COUNTER_CH].LDVAL = diff;
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);
cu_timer[dev] = 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;
diff = value - cu_timer[dev];
TIMER_BASE->CHANNEL[TIMER_1_COUNTER_CH].LDVAL = diff;
pit_timer_start(TIMER_1_COUNTER_CH);
break;
#endif
@ -175,8 +170,7 @@ int timer_set_absolute(tim_t dev, int channel, unsigned int value)
return -1;
}
DEBUG("cntr: %lu, value: %u, diff: %lu\n",
cu_timer[dev].counter32b, value, cu_timer[dev].diff);
DEBUG("cntr: %lu, value: %u, diff: %lu\n", cu_timer[dev], value, diff);
return 0;
}
@ -191,16 +185,14 @@ 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;
cu_timer[dev] = timer_read(dev);
pit_timer_set_max(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;
cu_timer[dev] = timer_read(dev);
pit_timer_set_max(TIMER_1_COUNTER_CH);
break;
#endif
@ -210,8 +202,6 @@ int timer_clear(tim_t dev, int channel)
return -1;
}
DEBUG("clear\n");
return 0;
}
@ -344,16 +334,15 @@ 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;
cu_timer[dev] += TIMER_BASE->CHANNEL[ch].LDVAL + 1;
pit_timer_set_max(ch);
if (config[dev].cb != NULL) {
config[dev].cb(dev);
}
TIMER_BASE->CHANNEL[ch].TFLG = PIT_TFLG_TIF_MASK;
if (cu_timer[dev].diff) {
if (config[dev].cb != NULL) {
config[dev].cb(0);
}
}
if (sched_context_switch_request) {
thread_yield();
}