X-Git-Url: https://oss.titaniummirror.com/gitweb/?a=blobdiff_plain;f=tos%2Fchips%2Ftda5250%2Fmac%2FRedMacP.nc;h=d734b492e17f9b7be6b634c810aa7005dcd91193;hb=9092b3c0aa9215dff07b3465a88eb706e3e2193f;hp=1a8600f7a1f016e37df9404e5558bd4c06b2295f;hpb=337d0b13acf569c2640b3ed7b7f5c7cec35d7ddd;p=tinyos-2.x.git diff --git a/tos/chips/tda5250/mac/RedMacP.nc b/tos/chips/tda5250/mac/RedMacP.nc index 1a8600f7..d734b492 100644 --- a/tos/chips/tda5250/mac/RedMacP.nc +++ b/tos/chips/tda5250/mac/RedMacP.nc @@ -39,7 +39,10 @@ #include "PacketAck.h" #include "RedMac.h" -// #define MACM_DEBUG // debug... +#ifdef DELTATIMEDEBUG +#include "DeltaTrace.h" +#endif + module RedMacP { provides { interface Init; @@ -47,11 +50,12 @@ module RedMacP { interface MacSend; interface MacReceive; interface Packet; - interface LocalTime as LocalTime32khz; - interface SleepTime; + interface Sleeptime; interface Teamgeist; interface ChannelCongestion; - interface McuPowerOverride; +#ifdef MAC_EVAL + interface MacEval; +#endif } uses { interface StdControl as CcaStdControl; @@ -74,13 +78,27 @@ module RedMacP { interface Alarm as Timer; interface Alarm as SampleTimer; - interface Counter as Counter32khz16; + interface LocalTime as LocalTime32kHz; + + interface Duplicate; + interface TimeDiff16; + interface TimeDiff32; + async command am_addr_t amAddress(); -#ifdef MACM_DEBUG +/* interface GeneralIO as Led0; interface GeneralIO as Led1; interface GeneralIO as Led2; - interface GeneralIO as Led3; + interface GeneralIO as Led3; +*/ +#ifdef REDMAC_DEBUG + interface SerialDebug; +#endif +#ifdef REDMAC_PERFORMANCE + interface Performance; +#endif +#ifdef DELTATIMEDEBUG + interface DeltaTrace; #endif } } @@ -104,134 +122,71 @@ implementation macState_t macState; /****** debug vars & defs & functions ***********************/ -#ifdef MACM_DEBUG -#define HISTORY_ENTRIES 60 - typedef struct { - int index; - macState_t state; - int place; - } history_t; - - history_t history[HISTORY_ENTRIES]; - unsigned histIndex; - void storeOldState(int p) { - atomic { - history[histIndex].index = histIndex; - history[histIndex].state = macState; - history[histIndex].place = p; - histIndex++; - if(histIndex >= HISTORY_ENTRIES) histIndex = 0; - } +#ifdef REDMAC_DEBUG + void sdDebug(uint16_t p) { + call SerialDebug.putPlace(p); } + uint8_t repCounter; #else - void storeOldState(int p) {}; -#endif - - void signalFailure(uint8_t place) { -#ifdef MACM_DEBUG - unsigned long i,j; - atomic { - for(;;) { - call Led0.clr(); - call Led1.clr(); - call Led2.clr(); - call Led3.clr(); - - for(i = 0; i < 100; i++) { - for(j=0; j < 200; j++) { - (i & 1) ? call Led0.set() : call Led0.clr(); - } - for(j=0; j < 200; j++) { - (i & 2) ? call Led1.set() : call Led1.clr(); - } - for(j=0; j < 200; j++) { - (i & 4) ? call Led2.set() : call Led2.clr(); - } - for(j=0; j < 200; j++) { - (i & 8) ? call Led3.set() : call Led3.clr(); - } - } - - (place & 1) ? call Led0.set() : call Led0.clr(); - (place & 2) ? call Led1.set() : call Led1.clr(); - (place & 4) ? call Led2.set() : call Led2.clr(); - (place & 8) ? call Led3.set() : call Led3.clr(); - - for(i = 0; i < 1000000; i++) { - ; - } - - (macState & 1) ? call Led0.set() : call Led0.clr(); - (macState & 2) ? call Led1.set() : call Led1.clr(); - (macState & 4) ? call Led2.set() : call Led2.clr(); - (macState & 8) ? call Led3.set() : call Led3.clr(); - - for(i = 0; i < 1000000; i++) { - ; - } - } - } + void sdDebug(uint16_t p) {}; #endif - } - - void signalMacState() { -#ifdef MACM_DEBUG -/* (macState & 1) ? call Led0.set() : call Led0.clr(); - (macState & 2) ? call Led1.set() : call Led1.clr(); - (macState & 4) ? call Led2.set() : call Led2.clr(); - (macState & 8) ? call Led3.set() : call Led3.clr(); -*/ + +#ifdef REDMAC_PERFORMANCE + PfmTxMsg_t txStat; + PfmRxMsg_t rxStat; #endif - } - /**************** Module Global Constants *****************/ enum { - BYTE_TIME=13, // byte at 38400 kBit/s, 4b6b encoded - PREAMBLE_BYTE_TIME=9, // byte at 38400 kBit/s, no coding - PHY_HEADER_TIME=51, // 6 Phy Preamble at 38400 - SUB_HEADER_TIME=PHY_HEADER_TIME + sizeof(tda5250_header_t)*BYTE_TIME, - SUB_FOOTER_TIME=2*BYTE_TIME, // 2 bytes crc 38400 kBit/s with 4b6b encoding - MAX_TIME_VALUE=0xFFFFFFFF, - MAXTIMERVALUE=0xFFFF, // helps to compute backoff - //DEFAULT_SLEEP_TIME=3250, - DEFAULT_SLEEP_TIME=6500, - // DEFAULT_SLEEP_TIME=9750, + + BYTE_TIME=ENCODED_32KHZ_BYTE_TIME, // phy encoded + PREAMBLE_BYTE_TIME=TDA5250_32KHZ_BYTE_TIME, // no coding + PHY_HEADER_TIME=6*PREAMBLE_BYTE_TIME, // 6 Phy Preamble + TIME_CORRECTION=TDA5250_32KHZ_BYTE_TIME+2, // difference between txSFD and rxSFD + + SUB_HEADER_TIME=PHY_HEADER_TIME + sizeof(message_header_t)*BYTE_TIME, + SUB_FOOTER_TIME=2*BYTE_TIME, // 2 bytes crc + // DEFAULT_SLEEP_TIME=1625, + DEFAULT_SLEEP_TIME=2048, + // DEFAULT_SLEEP_TIME=4096, + // DEFAULT_SLEEP_TIME=8192, + // DEFAULT_SLEEP_TIME=16384, + // DEFAULT_SLEEP_TIME=32768U, + // DEFAULT_SLEEP_TIME=65535U, DATA_DETECT_TIME=17, - RX_SETUP_TIME=111, // time to set up receiver - TX_SETUP_TIME=69, // time to set up transmitter - ADDED_DELAY = 40, - RX_ACK_TIMEOUT = RX_SETUP_TIME + PHY_HEADER_TIME + 29 + 2*ADDED_DELAY, - TX_GAP_TIME=RX_ACK_TIMEOUT + TX_SETUP_TIME + 11, + RX_SETUP_TIME=102, // time to set up receiver + TX_SETUP_TIME=58, // time to set up transmitter + ADDED_DELAY = 30, + RX_ACK_TIMEOUT = RX_SETUP_TIME + PHY_HEADER_TIME + ADDED_DELAY + 30, + TX_GAP_TIME = RX_ACK_TIMEOUT + TX_SETUP_TIME + 33, // the duration of a send ACK ACK_DURATION = SUB_HEADER_TIME + SUB_FOOTER_TIME, - MAX_SHORT_RETRY=7, - MAX_LONG_RETRY=2, - MAX_AGE=2*MAX_LONG_RETRY*MAX_SHORT_RETRY, - MSG_TABLE_ENTRIES=20, + NAV_FACTOR = 4, +#ifndef MAC_EVAL + MAX_SHORT_RETRY=9, + MAX_LONG_RETRY=3, + ADD_NAV = 2, + INCREASE_BACKOFF = TRUE, +#endif TOKEN_ACK_FLAG = 64, TOKEN_ACK_MASK = 0x3f, - /* correct the difference between the transmittedSFD and the receivedSFD - that appears due to buffering, measured value on an osci is 320us, so this - value is actually 10.48576 - */ - TIME_CORRECTION = 10, INVALID_SNR = 0xffff, - PREAMBLE_LONG = 6, - PREAMBLE_SHORT = 2, + // PREAMBLE_LONG = 5, + // PREAMBLE_SHORT = 2, + // reduced minimal backoff + ZERO_BACKOFF_MASK = 0xff }; - +#ifdef MAC_EVAL + uint8_t MAX_SHORT_RETRY = 9; + uint8_t MAX_LONG_RETRY = 3; + uint8_t ADD_NAV = 4; + bool INCREASE_BACKOFF = TRUE; +#endif +#ifdef DELTATIMEDEBUG + DeltaTrace_t dTrace; +#endif /**************** Module Global Variables *****************/ - typedef union - { - uint32_t op; - struct { - uint16_t lo; - uint16_t hi; - }; - } ui32parts_t; - /* flags */ typedef enum { SWITCHING = 1, @@ -244,37 +199,29 @@ implementation TEAMGEIST_ACTIVE=128 } flags_t; - /* duplicate suppression */ - typedef struct knownMessage_t { - am_addr_t src; - uint8_t token; - uint8_t age; - } knownMessage_t; - - knownMessage_t knownMsgTable[MSG_TABLE_ENTRIES]; - uint8_t flags; - uint8_t checkCounter; - uint8_t shortRetryCounter; - uint8_t longRetryCounter; - uint16_t sleepTime; - uint16_t rssiValue; - uint32_t restLaufzeit; + uint8_t flags = 0; + uint8_t checkCounter = 0; + uint8_t shortRetryCounter = 0; + uint8_t longRetryCounter = 0; + uint16_t networkSleeptime = DEFAULT_SLEEP_TIME; + uint16_t localSleeptime = DEFAULT_SLEEP_TIME; + uint16_t rssiValue = 0; + uint32_t restLaufzeit = 0; - message_t *txBufPtr; - uint16_t txLen; - red_mac_header_t *txMacHdr; + uint32_t rxTime = 0; + am_id_t teamgeistType = 0; + + uint8_t congestionLevel = 0; + + message_t *txBufPtr = NULL; + uint16_t txLen = 0; + red_mac_header_t *txMacHdr = NULL; uint16_t seqNo; message_t ackMsg; - uint16_t counter2sec; - uint32_t rxTime; - - am_id_t teamgeistType; - - uint8_t congestionLevel; uint16_t MIN_BACKOFF_MASK; - + /****** Secure switching of radio modes ***/ void interruptBackoffTimer(); @@ -301,12 +248,17 @@ implementation void setRxMode() { setFlag(&flags, SWITCHING); clearFlag(&flags, RSSI_STABLE); - storeOldState(0); + // sdDebug(10); checkCounter = 0; rssiValue = INVALID_SNR; if(call RadioModes.RxMode() == FAIL) { post SetRxModeTask(); } + else { +#ifdef REDMAC_PERFORMANCE + call Performance.macRxMode(); +#endif + } requestAdc(); } @@ -317,13 +269,18 @@ implementation } void setSleepMode() { - storeOldState(161); + // sdDebug(20); clearFlag(&flags, RSSI_STABLE); post ReleaseAdcTask(); setFlag(&flags, SWITCHING); if(call RadioModes.SleepMode() == FAIL) { post SetSleepModeTask(); } + else { +#ifdef REDMAC_PERFORMANCE + call Performance.macSleepMode(); +#endif + } } task void SetSleepModeTask() { @@ -333,12 +290,17 @@ implementation void setTxMode() { post ReleaseAdcTask(); - storeOldState(2); + // sdDebug(30); clearFlag(&flags, RSSI_STABLE); setFlag(&flags, SWITCHING); if(call RadioModes.TxMode() == FAIL) { post SetTxModeTask(); } + else { +#ifdef REDMAC_PERFORMANCE + call Performance.macTxMode(); +#endif + } } task void SetTxModeTask() { @@ -347,21 +309,34 @@ implementation } } - /**************** Helper functions ************************/ + /**************** Helper functions ************************/ + void computeBackoff(); + void checkSend() { - storeOldState(10); if((shortRetryCounter) && (txBufPtr != NULL) && (isFlagSet(&flags, MESSAGE_PREPARED)) && (macState == SLEEP) && (!isFlagSet(&flags, RESUME_BACKOFF)) && (!call Timer.isRunning())) { - storeOldState(11); + // sdDebug(40); macState = CCA; checkCounter = 0; setRxMode(); } +/* else { + if(txBufPtr) // sdDebug(41); + if(shortRetryCounter) // sdDebug(42); + if(isFlagSet(&flags, MESSAGE_PREPARED)) // sdDebug(43); + if(txBufPtr) { + if(macState == SLEEP) // sdDebug(44); + if(!isFlagSet(&flags, RESUME_BACKOFF)) // sdDebug(45); + if(!call Timer.isRunning()) // sdDebug(46); + } + } +*/ } uint32_t backoff(uint8_t counter) { uint32_t rVal = call Random.rand16() & MIN_BACKOFF_MASK; - return rVal << counter; + if(!INCREASE_BACKOFF) counter = 1; + return (rVal << counter) + ZERO_BACKOFF_MASK; } bool needsAckTx(message_t* msg) { @@ -390,8 +365,8 @@ implementation if(isFlagSet(&flags, TEAMGEIST_ACTIVE) && (getHeader(msg)->type == teamgeistType)) { if(rssiValue != INVALID_SNR) snr = rssiValue; + *level = 2; rVal = signal Teamgeist.needsAck(msg, getHeader(msg)->src, getHeader(msg)->dest, snr); - *level = 1; } } } @@ -406,10 +381,10 @@ implementation atomic { msg = txBufPtr; length = txLen; - sT = sleepTime; + sT = networkSleeptime; } if(msg == NULL) return; - macHdr = (red_mac_header_t *)call SubPacket.getPayload(msg, NULL); + macHdr = (red_mac_header_t *)call SubPacket.getPayload(msg, sizeof(red_mac_header_t) + length); macHdr->repetitionCounter = sT/(length * BYTE_TIME + SUB_HEADER_TIME + SUB_FOOTER_TIME + TX_GAP_TIME) + 1; atomic { @@ -423,7 +398,35 @@ implementation txMacHdr = macHdr; setFlag(&flags, MESSAGE_PREPARED); if((macState == SLEEP) && (!call Timer.isRunning()) && (!isFlagSet(&flags, RESUME_BACKOFF))) { - call Timer.start(backoff(longRetryCounter)); + if((longRetryCounter == 1) && + (getHeader(msg)->dest != AM_BROADCAST_ADDR)) { + call Timer.start((call Random.rand16() >> 3) & ZERO_BACKOFF_MASK); + } + else { + call Timer.start(backoff(longRetryCounter)); + } + } +#ifdef REDMAC_PERFORMANCE + txStat.type = getHeader(msg)->type; + txStat.to = getHeader(msg)->dest; + txStat.token = getHeader(msg)->token; + txStat.maxRepCounter = macHdr->repetitionCounter; + txStat.creationTime = getMetadata(msg)->time; +#endif + getMetadata(msg)->maxRepetitions = macHdr->repetitionCounter; + } + } + + void storeStrength(message_t *m) { + if(rssiValue != INVALID_SNR) { + (getMetadata(m))->strength = rssiValue; + } + else { + if(call RssiAdcResource.isOwner()) { + (getMetadata(m))->strength = call ChannelMonitorData.readSnr(); + } + else { + (getMetadata(m))->strength = 1; } } } @@ -431,35 +434,47 @@ implementation bool prepareRepetition() { bool repeat; atomic { - if(isFlagSet(&flags, CANCEL_SEND)) txMacHdr->repetitionCounter = 0; - repeat = (txMacHdr->repetitionCounter >= 1); - txMacHdr->repetitionCounter--; + if(isFlagSet(&flags, CANCEL_SEND)) { + repeat = txMacHdr->repetitionCounter = 0; + } + else { + repeat = txMacHdr->repetitionCounter; + txMacHdr->repetitionCounter--; + } } return repeat; } - + void signalSendDone(error_t error) { message_t *m; error_t e = error; - storeOldState(12); + // sdDebug(50); atomic { m = txBufPtr; txBufPtr = NULL; txLen = 0; +#ifdef REDMAC_PERFORMANCE + txStat.repCounter = txMacHdr->repetitionCounter; + txStat.longRetry = longRetryCounter; + txStat.shortRetry = shortRetryCounter; +#endif longRetryCounter = 0; shortRetryCounter = 0; - if(rssiValue != INVALID_SNR) { - (getMetadata(m))->strength = rssiValue; - } - else { - (getMetadata(m))->strength = call ChannelMonitorData.readSnr(); - } + storeStrength(m); if(isFlagSet(&flags, CANCEL_SEND)) { e = ECANCEL; } + clearFlag(&flags, MESSAGE_PREPARED); clearFlag(&flags, CANCEL_SEND); } + // sdDebug(3000 + e); + // sdDebug(4000 + getHeader(m)->type); signal MacSend.sendDone(m, e); +#ifdef REDMAC_PERFORMANCE + txStat.success = e; + txStat.strength = getMetadata(m)->strength; + call Performance.macTxMsgStats(&txStat); +#endif } void updateRetryCounters() { @@ -468,7 +483,7 @@ implementation longRetryCounter++; shortRetryCounter = 1; if(longRetryCounter > MAX_LONG_RETRY) { - storeOldState(13); + // sdDebug(60); signalSendDone(FAIL); } } @@ -480,7 +495,7 @@ implementation longRetryCounter++; shortRetryCounter = 1; if(longRetryCounter > MAX_LONG_RETRY) { - storeOldState(13); + // sdDebug(70); signalSendDone(FAIL); } else { post PrepareMsgTask(); @@ -496,19 +511,11 @@ implementation } void interruptBackoffTimer() { - uint16_t now; if(call Timer.isRunning()) { - restLaufzeit = call Timer.getAlarm(); + restLaufzeit = call TimeDiff16.computeDelta(call Timer.getAlarm(), call Timer.getNow()); call Timer.stop(); - now = call Timer.getNow(); - if(restLaufzeit >= now) { - restLaufzeit = restLaufzeit - now; - } - else { - restLaufzeit += MAXTIMERVALUE - now; - } if(restLaufzeit > MIN_BACKOFF_MASK << MAX_LONG_RETRY) { - restLaufzeit = backoff(0); + restLaufzeit = call Random.rand16() & ZERO_BACKOFF_MASK; } setFlag(&flags, RESUME_BACKOFF); } @@ -519,7 +526,6 @@ implementation setFlag(&flags, RESUME_BACKOFF); restLaufzeit = backoff(longRetryCounter); updateRetryCounters(); - storeOldState(92); } } @@ -536,38 +542,14 @@ implementation } bool isNewMsg(message_t* msg) { - bool rVal = TRUE; - uint8_t i; - for(i=0; i < MSG_TABLE_ENTRIES; i++) { - if((getHeader(msg)->src == knownMsgTable[i].src) && - (((getHeader(msg)->token) & TOKEN_ACK_MASK) == knownMsgTable[i].token) && - (knownMsgTable[i].age < MAX_AGE)) { - knownMsgTable[i].age = 0; - rVal = FALSE; - break; - } - } - return rVal; - } - - unsigned findOldest() { - unsigned i; - unsigned oldIndex = 0; - unsigned age = knownMsgTable[oldIndex].age; - for(i = 1; i < MSG_TABLE_ENTRIES; i++) { - if(age < knownMsgTable[i].age) { - oldIndex = i; - age = knownMsgTable[i].age; - } - } - return oldIndex; - } + return call Duplicate.isNew(getHeader(msg)->src, + getHeader(msg)->dest, + (getHeader(msg)->token) & TOKEN_ACK_MASK); + } void rememberMsg(message_t* msg) { - unsigned oldest = findOldest(); - knownMsgTable[oldest].src = getHeader(msg)->src; - knownMsgTable[oldest].token = (getHeader(msg)->token) & TOKEN_ACK_MASK; - knownMsgTable[oldest].age = 0; + call Duplicate.remember(getHeader(msg)->src, getHeader(msg)->dest, + (getHeader(msg)->token) & TOKEN_ACK_MASK); } void prepareAck(message_t* msg) { @@ -577,50 +559,46 @@ implementation getHeader(&ackMsg)->src = call amAddress(); getHeader(&ackMsg)->dest = getHeader(msg)->src; getHeader(&ackMsg)->type = getHeader(msg)->type; +#ifdef REDMAC_DEBUG + repCounter = ((red_mac_header_t *) + call SubPacket.getPayload(msg, sizeof(red_mac_header_t)))->repetitionCounter; +#endif } uint32_t calcGeneratedTime(red_mac_header_t *m) { - return rxTime - m->time - TIME_CORRECTION; + uint32_t lt = rxTime - m->time - TIME_CORRECTION; +#ifdef DELTATIMEDEBUG + dTrace.now = rxTime; + dTrace.msgTime = lt; + dTrace.delta = m->time; + call DeltaTrace.traceRx(&dTrace); +#endif + return lt; } - + /**************** Init ************************/ command error_t Init.init(){ - uint8_t i; atomic { macState = INIT; - flags = 0; - checkCounter = 0; - rssiValue = 0; - restLaufzeit = 0; seqNo = call Random.rand16() % TOKEN_ACK_FLAG; - txBufPtr = NULL; - txLen = 0; - txMacHdr = NULL; - sleepTime = DEFAULT_SLEEP_TIME; - for(i = 0; i < MSG_TABLE_ENTRIES; i++) { - knownMsgTable[i].age = MAX_AGE; - } - for(MIN_BACKOFF_MASK = 1; MIN_BACKOFF_MASK < sleepTime; ) { + for(MIN_BACKOFF_MASK = 1; MIN_BACKOFF_MASK < networkSleeptime; ) { MIN_BACKOFF_MASK = (MIN_BACKOFF_MASK << 1) + 1; } MIN_BACKOFF_MASK >>= 2; - storeOldState(20); - shortRetryCounter = 0; - longRetryCounter = 0; - counter2sec = 127; - rxTime = 0; - teamgeistType = 0; } +#ifdef REDMAC_DEBUG + call SerialDebug.putShortDesc("RedMacP"); +#endif return SUCCESS; } /**************** SplitControl *****************/ task void StartDoneTask() { - storeOldState(14); + // sdDebug(90); atomic { - call SampleTimer.start(sleepTime); + call SampleTimer.start(localSleeptime); macState = SLEEP; setFlag(&flags, TEAMGEIST_ACTIVE); teamgeistType = signal Teamgeist.observedAMType(); @@ -632,16 +610,15 @@ implementation call CcaStdControl.start(); atomic { macState = INIT; - // signalMacState(); setRxMode(); - storeOldState(15); + // sdDebug(100); } return SUCCESS; } task void StopDoneTask() { call Init.init(); - storeOldState(16); + // sdDebug(110); signal SplitControl.stopDone(SUCCESS); } @@ -652,12 +629,12 @@ implementation atomic { if((macState == SLEEP) && isFlagSet(&flags, SWITCHING)) { macState = STOP; - storeOldState(17); + // sdDebug(120); } else { macState = STOP; setSleepMode(); - storeOldState(18); + // sdDebug(121); } } return SUCCESS; @@ -680,34 +657,28 @@ implementation return call SubPacket.maxPayloadLength() - sizeof(red_mac_header_t); } - command void* Packet.getPayload(message_t* msg, uint8_t* len) { - nx_uint8_t *payload = (nx_uint8_t *)call SubPacket.getPayload(msg, len); - if (len != NULL) { - *len -= sizeof(red_mac_header_t); - } + command void* Packet.getPayload(message_t* msg, uint8_t len) { + nx_uint8_t *payload = (nx_uint8_t *)call SubPacket.getPayload(msg, len + sizeof(red_mac_header_t)); return (void*)(payload + sizeof(red_mac_header_t)); } /****** Radio(Mode) events *************************/ async event void RadioModes.RssiStable() { - if(isFlagSet(&flags, RSSI_STABLE)) signalFailure(0); setFlag(&flags, RSSI_STABLE); if((macState == RX) || (macState == CCA)) { call Timer.start(DATA_DETECT_TIME); - storeOldState(30); + // sdDebug(130); } else if(macState == RX_P) { - storeOldState(31); + // sdDebug(131); if(call RssiAdcResource.isOwner()) call ChannelMonitorData.getSnr(); } else if(macState == RX_ACK) { - // if(call RssiAdcResource.isOwner()) call ChannelMonitor.start(); - storeOldState(32); } else if(macState == RX_ACK_P) { } else if(macState == INIT) { - storeOldState(33); + // sdDebug(133); if(call RssiAdcResource.isOwner()) { call ChannelMonitorControl.updateNoiseFloor(); } else { @@ -715,65 +686,55 @@ implementation } } else if(macState == STOP) { - storeOldState(34); + // sdDebug(134); } else { - storeOldState(35); - signalFailure(1); + // sdDebug(135); } } async event void RadioModes.RxModeDone() { - storeOldState(40); - if(!isFlagSet(&flags, SWITCHING)) signalFailure(2); atomic { clearFlag(&flags, SWITCHING); if((macState == RX) || (macState == RX_ACK) || (macState == CCA) || (macState == INIT) || (macState == STOP)) { - storeOldState(41); + // sdDebug(140); if(macState != RX_ACK) requestAdc(); } else { - storeOldState(42); - signalFailure(3); + // sdDebug(141); } } } async event void RadioModes.TxModeDone() { - storeOldState(50); - if(!isFlagSet(&flags, SWITCHING)) signalFailure(4); + // sdDebug(150); atomic { clearFlag(&flags, SWITCHING); if(macState == TX) { - call UartPhyControl.setNumPreambles(PREAMBLE_SHORT); setFlag(&flags, ACTION_DETECTED); - if(txBufPtr == NULL) signalFailure(5); if(call PacketSend.send(txBufPtr, txLen) == SUCCESS) { - storeOldState(51); - } else { - storeOldState(52); - signalFailure(6); + // sdDebug(151); + } + else { + // sdDebug(152); } } else if(macState == TX_ACK) { if(call PacketSend.send(&ackMsg, 0) == SUCCESS) { - storeOldState(53); + // sdDebug(153); } else { - storeOldState(54); - signalFailure(6); + // sdDebug(154); } } else { - storeOldState(55); - signalFailure(7); + // sdDebug(155); } } } async event void RadioModes.SleepModeDone() { - storeOldState(60); - if(!isFlagSet(&flags, SWITCHING)) signalFailure(8); + // sdDebug(160); atomic { clearFlag(&flags, SWITCHING); if(isFlagSet(&flags, ACTION_DETECTED)) { @@ -781,24 +742,25 @@ implementation } else { if(congestionLevel > 0) congestionLevel--; } - if((macState == SLEEP) && (!call Timer.isRunning())) { - if(isFlagSet(&flags, RESUME_BACKOFF)) { - storeOldState(61); - clearFlag(&flags, RESUME_BACKOFF); - call Timer.start(restLaufzeit); - restLaufzeit = 0; - } - else { - storeOldState(62); - checkSend(); + // if(congestionLevel > 3) // sdDebug(2000 + congestionLevel); + if(macState == SLEEP) { + // sdDebug(161); + if(!call Timer.isRunning()) { + // sdDebug(162); + if(isFlagSet(&flags, RESUME_BACKOFF)) { + // sdDebug(164); + clearFlag(&flags, RESUME_BACKOFF); + call Timer.start(restLaufzeit); + restLaufzeit = 0; + } + else { + // sdDebug(165); + checkSend(); + } } } - else if(macState == INIT) { - storeOldState(63); - post StartDoneTask(); - } else if(macState == STOP) { - storeOldState(64); + // sdDebug(168); post StopDoneTask(); } signal ChannelCongestion.congestionEvent(congestionLevel); @@ -811,16 +773,20 @@ implementation atomic { if((shortRetryCounter == 0) && (txBufPtr == NULL)) { clearFlag(&flags, MESSAGE_PREPARED); - storeOldState(65); + // sdDebug(5000 + getHeader(msg)->type); shortRetryCounter = 1; longRetryCounter = 1; txBufPtr = msg; txLen = len + sizeof(red_mac_header_t); seqNo++; if(seqNo >= TOKEN_ACK_FLAG) seqNo = 1; +#ifdef REDMAC_PERFORMANCE + txStat.payloadLength = txLen; + txStat.interfaceTime = call LocalTime32kHz.get(); +#endif } else { - storeOldState(66); + // sdDebug(171); err = EBUSY; } } @@ -834,12 +800,24 @@ implementation error_t err = FAIL; atomic { if(msg == txBufPtr) { + // sdDebug(320); setFlag(&flags, CANCEL_SEND); shortRetryCounter = MAX_SHORT_RETRY + 2; longRetryCounter = MAX_LONG_RETRY + 2; - if(macState == SLEEP) signalSendDone(ECANCEL); + if(macState == SLEEP) { + // sdDebug(321); + signalSendDone(ECANCEL); + } + else { + // sdDebug(322); + } + // sdDebug(1000 + macState); err = SUCCESS; } + else { + // sdDebug(323); + // sdDebug(1100 + macState); + } } return err; } @@ -849,8 +827,14 @@ implementation async event void PacketReceive.receiveDetected() { rssiValue = INVALID_SNR; setFlag(&flags, ACTION_DETECTED); + call ChannelMonitor.rxSuccess(); if(macState <= CCA_ACK) { - if(macState == CCA) computeBackoff(); + if(macState == CCA) { + computeBackoff(); +#ifdef REDMAC_PERFORMANCE + call Performance.macDetectedOnCca(); +#endif + } if(macState != RX_ACK) { macState = RX_P; } else { @@ -858,8 +842,7 @@ implementation } } else if(macState == INIT) { - storeOldState(72); - if(isFlagSet(&flags, UNHANDLED_PACKET)) signalFailure(9); + // sdDebug(180); setFlag(&flags, UNHANDLED_PACKET); } } @@ -870,47 +853,58 @@ implementation uint32_t nav = 0; uint8_t level = 0; bool isCnt; - - storeOldState(80); +#ifdef REDMAC_PERFORMANCE + rxStat.duplicate = PERF_UNKNOWN; + rxStat.repCounter = 0xff; +#endif + sdDebug(190); if(macState == RX_P) { - storeOldState(81); + // sdDebug(191); if(error == SUCCESS) { - storeOldState(82); + // sdDebug(192); isCnt = isControl(msg); if(msgIsForMe(msg)) { if(!isCnt) { - storeOldState(83); + // sdDebug(193); if(isNewMsg(msg)) { - storeOldState(84); - if(rssiValue != INVALID_SNR) { - (getMetadata(m))->strength = rssiValue; - } - else { - if(call RssiAdcResource.isOwner()) { - (getMetadata(m))->strength = call ChannelMonitorData.readSnr(); - } - else { - (getMetadata(m))->strength = 1; - } - } - (getMetadata(msg))->time = calcGeneratedTime((red_mac_header_t*) payload); +#ifdef REDMAC_PERFORMANCE + rxStat.duplicate = PERF_NEW_MSG; +#endif + // sdDebug(194); + storeStrength(msg); +#ifdef DELTATIMEDEBUG + dTrace.sender = getHeader(msg)->src; +#endif + getMetadata(msg)->sfdtime = rxTime; + getMetadata(msg)->time = calcGeneratedTime((red_mac_header_t*) payload); + getMetadata(msg)->ack = WAS_NOT_ACKED; m = signal MacReceive.receiveDone(msg); // assume a buffer swap -- if buffer is not swapped, assume that the // message was not successfully delivered to upper layers if(m != msg) { - storeOldState(85); + // sdDebug(195); rememberMsg(msg); } else { - storeOldState(86); + // sdDebug(196); action = RX; +#ifdef REDMAC_PERFORMANCE + call Performance.macQueueFull(); +#endif } } + else { +#ifdef REDMAC_PERFORMANCE + rxStat.duplicate = PERF_REPEATED_MSG; +#endif + } if(needsAckRx(msg, &level) && (action != RX)) { - storeOldState(87); action = CCA_ACK; + if(level == 2) { + getMetadata(msg)->ack = WAS_ACKED; + } } else { - storeOldState(88); + // sdDebug(198); if(action != RX) { nav = ((red_mac_header_t*)payload)->repetitionCounter * (SUB_HEADER_TIME + getHeader(msg)->length*BYTE_TIME + @@ -920,12 +914,12 @@ implementation } } else { - storeOldState(89); + // sdDebug(199); action = RX; } } else { - storeOldState(90); + // sdDebug(200); action = SLEEP; if(!isCnt) { nav = ((red_mac_header_t*)payload)->repetitionCounter * @@ -936,64 +930,61 @@ implementation } } else { - storeOldState(91); - action = RX; + // sdDebug(201); + action = SLEEP; } } else if(macState == RX_ACK_P) { if(error == SUCCESS) { if(ackIsForMe(msg)) { - storeOldState(92); - if(rssiValue != INVALID_SNR) { - (getMetadata(txBufPtr))->strength = rssiValue; - } - else { - if(call RssiAdcResource.isOwner()) { - (getMetadata(txBufPtr))->strength = call ChannelMonitorData.readSnr(); - } - else { - (getMetadata(txBufPtr))->strength = 1; - } - } - (getMetadata(txBufPtr))->ack = WAS_ACKED; - if(isFlagSet(&flags, TEAMGEIST_ACTIVE) && (getHeader(txBufPtr)->type == teamgeistType)) { + // sdDebug(202); + getMetadata(txBufPtr)->ack = WAS_ACKED; + getMetadata(txBufPtr)->repetitions = txMacHdr->repetitionCounter; + if(isFlagSet(&flags, TEAMGEIST_ACTIVE) && + (getHeader(txBufPtr)->type == teamgeistType)) + { signal Teamgeist.gotAck(txBufPtr, getHeader(msg)->src, getMetadata(txBufPtr)->strength); } + // sdDebug(203); signalSendDone(SUCCESS); + // sdDebug(30000 + getHeader(msg)->src); action = SLEEP; } else { - updateLongRetryCounters(); - action = RX; + // sdDebug(203); + updateLongRetryCounters(); // this will eventually schedule the right backoff + macState = SLEEP; // so much traffic is going on -- take a nap + setSleepMode(); + action = INIT; // a difficult way to say: do nothing } } else { if(call Timer.isRunning()) { - storeOldState(94); + // sdDebug(204); action = RX_ACK; } else { + // sdDebug(205); updateLongRetryCounters(); action = RX; } } } else { - storeOldState(96); + // sdDebug(206); action = INIT; } if(action == CCA_ACK) { - prepareAck(msg); macState = CCA_ACK; - if(call Random.rand16() & 4) { - call Timer.start(RX_SETUP_TIME - TX_SETUP_TIME + (ADDED_DELAY>>level)); - call UartPhyControl.setNumPreambles(PREAMBLE_SHORT); + if(call Random.rand16() & 2) { + call Timer.start(RX_SETUP_TIME - TX_SETUP_TIME + 16 - level*8 + ADDED_DELAY); } else { - call Timer.start(RX_SETUP_TIME - TX_SETUP_TIME); - call UartPhyControl.setNumPreambles(PREAMBLE_LONG); + macState = TX_ACK; + call Timer.start(RX_SETUP_TIME - TX_SETUP_TIME + 16); } + prepareAck(msg); } else if(action == RX_ACK) { macState = RX_ACK; @@ -1005,43 +996,56 @@ implementation } else if(action == SLEEP) { macState = SLEEP; - setSleepMode(); if(isFlagSet(&flags, RESUME_BACKOFF)) { + nav = nav*(uint32_t)ADD_NAV/(uint32_t)NAV_FACTOR; if(nav > restLaufzeit) restLaufzeit += nav; } else { setFlag(&flags, RESUME_BACKOFF); - restLaufzeit = nav + backoff(longRetryCounter); + restLaufzeit = call Random.rand16() & ZERO_BACKOFF_MASK; } + setSleepMode(); } else if(action == INIT) { - if(!isFlagSet(&flags, UNHANDLED_PACKET)) signalFailure(11); clearFlag(&flags, UNHANDLED_PACKET); } else { - storeOldState(94); - signalFailure(11); + // sdDebug(207); + } +#ifdef REDMAC_PERFORMANCE + if(error == SUCCESS) { + rxStat.type = getHeader(msg)->type; + rxStat.from = getHeader(msg)->src; + rxStat.to = getHeader(msg)->dest; + rxStat.token = getHeader(msg)->token; + if(!isControl(msg)) rxStat.repCounter = ((red_mac_header_t*)payload)->repetitionCounter; + rxStat.payloadLength = len; + rxStat.strength = rssiValue; + rxStat.creationTime = getMetadata(msg)->time; + call Performance.macRxStats(&rxStat); } +#endif return m; } async event void PacketSend.sendDone(message_t* msg, error_t error) { if(macState == TX) { - storeOldState(97); - if(msg != txBufPtr) signalFailure(12); - storeOldState(99); macState = RX_ACK; setRxMode(); call Timer.start(RX_ACK_TIMEOUT); + // sdDebug(220); checkCounter = 0; } else if(macState == TX_ACK) { checkCounter = 0; - macState = RX; - setRxMode(); - } - else { - signalFailure(13); + macState = SLEEP; + setSleepMode(); + // macState = RX; + // setRxMode(); + // sdDebug(221); +#ifdef REDMAC_DEBUG + // sdDebug(40000U + repCounter); +#endif } } @@ -1049,41 +1053,29 @@ implementation async event void RadioTimeStamping.receivedSFD( uint16_t time ) { if(call RssiAdcResource.isOwner()) call ChannelMonitorData.getSnr(); if(macState == RX_P) { - rxTime = call LocalTime32khz.get(); + rxTime = call LocalTime32kHz.get(); call ChannelMonitor.rxSuccess(); + sdDebug(221); } } async event void RadioTimeStamping.transmittedSFD( uint16_t time, message_t* p_msg ) { - uint32_t now; - uint32_t mTime; if((macState == TX) && (p_msg == txBufPtr)) { - now = call LocalTime32khz.get(); - mTime = getMetadata(p_msg)->time; - if(now >= mTime) { - txMacHdr->time = now - mTime; - } - else { - // assume a clock wrap here - txMacHdr->time = MAX_TIME_VALUE - mTime + now; - } - } - } - - async command uint32_t LocalTime32khz.get() { - ui32parts_t time; - atomic { - time.lo = call Counter32khz16.get(); - time.hi = counter2sec; +#ifdef DELTATIMEDEBUG + dTrace.now = call LocalTime32kHz.get(); + dTrace.msgTime = getMetadata(p_msg)->time; + dTrace.delta = call TimeDiff32.computeDelta(dTrace.now, dTrace.msgTime); + txMacHdr->time = dTrace.delta; + call DeltaTrace.traceTx(&dTrace); + getMetadata(p_msg)->sfdtime = dTrace.now; +#else + getMetadata(p_msg)->sfdtime = call LocalTime32kHz.get(); + txMacHdr->time = + call TimeDiff32.computeDelta(getMetadata(p_msg)->sfdtime, + getMetadata(p_msg)->time); +#endif } - return time.op; - } - - async event void Counter32khz16.overflow() { - counter2sec++; } - - /****** Timer ******************************/ @@ -1092,9 +1084,12 @@ implementation if((macState == RX) || (macState == CCA) || (macState == CCA_ACK)) { if(macState == CCA) { computeBackoff(); +#ifdef REDMAC_PERFORMANCE + call Performance.macBusyOnCca(); +#endif } requestAdc(); - storeOldState(150); + // sdDebug(230); macState = RX; checkCounter = 0; call Timer.start(TX_GAP_TIME>>1); @@ -1105,122 +1100,144 @@ implementation if(macState == RX) { checkCounter++; if(checkCounter >= 3) { - storeOldState(153); + // sdDebug(240); macState = SLEEP; setSleepMode(); } else { - storeOldState(154); - call Timer.start(TX_GAP_TIME>>1); + // sdDebug(241); + call Timer.start(TX_GAP_TIME >> 1); requestAdc(); } } else if(macState == CCA) { checkCounter++; if(checkCounter < 3) { - storeOldState(158); - call Timer.start((TX_GAP_TIME + backoff(0))>>1); + // sdDebug(242); + call Timer.start(TX_GAP_TIME >> 1); requestAdc(); } else { - storeOldState(159); + // sdDebug(243); macState = TX; setTxMode(); +#ifdef REDMAC_PERFORMANCE + call Performance.macIdleOnCca(); + txStat.txModeTime = call LocalTime32kHz.get(); +#endif } } else if(macState == CCA_ACK) { - storeOldState(160); + // sdDebug(244); macState = TX_ACK; setTxMode(); + // sdDebug(20000 + getHeader(&ackMsg)->dest); +#ifdef REDMAC_PERFORMANCE + call Performance.macTxAckStats(getHeader(&ackMsg)->type, + getHeader(&ackMsg)->dest, + getHeader(&ackMsg)->token); +#endif } } async event void Timer.fired() { - storeOldState(100); + // sdDebug(250); if((macState == RX) || (macState == CCA) || (macState == CCA_ACK)) { - if(isFlagSet(&flags, SWITCHING)) signalFailure(14); if((!call RssiAdcResource.isOwner()) || (call ChannelMonitor.start() != SUCCESS)) { if(call UartPhyControl.isBusy()) { - storeOldState(101); + // sdDebug(251); checkOnBusy(); } else { - storeOldState(102); + // sdDebug(252); checkOnIdle(); } } } else if(macState == RX_ACK) { if(prepareRepetition()) { - storeOldState(156); + // sdDebug(253); macState = TX; setTxMode(); } else { if(needsAckTx(txBufPtr)) { - storeOldState(157); + // sdDebug(254); +#ifdef REDMAC_PERFORMANCE + call Performance.macAckTimeout(); +#endif updateLongRetryCounters(); } else { - storeOldState(158); + // sdDebug(255); signalSendDone(SUCCESS); } macState = SLEEP; setSleepMode(); } } + else if(macState == TX_ACK) { + setTxMode(); + // sdDebug(10000 + getHeader(&ackMsg)->dest); + } else if(macState == SLEEP) { if(isFlagSet(&flags, SWITCHING)) { - storeOldState(106); - call Timer.start(backoff(0)); + // sdDebug(256); + call Timer.start(call Random.rand16() & 0x0f); } else { - storeOldState(107); - checkSend(); + if(isFlagSet(&flags, RESUME_BACKOFF)) { + // sdDebug(261); + clearFlag(&flags, RESUME_BACKOFF); + call Timer.start(restLaufzeit); + restLaufzeit = 0; + } + else { + // sdDebug(262); + checkSend(); + } } } else if((macState == RX_ACK_P) || (macState == RX_P)) { - storeOldState(108); + // sdDebug(258); } else if(macState == INIT) { - storeOldState(109); + // sdDebug(259); post StartDoneTask(); } else { - storeOldState(110); - signalFailure(15); - } - } - - /****** SampleTimer ******************************/ - - task void ageMsgsTask() { - unsigned i; - atomic { - for(i = 0; i < MSG_TABLE_ENTRIES; i++) { - if(knownMsgTable[i].age <= MAX_AGE) ++knownMsgTable[i].age; - } + // sdDebug(260); } } + /****** SampleTimer ******************************/ async event void SampleTimer.fired() { - call SampleTimer.start(sleepTime); - storeOldState(111); + call SampleTimer.start(localSleeptime); + // sdDebug(270); if((macState == SLEEP) && (!isFlagSet(&flags, SWITCHING))) { clearFlag(&flags, ACTION_DETECTED); interruptBackoffTimer(); macState = RX; - storeOldState(112); + // sdDebug(271); setRxMode(); call Timer.stop(); } - post ageMsgsTask(); } - /***** SleepTime **********************************/ - async command void SleepTime.setSleepTime(uint16_t sT) { + /***** Sleeptime **********************************/ + async command void Sleeptime.setLocalSleeptime(uint16_t sT) { + atomic localSleeptime = sT; + } + + async command uint16_t Sleeptime.getLocalSleeptime() { + uint16_t st; + atomic st = localSleeptime; + return st; + } + + async command void Sleeptime.setNetworkSleeptime(uint16_t sT) { atomic { - sleepTime = sT; + networkSleeptime = sT; for(MIN_BACKOFF_MASK = 1; MIN_BACKOFF_MASK < sT; ) { MIN_BACKOFF_MASK = (MIN_BACKOFF_MASK << 1) + 1; } @@ -1228,21 +1245,21 @@ implementation } } - async command uint16_t SleepTime.getSleepTime() { + async command uint16_t Sleeptime.getNetworkSleeptime() { uint16_t st; - atomic st = sleepTime; + atomic st = networkSleeptime; return st; } /****** ChannelMonitor events *********************/ async event void ChannelMonitor.channelBusy() { - storeOldState(120); + // sdDebug(280); checkOnBusy(); } async event void ChannelMonitor.channelIdle() { - storeOldState(121); + // sdDebug(281); checkOnIdle(); } @@ -1250,19 +1267,17 @@ implementation event void ChannelMonitorControl.updateNoiseFloorDone() { if(macState == INIT) { - storeOldState(130); - call Timer.start(call Random.rand16() % DEFAULT_SLEEP_TIME); + // sdDebug(290); + call Timer.start(call Random.rand16() % localSleeptime); setSleepMode(); } else { - storeOldState(131); - signalFailure(16); + // sdDebug(291); } } /***** ChannelMonitorData events ******************/ async event void ChannelMonitorData.getSnrDone(int16_t data) { - storeOldState(140); atomic if((macState == RX_P) || (macState == RX_ACK_P)) rssiValue = data; } @@ -1271,14 +1286,14 @@ implementation macState_t ms; atomic ms = macState; if(ms < SLEEP) { - storeOldState(144); + // sdDebug(300); } else if(ms == INIT) { - storeOldState(145); + // sdDebug(301); call ChannelMonitorControl.updateNoiseFloor(); } else { - storeOldState(146); + // sdDebug(302); post ReleaseAdcTask(); } } @@ -1307,23 +1322,29 @@ implementation } default async event void ChannelCongestion.congestionEvent(uint8_t level) {} + + /***** Mac Eval *******************************************/ +#ifdef MAC_EVAL + async command void MacEval.setBackoffMask(uint16_t mask) { + atomic MIN_BACKOFF_MASK = mask; + } + async command void MacEval.increaseBackoff(bool value) { + atomic INCREASE_BACKOFF = value; + } + async command void MacEval.addNav(uint8_t value) { + atomic ADD_NAV = value; + } + async command void MacEval.setLongRetry(uint8_t lr) { + atomic MAX_LONG_RETRY = lr; + } + async command void MacEval.setShortRetry(uint8_t sr) { + atomic MAX_SHORT_RETRY = sr; + } +#endif /***** unused Radio Modes events **************************/ - async event void RadioModes.TimerModeDone() {} async event void RadioModes.SelfPollingModeDone() {} async event void RadioModes.PWDDDInterrupt() {} - - /** prevent MCU from going into a too low power mode */ - async command mcu_power_t McuPowerOverride.lowestState() { - mcu_power_t mp; - if(macState != SLEEP) { - mp = MSP430_POWER_LPM1; - } - else { - mp = MSP430_POWER_LPM3; - } - return mp; - } }