t
Fork of mbed-dev by
Diff: targets/TARGET_ONSEMI/TARGET_NCS36510/ncs36510_us_ticker_api.c
- Revision:
- 169:e3b6fe271b81
- Parent:
- 167:e84263d55307
- Child:
- 174:b96e65c34a4d
diff -r 9672193075cf -r e3b6fe271b81 targets/TARGET_ONSEMI/TARGET_NCS36510/ncs36510_us_ticker_api.c --- a/targets/TARGET_ONSEMI/TARGET_NCS36510/ncs36510_us_ticker_api.c Thu Jul 06 15:42:05 2017 +0100 +++ b/targets/TARGET_ONSEMI/TARGET_NCS36510/ncs36510_us_ticker_api.c Wed Jul 19 17:31:21 2017 +0100 @@ -38,7 +38,7 @@ static void us_timer_init(void); static uint32_t us_ticker_target = 0; -static volatile uint32_t msb_counter = 0; +static volatile uint16_t msb_counter = 0; void us_ticker_init(void) { @@ -55,7 +55,6 @@ * which is why a software timer is required to get 32-bit word length. ******************************************************************************/ /* TODO - Need some sort of load value/prescale calculation for non-32MHz clock */ -/* TODO - Add msb_counter rollover protection at 16 bits count? */ /* TODO - How is overflow handled? */ /* Timer 0 for free running time */ @@ -108,22 +107,21 @@ /* Reads 32 bit timer's current value (16 bit s/w timer | 16 bit h/w timer) */ uint32_t us_ticker_read() { - uint32_t retval, tim0cval; if (!us_ticker_inited) { us_timer_init(); } + NVIC_DisableIRQ(Tim0_IRQn); + uint32_t retval, tim0cval; /* Get the current tick from the hw and sw timers */ tim0cval = TIM0REG->VALUE; /* read current time */ retval = (0xFFFF - tim0cval); /* subtract down count */ - NVIC_DisableIRQ(Tim0_IRQn); if (TIM0REG->CONTROL.BITS.INT) { - TIM0REG->CLEAR = 0; - msb_counter++; - tim0cval = TIM0REG->VALUE; /* read current time again after interrupt */ - retval = (0xFFFF - tim0cval); + us_timer_isr(); /* handle ISR again */ + NVIC_ClearPendingIRQ(Tim0_IRQn); + retval = (0xFFFF - TIM0REG->VALUE); } retval |= msb_counter << 16; /* add software bits */ NVIC_EnableIRQ(Tim0_IRQn); @@ -168,25 +166,21 @@ /* Clear IRQ flag */ TIM1REG->CLEAR = 0; - int32_t delta = us_ticker_target - us_ticker_read(); - if (delta <= 0) { - TIM1REG->CONTROL.BITS.ENABLE = False; - us_ticker_irq_handler(); + if (us_ticker_target > 0) { + --us_ticker_target; + ticker_set(0xFFFF); } else { - // Clamp at max value of timer - if (delta > 0xFFFF) { - delta = 0xFFFF; - } - - ticker_set(delta); + us_ticker_irq_handler(); } } /* Set timer 1 ticker interrupt */ void us_ticker_set_interrupt(timestamp_t timestamp) { - us_ticker_target = (uint32_t)timestamp; - int32_t delta = us_ticker_target - us_ticker_read(); + int32_t delta = timestamp - us_ticker_read(); + // we got 16 bit timer, use upper 16bit as a simple counter how many times + // we need to schedule full range ticker count + us_ticker_target = (uint32_t)delta >> 16; if (delta <= 0) { /* This event was in the past */ @@ -200,10 +194,6 @@ return; } - // Clamp at max value of timer - if (delta > 0xFFFF) { - delta = 0xFFFF; - } - - ticker_set(delta); + // we set the full reminder of 16 bit, the next ISR will do the upper part + ticker_set(delta & 0xFFFF); }