]> oss.titaniummirror.com Git - tinyos-2.x.git/blobdiff - tos/chips/tda5250/mac/RedMacP.nc
Merge TinyOS 2.1.1 into master.
[tinyos-2.x.git] / tos / chips / tda5250 / mac / RedMacP.nc
index 164813de6f9177edbfd9c03c41b5e4f14d969271..d0de4d0e4b5f0aba95df81735928e491a80095f1 100644 (file)
 #include "PacketAck.h"
 #include "RedMac.h"
 
+#ifdef DELTATIMEDEBUG
+#include "DeltaTrace.h"
+#endif
+
 module RedMacP {
     provides {
         interface Init;
@@ -46,10 +50,12 @@ module RedMacP {
         interface MacSend;
         interface MacReceive;
         interface Packet;
-        interface LocalTime<T32khz> as LocalTime32khz;
         interface Sleeptime;
         interface Teamgeist;
         interface ChannelCongestion;
+#ifdef MAC_EVAL
+        interface MacEval;
+#endif
     }
     uses {
         interface StdControl as CcaStdControl;
@@ -72,7 +78,12 @@ module RedMacP {
         
         interface Alarm<T32khz, uint16_t> as Timer;
         interface Alarm<T32khz, uint16_t> as SampleTimer;
-        interface Counter<T32khz,uint16_t> as Counter32khz16;
+        interface LocalTime<T32khz> as LocalTime32kHz;
+
+        interface Duplicate;
+        interface TimeDiff16;
+        interface TimeDiff32;
+        
         async command am_addr_t amAddress();
 /*
         interface GeneralIO as Led0;
@@ -86,7 +97,9 @@ module RedMacP {
 #ifdef REDMAC_PERFORMANCE
         interface Performance;
 #endif
-
+#ifdef DELTATIMEDEBUG
+        interface DeltaTrace;
+#endif
     }
 }
 implementation
@@ -119,26 +132,29 @@ implementation
 #endif
     
 #ifdef REDMAC_PERFORMANCE
-    macTxStat_t txStat;
-    macRxStat_t rxStat;
+     PfmTxMsg_t txStat;
+     PfmRxMsg_t rxStat;
 #endif
 
     /**************** Module Global Constants  *****************/
     enum {
+        
+        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
 
-        BYTE_TIME=21,                 // byte at 23405 kBit/s, 4b6b encoded
-        PREAMBLE_BYTE_TIME=14,        // byte at 23405 kBit/s, no coding
-        PHY_HEADER_TIME=84,           // 6 Phy Preamble at 23405 bits/s
-        TIME_CORRECTION=16,           // difference between txSFD and rxSFD: 475us
-                
         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=3250,
-        // DEFAULT_SLEEP_TIME=6500,
-        // DEFAULT_SLEEP_TIME=9750,
-        DEFAULT_SLEEP_TIME=16384,
+#ifndef DEFAULT_SLEEP_TIME
+        DEFAULT_SLEEP_TIME=2048,
+        // DEFAULT_SLEEP_TIME=4096,
+        // DEFAULT_SLEEP_TIME=8192,
+        // DEFAULT_SLEEP_TIME=16384,
         // DEFAULT_SLEEP_TIME=32768U,
+        // DEFAULT_SLEEP_TIME=65535U,
+#endif
         DATA_DETECT_TIME=17,
         RX_SETUP_TIME=102,    // time to set up receiver
         TX_SETUP_TIME=58,     // time to set up transmitter
@@ -147,10 +163,13 @@ implementation
         TX_GAP_TIME = RX_ACK_TIMEOUT + TX_SETUP_TIME + 33,
         // the duration of a send ACK
         ACK_DURATION = SUB_HEADER_TIME + SUB_FOOTER_TIME,
+        NAV_FACTOR = 4,
+#ifndef MAC_EVAL
         MAX_SHORT_RETRY=9,
         MAX_LONG_RETRY=3,
-        MAX_AGE=2*MAX_LONG_RETRY*MAX_SHORT_RETRY,
-        MSG_TABLE_ENTRIES=20,
+        ADD_NAV = 2,
+        INCREASE_BACKOFF = TRUE,
+#endif
         TOKEN_ACK_FLAG = 64,
         TOKEN_ACK_MASK = 0x3f,
         INVALID_SNR = 0xffff,
@@ -159,17 +178,17 @@ implementation
         // 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,
@@ -182,14 +201,6 @@ 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 = 0;
     uint8_t checkCounter = 0;
     uint8_t shortRetryCounter = 0;
@@ -198,8 +209,7 @@ implementation
     uint16_t localSleeptime = DEFAULT_SLEEP_TIME;
     uint16_t rssiValue = 0;
     uint32_t restLaufzeit = 0;
-
-    uint16_t counter2sec = 127;
+    
     uint32_t rxTime = 0;
 
     am_id_t teamgeistType = 0;
@@ -213,7 +223,7 @@ implementation
     message_t ackMsg;
 
     uint16_t MIN_BACKOFF_MASK;
-    
+
     /****** Secure switching of radio modes ***/
     void interruptBackoffTimer();
     
@@ -301,7 +311,7 @@ implementation
         }
     }
 
-    /**************** Helper functions ************************/
+    /**************** Helper functions ************************/    
     void computeBackoff();
     
     void checkSend() {
@@ -327,6 +337,7 @@ implementation
 
     uint32_t backoff(uint8_t counter) {
         uint32_t rVal = call Random.rand16() &  MIN_BACKOFF_MASK;
+        if(!INCREASE_BACKOFF) counter = 1;
         return (rVal << counter) + ZERO_BACKOFF_MASK;
     }
     
@@ -356,8 +367,8 @@ implementation
                 if(isFlagSet(&flags, TEAMGEIST_ACTIVE) &&
                    (getHeader(msg)->type == teamgeistType)) {
                     if(rssiValue != INVALID_SNR) snr = rssiValue;
-                    rVal = signal Teamgeist.needsAck(msg, getHeader(msg)->src, getHeader(msg)->dest, snr);
                     *level = 2;
+                    rVal = signal Teamgeist.needsAck(msg, getHeader(msg)->src, getHeader(msg)->dest, snr);
                 }
             }
         }
@@ -375,7 +386,7 @@ implementation
             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));
         macHdr->repetitionCounter = sT/(length * BYTE_TIME + SUB_HEADER_TIME + SUB_FOOTER_TIME + 
                                         TX_GAP_TIME) + 1;
         atomic {
@@ -394,6 +405,8 @@ implementation
                     call Timer.start((call Random.rand16() >> 3) & ZERO_BACKOFF_MASK);
                 }
                 else {
+                    sdDebug(332);
+                    sdDebug(macHdr->repetitionCounter);
                     call Timer.start(backoff(longRetryCounter));
                 }
             }
@@ -408,6 +421,20 @@ implementation
         }
     }
 
+    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;
+            }
+        }
+    }
+
     bool prepareRepetition() {
         bool repeat;
         atomic {
@@ -421,7 +448,7 @@ implementation
         }
         return repeat;
     }
-
+    
     void signalSendDone(error_t error) {
         message_t *m;
         error_t e = error;
@@ -437,12 +464,7 @@ implementation
 #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;
             }
@@ -493,17 +515,9 @@ implementation
     }
 
     void interruptBackoffTimer() {
-        uint16_t now;
         if(call Timer.isRunning()) {
-            restLaufzeit = call Timer.getAlarm();
-            call Timer.stop(); 
-            now = call Timer.getNow(); 
-            if(restLaufzeit >= now) {
-                restLaufzeit = restLaufzeit - now;
-            }
-            else {
-                restLaufzeit =  (uint16_t)(-1) - restLaufzeit + now;
-            }
+            restLaufzeit = call TimeDiff16.computeDelta(call Timer.getAlarm(), call Timer.getNow());
+            call Timer.stop();
             if(restLaufzeit > MIN_BACKOFF_MASK << MAX_LONG_RETRY) {
                 restLaufzeit = call Random.rand16() & ZERO_BACKOFF_MASK;
             }
@@ -532,38 +546,14 @@ implementation
     }
     
     bool isNewMsg(message_t* msg) {
-        bool rVal = TRUE;
-        uint8_t i;
-        for(i=0; i < MSG_TABLE_ENTRIES; i++) {
-            if((knownMsgTable[i].age < MAX_AGE) &&
-               (getHeader(msg)->src == knownMsgTable[i].src) &&
-               (((getHeader(msg)->token) & TOKEN_ACK_MASK) == knownMsgTable[i].token)) {
-                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) {
@@ -574,24 +564,28 @@ implementation
         getHeader(&ackMsg)->dest = getHeader(msg)->src;
         getHeader(&ackMsg)->type = getHeader(msg)->type;
 #ifdef REDMAC_DEBUG
-        repCounter = ((red_mac_header_t *)call SubPacket.getPayload(msg, NULL))->repetitionCounter;
+        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;
             seqNo = call Random.rand16() % TOKEN_ACK_FLAG;
-            for(i = 0; i < MSG_TABLE_ENTRIES; i++) {
-                knownMsgTable[i].age = MAX_AGE;
-            }
             for(MIN_BACKOFF_MASK = 1; MIN_BACKOFF_MASK < networkSleeptime; ) {
                 MIN_BACKOFF_MASK = (MIN_BACKOFF_MASK << 1) + 1;
             }
@@ -667,11 +661,8 @@ 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));
     }
     
@@ -687,8 +678,6 @@ implementation
             if(call RssiAdcResource.isOwner()) call ChannelMonitorData.getSnr();
         }
         else if(macState == RX_ACK) {
-            // if(call RssiAdcResource.isOwner()) call ChannelMonitor.start();
-            // sdDebug(132);
         }
         else if(macState == RX_ACK_P) {
         }
@@ -797,7 +786,7 @@ implementation
                 if(seqNo >= TOKEN_ACK_FLAG) seqNo = 1;
 #ifdef REDMAC_PERFORMANCE
                 txStat.payloadLength = txLen;
-                txStat.interfaceTime = call LocalTime32khz.get();
+                txStat.interfaceTime = call LocalTime32kHz.get();
 #endif
             }
             else {
@@ -886,17 +875,11 @@ implementation
                             rxStat.duplicate = PERF_NEW_MSG;
 #endif
                             // sdDebug(194);
-                            if(rssiValue != INVALID_SNR) {
-                                (getMetadata(m))->strength = rssiValue;
-                            }
-                            else {
-                                if(call RssiAdcResource.isOwner()) {
-                                    (getMetadata(m))->strength = call ChannelMonitorData.readSnr();
-                                }
-                                else {
-                                    (getMetadata(m))->strength = 1;
-                                }
-                            }
+                            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);
@@ -913,14 +896,16 @@ implementation
 #endif
                             }
                         }
-#ifdef REDMAC_PERFORMANCE
                         else {
+#ifdef REDMAC_PERFORMANCE
                             rxStat.duplicate = PERF_REPEATED_MSG;
+#endif
                         }
-#endif                  
                         if(needsAckRx(msg, &level) && (action != RX)) {
-                            // sdDebug(197);
                             action = CCA_ACK;
+                            if(level == 2) {
+                                getMetadata(msg)->ack = WAS_ACKED;
+                            }
                         }
                         else {
                             // sdDebug(198);
@@ -950,24 +935,13 @@ implementation
             }
             else {
                 // sdDebug(201);
-                action = RX;
+                action = SLEEP;
             }
         }
         else if(macState == RX_ACK_P) {
             if(error == SUCCESS) {
                 if(ackIsForMe(msg)) {
                     // sdDebug(202);
-                    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;
                     getMetadata(txBufPtr)->repetitions = txMacHdr->repetitionCounter;
                     if(isFlagSet(&flags, TEAMGEIST_ACTIVE) &&
@@ -982,7 +956,7 @@ implementation
                     action = SLEEP;
                 }
                 else {
-                    sdDebug(203);
+                    // sdDebug(203);
                     updateLongRetryCounters(); // this will eventually schedule the right backoff
                     macState = SLEEP;          // so much traffic is going on -- take a nap
                     setSleepMode();
@@ -991,11 +965,11 @@ implementation
             }
             else {
                 if(call Timer.isRunning()) {
-                    sdDebug(204);
+                    // sdDebug(204);
                     action = RX_ACK;
                 }
                 else {
-                    sdDebug(205);
+                    // sdDebug(205);
                     updateLongRetryCounters();
                     action = RX;
                 }
@@ -1027,6 +1001,7 @@ implementation
         else if(action == SLEEP) {
             macState = SLEEP;
             if(isFlagSet(&flags, RESUME_BACKOFF)) {
+                nav = nav*(uint32_t)ADD_NAV/(uint32_t)NAV_FACTOR;
                 if(nav > restLaufzeit) restLaufzeit += nav;
             }
             else {
@@ -1067,8 +1042,10 @@ implementation
         }
         else if(macState == TX_ACK) {
             checkCounter = 0;
-            macState = RX;
-            setRxMode();
+            macState = SLEEP;
+            setSleepMode();
+            // macState = RX;
+            // setRxMode();
             // sdDebug(221);
 #ifdef REDMAC_DEBUG            
             // sdDebug(40000U + repCounter);
@@ -1080,42 +1057,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();
         }
     }
     
     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 = (uint32_t)(-1) - mTime + now;
-            }
-        }
-    }
-    
-    async command uint32_t LocalTime32khz.get() {
-        ui32parts_t time;
-        atomic {
-            time.lo = call Counter32khz16.get();
-            time.hi = counter2sec;
-            if(call Counter32khz16.isOverflowPending()) ++time.hi;
+#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 ******************************/
 
     void checkOnBusy() {
@@ -1162,7 +1126,7 @@ implementation
                 setTxMode();
 #ifdef REDMAC_PERFORMANCE
                 call Performance.macIdleOnCca();
-                txStat.txModeTime = call LocalTime32khz.get();
+                txStat.txModeTime = call LocalTime32kHz.get();
 #endif
             }
         }
@@ -1248,18 +1212,8 @@ implementation
             // sdDebug(260);
         }
     }
-
-    /****** SampleTimer ******************************/
-
-    task void ageMsgsTask() {
-        unsigned i;
-        atomic {
-            for(i = 0; i < MSG_TABLE_ENTRIES; i++) {
-                if(knownMsgTable[i].age <= MAX_AGE) ++knownMsgTable[i].age;
-            }
-        }
-    }
     
+    /****** SampleTimer ******************************/
     async event void SampleTimer.fired() {
         call SampleTimer.start(localSleeptime);
         // sdDebug(270);
@@ -1271,7 +1225,6 @@ implementation
             setRxMode();
             call Timer.stop();
         }
-        post ageMsgsTask();
     }
 
     /***** Sleeptime **********************************/
@@ -1373,8 +1326,26 @@ implementation
     
     default async event void ChannelCongestion.congestionEvent(uint8_t level) {}
 
-    /***** unused Radio Modes events **************************/
+    /***** 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() {}