1
0
mirror of https://github.com/RIOT-OS/RIOT.git synced 2025-01-17 05:12:57 +01:00

pkg/openwsn/sctimer_rtt: account for counters < uint32

This commit is contained in:
Francisco Molina 2020-10-08 16:47:51 +02:00
parent 0731fdbbaa
commit 0e0f385f3f
No known key found for this signature in database
GPG Key ID: 3E94EAC3DBDEEDA8

View File

@ -67,6 +67,15 @@ static uint32_t _prescaler;
static atomic_bool _enable;
#endif
#if RTT_MAX_VALUE < UINT32_MAX
/* If RTT_MAX_VALUE is smaller the UINT32_MAX then handle the remaining
bits here, sctimer is scheduled at least every slot (20ms) so no
overflow will be missed */
#define SCTIMER_RTT_EXTEND_MSB (1 << (32UL - __builtin_clz(RTT_MAX_VALUE)))
static atomic_uint_fast32_t _counter_msb;
static atomic_uint_fast32_t _now_last;
#endif
static sctimer_cbt sctimer_cb;
static void sctimer_isr_internal(void *arg)
@ -84,6 +93,10 @@ void sctimer_init(void)
{
rtt_init();
sctimer_cb = NULL;
#ifdef SCTIMER_RTT_EXTEND_MSB
atomic_store(&_counter_msb, 0);
atomic_store(&_now_last, 0);
#endif
#ifdef SCTIMER_TIME_DIVISION
_prescaler = 0;
_enable = false;
@ -115,12 +128,34 @@ uint32_t _update_val(uint32_t val, uint32_t now)
}
#endif
#ifdef SCTIMER_RTT_EXTEND_MSB
uint32_t _sctimer_extend(uint32_t now)
{
unsigned state = irq_disable();
uint32_t now_last = atomic_load(&_now_last);
uint32_t counter_msb = atomic_load(&_counter_msb);
if (now < now_last) {
/* account for overflow */
counter_msb += SCTIMER_RTT_EXTEND_MSB;
atomic_store(&_counter_msb, counter_msb);
}
atomic_store(&_now_last, now);
now += counter_msb;
irq_restore(state);
return now;
}
#endif
void sctimer_setCompare(uint32_t val)
{
unsigned state = irq_disable();
uint32_t now = rtt_get_counter();
#ifdef SCTIMER_RTT_EXTEND_MSB
now = _sctimer_extend(now);
#endif
#ifdef SCTIMER_TIME_DIVISION
val = _update_val(val, now);
#endif
@ -150,6 +185,10 @@ uint32_t sctimer_readCounter(void)
{
uint32_t now = rtt_get_counter();
#ifdef SCTIMER_RTT_EXTEND_MSB
now = _sctimer_extend(now);
#endif
#ifdef SCTIMER_TIME_DIVISION
now &= SCTIMER_TIME_DIVISION_MASK;
now = (now << SCTIMER_PRESCALER);