diff --git a/hal/targets/cmsis/TARGET_ARM_SSG/TARGET_BEETLE/apb_timer.c b/hal/targets/cmsis/TARGET_ARM_SSG/TARGET_BEETLE/apb_timer.c index 1b0a56bbcc..f4b880972f 100644 --- a/hal/targets/cmsis/TARGET_ARM_SSG/TARGET_BEETLE/apb_timer.c +++ b/hal/targets/cmsis/TARGET_ARM_SSG/TARGET_BEETLE/apb_timer.c @@ -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; +} diff --git a/hal/targets/cmsis/TARGET_ARM_SSG/TARGET_BEETLE/apb_timer.h b/hal/targets/cmsis/TARGET_ARM_SSG/TARGET_BEETLE/apb_timer.h index c174174e74..e08c58251a 100644 --- a/hal/targets/cmsis/TARGET_ARM_SSG/TARGET_BEETLE/apb_timer.h +++ b/hal/targets/cmsis/TARGET_ARM_SSG/TARGET_BEETLE/apb_timer.h @@ -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 diff --git a/hal/targets/hal/TARGET_ARM_SSG/TARGET_BEETLE/us_ticker.c b/hal/targets/hal/TARGET_ARM_SSG/TARGET_BEETLE/us_ticker.c index 0afda94e2c..809961f98d 100644 --- a/hal/targets/hal/TARGET_ARM_SSG/TARGET_BEETLE/us_ticker.c +++ b/hal/targets/hal/TARGET_ARM_SSG/TARGET_BEETLE/us_ticker.c @@ -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; }