mirror of
https://github.com/RIOT-OS/RIOT.git
synced 2025-01-18 12:52:44 +01:00
Merge pull request #4839 from haukepetersen/opt_nrf_timer
cpu/nrf5x: unified and reworked timer driver
This commit is contained in:
commit
3f99028b19
@ -20,6 +20,8 @@
|
||||
#ifndef PERIPH_CONF_H_
|
||||
#define PERIPH_CONF_H_
|
||||
|
||||
#include "periph_cpu.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
@ -41,35 +43,14 @@
|
||||
* @name Timer configuration
|
||||
* @{
|
||||
*/
|
||||
#define TIMER_NUMOF (1U)
|
||||
#define TIMER_0_EN 1
|
||||
#define TIMER_1_EN 0
|
||||
#define TIMER_2_EN 0
|
||||
#define TIMER_IRQ_PRIO 1
|
||||
static const timer_conf_t timer_config[] = {
|
||||
/* dev, channels, width */
|
||||
{ NRF_TIMER0, 3, TIMER_BITMODE_BITMODE_24Bit, TIMER0_IRQn }
|
||||
};
|
||||
|
||||
/* Timer 0 configuration */
|
||||
#define TIMER_0_DEV NRF_TIMER0
|
||||
#define TIMER_0_CHANNELS 3
|
||||
#define TIMER_0_MAX_VALUE (0xffffff)
|
||||
#define TIMER_0_BITMODE TIMER_BITMODE_BITMODE_24Bit /* only possible value for TIMER0 */
|
||||
#define TIMER_0_ISR isr_timer0
|
||||
#define TIMER_0_IRQ TIMER0_IRQn
|
||||
|
||||
/* Timer 1 configuration */
|
||||
#define TIMER_1_DEV NRF_TIMER1
|
||||
#define TIMER_1_CHANNELS 3
|
||||
#define TIMER_1_MAX_VALUE (0xffff)
|
||||
#define TIMER_1_BITMODE TIMER_BITMODE_BITMODE_16Bit
|
||||
#define TIMER_1_ISR isr_timer1
|
||||
#define TIMER_1_IRQ TIMER1_IRQn
|
||||
|
||||
/* Timer 2 configuration */
|
||||
#define TIMER_2_DEV NRF_TIMER2
|
||||
#define TIMER_2_CHANNELS 3
|
||||
#define TIMER_2_MAX_VALUE (0xffff)
|
||||
#define TIMER_2_BITMODE TIMER_BITMODE_BITMODE_16Bit
|
||||
#define TIMER_2_ISR isr_timer2
|
||||
#define TIMER_2_IRQ TIMER2_IRQn
|
||||
#define TIMER_NUMOF (sizeof(timer_config) / sizeof(timer_config[0]))
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
|
@ -19,6 +19,8 @@
|
||||
#ifndef PERIPH_CONF_H
|
||||
#define PERIPH_CONF_H
|
||||
|
||||
#include "periph_cpu.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
@ -40,35 +42,14 @@ extern "C" {
|
||||
* @name Timer configuration
|
||||
* @{
|
||||
*/
|
||||
#define TIMER_NUMOF (1U)
|
||||
#define TIMER_0_EN 1
|
||||
#define TIMER_1_EN 0
|
||||
#define TIMER_2_EN 0
|
||||
#define TIMER_IRQ_PRIO 1
|
||||
static const timer_conf_t timer_config[] = {
|
||||
/* dev, channels, width */
|
||||
{ NRF_TIMER0, 3, TIMER_BITMODE_BITMODE_24Bit, TIMER0_IRQn }
|
||||
};
|
||||
|
||||
/* Timer 0 configuration */
|
||||
#define TIMER_0_DEV NRF_TIMER0
|
||||
#define TIMER_0_CHANNELS 3
|
||||
#define TIMER_0_MAX_VALUE (0xffffff)
|
||||
#define TIMER_0_BITMODE TIMER_BITMODE_BITMODE_24Bit
|
||||
#define TIMER_0_ISR isr_timer0
|
||||
#define TIMER_0_IRQ TIMER0_IRQn
|
||||
|
||||
/* Timer 1 configuration */
|
||||
#define TIMER_1_DEV NRF_TIMER1
|
||||
#define TIMER_1_CHANNELS 3
|
||||
#define TIMER_1_MAX_VALUE (0xffff)
|
||||
#define TIMER_1_BITMODE TIMER_BITMODE_BITMODE_16Bit
|
||||
#define TIMER_1_ISR isr_timer1
|
||||
#define TIMER_1_IRQ TIMER1_IRQn
|
||||
|
||||
/* Timer 2 configuration */
|
||||
#define TIMER_2_DEV NRF_TIMER2
|
||||
#define TIMER_2_CHANNELS 3
|
||||
#define TIMER_2_MAX_VALUE (0xffff)
|
||||
#define TIMER_2_BITMODE TIMER_BITMODE_BITMODE_16Bit
|
||||
#define TIMER_2_ISR isr_timer2
|
||||
#define TIMER_2_IRQ TIMER2_IRQn
|
||||
#define TIMER_NUMOF (sizeof(timer_config) / sizeof(timer_config[0]))
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
|
@ -20,6 +20,8 @@
|
||||
#ifndef PERIPH_CONF_H
|
||||
#define PERIPH_CONF_H
|
||||
|
||||
#include "periph_cpu.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
@ -40,16 +42,14 @@ extern "C" {
|
||||
* @brief Timer configuration
|
||||
* @{
|
||||
*/
|
||||
#define TIMER_NUMOF (1U)
|
||||
#define TIMER_0_EN 1
|
||||
static const timer_conf_t timer_config[] = {
|
||||
/* dev, channels, width, IRQn */
|
||||
{ NRF_TIMER0, 3, TIMER_BITMODE_BITMODE_32Bit, TIMER0_IRQn }
|
||||
};
|
||||
|
||||
/* Timer 0 configuration */
|
||||
#define TIMER_0_DEV NRF_TIMER0
|
||||
#define TIMER_0_CHANNELS 3
|
||||
#define TIMER_0_MAX_VALUE (0xffffffff)
|
||||
#define TIMER_0_BITMODE TIMER_BITMODE_BITMODE_32Bit
|
||||
#define TIMER_0_ISR isr_timer0
|
||||
#define TIMER_0_IRQ TIMER0_IRQn
|
||||
|
||||
#define TIMER_NUMOF (sizeof(timer_config) / sizeof(timer_config[0]))
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
|
@ -22,6 +22,8 @@
|
||||
#ifndef PERIPH_CONF_H
|
||||
#define PERIPH_CONF_H
|
||||
|
||||
#include "periph_cpu.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
@ -43,35 +45,14 @@ extern "C" {
|
||||
* @name Timer configuration
|
||||
* @{
|
||||
*/
|
||||
#define TIMER_NUMOF (1U)
|
||||
#define TIMER_0_EN 1
|
||||
#define TIMER_1_EN 0
|
||||
#define TIMER_2_EN 0
|
||||
#define TIMER_IRQ_PRIO 1
|
||||
static const timer_conf_t timer_config[] = {
|
||||
/* dev, channels, width */
|
||||
{ NRF_TIMER0, 3, TIMER_BITMODE_BITMODE_24Bit, TIMER0_IRQn }
|
||||
};
|
||||
|
||||
/* Timer 0 configuration */
|
||||
#define TIMER_0_DEV NRF_TIMER0
|
||||
#define TIMER_0_CHANNELS 3
|
||||
#define TIMER_0_MAX_VALUE (0xffffff)
|
||||
#define TIMER_0_BITMODE TIMER_BITMODE_BITMODE_24Bit
|
||||
#define TIMER_0_ISR isr_timer0
|
||||
#define TIMER_0_IRQ TIMER0_IRQn
|
||||
|
||||
/* Timer 1 configuration */
|
||||
#define TIMER_1_DEV NRF_TIMER1
|
||||
#define TIMER_1_CHANNELS 3
|
||||
#define TIMER_1_MAX_VALUE (0xffff)
|
||||
#define TIMER_1_BITMODE TIMER_BITMODE_BITMODE_16Bit
|
||||
#define TIMER_1_ISR isr_timer1
|
||||
#define TIMER_1_IRQ TIMER1_IRQn
|
||||
|
||||
/* Timer 2 configuration */
|
||||
#define TIMER_2_DEV NRF_TIMER2
|
||||
#define TIMER_2_CHANNELS 3
|
||||
#define TIMER_2_MAX_VALUE (0xffff)
|
||||
#define TIMER_2_BITMODE TIMER_BITMODE_BITMODE_16Bit
|
||||
#define TIMER_2_ISR isr_timer2
|
||||
#define TIMER_2_IRQ TIMER2_IRQn
|
||||
#define TIMER_NUMOF (sizeof(timer_config) / sizeof(timer_config[0]))
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
|
@ -21,6 +21,8 @@
|
||||
#ifndef PERIPH_CONF_H_
|
||||
#define PERIPH_CONF_H_
|
||||
|
||||
#include "periph_cpu.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
@ -42,35 +44,14 @@ extern "C" {
|
||||
* @name Timer configuration
|
||||
* @{
|
||||
*/
|
||||
#define TIMER_NUMOF (1U)
|
||||
#define TIMER_0_EN 1
|
||||
#define TIMER_1_EN 0
|
||||
#define TIMER_2_EN 0
|
||||
#define TIMER_IRQ_PRIO 1
|
||||
static const timer_conf_t timer_config[] = {
|
||||
/* dev, channels, width */
|
||||
{ NRF_TIMER0, 3, TIMER_BITMODE_BITMODE_24Bit, TIMER0_IRQn }
|
||||
};
|
||||
|
||||
/* Timer 0 configuration */
|
||||
#define TIMER_0_DEV NRF_TIMER0
|
||||
#define TIMER_0_CHANNELS 3
|
||||
#define TIMER_0_MAX_VALUE (0xffffff)
|
||||
#define TIMER_0_BITMODE TIMER_BITMODE_BITMODE_24Bit
|
||||
#define TIMER_0_ISR isr_timer0
|
||||
#define TIMER_0_IRQ TIMER0_IRQn
|
||||
|
||||
/* Timer 1 configuration */
|
||||
#define TIMER_1_DEV NRF_TIMER1
|
||||
#define TIMER_1_CHANNELS 3
|
||||
#define TIMER_1_MAX_VALUE (0xffff)
|
||||
#define TIMER_1_BITMODE TIMER_BITMODE_BITMODE_16Bit
|
||||
#define TIMER_1_ISR isr_timer1
|
||||
#define TIMER_1_IRQ TIMER1_IRQn
|
||||
|
||||
/* Timer 2 configuration */
|
||||
#define TIMER_2_DEV NRF_TIMER2
|
||||
#define TIMER_2_CHANNELS 3
|
||||
#define TIMER_2_MAX_VALUE (0xffff)
|
||||
#define TIMER_2_BITMODE TIMER_BITMODE_BITMODE_16Bit
|
||||
#define TIMER_2_ISR isr_timer2
|
||||
#define TIMER_2_IRQ TIMER2_IRQn
|
||||
#define TIMER_NUMOF (sizeof(timer_config) / sizeof(timer_config[0]))
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
|
@ -21,6 +21,8 @@
|
||||
#ifndef PERIPH_CONF_H_
|
||||
#define PERIPH_CONF_H_
|
||||
|
||||
#include "periph_cpu.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
@ -42,35 +44,14 @@ extern "C" {
|
||||
* @name Timer configuration
|
||||
* @{
|
||||
*/
|
||||
#define TIMER_NUMOF (1U)
|
||||
#define TIMER_0_EN 1
|
||||
#define TIMER_1_EN 0
|
||||
#define TIMER_2_EN 0
|
||||
#define TIMER_IRQ_PRIO 1
|
||||
static const timer_conf_t timer_config[] = {
|
||||
/* dev, channels, width */
|
||||
{ NRF_TIMER0, 3, TIMER_BITMODE_BITMODE_24Bit, TIMER0_IRQn }
|
||||
};
|
||||
|
||||
/* Timer 0 configuration */
|
||||
#define TIMER_0_DEV NRF_TIMER0
|
||||
#define TIMER_0_CHANNELS 3
|
||||
#define TIMER_0_MAX_VALUE (0xffffff)
|
||||
#define TIMER_0_BITMODE TIMER_BITMODE_BITMODE_24Bit
|
||||
#define TIMER_0_ISR isr_timer0
|
||||
#define TIMER_0_IRQ TIMER0_IRQn
|
||||
|
||||
/* Timer 1 configuration */
|
||||
#define TIMER_1_DEV NRF_TIMER1
|
||||
#define TIMER_1_CHANNELS 3
|
||||
#define TIMER_1_MAX_VALUE (0xffff)
|
||||
#define TIMER_1_BITMODE TIMER_BITMODE_BITMODE_16Bit
|
||||
#define TIMER_1_ISR isr_timer1
|
||||
#define TIMER_1_IRQ TIMER1_IRQn
|
||||
|
||||
/* Timer 2 configuration */
|
||||
#define TIMER_2_DEV NRF_TIMER2
|
||||
#define TIMER_2_CHANNELS 3
|
||||
#define TIMER_2_MAX_VALUE (0xffff)
|
||||
#define TIMER_2_BITMODE TIMER_BITMODE_BITMODE_16Bit
|
||||
#define TIMER_2_ISR isr_timer2
|
||||
#define TIMER_2_IRQ TIMER2_IRQn
|
||||
#define TIMER_NUMOF (sizeof(timer_config) / sizeof(timer_config[0]))
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
|
@ -19,6 +19,8 @@
|
||||
#ifndef PERIPH_CONF_H_
|
||||
#define PERIPH_CONF_H_
|
||||
|
||||
#include "periph_cpu.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
@ -40,35 +42,14 @@ extern "C" {
|
||||
* @name Timer configuration
|
||||
* @{
|
||||
*/
|
||||
#define TIMER_NUMOF (1U)
|
||||
#define TIMER_0_EN 1
|
||||
#define TIMER_1_EN 0
|
||||
#define TIMER_2_EN 0
|
||||
#define TIMER_IRQ_PRIO 1
|
||||
static const timer_conf_t timer_config[] = {
|
||||
/* dev, channels, width */
|
||||
{ NRF_TIMER0, 3, TIMER_BITMODE_BITMODE_24Bit, TIMER0_IRQn }
|
||||
};
|
||||
|
||||
/* Timer 0 configuration */
|
||||
#define TIMER_0_DEV NRF_TIMER0
|
||||
#define TIMER_0_CHANNELS 3
|
||||
#define TIMER_0_MAX_VALUE (0xffffff)
|
||||
#define TIMER_0_BITMODE TIMER_BITMODE_BITMODE_24Bit /* only possible value for TIMER0 */
|
||||
#define TIMER_0_ISR isr_timer0
|
||||
#define TIMER_0_IRQ TIMER0_IRQn
|
||||
|
||||
/* Timer 1 configuration */
|
||||
#define TIMER_1_DEV NRF_TIMER1
|
||||
#define TIMER_1_CHANNELS 3
|
||||
#define TIMER_1_MAX_VALUE (0xffff)
|
||||
#define TIMER_1_BITMODE TIMER_BITMODE_BITMODE_16Bit
|
||||
#define TIMER_1_ISR isr_timer1
|
||||
#define TIMER_1_IRQ TIMER1_IRQn
|
||||
|
||||
/* Timer 2 configuration */
|
||||
#define TIMER_2_DEV NRF_TIMER2
|
||||
#define TIMER_2_CHANNELS 3
|
||||
#define TIMER_2_MAX_VALUE (0xffff)
|
||||
#define TIMER_2_BITMODE TIMER_BITMODE_BITMODE_16Bit
|
||||
#define TIMER_2_ISR isr_timer2
|
||||
#define TIMER_2_IRQ TIMER2_IRQn
|
||||
#define TIMER_NUMOF (sizeof(timer_config) / sizeof(timer_config[0]))
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
|
@ -1,336 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2014 Freie Universität Berlin
|
||||
*
|
||||
* 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
|
||||
* details.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @ingroup cpu_nrf51822
|
||||
* @{
|
||||
*
|
||||
* @file
|
||||
* @brief Low-level timer driver implementation
|
||||
*
|
||||
* @author Christian Kühling <kuehling@zedat.fu-berlin.de>
|
||||
* @author Timo Ziegler <timo.ziegler@fu-berlin.de>
|
||||
* @author Hauke Petersen <hauke.petersen@fu-berlin.de>
|
||||
*
|
||||
* @}
|
||||
*/
|
||||
|
||||
#include "cpu.h"
|
||||
#include "board.h"
|
||||
#include "sched.h"
|
||||
#include "thread.h"
|
||||
#include "periph_conf.h"
|
||||
#include "periph/timer.h"
|
||||
|
||||
/**
|
||||
* @name Flags to mark active channels
|
||||
* @{
|
||||
*/
|
||||
#define TIMER_CH0 0x01
|
||||
#define TIMER_CH1 0x02
|
||||
#define TIMER_CH2 0x04
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @brief struct for keeping track of a timer's state
|
||||
*/
|
||||
typedef struct {
|
||||
timer_cb_t cb;
|
||||
void *arg;
|
||||
uint8_t flags;
|
||||
} timer_conf_t;
|
||||
|
||||
/**
|
||||
* @brief timer state memory
|
||||
*/
|
||||
static timer_conf_t timer_config[TIMER_NUMOF];
|
||||
|
||||
/**
|
||||
* @brief static timer mapping
|
||||
*/
|
||||
static NRF_TIMER_Type *const timer[] = {
|
||||
#if TIMER_0_EN
|
||||
TIMER_0_DEV,
|
||||
#endif
|
||||
#if TIMER_1_EN
|
||||
TIMER_1_DEV,
|
||||
#endif
|
||||
#if TIMER_2_EN
|
||||
TIMER_2_DEV
|
||||
#endif
|
||||
};
|
||||
|
||||
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 = cb;
|
||||
timer_config[dev].arg = arg;
|
||||
/* power on timer */
|
||||
timer[dev]->POWER = 1;
|
||||
|
||||
switch (dev) {
|
||||
#if TIMER_0_EN
|
||||
case TIMER_0:
|
||||
TIMER_0_DEV->BITMODE = TIMER_0_BITMODE;
|
||||
NVIC_SetPriority(TIMER_0_IRQ, TIMER_IRQ_PRIO);
|
||||
NVIC_EnableIRQ(TIMER_0_IRQ);
|
||||
break;
|
||||
#endif
|
||||
#if TIMER_1_EN
|
||||
case TIMER_1:
|
||||
TIMER_1_DEV->BITMODE = TIMER_1_BITMODE;
|
||||
NVIC_SetPriority(TIMER_1_IRQ, TIMER_IRQ_PRIO);
|
||||
NVIC_EnableIRQ(TIMER_1_IRQ);
|
||||
break;
|
||||
#endif
|
||||
#if TIMER_2_EN
|
||||
case TIMER_2:
|
||||
TIMER_2_DEV->BITMODE = TIMER_2_BITMODE;
|
||||
NVIC_SetPriority(TIMER_2_IRQ, TIMER_IRQ_PRIO);
|
||||
NVIC_EnableIRQ(TIMER_2_IRQ);
|
||||
break;
|
||||
#endif
|
||||
case TIMER_UNDEFINED:
|
||||
return -1;
|
||||
}
|
||||
|
||||
timer[dev]->TASKS_STOP = 1;
|
||||
timer[dev]->MODE = TIMER_MODE_MODE_Timer; /* set the timer in Timer Mode. */
|
||||
timer[dev]->TASKS_CLEAR = 1; /* clear the task first to be usable for later. */
|
||||
|
||||
switch (freq) {
|
||||
case 125000ul:
|
||||
timer[dev]->PRESCALER = 7;
|
||||
break;
|
||||
case 250000ul:
|
||||
timer[dev]->PRESCALER = 6;
|
||||
break;
|
||||
case 500000ul:
|
||||
timer[dev]->PRESCALER = 5;
|
||||
break;
|
||||
case 1000000ul:
|
||||
timer[dev]->PRESCALER = 4;
|
||||
break;
|
||||
case 2000000ul:
|
||||
timer[dev]->PRESCALER = 3;
|
||||
break;
|
||||
case 4000000ul:
|
||||
timer[dev]->PRESCALER = 2;
|
||||
break;
|
||||
case 8000000ul:
|
||||
timer[dev]->PRESCALER = 1;
|
||||
break;
|
||||
case 16000000ul:
|
||||
timer[dev]->PRESCALER = 0;
|
||||
break;
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* reset compare state */
|
||||
timer[dev]->EVENTS_COMPARE[0] = 0;
|
||||
timer[dev]->EVENTS_COMPARE[1] = 0;
|
||||
timer[dev]->EVENTS_COMPARE[2] = 0;
|
||||
|
||||
/* start the timer */
|
||||
timer[dev]->TASKS_START = 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int timer_set(tim_t dev, int channel, unsigned int timeout)
|
||||
{
|
||||
uint32_t now = timer_read(dev);
|
||||
return timer_set_absolute(dev, channel, (now + timeout - 1));
|
||||
}
|
||||
|
||||
int timer_set_absolute(tim_t dev, int channel, unsigned int value)
|
||||
{
|
||||
if (dev >= TIMER_NUMOF) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
switch (channel) {
|
||||
case 0:
|
||||
timer[dev]->CC[0] = value;
|
||||
timer_config[dev].flags |= TIMER_CH0;
|
||||
timer[dev]->INTENSET |= TIMER_INTENSET_COMPARE0_Msk;
|
||||
break;
|
||||
case 1:
|
||||
timer[dev]->CC[1] = value;
|
||||
timer_config[dev].flags |= TIMER_CH1;
|
||||
timer[dev]->INTENSET |= TIMER_INTENSET_COMPARE1_Msk;
|
||||
break;
|
||||
case 2:
|
||||
timer[dev]->CC[2] = value;
|
||||
timer_config[dev].flags |= TIMER_CH2;
|
||||
timer[dev]->INTENSET |= TIMER_INTENSET_COMPARE2_Msk;
|
||||
break;
|
||||
default:
|
||||
return -2;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int timer_clear(tim_t dev, int channel)
|
||||
{
|
||||
if (dev >= TIMER_NUMOF) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* set timeout value */
|
||||
switch (channel) {
|
||||
case 0:
|
||||
timer_config[dev].flags &= ~TIMER_CH0;
|
||||
timer[dev]->INTENCLR = TIMER_INTENCLR_COMPARE0_Msk;
|
||||
break;
|
||||
case 1:
|
||||
timer_config[dev].flags &= ~TIMER_CH1;
|
||||
timer[dev]->INTENCLR = TIMER_INTENCLR_COMPARE1_Msk;
|
||||
break;
|
||||
case 2:
|
||||
timer_config[dev].flags &= ~TIMER_CH2;
|
||||
timer[dev]->INTENCLR = TIMER_INTENCLR_COMPARE2_Msk;
|
||||
break;
|
||||
default:
|
||||
return -2;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
unsigned int timer_read(tim_t dev)
|
||||
{
|
||||
if (dev >= TIMER_NUMOF) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
timer[dev]->TASKS_CAPTURE[3] = 1;
|
||||
return timer[dev]->CC[3];
|
||||
}
|
||||
|
||||
void timer_start(tim_t dev)
|
||||
{
|
||||
if (dev < TIMER_NUMOF) {
|
||||
timer[dev]->TASKS_START = 1;
|
||||
}
|
||||
}
|
||||
|
||||
void timer_stop(tim_t dev)
|
||||
{
|
||||
if (dev < TIMER_NUMOF) {
|
||||
timer[dev]->TASKS_STOP = 1;
|
||||
}
|
||||
}
|
||||
|
||||
void timer_irq_enable(tim_t dev)
|
||||
{
|
||||
switch (dev) {
|
||||
#if TIMER_0_EN
|
||||
case TIMER_0:
|
||||
NVIC_EnableIRQ(TIMER_0_IRQ);
|
||||
break;
|
||||
#endif
|
||||
#if TIMER_1_EN
|
||||
case TIMER_1:
|
||||
NVIC_EnableIRQ(TIMER_1_IRQ);
|
||||
break;
|
||||
#endif
|
||||
#if TIMER_2_EN
|
||||
case TIMER_2:
|
||||
NVIC_EnableIRQ(TIMER_2_IRQ);
|
||||
break;
|
||||
#endif
|
||||
case TIMER_UNDEFINED:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void timer_irq_disable(tim_t dev)
|
||||
{
|
||||
switch (dev) {
|
||||
#if TIMER_0_EN
|
||||
case TIMER_0:
|
||||
NVIC_DisableIRQ(TIMER_0_IRQ);
|
||||
break;
|
||||
#endif
|
||||
#if TIMER_1_EN
|
||||
case TIMER_1:
|
||||
NVIC_DisableIRQ(TIMER_1_IRQ);
|
||||
break;
|
||||
#endif
|
||||
#if TIMER_2_EN
|
||||
case TIMER_2:
|
||||
NVIC_DisableIRQ(TIMER_2_IRQ);
|
||||
break;
|
||||
#endif
|
||||
case TIMER_UNDEFINED:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
#if TIMER_0_EN
|
||||
void TIMER_0_ISR(void)
|
||||
{
|
||||
for(int i = 0; i < TIMER_0_CHANNELS; i++){
|
||||
if(TIMER_0_DEV->EVENTS_COMPARE[i] == 1){
|
||||
TIMER_0_DEV->EVENTS_COMPARE[i] = 0;
|
||||
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(timer_config[TIMER_0].arg, i);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (sched_context_switch_request) {
|
||||
thread_yield();
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#if TIMER_1_EN
|
||||
void TIMER_1_ISR(void)
|
||||
{
|
||||
for(int i = 0; i < TIMER_1_CHANNELS; i++){
|
||||
if(TIMER_1_DEV->EVENTS_COMPARE[i] == 1){
|
||||
TIMER_1_DEV->EVENTS_COMPARE[i] = 0;
|
||||
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(timer_config[TIMER_1].arg, i);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (sched_context_switch_request) {
|
||||
thread_yield();
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#if TIMER_2_EN
|
||||
void TIMER_2_ISR(void)
|
||||
{
|
||||
for(int i = 0; i < TIMER_2_CHANNELS; i++){
|
||||
if(TIMER_2_DEV->EVENTS_COMPARE[i] == 1){
|
||||
TIMER_2_DEV->EVENTS_COMPARE[i] = 0;
|
||||
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(timer_config[TIMER_2].arg, i);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (sched_context_switch_request) {
|
||||
thread_yield();
|
||||
}
|
||||
}
|
||||
#endif
|
@ -1,364 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2015 Jan Wagner <mail@jwagner.eu>
|
||||
* 2016 Freie Universität Berlin
|
||||
*
|
||||
* 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 details.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @ingroup cpu_nrf52
|
||||
* @{
|
||||
*
|
||||
* @file
|
||||
* @brief Implementation of the peripheral timer interface
|
||||
*
|
||||
* @author Hauke Petersen <hauke.petersen@fu-berlin.de>
|
||||
* @author Jan Wagner <mail@jwagner.eu>
|
||||
*
|
||||
* @}
|
||||
*/
|
||||
|
||||
#include "cpu.h"
|
||||
#include "board.h"
|
||||
#include "sched.h"
|
||||
#include "thread.h"
|
||||
#include "periph_conf.h"
|
||||
#include "periph/timer.h"
|
||||
|
||||
/**
|
||||
* @name Flags to mark active channels
|
||||
* @{
|
||||
*/
|
||||
#define TIMER_CH0 0x01
|
||||
#define TIMER_CH1 0x02
|
||||
#define TIMER_CH2 0x04
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @brief struct for keeping track of a timer's state
|
||||
*/
|
||||
typedef struct {
|
||||
timer_cb_t cb;
|
||||
void *arg;
|
||||
uint8_t flags;
|
||||
} timer_conf_t;
|
||||
|
||||
/**
|
||||
* @brief timer state memory
|
||||
*/
|
||||
static timer_conf_t timer_config[TIMER_NUMOF];
|
||||
|
||||
/**
|
||||
* @brief static timer mapping
|
||||
*/
|
||||
static NRF_TIMER_Type *const timer[] = {
|
||||
#if TIMER_0_EN
|
||||
TIMER_0_DEV,
|
||||
#endif
|
||||
#if TIMER_1_EN
|
||||
TIMER_1_DEV,
|
||||
#endif
|
||||
#if TIMER_2_EN
|
||||
TIMER_2_DEV
|
||||
#endif
|
||||
};
|
||||
|
||||
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 = cb;
|
||||
timer_config[dev].arg = arg;
|
||||
/* power on timer */
|
||||
/* timer[dev]->POWER = 1; */
|
||||
|
||||
switch (dev) {
|
||||
#if TIMER_0_EN
|
||||
|
||||
case TIMER_0:
|
||||
TIMER_0_DEV->BITMODE = TIMER_0_BITMODE;
|
||||
NVIC_EnableIRQ(TIMER_0_IRQ);
|
||||
break;
|
||||
#endif
|
||||
#if TIMER_1_EN
|
||||
|
||||
case TIMER_1:
|
||||
TIMER_1_DEV->BITMODE = TIEMR_1_BITMODE;
|
||||
NVIC_EnableIRQ(TIMER_1_IRQ);
|
||||
break;
|
||||
#endif
|
||||
#if TIMER_2_EN
|
||||
|
||||
case TIMER_2:
|
||||
TIMER_2_DEV->BITMODE = TIMER_2_BITMODE;
|
||||
NVIC_EnableIRQ(TIMER_2_IRQ);
|
||||
break;
|
||||
#endif
|
||||
|
||||
case TIMER_UNDEFINED:
|
||||
return -1;
|
||||
}
|
||||
|
||||
timer[dev]->TASKS_STOP = 1;
|
||||
timer[dev]->MODE = TIMER_MODE_MODE_Timer; /* set the timer in Timer Mode. */
|
||||
timer[dev]->TASKS_CLEAR = 1; /* clear the task first to be usable for later. */
|
||||
|
||||
switch (freq) {
|
||||
case 125000ul:
|
||||
timer[dev]->PRESCALER = 7;
|
||||
break;
|
||||
case 250000ul:
|
||||
timer[dev]->PRESCALER = 6;
|
||||
break;
|
||||
case 500000ul:
|
||||
timer[dev]->PRESCALER = 5;
|
||||
break;
|
||||
case 1000000ul:
|
||||
timer[dev]->PRESCALER = 4;
|
||||
break;
|
||||
case 2000000ul:
|
||||
timer[dev]->PRESCALER = 3;
|
||||
break;
|
||||
case 4000000ul:
|
||||
timer[dev]->PRESCALER = 2;
|
||||
break;
|
||||
case 8000000ul:
|
||||
timer[dev]->PRESCALER = 1;
|
||||
break;
|
||||
case 16000000ul:
|
||||
timer[dev]->PRESCALER = 0;
|
||||
break;
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* reset compare state */
|
||||
timer[dev]->EVENTS_COMPARE[0] = 0;
|
||||
timer[dev]->EVENTS_COMPARE[1] = 0;
|
||||
timer[dev]->EVENTS_COMPARE[2] = 0;
|
||||
|
||||
/* start the timer */
|
||||
timer[dev]->TASKS_START = 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int timer_set(tim_t dev, int channel, unsigned int timeout)
|
||||
{
|
||||
uint32_t now = timer_read(dev);
|
||||
return timer_set_absolute(dev, channel, (now + timeout - 1));
|
||||
}
|
||||
|
||||
int timer_set_absolute(tim_t dev, int channel, unsigned int value)
|
||||
{
|
||||
if (dev >= TIMER_NUMOF) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
switch (channel) {
|
||||
case 0:
|
||||
timer[dev]->CC[0] = value;
|
||||
timer_config[dev].flags |= TIMER_CH0;
|
||||
timer[dev]->INTENSET |= TIMER_INTENSET_COMPARE0_Msk;
|
||||
break;
|
||||
|
||||
case 1:
|
||||
timer[dev]->CC[1] = value;
|
||||
timer_config[dev].flags |= TIMER_CH1;
|
||||
timer[dev]->INTENSET |= TIMER_INTENSET_COMPARE1_Msk;
|
||||
break;
|
||||
|
||||
case 2:
|
||||
timer[dev]->CC[2] = value;
|
||||
timer_config[dev].flags |= TIMER_CH2;
|
||||
timer[dev]->INTENSET |= TIMER_INTENSET_COMPARE2_Msk;
|
||||
break;
|
||||
|
||||
default:
|
||||
return -2;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int timer_clear(tim_t dev, int channel)
|
||||
{
|
||||
if (dev >= TIMER_NUMOF) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* set timeout value */
|
||||
switch (channel) {
|
||||
case 0:
|
||||
timer_config[dev].flags &= ~TIMER_CH0;
|
||||
timer[dev]->INTENCLR = TIMER_INTENCLR_COMPARE0_Msk;
|
||||
break;
|
||||
|
||||
case 1:
|
||||
timer_config[dev].flags &= ~TIMER_CH1;
|
||||
timer[dev]->INTENCLR = TIMER_INTENCLR_COMPARE1_Msk;
|
||||
break;
|
||||
|
||||
case 2:
|
||||
timer_config[dev].flags &= ~TIMER_CH2;
|
||||
timer[dev]->INTENCLR = TIMER_INTENCLR_COMPARE2_Msk;
|
||||
break;
|
||||
|
||||
default:
|
||||
return -2;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
unsigned int timer_read(tim_t dev)
|
||||
{
|
||||
if (dev >= TIMER_NUMOF) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
timer[dev]->TASKS_CAPTURE[3] = 1;
|
||||
return timer[dev]->CC[3];
|
||||
}
|
||||
|
||||
void timer_start(tim_t dev)
|
||||
{
|
||||
if (dev < TIMER_NUMOF) {
|
||||
timer[dev]->TASKS_START = 1;
|
||||
}
|
||||
}
|
||||
|
||||
void timer_stop(tim_t dev)
|
||||
{
|
||||
if (dev < TIMER_NUMOF) {
|
||||
timer[dev]->TASKS_STOP = 1;
|
||||
}
|
||||
}
|
||||
|
||||
void timer_irq_enable(tim_t dev)
|
||||
{
|
||||
switch (dev) {
|
||||
#if TIMER_0_EN
|
||||
|
||||
case TIMER_0:
|
||||
NVIC_EnableIRQ(TIMER_0_IRQ);
|
||||
break;
|
||||
#endif
|
||||
#if TIMER_1_EN
|
||||
|
||||
case TIMER_1:
|
||||
NVIC_EnableIRQ(TIMER_1_IRQ);
|
||||
break;
|
||||
#endif
|
||||
#if TIMER_2_EN
|
||||
|
||||
case TIMER_2:
|
||||
NVIC_EnableIRQ(TIMER_2_IRQ);
|
||||
break;
|
||||
#endif
|
||||
|
||||
case TIMER_UNDEFINED:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void timer_irq_disable(tim_t dev)
|
||||
{
|
||||
switch (dev) {
|
||||
#if TIMER_0_EN
|
||||
|
||||
case TIMER_0:
|
||||
NVIC_DisableIRQ(TIMER_0_IRQ);
|
||||
break;
|
||||
#endif
|
||||
#if TIMER_1_EN
|
||||
|
||||
case TIMER_1:
|
||||
NVIC_DisableIRQ(TIMER_1_IRQ);
|
||||
break;
|
||||
#endif
|
||||
#if TIMER_2_EN
|
||||
|
||||
case TIMER_2:
|
||||
NVIC_DisableIRQ(TIMER_2_IRQ);
|
||||
break;
|
||||
#endif
|
||||
|
||||
case TIMER_UNDEFINED:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void timer_reset(tim_t dev)
|
||||
{
|
||||
if (dev < TIMER_NUMOF) {
|
||||
timer[dev]->TASKS_CLEAR = 1;
|
||||
}
|
||||
}
|
||||
|
||||
#if TIMER_0_EN
|
||||
void TIMER_0_ISR(void)
|
||||
{
|
||||
for (int i = 0; i < TIMER_0_CHANNELS; i++) {
|
||||
if (TIMER_0_DEV->EVENTS_COMPARE[i] == 1) {
|
||||
TIMER_0_DEV->EVENTS_COMPARE[i] = 0;
|
||||
|
||||
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(timer_config[TIMER_0].arg, i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (sched_context_switch_request) {
|
||||
thread_yield();
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#if TIMER_1_EN
|
||||
void TIMER_1_ISR(void)
|
||||
{
|
||||
for (int i = 0; i < TIMER_1_CHANNELS; i++) {
|
||||
if (TIMER_1_DEV->EVENTS_COMPARE[i] == 1) {
|
||||
TIMER_1_DEV->EVENTS_COMPARE[i] = 0;
|
||||
|
||||
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(timer_config[TIMER_1].arg, i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (sched_context_switch_request) {
|
||||
thread_yield();
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#if TIMER_2_EN
|
||||
void TIMER_2_ISR(void)
|
||||
{
|
||||
for (int i = 0; i < TIMER_2_CHANNELS; i++) {
|
||||
if (TIMER_2_DEV->EVENTS_COMPARE[i] == 1) {
|
||||
TIMER_2_DEV->EVENTS_COMPARE[i] = 0;
|
||||
|
||||
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(timer_config[TIMER_2].arg, i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (sched_context_switch_request) {
|
||||
thread_yield();
|
||||
}
|
||||
}
|
||||
#endif
|
@ -77,6 +77,16 @@ typedef enum {
|
||||
} gpio_flank_t;
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @brief Timer configuration options
|
||||
*/
|
||||
typedef struct {
|
||||
NRF_TIMER_Type *dev;
|
||||
uint8_t channels;
|
||||
uint8_t bitmode;
|
||||
uint8_t irqn;
|
||||
} timer_conf_t;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
191
cpu/nrf5x_common/periph/timer.c
Normal file
191
cpu/nrf5x_common/periph/timer.c
Normal file
@ -0,0 +1,191 @@
|
||||
/*
|
||||
* Copyright (C) 2014-2016 Freie Universität Berlin
|
||||
* 2015 Jan Wagner <mail@jwagner.eu>
|
||||
*
|
||||
* 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 details.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @ingroup cpu_nrf5x_common
|
||||
* @{
|
||||
*
|
||||
* @file
|
||||
* @brief Implementation of the peripheral timer interface
|
||||
*
|
||||
* @author Christian Kühling <kuehling@zedat.fu-berlin.de>
|
||||
* @author Timo Ziegler <timo.ziegler@fu-berlin.de>
|
||||
* @author Hauke Petersen <hauke.petersen@fu-berlin.de>
|
||||
* @author Jan Wagner <mail@jwagner.eu>
|
||||
*
|
||||
* @}
|
||||
*/
|
||||
|
||||
#include "sched.h"
|
||||
#include "thread.h"
|
||||
#include "periph/timer.h"
|
||||
|
||||
#define F_TIMER (16000000U) /* the timer is clocked at 16MHz */
|
||||
|
||||
typedef struct {
|
||||
timer_cb_t cb;
|
||||
void *arg;
|
||||
uint8_t flags;
|
||||
} tim_ctx_t;
|
||||
|
||||
/**
|
||||
* @brief timer state memory
|
||||
*/
|
||||
static tim_ctx_t ctx[TIMER_NUMOF];
|
||||
|
||||
static inline NRF_TIMER_Type *dev(tim_t tim)
|
||||
{
|
||||
return timer_config[tim].dev;
|
||||
}
|
||||
|
||||
int timer_init(tim_t tim, unsigned long freq, timer_cb_t cb, void *arg)
|
||||
{
|
||||
/* make sure the given timer is valid */
|
||||
if (tim >= TIMER_NUMOF) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* save interrupt context */
|
||||
ctx[tim].cb = cb;
|
||||
ctx[tim].arg = arg;
|
||||
|
||||
/* power on timer */
|
||||
#if CPU_FAM_NRF51
|
||||
dev(tim)->POWER = 1;
|
||||
#endif
|
||||
|
||||
/* reset and configure the timer */
|
||||
dev(tim)->TASKS_STOP = 1;
|
||||
dev(tim)->BITMODE = timer_config[tim].bitmode;
|
||||
dev(tim)->MODE = TIMER_MODE_MODE_Timer;
|
||||
dev(tim)->TASKS_CLEAR = 1;
|
||||
|
||||
/* figure out if desired frequency is available */
|
||||
int i;
|
||||
unsigned long cando = F_TIMER;
|
||||
for (i = 0; i < 10; i++) {
|
||||
if (freq == cando) {
|
||||
dev(tim)->PRESCALER = i;
|
||||
break;
|
||||
}
|
||||
cando /= 2;
|
||||
}
|
||||
if (i == 10) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* reset compare state */
|
||||
dev(tim)->EVENTS_COMPARE[0] = 0;
|
||||
dev(tim)->EVENTS_COMPARE[1] = 0;
|
||||
dev(tim)->EVENTS_COMPARE[2] = 0;
|
||||
|
||||
/* enable interrupts */
|
||||
timer_irq_enable(tim);
|
||||
/* start the timer */
|
||||
dev(tim)->TASKS_START = 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int timer_set(tim_t tim, int chan, unsigned int value)
|
||||
{
|
||||
uint32_t now = timer_read(tim);
|
||||
return timer_set_absolute(tim, chan, (now + value));
|
||||
}
|
||||
|
||||
int timer_set_absolute(tim_t tim, int chan, unsigned int value)
|
||||
{
|
||||
/* see if channel is valid */
|
||||
if (chan >= timer_config[tim].channels) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
ctx[tim].flags |= (1 << chan);
|
||||
dev(tim)->CC[chan] = value;
|
||||
dev(tim)->INTENSET = (TIMER_INTENSET_COMPARE0_Msk << chan);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int timer_clear(tim_t tim, int chan)
|
||||
{
|
||||
/* see if channel is valid */
|
||||
if (chan >= timer_config[tim].channels) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
dev(tim)->INTENCLR = (TIMER_INTENSET_COMPARE0_Msk << chan);
|
||||
ctx[tim].flags &= ~(1 << chan);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
unsigned int timer_read(tim_t tim)
|
||||
{
|
||||
dev(tim)->TASKS_CAPTURE[timer_config[tim].channels] = 1;
|
||||
return dev(tim)->CC[timer_config[tim].channels];
|
||||
}
|
||||
|
||||
void timer_start(tim_t tim)
|
||||
{
|
||||
dev(tim)->TASKS_START = 1;
|
||||
}
|
||||
|
||||
void timer_stop(tim_t tim)
|
||||
{
|
||||
dev(tim)->TASKS_STOP = 1;
|
||||
}
|
||||
|
||||
void timer_irq_enable(tim_t tim)
|
||||
{
|
||||
NVIC_EnableIRQ(timer_config[tim].irqn);
|
||||
}
|
||||
|
||||
void timer_irq_disable(tim_t tim)
|
||||
{
|
||||
NVIC_DisableIRQ(timer_config[tim].irqn);
|
||||
}
|
||||
|
||||
static inline void irq_handler(int num)
|
||||
{
|
||||
for (unsigned i = 0; i < timer_config[num].channels; i++) {
|
||||
if (dev(num)->EVENTS_COMPARE[i] == 1) {
|
||||
dev(num)->EVENTS_COMPARE[i] = 0;
|
||||
if (ctx[num].flags & (1 << i)) {
|
||||
ctx[num].flags &= ~(1 << i);
|
||||
dev(num)->INTENCLR = (TIMER_INTENSET_COMPARE0_Msk << i);
|
||||
ctx[num].cb(ctx[num].arg, i);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (sched_context_switch_request) {
|
||||
thread_yield();
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef TIMER_0_ISR
|
||||
void TIMER_0_ISR(void)
|
||||
{
|
||||
irq_handler(0);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef TIMER_1_ISR
|
||||
void TIMER_1_ISR(void)
|
||||
{
|
||||
irq_handler(1);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef TIMER_2_ISR
|
||||
void TIMER_2_ISR(void)
|
||||
{
|
||||
irq_handler(2);
|
||||
}
|
||||
#endif
|
Loading…
Reference in New Issue
Block a user