mbed library sources. Supersedes mbed-src.
Fork of mbed-dev by
Diff: targets/TARGET_ARM_SSG/TARGET_BEETLE/lp_ticker.c
- Revision:
- 149:156823d33999
- Parent:
- 144:ef7eb2e8f9f7
- Child:
- 150:02e0a0aed4ec
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/targets/TARGET_ARM_SSG/TARGET_BEETLE/lp_ticker.c Fri Oct 28 11:17:30 2016 +0100 @@ -0,0 +1,157 @@ +/* + * PackageLicenseDeclared: Apache-2.0 + * Copyright (c) 2015 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 "cmsis.h" +#include "device.h" +#include "objects.h" +#include "lp_ticker_api.h" + +/* Private lp_ticker data */ +/* lp_ticker initialize */ +static uint32_t lp_ticker_initialized = 0; +/* lp_ticker reload value */ +static uint32_t lp_ticker_reload = 0x0; /* Max Value */ +/* Store Overflow Delta */ +static uint32_t lp_ticker_overflows_delta = 0; +/* lp_ticker Overflow limit */ +static uint32_t lp_ticker_overflow_limit = 0; + +#if DEVICE_LOWPOWERTIMER +/** + * Interrupt Handler + */ +void __lp_ticker_irq_handler(void) +{ + if (DualTimer_GetIRQInfo(DUALTIMER0) == SINGLETIMER2) { + DualTimer_ClearInterrupt(DUALTIMER0); + /* + * For each overflow event adds the timer max represented value to + * the delta. This allows the lp_ticker to keep track of the elapsed + * time: + * elapsed_time = (num_overflow * overflow_limit) + current_time + */ + lp_ticker_overflows_delta += lp_ticker_overflow_limit; + } else { + lp_ticker_irq_handler(); + } +} + +/** + * Initialize the low power ticker + */ +void lp_ticker_init(void) +{ + uint32_t lp_ticker_irqn = 0; + /* Verify if lp_ticker has been already Initialized */ + if (lp_ticker_initialized == 1) + { + return; + } + lp_ticker_initialized = 1; + + /* Dualtimer Initialize */ + DualTimer_Initialize(DUALTIMER0, lp_ticker_reload); + /* Dualtimer Enable */ + DualTimer_Enable(DUALTIMER0, DUALTIMER_COUNT_32 + //| DUALTIMER_PERIODIC + ); + /* DualTimer get IRQn */ + lp_ticker_irqn = DualTimer_GetIRQn(DUALTIMER0); + /* Enable lp_ticker IRQ */ + NVIC_SetVector((IRQn_Type)lp_ticker_irqn, + (uint32_t)__lp_ticker_irq_handler); + NVIC_EnableIRQ((IRQn_Type)lp_ticker_irqn); + + /* DualTimer set interrupt on SINGLETIMER2 */ + DualTimer_SetInterrupt_2(DUALTIMER0, DUALTIMER_DEFAULT_RELOAD, + DUALTIMER_COUNT_32 | DUALTIMER_PERIODIC); + + /* + * Set lp_ticker Overflow limit. The lp_ticker overflow limit is required + * to calculated the return value of the lp_ticker read function in us + * on 32bit. + * A 32bit us value cannot be represented directly in the Dual Timer Load + * register if it is greater than (0xFFFFFFFF ticks)/DUALTIMER_DIVIDER_US. + */ + lp_ticker_overflow_limit = DualTimer_GetReloadValue(DUALTIMER0, + SINGLETIMER2); +} + +/** + * Read the current counter + * @return: The current timer's counter value in microseconds + */ +uint32_t lp_ticker_read(void) +{ + uint32_t microseconds = 0; + + /* Verify if lp_ticker has not been Initialized */ + if (lp_ticker_initialized == 0) + lp_ticker_init(); + + /* Read Timer Value */ + microseconds = lp_ticker_overflows_delta + DualTimer_Read_2(DUALTIMER0); + + return microseconds; +} + +/** + * Set interrupt for specified timestamp + * timestamp: The time in microseconds to be set + */ +void lp_ticker_set_interrupt(timestamp_t timestamp) +{ + int32_t delta = 0; + + /* Verify if lp_ticker has been not Initialized */ + if (lp_ticker_initialized == 0) + lp_ticker_init(); + + /* Calculate the delta */ + delta = (int32_t)(timestamp - lp_ticker_read()); + /* Check if the event was in the past */ + if (delta <= 0) { + /* This event was in the past */ + DualTimer_SetInterrupt_1(DUALTIMER0, 0, + DUALTIMER_COUNT_32 | DUALTIMER_ONESHOT); + return; + } + + /* Enable interrupt on SingleTimer1 */ + DualTimer_SetInterrupt_1(DUALTIMER0, delta, + DUALTIMER_COUNT_32 | DUALTIMER_ONESHOT); +} + +/** + * Disable low power ticker interrupt + */ +void lp_ticker_disable_interrupt(void) +{ + /* Disable Interrupt */ + DualTimer_DisableInterrupt(DUALTIMER0); +} + +/** + * Clear the low power ticker interrupt + */ +void lp_ticker_clear_interrupt(void) +{ + /* Clear Interrupt */ + DualTimer_ClearInterrupt(DUALTIMER0); +} + +#endif