mirror of https://github.com/ARMmbed/mbed-os.git
Merge pull request #8737 from kapi90/cm3ds_lp_requirements
Add low power implementations for CM3DSpull/8863/head
commit
d7f2e3056c
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2018 ARM Limited
|
||||
* Copyright (c) 2018 Arm Limited
|
||||
*
|
||||
* Licensed under the Apache License Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
|
@ -27,8 +27,54 @@
|
|||
*/
|
||||
|
||||
/* CMSDK Timers */
|
||||
#define ARM_CMSDK_TIMER0
|
||||
#define ARM_CMSDK_TIMER1
|
||||
#define ARM_CMSDK_DUALTIMER
|
||||
|
||||
/* Timer Peripherals are driven by APB System Core Clocks,
|
||||
* defined in system_CMSDK_CM3DS.c
|
||||
*/
|
||||
#define TIMERS_INPUT_CLOCK_FREQ_HZ 25000000U
|
||||
|
||||
/* mbed usec high-resolution ticker configuration */
|
||||
#define USEC_TIMER_DEV CMSDK_TIMER1_DEV
|
||||
|
||||
#define usec_interval_irq_handler TIMER1_IRQHandler
|
||||
#define USEC_INTERVAL_IRQ TIMER1_IRQn
|
||||
|
||||
/* The us ticker uses CMSDK Timer1, that does not have HW prescaler.
|
||||
* The reported shift define is necessary for the software emulated
|
||||
* prescaler behavior, so the ticker works as if it was ticking on a
|
||||
* virtually slower frequency. The value 5 sets up the ticker to work
|
||||
* properly in the specified frequency interval.
|
||||
*/
|
||||
#define USEC_TIMER_BIT_WIDTH 32U
|
||||
#define USEC_REPORTED_SHIFT 5U
|
||||
#define USEC_REPORTED_FREQ_HZ (TIMERS_INPUT_CLOCK_FREQ_HZ >> \
|
||||
USEC_REPORTED_SHIFT)
|
||||
#define USEC_REPORTED_BITS (USEC_TIMER_BIT_WIDTH - USEC_REPORTED_SHIFT)
|
||||
|
||||
/* mbed low power ticker configuration */
|
||||
#define LP_TIMER_DEV CMSDK_DUALTIMER_DEV
|
||||
|
||||
#define lp_interval_irq_handler DUALTIMER_IRQHandler
|
||||
#define LP_INTERVAL_IRQ DUALTIMER_IRQn
|
||||
|
||||
/* The lp ticker a CMSDK Dual Timer that is capable of prescaling
|
||||
* its input clock frequency by 256 at most. Having 25MHz as input
|
||||
* frequency requires an additional slowing factor in order for the ticker
|
||||
* to operate in the specified frequency interval, thus the effective
|
||||
* prescaler value is going to be the sum of the HW and the virtual
|
||||
* prescaler values.
|
||||
*/
|
||||
#define LP_TIMER_BIT_WIDTH 32U
|
||||
#define LP_TIMER_HW_PRESCALER 8U
|
||||
#define LP_REPORTED_SHIFT 1U
|
||||
#define LP_REPORTED_FREQ_HZ (TIMERS_INPUT_CLOCK_FREQ_HZ >> \
|
||||
(LP_TIMER_HW_PRESCALER+LP_REPORTED_SHIFT))
|
||||
#define LP_REPORTED_BITS (LP_TIMER_BIT_WIDTH - LP_REPORTED_SHIFT)
|
||||
|
||||
/* RTC PL031 */
|
||||
#define RTC_PL031
|
||||
|
||||
/* ARM GPIO */
|
||||
#define ARM_GPIO0
|
||||
|
@ -51,7 +97,7 @@
|
|||
#define ARM_SPI4
|
||||
|
||||
/* ARM UART */
|
||||
#define DEFAULT_UART_BAUDRATE 9600
|
||||
#define DEFAULT_UART_BAUDRATE 9600U
|
||||
#define ARM_UART0
|
||||
#define ARM_UART1
|
||||
#define ARM_UART2
|
||||
|
|
|
@ -0,0 +1,590 @@
|
|||
/*
|
||||
* Copyright (c) 2016-2018 Arm Limited
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
/**
|
||||
* \file dualtimer_cmsdk_drv.c
|
||||
* \brief Generic driver for CMSDK Dualtimers.
|
||||
*/
|
||||
|
||||
#include "dualtimer_cmsdk_drv.h"
|
||||
|
||||
/** Dualtimer state definition */
|
||||
#define DUALTIMER_CMSDK_INITIALIZED (1u)
|
||||
|
||||
/** Dual timer control register bit indexes */
|
||||
#define CTRL_REG_ONE_SHOT_INDEX (0u)
|
||||
#define CTRL_REG_SIZE_INDEX (1u)
|
||||
#define CTRL_REG_PRESCALE_INDEX (3u)
|
||||
#define CTRL_REG_IRQ_EN_INDEX (5u)
|
||||
#define CTRL_REG_MODE_INDEX (6u)
|
||||
#define CTRL_REG_TIMER_EN_INDEX (7u)
|
||||
|
||||
/** Dual timer interrupt registers bit indexes */
|
||||
#define XRIS_REG_RAW_IRQ_INDEX (0u)
|
||||
#define XMIS_REG_MASKED_IRQ_INDEX (0u)
|
||||
#define XINTCLR_REG_CLEAR_IRQ_INDEX (0u)
|
||||
|
||||
/** Misc definition */
|
||||
#define TWO_BITS_WIDTH (2u)
|
||||
|
||||
/** Bit handling macros */
|
||||
#define ATOMIC_SET_BIT(WORD, BIT_INDEX) (WORD = (1u << BIT_INDEX))
|
||||
#define ATOMIC_CLR_BIT(WORD, BIT_INDEX) (WORD = ~(1u << BIT_INDEX))
|
||||
#define SET_BIT(WORD, BIT_INDEX) (WORD |= (1u << BIT_INDEX))
|
||||
#define CLR_BIT(WORD, BIT_INDEX) (WORD &= ~(1u << BIT_INDEX))
|
||||
#define GET_BIT(WORD, BIT_INDEX) (bool)((WORD & (1u << BIT_INDEX)))
|
||||
|
||||
/** Generate a flexible width left shifted bit-mask */
|
||||
#define BIT_MASK(BIT_INDEX, WIDTH)\
|
||||
(((1u << (WIDTH)) - 1u) << (BIT_INDEX - WIDTH + 1u))
|
||||
|
||||
/** Set N number of bits defined by width at index position in a register */
|
||||
#define SET_NBITS(WORD, BIT_INDEX, WIDTH, DATA)\
|
||||
(WORD |= (DATA << (BIT_INDEX - WIDTH + 1u))\
|
||||
& BIT_MASK(BIT_INDEX, WIDTH))
|
||||
|
||||
/** Get N number of bits defined by width at index position in a register */
|
||||
#define GET_NBITS(WORD, BIT_INDEX, WIDTH)\
|
||||
((WORD & BIT_MASK(BIT_INDEX, WIDTH))\
|
||||
>> (BIT_INDEX - WIDTH + 1u))
|
||||
|
||||
/** Map the registers for dualtimer device */
|
||||
#define DUALTIMER_REG_MAP(DEVICE)\
|
||||
((struct dualtimer_cmsdk_reg_map_t*)((DEVICE)->cfg->base))
|
||||
|
||||
/** DualTimer register map structure */
|
||||
struct dualtimer_cmsdk_reg_map_t {
|
||||
volatile uint32_t timer1load; /** Offset: 0x000 (R/W) Timer 1 Load */
|
||||
volatile uint32_t timer1value; /** Offset: 0x004 (R/ ) Timer 1 Counter
|
||||
* Current Value */
|
||||
volatile uint32_t timer1ctrl; /** Offset: 0x008 (R/W) Timer 1 Control */
|
||||
volatile uint32_t timer1intclr; /** Offset: 0x00C ( /W) Timer 1 Interrupt
|
||||
* Clear */
|
||||
volatile uint32_t timer1ris; /** Offset: 0x010 (R/ ) Timer 1 Raw
|
||||
* Interrupt Status */
|
||||
volatile uint32_t timer1mis; /** Offset: 0x014 (R/ ) Timer 1 Masked
|
||||
* Interrupt Status */
|
||||
volatile uint32_t timer1bgload; /** Offset: 0x018 (R/W) Background Load
|
||||
* Register */
|
||||
volatile uint32_t reserved0;
|
||||
volatile uint32_t timer2load; /** Offset: 0x020 (R/W) Timer 2 Load */
|
||||
volatile uint32_t timer2value; /** Offset: 0x024 (R/ ) Timer 2 Counter
|
||||
* Current Value */
|
||||
volatile uint32_t timer2ctrl; /** Offset: 0x028 (R/W) Timer 2 Control */
|
||||
volatile uint32_t timer2intclr; /** Offset: 0x02C ( /W) Timer 2 Interrupt
|
||||
* Clear */
|
||||
volatile uint32_t timer2ris; /** Offset: 0x030 (R/ ) Timer 2 Raw
|
||||
* Interrupt Status */
|
||||
volatile uint32_t timer2mis; /** Offset: 0x034 (R/ ) Timer 2 Masked
|
||||
* Interrupt Status */
|
||||
volatile uint32_t timer2bgload; /** Offset: 0x038 (R/W) Background Load
|
||||
* Register */
|
||||
volatile uint32_t reserved1[945];
|
||||
volatile uint32_t itcr; /** Offset: 0xF00 (R/W) Integration Test
|
||||
* Control Register */
|
||||
volatile uint32_t itop; /** Offset: 0xF04 ( /W) Integration Test
|
||||
* Output Set
|
||||
* Register */
|
||||
};
|
||||
|
||||
static void dualtimer_cmsdk_defaults(const struct dualtimer_cmsdk_dev_t* dev)
|
||||
{
|
||||
dualtimer_cmsdk_disable_both_timers(dev);
|
||||
dualtimer_cmsdk_clear_interrupt_timer1(dev);
|
||||
dualtimer_cmsdk_clear_interrupt_timer2(dev);
|
||||
dualtimer_cmsdk_set_oneshot_count_both_timers(dev,
|
||||
DUALTIMER_CMSDK_WRAPPING);
|
||||
dualtimer_cmsdk_set_size_both_timers(dev, DUALTIMER_CMSDK_SIZE_16BIT);
|
||||
dualtimer_cmsdk_set_prescale_both_timers(dev,
|
||||
DUALTIMER_CMSDK_CLOCK_DIV1);
|
||||
dualtimer_cmsdk_enable_interrupt_both_timers(dev);
|
||||
dualtimer_cmsdk_set_mode_both_timers(dev, DUALTIMER_CMSDK_FREE_RUNNING);
|
||||
dualtimer_cmsdk_set_reload_both_timers(dev,
|
||||
DUALTIMER_CMSDK_DEF_16BIT_RELOAD);
|
||||
}
|
||||
/** Init */
|
||||
void dualtimer_cmsdk_init(const struct dualtimer_cmsdk_dev_t* dev)
|
||||
{
|
||||
if (DUALTIMER_CMSDK_INITIALIZED != dev->data->is_initialized) {
|
||||
dualtimer_cmsdk_defaults(dev);
|
||||
dev->data->is_initialized = 1;
|
||||
}
|
||||
}
|
||||
|
||||
bool dualtimer_cmsdk_is_initialized(const struct dualtimer_cmsdk_dev_t* dev)
|
||||
{
|
||||
return(bool)dev->data->is_initialized;
|
||||
}
|
||||
|
||||
void dualtimer_cmsdk_free(const struct dualtimer_cmsdk_dev_t* dev)
|
||||
{
|
||||
dualtimer_cmsdk_disable_both_timers(dev);
|
||||
dev->data->is_initialized = 0;
|
||||
}
|
||||
|
||||
/** Enable - Disable */
|
||||
void dualtimer_cmsdk_enable_timer1(const struct dualtimer_cmsdk_dev_t* dev)
|
||||
{
|
||||
SET_BIT(DUALTIMER_REG_MAP(dev)->timer1ctrl, CTRL_REG_TIMER_EN_INDEX);
|
||||
}
|
||||
|
||||
void dualtimer_cmsdk_enable_timer2(const struct dualtimer_cmsdk_dev_t* dev)
|
||||
{
|
||||
SET_BIT(DUALTIMER_REG_MAP(dev)->timer2ctrl, CTRL_REG_TIMER_EN_INDEX);
|
||||
}
|
||||
|
||||
void dualtimer_cmsdk_enable_both_timers(const struct dualtimer_cmsdk_dev_t* dev)
|
||||
{
|
||||
dualtimer_cmsdk_enable_timer1(dev);
|
||||
dualtimer_cmsdk_enable_timer2(dev);
|
||||
}
|
||||
|
||||
void dualtimer_cmsdk_disable_timer1(const struct dualtimer_cmsdk_dev_t* dev)
|
||||
{
|
||||
CLR_BIT(DUALTIMER_REG_MAP(dev)->timer1ctrl, CTRL_REG_TIMER_EN_INDEX);
|
||||
}
|
||||
|
||||
void dualtimer_cmsdk_disable_timer2(const struct dualtimer_cmsdk_dev_t* dev)
|
||||
{
|
||||
CLR_BIT(DUALTIMER_REG_MAP(dev)->timer2ctrl, CTRL_REG_TIMER_EN_INDEX);
|
||||
}
|
||||
|
||||
void dualtimer_cmsdk_disable_both_timers(
|
||||
const struct dualtimer_cmsdk_dev_t* dev)
|
||||
{
|
||||
dualtimer_cmsdk_disable_timer1(dev);
|
||||
dualtimer_cmsdk_disable_timer2(dev);
|
||||
}
|
||||
|
||||
/** Interrupts */
|
||||
void dualtimer_cmsdk_enable_interrupt_timer1(
|
||||
const struct dualtimer_cmsdk_dev_t* dev)
|
||||
{
|
||||
SET_BIT(DUALTIMER_REG_MAP(dev)->timer1ctrl, CTRL_REG_IRQ_EN_INDEX);
|
||||
}
|
||||
|
||||
void dualtimer_cmsdk_enable_interrupt_timer2(
|
||||
const struct dualtimer_cmsdk_dev_t* dev)
|
||||
{
|
||||
SET_BIT(DUALTIMER_REG_MAP(dev)->timer2ctrl, CTRL_REG_IRQ_EN_INDEX);
|
||||
}
|
||||
|
||||
void dualtimer_cmsdk_enable_interrupt_both_timers(
|
||||
const struct dualtimer_cmsdk_dev_t* dev)
|
||||
{
|
||||
dualtimer_cmsdk_enable_interrupt_timer1(dev);
|
||||
dualtimer_cmsdk_enable_interrupt_timer2(dev);
|
||||
}
|
||||
|
||||
void dualtimer_cmsdk_disable_interrupt_timer1(
|
||||
const struct dualtimer_cmsdk_dev_t* dev)
|
||||
{
|
||||
CLR_BIT(DUALTIMER_REG_MAP(dev)->timer1ctrl, CTRL_REG_IRQ_EN_INDEX);
|
||||
}
|
||||
|
||||
void dualtimer_cmsdk_disable_interrupt_timer2(
|
||||
const struct dualtimer_cmsdk_dev_t* dev)
|
||||
{
|
||||
CLR_BIT(DUALTIMER_REG_MAP(dev)->timer2ctrl, CTRL_REG_IRQ_EN_INDEX);
|
||||
}
|
||||
|
||||
void dualtimer_cmsdk_disable_interrupt_both_timers(
|
||||
const struct dualtimer_cmsdk_dev_t* dev)
|
||||
{
|
||||
dualtimer_cmsdk_disable_interrupt_timer1(dev);
|
||||
dualtimer_cmsdk_disable_interrupt_timer2(dev);
|
||||
}
|
||||
|
||||
void dualtimer_cmsdk_clear_interrupt_timer1(
|
||||
const struct dualtimer_cmsdk_dev_t* dev)
|
||||
{
|
||||
ATOMIC_SET_BIT(DUALTIMER_REG_MAP(dev)->timer1intclr,
|
||||
XINTCLR_REG_CLEAR_IRQ_INDEX);
|
||||
}
|
||||
|
||||
void dualtimer_cmsdk_clear_interrupt_timer2(
|
||||
const struct dualtimer_cmsdk_dev_t* dev)
|
||||
{
|
||||
ATOMIC_SET_BIT(DUALTIMER_REG_MAP(dev)->timer2intclr,
|
||||
XINTCLR_REG_CLEAR_IRQ_INDEX);
|
||||
}
|
||||
|
||||
/** One Shot */
|
||||
void dualtimer_cmsdk_set_oneshot_count_timer1(
|
||||
const struct dualtimer_cmsdk_dev_t* dev,
|
||||
enum dualtimer_cmsdk_oneshot_t mode)
|
||||
{
|
||||
if (DUALTIMER_CMSDK_ONE_SHOT == mode) {
|
||||
SET_BIT(DUALTIMER_REG_MAP(dev)->timer1ctrl, CTRL_REG_ONE_SHOT_INDEX);
|
||||
} else {
|
||||
CLR_BIT(DUALTIMER_REG_MAP(dev)->timer1ctrl, CTRL_REG_ONE_SHOT_INDEX);
|
||||
}
|
||||
}
|
||||
|
||||
void dualtimer_cmsdk_set_oneshot_count_timer2(
|
||||
const struct dualtimer_cmsdk_dev_t* dev,
|
||||
enum dualtimer_cmsdk_oneshot_t mode)
|
||||
{
|
||||
if (DUALTIMER_CMSDK_ONE_SHOT == mode) {
|
||||
SET_BIT(DUALTIMER_REG_MAP(dev)->timer2ctrl, CTRL_REG_ONE_SHOT_INDEX);
|
||||
} else {
|
||||
CLR_BIT(DUALTIMER_REG_MAP(dev)->timer2ctrl, CTRL_REG_ONE_SHOT_INDEX);
|
||||
}
|
||||
}
|
||||
|
||||
void dualtimer_cmsdk_set_oneshot_count_both_timers(
|
||||
const struct dualtimer_cmsdk_dev_t* dev,
|
||||
enum dualtimer_cmsdk_oneshot_t mode)
|
||||
{
|
||||
dualtimer_cmsdk_set_oneshot_count_timer1(dev, mode);
|
||||
dualtimer_cmsdk_set_oneshot_count_timer2(dev, mode);
|
||||
}
|
||||
|
||||
/** Timer Size */
|
||||
void dualtimer_cmsdk_set_size_timer1(const struct dualtimer_cmsdk_dev_t* dev,
|
||||
enum dualtimer_cmsdk_size_t bit_size)
|
||||
{
|
||||
if (DUALTIMER_CMSDK_SIZE_32BIT == bit_size) {
|
||||
SET_BIT(DUALTIMER_REG_MAP(dev)->timer1ctrl, CTRL_REG_SIZE_INDEX);
|
||||
} else {
|
||||
CLR_BIT(DUALTIMER_REG_MAP(dev)->timer1ctrl, CTRL_REG_SIZE_INDEX);
|
||||
}
|
||||
}
|
||||
void dualtimer_cmsdk_set_size_timer2(const struct dualtimer_cmsdk_dev_t* dev,
|
||||
enum dualtimer_cmsdk_size_t bit_size)
|
||||
{
|
||||
if (DUALTIMER_CMSDK_SIZE_32BIT == bit_size) {
|
||||
SET_BIT(DUALTIMER_REG_MAP(dev)->timer2ctrl, CTRL_REG_SIZE_INDEX);
|
||||
} else {
|
||||
CLR_BIT(DUALTIMER_REG_MAP(dev)->timer2ctrl, CTRL_REG_SIZE_INDEX);
|
||||
}
|
||||
}
|
||||
|
||||
void dualtimer_cmsdk_set_size_both_timers(
|
||||
const struct dualtimer_cmsdk_dev_t* dev,
|
||||
enum dualtimer_cmsdk_size_t bit_size)
|
||||
{
|
||||
dualtimer_cmsdk_set_size_timer1(dev, bit_size);
|
||||
dualtimer_cmsdk_set_size_timer2(dev, bit_size);
|
||||
}
|
||||
|
||||
enum dualtimer_cmsdk_size_t dualtimer_cmsdk_get_size_timer1(
|
||||
const struct dualtimer_cmsdk_dev_t* dev)
|
||||
{
|
||||
if(GET_BIT(DUALTIMER_REG_MAP(dev)->timer1ctrl, CTRL_REG_SIZE_INDEX)) {
|
||||
return DUALTIMER_CMSDK_SIZE_32BIT;
|
||||
}
|
||||
return DUALTIMER_CMSDK_SIZE_16BIT;
|
||||
}
|
||||
|
||||
enum dualtimer_cmsdk_size_t dualtimer_cmsdk_get_size_timer2(
|
||||
const struct dualtimer_cmsdk_dev_t* dev)
|
||||
{
|
||||
if(GET_BIT(DUALTIMER_REG_MAP(dev)->timer2ctrl, CTRL_REG_SIZE_INDEX)) {
|
||||
return DUALTIMER_CMSDK_SIZE_32BIT;
|
||||
}
|
||||
return DUALTIMER_CMSDK_SIZE_16BIT;
|
||||
}
|
||||
|
||||
/** Timer Prescale */
|
||||
void dualtimer_cmsdk_set_prescale_timer1(
|
||||
const struct dualtimer_cmsdk_dev_t* dev,
|
||||
enum dualtimer_cmsdk_prescale_t prescale)
|
||||
{
|
||||
SET_NBITS(DUALTIMER_REG_MAP(dev)->timer1ctrl, CTRL_REG_PRESCALE_INDEX,
|
||||
TWO_BITS_WIDTH, prescale);
|
||||
}
|
||||
|
||||
void dualtimer_cmsdk_set_prescale_timer2(
|
||||
const struct dualtimer_cmsdk_dev_t* dev,
|
||||
enum dualtimer_cmsdk_prescale_t prescale)
|
||||
{
|
||||
SET_NBITS(DUALTIMER_REG_MAP(dev)->timer2ctrl, CTRL_REG_PRESCALE_INDEX,
|
||||
TWO_BITS_WIDTH, prescale);
|
||||
}
|
||||
void dualtimer_cmsdk_set_prescale_both_timers(
|
||||
const struct dualtimer_cmsdk_dev_t* dev,
|
||||
enum dualtimer_cmsdk_prescale_t prescale)
|
||||
{
|
||||
dualtimer_cmsdk_set_prescale_timer1(dev, prescale);
|
||||
dualtimer_cmsdk_set_prescale_timer2(dev, prescale);
|
||||
}
|
||||
|
||||
enum dualtimer_cmsdk_prescale_t dualtimer_cmsdk_get_prescale_timer1(
|
||||
const struct dualtimer_cmsdk_dev_t* dev)
|
||||
{
|
||||
return (enum dualtimer_cmsdk_prescale_t)\
|
||||
GET_NBITS(DUALTIMER_REG_MAP(dev)->timer1ctrl, CTRL_REG_PRESCALE_INDEX,
|
||||
TWO_BITS_WIDTH);
|
||||
}
|
||||
|
||||
enum dualtimer_cmsdk_prescale_t dualtimer_cmsdk_get_prescale_timer2(
|
||||
const struct dualtimer_cmsdk_dev_t* dev)
|
||||
{
|
||||
return (enum dualtimer_cmsdk_prescale_t)\
|
||||
GET_NBITS(DUALTIMER_REG_MAP(dev)->timer2ctrl, CTRL_REG_PRESCALE_INDEX,
|
||||
TWO_BITS_WIDTH);
|
||||
}
|
||||
|
||||
/** Timer Mode */
|
||||
void dualtimer_cmsdk_set_mode_timer1(const struct dualtimer_cmsdk_dev_t* dev,
|
||||
enum dualtimer_cmsdk_mode_t mode)
|
||||
{
|
||||
if (DUALTIMER_CMSDK_PERIODIC == mode) {
|
||||
SET_BIT(DUALTIMER_REG_MAP(dev)->timer1ctrl, CTRL_REG_MODE_INDEX);
|
||||
} else {
|
||||
CLR_BIT(DUALTIMER_REG_MAP(dev)->timer1ctrl, CTRL_REG_MODE_INDEX);
|
||||
}
|
||||
}
|
||||
|
||||
void dualtimer_cmsdk_set_mode_timer2(const struct dualtimer_cmsdk_dev_t* dev,
|
||||
enum dualtimer_cmsdk_mode_t mode)
|
||||
{
|
||||
if (DUALTIMER_CMSDK_PERIODIC == mode) {
|
||||
SET_BIT(DUALTIMER_REG_MAP(dev)->timer2ctrl, CTRL_REG_MODE_INDEX);
|
||||
} else {
|
||||
CLR_BIT(DUALTIMER_REG_MAP(dev)->timer2ctrl, CTRL_REG_MODE_INDEX);
|
||||
}
|
||||
}
|
||||
|
||||
void dualtimer_cmsdk_set_mode_both_timers(
|
||||
const struct dualtimer_cmsdk_dev_t* dev,
|
||||
enum dualtimer_cmsdk_mode_t mode)
|
||||
{
|
||||
dualtimer_cmsdk_set_mode_timer1(dev, mode);
|
||||
dualtimer_cmsdk_set_mode_timer2(dev, mode);
|
||||
}
|
||||
|
||||
enum dualtimer_cmsdk_mode_t dualtimer_cmsdk_get_mode_timer1(
|
||||
const struct dualtimer_cmsdk_dev_t* dev)
|
||||
{
|
||||
return (enum dualtimer_cmsdk_mode_t)\
|
||||
GET_BIT(DUALTIMER_REG_MAP(dev)->timer1ctrl, CTRL_REG_MODE_INDEX);
|
||||
}
|
||||
|
||||
enum dualtimer_cmsdk_mode_t dualtimer_cmsdk_get_mode_timer2(
|
||||
const struct dualtimer_cmsdk_dev_t* dev)
|
||||
{
|
||||
return (enum dualtimer_cmsdk_mode_t)\
|
||||
GET_BIT(DUALTIMER_REG_MAP(dev)->timer2ctrl, CTRL_REG_MODE_INDEX);
|
||||
}
|
||||
|
||||
/** Reload-Background reload */
|
||||
enum dualtimer_cmsdk_error_t dualtimer_cmsdk_set_reload_timer1(
|
||||
const struct dualtimer_cmsdk_dev_t* dev,
|
||||
uint32_t reload)
|
||||
{
|
||||
const uint32_t rel_size = dualtimer_cmsdk_get_size_timer1(dev);
|
||||
if (DUALTIMER_CMSDK_SIZE_16BIT == rel_size && UINT16_MAX <= reload) {
|
||||
return DUALTIMER_CMSDK_ERR_OVERFLOW;
|
||||
}
|
||||
DUALTIMER_REG_MAP(dev)->timer1load = reload;
|
||||
return DUALTIMER_CMSDK_ERR_NONE;
|
||||
}
|
||||
|
||||
enum dualtimer_cmsdk_error_t dualtimer_cmsdk_set_reload_timer2(
|
||||
const struct dualtimer_cmsdk_dev_t* dev,
|
||||
uint32_t reload)
|
||||
{
|
||||
const uint32_t rel_size = dualtimer_cmsdk_get_size_timer2(dev);
|
||||
if (DUALTIMER_CMSDK_SIZE_16BIT == rel_size && UINT16_MAX <= reload) {
|
||||
return DUALTIMER_CMSDK_ERR_OVERFLOW;
|
||||
}
|
||||
DUALTIMER_REG_MAP(dev)->timer2load = reload;
|
||||
return DUALTIMER_CMSDK_ERR_NONE;
|
||||
}
|
||||
|
||||
enum dualtimer_cmsdk_error_t dualtimer_cmsdk_set_reload_both_timers(
|
||||
const struct dualtimer_cmsdk_dev_t* dev,
|
||||
uint32_t reload)
|
||||
{
|
||||
uint32_t ret = 0;
|
||||
ret +=(uint32_t)dualtimer_cmsdk_set_reload_timer2(dev, reload);
|
||||
ret +=(uint32_t)dualtimer_cmsdk_set_reload_timer2(dev, reload);
|
||||
if (ret) {
|
||||
return DUALTIMER_CMSDK_ERR_OVERFLOW;
|
||||
}
|
||||
return DUALTIMER_CMSDK_ERR_NONE;
|
||||
}
|
||||
|
||||
uint32_t dualtimer_cmsdk_get_reload_timer1(
|
||||
const struct dualtimer_cmsdk_dev_t* dev)
|
||||
{
|
||||
return DUALTIMER_REG_MAP(dev)->timer1load;
|
||||
}
|
||||
|
||||
uint32_t dualtimer_cmsdk_get_reload_timer2(
|
||||
const struct dualtimer_cmsdk_dev_t* dev)
|
||||
{
|
||||
return DUALTIMER_REG_MAP(dev)->timer2load;
|
||||
}
|
||||
|
||||
enum dualtimer_cmsdk_error_t dualtimer_cmsdk_set_bgreload_timer1(
|
||||
const struct dualtimer_cmsdk_dev_t* dev,
|
||||
uint32_t reload)
|
||||
{
|
||||
const uint32_t rel_size = dualtimer_cmsdk_get_size_timer1(dev);
|
||||
if (DUALTIMER_CMSDK_SIZE_16BIT == rel_size && UINT16_MAX <= reload) {
|
||||
return DUALTIMER_CMSDK_ERR_OVERFLOW;
|
||||
}
|
||||
DUALTIMER_REG_MAP(dev)->timer1bgload = reload;
|
||||
return DUALTIMER_CMSDK_ERR_NONE;
|
||||
}
|
||||
|
||||
enum dualtimer_cmsdk_error_t dualtimer_cmsdk_set_bgreload_timer2(
|
||||
const struct dualtimer_cmsdk_dev_t* dev,
|
||||
uint32_t reload)
|
||||
{
|
||||
const uint32_t rel_size = dualtimer_cmsdk_get_size_timer2(dev);
|
||||
if (DUALTIMER_CMSDK_SIZE_16BIT == rel_size && UINT16_MAX <= reload) {
|
||||
return DUALTIMER_CMSDK_ERR_OVERFLOW;
|
||||
}
|
||||
DUALTIMER_REG_MAP(dev)->timer2bgload = reload;
|
||||
return DUALTIMER_CMSDK_ERR_NONE;
|
||||
}
|
||||
|
||||
enum dualtimer_cmsdk_error_t dualtimer_cmsdk_set_bgreload_both_timers(
|
||||
const struct dualtimer_cmsdk_dev_t* dev,
|
||||
uint32_t reload)
|
||||
{
|
||||
uint32_t ret = 0;
|
||||
ret +=(uint32_t)dualtimer_cmsdk_set_bgreload_timer1(dev, reload);
|
||||
ret +=(uint32_t)dualtimer_cmsdk_set_bgreload_timer2(dev, reload);
|
||||
if (ret) {
|
||||
return DUALTIMER_CMSDK_ERR_OVERFLOW;
|
||||
}
|
||||
return DUALTIMER_CMSDK_ERR_NONE;
|
||||
}
|
||||
|
||||
uint32_t dualtimer_cmsdk_get_bgreload_timer1(
|
||||
const struct dualtimer_cmsdk_dev_t* dev)
|
||||
{
|
||||
return DUALTIMER_REG_MAP(dev)->timer1bgload;
|
||||
}
|
||||
|
||||
uint32_t dualtimer_cmsdk_get_bgreload_timer2(
|
||||
const struct dualtimer_cmsdk_dev_t* dev)
|
||||
{
|
||||
return DUALTIMER_REG_MAP(dev)->timer2bgload;
|
||||
}
|
||||
|
||||
/** Current timer value */
|
||||
uint32_t dualtimer_cmsdk_get_current_timer1(
|
||||
const struct dualtimer_cmsdk_dev_t* dev)
|
||||
{
|
||||
return DUALTIMER_REG_MAP(dev)->timer1value;
|
||||
}
|
||||
|
||||
uint32_t dualtimer_cmsdk_get_current_timer2(
|
||||
const struct dualtimer_cmsdk_dev_t* dev)
|
||||
{
|
||||
return DUALTIMER_REG_MAP(dev)->timer2value;
|
||||
}
|
||||
|
||||
/** Status check methods */
|
||||
bool dualtimer_cmsdk_is_enabled_timer1(
|
||||
const struct dualtimer_cmsdk_dev_t* dev)
|
||||
{
|
||||
return (bool)GET_BIT(DUALTIMER_REG_MAP(dev)->timer1ctrl,
|
||||
CTRL_REG_TIMER_EN_INDEX);
|
||||
}
|
||||
|
||||
bool dualtimer_cmsdk_is_enabled_timer2(
|
||||
const struct dualtimer_cmsdk_dev_t* dev)
|
||||
{
|
||||
return (bool)GET_BIT(DUALTIMER_REG_MAP(dev)->timer2ctrl,
|
||||
CTRL_REG_TIMER_EN_INDEX);
|
||||
}
|
||||
|
||||
bool dualtimer_cmsdk_is_interrupt_enabled_timer1(
|
||||
const struct dualtimer_cmsdk_dev_t* dev)
|
||||
{
|
||||
return (bool)GET_BIT(DUALTIMER_REG_MAP(dev)->timer1ctrl,
|
||||
CTRL_REG_IRQ_EN_INDEX);
|
||||
}
|
||||
|
||||
bool dualtimer_cmsdk_is_interrupt_enabled_timer2(
|
||||
const struct dualtimer_cmsdk_dev_t* dev)
|
||||
{
|
||||
return (bool)GET_BIT(DUALTIMER_REG_MAP(dev)->timer2ctrl,
|
||||
CTRL_REG_IRQ_EN_INDEX);
|
||||
}
|
||||
|
||||
bool dualtimer_cmsdk_is_interrupt_active_timer1(
|
||||
const struct dualtimer_cmsdk_dev_t* dev)
|
||||
{
|
||||
return (bool)GET_BIT(DUALTIMER_REG_MAP(dev)->timer1mis,
|
||||
XMIS_REG_MASKED_IRQ_INDEX);
|
||||
}
|
||||
|
||||
bool dualtimer_cmsdk_is_interrupt_active_timer2(
|
||||
const struct dualtimer_cmsdk_dev_t* dev)
|
||||
{
|
||||
return (bool)GET_BIT(DUALTIMER_REG_MAP(dev)->timer2mis,
|
||||
XMIS_REG_MASKED_IRQ_INDEX);
|
||||
}
|
||||
|
||||
bool dualtimer_cmsdk_is_raw_interrupt_active_timer1(
|
||||
const struct dualtimer_cmsdk_dev_t* dev)
|
||||
{
|
||||
return (bool)GET_BIT(DUALTIMER_REG_MAP(dev)->timer1ris,
|
||||
XRIS_REG_RAW_IRQ_INDEX);
|
||||
}
|
||||
|
||||
bool dualtimer_cmsdk_is_raw_interrupt_active_timer2(
|
||||
const struct dualtimer_cmsdk_dev_t* dev)
|
||||
{
|
||||
return (bool)GET_BIT(DUALTIMER_REG_MAP(dev)->timer2ris,
|
||||
XRIS_REG_RAW_IRQ_INDEX);
|
||||
}
|
||||
|
||||
uint32_t dualtimer_cmsdk_get_elapsed_value_timer1(
|
||||
const struct dualtimer_cmsdk_dev_t* dev)
|
||||
{
|
||||
struct dualtimer_cmsdk_reg_map_t* register_map =
|
||||
(struct dualtimer_cmsdk_reg_map_t*)dev->cfg->base;
|
||||
return register_map->timer1load - register_map->timer1value;
|
||||
}
|
||||
|
||||
uint32_t dualtimer_cmsdk_get_elapsed_value_timer2(
|
||||
const struct dualtimer_cmsdk_dev_t* dev)
|
||||
{
|
||||
struct dualtimer_cmsdk_reg_map_t* register_map =
|
||||
(struct dualtimer_cmsdk_reg_map_t*)dev->cfg->base;
|
||||
return register_map->timer2load - register_map->timer2value;
|
||||
}
|
||||
|
||||
void dualtimer_cmsdk_reset_timer1(const struct dualtimer_cmsdk_dev_t* dev)
|
||||
{
|
||||
struct dualtimer_cmsdk_reg_map_t* register_map =
|
||||
(struct dualtimer_cmsdk_reg_map_t*)dev->cfg->base;
|
||||
register_map->timer1value = register_map->timer1load;
|
||||
}
|
||||
|
||||
void dualtimer_cmsdk_reset_timer2(const struct dualtimer_cmsdk_dev_t* dev)
|
||||
{
|
||||
struct dualtimer_cmsdk_reg_map_t* register_map =
|
||||
(struct dualtimer_cmsdk_reg_map_t*)dev->cfg->base;
|
||||
register_map->timer2value = register_map->timer2load;
|
||||
}
|
||||
|
||||
void dualtimer_cmsdk_reset_both_timers(const struct dualtimer_cmsdk_dev_t* dev)
|
||||
{
|
||||
struct dualtimer_cmsdk_reg_map_t* register_map =
|
||||
(struct dualtimer_cmsdk_reg_map_t*)dev->cfg->base;
|
||||
register_map->timer1value = register_map->timer1load;
|
||||
register_map->timer2value = register_map->timer2load;
|
||||
}
|
|
@ -0,0 +1,888 @@
|
|||
/*
|
||||
* Copyright (c) 2016-2018 Arm Limited
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
/**
|
||||
* \file dualtimer_cmsdk_drv.h
|
||||
* \brief Generic driver for ARM CMSDK Dualtimers.
|
||||
*/
|
||||
|
||||
#ifndef __DUALTIMER_CMSDK_DRV_H__
|
||||
#define __DUALTIMER_CMSDK_DRV_H__
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Dualtimer default reload value */
|
||||
#define DUALTIMER_CMSDK_DEF_32BIT_RELOAD UINT32_MAX
|
||||
#define DUALTIMER_CMSDK_DEF_16BIT_RELOAD UINT16_MAX
|
||||
|
||||
/* Dualtimer device configuration structure */
|
||||
struct dualtimer_cmsdk_dev_cfg_t {
|
||||
const uint32_t base; /*!< Dualtimer base address */
|
||||
};
|
||||
|
||||
/* Dualtimer device data structure */
|
||||
struct dualtimer_cmsdk_dev_data_t {
|
||||
uint32_t is_initialized; /*!< Indicates if the timer is initialized */
|
||||
};
|
||||
|
||||
/* Dualtimer device structure */
|
||||
struct dualtimer_cmsdk_dev_t {
|
||||
const struct dualtimer_cmsdk_dev_cfg_t* const cfg; /*!< Dualtimer
|
||||
configuration */
|
||||
struct dualtimer_cmsdk_dev_data_t* const data; /*!< Dualtimer data */
|
||||
};
|
||||
|
||||
/* Dualtimer enumeration types */
|
||||
enum dualtimer_cmsdk_error_t {
|
||||
DUALTIMER_CMSDK_ERR_NONE = 0u, /*!< No error */
|
||||
DUALTIMER_CMSDK_ERR_NOT_INIT, /*!< Error dualtimer is not initialized */
|
||||
DUALTIMER_CMSDK_ERR_NOT_ENABLE, /*!< Error timer is not enabled */
|
||||
DUALTIMER_CMSDK_ERR_OVERFLOW
|
||||
};
|
||||
|
||||
enum dualtimer_cmsdk_size_t {
|
||||
DUALTIMER_CMSDK_SIZE_16BIT = 0u, /*!< Timer is set as 16 Bit */
|
||||
DUALTIMER_CMSDK_SIZE_32BIT = 1u /*!< Timer is set as 32 Bit */
|
||||
};
|
||||
|
||||
enum dualtimer_cmsdk_prescale_t {
|
||||
DUALTIMER_CMSDK_CLOCK_DIV1 = 0u, /*!< Timer pre-scale is clock/1 */
|
||||
DUALTIMER_CMSDK_CLOCK_DIV16 = 1u, /*!< Timer pre-scale is clock/16 */
|
||||
DUALTIMER_CMSDK_CLOCK_DIV256 = 2u, /*!< Timer pre-scale is clock/256 */
|
||||
};
|
||||
|
||||
enum dualtimer_cmsdk_oneshot_t {
|
||||
DUALTIMER_CMSDK_WRAPPING = 0u, /*!< Timer wraps around */
|
||||
DUALTIMER_CMSDK_ONE_SHOT = 1u /*!< Timer will halt when reaching 0 */
|
||||
};
|
||||
|
||||
enum dualtimer_cmsdk_mode_t {
|
||||
DUALTIMER_CMSDK_FREE_RUNNING = 0u, /*!< Timer counts from UINT32_MAX */
|
||||
DUALTIMER_CMSDK_PERIODIC = 1u /*!< Timer counts from load value */
|
||||
};
|
||||
|
||||
/**
|
||||
* \brief Initializes a dualtimer hardware.
|
||||
*
|
||||
* \param[in] dev Dualtimer device structure \ref dualtimer_cmsdk_dev_t
|
||||
*
|
||||
* \note This function doesn't check if dev is NULL.
|
||||
* \note Init should be called prior to any other process.
|
||||
*/
|
||||
void dualtimer_cmsdk_init(const struct dualtimer_cmsdk_dev_t* dev);
|
||||
|
||||
/**
|
||||
* \brief Frees up a dualtimer hardware, so it could be reinitalized.
|
||||
*
|
||||
* \param[in] dev Dualtimer device structure \ref dualtimer_cmsdk_dev_t
|
||||
*
|
||||
* \note This function doesn't check if dev is NULL.
|
||||
* \note Init should be called prior to any other process.
|
||||
*/
|
||||
void dualtimer_cmsdk_free(const struct dualtimer_cmsdk_dev_t* dev);
|
||||
|
||||
/**
|
||||
* \brief Enables single timer 1 included in dualtimer hardware.
|
||||
*
|
||||
* \param[in] dev Dualtimer device structure \ref dualtimer_cmsdk_dev_t
|
||||
*
|
||||
* \note This function doesn't check if dev is NULL.
|
||||
* \note This function doesn't check if dualtimer has been initialized.
|
||||
*/
|
||||
void dualtimer_cmsdk_enable_timer1(const struct dualtimer_cmsdk_dev_t* dev);
|
||||
|
||||
/**
|
||||
* \brief Enables single timer 2 included in dualtimer hardware.
|
||||
*
|
||||
* \param[in] dev Dualtimer device structure \ref dualtimer_cmsdk_dev_t
|
||||
*
|
||||
* \note This function doesn't check if dev is NULL.
|
||||
* \note This function doesn't check if dualtimer has been initialized.
|
||||
*/
|
||||
void dualtimer_cmsdk_enable_timer2(const struct dualtimer_cmsdk_dev_t* dev);
|
||||
|
||||
/**
|
||||
* \brief Enables both timer 1&2 included in dualtimer hardware.
|
||||
*
|
||||
* \param[in] dev Dualtimer device structure \ref dualtimer_cmsdk_dev_t
|
||||
*
|
||||
* \note This function doesn't check if dev is NULL.
|
||||
* \note This function doesn't check if dualtimer has been initialized.
|
||||
*/
|
||||
void dualtimer_cmsdk_enable_both_timers(
|
||||
const struct dualtimer_cmsdk_dev_t* dev);
|
||||
|
||||
|
||||
/**
|
||||
* \brief Disables timer 1 included in dualtimer hardware.
|
||||
*
|
||||
* \param[in] dev Dualtimer device structure \ref dualtimer_cmsdk_dev_t
|
||||
*
|
||||
* \note This function doesn't check if dev is NULL.
|
||||
* \note This function doesn't check if dualtimer has been initialized.
|
||||
*/
|
||||
void dualtimer_cmsdk_disable_timer1(
|
||||
const struct dualtimer_cmsdk_dev_t* dev);
|
||||
|
||||
/**
|
||||
* \brief Disables timer 2 included in dualtimer hardware.
|
||||
*
|
||||
* \param[in] dev Dualtimer device structure \ref dualtimer_cmsdk_dev_t
|
||||
*
|
||||
* \note This function doesn't check if dev is NULL.
|
||||
* \note This function doesn't check if dualtimer has been initialized.
|
||||
*/
|
||||
void dualtimer_cmsdk_disable_timer2(const struct dualtimer_cmsdk_dev_t* dev);
|
||||
|
||||
/**
|
||||
* \brief Disables both timers 1&2 included in dualtimer hardware.
|
||||
*
|
||||
* \param[in] dev Dualtimer device structure \ref dualtimer_cmsdk_dev_t
|
||||
*
|
||||
* \note This function doesn't check if dev is NULL.
|
||||
* \note This function doesn't check if dualtimer has been initialized.
|
||||
*/
|
||||
void dualtimer_cmsdk_disable_both_timers(
|
||||
const struct dualtimer_cmsdk_dev_t* dev);
|
||||
|
||||
/**
|
||||
* \brief Sets one shot count for timer 1 included in dualtimer hardware.
|
||||
*
|
||||
* When timer reaches zero if one-shot is set it will wait there until user
|
||||
* does one of the following:
|
||||
* - Write a new value to load register.
|
||||
* - Clear one shot setting the timers to WRAPPING mode.
|
||||
*
|
||||
* \param[in] dev Dualtimer device structure \ref dualtimer_cmsdk_dev_t
|
||||
* \param[in] mode enum dualtimer_cmsdk_oneshot_t WRAPPING/ONE_SHOT
|
||||
*
|
||||
* \note This function doesn't check if dev is NULL.
|
||||
* \note This function doesn't check if dualtimer has been initialized.
|
||||
*/
|
||||
void dualtimer_cmsdk_set_oneshot_count_timer1(
|
||||
const struct dualtimer_cmsdk_dev_t* dev,
|
||||
enum dualtimer_cmsdk_oneshot_t mode);
|
||||
|
||||
/**
|
||||
* \brief Sets one shot count for timer 2 included in dualtimer hardware.
|
||||
*
|
||||
* When timer reaches zero if one-shot is set it will wait there until user
|
||||
* does one of the following:
|
||||
* - Write a new value to load register.
|
||||
* - Clear one shot setting the timers to WRAPPING mode.
|
||||
*
|
||||
* \param[in] dev Dualtimer device structure \ref dualtimer_cmsdk_dev_t
|
||||
* \param[in] mode enum dualtimer_cmsdk_oneshot_t WRAPING/ONE_SHOT
|
||||
*
|
||||
* \note This function doesn't check if dev is NULL.
|
||||
* \note This function doesn't check if dualtimer has been initialized.
|
||||
*/
|
||||
void dualtimer_cmsdk_set_oneshot_count_timer2(
|
||||
const struct dualtimer_cmsdk_dev_t* dev,
|
||||
enum dualtimer_cmsdk_oneshot_t mode);
|
||||
|
||||
/**
|
||||
* \brief Sets one shot count for timers 1&2 included in dualtimer hardware.
|
||||
*
|
||||
* When timer reaches zero if one-shot is set it will wait there until user
|
||||
* does one of the following:
|
||||
* - Write a new value to load register.
|
||||
* - Clear one shot setting the timers to WRAPPING mode.
|
||||
*
|
||||
* \param[in] dev Dualtimer device structure \ref dualtimer_cmsdk_dev_t
|
||||
* \param[in] mode enum dualtimer_cmsdk_oneshot_t WRAPING/ONE_SHOT
|
||||
*
|
||||
* \note This function doesn't check if dev is NULL.
|
||||
* \note This function doesn't check if dualtimer has been initialized.
|
||||
*/
|
||||
void dualtimer_cmsdk_set_oneshot_count_both_timers(
|
||||
const struct dualtimer_cmsdk_dev_t* dev,
|
||||
enum dualtimer_cmsdk_oneshot_t mode);
|
||||
|
||||
/**
|
||||
* \brief Sets the size of timer 1 included in dualtimer hardware.
|
||||
*
|
||||
*
|
||||
* \param[in] dev Dualtimer device structure \ref dualtimer_cmsdk_dev_t
|
||||
* \param[in] bit_size enum dualtimer_cmsdk_oneshot_t SIZE_16BIT/SIZE_32BIT
|
||||
*
|
||||
* \note This function doesn't check if dev is NULL.
|
||||
* \note This function doesn't check if dualtimer has been initialized.
|
||||
*/
|
||||
void dualtimer_cmsdk_set_size_timer1(
|
||||
const struct dualtimer_cmsdk_dev_t* dev,
|
||||
enum dualtimer_cmsdk_size_t bit_size);
|
||||
|
||||
/**
|
||||
* \brief Sets the size of timer 2 included in dualtimer hardware.
|
||||
*
|
||||
*
|
||||
* \param[in] dev Dualtimer device structure \ref dualtimer_cmsdk_dev_t
|
||||
* \param[in] bit_size enum dualtimer_cmsdk_oneshot_t SIZE_16BIT/SIZE_32BIT
|
||||
*
|
||||
* \note This function doesn't check if dev is NULL.
|
||||
* \note This function doesn't check if dualtimer has been initialized.
|
||||
*/
|
||||
void dualtimer_cmsdk_set_size_timer2(
|
||||
const struct dualtimer_cmsdk_dev_t* dev,
|
||||
enum dualtimer_cmsdk_size_t bit_size);
|
||||
|
||||
/**
|
||||
* \brief Sets the size of timers 1&2 included in dualtimer hardware.
|
||||
*
|
||||
*
|
||||
* \param[in] dev Dualtimer device structure \ref dualtimer_cmsdk_dev_t
|
||||
* \param[in] bit_size enum dualtimer_cmsdk_oneshot_t SIZE_16BIT/SIZE_32BIT
|
||||
*
|
||||
* \note This function doesn't check if dev is NULL.
|
||||
* \note This function doesn't check if dualtimer has been initialized.
|
||||
*/
|
||||
void dualtimer_cmsdk_set_size_both_timers(
|
||||
const struct dualtimer_cmsdk_dev_t* dev,
|
||||
enum dualtimer_cmsdk_size_t bit_size);
|
||||
|
||||
/**
|
||||
* \brief Gets the size of timer 1 included in dualtimer hardware.
|
||||
*
|
||||
* \param[in] dev Dualtimer device structure \ref dualtimer_cmsdk_dev_t
|
||||
*
|
||||
* \return enum dualtimer_cmsdk_oneshot_t SIZE_16BIT/SIZE_32BIT
|
||||
*
|
||||
* \note This function doesn't check if dev is NULL.
|
||||
* \note This function doesn't check if dualtimer has been initialized.
|
||||
*/
|
||||
enum dualtimer_cmsdk_size_t dualtimer_cmsdk_get_size_timer1(
|
||||
const struct dualtimer_cmsdk_dev_t* dev);
|
||||
|
||||
/**
|
||||
* \brief Gets the size of timer 2 included in dualtimer hardware.
|
||||
*
|
||||
* \param[in] dev Dualtimer device structure \ref dualtimer_cmsdk_dev_t
|
||||
*
|
||||
* \return enum dualtimer_cmsdk_oneshot_t SIZE_16BIT/SIZE_32BIT
|
||||
*
|
||||
* \note This function doesn't check if dev is NULL.
|
||||
* \note This function doesn't check if dualtimer has been initialized.
|
||||
*/
|
||||
enum dualtimer_cmsdk_size_t dualtimer_cmsdk_get_size_timer2(
|
||||
const struct dualtimer_cmsdk_dev_t* dev);
|
||||
|
||||
/**
|
||||
* \brief Sets the clock divider for timer 1 included in dualtimer hardware.
|
||||
*
|
||||
*
|
||||
* \param[in] dev Dualtimer device structure \ref dualtimer_cmsdk_dev_t
|
||||
* \param[in] enum dualtimer_cmsdk_prescale_t prescale CLOCK_DIV1/16/256
|
||||
*
|
||||
* \note This function doesn't check if dev is NULL.
|
||||
* \note This function doesn't check if dualtimer has been initialized.
|
||||
*/
|
||||
void dualtimer_cmsdk_set_prescale_timer1(
|
||||
const struct dualtimer_cmsdk_dev_t* dev,
|
||||
enum dualtimer_cmsdk_prescale_t prescale);
|
||||
|
||||
/**
|
||||
* \brief Sets the clock divider for timer 2 included in dualtimer hardware.
|
||||
*
|
||||
*
|
||||
* \param[in] dev Dualtimer device structure \ref dualtimer_cmsdk_dev_t
|
||||
* \param[in] enum dualtimer_cmsdk_prescale_t prescale CLOCK_DIV1/16/256
|
||||
*
|
||||
* \note This function doesn't check if dev is NULL.
|
||||
* \note This function doesn't check if dualtimer has been initialized.
|
||||
*/
|
||||
void dualtimer_cmsdk_set_prescale_timer2(
|
||||
const struct dualtimer_cmsdk_dev_t* dev,
|
||||
enum dualtimer_cmsdk_prescale_t prescale);
|
||||
|
||||
/**
|
||||
* \brief Sets the clock divider for timers 1&2 included in dualtimer hardware.
|
||||
*
|
||||
*
|
||||
* \param[in] dev Dualtimer device structure \ref dualtimer_cmsdk_dev_t
|
||||
* \param[in] enum dualtimer_cmsdk_prescale_t prescale CLOCK_DIV1/16/256
|
||||
*
|
||||
* \note This function doesn't check if dev is NULL.
|
||||
* \note This function doesn't check if dualtimer has been initialized.
|
||||
*/
|
||||
void dualtimer_cmsdk_set_prescale_both_timers(
|
||||
const struct dualtimer_cmsdk_dev_t* dev,
|
||||
enum dualtimer_cmsdk_prescale_t prescale);
|
||||
|
||||
/**
|
||||
* \brief Gets the current set prescale value for timer 1.
|
||||
*
|
||||
* \param[in] dev Dualtimer device structure \ref dualtimer_cmsdk_dev_t
|
||||
*
|
||||
* \return enum dualtimer_cmsdk_prescale_t prescale CLOCK_DIV1/16/256
|
||||
*
|
||||
* \note This function doesn't check if dev is NULL.
|
||||
* \note This function doesn't check if dualtimer has been initialized.
|
||||
*/
|
||||
enum dualtimer_cmsdk_prescale_t dualtimer_cmsdk_get_prescale_timer1(
|
||||
const struct dualtimer_cmsdk_dev_t* dev);
|
||||
|
||||
|
||||
/**
|
||||
* \brief Gets the current set prescale value for timer 2.
|
||||
*
|
||||
* \param[in] dev Dualtimer device structure \ref dualtimer_cmsdk_dev_t
|
||||
*
|
||||
* \return enum dualtimer_cmsdk_prescale_t prescale CLOCK_DIV1/16/256
|
||||
*
|
||||
* \note This function doesn't check if dev is NULL.
|
||||
* \note This function doesn't check if dualtimer has been initialized.
|
||||
*/
|
||||
enum dualtimer_cmsdk_prescale_t dualtimer_cmsdk_get_prescale_timer2(
|
||||
const struct dualtimer_cmsdk_dev_t* dev);
|
||||
|
||||
/**
|
||||
* \brief Sets the run mode for timer1 1 included in dualtimer hardware.
|
||||
*
|
||||
* \param[in] dev Dualtimer device structure \ref dualtimer_cmsdk_dev_t
|
||||
* \param[in] enum dualtimer_cmsdk_mode_t mode FREE_RUNNING/PERIODIC
|
||||
*
|
||||
* \note This function doesn't check if dev is NULL.
|
||||
* \note This function doesn't check if dualtimer has been initialized.
|
||||
*/
|
||||
void dualtimer_cmsdk_set_mode_timer1(const struct dualtimer_cmsdk_dev_t* dev,
|
||||
enum dualtimer_cmsdk_mode_t mode);
|
||||
|
||||
/**
|
||||
* \brief Sets the run mode for timer 2 included in dualtimer hardware.
|
||||
*
|
||||
* \param[in] dev Dualtimer device structure \ref dualtimer_cmsdk_dev_t
|
||||
* \param[in] enum dualtimer_cmsdk_mode_t mode FREE_RUNNING/PERIODIC
|
||||
*
|
||||
* \note This function doesn't check if dev is NULL.
|
||||
* \note This function doesn't check if dualtimer has been initialized.
|
||||
*/
|
||||
void dualtimer_cmsdk_set_mode_timer2(const struct dualtimer_cmsdk_dev_t* dev,
|
||||
enum dualtimer_cmsdk_mode_t mode);
|
||||
|
||||
/**
|
||||
* \brief Sets the run mode for timers 1&2 included in dualtimer hardware.
|
||||
*
|
||||
* \param[in] dev Dualtimer device structure \ref dualtimer_cmsdk_dev_t
|
||||
* \param[in] enum dualtimer_cmsdk_mode_t mode FREE_RUNNING/PERIODIC
|
||||
*
|
||||
* \note This function doesn't check if dev is NULL.
|
||||
* \note This function doesn't check if dualtimer has been initialized.
|
||||
*/
|
||||
void dualtimer_cmsdk_set_mode_both_timers(
|
||||
const struct dualtimer_cmsdk_dev_t* dev,
|
||||
enum dualtimer_cmsdk_mode_t mode);
|
||||
|
||||
/**
|
||||
* \brief Gets the run mode for timer 1 included in dualtimer hardware.
|
||||
*
|
||||
* \param[in] dev Dualtimer device structure \ref dualtimer_cmsdk_dev_t
|
||||
*
|
||||
* \return enum dualtimer_cmsdk_mode_t mode FREE_RUNNING/PERIODIC
|
||||
*
|
||||
* \note This function doesn't check if dev is NULL.
|
||||
* \note This function doesn't check if dualtimer has been initialized.
|
||||
*/
|
||||
enum dualtimer_cmsdk_mode_t dualtimer_cmsdk_get_mode_timer1(
|
||||
const struct dualtimer_cmsdk_dev_t* dev);
|
||||
|
||||
/**
|
||||
* \brief Gets the run mode for timer 2 included in dualtimer hardware.
|
||||
*
|
||||
* \param[in] dev Dualtimer device structure \ref dualtimer_cmsdk_dev_t
|
||||
*
|
||||
* \return enum dualtimer_cmsdk_mode_t mode FREE_RUNNING/PERIODIC
|
||||
*
|
||||
* \note This function doesn't check if dev is NULL.
|
||||
* \note This function doesn't check if dualtimer has been initialized.
|
||||
*/
|
||||
enum dualtimer_cmsdk_mode_t dualtimer_cmsdk_get_mode_timer2(
|
||||
const struct dualtimer_cmsdk_dev_t* dev);
|
||||
|
||||
/**
|
||||
* \brief Enables the interrupt for timer 1 included in dualtimer hardware.
|
||||
*
|
||||
* \param[in] dev Dualtimer device structure \ref dualtimer_cmsdk_dev_t
|
||||
*
|
||||
* \note This function doesn't check if dev is NULL.
|
||||
* \note This function doesn't check if dualtimer has been initialized.
|
||||
* \note This function only enables the hardware irq, use NVIC for handler setup.
|
||||
*/
|
||||
void dualtimer_cmsdk_enable_interrupt_timer1(
|
||||
const struct dualtimer_cmsdk_dev_t* dev);
|
||||
|
||||
/**
|
||||
* \brief Enables the interrupt for timer 2 included in dualtimer hardware.
|
||||
*
|
||||
* \param[in] dev Dualtimer device structure \ref dualtimer_cmsdk_dev_t
|
||||
*
|
||||
* \note This function doesn't check if dev is NULL.
|
||||
* \note This function doesn't check if dualtimer has been initialized.
|
||||
* \note This function only enables the hardware irq, use NVIC for handler setup.
|
||||
*/
|
||||
void dualtimer_cmsdk_enable_interrupt_timer2(
|
||||
const struct dualtimer_cmsdk_dev_t* dev);
|
||||
|
||||
/**
|
||||
* \brief Enables the interrupt for timer 1&2 included in dualtimer hardware.
|
||||
*
|
||||
* \param[in] dev Dualtimer device structure \ref dualtimer_cmsdk_dev_t
|
||||
*
|
||||
* \note This function doesn't check if dev is NULL.
|
||||
* \note This function doesn't check if dualtimer has been initialized.
|
||||
* \note This function only enables the hardware irq, use NVIC for handler setup.
|
||||
*/
|
||||
void dualtimer_cmsdk_enable_interrupt_both_timers(
|
||||
const struct dualtimer_cmsdk_dev_t* dev);
|
||||
|
||||
/**
|
||||
* \brief Disables the interrupt for timer 1 included in dualtimer hardware.
|
||||
*
|
||||
* \param[in] dev Dualtimer device structure \ref dualtimer_cmsdk_dev_t
|
||||
*
|
||||
* \note This function doesn't check if dev is NULL.
|
||||
* \note This function doesn't check if dualtimer has been initialized.
|
||||
*/
|
||||
void dualtimer_cmsdk_disable_interrupt_timer1(
|
||||
const struct dualtimer_cmsdk_dev_t* dev);
|
||||
|
||||
/**
|
||||
* \brief Disables the interrupt for timer 2 included in dualtimer hardware.
|
||||
*
|
||||
* \param[in] dev Dualtimer device structure \ref dualtimer_cmsdk_dev_t
|
||||
*
|
||||
* \note This function doesn't check if dev is NULL.
|
||||
* \note This function doesn't check if dualtimer has been initialized.
|
||||
*/
|
||||
void dualtimer_cmsdk_disable_interrupt_timer2(
|
||||
const struct dualtimer_cmsdk_dev_t* dev);
|
||||
|
||||
/**
|
||||
* \brief Disables the interrupt for timers 1&2 included in dualtimer hardware.
|
||||
*
|
||||
* \param[in] dev Dualtimer device structure \ref dualtimer_cmsdk_dev_t
|
||||
*
|
||||
* \note This function doesn't check if dev is NULL.
|
||||
* \note This function doesn't check if dualtimer has been initialized.
|
||||
*/
|
||||
void dualtimer_cmsdk_disable_interrupt_both_timers(
|
||||
const struct dualtimer_cmsdk_dev_t* dev);
|
||||
|
||||
/**
|
||||
* \brief Clears the interrupt for timer 1 included in dualtimer hardware.
|
||||
*
|
||||
* \param[in] dev Dualtimer device structure \ref dualtimer_cmsdk_dev_t
|
||||
*
|
||||
* \note This function doesn't check if dev is NULL.
|
||||
* \note This function doesn't check if dualtimer has been initialized.
|
||||
*/
|
||||
void dualtimer_cmsdk_clear_interrupt_timer1(
|
||||
const struct dualtimer_cmsdk_dev_t* dev);
|
||||
|
||||
/**
|
||||
* \brief Clears the interrupt for timer 2 included in dualtimer hardware.
|
||||
*
|
||||
* \param[in] dev Dualtimer device structure \ref dualtimer_cmsdk_dev_t
|
||||
*
|
||||
* \note This function doesn't check if dev is NULL.
|
||||
* \note This function doesn't check if dualtimer has been initialized.
|
||||
*/
|
||||
void dualtimer_cmsdk_clear_interrupt_timer2(
|
||||
const struct dualtimer_cmsdk_dev_t* dev);
|
||||
|
||||
/**
|
||||
* \brief Set the reload value for timer 1 included in dualtimer hardware.
|
||||
*
|
||||
* Writing to the reload register while timer is active will reset the
|
||||
* current value register to the reload value
|
||||
*
|
||||
* \param[in] dev Dualtimer device structure \ref dualtimer_cmsdk_dev_t
|
||||
* \param[in] reload uint32_t value that the timer counts down from
|
||||
*
|
||||
* \return dualtimer_cmsdk_error_t NONE/ERR_OVERFLOW
|
||||
*
|
||||
* \note This function doesn't check if dev is NULL.
|
||||
* \note This function doesn't check if dualtimer has been initialized.
|
||||
* \note This function will detect if users sets a uint32_t value to 16Bit timer
|
||||
*/
|
||||
enum dualtimer_cmsdk_error_t dualtimer_cmsdk_set_reload_timer1(
|
||||
const struct dualtimer_cmsdk_dev_t* dev,
|
||||
uint32_t reload);
|
||||
|
||||
/**
|
||||
* \brief Set the reload value for timer 2 included in dualtimer hardware.
|
||||
*
|
||||
* Writing to the reload register while timer is active will reset the
|
||||
* current value register to the reload value
|
||||
*
|
||||
* \param[in] dev Dualtimer device structure \ref dualtimer_cmsdk_dev_t
|
||||
* \param[in] reload uint32_t value that the timer counts down from
|
||||
*
|
||||
* \return dualtimer_cmsdk_error_t NONE/ERR_OVERFLOW
|
||||
*
|
||||
* \note This function doesn't check if dev is NULL.
|
||||
* \note This function doesn't check if dualtimer has been initialized.
|
||||
* \note This function will detect if users sets a uint32_t value to 16Bit timer
|
||||
*/
|
||||
enum dualtimer_cmsdk_error_t dualtimer_cmsdk_set_reload_timer2(
|
||||
const struct dualtimer_cmsdk_dev_t* dev,
|
||||
uint32_t reload);
|
||||
|
||||
/**
|
||||
* \brief Set the reload value for timers 1&2 included in dualtimer hardware.
|
||||
*
|
||||
* Writing to the reload register while timer is active will reset the
|
||||
* current value register to the reload value
|
||||
*
|
||||
* \param[in] dev Dualtimer device structure \ref dualtimer_cmsdk_dev_t
|
||||
* \param[in] reload uint32_t value that the timer counts down from
|
||||
*
|
||||
* \return dualtimer_cmsdk_error_t NONE/ERR_OVERFLOW
|
||||
*
|
||||
* \note This function doesn't check if dev is NULL.
|
||||
* \note This function doesn't check if dualtimer has been initialized.
|
||||
* \note This function will detect if users sets a uint32_t value to 16Bit timer
|
||||
*/
|
||||
enum dualtimer_cmsdk_error_t dualtimer_cmsdk_set_reload_both_timers(
|
||||
const struct dualtimer_cmsdk_dev_t* dev,
|
||||
uint32_t reload);
|
||||
|
||||
/**
|
||||
* \brief Gets the reload value for timer 1 included in dualtimer hardware.
|
||||
*
|
||||
* \param[in] dev Dualtimer device structure \ref dualtimer_cmsdk_dev_t
|
||||
*
|
||||
* \return uint32_t Reload value of timer 1
|
||||
*
|
||||
* \note This function doesn't check if dev is NULL.
|
||||
* \note This function doesn't check if dualtimer has been initialized.
|
||||
*/
|
||||
uint32_t dualtimer_cmsdk_get_reload_timer1(
|
||||
const struct dualtimer_cmsdk_dev_t* dev);
|
||||
|
||||
/**
|
||||
* \brief Gets the reload value for timer 2 included in dualtimer hardware.
|
||||
*
|
||||
* \param[in] dev Dualtimer device structure \ref dualtimer_cmsdk_dev_t
|
||||
*
|
||||
* \return uint32_t Reload value of timer 2
|
||||
*
|
||||
* \note This function doesn't check if dev is NULL.
|
||||
* \note This function doesn't check if dualtimer has been initialized.
|
||||
*/
|
||||
uint32_t dualtimer_cmsdk_get_reload_timer2(
|
||||
const struct dualtimer_cmsdk_dev_t* dev);
|
||||
|
||||
/**
|
||||
* \brief Set the background-reload value for timer 1 of dualtimer hw.
|
||||
*
|
||||
* Unlike normal reload, writing to this register will not affect current
|
||||
* value of timer, and the change become effective after the timer counts to zero
|
||||
*
|
||||
* \param[in] dev Dualtimer device structure \ref dualtimer_cmsdk_dev_t
|
||||
* \param[in] reload uint32_t value that the timer counts down from
|
||||
*
|
||||
* \return dualtimer_cmsdk_error_t NONE/ERR_OVERFLOW
|
||||
*
|
||||
* \note This function doesn't check if dev is NULL.
|
||||
* \note This function doesn't check if dualtimer has been initialized.
|
||||
* \note This function will detect if users sets a uint32_t value to 16Bit timer
|
||||
*/
|
||||
enum dualtimer_cmsdk_error_t dualtimer_cmsdk_set_bgreload_timer1(
|
||||
const struct dualtimer_cmsdk_dev_t* dev,
|
||||
uint32_t reload);
|
||||
|
||||
/**
|
||||
* \brief Set the background-reload value for timers 2 of dualtimer hw.
|
||||
*
|
||||
* Unlike normal reload, writing to this register will not affect current
|
||||
* value of timer, and the change become effective after the timer counts to zero
|
||||
*
|
||||
* \param[in] dev Dualtimer device structure \ref dualtimer_cmsdk_dev_t
|
||||
* \param[in] reload uint32_t value that the timer counts down from
|
||||
*
|
||||
* \return dualtimer_cmsdk_error_t NONE/ERR_OVERFLOW
|
||||
*
|
||||
* \note This function doesn't check if dev is NULL.
|
||||
* \note This function doesn't check if dualtimer has been initialized.
|
||||
* \note This function will detect if users sets a uint32_t value to 16Bit timer
|
||||
*/
|
||||
enum dualtimer_cmsdk_error_t dualtimer_cmsdk_set_bgreload_timer2(
|
||||
const struct dualtimer_cmsdk_dev_t* dev,
|
||||
uint32_t reload);
|
||||
|
||||
/**
|
||||
* \brief Set the background-reload value for timers 1&2 of dualtimer hw.
|
||||
*
|
||||
* Unlike normal reload, writing to this register will not affect current
|
||||
* value of timer, and the change become effective after the timer counts to zero
|
||||
*
|
||||
* \param[in] dev Dualtimer device structure \ref dualtimer_cmsdk_dev_t
|
||||
* \param[in] reload uint32_t value that the timer counts down from
|
||||
*
|
||||
* \return dualtimer_cmsdk_error_t NONE/ERR_OVERFLOW
|
||||
*
|
||||
* \note This function doesn't check if dev is NULL.
|
||||
* \note This function doesn't check if dualtimer has been initialized.
|
||||
* \note This function will detect if users sets a uint32_t value to 16Bit timer
|
||||
*/
|
||||
enum dualtimer_cmsdk_error_t dualtimer_cmsdk_set_bgreload_both_timers(
|
||||
const struct dualtimer_cmsdk_dev_t* dev,
|
||||
uint32_t reload);
|
||||
|
||||
/**
|
||||
* \brief Gets the background-reload value for timer 1 of dualtimer hw.
|
||||
*
|
||||
* \param[in] dev Dualtimer device structure \ref dualtimer_cmsdk_dev_t
|
||||
*
|
||||
* \return uint32_t Reload value of timer 1
|
||||
*
|
||||
* \note This function doesn't check if dev is NULL.
|
||||
* \note This function doesn't check if dualtimer has been initialized.
|
||||
*/
|
||||
uint32_t dualtimer_cmsdk_get_bgreload_timer1(
|
||||
const struct dualtimer_cmsdk_dev_t* dev);
|
||||
|
||||
/**
|
||||
* \brief Gets the background-reload value for timer 2 of dualtimer hw.
|
||||
*
|
||||
* \param[in] dev Dualtimer device structure \ref dualtimer_cmsdk_dev_t
|
||||
*
|
||||
* \return uint32_t Reload value of timer 2
|
||||
*
|
||||
* \note This function doesn't check if dev is NULL.
|
||||
* \note This function doesn't check if dualtimer has been initialized.
|
||||
*/
|
||||
uint32_t dualtimer_cmsdk_get_bgreload_timer2(
|
||||
const struct dualtimer_cmsdk_dev_t* dev);
|
||||
|
||||
/**
|
||||
* \brief Gets the current value for timer 1 included in dualtimer hardware.
|
||||
*
|
||||
*
|
||||
* \param[in] dev Dualtimer device structure \ref dualtimer_cmsdk_dev_t
|
||||
*
|
||||
* \return uint32_t Copy of current value of timer.
|
||||
*
|
||||
* \note This function doesn't check if dev is NULL.
|
||||
* \note This function doesn't check if dualtimer has been initialized.
|
||||
*/
|
||||
uint32_t dualtimer_cmsdk_get_current_timer1(
|
||||
const struct dualtimer_cmsdk_dev_t* dev);
|
||||
|
||||
/**
|
||||
* \brief Gets the current value for timer 2 included in dualtimer hardware.
|
||||
*
|
||||
*
|
||||
* \param[in] dev Dualtimer device structure \ref dualtimer_cmsdk_dev_t
|
||||
*
|
||||
* \return uint32_t Copy of current value of timer.
|
||||
*
|
||||
* \note This function doesn't check if dev is NULL.
|
||||
* \note This function doesn't check if dualtimer has been initialized.
|
||||
*/
|
||||
uint32_t dualtimer_cmsdk_get_current_timer2(
|
||||
const struct dualtimer_cmsdk_dev_t* dev);
|
||||
|
||||
/**
|
||||
* \brief Checks if timer 1 included in dualtimer hardware, is enabled.
|
||||
*
|
||||
*
|
||||
* \param[in] dev Dualtimer device structure \ref dualtimer_cmsdk_dev_t
|
||||
*
|
||||
* \return bool true if timer 1 is enabled.
|
||||
*
|
||||
* \note This function doesn't check if dev is NULL.
|
||||
* \note This function doesn't check if dualtimer has been initialized.
|
||||
*/
|
||||
bool dualtimer_cmsdk_is_enabled_timer1(const struct dualtimer_cmsdk_dev_t* dev);
|
||||
|
||||
/**
|
||||
* \brief Checks if timer 2 included in dualtimer hardware, is enabled.
|
||||
*
|
||||
*
|
||||
* \param[in] dev Dualtimer device structure \ref dualtimer_cmsdk_dev_t
|
||||
*
|
||||
* \return bool true if timer 2 is enabled.
|
||||
*
|
||||
* \note This function doesn't check if dev is NULL.
|
||||
* \note This function doesn't check if dualtimer has been initialized.
|
||||
*/
|
||||
bool dualtimer_cmsdk_is_enabled_timer2(const struct dualtimer_cmsdk_dev_t* dev);
|
||||
|
||||
/**
|
||||
* \brief Checks if timer 1 included in dualtimer hardware, has the irq enabled.
|
||||
*
|
||||
*
|
||||
* \param[in] dev Dualtimer device structure \ref dualtimer_cmsdk_dev_t
|
||||
*
|
||||
* \return bool true if timer 1 irq is enabled.
|
||||
*
|
||||
* \note This function doesn't check if dev is NULL.
|
||||
* \note This function doesn't check if dualtimer has been initialized.
|
||||
*/
|
||||
bool dualtimer_cmsdk_is_interrupt_enabled_timer1(
|
||||
const struct dualtimer_cmsdk_dev_t* dev);
|
||||
|
||||
/**
|
||||
* \brief Checks if timer 2 included in dualtimer hardware, has the irq enabled.
|
||||
*
|
||||
*
|
||||
* \param[in] dev Dualtimer device structure \ref dualtimer_cmsdk_dev_t
|
||||
*
|
||||
* \return bool true if timer 2 irq is enabled.
|
||||
*
|
||||
* \note This function doesn't check if dev is NULL.
|
||||
* \note This function doesn't check if dualtimer has been initialized.
|
||||
*/
|
||||
bool dualtimer_cmsdk_is_interrupt_enabled_timer2(
|
||||
const struct dualtimer_cmsdk_dev_t* dev);
|
||||
|
||||
/**
|
||||
* \brief Checks the masked interrupt status of timer 1 included in dualtimer hw.
|
||||
*
|
||||
* This function is checking against the masked interrupt register which is the
|
||||
* output of timerx enabled AND timerX raw interrupt.
|
||||
*
|
||||
* \param[in] dev Dualtimer device structure \ref dualtimer_cmsdk_dev_t
|
||||
*
|
||||
* \return bool true if timer 1's masked irq is active
|
||||
*
|
||||
* \note This function doesn't check if dev is NULL.
|
||||
* \note This function doesn't check if dualtimer has been initialized.
|
||||
*/
|
||||
bool dualtimer_cmsdk_is_interrupt_active_timer1(
|
||||
const struct dualtimer_cmsdk_dev_t* dev);
|
||||
|
||||
/**
|
||||
* \brief Checks the masked interrupt status of timer 1 included in dualtimer hw.
|
||||
*
|
||||
* This function is checking against the masked interrupt register which is the
|
||||
* output of timerx enabled AND timerX raw interrupt.
|
||||
*
|
||||
* \param[in] dev Dualtimer device structure \ref dualtimer_cmsdk_dev_t
|
||||
*
|
||||
* \return bool true if timer 2's masked irq is active
|
||||
*
|
||||
* \note This function doesn't check if dev is NULL.
|
||||
* \note This function doesn't check if dualtimer has been initialized.
|
||||
*/
|
||||
bool dualtimer_cmsdk_is_interrupt_active_timer2(
|
||||
const struct dualtimer_cmsdk_dev_t* dev);
|
||||
|
||||
/**
|
||||
* \brief Checks the raw interrupt status of timer 1 included in dualtimer hw.
|
||||
*
|
||||
* This function is checking for the raw interrupt produced when timer reaches 0
|
||||
*
|
||||
* \param[in] dev Dualtimer device structure \ref dualtimer_cmsdk_dev_t
|
||||
*
|
||||
* \return bool true if timer 1's masked irq is active
|
||||
*
|
||||
* \note This function doesn't check if dev is NULL.
|
||||
* \note This function doesn't check if dualtimer has been initialized.
|
||||
*/
|
||||
bool dualtimer_cmsdk_is_raw_interrupt_active_timer1(
|
||||
const struct dualtimer_cmsdk_dev_t* dev);
|
||||
|
||||
/**
|
||||
* \brief Checks the raw interrupt status of timer 1 included in dualtimer hw.
|
||||
*
|
||||
* This function is checking for the raw interrupt produced when timer reaches 0
|
||||
*
|
||||
* \param[in] dev Dualtimer device structure \ref dualtimer_cmsdk_dev_t
|
||||
*
|
||||
* \return bool true if timer 2's masked irq is active
|
||||
*
|
||||
* \note This function doesn't check if dev is NULL.
|
||||
* \note This function doesn't check if dualtimer has been initialized.
|
||||
*/
|
||||
bool dualtimer_cmsdk_is_raw_interrupt_active_timer2(
|
||||
const struct dualtimer_cmsdk_dev_t* dev);
|
||||
|
||||
/**
|
||||
* \brief Checks if dualtimer hardware has been initialized.
|
||||
*
|
||||
* \param[in] dev Dualtimer device structure \ref dualtimer_cmsdk_dev_t
|
||||
*
|
||||
* \return bool true if dualtimer has been initialized.
|
||||
*
|
||||
* \note This function doesn't check if dev is NULL.
|
||||
*/
|
||||
bool dualtimer_cmsdk_is_initialized(const struct dualtimer_cmsdk_dev_t* dev);
|
||||
|
||||
/**
|
||||
* \brief Reads the number of ticks elapsed in the current cycle of timer 1.
|
||||
*
|
||||
* \param[in] dev Dualtimer device structure \ref dualtimer_cmsdk_dev_t
|
||||
*
|
||||
* \return Get elapsed number of ticks since last reload was set.
|
||||
* Elapsed = (Reload value - Current value)
|
||||
*/
|
||||
uint32_t dualtimer_cmsdk_get_elapsed_value_timer1(
|
||||
const struct dualtimer_cmsdk_dev_t* dev);
|
||||
|
||||
/**
|
||||
* \brief Reads the number of ticks elapsed in the current cycle of timer 2.
|
||||
*
|
||||
* \param[in] dev Dualtimer device structure \ref dualtimer_cmsdk_dev_t
|
||||
*
|
||||
* \return Get elapsed number of ticks since last reload was set.
|
||||
* Elapsed = (Reload value - Current value)
|
||||
*/
|
||||
uint32_t dualtimer_cmsdk_get_elapsed_value_timer2(
|
||||
const struct dualtimer_cmsdk_dev_t* dev);
|
||||
|
||||
/**
|
||||
* \brief Resets the timer 1 count value to the reload value.
|
||||
*
|
||||
* \param[in] dev Dualtimer device structure \ref dualtimer_cmsdk_dev_t
|
||||
*
|
||||
* \note This function doesn't check if dev is NULL.
|
||||
* \note This function doesn't check if dualtimer has been initialized.
|
||||
*/
|
||||
void dualtimer_cmsdk_reset_timer1(const struct dualtimer_cmsdk_dev_t* dev);
|
||||
|
||||
/**
|
||||
* \brief Resets the timer 2 count value to the reload value.
|
||||
*
|
||||
* \param[in] dev Dualtimer device structure \ref dualtimer_cmsdk_dev_t
|
||||
*
|
||||
* \note This function doesn't check if dev is NULL.
|
||||
* \note This function doesn't check if dualtimer has been initialized.
|
||||
*/
|
||||
void dualtimer_cmsdk_reset_timer2(const struct dualtimer_cmsdk_dev_t* dev);
|
||||
|
||||
/**
|
||||
* \brief Resets both timers' count values to their reload values.
|
||||
*
|
||||
* \param[in] dev Dualtimer device structure \ref dualtimer_cmsdk_dev_t
|
||||
*
|
||||
* \note This function doesn't check if dev is NULL.
|
||||
* \note This function doesn't check if dualtimer has been initialized.
|
||||
*/
|
||||
void dualtimer_cmsdk_reset_both_timers(const struct dualtimer_cmsdk_dev_t* dev);
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif /* __DUALTIMER_CMSDK_DRV_H__ */
|
|
@ -0,0 +1,226 @@
|
|||
/*
|
||||
* Copyright (c) 2018 Arm Limited
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
/**
|
||||
* \file rtc_pl031_drv.c
|
||||
* \brief Implementation of the PL031 Real Time Clock (RTC) native driver.
|
||||
*
|
||||
* \note PL031 device specific definitions based on
|
||||
* real_time_clock_pl031_r1p3_technical_reference_manual.pdf
|
||||
* which is available from http://infocenter.arm.com.
|
||||
*/
|
||||
|
||||
#include <stddef.h>
|
||||
#include "rtc_pl031_drv.h"
|
||||
|
||||
/**
|
||||
* \brief Structure to access the memory mapped registers of the PL031.
|
||||
*/
|
||||
struct rtc_pl031_dev_reg_map_t {
|
||||
volatile uint32_t rtcdr; /*!< Data Register */
|
||||
volatile uint32_t rtcmr; /*!< Match Register */
|
||||
volatile uint32_t rtclr; /*!< Load Register */
|
||||
volatile uint32_t rtccr; /*!< Control Register */
|
||||
volatile uint32_t rtcimsc;
|
||||
/*!< Interrupt Mask Set or Clear Register */
|
||||
volatile uint32_t rtcris; /*!< Raw Interrupt Status Register */
|
||||
volatile uint32_t rtcmis; /*!< Masked Interrupt Status Register */
|
||||
volatile uint32_t rtcicr; /*!< Interrupt Clear Register */
|
||||
volatile uint32_t reserved[1008]; /*!< Reserved from Offset 0x20-0xFDC */
|
||||
volatile uint32_t rtcperiphid0; /*!< Peripheral ID0 Register */
|
||||
volatile uint32_t rtcperiphid1; /*!< Peripheral ID1 Register */
|
||||
volatile uint32_t rtcperiphid2; /*!< Peripheral ID2 Register */
|
||||
volatile uint32_t rtcperiphid3; /*!< Peripheral ID3 Register */
|
||||
volatile uint32_t rtcpcellid0; /*!< Primary Cell ID0 Register */
|
||||
volatile uint32_t rtcpcellid1; /*!< Primary Cell ID1 Register */
|
||||
volatile uint32_t rtcpcellid2; /*!< Primary Cell ID2 Register */
|
||||
volatile uint32_t rtcpcellid3; /*!< Primary Cell ID3 Register */
|
||||
};
|
||||
|
||||
/* RTC Control Register */
|
||||
#define RTC_PL031_RTCCR_ENABLE_POS 0x0U
|
||||
#define RTC_PL031_RTCCR_ENABLE_MSK (0x1U << RTC_PL031_RTCCR_ENABLE_POS)
|
||||
|
||||
/* RTC Interrupt Mask Set or Clear Register */
|
||||
#define RTC_PL031_RTCIMSC_SET_CLEAR_POS 0x0U
|
||||
#define RTC_PL031_RTCIMSC_SET_CLEAR_MSK (0x1U << \
|
||||
RTC_PL031_RTCIMSC_SET_CLEAR_POS)
|
||||
|
||||
/* RTC RAW Interrupt Status Register */
|
||||
#define RTC_PL031_RTCRIS_STATUS_POS 0x0U
|
||||
#define RTC_PL031_RTCRIS_STATUS_MSK (0x1U << RTC_PL031_RTCRIS_STATUS_POS)
|
||||
|
||||
/* RTC Masked Interrupt Status Register */
|
||||
#define RTC_PL031_RTCMIS_STATUS_POS 0x0U
|
||||
#define RTC_PL031_RTCMIS_STATUS_MSK (0x1U << RTC_PL031_RTCMIS_STATUS_POS)
|
||||
|
||||
/* RTC Interrupt Clear Register */
|
||||
#define RTC_PL031_RTCICR_CLEAR_POS 0x0U
|
||||
#define RTC_PL031_RTCICR_CLEAR_MSK (0x1U << RTC_PL031_RTCICR_CLEAR_POS)
|
||||
|
||||
bool rtc_pl031_init(struct rtc_pl031_dev_t* dev)
|
||||
{
|
||||
struct rtc_pl031_dev_reg_map_t* p_rtc;
|
||||
|
||||
if (dev == NULL) {
|
||||
return false;
|
||||
}
|
||||
|
||||
p_rtc = (struct rtc_pl031_dev_reg_map_t*) dev->cfg->base;
|
||||
p_rtc->rtcmr = 0U;
|
||||
p_rtc->rtcicr = RTC_PL031_RTCICR_CLEAR_MSK;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool rtc_pl031_dev_enable(struct rtc_pl031_dev_t* dev)
|
||||
{
|
||||
struct rtc_pl031_dev_reg_map_t* p_rtc;
|
||||
|
||||
if (dev == NULL) {
|
||||
return false;
|
||||
}
|
||||
|
||||
p_rtc = (struct rtc_pl031_dev_reg_map_t*) dev->cfg->base;
|
||||
p_rtc->rtccr = RTC_PL031_RTCCR_ENABLE_MSK;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool rtc_pl031_dev_disable(struct rtc_pl031_dev_t* dev)
|
||||
{
|
||||
struct rtc_pl031_dev_reg_map_t* p_rtc;
|
||||
|
||||
if (dev == NULL) {
|
||||
return false;
|
||||
}
|
||||
|
||||
p_rtc = (struct rtc_pl031_dev_reg_map_t*) dev->cfg->base;
|
||||
p_rtc->rtccr = 0U;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool rtc_pl031_read_current_time(struct rtc_pl031_dev_t* dev, uint32_t *seconds)
|
||||
{
|
||||
struct rtc_pl031_dev_reg_map_t* p_rtc;
|
||||
|
||||
if (dev == NULL || seconds == NULL) {
|
||||
return false;
|
||||
}
|
||||
|
||||
p_rtc = (struct rtc_pl031_dev_reg_map_t*) dev->cfg->base;
|
||||
*seconds = (uint32_t)p_rtc->rtcdr;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool rtc_pl031_write_current_time(struct rtc_pl031_dev_t* dev, uint32_t seconds)
|
||||
{
|
||||
struct rtc_pl031_dev_reg_map_t* p_rtc;
|
||||
|
||||
if (dev == NULL) {
|
||||
return false;
|
||||
}
|
||||
|
||||
p_rtc = (struct rtc_pl031_dev_reg_map_t*) dev->cfg->base;
|
||||
p_rtc->rtclr = (uint32_t)seconds;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool rtc_pl031_enable_interrupt(struct rtc_pl031_dev_t* dev)
|
||||
{
|
||||
struct rtc_pl031_dev_reg_map_t* p_rtc;
|
||||
|
||||
if (dev == NULL) {
|
||||
return false;
|
||||
}
|
||||
|
||||
p_rtc = (struct rtc_pl031_dev_reg_map_t*) dev->cfg->base;
|
||||
p_rtc->rtcimsc = 0U;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool rtc_pl031_disable_interrupt(struct rtc_pl031_dev_t* dev)
|
||||
{
|
||||
struct rtc_pl031_dev_reg_map_t* p_rtc;
|
||||
|
||||
if (dev == NULL) {
|
||||
return false;
|
||||
}
|
||||
|
||||
p_rtc = (struct rtc_pl031_dev_reg_map_t*) dev->cfg->base;
|
||||
p_rtc->rtcimsc = RTC_PL031_RTCIMSC_SET_CLEAR_MSK;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool rtc_pl031_is_interrupt_masked(struct rtc_pl031_dev_t* dev)
|
||||
{
|
||||
struct rtc_pl031_dev_reg_map_t* p_rtc =
|
||||
(struct rtc_pl031_dev_reg_map_t*) dev->cfg->base;
|
||||
|
||||
if (p_rtc->rtcimsc & RTC_PL031_RTCIMSC_SET_CLEAR_MSK){
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool rtc_pl031_is_raw_interrupt_pending(struct rtc_pl031_dev_t* dev)
|
||||
{
|
||||
struct rtc_pl031_dev_reg_map_t* p_rtc =
|
||||
(struct rtc_pl031_dev_reg_map_t*) dev->cfg->base;
|
||||
|
||||
if (p_rtc->rtcris & RTC_PL031_RTCRIS_STATUS_MSK) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool rtc_pl031_is_masked_interrupt_pending(struct rtc_pl031_dev_t* dev)
|
||||
{
|
||||
struct rtc_pl031_dev_reg_map_t* p_rtc =
|
||||
(struct rtc_pl031_dev_reg_map_t*) dev->cfg->base;
|
||||
|
||||
if (p_rtc->rtcmis & RTC_PL031_RTCMIS_STATUS_MSK) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool rtc_pl031_write_match_value(struct rtc_pl031_dev_t* dev, uint32_t seconds)
|
||||
{
|
||||
struct rtc_pl031_dev_reg_map_t* p_rtc;
|
||||
|
||||
if (dev == NULL) {
|
||||
return false;
|
||||
}
|
||||
|
||||
p_rtc = (struct rtc_pl031_dev_reg_map_t*) dev->cfg->base;
|
||||
p_rtc->rtcmr = (uint32_t)seconds;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool rtc_pl031_clear_interrupt(struct rtc_pl031_dev_t* dev)
|
||||
{
|
||||
struct rtc_pl031_dev_reg_map_t* p_rtc;
|
||||
|
||||
if (dev == NULL) {
|
||||
return false;
|
||||
}
|
||||
|
||||
p_rtc = (struct rtc_pl031_dev_reg_map_t*) dev->cfg->base;
|
||||
p_rtc->rtcicr = RTC_PL031_RTCICR_CLEAR_MSK;
|
||||
return true;
|
||||
}
|
|
@ -0,0 +1,180 @@
|
|||
/*
|
||||
* Copyright (c) 2018 Arm Limited
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
/**
|
||||
* \file rtc_pl031_drv.h
|
||||
* \brief Declarations for the PL031 Real Time Clock (RTC) native driver.
|
||||
*/
|
||||
|
||||
#ifndef __RTC_PL031_DRV_H__
|
||||
#define __RTC_PL031_DRV_H__
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* \brief RTC PL031 device configuration structure.
|
||||
*/
|
||||
struct rtc_pl031_dev_cfg_t {
|
||||
const uintptr_t base; /*!< RTC PL031 base address */
|
||||
};
|
||||
|
||||
/**
|
||||
* \brief RTC PL031 device structure.
|
||||
*/
|
||||
struct rtc_pl031_dev_t {
|
||||
const struct rtc_pl031_dev_cfg_t* const cfg;
|
||||
/*!< RTC driver configuration */
|
||||
};
|
||||
|
||||
/**
|
||||
* \brief Initializes the RTC PL031 device.
|
||||
*
|
||||
* \param[in] dev RTC device structure \ref rtc_pl031_dev_t.
|
||||
*
|
||||
* \return Return true indicates that the function executed successfully,
|
||||
* otherwise an error occurred.
|
||||
*/
|
||||
bool rtc_pl031_init(struct rtc_pl031_dev_t* dev);
|
||||
|
||||
/**
|
||||
* \brief Enables RTC PL031 device.
|
||||
*
|
||||
* \param[in] dev RTC device structure \ref rtc_pl031_dev_t.
|
||||
*
|
||||
* \return Return true indicates that the function executed successfully,
|
||||
* otherwise an error occurred.
|
||||
*/
|
||||
bool rtc_pl031_dev_enable(struct rtc_pl031_dev_t* dev);
|
||||
|
||||
/**
|
||||
* \brief Disables RTC PL031 device.
|
||||
*
|
||||
* \param[in] dev RTC device structure \ref rtc_pl031_dev_t.
|
||||
*
|
||||
* \return Return true indicates that the function executed successfully,
|
||||
* otherwise an error occurred.
|
||||
*/
|
||||
bool rtc_pl031_dev_disable(struct rtc_pl031_dev_t* dev);
|
||||
|
||||
/**
|
||||
* \brief Reads current time from RTC PL031 device.
|
||||
*
|
||||
* \param[in] dev RTC device structure \ref rtc_pl031_dev_t.
|
||||
* \param[out] seconds Current time in seconds.
|
||||
*
|
||||
* \return Return true indicates that the function executed successfully,
|
||||
* otherwise an error occurred.
|
||||
*/
|
||||
bool rtc_pl031_read_current_time(struct rtc_pl031_dev_t* dev,
|
||||
uint32_t *seconds);
|
||||
|
||||
/**
|
||||
* \brief Writes current time to RTC PL031 device.
|
||||
*
|
||||
* \param[in] dev RTC device structure \ref rtc_pl031_dev_t.
|
||||
* \param[in] seconds Current time to be set in seconds.
|
||||
*
|
||||
* \return Return true indicates that the function executed successfully,
|
||||
* otherwise an error occurred.
|
||||
*/
|
||||
bool rtc_pl031_write_current_time(struct rtc_pl031_dev_t* dev,
|
||||
uint32_t seconds);
|
||||
|
||||
/**
|
||||
* \brief Clears interrupt mask of RTC PL031.
|
||||
*
|
||||
* \param[in] dev RTC device structure \ref rtc_pl031_dev_t.
|
||||
*
|
||||
* \return Return true indicates that the function executed successfully,
|
||||
* otherwise an error occurred.
|
||||
*/
|
||||
bool rtc_pl031_enable_interrupt(struct rtc_pl031_dev_t* dev);
|
||||
|
||||
/**
|
||||
* \brief Sets interrupt mask of RTC PL031.
|
||||
*
|
||||
* \param[in] dev RTC device structure \ref rtc_pl031_dev_t.
|
||||
*
|
||||
* \return Return true indicates that the function executed successfully,
|
||||
* otherwise an error occurred.
|
||||
*/
|
||||
bool rtc_pl031_disable_interrupt(struct rtc_pl031_dev_t* dev);
|
||||
|
||||
/**
|
||||
* \brief Check if RTC PL031 interrupt is masked.
|
||||
*
|
||||
* \param[in] dev RTC device structure \ref rtc_pl031_dev_t.
|
||||
*
|
||||
* \return Return true indicates that RTC PL031 interrupt is masked.
|
||||
*
|
||||
* \note This function does not check if dev is NULL.
|
||||
*/
|
||||
bool rtc_pl031_is_interrupt_masked(struct rtc_pl031_dev_t* dev);
|
||||
|
||||
/**
|
||||
* \brief Gets raw interrupt pending status of RTC PL031.
|
||||
*
|
||||
* \param[in] dev RTC device structure \ref rtc_pl031_dev_t.
|
||||
*
|
||||
* \return Return true indicates that RTC PL031 raw interrupt
|
||||
* status is pending.
|
||||
*
|
||||
* \note This function does not check if dev is NULL.
|
||||
*/
|
||||
bool rtc_pl031_is_raw_interrupt_pending(struct rtc_pl031_dev_t* dev);
|
||||
|
||||
/**
|
||||
* \brief Gets masked interrupt pending status of RTC PL031.
|
||||
*
|
||||
* \param[in] dev RTC device structure \ref rtc_pl031_dev_t.
|
||||
*
|
||||
* \return Return true indicates that RTC PL031 masked interrupt
|
||||
* status is pending.
|
||||
*
|
||||
* \note This function does not check if dev is NULL.
|
||||
*/
|
||||
bool rtc_pl031_is_masked_interrupt_pending(struct rtc_pl031_dev_t* dev);
|
||||
|
||||
/**
|
||||
* \brief Writes match value to RTC PL031 device.
|
||||
*
|
||||
* \param[in] dev RTC device structure \ref rtc_pl031_dev_t.
|
||||
* \param[in] seconds Match value to be set in seconds.
|
||||
*
|
||||
* \return Return true indicates that the function executed successfully,
|
||||
* otherwise an error occurred.
|
||||
*/
|
||||
bool rtc_pl031_write_match_value(struct rtc_pl031_dev_t* dev, uint32_t seconds);
|
||||
|
||||
/**
|
||||
* \brief Clear interrupt status bit of RTC PL031.
|
||||
*
|
||||
* \param[in] dev RTC device structure \ref rtc_pl031_dev_t.
|
||||
*
|
||||
* \return Return true indicates that the function executed successfully,
|
||||
* otherwise an error occurred.
|
||||
*/
|
||||
bool rtc_pl031_clear_interrupt(struct rtc_pl031_dev_t* dev);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif /* __RTC_PL031_DRV_H__ */
|
|
@ -37,6 +37,23 @@ struct timer_cmsdk_dev_t CMSDK_TIMER1_DEV = {&(CMSDK_TIMER1_DEV_CFG),
|
|||
&(CMSDK_TIMER1_DEV_DATA)};
|
||||
#endif
|
||||
|
||||
/* ARM CMSDK Dual Timer driver structure */
|
||||
#ifdef ARM_CMSDK_DUALTIMER
|
||||
static const struct dualtimer_cmsdk_dev_cfg_t CMSDK_DUALTIMER_DEV_CFG = {
|
||||
.base = CMSDK_DUALTIMER_BASE};
|
||||
static struct dualtimer_cmsdk_dev_data_t CMSDK_DUALTIMER_DEV_DATA = {
|
||||
.is_initialized = 0};
|
||||
struct dualtimer_cmsdk_dev_t CMSDK_DUALTIMER_DEV = {&(CMSDK_DUALTIMER_DEV_CFG),
|
||||
&(CMSDK_DUALTIMER_DEV_DATA)};
|
||||
#endif
|
||||
|
||||
/* PL031 Real-Time Clock structure */
|
||||
#ifdef RTC_PL031
|
||||
static const struct rtc_pl031_dev_cfg_t RTC_PL031_DEV_CFG = {
|
||||
.base = CMSDK_RTC_BASE};
|
||||
struct rtc_pl031_dev_t RTC_PL031_DEV = {&(RTC_PL031_DEV_CFG)};
|
||||
#endif
|
||||
|
||||
/* ARM GPIO driver structures */
|
||||
#ifdef ARM_GPIO0
|
||||
static const struct arm_gpio_dev_cfg_t ARM_GPIO0_DEV_CFG = {
|
||||
|
|
|
@ -20,84 +20,107 @@
|
|||
/* ======= Configures the peripheral set ======= */
|
||||
#include "device_cfg.h"
|
||||
|
||||
/* ======= Includes generic driver headers ======= */
|
||||
#include "timer_cmsdk_drv.h"
|
||||
#include "arm_gpio_drv.h"
|
||||
#include "arm_mps2_io_drv.h"
|
||||
#include "spi_pl022_drv.h"
|
||||
#include "arm_uart_drv.h"
|
||||
#include "smsc9220_eth_drv.h"
|
||||
|
||||
/* ======= Defines peripheral configuration structures ======= */
|
||||
|
||||
/* ARM CMSDK Timer driver structures */
|
||||
#ifdef ARM_CMSDK_TIMER0
|
||||
#include "timer_cmsdk_drv.h"
|
||||
extern struct timer_cmsdk_dev_t CMSDK_TIMER0_DEV;
|
||||
#endif
|
||||
|
||||
#ifdef ARM_CMSDK_TIMER1
|
||||
#include "timer_cmsdk_drv.h"
|
||||
extern struct timer_cmsdk_dev_t CMSDK_TIMER1_DEV;
|
||||
#endif
|
||||
|
||||
/* ARM CMSDK Dual Timer driver structure */
|
||||
#ifdef ARM_CMSDK_DUALTIMER
|
||||
#include "dualtimer_cmsdk_drv.h"
|
||||
extern struct dualtimer_cmsdk_dev_t CMSDK_DUALTIMER_DEV;
|
||||
#endif
|
||||
|
||||
/* RTC PL031 */
|
||||
#ifdef RTC_PL031
|
||||
#include "rtc_pl031_drv.h"
|
||||
extern struct rtc_pl031_dev_t RTC_PL031_DEV;
|
||||
#endif
|
||||
|
||||
/* ARM GPIO driver structures */
|
||||
#ifdef ARM_GPIO0
|
||||
#include "arm_gpio_drv.h"
|
||||
extern struct arm_gpio_dev_t ARM_GPIO0_DEV;
|
||||
#endif
|
||||
#ifdef ARM_GPIO1
|
||||
#include "arm_gpio_drv.h"
|
||||
extern struct arm_gpio_dev_t ARM_GPIO1_DEV;
|
||||
#endif
|
||||
#ifdef ARM_GPIO2
|
||||
#include "arm_gpio_drv.h"
|
||||
extern struct arm_gpio_dev_t ARM_GPIO2_DEV;
|
||||
#endif
|
||||
#ifdef ARM_GPIO3
|
||||
#include "arm_gpio_drv.h"
|
||||
extern struct arm_gpio_dev_t ARM_GPIO3_DEV;
|
||||
#endif
|
||||
|
||||
/* ARM MPS2 IO FPGAIO driver structures */
|
||||
#ifdef ARM_MPS2_IO_FPGAIO
|
||||
#include "arm_mps2_io_drv.h"
|
||||
extern struct arm_mps2_io_dev_t ARM_MPS2_IO_FPGAIO_DEV;
|
||||
#endif
|
||||
|
||||
/* ARM MPS2 IO SCC driver structures */
|
||||
#ifdef ARM_MPS2_IO_SCC
|
||||
#include "arm_mps2_io_drv.h"
|
||||
extern struct arm_mps2_io_dev_t ARM_MPS2_IO_SCC_DEV;
|
||||
#endif
|
||||
|
||||
/* ARM SPI driver structures */
|
||||
#ifdef ARM_SPI0
|
||||
#include "spi_pl022_drv.h"
|
||||
extern struct spi_pl022_dev_t SPI0_PL022_DEV;
|
||||
#endif
|
||||
#ifdef ARM_SPI1
|
||||
#include "spi_pl022_drv.h"
|
||||
extern struct spi_pl022_dev_t SPI1_PL022_DEV;
|
||||
#endif
|
||||
#ifdef ARM_SPI2
|
||||
#include "spi_pl022_drv.h"
|
||||
extern struct spi_pl022_dev_t SPI2_PL022_DEV;
|
||||
#endif
|
||||
#ifdef ARM_SPI3
|
||||
#include "spi_pl022_drv.h"
|
||||
extern struct spi_pl022_dev_t SPI3_PL022_DEV;
|
||||
#endif
|
||||
#ifdef ARM_SPI4
|
||||
#include "spi_pl022_drv.h"
|
||||
extern struct spi_pl022_dev_t SPI4_PL022_DEV;
|
||||
#endif
|
||||
|
||||
/* ARM UART driver structures */
|
||||
#ifdef ARM_UART0
|
||||
#include "arm_uart_drv.h"
|
||||
extern struct arm_uart_dev_t ARM_UART0_DEV;
|
||||
#endif
|
||||
#ifdef ARM_UART1
|
||||
#include "arm_uart_drv.h"
|
||||
extern struct arm_uart_dev_t ARM_UART1_DEV;
|
||||
#endif
|
||||
#ifdef ARM_UART2
|
||||
#include "arm_uart_drv.h"
|
||||
extern struct arm_uart_dev_t ARM_UART2_DEV;
|
||||
#endif
|
||||
#ifdef ARM_UART3
|
||||
#include "arm_uart_drv.h"
|
||||
extern struct arm_uart_dev_t ARM_UART3_DEV;
|
||||
#endif
|
||||
#ifdef ARM_UART4
|
||||
#include "arm_uart_drv.h"
|
||||
extern struct arm_uart_dev_t ARM_UART4_DEV;
|
||||
#endif
|
||||
|
||||
#ifdef SMSC9220_ETH
|
||||
#include "smsc9220_eth_drv.h"
|
||||
extern struct smsc9220_eth_dev_t SMSC9220_ETH_DEV;
|
||||
#endif
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/* mbed Microcontroller Library
|
||||
* Copyright (c) 2018 ARM Limited
|
||||
* Copyright (c) 2017-2018 Arm Limited
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
|
@ -14,108 +14,95 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Low-power elapsed time measure and interval timer in micro-secundum,
|
||||
* servicing \ref lp_ticker_api.h, using CMSDK Timer1 \ref CMSDK_TIMER1_DEV.
|
||||
*/
|
||||
/**
|
||||
* Supports the Low Power Ticker for mbed by implementing \ref lp_ticker_api.h,
|
||||
* using both timers in a CMSDK Dual Timer \ref dualtimer_cmsdk_dev_t.
|
||||
*/
|
||||
|
||||
#include <limits.h>
|
||||
|
||||
#include "cmsdk_ticker.h"
|
||||
#include "dualtimer_cmsdk_drv.h"
|
||||
#include "lp_ticker_api.h"
|
||||
#include "platform_devices.h"
|
||||
|
||||
#if DEVICE_LPTICKER
|
||||
/**
|
||||
* \brief Calculate clocks to us
|
||||
*
|
||||
* \param[in] tick Number of clock ticks
|
||||
*
|
||||
* \return Number of usec, relative to the timer frequency,
|
||||
* that a given ammount of ticks equates to.
|
||||
static uint32_t last_read = 0;
|
||||
|
||||
/* Initializes both timers in the Dualtimer:
|
||||
* -Timer1 as the free running timer
|
||||
* -Timer2 as the interval timer
|
||||
* Both timers are set:
|
||||
* -32 bit size
|
||||
* -256 Clk divisor
|
||||
* -Maximum reload value
|
||||
*/
|
||||
static uint32_t convert_tick_to_us(uint32_t tick)
|
||||
{
|
||||
return (tick / (SystemCoreClock / SEC_TO_USEC_MULTIPLIER));
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Calculate us to clock ticks
|
||||
*
|
||||
* \param[in] us Time to convert to clock ticks
|
||||
*
|
||||
* \return Number of clock ticks relative to the timer frequency,
|
||||
* that a given period of usec equates to.
|
||||
*/
|
||||
static uint32_t convert_us_to_tick(uint32_t us)
|
||||
{
|
||||
return (us * (SystemCoreClock / SEC_TO_USEC_MULTIPLIER));
|
||||
}
|
||||
|
||||
static const struct tick_cfg_t cfg =
|
||||
{
|
||||
.timer_driver = &CMSDK_TIMER1_DEV,
|
||||
.irq_n = TIMER1_IRQn,
|
||||
.interval_callback = &lp_ticker_irq_handler,
|
||||
.convert_tick_to_time = &convert_tick_to_us,
|
||||
.convert_time_to_tick = &convert_us_to_tick
|
||||
};
|
||||
|
||||
static struct tick_data_t data =
|
||||
{
|
||||
.is_initialized = false,
|
||||
.cumulated_time = 0,
|
||||
.max_interval_time = 0,
|
||||
.reload_time = 0,
|
||||
.interval_callback_enabled = false,
|
||||
.previous_cumulated_time = 0,
|
||||
.previous_elapsed = 0
|
||||
};
|
||||
|
||||
static struct tick_drv_data_t timer_data =
|
||||
{
|
||||
.cfg = &cfg,
|
||||
.data = &data
|
||||
};
|
||||
|
||||
void lp_ticker_init(void)
|
||||
{
|
||||
cmsdk_ticker_init(&timer_data);
|
||||
}
|
||||
|
||||
uint32_t lp_ticker_read()
|
||||
{
|
||||
return cmsdk_ticker_read(&timer_data);
|
||||
}
|
||||
|
||||
void lp_ticker_set_interrupt(timestamp_t timestamp)
|
||||
{
|
||||
cmsdk_ticker_set_interrupt(&timer_data, timestamp);
|
||||
}
|
||||
|
||||
void lp_ticker_disable_interrupt(void)
|
||||
{
|
||||
cmsdk_ticker_disable_interrupt(&timer_data);
|
||||
}
|
||||
|
||||
void lp_ticker_clear_interrupt(void)
|
||||
{
|
||||
cmsdk_ticker_clear_interrupt(&timer_data);
|
||||
}
|
||||
|
||||
void lp_ticker_fire_interrupt(void)
|
||||
{
|
||||
cmsdk_ticker_fire_interrupt(&timer_data);
|
||||
dualtimer_cmsdk_init(&LP_TIMER_DEV);
|
||||
dualtimer_cmsdk_set_size_both_timers(&LP_TIMER_DEV,
|
||||
DUALTIMER_CMSDK_SIZE_32BIT);
|
||||
dualtimer_cmsdk_set_prescale_both_timers(&LP_TIMER_DEV,
|
||||
DUALTIMER_CMSDK_CLOCK_DIV256);
|
||||
dualtimer_cmsdk_disable_both_timers(&LP_TIMER_DEV);
|
||||
dualtimer_cmsdk_set_reload_both_timers(&LP_TIMER_DEV,
|
||||
TIMER_CMSDK_MAX_RELOAD);
|
||||
dualtimer_cmsdk_reset_both_timers(&LP_TIMER_DEV);
|
||||
NVIC_EnableIRQ(LP_INTERVAL_IRQ);
|
||||
dualtimer_cmsdk_enable_both_timers(&LP_TIMER_DEV);
|
||||
}
|
||||
|
||||
void lp_ticker_free(void)
|
||||
{
|
||||
|
||||
dualtimer_cmsdk_free(&LP_TIMER_DEV);
|
||||
}
|
||||
|
||||
void TIMER1_IRQHandler(void)
|
||||
uint32_t lp_ticker_read()
|
||||
{
|
||||
cmsdk_ticker_irq_handler(&timer_data);
|
||||
uint32_t tick = dualtimer_cmsdk_get_elapsed_value_timer1(&LP_TIMER_DEV);
|
||||
last_read = tick >> LP_REPORTED_SHIFT;
|
||||
return last_read;
|
||||
}
|
||||
|
||||
void lp_ticker_set_interrupt(timestamp_t timestamp)
|
||||
{
|
||||
uint32_t reload = (timestamp - last_read) << LP_REPORTED_SHIFT;
|
||||
dualtimer_cmsdk_disable_timer2(&LP_TIMER_DEV);
|
||||
dualtimer_cmsdk_set_reload_timer2(&LP_TIMER_DEV, reload);
|
||||
dualtimer_cmsdk_reset_timer2(&LP_TIMER_DEV);
|
||||
dualtimer_cmsdk_enable_interrupt_timer2(&LP_TIMER_DEV);
|
||||
dualtimer_cmsdk_enable_timer2(&LP_TIMER_DEV);
|
||||
}
|
||||
|
||||
void lp_ticker_disable_interrupt(void)
|
||||
{
|
||||
dualtimer_cmsdk_disable_interrupt_timer2(&LP_TIMER_DEV);
|
||||
}
|
||||
|
||||
void lp_ticker_clear_interrupt(void)
|
||||
{
|
||||
dualtimer_cmsdk_clear_interrupt_timer2(&LP_TIMER_DEV);
|
||||
}
|
||||
|
||||
void lp_ticker_fire_interrupt(void)
|
||||
{
|
||||
NVIC_SetPendingIRQ(LP_INTERVAL_IRQ);
|
||||
}
|
||||
|
||||
const ticker_info_t* lp_ticker_get_info()
|
||||
{
|
||||
static const ticker_info_t info = {
|
||||
LP_REPORTED_FREQ_HZ,
|
||||
LP_REPORTED_BITS
|
||||
};
|
||||
return &info;
|
||||
}
|
||||
|
||||
#ifndef lp_interval_irq_handler
|
||||
#error "lp_interval_irq_handler should be defined, check device_cfg.h!"
|
||||
#endif
|
||||
/* According to mbed's specification, the free running timer shouldn't fire
|
||||
* interrupt, since the upper layer polls that and handles the overflow,
|
||||
* by cumulating the read values.
|
||||
*/
|
||||
void lp_interval_irq_handler(void)
|
||||
{
|
||||
lp_ticker_disable_interrupt();
|
||||
lp_ticker_irq_handler();
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2017 ARM Limited
|
||||
* Copyright (c) 2018 Arm Limited
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
|
@ -15,8 +15,10 @@
|
|||
*/
|
||||
|
||||
#include "rtc_api.h"
|
||||
#include "device.h"
|
||||
#include "cmsis.h"
|
||||
#include "platform_devices.h"
|
||||
#include "rtc_pl031_drv.h"
|
||||
|
||||
static uint32_t is_enabled = 0;
|
||||
|
||||
/**
|
||||
* \defgroup hal_rtc RTC hal functions
|
||||
|
@ -31,7 +33,9 @@
|
|||
*/
|
||||
void rtc_init(void)
|
||||
{
|
||||
CMSDK_RTC->RTCCR |= (1 << CMSDK_RTC_ENABLE_Pos);
|
||||
rtc_pl031_init(&RTC_PL031_DEV);
|
||||
rtc_pl031_dev_enable(&RTC_PL031_DEV);
|
||||
is_enabled = 1;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -41,7 +45,7 @@ void rtc_init(void)
|
|||
*/
|
||||
void rtc_free(void)
|
||||
{
|
||||
/* Not supported */
|
||||
is_enabled = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -51,17 +55,24 @@ void rtc_free(void)
|
|||
*/
|
||||
int rtc_isenabled(void)
|
||||
{
|
||||
return (CMSDK_RTC->RTCCR & CMSDK_RTC_ENABLE_Msk);
|
||||
return is_enabled;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Get the current time from the RTC peripheral
|
||||
*
|
||||
* Sysclock and RTC clock may not be in sync which can cause reading
|
||||
* out metastable values. It's usually prevented by adding a loop,
|
||||
* however PL031 has a syncronisation block to prevent this, therefore
|
||||
* no additional loop needed.
|
||||
*
|
||||
* \return The current time in seconds
|
||||
*/
|
||||
time_t rtc_read(void)
|
||||
{
|
||||
return (time_t)CMSDK_RTC->RTCDR;
|
||||
uint32_t val;
|
||||
rtc_pl031_read_current_time(&RTC_PL031_DEV, &val);
|
||||
return (time_t)val;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -72,7 +83,7 @@ time_t rtc_read(void)
|
|||
|
||||
void rtc_write(time_t t)
|
||||
{
|
||||
CMSDK_RTC->RTCLR = (uint32_t)t;
|
||||
rtc_pl031_write_current_time(&RTC_PL031_DEV, (uint32_t)t);
|
||||
}
|
||||
/**@}*/
|
||||
|
||||
|
|
|
@ -0,0 +1,50 @@
|
|||
|
||||
/** \addtogroup hal */
|
||||
/** @{*/
|
||||
/* mbed Microcontroller Library
|
||||
* Copyright (c) 2018 Arm Limited
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include "platform_devices.h"
|
||||
#include "sleep_api.h"
|
||||
#include "timer_cmsdk_drv.h"
|
||||
|
||||
#if DEVICE_SLEEP
|
||||
|
||||
void hal_sleep(void)
|
||||
{
|
||||
__WFI();
|
||||
}
|
||||
|
||||
/* Since there is no power management implemented in CM3DS, Deep Sleep could be
|
||||
* supported only by additional software components, registering and managing
|
||||
* the currently configured IPs. This would also mean a huge implementation
|
||||
* overhead, that is not intended to be added. Therefore, Deep Sleep is almost
|
||||
* identical to Sleep, representing a "Waiting For Interrupt" state, and
|
||||
* disabling the Microsec ticker in addition */
|
||||
void hal_deepsleep(void)
|
||||
{
|
||||
#if DEVICE_USTICKER
|
||||
timer_cmsdk_disable(&USEC_TIMER_DEV);
|
||||
#endif
|
||||
__WFI();
|
||||
#if DEVICE_USTICKER
|
||||
timer_cmsdk_enable(&USEC_TIMER_DEV);
|
||||
#endif
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
/**@}*/
|
|
@ -15,124 +15,104 @@
|
|||
*/
|
||||
|
||||
/**
|
||||
* Elapsed time measure and interval timer in micro-secundum,
|
||||
* servicing \ref us_ticker_api.h, using CMSDK Timer0 \ref CMSDK_TIMER0_DEV.
|
||||
* Supports the High-resolution Ticker for mbed by implementing
|
||||
* \ref us_ticker_api.h, using a CMSDK Timer \ref timer_cmsdk_dev_t.
|
||||
*/
|
||||
|
||||
#include "cmsdk_ticker.h"
|
||||
#include "us_ticker_api.h"
|
||||
#include "platform_devices.h"
|
||||
#include "timer_cmsdk_drv.h"
|
||||
|
||||
/*
|
||||
* The CMSDK Ticker counts on 32 bits.
|
||||
static uint64_t total_ticks = 0;
|
||||
/* Stores the last reload value, or the last tick value read when a read API
|
||||
* call occurs from the upper layer, needed to keep total_ticks
|
||||
* accumulated properly.
|
||||
*/
|
||||
#define CMSDK_TICKER_COUNTER_BITS 32U
|
||||
static uint32_t previous_ticks = 0;
|
||||
static uint32_t last_read = 0;
|
||||
|
||||
/**
|
||||
* \brief Pass-through function to make the US ticker HAL only work in the tick
|
||||
* domain. This function is needed by the CMSDK Ticker layer.
|
||||
*
|
||||
* \param[in] tick Number of clock ticks
|
||||
*
|
||||
* \return The number of ticks given.
|
||||
*/
|
||||
static uint32_t convert_tick_to_us(uint32_t tick)
|
||||
static void restart_timer(uint32_t new_reload)
|
||||
{
|
||||
/* Work only in the tick domain. */
|
||||
return tick;
|
||||
timer_cmsdk_disable(&USEC_TIMER_DEV);
|
||||
timer_cmsdk_set_reload_value(&USEC_TIMER_DEV,
|
||||
new_reload);
|
||||
timer_cmsdk_reset(&USEC_TIMER_DEV);
|
||||
timer_cmsdk_clear_interrupt(&USEC_TIMER_DEV);
|
||||
timer_cmsdk_enable_interrupt(&USEC_TIMER_DEV);
|
||||
timer_cmsdk_enable(&USEC_TIMER_DEV);
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Pass-through function to make the US ticker HAL only work in the tick
|
||||
* domain. This function is needed by the CMSDK Ticker layer.
|
||||
*
|
||||
* \param[in] us Number of us
|
||||
*
|
||||
* \return The number of us given.
|
||||
*/
|
||||
static uint32_t convert_us_to_tick(uint32_t us)
|
||||
{
|
||||
/* Work only in the tick domain. */
|
||||
return us;
|
||||
}
|
||||
|
||||
static const struct tick_cfg_t cfg =
|
||||
{
|
||||
.timer_driver = &CMSDK_TIMER0_DEV,
|
||||
.irq_n = TIMER0_IRQn,
|
||||
.interval_callback = &us_ticker_irq_handler,
|
||||
.convert_tick_to_time = &convert_tick_to_us,
|
||||
.convert_time_to_tick = &convert_us_to_tick
|
||||
};
|
||||
|
||||
static struct tick_data_t data =
|
||||
{
|
||||
.is_initialized = false,
|
||||
.cumulated_time = 0,
|
||||
.max_interval_time = 0,
|
||||
.reload_time = 0,
|
||||
.interval_callback_enabled = false,
|
||||
.previous_cumulated_time = 0,
|
||||
.previous_elapsed = 0
|
||||
};
|
||||
|
||||
static struct tick_drv_data_t timer_data =
|
||||
{
|
||||
.cfg = &cfg,
|
||||
.data = &data
|
||||
};
|
||||
|
||||
void us_ticker_init(void)
|
||||
{
|
||||
cmsdk_ticker_init(&timer_data);
|
||||
}
|
||||
|
||||
uint32_t us_ticker_read()
|
||||
{
|
||||
return cmsdk_ticker_read(&timer_data);
|
||||
}
|
||||
|
||||
void us_ticker_set_interrupt(timestamp_t timestamp)
|
||||
{
|
||||
cmsdk_ticker_set_interrupt(&timer_data, timestamp);
|
||||
}
|
||||
|
||||
void us_ticker_disable_interrupt(void)
|
||||
{
|
||||
cmsdk_ticker_disable_interrupt(&timer_data);
|
||||
}
|
||||
|
||||
void us_ticker_clear_interrupt(void)
|
||||
{
|
||||
cmsdk_ticker_clear_interrupt(&timer_data);
|
||||
}
|
||||
|
||||
void us_ticker_fire_interrupt(void)
|
||||
{
|
||||
cmsdk_ticker_fire_interrupt(&timer_data);
|
||||
timer_cmsdk_init(&USEC_TIMER_DEV);
|
||||
previous_ticks = TIMER_CMSDK_MAX_RELOAD;
|
||||
NVIC_EnableIRQ(USEC_INTERVAL_IRQ);
|
||||
restart_timer(previous_ticks);
|
||||
}
|
||||
|
||||
void us_ticker_free(void)
|
||||
{
|
||||
|
||||
timer_cmsdk_disable(&USEC_TIMER_DEV);
|
||||
}
|
||||
|
||||
void TIMER0_IRQHandler(void)
|
||||
uint32_t us_ticker_read(void)
|
||||
{
|
||||
cmsdk_ticker_irq_handler(&timer_data);
|
||||
if (timer_cmsdk_is_interrupt_active(&USEC_TIMER_DEV)) {
|
||||
total_ticks += previous_ticks;
|
||||
previous_ticks = TIMER_CMSDK_MAX_RELOAD;
|
||||
restart_timer(previous_ticks);
|
||||
} else {
|
||||
uint32_t tick = timer_cmsdk_get_current_value(&USEC_TIMER_DEV);
|
||||
|
||||
if (tick < previous_ticks) {
|
||||
uint32_t delta = previous_ticks - tick;
|
||||
total_ticks += delta;
|
||||
previous_ticks = tick;
|
||||
}
|
||||
}
|
||||
last_read = (uint32_t)(total_ticks >> USEC_REPORTED_SHIFT);
|
||||
return last_read;
|
||||
}
|
||||
|
||||
const ticker_info_t* us_ticker_get_info(void)
|
||||
/* To ensure that timestamp is always bigger than the current time, it should
|
||||
* be calculated by using the us_ticker_read() method.
|
||||
*/
|
||||
void us_ticker_set_interrupt(timestamp_t timestamp)
|
||||
{
|
||||
static ticker_info_t us_ticker_info = {
|
||||
.bits = CMSDK_TICKER_COUNTER_BITS
|
||||
uint32_t reload = (timestamp - last_read) << USEC_REPORTED_SHIFT;
|
||||
previous_ticks = reload;
|
||||
restart_timer(previous_ticks);
|
||||
}
|
||||
|
||||
void us_ticker_disable_interrupt(void)
|
||||
{
|
||||
timer_cmsdk_disable_interrupt(&USEC_TIMER_DEV);
|
||||
}
|
||||
|
||||
void us_ticker_clear_interrupt(void)
|
||||
{
|
||||
timer_cmsdk_clear_interrupt(&USEC_TIMER_DEV);
|
||||
}
|
||||
|
||||
void us_ticker_fire_interrupt(void)
|
||||
{
|
||||
NVIC_SetPendingIRQ(USEC_INTERVAL_IRQ);
|
||||
}
|
||||
|
||||
const ticker_info_t* us_ticker_get_info()
|
||||
{
|
||||
static const ticker_info_t info = {
|
||||
USEC_REPORTED_FREQ_HZ,
|
||||
USEC_REPORTED_BITS
|
||||
};
|
||||
|
||||
/*
|
||||
* SystemCoreClock is not a constant so it cannot be used to initialize the
|
||||
* ticker_info_t structure.
|
||||
*/
|
||||
us_ticker_info.frequency = SystemCoreClock;
|
||||
|
||||
return &us_ticker_info;
|
||||
return &info;
|
||||
}
|
||||
|
||||
#ifndef usec_interval_irq_handler
|
||||
#error "usec_interval_irq_handler should be defined, check device_cfg.h!"vector!
|
||||
#endif
|
||||
void usec_interval_irq_handler(void)
|
||||
{
|
||||
us_ticker_read();
|
||||
us_ticker_irq_handler();
|
||||
}
|
||||
|
|
|
@ -4648,12 +4648,16 @@
|
|||
"FLASH",
|
||||
"I2C",
|
||||
"INTERRUPTIN",
|
||||
"LPTICKER",
|
||||
"PORTIN",
|
||||
"PORTINOUT",
|
||||
"PORTOUT",
|
||||
"RTC",
|
||||
"SERIAL",
|
||||
"SLEEP",
|
||||
"SPI",
|
||||
"TRNG"
|
||||
"TRNG",
|
||||
"USTICKER"
|
||||
],
|
||||
"release_versions": ["2", "5"],
|
||||
"copy_method": "mps2",
|
||||
|
|
Loading…
Reference in New Issue