shortened the comment in us_ticker_set_interrupt().

pull/932/head
Rohit Grover 2015-03-16 12:48:54 +00:00
parent be71348f20
commit ea4537df7d
1 changed files with 18 additions and 30 deletions

View File

@ -202,42 +202,30 @@ void us_ticker_set_interrupt(timestamp_t timestamp)
}
/*
* Alert: Get yourself a beverage.
*
* In comes a harmless, merry-looking 32-bit timestamp in units of micro-
* seconds from the generic us_ticker_api. On most platforms with 32-bit
* hardware timers running at micro-second precision this poses no serious
* challenge. But on the nRF51, we use an RTC timer running at 32kHz to
* implement a low-power us-ticker. This brings with a problem that's rooted
* in the fact that 1000000 is not a multiple of 32768.
* The argument to this function is a 32-bit microsecond timestamp for when
* a callback should be invoked. On the nRF51, we use an RTC timer running
* at 32kHz to implement a low-power us-ticker. This brings with a problem
* that's rooted in the fact that 1000000 is not a multiple of 32768.
*
* Going from a micro-second based timestamp to a 32kHz based RTC-time is a
* linear mapping; but then when the 32-bit micro-second timestamp wraps
* around, unfortunately the underlying RTC counter doesn't. The result is
* that timestamp expiry checks on micro-second timestamps don't yield the
* same result when applied on the corresponding RTC timestamp values.
* You'll really need to whip up some numbers to see the problem.
* linear mapping; but this mapping doesn't preserve wraparounds--i.e. when
* the 32-bit micro-second timestamp wraps around unfortunately the
* underlying RTC counter doesn't. The result is that timestamp expiry
* checks on micro-second timestamps don't yield the same result when
* applied on the corresponding RTC timestamp values.
*
* As far as I understand--and this could just be me turning old and rusty,
* --there is no clean solution for this problem at the wrap-around
* boundary. I'd be interested to be shown how. My solution is to translate
* the incoming 32-bit timestamp into a virtual 64-bit timestamp based on
* the knowledge of system-uptime, and then use this 64-bit value to do a
* linear mapping to RTC time. 64-bit timestamp values shouldn't wrap around
* in a few thousand years. This may be pulling down the theoretical upper
* boundary for the shelf life of nRF products when used with mbed; please
* accept my two to the power 56 apologies for that. But then life often
* forces one to live within constraints. What's the meaning of all this
* anyway?
*
* System uptime on an nRF is maintained using RTC's counter. We track the
* overflow count to extend the 24-bit hardware counter by an additional 32
* bits. This then forms the basis for system time.
* One solution is to translate the incoming 32-bit timestamp into a virtual
* 64-bit timestamp based on the knowledge of system-uptime, and then use
* this wraparound-free 64-bit value to do a linear mapping to RTC time.
* System uptime on an nRF is maintained using the 24-bit RTC counter. We
* track the overflow count to extend the 24-bit hardware counter by an
* additional 32 bits. This then forms the basis for system time.
* RTC_UNITS_TO_MICROSECONDS() converts this into microsecond units (in
* 64-bits). We then shave off the lower 32-bits of it and add in the
* incoming timestamp to get a mapping into a virtual 64-bit timestamp.
* There's one additional check to handle the case of wraparound for the
* 32-bit timestamp.
* There's one additional check to handle the case where the 32-bit callback
* timestamp is wrapped around--i.e. where the current time is near
* 0xFFFFFFFF, but incoming timestamp is near 0x00000000.
*/
uint64_t timestamp64 = (RTC_UNITS_TO_MICROSECONDS(rtc1_getCounter()) & ~(uint64_t)0xFFFFFFFF) + timestamp;
if ((us_ticker_read() > 0xF0000000) && (timestamp < 0x10000000)) {