X-Git-Url: https://oss.titaniummirror.com/gitweb/?a=blobdiff_plain;f=tos%2Fplatforms%2Ftelosb%2Fmac%2Ftkn154%2FTKN154TimingP.nc;h=fe2782b7ea753c53d1d9a915b8663d15c9be3edc;hb=e9bfab607e051bae6afb47b44892ce37541d1b44;hp=d9713c201d0985a60f553d5b45fa8ad8d96caa11;hpb=adf1de6c009d13b7b52e68535c63b28f59c97400;p=tinyos-2.x.git diff --git a/tos/platforms/telosb/mac/tkn154/TKN154TimingP.nc b/tos/platforms/telosb/mac/tkn154/TKN154TimingP.nc index d9713c20..fe2782b7 100644 --- a/tos/platforms/telosb/mac/tkn154/TKN154TimingP.nc +++ b/tos/platforms/telosb/mac/tkn154/TKN154TimingP.nc @@ -34,12 +34,10 @@ */ /** - * NOTE: * In slotted CSMA-CA frames must be sent on backoff boundaries (slot width: - * 320 us). On TelosB the only clock source with sufficient accuracy is the - * external quartz, unfortunately it is not precise enough (32.768 Hz). - * Therefore, currently the following code is not even trying to achieve - * accurate timing. + * 320 us). The TelosB platform lacks a clock with sufficient precision and + * accuracy, i.e. for slotted CSMA-CA the timing is *not* standard compliant + * (this code is experimental) */ #include "TKN154_platform.h" @@ -49,24 +47,26 @@ module TKN154TimingP provides interface ReliableWait; provides interface ReferenceTime; uses interface TimeCalc; - uses interface LocalTime; + uses interface GetNow as CCA; + uses interface Alarm as SymbolAlarm; + uses interface Leds; } implementation { + enum { + S_WAIT_OFF, + S_WAIT_RX, + S_WAIT_TX, + S_WAIT_BACKOFF, + }; + uint8_t m_state = S_WAIT_OFF; -#define UWAIT1 nop();nop();nop();nop() -#define UWAIT2 UWAIT1;UWAIT1 -#define UWAIT4 UWAIT2;UWAIT2 -#define UWAIT8 UWAIT4;UWAIT4 - - async command void CaptureTime.convert(uint16_t time, ieee154_reftime_t *localTime, int16_t offset) + async command error_t CaptureTime.convert(uint16_t time, ieee154_timestamp_t *localTime, int16_t offset) { // TimerB is used for capturing, it is sourced by ACLK (32768Hz), - // we now need to convert the capture "time" into ieee154_reftime_t. + // we now need to convert the capture "time" into ieee154_timestamp_t. // With the 32768Hz quartz we don't have enough precision anyway, // so the code below generates a timestamp that is not accurate - // (deviating about +-50 microseconds; this could probably - // improved if we don't go through LocalTime) uint16_t tbr1, tbr2, delta; uint32_t now; atomic { @@ -74,51 +74,78 @@ implementation tbr1 = TBR; tbr2 = TBR; } while (tbr1 != tbr2); // majority vote required (see msp430 manual) - now = call LocalTime.get(); + now = call SymbolAlarm.getNow(); } if (time < tbr1) delta = tbr1 - time; else delta = ~(time - tbr1) + 1; - *localTime = now - delta*2 + offset; + *localTime = now - delta * 2 + offset; /* one tick of TimerB ~ two symbols */ + return SUCCESS; } - async command void ReliableWait.busyWait(uint16_t dt) + async command bool ReliableWait.ccaOnBackoffBoundary(ieee154_timestamp_t *slot0) { - uint32_t start = call LocalTime.get(); - while (!call TimeCalc.hasExpired(start, dt)) - ; + // There is no point in trying + return (call CCA.getNow() ? 20: 0); } - async command void ReliableWait.waitCCA(ieee154_reftime_t *t0, uint16_t dt) + async command bool CaptureTime.isValidTimestamp(uint16_t risingSFDTime, uint16_t fallingSFDTime) { - while (!call TimeCalc.hasExpired(*t0, dt)) - ; - signal ReliableWait.waitCCADone(); + // smallest packet (ACK) takes + // length field (1) + MPDU (5) = 6 byte => 12 * 16 us = 192 us + return (fallingSFDTime - risingSFDTime) > 5; } - async command void ReliableWait.waitTx(ieee154_reftime_t *t0, uint16_t dt) + async command void ReliableWait.waitRx(uint32_t t0, uint32_t dt) { - while (!call TimeCalc.hasExpired(*t0, dt)) - ; - signal ReliableWait.waitTxDone(); + if (m_state != S_WAIT_OFF){ + ASSERT(0); + return; + } + m_state = S_WAIT_RX; + call SymbolAlarm.startAt(t0 - 16, dt); // subtract 12 symbols required for Rx calibration } - async command void ReliableWait.waitRx(ieee154_reftime_t *t0, uint16_t dt) + async command void ReliableWait.waitTx(ieee154_timestamp_t *t0, uint32_t dt) + { + if (m_state != S_WAIT_OFF){ + ASSERT(0); + return; + } + m_state = S_WAIT_TX; + call SymbolAlarm.startAt(*t0 - 16, dt); // subtract 12 symbols required for Tx calibration + } + + async command void ReliableWait.waitBackoff(uint32_t dt) { - while (!call TimeCalc.hasExpired(*t0, dt)) - ; - signal ReliableWait.waitRxDone(); + if (m_state != S_WAIT_OFF){ + ASSERT(0); + return; + } + m_state = S_WAIT_BACKOFF; + call SymbolAlarm.start(dt); } - - async command void ReferenceTime.getNow(ieee154_reftime_t* reftime, uint16_t dt) + + async event void SymbolAlarm.fired() + { + switch (m_state) + { + case S_WAIT_RX: m_state = S_WAIT_OFF; signal ReliableWait.waitRxDone(); break; + case S_WAIT_TX: m_state = S_WAIT_OFF; signal ReliableWait.waitTxDone(); break; + case S_WAIT_BACKOFF: m_state = S_WAIT_OFF; signal ReliableWait.waitBackoffDone(); break; + default: ASSERT(0); break; + } + } + + async command void ReferenceTime.getNow(ieee154_timestamp_t* timestamp, uint16_t dt) { - *reftime = call LocalTime.get(); + *timestamp = call SymbolAlarm.getNow() + dt; } - async command uint32_t ReferenceTime.toLocalTime(ieee154_reftime_t* refTime) + async command uint32_t ReferenceTime.toLocalTime(const ieee154_timestamp_t* timestamp) { - return *refTime; + return *timestamp; } }