[BEETLE] Fix US_Ticker read

MBED OS requires an us_ticker_read function that returns a 32bit
value in microseconds. This can not be represented directly on
the Beetle Timer Load register.

max_us_on_reg = (0xFFFFFFFF ticks)/DIVIDER_US

This patch introduces an intermediate layer that counts the timer wraps
around and returns the correct value of us to the MBED library.

Signed-off-by: Vincenzo Frascino <vincenzo.frascino@arm.com>
pull/2204/head
Vincenzo Frascino 2016-07-20 10:18:00 +01:00
parent 1b364a1e52
commit 4f5b191e74
3 changed files with 63 additions and 4 deletions

View File

@ -165,14 +165,22 @@ uint32_t Timer_Read(uint32_t timer)
*/
void Timer_SetInterrupt(uint32_t timer, uint32_t time_us)
{
uint32_t load_time_us = 0;
/* Verify if the Timer is enabled */
if (Timer_isEnabled(timer) == 1) {
/* Disable Timer */
Timer_Disable(timer);
/* Enable Interrupt */
(Timers[timer].timerN)->CTRL = CMSDK_TIMER_CTRL_IRQEN_Msk;
/* Check time us condition */
if(time_us == TIMER_DEFAULT_RELOAD)
load_time_us = TIMER_MAX_VALUE;
else
load_time_us = time_us * TIMER_TICKS_US;
/* Initialize Timer Value */
Timers[timer].timerReload = (time_us) * TIMER_TICKS_US;
Timers[timer].timerReload = load_time_us;
(Timers[timer].timerN)->RELOAD = Timers[timer].timerReload;
(Timers[timer].timerN)->VALUE = Timers[timer].timerReload;
/* Enable Counter */
@ -234,3 +242,21 @@ uint32_t Timer_GetTicksUS(uint32_t timer)
}
return 0;
}
/*
* Timer_GetReloadValue(): returns the load value of the selected
* timer.
* timer: timer associated with the Ticks per us
* @return: reload value of the selected singletimer
*/
uint32_t Timer_GetReloadValue(uint32_t timer)
{
/* Verify if the Timer is enabled */
if (Timer_isEnabled(timer) == 1) {
if (timer == TIMER1)
return Timers[timer].timerReload / TIMER_TICKS_US;
else
return Timers[timer].timerReload / TIMER_TICKS_US;
}
return 0;
}

View File

@ -26,6 +26,9 @@ extern "C" {
#define TIMER0 0
#define TIMER1 1
/* Default reload */
#define TIMER_DEFAULT_RELOAD 0xFFFFFFFF
/*
* Timer_Initialize(): Initializes an hardware timer
* timer: timer to be Initialized
@ -92,6 +95,14 @@ uint32_t Timer_GetIRQn(uint32_t timer);
*/
uint32_t Timer_GetTicksUS(uint32_t timer);
/*
* Timer_GetReloadValue(): returns the load value of the selected
* timer.
* timer: timer associated with the Ticks per us
* @return: reload value of the selected singletimer
*/
uint32_t Timer_GetReloadValue(uint32_t timer);
#ifdef __cplusplus
}
#endif

View File

@ -23,11 +23,19 @@ static uint32_t us_ticker_reload = 0x0; /* Max Value */
/* us ticker initialized */
static uint32_t us_ticker_inited = 0;
/* us ticker overflow */
static uint32_t us_ticker_overflow = 0;
static uint32_t us_ticker_overflow_delta = 0;
/* us ticker overflow limit */
static uint32_t us_ticker_overflow_limit = 0;
void __us_ticker_irq_handler(void) {
Timer_ClearInterrupt(TIMER1);
us_ticker_overflow++;
/*
* For each overflow event adds the timer max represented value to
* the delta. This allows the us_ticker to keep track of the elapsed
* time:
* elapsed_time = (num_overflow * overflow_limit) + current_time
*/
us_ticker_overflow_delta += us_ticker_overflow_limit;
}
void us_ticker_init(void) {
@ -57,6 +65,18 @@ void us_ticker_init(void) {
us_ticker_irqn1 = Timer_GetIRQn(TIMER1);
NVIC_SetVector((IRQn_Type)us_ticker_irqn1, (uint32_t)__us_ticker_irq_handler);
NVIC_EnableIRQ((IRQn_Type)us_ticker_irqn1);
/* Timer set interrupt on TIMER1 */
Timer_SetInterrupt(TIMER1, TIMER_DEFAULT_RELOAD);
/*
* Set us_ticker Overflow limit. The us_ticker overflow limit is required
* to calculated the return value of the us_ticker read function in us
* on 32bit.
* A 32bit us value cannot be represented directly in the Timer Load
* register if it is greater than (0xFFFFFFFF ticks)/TIMER_DIVIDER_US.
*/
us_ticker_overflow_limit = Timer_GetReloadValue(TIMER1);
}
uint32_t us_ticker_read() {
@ -64,7 +84,9 @@ uint32_t us_ticker_read() {
if (!us_ticker_inited)
us_ticker_init();
return_value = Timer_Read(TIMER1);
return_value = us_ticker_overflow_delta + Timer_Read(TIMER1);
return return_value;
}