X-Git-Url: https://oss.titaniummirror.com/gitweb/?a=blobdiff_plain;f=tos%2Fchips%2Ftda5250%2Fmac%2FCsmaMacP.nc;h=7f17e4145d0ef57d8fd763f2ceea178dd0d0cac0;hb=a17321a72cfe58782f13e2b27afff01fae9b9e39;hp=28de91414a2145e3e98d880136962514a85b774c;hpb=337d0b13acf569c2640b3ed7b7f5c7cec35d7ddd;p=tinyos-2.x.git diff --git a/tos/chips/tda5250/mac/CsmaMacP.nc b/tos/chips/tda5250/mac/CsmaMacP.nc index 28de9141..7f17e414 100644 --- a/tos/chips/tda5250/mac/CsmaMacP.nc +++ b/tos/chips/tda5250/mac/CsmaMacP.nc @@ -45,12 +45,10 @@ // #define MACM_DEBUG // debug... module CsmaMacP { provides { - interface Init; interface SplitControl; interface MacSend; interface MacReceive; interface Packet; - interface McuPowerOverride; } uses { interface StdControl as CcaStdControl; @@ -72,43 +70,54 @@ module CsmaMacP { interface Random; interface Timer as ReRxTimer; + interface Duplicate; + interface TimeDiff16; interface Alarm as Timer; async command am_addr_t amAddress(); - + interface LocalTime as LocalTime32kHz; + #ifdef MACM_DEBUG - interface GeneralIO as Led0; - interface GeneralIO as Led1; - interface GeneralIO as Led2; - interface GeneralIO as Led3; + interface SerialDebug; #endif } } implementation { + /****** debug vars & defs & functions ***********************/ +#ifdef MACM_DEBUG + void sdDebug(uint16_t p) { + call SerialDebug.putPlace(p); + }; +#else + void sdDebug(uint16_t p) {}; +#endif + /******* constants and type definitions *********************/ 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 + + 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(tda5250_header_t)*BYTE_TIME, - SUB_FOOTER_TIME=2*BYTE_TIME, // 2 bytes crc 38400 kBit/s with 4b6b encoding + SUB_FOOTER_TIME=2*BYTE_TIME, // 2 bytes crc MAXTIMERVALUE=0xFFFF, // helps to compute backoff DATA_DETECT_TIME=17, - RX_SETUP_TIME=111, // time to set up receiver - TX_SETUP_TIME=69, // time to set up transmitter + 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 + 19 + 2*ADDED_DELAY, - TX_GAP_TIME=RX_ACK_TIMEOUT + TX_SETUP_TIME + 11, + RX_ACK_TIMEOUT=RX_SETUP_TIME + PHY_HEADER_TIME + 2*ADDED_DELAY, + TX_GAP_TIME=RX_ACK_TIMEOUT + TX_SETUP_TIME + 33, MAX_SHORT_RETRY=7, MAX_LONG_RETRY=4, BACKOFF_MASK=0xFFF, // minimum time around one packet time MIN_PREAMBLE_BYTES=2, TOKEN_ACK_FLAG = 64, TOKEN_ACK_MASK = 0x3f, - INVALID_SNR = 0xffff, - MSG_TABLE_ENTRIES=20, - MAX_AGE=2*MAX_LONG_RETRY*MAX_SHORT_RETRY, + INVALID_SNR = 0xffff }; /**************** Module Global Variables *****************/ @@ -139,109 +148,24 @@ implementation } flags_t; /* Packet vars */ - message_t* txBufPtr; + message_t* txBufPtr = NULL; message_t ackMsg; uint8_t txLen; - uint8_t shortRetryCounter; + uint8_t shortRetryCounter = 0; - uint8_t longRetryCounter; + uint8_t longRetryCounter = 0; unsigned checkCounter; - macState_t macState; - uint8_t flags; + macState_t macState = INIT; + uint8_t flags = 0; uint8_t seqNo; uint16_t restLaufzeit; - /* duplicate suppression */ - typedef struct knownMessage_t { - am_addr_t src; - uint8_t token; - uint8_t age; - } knownMessage_t; - - knownMessage_t knownMsgTable[MSG_TABLE_ENTRIES]; + uint16_t rssiValue = 0; - task void ageMsgsTask() { - unsigned i; - atomic { - for(i = 0; i < MSG_TABLE_ENTRIES; i++) { - if(knownMsgTable[i].age <= MAX_AGE) ++knownMsgTable[i].age; - } - } - } - - /****** debug vars & defs & functions ***********************/ -#ifdef MACM_DEBUG -#define HISTORY_ENTRIES 100 - 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; - } - } -#else - void storeOldState(int p) {}; -#endif - - void signalFailure(uint8_t place) { -#ifdef MACM_DEBUG - unsigned long i; - atomic { - for(;;) { - call Led0.set(); - call Led1.clr(); - call Led2.clr(); - call Led3.clr(); - - for(i = 0; i < 1000000; i++) { - ; - } - - (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++) { - ; - } - } - } -#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(); -*/ -#endif - } + uint32_t rxTime = 0; /****** Secure switching of radio modes ***/ @@ -274,6 +198,7 @@ implementation } void setRxMode() { + rssiValue = INVALID_SNR; if(call RadioModes.RxMode() == FAIL) { post SetRxModeTask(); } @@ -312,31 +237,37 @@ implementation task void postponeReRx() { call ReRxTimer.startOneShot(5000); } - + uint16_t backoff(uint8_t counter) { uint16_t mask = BACKOFF_MASK >> (MAX_LONG_RETRY - counter); return (call Random.rand16() & mask); } 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 > BACKOFF_MASK) { - restLaufzeit = backoff(0); + restLaufzeit = call Random.rand16() & 0xFF; } setFlag(&flags, RESUME_BACKOFF); } } - + + 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; + } + } + } + void signalSendDone(error_t error) { message_t *m; error_t e = error; @@ -349,6 +280,7 @@ implementation if(isFlagSet(&flags, CANCEL_SEND)) { e = ECANCEL; } + storeStrength(m); clearFlag(&flags, CANCEL_SEND); } signal MacSend.sendDone(m, e); @@ -358,7 +290,7 @@ implementation longRetryCounter++; shortRetryCounter = 1; if(longRetryCounter > MAX_LONG_RETRY) { - storeOldState(13); + sdDebug(13); getMetadata(txBufPtr)->ack = WAS_NOT_ACKED; signalSendDone(FAIL); } @@ -381,54 +313,30 @@ implementation setFlag(&flags, RESUME_BACKOFF); restLaufzeit = backoff(longRetryCounter); updateRetryCounters(); - storeOldState(92); + sdDebug(92); } } bool isNewMsg(message_t* msg) { - 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; - return FALSE; - } - } - return TRUE; - } - - 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 checkSend() { if((txBufPtr != NULL) && (macState == RX) && (!call Timer.isRunning())) { macState = CCA; - signalMacState(); checkCounter = 0; requestAdc(); call Timer.start(DATA_DETECT_TIME); - storeOldState(170); + sdDebug(170); } else { - storeOldState(171); + sdDebug(171); post ReleaseAdcTask(); } } @@ -480,33 +388,11 @@ implementation return isFlagSet(&token, TOKEN_ACK_FLAG); } - /**************** Init ************************/ - - command error_t Init.init(){ - unsigned i; - atomic { - txBufPtr = NULL; - macState = INIT; - signalMacState(); - shortRetryCounter = 0; - longRetryCounter = 0; - flags = 0; - for(i = 0; i < MSG_TABLE_ENTRIES; i++) { - knownMsgTable[i].age = MAX_AGE; - } -#ifdef MACM_DEBUG - histIndex = 0; -#endif - } - return SUCCESS; - } - /**************** SplitControl *****************/ task void StartDoneTask() { atomic { macState = RX; - signalMacState(); call UartPhyControl.setNumPreambles(MIN_PREAMBLE_BYTES); } post ReleaseAdcTask(); @@ -517,9 +403,9 @@ implementation call CcaStdControl.start(); atomic { macState = INIT; - signalMacState(); + setRxMode(); - storeOldState(1); + sdDebug(1); } return SUCCESS; } @@ -528,11 +414,15 @@ implementation atomic { if (macState != RX) { post StopDone(); - storeOldState(2); + sdDebug(2); } else { - storeOldState(3); + sdDebug(3); call Timer.stop(); - call Init.init(); + txBufPtr = NULL; + macState = INIT; + shortRetryCounter = 0; + longRetryCounter = 0; + flags = 0; signal SplitControl.stopDone(SUCCESS); } } @@ -540,7 +430,7 @@ implementation command error_t SplitControl.stop() { call CcaStdControl.stop(); - storeOldState(4); + sdDebug(4); post StopDone(); return SUCCESS; } @@ -562,7 +452,7 @@ implementation return call SubPacket.maxPayloadLength(); } - command void* Packet.getPayload(message_t* msg, uint8_t* len) { + command void* Packet.getPayload(message_t* msg, uint8_t len) { return call SubPacket.getPayload(msg, len); } @@ -571,13 +461,13 @@ implementation atomic { setFlag(&flags, RSSI_STABLE); if(macState == INIT) { - storeOldState(11); + sdDebug(11); if(call RssiAdcResource.isOwner()) { call ChannelMonitorControl.updateNoiseFloor(); } } else { - storeOldState(12); + sdDebug(12); } } } @@ -586,9 +476,9 @@ implementation post postponeReRx(); atomic { if(macState == SW_RX) { - storeOldState(21); + sdDebug(21); macState = RX; - signalMacState(); + if(isFlagSet(&flags, RESUME_BACKOFF)) { clearFlag(&flags, RESUME_BACKOFF); call Timer.start(restLaufzeit); @@ -597,16 +487,14 @@ implementation } } else if(macState == SW_RX_ACK) { - storeOldState(22); + sdDebug(22); macState = RX_ACK; - signalMacState(); } else if(macState == INIT) { - storeOldState(24); + sdDebug(24); } else { - storeOldState(25); - signalFailure(1); + sdDebug(25); } } } @@ -615,31 +503,27 @@ implementation post postponeReRx(); atomic { if(macState == SW_TX) { - storeOldState(30); + sdDebug(30); if(txBufPtr) { macState = TX; - signalMacState(); if(call PacketSend.send(txBufPtr, txLen) == SUCCESS) { - storeOldState(31); + sdDebug(31); } else { - storeOldState(32); - signalFailure(2); + sdDebug(32); } } } else if(macState == SW_TX_ACK) { macState = TX_ACK; - signalMacState(); + if(call PacketSend.send(&ackMsg, 0) == SUCCESS) { - storeOldState(53); + sdDebug(53); } else { - storeOldState(54); - signalFailure(6); + sdDebug(54); } } else { - storeOldState(33); - signalFailure(3); + sdDebug(33); } } } @@ -649,11 +533,13 @@ implementation error_t err = SUCCESS; atomic { if((shortRetryCounter == 0) && (txBufPtr == NULL) && (macState != INIT)) { - storeOldState(40); + sdDebug(40); shortRetryCounter = 1; longRetryCounter = 1; txBufPtr = msg; txLen = len; + sdDebug(10); + sdDebug(len); seqNo++; if(seqNo >= TOKEN_ACK_FLAG) seqNo = 1; getHeader(msg)->token = seqNo; @@ -661,7 +547,7 @@ implementation if(macState != RX_P) checkSend(); } else { - storeOldState(41); + sdDebug(41); err = EBUSY; } } @@ -672,14 +558,14 @@ implementation error_t err = SUCCESS; if((shortRetryCounter != 0) && (txBufPtr == msg) && (macState != TX) && (macState != RX_ACK) && (macState != SW_RX_ACK)) { - storeOldState(50); + sdDebug(50); shortRetryCounter = 0; txBufPtr = NULL; txLen = 0; signal MacSend.sendDone(msg, ECANCEL); } else { - storeOldState(51); + sdDebug(51); err = FAIL; } return err; @@ -687,30 +573,29 @@ implementation /****** PacketSerializer events **********************/ async event void PacketReceive.receiveDetected() { + rssiValue = INVALID_SNR; if(macState <= RX_ACK) { - storeOldState(60); + sdDebug(60); interruptBackoffTimer(); if(macState == CCA) computeBackoff(); } if(macState <= RX) { - post ReleaseAdcTask(); - storeOldState(61); + sdDebug(61); macState = RX_P; - signalMacState(); + + requestAdc(); } else if(macState <= RX_ACK) { - post ReleaseAdcTask(); - storeOldState(62); + sdDebug(62); macState = RX_ACK_P; - signalMacState(); + } else if(macState == INIT) { - storeOldState(63); + sdDebug(63); } else { post ReleaseAdcTask(); - storeOldState(64); - signalFailure(4); + sdDebug(64); } } @@ -720,55 +605,53 @@ implementation macState_t action = RX; if(macState == RX_P) { if(error == SUCCESS) { - post ageMsgsTask(); - storeOldState(82); + sdDebug(82); isCnt = isControl(msg); if(msgIsForMe(msg)) { if(!isCnt) { - (getMetadata(m))->strength = 10; + storeStrength(msg); if(isNewMsg(m)) { m = signal MacReceive.receiveDone(msg); rememberMsg(m); } if(needsAckRx(msg)) { - storeOldState(87); + sdDebug(87); action = CCA_ACK; } else { - storeOldState(88); + sdDebug(88); } } else { - storeOldState(89); + sdDebug(89); } } else { - storeOldState(90); + sdDebug(90); } } else { - storeOldState(91); + sdDebug(91); } } else if(macState == RX_ACK_P) { if(error == SUCCESS) { if(ackIsForMe(msg)) { - storeOldState(92); - (getMetadata(txBufPtr))->strength = 10; + sdDebug(92); (getMetadata(txBufPtr))->ack = WAS_ACKED; signalSendDone(SUCCESS); } else { - storeOldState(93); + sdDebug(93); updateLongRetryCounters(); } } else { if(call Timer.isRunning()) { - storeOldState(94); + sdDebug(94); action = RX_ACK; } else { - storeOldState(95); + sdDebug(95); if(needsAckTx(txBufPtr)) { updateLongRetryCounters(); } @@ -784,16 +667,16 @@ implementation if(action == CCA_ACK) { prepareAck(msg); macState = CCA_ACK; - signalMacState(); + call Timer.start(RX_SETUP_TIME - TX_SETUP_TIME + ADDED_DELAY); } else if(action == RX_ACK) { macState = RX_ACK; - signalMacState(); + } else if(action == RX) { macState = RX; - signalMacState(); + if(isFlagSet(&flags, RESUME_BACKOFF)) { clearFlag(&flags, RESUME_BACKOFF); call Timer.start(restLaufzeit); @@ -804,43 +687,40 @@ implementation } else if(action == TX) { macState = SW_TX; - signalMacState(); + setTxMode(); } else if(action == INIT) { } else { - storeOldState(94); - signalFailure(11); + sdDebug(94); } + post ReleaseAdcTask(); return m; } async event void PacketSend.sendDone(message_t* msg, error_t error) { if(macState == TX) { - if(msg != txBufPtr) signalFailure(12); if(needsAckTx(msg)) { - storeOldState(97); + sdDebug(97); macState = SW_RX_ACK; - signalMacState(); + call Timer.start(RX_ACK_TIMEOUT); } else { - storeOldState(99); + sdDebug(99); signalSendDone(error); macState = SW_RX; - signalMacState(); + } setRxMode(); } else if(macState == TX_ACK) { macState = SW_RX; - signalMacState(); + setRxMode(); } - else { - signalFailure(13); - } + post ReleaseAdcTask(); } @@ -850,8 +730,8 @@ implementation computeBackoff(); macState = RX; requestAdc(); - storeOldState(150); - signalMacState(); + sdDebug(150); + if(!call Timer.isRunning()) call Timer.start(TX_GAP_TIME >> 1); } else if(macState == RX) { if(!call Timer.isRunning()) call Timer.start(TX_GAP_TIME + backoff(0)); @@ -865,30 +745,30 @@ implementation else if(macState == CCA) { checkCounter++; if(checkCounter < 3) { - storeOldState(158); + sdDebug(158); call Timer.start((TX_GAP_TIME + backoff(0))>>1); requestAdc(); } else { call Timer.stop(); - storeOldState(159); + sdDebug(159); macState = SW_TX; - signalMacState(); + setTxMode(); } } } async event void Timer.fired() { - storeOldState(100); + sdDebug(100); if(macState == CCA) { if((!call RssiAdcResource.isOwner()) || (call ChannelMonitor.start() != SUCCESS)) { if(call UartPhyControl.isBusy()) { - storeOldState(101); + sdDebug(101); checkOnBusy(); } else { - storeOldState(102); + sdDebug(102); checkOnIdle(); } } else { @@ -897,31 +777,30 @@ implementation } else if(macState == RX_ACK) { if(needsAckTx(txBufPtr)) { - storeOldState(103); + sdDebug(103); updateLongRetryCounters(); macState = RX; call Timer.start(backoff(longRetryCounter)); } else { - storeOldState(104); - signalFailure(7); + sdDebug(104); } } else if(macState == CCA_ACK) { - storeOldState(160); + sdDebug(160); macState = SW_TX_ACK; - signalMacState(); + setTxMode(); } else if((macState == RX_ACK_P) || (macState == RX_P)) { - storeOldState(108); + sdDebug(108); } else if(macState == INIT) { - storeOldState(109); + sdDebug(109); post StartDoneTask(); } else { - storeOldState(110); + sdDebug(110); checkSend(); } } @@ -930,13 +809,13 @@ implementation async event void ChannelMonitor.channelBusy() { clearFlag(&flags, CCA_PENDING); - storeOldState(120); + sdDebug(120); checkOnBusy(); } async event void ChannelMonitor.channelIdle() { clearFlag(&flags, CCA_PENDING); - storeOldState(121); + sdDebug(121); checkOnIdle(); } @@ -945,17 +824,18 @@ implementation event void ChannelMonitorControl.updateNoiseFloorDone() { if(macState == INIT) { - storeOldState(122); + sdDebug(122); post StartDoneTask(); } else { - storeOldState(124); - signalFailure(11); + sdDebug(124); } } /***** ChannelMonitorData events ******************/ async event void ChannelMonitorData.getSnrDone(int16_t data) { + atomic if((macState == RX_P) || (macState == RX_ACK_P)) rssiValue = data; + post ReleaseAdcTask(); } /***** unused Radio Modes events **************************/ @@ -982,21 +862,29 @@ implementation /***** abused TimeStamping events **************************/ async event void RadioTimeStamping.receivedSFD( uint16_t time ) { - if(macState == RX_P) call ChannelMonitor.rxSuccess(); + if(call RssiAdcResource.isOwner()) call ChannelMonitorData.getSnr(); + if(macState == RX_P) { + rxTime = call LocalTime32kHz.get(); + call ChannelMonitor.rxSuccess(); + } } - async event void RadioTimeStamping.transmittedSFD( uint16_t time, message_t* p_msg ) {} + async event void RadioTimeStamping.transmittedSFD( uint16_t time, message_t* p_msg ) { + if((macState == TX) && (p_msg == txBufPtr)) { + // to do + } + } /***** Rssi Resource events ******************/ event void RssiAdcResource.granted() { macState_t ms; atomic ms = macState; if((ms == INIT) && isFlagSet(&flags, RSSI_STABLE)) { - storeOldState(145); + sdDebug(145); call ChannelMonitorControl.updateNoiseFloor(); } else { - storeOldState(146); + sdDebug(146); call RssiAdcResource.release(); } } @@ -1012,11 +900,6 @@ implementation // we don't care about urgent Resource requestes async event void RadioResourceRequested.immediateRequested() {} - - /** prevent MCU from going into a too low power mode */ - async command mcu_power_t McuPowerOverride.lowestState() { - return MSP430_POWER_LPM1; - } }