2015-01-06 00:19:24 +01:00
|
|
|
/*
|
2016-03-20 19:39:53 +01:00
|
|
|
* Copyright (C) 2016 Eistec AB
|
2015-01-06 00:19:24 +01:00
|
|
|
* Copyright (C) 2014 Freie Universität Berlin
|
2015-10-03 12:44:11 +02:00
|
|
|
* Copyright (C) 2014-2015 PHYTEC Messtechnik GmbH
|
2015-01-06 00:19:24 +01:00
|
|
|
*
|
|
|
|
* 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.
|
|
|
|
*/
|
|
|
|
|
|
|
|
/**
|
2017-10-27 01:26:26 +02:00
|
|
|
* @ingroup cpu_kinetis
|
2017-06-22 15:43:17 +02:00
|
|
|
* @ingroup drivers_periph_timer
|
2015-01-06 00:19:24 +01:00
|
|
|
*
|
|
|
|
* @{
|
|
|
|
*
|
|
|
|
* @file
|
|
|
|
* @brief Low-level timer driver implementation
|
|
|
|
*
|
|
|
|
* @author Hauke Petersen <hauke.petersen@fu-berlin.de>
|
|
|
|
* @author Johann Fischer <j.fischer@phytec.de>
|
2016-03-20 19:39:53 +01:00
|
|
|
* @author Joakim Nohlgård <joakim.nohlgard@eistec.se>
|
2015-01-06 00:19:24 +01:00
|
|
|
*
|
|
|
|
* @}
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include <stdlib.h>
|
|
|
|
|
2017-04-15 14:57:02 +02:00
|
|
|
#include "bit.h"
|
2023-05-03 18:03:33 +02:00
|
|
|
#include "bitarithm.h"
|
2015-01-06 00:19:24 +01:00
|
|
|
#include "board.h"
|
2023-05-03 18:03:33 +02:00
|
|
|
#include "cpu.h"
|
|
|
|
#include "macros/utils.h"
|
2015-01-06 00:19:24 +01:00
|
|
|
#include "periph/timer.h"
|
2023-05-03 18:03:33 +02:00
|
|
|
#include "periph_conf.h"
|
2015-01-06 00:19:24 +01:00
|
|
|
|
2017-03-24 14:48:39 +01:00
|
|
|
#ifdef PIT_LTMR64H_LTH_MASK
|
|
|
|
/* The KW41Z PIT module provides only one IRQ for all PIT channels combined. */
|
|
|
|
/* TODO: find a better way to distinguish which Kinetis CPUs have separate PIT
|
|
|
|
* channel interrupts */
|
|
|
|
#define KINETIS_PIT_COMBINED_IRQ 1
|
|
|
|
#else
|
|
|
|
/* K60, K64F etc have a separate IRQ number for each PIT channel */
|
|
|
|
#define KINETIS_PIT_COMBINED_IRQ 0
|
|
|
|
#endif
|
|
|
|
|
2020-10-22 11:34:00 +02:00
|
|
|
#define ENABLE_DEBUG 0
|
2015-01-06 00:19:24 +01:00
|
|
|
#include "debug.h"
|
|
|
|
|
2016-03-20 19:39:53 +01:00
|
|
|
#define PIT_MAX_VALUE (PIT_LDVAL_TSV_MASK >> PIT_LDVAL_TSV_SHIFT)
|
|
|
|
#define LPTMR_MAX_VALUE (LPTMR_CNR_COUNTER_MASK >> LPTMR_CNR_COUNTER_SHIFT)
|
2015-01-06 00:19:24 +01:00
|
|
|
|
2016-03-20 19:39:53 +01:00
|
|
|
#if TIMER_NUMOF != (PIT_NUMOF + LPTMR_NUMOF)
|
|
|
|
#error TIMER_NUMOF should be the total of PIT and LPTMR timers in the system
|
|
|
|
#endif
|
2015-01-06 00:19:24 +01:00
|
|
|
|
2021-01-08 12:00:57 +01:00
|
|
|
#if defined(KINETIS_HAVE_LPTMR) && LPTMR_NUMOF > 0
|
|
|
|
#define KINETIS_BOARD_HAVE_CONFIGURED_LPTMR
|
|
|
|
#endif
|
|
|
|
|
2016-03-20 19:39:53 +01:00
|
|
|
/**
|
|
|
|
* @brief The number of ticks that will be lost when setting a new target in the LPTMR
|
|
|
|
*
|
|
|
|
* The counter will otherwise drop ticks when setting new timeouts.
|
|
|
|
*/
|
2018-03-03 08:44:05 +01:00
|
|
|
#define LPTMR_RELOAD_OVERHEAD 1
|
2016-03-20 19:39:53 +01:00
|
|
|
|
|
|
|
/* PIT channel state */
|
|
|
|
typedef struct {
|
|
|
|
timer_isr_ctx_t isr_ctx;
|
|
|
|
uint32_t count;
|
|
|
|
uint32_t tctrl;
|
|
|
|
uint32_t ldval;
|
|
|
|
} pit_t;
|
|
|
|
|
2021-01-08 12:00:57 +01:00
|
|
|
#ifdef KINETIS_BOARD_HAVE_CONFIGURED_LPTMR
|
2016-03-20 19:39:53 +01:00
|
|
|
/* LPTMR state */
|
|
|
|
typedef struct {
|
|
|
|
timer_isr_ctx_t isr_ctx;
|
2018-03-03 08:44:05 +01:00
|
|
|
uint32_t cnr;
|
2016-03-20 19:39:53 +01:00
|
|
|
uint32_t cmr;
|
|
|
|
uint32_t running;
|
|
|
|
} lptmr_t;
|
2018-07-31 18:08:07 +02:00
|
|
|
#endif
|
2016-03-20 19:39:53 +01:00
|
|
|
|
|
|
|
static const pit_conf_t pit_config[PIT_NUMOF] = PIT_CONFIG;
|
2021-01-08 12:00:57 +01:00
|
|
|
#ifdef KINETIS_BOARD_HAVE_CONFIGURED_LPTMR
|
2016-03-20 19:39:53 +01:00
|
|
|
static const lptmr_conf_t lptmr_config[LPTMR_NUMOF] = LPTMR_CONFIG;
|
2018-07-31 18:08:07 +02:00
|
|
|
#endif
|
2016-03-20 19:39:53 +01:00
|
|
|
|
|
|
|
static pit_t pit[PIT_NUMOF];
|
2021-01-08 12:00:57 +01:00
|
|
|
#ifdef KINETIS_BOARD_HAVE_CONFIGURED_LPTMR
|
2016-03-20 19:39:53 +01:00
|
|
|
static lptmr_t lptmr[LPTMR_NUMOF];
|
2018-07-31 18:08:07 +02:00
|
|
|
#endif
|
2016-03-20 19:39:53 +01:00
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief Find out whether a given timer is a LPTMR or a PIT timer
|
|
|
|
*/
|
2018-07-31 18:08:07 +02:00
|
|
|
static inline unsigned int _timer_variant(tim_t dev)
|
|
|
|
{
|
2021-01-08 12:00:57 +01:00
|
|
|
#ifdef KINETIS_BOARD_HAVE_CONFIGURED_LPTMR
|
2016-03-20 19:39:53 +01:00
|
|
|
if ((unsigned int) dev >= PIT_NUMOF) {
|
|
|
|
return TIMER_LPTMR;
|
|
|
|
}
|
2018-07-31 18:08:07 +02:00
|
|
|
else
|
|
|
|
#endif
|
|
|
|
{
|
|
|
|
(void) dev;
|
2016-03-20 19:39:53 +01:00
|
|
|
return TIMER_PIT;
|
|
|
|
}
|
2015-01-06 00:19:24 +01:00
|
|
|
}
|
|
|
|
|
2016-03-20 19:39:53 +01:00
|
|
|
/**
|
|
|
|
* @brief Find device index in the pit_config array
|
|
|
|
*/
|
2018-07-31 18:08:07 +02:00
|
|
|
static inline unsigned int _pit_index(tim_t dev)
|
|
|
|
{
|
2016-03-20 19:39:53 +01:00
|
|
|
return ((unsigned int)dev) - TIMER_DEV(0);
|
2015-01-06 00:19:24 +01:00
|
|
|
}
|
|
|
|
|
2016-03-20 19:39:53 +01:00
|
|
|
/**
|
|
|
|
* @brief Get TIMER_x enum value from PIT device index
|
|
|
|
*/
|
2018-07-31 18:08:07 +02:00
|
|
|
static inline tim_t _pit_tim_t(uint8_t dev)
|
|
|
|
{
|
2016-03-20 19:39:53 +01:00
|
|
|
return (tim_t)(((unsigned int)TIMER_DEV(0)) + dev);
|
|
|
|
}
|
|
|
|
|
2021-01-08 12:00:57 +01:00
|
|
|
#ifdef KINETIS_BOARD_HAVE_CONFIGURED_LPTMR
|
2016-03-20 19:39:53 +01:00
|
|
|
/**
|
|
|
|
* @brief Find device index in the lptmr_config array
|
|
|
|
*/
|
2018-07-31 18:08:07 +02:00
|
|
|
static inline unsigned int _lptmr_index(tim_t dev)
|
|
|
|
{
|
2016-03-20 19:39:53 +01:00
|
|
|
return ((unsigned int)dev) - TIMER_DEV(0) - PIT_NUMOF;
|
2015-01-06 00:19:24 +01:00
|
|
|
}
|
|
|
|
|
2018-08-13 18:37:39 +02:00
|
|
|
#if defined(LPTMR_ISR_0) || defined(LPTMR_ISR_1)
|
2016-03-20 19:39:53 +01:00
|
|
|
/**
|
|
|
|
* @brief Get TIMER_x enum value from LPTMR device index
|
|
|
|
*/
|
2018-07-31 18:08:07 +02:00
|
|
|
static inline tim_t _lptmr_tim_t(uint8_t dev)
|
|
|
|
{
|
2016-03-20 19:39:53 +01:00
|
|
|
return (tim_t)(((unsigned int)TIMER_DEV(0)) + PIT_NUMOF + dev);
|
|
|
|
}
|
2018-08-13 18:37:39 +02:00
|
|
|
#endif /* defined(LPTMR_ISR_0) || defined(LPTMR_ISR_1) */
|
2021-01-08 12:00:57 +01:00
|
|
|
#endif /* KINETIS_BOARD_HAVE_CONFIGURED_LPTMR */
|
2016-03-20 19:39:53 +01:00
|
|
|
|
|
|
|
/* ****** PIT module functions ****** */
|
|
|
|
|
|
|
|
/* Forward declarations */
|
make: fix various compile errors with Wextra
pkg, nordic_softdevice_ble: disable CFLAGS to omit compiler error
sys, pm_layered: fix casting nonscalar to the same type
cpu, stm32_common: fix type-limits, remove always true assert
cpu, stm32f4: fix pointer arithmetic in periph/i2c
drivers, at86rf2xx: fix type-limits where condition always true
saul, gpio: fix if no gpio configured for saul
cpu, saml21: add frequency check to periph/timer
driver, cc110x: fix unused param and type-limts errors
boards, wsn430-common: fix old-style-declaration
make: fix old style definition
drivers, sdcard_spi: fix old style typedef
driver, at30tse: remove unnecessary check
driver, nrf24: fix type-limit
driver, pn532: change buffer from char to uint8_t
tests/driver_sdcard: fix type limits
boards, feather-m0: add missing field inits
driver, tcs37727: fix type limits
pkg, emb6: disable some compiler warnings
tests/emb6: disable some compiler warings
pkg, openthread: fix sign compare and unused params
tests/trickle: fix struct init
tests/pthread_cooperation: fix type limits
board, mips-malta: remove feature periph_uart
shell: fix var size for netif command
gnrc, netif: fix sign-compare
gnrc, nib: fix sign-compare
shell: fix output in netif command
posix: fix type-limits in pthread_cond
2017-10-31 11:52:18 +01:00
|
|
|
static inline int pit_init(uint8_t dev, uint32_t freq, timer_cb_t cb, void *arg);
|
|
|
|
static inline int pit_set(uint8_t dev, uint32_t timeout);
|
|
|
|
static inline int pit_set_absolute(uint8_t dev, uint32_t target);
|
|
|
|
static inline int pit_clear(uint8_t dev);
|
|
|
|
static inline uint32_t pit_read(uint8_t dev);
|
|
|
|
static inline void pit_start(uint8_t dev);
|
|
|
|
static inline void pit_stop(uint8_t dev);
|
|
|
|
static inline void pit_irq_handler(tim_t dev);
|
|
|
|
|
|
|
|
static inline int pit_init(uint8_t dev, uint32_t freq, timer_cb_t cb, void *arg)
|
2015-01-06 00:19:24 +01:00
|
|
|
{
|
2017-04-15 14:57:02 +02:00
|
|
|
/* Turn on module clock gate */
|
|
|
|
PIT_CLKEN();
|
2016-03-20 19:39:53 +01:00
|
|
|
/* Completely disable the module before messing with the settings */
|
|
|
|
PIT->MCR = PIT_MCR_MDIS_MASK;
|
2015-01-06 00:19:24 +01:00
|
|
|
|
2016-03-20 19:39:53 +01:00
|
|
|
/* Disable IRQs to avoid race with ISR */
|
|
|
|
unsigned int mask = irq_disable();
|
2018-04-04 09:41:26 +02:00
|
|
|
uint8_t count_ch = pit_config[dev].count_ch;
|
2016-03-20 19:39:53 +01:00
|
|
|
/* Clear configuration */
|
2018-04-04 09:41:26 +02:00
|
|
|
PIT->CHANNEL[count_ch].TCTRL = 0;
|
2015-01-06 00:19:24 +01:00
|
|
|
|
2016-03-20 19:39:53 +01:00
|
|
|
/* Freeze timers during debug break, resume normal operations (clear MDIS) */
|
|
|
|
PIT->MCR = PIT_MCR_FRZ_MASK;
|
2015-01-06 00:19:24 +01:00
|
|
|
|
2018-04-04 09:41:26 +02:00
|
|
|
/* set callback function */
|
|
|
|
pit[dev].isr_ctx.cb = cb;
|
|
|
|
pit[dev].isr_ctx.arg = arg;
|
2015-01-06 00:19:24 +01:00
|
|
|
|
2016-03-20 19:39:53 +01:00
|
|
|
/* Clear IRQ flag */
|
2018-04-04 09:41:26 +02:00
|
|
|
PIT->CHANNEL[count_ch].TFLG = PIT_TFLG_TIF_MASK;
|
2017-03-24 14:48:39 +01:00
|
|
|
#if KINETIS_PIT_COMBINED_IRQ
|
|
|
|
/* One IRQ for all channels */
|
|
|
|
/* NVIC_ClearPendingIRQ(PIT_IRQn); */ /* does it make sense to clear this IRQ flag? */
|
|
|
|
NVIC_EnableIRQ(PIT_IRQn);
|
|
|
|
#else
|
2016-03-20 19:39:53 +01:00
|
|
|
/* Refactor the below lines if there are any CPUs where the PIT IRQs are not sequential */
|
2018-04-04 09:41:26 +02:00
|
|
|
NVIC_ClearPendingIRQ(PIT0_IRQn + count_ch);
|
|
|
|
NVIC_EnableIRQ(PIT0_IRQn + count_ch);
|
2017-03-24 14:48:39 +01:00
|
|
|
#endif
|
2016-03-20 19:39:53 +01:00
|
|
|
/* Reset up-counter */
|
|
|
|
pit[dev].count = PIT_MAX_VALUE;
|
2018-04-04 09:41:26 +02:00
|
|
|
PIT->CHANNEL[count_ch].LDVAL = PIT_MAX_VALUE;
|
|
|
|
/* Disable prescaler channel */
|
|
|
|
PIT->CHANNEL[pit_config[dev].prescaler_ch].TCTRL = 0x0;
|
|
|
|
/* Load prescaler value */
|
|
|
|
PIT->CHANNEL[pit_config[dev].prescaler_ch].LDVAL = (PIT_BASECLOCK / freq) - 1;
|
|
|
|
/* Start the prescaler counter */
|
|
|
|
PIT->CHANNEL[pit_config[dev].prescaler_ch].TCTRL = (PIT_TCTRL_TEN_MASK);
|
|
|
|
PIT->CHANNEL[count_ch].TCTRL = PIT_TCTRL_CHN_MASK | PIT_TCTRL_TEN_MASK;
|
2015-01-06 00:19:24 +01:00
|
|
|
|
2016-03-20 19:39:53 +01:00
|
|
|
irq_restore(mask);
|
|
|
|
return 0;
|
|
|
|
}
|
2015-01-06 00:19:24 +01:00
|
|
|
|
make: fix various compile errors with Wextra
pkg, nordic_softdevice_ble: disable CFLAGS to omit compiler error
sys, pm_layered: fix casting nonscalar to the same type
cpu, stm32_common: fix type-limits, remove always true assert
cpu, stm32f4: fix pointer arithmetic in periph/i2c
drivers, at86rf2xx: fix type-limits where condition always true
saul, gpio: fix if no gpio configured for saul
cpu, saml21: add frequency check to periph/timer
driver, cc110x: fix unused param and type-limts errors
boards, wsn430-common: fix old-style-declaration
make: fix old style definition
drivers, sdcard_spi: fix old style typedef
driver, at30tse: remove unnecessary check
driver, nrf24: fix type-limit
driver, pn532: change buffer from char to uint8_t
tests/driver_sdcard: fix type limits
boards, feather-m0: add missing field inits
driver, tcs37727: fix type limits
pkg, emb6: disable some compiler warnings
tests/emb6: disable some compiler warings
pkg, openthread: fix sign compare and unused params
tests/trickle: fix struct init
tests/pthread_cooperation: fix type limits
board, mips-malta: remove feature periph_uart
shell: fix var size for netif command
gnrc, netif: fix sign-compare
gnrc, nib: fix sign-compare
shell: fix output in netif command
posix: fix type-limits in pthread_cond
2017-10-31 11:52:18 +01:00
|
|
|
static inline int pit_set(uint8_t dev, uint32_t timeout)
|
2016-03-20 19:39:53 +01:00
|
|
|
{
|
|
|
|
const uint8_t ch = pit_config[dev].count_ch;
|
|
|
|
/* Disable IRQs to minimize the number of lost ticks */
|
|
|
|
unsigned int mask = irq_disable();
|
2018-04-04 09:41:26 +02:00
|
|
|
/* Subtract if there was anything left on the counter */
|
|
|
|
pit[dev].count -= PIT->CHANNEL[ch].CVAL;
|
|
|
|
/* Set new timeout */
|
|
|
|
PIT->CHANNEL[ch].TCTRL = 0;
|
|
|
|
PIT->CHANNEL[ch].LDVAL = timeout;
|
|
|
|
PIT->CHANNEL[ch].TFLG = PIT_TFLG_TIF_MASK;
|
|
|
|
PIT->CHANNEL[ch].TCTRL = PIT_TCTRL_TIE_MASK | PIT_TCTRL_CHN_MASK | PIT_TCTRL_TEN_MASK;
|
2016-03-20 19:39:53 +01:00
|
|
|
/* Add the new timeout offset to the up-counter */
|
|
|
|
pit[dev].count += timeout;
|
2018-04-04 09:41:26 +02:00
|
|
|
/* Set the timer to reload the maximum value to be able to count the number
|
|
|
|
* of overflow ticks inside the ISR */
|
|
|
|
PIT->CHANNEL[ch].LDVAL = PIT_MAX_VALUE;
|
2016-03-20 19:39:53 +01:00
|
|
|
irq_restore(mask);
|
|
|
|
return 0;
|
|
|
|
}
|
2015-01-06 00:19:24 +01:00
|
|
|
|
make: fix various compile errors with Wextra
pkg, nordic_softdevice_ble: disable CFLAGS to omit compiler error
sys, pm_layered: fix casting nonscalar to the same type
cpu, stm32_common: fix type-limits, remove always true assert
cpu, stm32f4: fix pointer arithmetic in periph/i2c
drivers, at86rf2xx: fix type-limits where condition always true
saul, gpio: fix if no gpio configured for saul
cpu, saml21: add frequency check to periph/timer
driver, cc110x: fix unused param and type-limts errors
boards, wsn430-common: fix old-style-declaration
make: fix old style definition
drivers, sdcard_spi: fix old style typedef
driver, at30tse: remove unnecessary check
driver, nrf24: fix type-limit
driver, pn532: change buffer from char to uint8_t
tests/driver_sdcard: fix type limits
boards, feather-m0: add missing field inits
driver, tcs37727: fix type limits
pkg, emb6: disable some compiler warnings
tests/emb6: disable some compiler warings
pkg, openthread: fix sign compare and unused params
tests/trickle: fix struct init
tests/pthread_cooperation: fix type limits
board, mips-malta: remove feature periph_uart
shell: fix var size for netif command
gnrc, netif: fix sign-compare
gnrc, nib: fix sign-compare
shell: fix output in netif command
posix: fix type-limits in pthread_cond
2017-10-31 11:52:18 +01:00
|
|
|
static inline int pit_set_absolute(uint8_t dev, uint32_t target)
|
2016-03-20 19:39:53 +01:00
|
|
|
{
|
|
|
|
uint8_t ch = pit_config[dev].count_ch;
|
|
|
|
/* Disable IRQs to minimize the number of lost ticks */
|
|
|
|
unsigned int mask = irq_disable();
|
2018-04-04 09:41:26 +02:00
|
|
|
uint32_t now = pit[dev].count - PIT->CHANNEL[ch].CVAL;
|
2016-03-20 19:39:53 +01:00
|
|
|
uint32_t offset = target - now;
|
2018-07-31 18:08:07 +02:00
|
|
|
|
2018-04-04 09:41:26 +02:00
|
|
|
/* Set new timeout */
|
|
|
|
PIT->CHANNEL[ch].TCTRL = 0;
|
|
|
|
PIT->CHANNEL[ch].LDVAL = offset;
|
|
|
|
PIT->CHANNEL[ch].TFLG = PIT_TFLG_TIF_MASK;
|
|
|
|
PIT->CHANNEL[ch].TCTRL = PIT_TCTRL_TIE_MASK | PIT_TCTRL_CHN_MASK | PIT_TCTRL_TEN_MASK;
|
2016-03-20 19:39:53 +01:00
|
|
|
/* Set the new target time in the up-counter */
|
|
|
|
pit[dev].count = target;
|
2018-04-04 09:41:26 +02:00
|
|
|
/* Set the timer to reload the maximum value to be able to count the number
|
|
|
|
* of overflow ticks inside the ISR */
|
|
|
|
PIT->CHANNEL[ch].LDVAL = PIT_MAX_VALUE;
|
2016-03-20 19:39:53 +01:00
|
|
|
irq_restore(mask);
|
2015-01-06 00:19:24 +01:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
make: fix various compile errors with Wextra
pkg, nordic_softdevice_ble: disable CFLAGS to omit compiler error
sys, pm_layered: fix casting nonscalar to the same type
cpu, stm32_common: fix type-limits, remove always true assert
cpu, stm32f4: fix pointer arithmetic in periph/i2c
drivers, at86rf2xx: fix type-limits where condition always true
saul, gpio: fix if no gpio configured for saul
cpu, saml21: add frequency check to periph/timer
driver, cc110x: fix unused param and type-limts errors
boards, wsn430-common: fix old-style-declaration
make: fix old style definition
drivers, sdcard_spi: fix old style typedef
driver, at30tse: remove unnecessary check
driver, nrf24: fix type-limit
driver, pn532: change buffer from char to uint8_t
tests/driver_sdcard: fix type limits
boards, feather-m0: add missing field inits
driver, tcs37727: fix type limits
pkg, emb6: disable some compiler warnings
tests/emb6: disable some compiler warings
pkg, openthread: fix sign compare and unused params
tests/trickle: fix struct init
tests/pthread_cooperation: fix type limits
board, mips-malta: remove feature periph_uart
shell: fix var size for netif command
gnrc, netif: fix sign-compare
gnrc, nib: fix sign-compare
shell: fix output in netif command
posix: fix type-limits in pthread_cond
2017-10-31 11:52:18 +01:00
|
|
|
static inline int pit_clear(uint8_t dev)
|
2015-01-06 00:19:24 +01:00
|
|
|
{
|
2016-03-20 19:39:53 +01:00
|
|
|
uint8_t ch = pit_config[dev].count_ch;
|
|
|
|
/* Disable IRQs to minimize the number of lost ticks */
|
|
|
|
unsigned int mask = irq_disable();
|
2018-07-31 18:08:07 +02:00
|
|
|
|
2018-03-29 21:01:21 +02:00
|
|
|
/* Subtract if there was anything left on the counter */
|
2018-04-04 09:41:26 +02:00
|
|
|
pit[dev].count -= PIT->CHANNEL[ch].CVAL;
|
|
|
|
/* No need to add PIT_MAX_VALUE + 1 to the counter because of modulo 2**32 */
|
|
|
|
/* Set a long timeout */
|
|
|
|
PIT->CHANNEL[ch].TCTRL = 0;
|
|
|
|
PIT->CHANNEL[ch].LDVAL = PIT_MAX_VALUE;
|
|
|
|
PIT->CHANNEL[ch].TFLG = PIT_TFLG_TIF_MASK;
|
|
|
|
PIT->CHANNEL[ch].TCTRL = PIT_TCTRL_CHN_MASK | PIT_TCTRL_TEN_MASK;
|
2016-03-20 19:39:53 +01:00
|
|
|
irq_restore(mask);
|
|
|
|
return 0;
|
2015-01-06 00:19:24 +01:00
|
|
|
}
|
|
|
|
|
2018-04-04 09:41:26 +02:00
|
|
|
/* CVAL is unreliable if the timer is not enabled (TCTRL_TEN bit clear),
|
|
|
|
* by stopping the prescaler instead of the counter channel we avoid this issue,
|
|
|
|
* and additionally do not need to worry about saving the control registers or
|
|
|
|
* recomputing the target time when starting the timer */
|
make: fix various compile errors with Wextra
pkg, nordic_softdevice_ble: disable CFLAGS to omit compiler error
sys, pm_layered: fix casting nonscalar to the same type
cpu, stm32_common: fix type-limits, remove always true assert
cpu, stm32f4: fix pointer arithmetic in periph/i2c
drivers, at86rf2xx: fix type-limits where condition always true
saul, gpio: fix if no gpio configured for saul
cpu, saml21: add frequency check to periph/timer
driver, cc110x: fix unused param and type-limts errors
boards, wsn430-common: fix old-style-declaration
make: fix old style definition
drivers, sdcard_spi: fix old style typedef
driver, at30tse: remove unnecessary check
driver, nrf24: fix type-limit
driver, pn532: change buffer from char to uint8_t
tests/driver_sdcard: fix type limits
boards, feather-m0: add missing field inits
driver, tcs37727: fix type limits
pkg, emb6: disable some compiler warnings
tests/emb6: disable some compiler warings
pkg, openthread: fix sign compare and unused params
tests/trickle: fix struct init
tests/pthread_cooperation: fix type limits
board, mips-malta: remove feature periph_uart
shell: fix var size for netif command
gnrc, netif: fix sign-compare
gnrc, nib: fix sign-compare
shell: fix output in netif command
posix: fix type-limits in pthread_cond
2017-10-31 11:52:18 +01:00
|
|
|
static inline uint32_t pit_read(uint8_t dev)
|
2015-01-06 00:19:24 +01:00
|
|
|
{
|
2016-03-20 19:39:53 +01:00
|
|
|
uint8_t ch = pit_config[dev].count_ch;
|
2018-07-31 18:08:07 +02:00
|
|
|
|
2018-03-29 21:01:21 +02:00
|
|
|
return pit[dev].count - PIT->CHANNEL[ch].CVAL;
|
2016-03-20 19:39:53 +01:00
|
|
|
}
|
2015-10-19 17:23:12 +02:00
|
|
|
|
make: fix various compile errors with Wextra
pkg, nordic_softdevice_ble: disable CFLAGS to omit compiler error
sys, pm_layered: fix casting nonscalar to the same type
cpu, stm32_common: fix type-limits, remove always true assert
cpu, stm32f4: fix pointer arithmetic in periph/i2c
drivers, at86rf2xx: fix type-limits where condition always true
saul, gpio: fix if no gpio configured for saul
cpu, saml21: add frequency check to periph/timer
driver, cc110x: fix unused param and type-limts errors
boards, wsn430-common: fix old-style-declaration
make: fix old style definition
drivers, sdcard_spi: fix old style typedef
driver, at30tse: remove unnecessary check
driver, nrf24: fix type-limit
driver, pn532: change buffer from char to uint8_t
tests/driver_sdcard: fix type limits
boards, feather-m0: add missing field inits
driver, tcs37727: fix type limits
pkg, emb6: disable some compiler warnings
tests/emb6: disable some compiler warings
pkg, openthread: fix sign compare and unused params
tests/trickle: fix struct init
tests/pthread_cooperation: fix type limits
board, mips-malta: remove feature periph_uart
shell: fix var size for netif command
gnrc, netif: fix sign-compare
gnrc, nib: fix sign-compare
shell: fix output in netif command
posix: fix type-limits in pthread_cond
2017-10-31 11:52:18 +01:00
|
|
|
static inline void pit_start(uint8_t dev)
|
2016-03-20 19:39:53 +01:00
|
|
|
{
|
2018-04-04 09:41:26 +02:00
|
|
|
uint8_t ch = pit_config[dev].prescaler_ch;
|
2018-07-31 18:08:07 +02:00
|
|
|
|
2018-04-04 09:41:26 +02:00
|
|
|
PIT->CHANNEL[ch].TCTRL = PIT_TCTRL_TEN_MASK;
|
2016-03-20 19:39:53 +01:00
|
|
|
}
|
2015-01-06 00:19:24 +01:00
|
|
|
|
make: fix various compile errors with Wextra
pkg, nordic_softdevice_ble: disable CFLAGS to omit compiler error
sys, pm_layered: fix casting nonscalar to the same type
cpu, stm32_common: fix type-limits, remove always true assert
cpu, stm32f4: fix pointer arithmetic in periph/i2c
drivers, at86rf2xx: fix type-limits where condition always true
saul, gpio: fix if no gpio configured for saul
cpu, saml21: add frequency check to periph/timer
driver, cc110x: fix unused param and type-limts errors
boards, wsn430-common: fix old-style-declaration
make: fix old style definition
drivers, sdcard_spi: fix old style typedef
driver, at30tse: remove unnecessary check
driver, nrf24: fix type-limit
driver, pn532: change buffer from char to uint8_t
tests/driver_sdcard: fix type limits
boards, feather-m0: add missing field inits
driver, tcs37727: fix type limits
pkg, emb6: disable some compiler warnings
tests/emb6: disable some compiler warings
pkg, openthread: fix sign compare and unused params
tests/trickle: fix struct init
tests/pthread_cooperation: fix type limits
board, mips-malta: remove feature periph_uart
shell: fix var size for netif command
gnrc, netif: fix sign-compare
gnrc, nib: fix sign-compare
shell: fix output in netif command
posix: fix type-limits in pthread_cond
2017-10-31 11:52:18 +01:00
|
|
|
static inline void pit_stop(uint8_t dev)
|
2016-03-20 19:39:53 +01:00
|
|
|
{
|
2018-04-04 09:41:26 +02:00
|
|
|
uint8_t ch = pit_config[dev].prescaler_ch;
|
2018-07-31 18:08:07 +02:00
|
|
|
|
2016-03-20 19:39:53 +01:00
|
|
|
PIT->CHANNEL[ch].TCTRL = 0;
|
|
|
|
}
|
2015-01-06 00:19:24 +01:00
|
|
|
|
make: fix various compile errors with Wextra
pkg, nordic_softdevice_ble: disable CFLAGS to omit compiler error
sys, pm_layered: fix casting nonscalar to the same type
cpu, stm32_common: fix type-limits, remove always true assert
cpu, stm32f4: fix pointer arithmetic in periph/i2c
drivers, at86rf2xx: fix type-limits where condition always true
saul, gpio: fix if no gpio configured for saul
cpu, saml21: add frequency check to periph/timer
driver, cc110x: fix unused param and type-limts errors
boards, wsn430-common: fix old-style-declaration
make: fix old style definition
drivers, sdcard_spi: fix old style typedef
driver, at30tse: remove unnecessary check
driver, nrf24: fix type-limit
driver, pn532: change buffer from char to uint8_t
tests/driver_sdcard: fix type limits
boards, feather-m0: add missing field inits
driver, tcs37727: fix type limits
pkg, emb6: disable some compiler warnings
tests/emb6: disable some compiler warings
pkg, openthread: fix sign compare and unused params
tests/trickle: fix struct init
tests/pthread_cooperation: fix type limits
board, mips-malta: remove feature periph_uart
shell: fix var size for netif command
gnrc, netif: fix sign-compare
gnrc, nib: fix sign-compare
shell: fix output in netif command
posix: fix type-limits in pthread_cond
2017-10-31 11:52:18 +01:00
|
|
|
static inline void pit_irq_handler(tim_t dev)
|
2016-03-20 19:39:53 +01:00
|
|
|
{
|
|
|
|
uint8_t ch = pit_config[_pit_index(dev)].count_ch;
|
|
|
|
pit_t *pit_ctx = &pit[_pit_index(dev)];
|
2018-07-31 18:08:07 +02:00
|
|
|
|
2018-04-04 09:41:26 +02:00
|
|
|
if (!PIT->CHANNEL[ch].TFLG) {
|
|
|
|
DEBUG("PIT%u!TFLG\n", (unsigned)dev);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
/* Add the overflow amount to the counter before resetting */
|
|
|
|
/* (this may be > 0 if the IRQ handler was delayed e.g. by irq_disable etc.) */
|
|
|
|
pit_ctx->count += PIT->CHANNEL[ch].LDVAL - PIT->CHANNEL[ch].CVAL;
|
|
|
|
/* inline pit_clear */
|
|
|
|
PIT->CHANNEL[ch].TCTRL = 0;
|
|
|
|
PIT->CHANNEL[ch].LDVAL = PIT_MAX_VALUE;
|
|
|
|
PIT->CHANNEL[ch].TFLG = PIT_TFLG_TIF_MASK;
|
|
|
|
PIT->CHANNEL[ch].TCTRL = PIT_TCTRL_CHN_MASK | PIT_TCTRL_TEN_MASK;
|
2016-03-20 19:39:53 +01:00
|
|
|
|
|
|
|
if (pit_ctx->isr_ctx.cb != NULL) {
|
|
|
|
pit_ctx->isr_ctx.cb(pit_ctx->isr_ctx.arg, 0);
|
2015-01-06 00:19:24 +01:00
|
|
|
}
|
|
|
|
|
2016-11-30 18:26:05 +01:00
|
|
|
cortexm_isr_end();
|
2015-01-06 00:19:24 +01:00
|
|
|
}
|
|
|
|
|
2021-01-08 12:00:57 +01:00
|
|
|
#ifdef KINETIS_BOARD_HAVE_CONFIGURED_LPTMR
|
2016-03-20 19:39:53 +01:00
|
|
|
/* ****** LPTMR module functions ****** */
|
|
|
|
|
|
|
|
/* Forward declarations */
|
make: fix various compile errors with Wextra
pkg, nordic_softdevice_ble: disable CFLAGS to omit compiler error
sys, pm_layered: fix casting nonscalar to the same type
cpu, stm32_common: fix type-limits, remove always true assert
cpu, stm32f4: fix pointer arithmetic in periph/i2c
drivers, at86rf2xx: fix type-limits where condition always true
saul, gpio: fix if no gpio configured for saul
cpu, saml21: add frequency check to periph/timer
driver, cc110x: fix unused param and type-limts errors
boards, wsn430-common: fix old-style-declaration
make: fix old style definition
drivers, sdcard_spi: fix old style typedef
driver, at30tse: remove unnecessary check
driver, nrf24: fix type-limit
driver, pn532: change buffer from char to uint8_t
tests/driver_sdcard: fix type limits
boards, feather-m0: add missing field inits
driver, tcs37727: fix type limits
pkg, emb6: disable some compiler warnings
tests/emb6: disable some compiler warings
pkg, openthread: fix sign compare and unused params
tests/trickle: fix struct init
tests/pthread_cooperation: fix type limits
board, mips-malta: remove feature periph_uart
shell: fix var size for netif command
gnrc, netif: fix sign-compare
gnrc, nib: fix sign-compare
shell: fix output in netif command
posix: fix type-limits in pthread_cond
2017-10-31 11:52:18 +01:00
|
|
|
static inline int lptmr_init(uint8_t dev, uint32_t freq, timer_cb_t cb, void *arg);
|
|
|
|
static inline int lptmr_set(uint8_t dev, uint16_t timeout);
|
|
|
|
static inline int lptmr_set_absolute(uint8_t dev, uint16_t target);
|
|
|
|
static inline int lptmr_clear(uint8_t dev);
|
|
|
|
static inline uint16_t lptmr_read(uint8_t dev);
|
|
|
|
static inline void lptmr_start(uint8_t dev);
|
|
|
|
static inline void lptmr_stop(uint8_t dev);
|
2018-08-13 18:37:39 +02:00
|
|
|
#if defined(LPTMR_ISR_0) || defined(LPTMR_ISR_1)
|
make: fix various compile errors with Wextra
pkg, nordic_softdevice_ble: disable CFLAGS to omit compiler error
sys, pm_layered: fix casting nonscalar to the same type
cpu, stm32_common: fix type-limits, remove always true assert
cpu, stm32f4: fix pointer arithmetic in periph/i2c
drivers, at86rf2xx: fix type-limits where condition always true
saul, gpio: fix if no gpio configured for saul
cpu, saml21: add frequency check to periph/timer
driver, cc110x: fix unused param and type-limts errors
boards, wsn430-common: fix old-style-declaration
make: fix old style definition
drivers, sdcard_spi: fix old style typedef
driver, at30tse: remove unnecessary check
driver, nrf24: fix type-limit
driver, pn532: change buffer from char to uint8_t
tests/driver_sdcard: fix type limits
boards, feather-m0: add missing field inits
driver, tcs37727: fix type limits
pkg, emb6: disable some compiler warnings
tests/emb6: disable some compiler warings
pkg, openthread: fix sign compare and unused params
tests/trickle: fix struct init
tests/pthread_cooperation: fix type limits
board, mips-malta: remove feature periph_uart
shell: fix var size for netif command
gnrc, netif: fix sign-compare
gnrc, nib: fix sign-compare
shell: fix output in netif command
posix: fix type-limits in pthread_cond
2017-10-31 11:52:18 +01:00
|
|
|
static inline void lptmr_irq_handler(tim_t tim);
|
2018-08-13 18:37:39 +02:00
|
|
|
#endif
|
2016-03-20 19:39:53 +01:00
|
|
|
|
make: fix various compile errors with Wextra
pkg, nordic_softdevice_ble: disable CFLAGS to omit compiler error
sys, pm_layered: fix casting nonscalar to the same type
cpu, stm32_common: fix type-limits, remove always true assert
cpu, stm32f4: fix pointer arithmetic in periph/i2c
drivers, at86rf2xx: fix type-limits where condition always true
saul, gpio: fix if no gpio configured for saul
cpu, saml21: add frequency check to periph/timer
driver, cc110x: fix unused param and type-limts errors
boards, wsn430-common: fix old-style-declaration
make: fix old style definition
drivers, sdcard_spi: fix old style typedef
driver, at30tse: remove unnecessary check
driver, nrf24: fix type-limit
driver, pn532: change buffer from char to uint8_t
tests/driver_sdcard: fix type limits
boards, feather-m0: add missing field inits
driver, tcs37727: fix type limits
pkg, emb6: disable some compiler warnings
tests/emb6: disable some compiler warings
pkg, openthread: fix sign compare and unused params
tests/trickle: fix struct init
tests/pthread_cooperation: fix type limits
board, mips-malta: remove feature periph_uart
shell: fix var size for netif command
gnrc, netif: fix sign-compare
gnrc, nib: fix sign-compare
shell: fix output in netif command
posix: fix type-limits in pthread_cond
2017-10-31 11:52:18 +01:00
|
|
|
static inline void _lptmr_set_cb_config(uint8_t dev, timer_cb_t cb, void *arg)
|
2015-01-06 00:19:24 +01:00
|
|
|
{
|
2016-03-20 19:39:53 +01:00
|
|
|
/* set callback function */
|
|
|
|
lptmr[dev].isr_ctx.cb = cb;
|
|
|
|
lptmr[dev].isr_ctx.arg = arg;
|
|
|
|
}
|
2015-01-06 00:19:24 +01:00
|
|
|
|
2016-03-20 19:39:53 +01:00
|
|
|
/**
|
|
|
|
* @brief Compute the LPTMR prescaler setting, see reference manual for details
|
|
|
|
*/
|
2018-07-31 18:08:07 +02:00
|
|
|
static inline int32_t _lptmr_compute_prescaler(uint8_t dev, uint32_t freq)
|
|
|
|
{
|
2016-03-20 19:39:53 +01:00
|
|
|
uint32_t prescale = 0;
|
2018-07-31 18:08:07 +02:00
|
|
|
|
2018-03-03 08:44:05 +01:00
|
|
|
if ((freq > lptmr_config[dev].base_freq) || (freq == 0)) {
|
2016-03-20 19:39:53 +01:00
|
|
|
/* Frequency out of range */
|
|
|
|
return -1;
|
|
|
|
}
|
2018-07-31 18:08:07 +02:00
|
|
|
while (freq < lptmr_config[dev].base_freq) {
|
2016-03-20 19:39:53 +01:00
|
|
|
++prescale;
|
|
|
|
freq <<= 1;
|
|
|
|
}
|
2018-03-03 08:44:05 +01:00
|
|
|
if (freq != lptmr_config[dev].base_freq) {
|
|
|
|
/* freq was not a power of two division of base_freq */
|
2016-03-20 19:39:53 +01:00
|
|
|
return -2;
|
|
|
|
}
|
2018-03-03 08:44:05 +01:00
|
|
|
if (prescale == 0) {
|
2016-03-20 19:39:53 +01:00
|
|
|
/* Prescaler bypass enabled */
|
|
|
|
return LPTMR_PSR_PBYP_MASK;
|
|
|
|
}
|
2018-03-03 08:44:05 +01:00
|
|
|
/* LPTMR_PSR_PRESCALE == 0 yields base_freq / 2,
|
|
|
|
* LPTMR_PSR_PRESCALE == 1 yields base_freq / 4 etc.. */
|
|
|
|
return LPTMR_PSR_PRESCALE(prescale - 1);
|
2016-03-20 19:39:53 +01:00
|
|
|
}
|
2015-01-06 00:19:24 +01:00
|
|
|
|
make: fix various compile errors with Wextra
pkg, nordic_softdevice_ble: disable CFLAGS to omit compiler error
sys, pm_layered: fix casting nonscalar to the same type
cpu, stm32_common: fix type-limits, remove always true assert
cpu, stm32f4: fix pointer arithmetic in periph/i2c
drivers, at86rf2xx: fix type-limits where condition always true
saul, gpio: fix if no gpio configured for saul
cpu, saml21: add frequency check to periph/timer
driver, cc110x: fix unused param and type-limts errors
boards, wsn430-common: fix old-style-declaration
make: fix old style definition
drivers, sdcard_spi: fix old style typedef
driver, at30tse: remove unnecessary check
driver, nrf24: fix type-limit
driver, pn532: change buffer from char to uint8_t
tests/driver_sdcard: fix type limits
boards, feather-m0: add missing field inits
driver, tcs37727: fix type limits
pkg, emb6: disable some compiler warnings
tests/emb6: disable some compiler warings
pkg, openthread: fix sign compare and unused params
tests/trickle: fix struct init
tests/pthread_cooperation: fix type limits
board, mips-malta: remove feature periph_uart
shell: fix var size for netif command
gnrc, netif: fix sign-compare
gnrc, nib: fix sign-compare
shell: fix output in netif command
posix: fix type-limits in pthread_cond
2017-10-31 11:52:18 +01:00
|
|
|
static inline int lptmr_init(uint8_t dev, uint32_t freq, timer_cb_t cb, void *arg)
|
2016-03-20 19:39:53 +01:00
|
|
|
{
|
2018-03-03 08:44:05 +01:00
|
|
|
int32_t prescale = _lptmr_compute_prescaler(dev, freq);
|
2018-07-31 18:08:07 +02:00
|
|
|
|
2016-03-20 19:39:53 +01:00
|
|
|
if (prescale < 0) {
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
LPTMR_Type *hw = lptmr_config[dev].dev;
|
|
|
|
/* Disable IRQs to avoid race with ISR */
|
|
|
|
unsigned int mask = irq_disable();
|
2015-01-06 00:19:24 +01:00
|
|
|
|
2016-03-20 19:39:53 +01:00
|
|
|
/* Turn on module clock */
|
2017-04-15 14:57:02 +02:00
|
|
|
LPTMR_CLKEN();
|
2018-03-03 08:44:05 +01:00
|
|
|
|
2016-03-20 19:39:53 +01:00
|
|
|
/* Completely disable the module before messing with the settings */
|
|
|
|
hw->CSR = 0;
|
2015-01-06 00:19:24 +01:00
|
|
|
|
2018-03-03 08:44:05 +01:00
|
|
|
/* select clock source and configure prescaler */
|
|
|
|
hw->PSR = LPTMR_PSR_PCS(lptmr_config[dev].src) | ((uint32_t)prescale);
|
|
|
|
|
2016-03-20 19:39:53 +01:00
|
|
|
/* Enable IRQs on the counting channel */
|
2017-04-15 14:57:02 +02:00
|
|
|
NVIC_ClearPendingIRQ(lptmr_config[dev].irqn);
|
|
|
|
NVIC_EnableIRQ(lptmr_config[dev].irqn);
|
2016-03-20 19:39:53 +01:00
|
|
|
|
|
|
|
_lptmr_set_cb_config(dev, cb, arg);
|
|
|
|
|
|
|
|
/* Reset state */
|
|
|
|
lptmr[dev].running = 1;
|
2018-03-03 08:44:05 +01:00
|
|
|
lptmr[dev].cnr = 0;
|
|
|
|
lptmr[dev].cmr = 0;
|
|
|
|
hw->CMR = 0;
|
|
|
|
hw->CSR = LPTMR_CSR_TEN_MASK | LPTMR_CSR_TFC_MASK;
|
2016-03-20 19:39:53 +01:00
|
|
|
|
|
|
|
irq_restore(mask);
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
make: fix various compile errors with Wextra
pkg, nordic_softdevice_ble: disable CFLAGS to omit compiler error
sys, pm_layered: fix casting nonscalar to the same type
cpu, stm32_common: fix type-limits, remove always true assert
cpu, stm32f4: fix pointer arithmetic in periph/i2c
drivers, at86rf2xx: fix type-limits where condition always true
saul, gpio: fix if no gpio configured for saul
cpu, saml21: add frequency check to periph/timer
driver, cc110x: fix unused param and type-limts errors
boards, wsn430-common: fix old-style-declaration
make: fix old style definition
drivers, sdcard_spi: fix old style typedef
driver, at30tse: remove unnecessary check
driver, nrf24: fix type-limit
driver, pn532: change buffer from char to uint8_t
tests/driver_sdcard: fix type limits
boards, feather-m0: add missing field inits
driver, tcs37727: fix type limits
pkg, emb6: disable some compiler warnings
tests/emb6: disable some compiler warings
pkg, openthread: fix sign compare and unused params
tests/trickle: fix struct init
tests/pthread_cooperation: fix type limits
board, mips-malta: remove feature periph_uart
shell: fix var size for netif command
gnrc, netif: fix sign-compare
gnrc, nib: fix sign-compare
shell: fix output in netif command
posix: fix type-limits in pthread_cond
2017-10-31 11:52:18 +01:00
|
|
|
static inline uint16_t lptmr_read(uint8_t dev)
|
2016-03-20 19:39:53 +01:00
|
|
|
{
|
|
|
|
LPTMR_Type *hw = lptmr_config[dev].dev;
|
2018-07-31 18:08:07 +02:00
|
|
|
|
2016-03-20 19:39:53 +01:00
|
|
|
/* latch the current timer value into CNR */
|
|
|
|
hw->CNR = 0;
|
2018-03-03 08:44:05 +01:00
|
|
|
return lptmr[dev].cnr + hw->CNR;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
2018-09-22 07:29:42 +02:00
|
|
|
* @brief Reload the timer with the given timeout
|
2018-03-03 08:44:05 +01:00
|
|
|
*
|
|
|
|
* @pre IRQs masked, timer running
|
|
|
|
*/
|
2018-09-22 07:29:42 +02:00
|
|
|
static inline void lptmr_reload(uint8_t dev, uint16_t timeout)
|
2018-03-03 08:44:05 +01:00
|
|
|
{
|
|
|
|
LPTMR_Type *hw = lptmr_config[dev].dev;
|
2018-07-31 18:08:07 +02:00
|
|
|
|
2018-03-03 08:44:05 +01:00
|
|
|
/* Disable timer and set target, 1 to 2 ticks will be dropped by the
|
|
|
|
* hardware during the disable-enable cycle */
|
|
|
|
/* Disable the timer interrupt first */
|
|
|
|
hw->CSR = LPTMR_CSR_TEN_MASK | LPTMR_CSR_TFC_MASK;
|
2018-09-22 07:29:42 +02:00
|
|
|
if (timeout >= LPTMR_RELOAD_OVERHEAD) {
|
|
|
|
timeout -= LPTMR_RELOAD_OVERHEAD;
|
2018-03-03 08:44:05 +01:00
|
|
|
}
|
|
|
|
/* Update reference */
|
|
|
|
hw->CNR = 0;
|
|
|
|
lptmr[dev].cnr += hw->CNR + LPTMR_RELOAD_OVERHEAD;
|
|
|
|
/* Disable timer */
|
|
|
|
hw->CSR = 0;
|
2018-09-22 07:29:42 +02:00
|
|
|
hw->CMR = timeout;
|
2018-03-03 08:44:05 +01:00
|
|
|
/* Enable timer and IRQ */
|
|
|
|
hw->CSR = LPTMR_CSR_TEN_MASK | LPTMR_CSR_TFC_MASK | LPTMR_CSR_TIE_MASK;
|
2016-03-20 19:39:53 +01:00
|
|
|
}
|
|
|
|
|
make: fix various compile errors with Wextra
pkg, nordic_softdevice_ble: disable CFLAGS to omit compiler error
sys, pm_layered: fix casting nonscalar to the same type
cpu, stm32_common: fix type-limits, remove always true assert
cpu, stm32f4: fix pointer arithmetic in periph/i2c
drivers, at86rf2xx: fix type-limits where condition always true
saul, gpio: fix if no gpio configured for saul
cpu, saml21: add frequency check to periph/timer
driver, cc110x: fix unused param and type-limts errors
boards, wsn430-common: fix old-style-declaration
make: fix old style definition
drivers, sdcard_spi: fix old style typedef
driver, at30tse: remove unnecessary check
driver, nrf24: fix type-limit
driver, pn532: change buffer from char to uint8_t
tests/driver_sdcard: fix type limits
boards, feather-m0: add missing field inits
driver, tcs37727: fix type limits
pkg, emb6: disable some compiler warnings
tests/emb6: disable some compiler warings
pkg, openthread: fix sign compare and unused params
tests/trickle: fix struct init
tests/pthread_cooperation: fix type limits
board, mips-malta: remove feature periph_uart
shell: fix var size for netif command
gnrc, netif: fix sign-compare
gnrc, nib: fix sign-compare
shell: fix output in netif command
posix: fix type-limits in pthread_cond
2017-10-31 11:52:18 +01:00
|
|
|
static inline int lptmr_set(uint8_t dev, uint16_t timeout)
|
2016-03-20 19:39:53 +01:00
|
|
|
{
|
2018-03-03 08:44:05 +01:00
|
|
|
LPTMR_Type *hw = lptmr_config[dev].dev;
|
2016-03-20 19:39:53 +01:00
|
|
|
/* Disable IRQs to minimize jitter */
|
|
|
|
unsigned int mask = irq_disable();
|
2018-07-31 18:08:07 +02:00
|
|
|
|
2018-03-03 08:44:05 +01:00
|
|
|
lptmr[dev].running = 1;
|
|
|
|
if (!(hw->CSR & LPTMR_CSR_TEN_MASK)) {
|
|
|
|
/* Timer is stopped, only update target */
|
|
|
|
if (timeout > LPTMR_RELOAD_OVERHEAD) {
|
|
|
|
/* Compensate for the reload delay */
|
|
|
|
lptmr[dev].cmr = timeout - LPTMR_RELOAD_OVERHEAD;
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
lptmr[dev].cmr = 0;
|
|
|
|
}
|
|
|
|
}
|
2018-09-22 07:29:42 +02:00
|
|
|
else if ((timeout > 0) && (hw->CSR & LPTMR_CSR_TCF_MASK)) {
|
2018-03-03 08:44:05 +01:00
|
|
|
/* TCF is set, safe to update CMR live */
|
|
|
|
hw->CNR = 0;
|
|
|
|
hw->CMR = timeout + hw->CNR;
|
|
|
|
/* cppcheck-suppress selfAssignment
|
2018-09-21 10:34:29 +02:00
|
|
|
* (reason: intentional self assignment to clear all pending IRQs) */
|
2018-03-03 08:44:05 +01:00
|
|
|
hw->CSR = hw->CSR;
|
|
|
|
/* Enable timer and IRQ */
|
|
|
|
hw->CSR = LPTMR_CSR_TEN_MASK | LPTMR_CSR_TFC_MASK | LPTMR_CSR_TIE_MASK;
|
|
|
|
}
|
|
|
|
else {
|
2018-09-22 07:29:42 +02:00
|
|
|
lptmr_reload(dev, timeout);
|
2015-01-06 00:19:24 +01:00
|
|
|
}
|
2016-03-20 19:39:53 +01:00
|
|
|
irq_restore(mask);
|
2019-09-11 13:46:15 +02:00
|
|
|
return 0;
|
2015-01-06 00:19:24 +01:00
|
|
|
}
|
|
|
|
|
make: fix various compile errors with Wextra
pkg, nordic_softdevice_ble: disable CFLAGS to omit compiler error
sys, pm_layered: fix casting nonscalar to the same type
cpu, stm32_common: fix type-limits, remove always true assert
cpu, stm32f4: fix pointer arithmetic in periph/i2c
drivers, at86rf2xx: fix type-limits where condition always true
saul, gpio: fix if no gpio configured for saul
cpu, saml21: add frequency check to periph/timer
driver, cc110x: fix unused param and type-limts errors
boards, wsn430-common: fix old-style-declaration
make: fix old style definition
drivers, sdcard_spi: fix old style typedef
driver, at30tse: remove unnecessary check
driver, nrf24: fix type-limit
driver, pn532: change buffer from char to uint8_t
tests/driver_sdcard: fix type limits
boards, feather-m0: add missing field inits
driver, tcs37727: fix type limits
pkg, emb6: disable some compiler warnings
tests/emb6: disable some compiler warings
pkg, openthread: fix sign compare and unused params
tests/trickle: fix struct init
tests/pthread_cooperation: fix type limits
board, mips-malta: remove feature periph_uart
shell: fix var size for netif command
gnrc, netif: fix sign-compare
gnrc, nib: fix sign-compare
shell: fix output in netif command
posix: fix type-limits in pthread_cond
2017-10-31 11:52:18 +01:00
|
|
|
static inline int lptmr_set_absolute(uint8_t dev, uint16_t target)
|
2015-01-06 00:19:24 +01:00
|
|
|
{
|
2018-03-03 08:44:05 +01:00
|
|
|
LPTMR_Type *hw = lptmr_config[dev].dev;
|
2016-03-20 19:39:53 +01:00
|
|
|
/* Disable IRQs to minimize jitter */
|
|
|
|
unsigned int mask = irq_disable();
|
2018-07-31 18:08:07 +02:00
|
|
|
|
2018-03-03 08:44:05 +01:00
|
|
|
lptmr[dev].running = 1;
|
|
|
|
if (!(hw->CSR & LPTMR_CSR_TEN_MASK)) {
|
|
|
|
/* Timer is stopped, only update target */
|
|
|
|
uint16_t timeout = target - lptmr[dev].cnr;
|
|
|
|
if (timeout > LPTMR_RELOAD_OVERHEAD) {
|
|
|
|
/* Compensate for the reload delay */
|
|
|
|
lptmr[dev].cmr = timeout - LPTMR_RELOAD_OVERHEAD;
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
lptmr[dev].cmr = 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else if (hw->CSR & LPTMR_CSR_TCF_MASK) {
|
|
|
|
/* TCF is set, safe to update CMR live */
|
|
|
|
hw->CMR = target - lptmr[dev].cnr;
|
|
|
|
/* cppcheck-suppress selfAssignment
|
2018-09-21 10:34:29 +02:00
|
|
|
* (reason: intentional self assignment to clear all pending IRQs) */
|
2018-03-03 08:44:05 +01:00
|
|
|
hw->CSR = hw->CSR;
|
|
|
|
/* Enable timer and IRQ */
|
|
|
|
hw->CSR = LPTMR_CSR_TEN_MASK | LPTMR_CSR_TFC_MASK | LPTMR_CSR_TIE_MASK;
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
uint16_t timeout = target - lptmr_read(dev);
|
2018-09-22 07:29:42 +02:00
|
|
|
lptmr_reload(dev, timeout);
|
2016-03-20 19:39:53 +01:00
|
|
|
}
|
|
|
|
irq_restore(mask);
|
2019-09-11 13:46:15 +02:00
|
|
|
return 0;
|
2016-03-20 19:39:53 +01:00
|
|
|
}
|
2015-01-06 00:19:24 +01:00
|
|
|
|
make: fix various compile errors with Wextra
pkg, nordic_softdevice_ble: disable CFLAGS to omit compiler error
sys, pm_layered: fix casting nonscalar to the same type
cpu, stm32_common: fix type-limits, remove always true assert
cpu, stm32f4: fix pointer arithmetic in periph/i2c
drivers, at86rf2xx: fix type-limits where condition always true
saul, gpio: fix if no gpio configured for saul
cpu, saml21: add frequency check to periph/timer
driver, cc110x: fix unused param and type-limts errors
boards, wsn430-common: fix old-style-declaration
make: fix old style definition
drivers, sdcard_spi: fix old style typedef
driver, at30tse: remove unnecessary check
driver, nrf24: fix type-limit
driver, pn532: change buffer from char to uint8_t
tests/driver_sdcard: fix type limits
boards, feather-m0: add missing field inits
driver, tcs37727: fix type limits
pkg, emb6: disable some compiler warnings
tests/emb6: disable some compiler warings
pkg, openthread: fix sign compare and unused params
tests/trickle: fix struct init
tests/pthread_cooperation: fix type limits
board, mips-malta: remove feature periph_uart
shell: fix var size for netif command
gnrc, netif: fix sign-compare
gnrc, nib: fix sign-compare
shell: fix output in netif command
posix: fix type-limits in pthread_cond
2017-10-31 11:52:18 +01:00
|
|
|
static inline int lptmr_clear(uint8_t dev)
|
2016-03-20 19:39:53 +01:00
|
|
|
{
|
|
|
|
/* Disable IRQs to minimize jitter */
|
2018-03-03 08:44:05 +01:00
|
|
|
LPTMR_Type *hw = lptmr_config[dev].dev;
|
2016-03-20 19:39:53 +01:00
|
|
|
unsigned int mask = irq_disable();
|
2018-07-31 18:08:07 +02:00
|
|
|
|
2018-03-03 08:44:05 +01:00
|
|
|
if (!lptmr[dev].running) {
|
|
|
|
/* Already clear */
|
|
|
|
irq_restore(mask);
|
2019-09-11 13:46:15 +02:00
|
|
|
return 0;
|
2016-03-20 19:39:53 +01:00
|
|
|
}
|
2018-03-03 08:44:05 +01:00
|
|
|
lptmr[dev].running = 0;
|
|
|
|
if (!(hw->CSR & LPTMR_CSR_TEN_MASK)) {
|
|
|
|
/* Timer is stopped */
|
|
|
|
irq_restore(mask);
|
2019-09-11 13:46:15 +02:00
|
|
|
return 0;
|
2016-03-20 19:39:53 +01:00
|
|
|
}
|
2018-03-03 08:44:05 +01:00
|
|
|
/* Disable interrupt, enable timer */
|
|
|
|
hw->CSR = LPTMR_CSR_TEN_MASK | LPTMR_CSR_TFC_MASK;
|
|
|
|
/* Clear IRQ if it occurred during this function */
|
|
|
|
NVIC_ClearPendingIRQ(lptmr_config[dev].irqn);
|
2016-03-20 19:39:53 +01:00
|
|
|
irq_restore(mask);
|
2019-09-11 13:46:15 +02:00
|
|
|
return 0;
|
2016-03-20 19:39:53 +01:00
|
|
|
}
|
2015-01-06 00:19:24 +01:00
|
|
|
|
make: fix various compile errors with Wextra
pkg, nordic_softdevice_ble: disable CFLAGS to omit compiler error
sys, pm_layered: fix casting nonscalar to the same type
cpu, stm32_common: fix type-limits, remove always true assert
cpu, stm32f4: fix pointer arithmetic in periph/i2c
drivers, at86rf2xx: fix type-limits where condition always true
saul, gpio: fix if no gpio configured for saul
cpu, saml21: add frequency check to periph/timer
driver, cc110x: fix unused param and type-limts errors
boards, wsn430-common: fix old-style-declaration
make: fix old style definition
drivers, sdcard_spi: fix old style typedef
driver, at30tse: remove unnecessary check
driver, nrf24: fix type-limit
driver, pn532: change buffer from char to uint8_t
tests/driver_sdcard: fix type limits
boards, feather-m0: add missing field inits
driver, tcs37727: fix type limits
pkg, emb6: disable some compiler warnings
tests/emb6: disable some compiler warings
pkg, openthread: fix sign compare and unused params
tests/trickle: fix struct init
tests/pthread_cooperation: fix type limits
board, mips-malta: remove feature periph_uart
shell: fix var size for netif command
gnrc, netif: fix sign-compare
gnrc, nib: fix sign-compare
shell: fix output in netif command
posix: fix type-limits in pthread_cond
2017-10-31 11:52:18 +01:00
|
|
|
static inline void lptmr_start(uint8_t dev)
|
2016-03-20 19:39:53 +01:00
|
|
|
{
|
2018-03-03 08:44:05 +01:00
|
|
|
LPTMR_Type *hw = lptmr_config[dev].dev;
|
2018-07-31 18:08:07 +02:00
|
|
|
|
2018-03-03 08:44:05 +01:00
|
|
|
if (hw->CSR & LPTMR_CSR_TEN_MASK) {
|
|
|
|
/* Timer is running */
|
2016-03-20 19:39:53 +01:00
|
|
|
return;
|
|
|
|
}
|
2018-03-03 08:44:05 +01:00
|
|
|
/* Disable IRQs to avoid race with ISR */
|
|
|
|
unsigned int mask = irq_disable();
|
|
|
|
/* ensure hardware is reset */
|
|
|
|
hw->CSR = 0;
|
|
|
|
if (lptmr[dev].running) {
|
|
|
|
/* set target */
|
|
|
|
hw->CMR = lptmr[dev].cmr;
|
|
|
|
/* enable interrupt and start timer */
|
|
|
|
hw->CSR = LPTMR_CSR_TEN_MASK | LPTMR_CSR_TFC_MASK | LPTMR_CSR_TIE_MASK;
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
/* no target */
|
|
|
|
hw->CMR = 0;
|
|
|
|
/* Disable interrupt, enable timer */
|
|
|
|
hw->CSR = LPTMR_CSR_TEN_MASK | LPTMR_CSR_TFC_MASK;
|
|
|
|
}
|
|
|
|
/* compensate for the reload delay when starting the timer */
|
|
|
|
lptmr[dev].cnr += LPTMR_RELOAD_OVERHEAD;
|
|
|
|
irq_restore(mask);
|
2016-03-20 19:39:53 +01:00
|
|
|
}
|
2015-01-06 00:19:24 +01:00
|
|
|
|
make: fix various compile errors with Wextra
pkg, nordic_softdevice_ble: disable CFLAGS to omit compiler error
sys, pm_layered: fix casting nonscalar to the same type
cpu, stm32_common: fix type-limits, remove always true assert
cpu, stm32f4: fix pointer arithmetic in periph/i2c
drivers, at86rf2xx: fix type-limits where condition always true
saul, gpio: fix if no gpio configured for saul
cpu, saml21: add frequency check to periph/timer
driver, cc110x: fix unused param and type-limts errors
boards, wsn430-common: fix old-style-declaration
make: fix old style definition
drivers, sdcard_spi: fix old style typedef
driver, at30tse: remove unnecessary check
driver, nrf24: fix type-limit
driver, pn532: change buffer from char to uint8_t
tests/driver_sdcard: fix type limits
boards, feather-m0: add missing field inits
driver, tcs37727: fix type limits
pkg, emb6: disable some compiler warnings
tests/emb6: disable some compiler warings
pkg, openthread: fix sign compare and unused params
tests/trickle: fix struct init
tests/pthread_cooperation: fix type limits
board, mips-malta: remove feature periph_uart
shell: fix var size for netif command
gnrc, netif: fix sign-compare
gnrc, nib: fix sign-compare
shell: fix output in netif command
posix: fix type-limits in pthread_cond
2017-10-31 11:52:18 +01:00
|
|
|
static inline void lptmr_stop(uint8_t dev)
|
2016-03-20 19:39:53 +01:00
|
|
|
{
|
|
|
|
/* Disable IRQs to avoid race with ISR */
|
|
|
|
unsigned int mask = irq_disable();
|
|
|
|
LPTMR_Type *hw = lptmr_config[dev].dev;
|
2018-07-31 18:08:07 +02:00
|
|
|
|
2018-03-03 08:44:05 +01:00
|
|
|
if (!(hw->CSR & LPTMR_CSR_TEN_MASK)) {
|
|
|
|
/* Timer is already stopped */
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
/* Update state */
|
|
|
|
/* Latch counter value */
|
|
|
|
hw->CNR = 0;
|
|
|
|
lptmr[dev].cnr += hw->CNR;
|
|
|
|
uint16_t timeout = hw->CMR - hw->CNR;
|
|
|
|
/* Disable timer */
|
|
|
|
hw->CSR = 0;
|
|
|
|
if (timeout > LPTMR_RELOAD_OVERHEAD) {
|
|
|
|
/* Compensate for the delay in reloading */
|
|
|
|
lptmr[dev].cmr = timeout - LPTMR_RELOAD_OVERHEAD;
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
lptmr[dev].cmr = timeout;
|
|
|
|
}
|
2016-03-20 19:39:53 +01:00
|
|
|
/* Clear any pending IRQ */
|
2017-04-15 14:57:02 +02:00
|
|
|
NVIC_ClearPendingIRQ(lptmr_config[dev].irqn);
|
2016-03-20 19:39:53 +01:00
|
|
|
irq_restore(mask);
|
2015-01-06 00:19:24 +01:00
|
|
|
}
|
|
|
|
|
2018-08-13 18:37:39 +02:00
|
|
|
#if defined(LPTMR_ISR_0) || defined(LPTMR_ISR_1)
|
make: fix various compile errors with Wextra
pkg, nordic_softdevice_ble: disable CFLAGS to omit compiler error
sys, pm_layered: fix casting nonscalar to the same type
cpu, stm32_common: fix type-limits, remove always true assert
cpu, stm32f4: fix pointer arithmetic in periph/i2c
drivers, at86rf2xx: fix type-limits where condition always true
saul, gpio: fix if no gpio configured for saul
cpu, saml21: add frequency check to periph/timer
driver, cc110x: fix unused param and type-limts errors
boards, wsn430-common: fix old-style-declaration
make: fix old style definition
drivers, sdcard_spi: fix old style typedef
driver, at30tse: remove unnecessary check
driver, nrf24: fix type-limit
driver, pn532: change buffer from char to uint8_t
tests/driver_sdcard: fix type limits
boards, feather-m0: add missing field inits
driver, tcs37727: fix type limits
pkg, emb6: disable some compiler warnings
tests/emb6: disable some compiler warings
pkg, openthread: fix sign compare and unused params
tests/trickle: fix struct init
tests/pthread_cooperation: fix type limits
board, mips-malta: remove feature periph_uart
shell: fix var size for netif command
gnrc, netif: fix sign-compare
gnrc, nib: fix sign-compare
shell: fix output in netif command
posix: fix type-limits in pthread_cond
2017-10-31 11:52:18 +01:00
|
|
|
static inline void lptmr_irq_handler(tim_t tim)
|
2015-01-06 00:19:24 +01:00
|
|
|
{
|
2016-03-20 19:39:53 +01:00
|
|
|
uint8_t dev = _lptmr_index(tim);
|
|
|
|
LPTMR_Type *hw = lptmr_config[dev].dev;
|
|
|
|
|
2018-03-03 08:44:05 +01:00
|
|
|
lptmr[dev].running = 0;
|
|
|
|
/* Disable interrupt generation, keep timer running */
|
|
|
|
/* Do not clear TCF flag here, it is required for writing CMR without
|
|
|
|
* disabling timer first */
|
|
|
|
hw->CSR = LPTMR_CSR_TEN_MASK | LPTMR_CSR_TFC_MASK;
|
2015-01-06 00:19:24 +01:00
|
|
|
|
2018-03-03 08:44:05 +01:00
|
|
|
if (lptmr[dev].isr_ctx.cb != NULL) {
|
|
|
|
lptmr[dev].isr_ctx.cb(lptmr[dev].isr_ctx.arg, 0);
|
|
|
|
}
|
2015-01-06 00:19:24 +01:00
|
|
|
|
2016-11-30 18:26:05 +01:00
|
|
|
cortexm_isr_end();
|
2016-03-20 19:39:53 +01:00
|
|
|
}
|
2018-08-13 18:37:39 +02:00
|
|
|
#endif /* defined(LPTMR_ISR_0) || defined(LPTMR_ISR_1) */
|
2015-01-06 00:19:24 +01:00
|
|
|
|
2018-07-31 18:08:07 +02:00
|
|
|
#endif
|
2016-03-20 19:39:53 +01:00
|
|
|
/* ****** Common timer API functions ****** */
|
|
|
|
|
2023-05-03 18:03:33 +02:00
|
|
|
uword_t timer_query_freqs_numof(tim_t dev)
|
|
|
|
{
|
|
|
|
assert(dev < TIMER_NUMOF);
|
|
|
|
|
|
|
|
switch (_timer_variant(dev)) {
|
|
|
|
case TIMER_PIT:
|
|
|
|
return UINT32_MAX;
|
|
|
|
#ifdef KINETIS_BOARD_HAVE_CONFIGURED_LPTMR
|
|
|
|
case TIMER_LPTMR:
|
|
|
|
/* 16 different pre-scaler values + bypassing the pre-scaler is
|
|
|
|
* supported, resulting in 17 possible frequencies. However, RIOT's
|
|
|
|
* timer API doesn't allow specifying frequencies below 1 Hz, so
|
|
|
|
* we possible have fewer options */
|
|
|
|
{
|
|
|
|
uword_t max_shifts = bitarithm_msb(lptmr_config[_lptmr_index(dev)].base_freq) + 1;
|
|
|
|
return MIN(max_shifts, 17);
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
default:
|
|
|
|
assert(0);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
uint32_t timer_query_freqs(tim_t dev, uword_t index)
|
|
|
|
{
|
|
|
|
assert(dev < TIMER_NUMOF);
|
|
|
|
|
|
|
|
switch (_timer_variant(dev)) {
|
|
|
|
case TIMER_PIT:
|
|
|
|
if (index == UINT32_MAX) {
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
return PIT_BASECLOCK / (index + 1);
|
|
|
|
#ifdef KINETIS_BOARD_HAVE_CONFIGURED_LPTMR
|
|
|
|
case TIMER_LPTMR:
|
|
|
|
if (index >= 17) {
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
return lptmr_config[_lptmr_index(dev)].base_freq >> index;
|
|
|
|
#endif
|
|
|
|
default:
|
|
|
|
assert(0);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-10-30 12:14:35 +01:00
|
|
|
int timer_init(tim_t dev, uint32_t freq, timer_cb_t cb, void *arg)
|
2016-03-20 19:39:53 +01:00
|
|
|
{
|
|
|
|
if ((unsigned int)dev >= TIMER_NUMOF) {
|
|
|
|
/* invalid timer */
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
/* demultiplex to handle two types of hardware timers */
|
|
|
|
switch (_timer_variant(dev)) {
|
|
|
|
case TIMER_PIT:
|
|
|
|
return pit_init(_pit_index(dev), freq, cb, arg);
|
2021-01-08 12:00:57 +01:00
|
|
|
#ifdef KINETIS_BOARD_HAVE_CONFIGURED_LPTMR
|
2016-03-20 19:39:53 +01:00
|
|
|
case TIMER_LPTMR:
|
|
|
|
return lptmr_init(_lptmr_index(dev), freq, cb, arg);
|
2018-07-31 18:08:07 +02:00
|
|
|
#endif
|
2016-03-20 19:39:53 +01:00
|
|
|
default:
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
int timer_set(tim_t dev, int channel, unsigned int timeout)
|
|
|
|
{
|
|
|
|
if (channel != 0) {
|
|
|
|
/* only one channel is supported */
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
if ((unsigned int)dev >= TIMER_NUMOF) {
|
|
|
|
/* invalid timer */
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
/* demultiplex to handle two types of hardware timers */
|
|
|
|
switch (_timer_variant(dev)) {
|
|
|
|
case TIMER_PIT:
|
|
|
|
return pit_set(_pit_index(dev), timeout);
|
2021-01-08 12:00:57 +01:00
|
|
|
#ifdef KINETIS_BOARD_HAVE_CONFIGURED_LPTMR
|
2016-03-20 19:39:53 +01:00
|
|
|
case TIMER_LPTMR:
|
|
|
|
return lptmr_set(_lptmr_index(dev), timeout);
|
2018-07-31 18:08:07 +02:00
|
|
|
#endif
|
2016-03-20 19:39:53 +01:00
|
|
|
default:
|
|
|
|
return -1;
|
2015-01-06 00:19:24 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-03-20 19:39:53 +01:00
|
|
|
int timer_set_absolute(tim_t dev, int channel, unsigned int target)
|
2015-01-06 00:19:24 +01:00
|
|
|
{
|
2016-03-20 19:39:53 +01:00
|
|
|
if (channel != 0) {
|
|
|
|
/* only one channel is supported */
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
if ((unsigned int)dev >= TIMER_NUMOF) {
|
|
|
|
/* invalid timer */
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
/* demultiplex to handle two types of hardware timers */
|
|
|
|
switch (_timer_variant(dev)) {
|
|
|
|
case TIMER_PIT:
|
|
|
|
return pit_set_absolute(_pit_index(dev), target);
|
2021-01-08 12:00:57 +01:00
|
|
|
#ifdef KINETIS_BOARD_HAVE_CONFIGURED_LPTMR
|
2016-03-20 19:39:53 +01:00
|
|
|
case TIMER_LPTMR:
|
2018-07-31 18:08:07 +02:00
|
|
|
return lptmr_set_absolute(_lptmr_index(dev), target);
|
|
|
|
#endif
|
2016-03-20 19:39:53 +01:00
|
|
|
default:
|
|
|
|
return -1;
|
|
|
|
}
|
2015-01-06 00:19:24 +01:00
|
|
|
|
2016-03-20 19:39:53 +01:00
|
|
|
return 0;
|
|
|
|
}
|
2015-01-06 00:19:24 +01:00
|
|
|
|
2016-03-20 19:39:53 +01:00
|
|
|
int timer_clear(tim_t dev, int channel)
|
|
|
|
{
|
|
|
|
if (channel != 0) {
|
|
|
|
/* only one channel is supported */
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
if ((unsigned int)dev >= TIMER_NUMOF) {
|
|
|
|
/* invalid timer */
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
/* demultiplex to handle two types of hardware timers */
|
|
|
|
switch (_timer_variant(dev)) {
|
|
|
|
case TIMER_PIT:
|
|
|
|
return pit_clear(_pit_index(dev));
|
2021-01-08 12:00:57 +01:00
|
|
|
#ifdef KINETIS_BOARD_HAVE_CONFIGURED_LPTMR
|
2016-03-20 19:39:53 +01:00
|
|
|
case TIMER_LPTMR:
|
|
|
|
return lptmr_clear(_lptmr_index(dev));
|
2018-07-31 18:08:07 +02:00
|
|
|
#endif
|
2016-03-20 19:39:53 +01:00
|
|
|
default:
|
|
|
|
return -1;
|
|
|
|
}
|
2015-01-06 00:19:24 +01:00
|
|
|
|
2016-03-20 19:39:53 +01:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
unsigned int timer_read(tim_t dev)
|
|
|
|
{
|
|
|
|
if ((unsigned int)dev >= TIMER_NUMOF) {
|
|
|
|
/* invalid timer */
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
/* demultiplex to handle two types of hardware timers */
|
|
|
|
switch (_timer_variant(dev)) {
|
|
|
|
case TIMER_PIT:
|
|
|
|
return pit_read(_pit_index(dev));
|
2021-01-08 12:00:57 +01:00
|
|
|
#ifdef KINETIS_BOARD_HAVE_CONFIGURED_LPTMR
|
2016-03-20 19:39:53 +01:00
|
|
|
case TIMER_LPTMR:
|
|
|
|
return lptmr_read(_lptmr_index(dev));
|
2018-07-31 18:08:07 +02:00
|
|
|
#endif
|
2016-03-20 19:39:53 +01:00
|
|
|
default:
|
|
|
|
return 0;
|
2015-01-06 00:19:24 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-03-20 19:39:53 +01:00
|
|
|
void timer_start(tim_t dev)
|
2015-01-06 00:19:24 +01:00
|
|
|
{
|
2016-03-20 19:39:53 +01:00
|
|
|
if ((unsigned int)dev >= TIMER_NUMOF) {
|
|
|
|
/* invalid timer */
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
/* demultiplex to handle two types of hardware timers */
|
|
|
|
switch (_timer_variant(dev)) {
|
|
|
|
case TIMER_PIT:
|
|
|
|
pit_start(_pit_index(dev));
|
|
|
|
return;
|
2021-01-08 12:00:57 +01:00
|
|
|
#ifdef KINETIS_BOARD_HAVE_CONFIGURED_LPTMR
|
2016-03-20 19:39:53 +01:00
|
|
|
case TIMER_LPTMR:
|
|
|
|
lptmr_start(_lptmr_index(dev));
|
|
|
|
return;
|
2018-07-31 18:08:07 +02:00
|
|
|
#endif
|
2016-03-20 19:39:53 +01:00
|
|
|
default:
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
2015-01-06 00:19:24 +01:00
|
|
|
|
2016-03-20 19:39:53 +01:00
|
|
|
void timer_stop(tim_t dev)
|
|
|
|
{
|
|
|
|
if ((unsigned int)dev >= TIMER_NUMOF) {
|
|
|
|
/* invalid timer */
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
/* demultiplex to handle two types of hardware timers */
|
|
|
|
switch (_timer_variant(dev)) {
|
|
|
|
case TIMER_PIT:
|
|
|
|
pit_stop(_pit_index(dev));
|
|
|
|
return;
|
2021-01-08 12:00:57 +01:00
|
|
|
#ifdef KINETIS_BOARD_HAVE_CONFIGURED_LPTMR
|
2016-03-20 19:39:53 +01:00
|
|
|
case TIMER_LPTMR:
|
|
|
|
lptmr_stop(_lptmr_index(dev));
|
|
|
|
return;
|
2018-07-31 18:08:07 +02:00
|
|
|
#endif
|
2016-03-20 19:39:53 +01:00
|
|
|
default:
|
|
|
|
return;
|
2015-01-06 00:19:24 +01:00
|
|
|
}
|
2016-03-20 19:39:53 +01:00
|
|
|
}
|
2015-01-06 00:19:24 +01:00
|
|
|
|
2016-03-20 19:39:53 +01:00
|
|
|
/* ****** ISR instances ****** */
|
2015-10-19 17:23:12 +02:00
|
|
|
|
2017-03-24 14:48:39 +01:00
|
|
|
void isr_pit(void)
|
|
|
|
{
|
|
|
|
/* Some of the lower end Kinetis CPUs combine the individual PIT interrupt
|
|
|
|
* flags into a single NVIC IRQ signal. This means that software needs to
|
|
|
|
* test which timer(s) went off when an IRQ occurs. */
|
|
|
|
for (size_t i = 0; i < PIT_NUMOF; ++i) {
|
|
|
|
if (PIT->CHANNEL[pit_config[i].count_ch].TCTRL & PIT_TCTRL_TIE_MASK) {
|
|
|
|
/* Interrupt is enabled */
|
|
|
|
if (PIT->CHANNEL[pit_config[i].count_ch].TFLG) {
|
|
|
|
/* Timer interrupt flag is set */
|
|
|
|
pit_irq_handler(_pit_tim_t(i));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-03-20 19:39:53 +01:00
|
|
|
#ifdef PIT_ISR_0
|
|
|
|
void PIT_ISR_0(void)
|
|
|
|
{
|
|
|
|
pit_irq_handler(_pit_tim_t(0));
|
2015-01-06 00:19:24 +01:00
|
|
|
}
|
2016-03-20 19:39:53 +01:00
|
|
|
#endif
|
2015-01-06 00:19:24 +01:00
|
|
|
|
2016-03-20 19:39:53 +01:00
|
|
|
#ifdef PIT_ISR_1
|
|
|
|
void PIT_ISR_1(void)
|
2015-01-06 00:19:24 +01:00
|
|
|
{
|
2016-03-20 19:39:53 +01:00
|
|
|
pit_irq_handler(_pit_tim_t(1));
|
2015-01-06 00:19:24 +01:00
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2016-03-20 19:39:53 +01:00
|
|
|
#ifdef PIT_ISR_2
|
|
|
|
void PIT_ISR_2(void)
|
2015-01-06 00:19:24 +01:00
|
|
|
{
|
2016-03-20 19:39:53 +01:00
|
|
|
pit_irq_handler(_pit_tim_t(2));
|
2015-01-06 00:19:24 +01:00
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2016-03-20 19:39:53 +01:00
|
|
|
#ifdef PIT_ISR_3
|
|
|
|
void PIT_ISR_3(void)
|
|
|
|
{
|
|
|
|
pit_irq_handler(_pit_tim_t(3));
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#ifdef LPTMR_ISR_0
|
|
|
|
void LPTMR_ISR_0(void)
|
|
|
|
{
|
|
|
|
lptmr_irq_handler(_lptmr_tim_t(0));
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#ifdef LPTMR_ISR_1
|
|
|
|
void LPTMR_ISR_1(void)
|
|
|
|
{
|
|
|
|
lptmr_irq_handler(_lptmr_tim_t(1));
|
|
|
|
}
|
2015-01-06 00:19:24 +01:00
|
|
|
#endif
|