X-Git-Url: https://oss.titaniummirror.com/gitweb/?a=blobdiff_plain;f=tos%2Fchips%2Fcc1000%2FCC1000CsmaP.nc;h=698ab8cbd205f359ad79079c6cbb7da2718ffba4;hb=1e12ec1e6ce70a5765c7602d3bb32e3c90412d4b;hp=8449652e9f1ddad82190fae084370ba81a2d3233;hpb=1ba974b83d19fc41bf80acd52726f36f7f1df297;p=tinyos-2.x.git diff --git a/tos/chips/cc1000/CC1000CsmaP.nc b/tos/chips/cc1000/CC1000CsmaP.nc index 8449652e..698ab8cb 100644 --- a/tos/chips/cc1000/CC1000CsmaP.nc +++ b/tos/chips/cc1000/CC1000CsmaP.nc @@ -1,6 +1,6 @@ // $Id$ -/* tab:4 +/* * "Copyright (c) 2000-2005 The Regents of the University of California. * All rights reserved. * @@ -50,7 +50,7 @@ * @author David Gay */ -module CC1000CsmaP { +module CC1000CsmaP @safe() { provides { interface Init; interface SplitControl; @@ -101,13 +101,16 @@ implementation int16_t macDelay; - uint8_t lplTxPower, lplRxPower; uint16_t sleepTime; uint16_t rssiForSquelch; task void setWakeupTask(); + cc1000_metadata_t * ONE getMetadata(message_t * ONE amsg) { + return TCAST(cc1000_metadata_t * ONE, (uint8_t*)amsg + offsetof(message_t, footer) + sizeof(cc1000_footer_t)); + } + void enterIdleState() { call cancelRssi(); radioState = IDLE_STATE; @@ -153,24 +156,11 @@ implementation } void radioOff() { - call ByteRadio.off(); call CC1000Control.off(); + call ByteRadio.off(); } - /* LPL preamble length and sleep time computation */ - - void setPreambleLength() { - uint16_t len = - (uint16_t)read_uint8_t(&CC1K_LPL_PreambleLength[lplTxPower * 2]) << 8 - | read_uint8_t(&CC1K_LPL_PreambleLength[lplTxPower * 2 + 1]); - call ByteRadio.setPreambleLength(len); - } - - void setSleepTime() { - sleepTime = - (uint16_t)read_uint8_t(&CC1K_LPL_SleepTime[lplRxPower *2 ]) << 8 | - read_uint8_t(&CC1K_LPL_SleepTime[lplRxPower * 2 + 1]); - } + void setPreambleLength(message_t * ONE msg); /* Initialisation, startup and stopping */ /*--------------------------------------*/ @@ -200,8 +190,6 @@ implementation call ByteRadioControl.start(); enterIdleStateSetWakeup(); f.txPending = FALSE; - setPreambleLength(); - setSleepTime(); } else return SUCCESS; @@ -234,11 +222,13 @@ implementation { case IDLE_STATE: /* Timer already running means that we have a noise floor - measurement scheduled. */ + measurement scheduled. If we just set a new alarm here, we + might indefinitely delay noise floor measurements if we're, + e,g, transmitting frequently. */ if (!call WakeupTimer.isRunning()) if (call CC1000Squelch.settled()) { - if (lplRxPower == 0 || f.txPending) + if (sleepTime == 0) call WakeupTimer.startOneShot(CC1K_SquelchIntervalSlow); else // timeout for receiving a message after an lpl check @@ -304,7 +294,7 @@ implementation bool turnOn = FALSE; atomic - if (f.txPending) + if (f.txPending || !sleepTime) { if (radioState == PULSECHECK_STATE || radioState == POWERDOWN_STATE) { @@ -312,8 +302,7 @@ implementation turnOn = TRUE; } } - else if (lplRxPower > 0 && call CC1000Squelch.settled() && - !call ByteRadio.syncing()) + else if (call CC1000Squelch.settled() && !call ByteRadio.syncing()) { radioOff(); enterPowerDownState(); @@ -341,6 +330,7 @@ implementation */ if (data > call CC1000Squelch.get() - (call CC1000Squelch.get() >> 2)) { + post sleepCheck(); // don't be too agressive (ignore really quiet thresholds). if (data < call CC1000Squelch.get() + (call CC1000Squelch.get() >> 3)) { @@ -348,7 +338,6 @@ implementation rssiForSquelch = data; post adjustSquelch(); } - post sleepCheck(); } else if (count++ > 5) { @@ -366,7 +355,7 @@ implementation /* CSMA */ /*------*/ - event void ByteRadio.rts() { + event void ByteRadio.rts(message_t * ONE msg) { atomic { f.txPending = TRUE; @@ -377,6 +366,8 @@ implementation macDelay = signal CsmaBackoff.initial(call ByteRadio.getTxMessage()); else macDelay = 1; + + setPreambleLength(msg); } } @@ -477,73 +468,83 @@ implementation return SUCCESS; } - async command error_t LowPowerListening.setListeningMode(uint8_t power) { - if (power >= CC1K_LPL_STATES) - return FAIL; + /* Default MAC backoff parameters */ + /*--------------------------------*/ - atomic - { - if (radioState != DISABLED_STATE) - return FAIL; - lplTxPower = power; - lplRxPower = power; - } - return SUCCESS; + default async event uint16_t CsmaBackoff.initial(message_t *m) { + // initially back off [1,32] bytes (approx 2/3 packet) + return (call Random.rand16() & 0x1F) + 1; } - async command uint8_t LowPowerListening.getListeningMode() { - atomic return lplRxPower; + default async event uint16_t CsmaBackoff.congestion(message_t *m) { + return (call Random.rand16() & 0xF) + 1; } - async command error_t LowPowerListening.setTransmitMode(uint8_t power) { - if (power >= CC1K_LPL_STATES) - return FAIL; + /* LowPowerListening setup */ + /* ----------------------- */ - atomic - { - lplTxPower = power; - setPreambleLength(); - } - return SUCCESS; + uint16_t validateSleepInterval(uint16_t sleepIntervalMs) { + if (sleepIntervalMs < CC1K_LPL_MIN_INTERVAL) + return 0; + else if (sleepIntervalMs > CC1K_LPL_MAX_INTERVAL) + return CC1K_LPL_MAX_INTERVAL; + else + return sleepIntervalMs; } - async command uint8_t LowPowerListening.getTransmitMode() { - atomic return lplTxPower; - } + uint16_t dutyToSleep(uint16_t dutyCycle) { + /* Scaling factors on CC1K_LPL_CHECK_TIME and dutyCycle are identical */ + uint16_t interval = (1000 * CC1K_LPL_CHECK_TIME) / dutyCycle; - async command error_t LowPowerListening.setPreambleLength(uint16_t bytes) { - call ByteRadio.setPreambleLength(bytes); - return SUCCESS; + return interval < CC1K_LPL_MIN_INTERVAL ? 0 : interval; } - async command uint16_t LowPowerListening.getPreambleLength() { - return call ByteRadio.getPreambleLength(); + uint16_t sleepToDuty(uint16_t sleepInterval) { + if (sleepInterval < CC1K_LPL_MIN_INTERVAL) + return 10000; + + /* Scaling factors on CC1K_LPL_CHECK_TIME and dutyCycle are identical */ + return (1000 * CC1K_LPL_CHECK_TIME) / sleepInterval; } - async command error_t LowPowerListening.setCheckInterval(uint16_t ms) { - atomic - { - if (lplRxPower == 0) - return FAIL; + command void LowPowerListening.setLocalWakeupInterval(uint16_t s) { + sleepTime = validateSleepInterval(s); + } - sleepTime = ms; - } - return SUCCESS; + command uint16_t LowPowerListening.getLocalWakeupInterval() { + return sleepTime; } - async command uint16_t LowPowerListening.getCheckInterval() { - atomic return sleepTime; + command void LowPowerListening.setRemoteWakeupInterval(message_t *msg, uint16_t sleepIntervalMs) { + cc1000_metadata_t *meta = getMetadata(msg); + + meta->strength_or_preamble = -(int16_t)validateSleepInterval(sleepIntervalMs) - 1; } - /* Default MAC backoff parameters */ - /*--------------------------------*/ + command uint16_t LowPowerListening.getRemoteWakeupInterval(message_t *msg) { + cc1000_metadata_t *meta = getMetadata(msg); - default async event uint16_t CsmaBackoff.initial(message_t *m) { - // initially back off [1,32] bytes (approx 2/3 packet) - return (call Random.rand16() & 0x1F) + 1; + if (meta->strength_or_preamble >= 0) + return sleepTime; + else + return -(meta->strength_or_preamble + 1); } - default async event uint16_t CsmaBackoff.congestion(message_t *m) { - return (call Random.rand16() & 0xF) + 1; + void setPreambleLength(message_t * ONE msg) { + cc1000_metadata_t *meta = getMetadata(msg); + uint16_t s; + uint32_t plen; + + if (meta->strength_or_preamble >= 0) + s = sleepTime; + else + s = -(meta->strength_or_preamble + 1); + meta->strength_or_preamble = 0; /* Destroy setting */ + + if (s == 0) + plen = 6; + else + plen = ((s * 614UL) >> 8) + 22; /* ~ s * 2.4 + 22 */ + call ByteRadio.setPreambleLength(plen); } }