CC1000RadioIntM.nc~
上传用户:joranyuan
上传日期:2022-06-23
资源大小:3306k
文件大小:51k
源码类别:

网络

开发平台:

Others

  1. includes crc;
  2. includes CC1000Const;
  3. includes zmacInfo;
  4. includes DrandInfo;
  5. module CC1000RadioIntM {
  6.   provides {
  7.     interface StdControl;
  8.     interface BareSendMsg as Send;
  9.     interface ReceiveMsg as Receive;
  10.     interface RadioCoordinator as RadioSendCoordinator;
  11.     interface RadioCoordinator as RadioReceiveCoordinator;
  12.     interface MacControl;
  13.     interface MacBackoff;
  14.     interface LowPowerListening;
  15.     interface SetDrand;
  16.     
  17.     // legacy commands supported, but should now use the
  18.     // Low Power Listening interface
  19.     async command result_t SetListeningMode(uint8_t power);
  20.     async command uint8_t GetListeningMode();
  21.     async command result_t SetTransmitMode(uint8_t power);
  22.     async command uint8_t GetTransmitMode();
  23.     // Used for debugging the noise floor (gets the current squelch value)
  24.     async command uint16_t GetSquelch();
  25.     // Used for debugging; gets an estimate of the power consumed by the radio
  26.     async command uint16_t GetPower();
  27.     async command result_t ResetPower();
  28.   }
  29.   uses {
  30.     interface SClock;
  31.     interface StdControl as SubControl;
  32.     interface PowerManagement;
  33.     interface StdControl as CC1000StdControl;
  34.     interface CC1000Control;
  35.     interface Random;
  36.     interface ADCControl;
  37.     interface ADC as RSSIADC;
  38.     interface SpiByteFifo;
  39.     interface StdControl as TimerControl;
  40.     interface Timer as WakeupTimer;
  41.     interface Timer as SquelchTimer;
  42.     interface Timer as TDMATimer;
  43.     interface Leds;
  44.   }
  45. }
  46. implementation {
  47. #include "DrandMSG.h"
  48. #include "zmacConst.h"
  49. #ifdef ZMAC_DEBUG
  50. #include "SODebug.h"
  51. #endif
  52.   enum {
  53.     NULL_STATE,
  54.     TX_STATE,
  55.     DISABLED_STATE,
  56.     IDLE_STATE,
  57.     PRETX_STATE,
  58.     SYNC_STATE,
  59.     RX_STATE,
  60.     SENDING_ACK,
  61.     POWER_DOWN_STATE,
  62.     PULSE_CHECK_STATE,
  63.   };
  64.   enum {
  65.     TXSTATE_WAIT,
  66.     TXSTATE_START,
  67.     TXSTATE_PREAMBLE,
  68.     TXSTATE_SYNC,
  69.     TXSTATE_DATA,
  70.     TXSTATE_CRC,
  71.     TXSTATE_FLUSH,
  72.     TXSTATE_WAIT_FOR_ACK,
  73.     TXSTATE_READ_ACK,
  74.     TXSTATE_DONE
  75.   };
  76.   enum {
  77.     SYNC_BYTE = 0x33,
  78.     NSYNC_BYTE = 0xcc,
  79.     SYNC_WORD = 0x33cc,
  80.     NSYNC_WORD = 0xcc33,
  81.     ACK_LENGTH = 16,
  82.     MAX_ACK_WAIT = 18,
  83.     TIME_BETWEEN_CHECKS = 50,
  84.     TIME_AFTER_CHECK = 30,
  85.     CHECK_MA_COUNT = 8888,
  86.     SEND_MA_COUNT = 7200,
  87.     PREAMBLE_LENGTH_TO_BASE = 8,
  88.     RECEIVE_MA_COUNT = 9600
  89.   };
  90.   uint8_t ack_code[5] = {0xab, 0xba, 0x83, 0xaa, 0xaa};
  91.   uint8_t RadioState;
  92.   uint8_t RadioTxState;
  93.   norace uint8_t iRSSIcount;
  94.   uint8_t RSSIInitState;
  95.   uint8_t iSquelchCount;
  96.   uint16_t txlength;
  97.   uint16_t rxlength;
  98.   TOS_MsgPtr txbufptr;  // pointer to transmit buffer
  99.   TOS_MsgPtr rxbufptr;  // pointer to receive buffer
  100.   TOS_Msg retxbuf; //re-transmit buffer in case ECN preempts send 
  101.   TOS_Msg RxBuf; // save received messages
  102.   uint8_t NextTxByte;
  103.   uint8_t lplpower;        //  low power listening mode
  104.   uint8_t lplpowertx;      //  low power listening transmit mode
  105.   uint16_t preamblelen;    //  current length of the preamble
  106.   uint16_t sleeptime;       //  current check interval (sleep time)
  107.  
  108.   uint16_t PreambleCount;   //  found a valid preamble
  109.   uint8_t SOFCount;
  110.   uint16_t search_word;
  111.   //modified by Mahesh
  112.   enum {
  113.     BMAC,
  114.     ZMAC
  115.   };
  116.   enum{
  117.     MAX_VAL = 0xFFFF
  118.   };
  119.   enum{
  120.     POSITIVE = 1,
  121.     NEGATIVE = 2,
  122.     ZERO = 3
  123.   };
  124.   
  125.   nodeInfo *nbrInfo;
  126.   
  127.   uint8_t currentMAC; // default must be BMAC and change to ZMAC after DRAND completes
  128.   uint16_t numSlots; // to be obtained from DRAND
  129.   uint16_t slotSize; 
  130.   uint16_t nextHop;
  131.   uint16_t ownSlot;
  132.   uint16_t slots_since_ecnsend;
  133.   uint16_t slots_since_ecnrecv;
  134.   uint16_t slots_since_ecncheck;
  135.   uint16_t globalFrameSize;
  136.   uint32_t globalSlot;
  137.   uint16_t currentSlot;
  138.   uint16_t packetsSent;
  139.   uint16_t pktsLastSync;
  140.   uint16_t congBackOffs;
  141.   double avgLoss;
  142.   uint32_t curHCLlist;
  143.   bool HCLselect;
  144.   bool ackOrig;
  145.   bool ecnPending;
  146.   bool ecnforward;
  147.   bool enableHCL;
  148.   bool pureHCL;
  149.   TOS_Msg ecnMsgHdr;
  150.   TOS_Msg ecnForwardMsgHdr;
  151.   TOS_Msg syncMsgHdr;
  152.   union {
  153.     uint16_t W;
  154.     struct {
  155.       uint8_t LSB;
  156.       uint8_t MSB;
  157.     };
  158.   } RxShiftBuf;
  159.   uint8_t RxBitOffset; // bit offset for spibus
  160.   uint16_t RxByteCnt; // received byte counter
  161.   uint16_t TxByteCnt;
  162.   uint16_t RSSISampleFreq; // in Bytes rcvd per sample
  163.   norace bool bInvertRxData; // data inverted
  164.   norace bool bTxPending;
  165.   bool bAckEnable;
  166.   bool bCCAEnable;
  167.   bool bTxBusy;
  168.   bool bRSSIValid;
  169.   uint16_t CC1K_PulseLevel;
  170.   uint16_t usRunningCRC; // Running CRC variable
  171.   uint16_t usRSSIVal;
  172.   uint16_t usSquelchVal;
  173.   uint16_t usTempSquelch;
  174.   uint8_t usSquelchIndex;
  175.   norace uint8_t pulse_check_count;
  176.   norace uint16_t pulse_check_sum;
  177.   norace uint16_t send_sum;
  178.   norace uint16_t receive_sum;
  179.   norace uint16_t power_sum;
  180.   uint16_t usSquelchTable[CC1K_SquelchTableSize];
  181.   int16_t sMacDelay;    // MAC delay for the next transmission
  182.   // XXX-PB:
  183.   // Here's the deal, the mica (RFM) radio stacks used TOS_LOCAL_ADDRESS
  184.   // to determine if an L2 ack was reqd.  This stack doesn't do L2 acks
  185.   // and, thus doesn't need it.  HOWEVER, some set-mote-id versions
  186.   // break if this symbol is missing from the binary.
  187.   // Thus, I put this LocalAddr here and set it to TOS_LOCAL_ADDRESS
  188.   // to keep things happy for now.
  189.   volatile uint16_t LocalAddr;
  190.   ///**********************************************************
  191.   //* local function definitions
  192.   //**********************************************************/
  193.   /*
  194.     int sortByShort(const void *x, const void *y) {
  195.     uint16_t* x1 = (uint16_t*)x;
  196.     uint16_t* y1 = (uint16_t*)y;
  197.     if (x1[0] > y1[0]) return -1;
  198.     if (x1[0] == y1[0]) return 0;
  199.     if (x1[0] < y1[0]) return 1;
  200.     return 0; // shouldn't reach here becasue it covers all the cases
  201.     }
  202.   */
  203.   void DivTime2(GTime* B, GTime* A){
  204.     if (A->mticks % 2 == 1){
  205.       B->mticks = (A->mticks >> 1);
  206.       B->sticks = (A->sticks >> 1)  + ((MAX_VAL) >>1);
  207.     }
  208.     else{
  209.       B->mticks = (A->mticks >>1);
  210.       B->sticks = (A->sticks >>1);
  211.     }
  212.   }
  213.   void AddTime(GTime* C, GTime* A, GTime* B){
  214.     if ((MAX_VAL - B->sticks) < A->sticks){
  215.       C->sticks = A->sticks - (MAX_VAL - B->sticks);
  216.       C->mticks = A->mticks + B->mticks + 1;
  217.     }
  218.     else{
  219.       C->sticks = A->sticks + B->sticks;
  220.       C->mticks = A->mticks + B->mticks;
  221.     }
  222.   }
  223.   void SubTime(GTime* C, GTime* A, GTime* B){
  224.     if (B->sticks > A->sticks){
  225.       C->sticks = MAX_VAL - (B->sticks - A->sticks);
  226.       C->mticks = A->mticks - (B->mticks + 1);
  227.     }
  228.     else {
  229.       C->sticks = A->sticks -  B->sticks;
  230.       C->mticks = A->mticks -  B->mticks;
  231.     }
  232.   }
  233.   uint8_t ModSubTime(GTime* C, GTime* A, GTime* B){
  234.     uint8_t retval;
  235.     if (A->mticks > B->mticks) 
  236.       retval = POSITIVE;
  237.     else if (A->mticks < B->mticks) 
  238.       retval = NEGATIVE;
  239.     else{
  240.       if (A->sticks > B->sticks)
  241.         retval = POSITIVE;
  242.       else if (A->sticks < B->sticks)
  243.         retval = NEGATIVE;
  244.       else
  245.         retval = ZERO;
  246.     }
  247.     if (retval == POSITIVE) SubTime(C,A,B);
  248.     else if (retval == NEGATIVE) SubTime(C,B,A);
  249.     else {
  250.       C->sticks = 0;
  251.       C->mticks = 0;
  252.     }
  253.     return retval;
  254.   }
  255.   bool IsHCL(uint32_t gSlot){
  256.     bool hclFlag;
  257.     atomic{
  258.       if((0x1 << gSlot) & curHCLlist)
  259.         hclFlag = TRUE;
  260.       else
  261.         hclFlag = FALSE;
  262.     }
  263.     return hclFlag;
  264.   }
  265.   task void adjustSquelch() {
  266.     uint16_t tempArray[CC1K_SquelchTableSize];
  267.     char i,j,min; 
  268.     uint16_t min_value;
  269.     uint32_t tempsquelch;
  270.     atomic {
  271.       usSquelchTable[usSquelchIndex] = usTempSquelch;
  272.       usSquelchIndex++;
  273.       if (usSquelchIndex >= CC1K_SquelchTableSize)
  274.         usSquelchIndex = 0;
  275.       if (iSquelchCount <= CC1K_SquelchCount)
  276.         iSquelchCount++;  
  277.     }
  278.     for (i=0; i<CC1K_SquelchTableSize; i++) {
  279.       tempArray[(int)i] = usSquelchTable[(int)i];
  280.     }
  281.     min = 0;
  282.     //    for (j = 0; j < ((CC1K_SquelchTableSize) >> 1); j++) {
  283.     for (j = 0; j < 3; j++) {
  284.       for (i = 1; i < CC1K_SquelchTableSize; i++) {
  285.         if ((tempArray[(int)i] != 0xFFFF) && 
  286.             ((tempArray[(int)i] > tempArray[(int)min]) ||
  287.              (tempArray[(int)min] == 0xFFFF))) {
  288.           min = i;
  289.         }
  290.       }
  291.       min_value = tempArray[(int)min];
  292.       tempArray[(int)min] = 0xFFFF;
  293.     }
  294.     tempsquelch = ((uint32_t)(usSquelchVal << 5) + (uint32_t)(min_value << 1));
  295.     atomic usSquelchVal = (uint16_t)((tempsquelch / 34) & 0x0FFFF);
  296.     /*
  297.     // XXX: qsort actually causes ~600bits/sec lower bandwidth... why???
  298.     //
  299.     qsort (tempArray,CC1K_SquelchTableSize, sizeof(uint16_t),sortByShort);
  300.     min_value = tempArray[CC1K_SquelchTableSize >> 1];
  301.     atomic usSquelchVal = ((usSquelchVal << 5) + (min_value << 1)) / 34;
  302.     */
  303.   }
  304.   void Blacklist(uint8_t ECN_slot,uint8_t ECN_fsize){
  305.     uint8_t black_slot;
  306.     //  SODbg(DBG_USR2,"%i  %i  %i",ECN_fsize,ECN_slot,numSlots);
  307.     // SODbg(DBG_USR2,"Curr list is %i",curHCLlist);
  308.     atomic {
  309.       if(ECN_fsize <= globalFrameSize) {
  310.         black_slot = ECN_slot;
  311.         while(black_slot < globalFrameSize) {
  312.           curHCLlist = curHCLlist | (1<<black_slot);
  313.           black_slot = black_slot + ECN_fsize;
  314.           // SODbg(DBG_USR2,"Vector: %i",curHCLlist);
  315.         }
  316.         // SODbg(DBG_USR2,"list:%i",curHCLlist);
  317.       }
  318.     }
  319.   }
  320.   void adjustTime(){
  321.     uint16_t sign, i, trust;
  322.     GTime loctime, timeStamp, diff;
  323.     syncMsgType* syncMsgPtr;
  324.     syncMsgPtr = (syncMsgType *) rxbufptr->data;
  325.     timeStamp.mticks = syncMsgPtr->mticks;
  326.     timeStamp.sticks = syncMsgPtr->sticks;
  327.     trust = syncMsgPtr->trust;
  328.     call SClock.getTime(&loctime);
  329. #ifdef ZMAC_TIME_SYNC
  330.     SODbg(DBG_USR2, "*********************************************n");
  331.     SODbg(DBG_USR2, "From: %i R_STICKS = %u, R_MTICKS = %u, MY_STICKS = %u, MY_MTICKS = %un",
  332.           syncMsgPtr->sender, timeStamp.sticks, timeStamp.mticks, loctime.sticks, loctime.mticks);
  333. #endif
  334.     sign = ModSubTime(&diff, &timeStamp, &loctime);
  335. #ifdef ZMAC_TIME_SYNC
  336.     //if(diff.mticks == 0 && TOS_LOCAL_ADDRESS == SINK)
  337.     //  SODbg(DBG_USR2, "Converged !!!");
  338. #endif
  339.     if(trust < MIN_TRUST)
  340.       trust = MIN_TRUST;
  341.     if(trust < MAX_TRUST){
  342.       for(i = 0; i < trust; i++){
  343.         DivTime2(&diff, &diff);
  344. #ifdef ZMAC_TIME_SYNC
  345.         SODbg(DBG_USR2, "diff = %u, %u, %u n", diff.mticks, diff.sticks, trust);
  346. #endif
  347.       }
  348.       call SClock.setTime(sign, &diff);
  349.       call SClock.getTime(&loctime);
  350. #ifdef ZMAC_TIME_SYNC
  351.       SODbg(DBG_USR2, "sign = %u, Adjusted Time MY_STICKS = %u, MY_MTICKS = %un",
  352.             sign, loctime.sticks, loctime.mticks);
  353. #endif
  354.     }
  355.   }
  356.    
  357.   task void PacketRcvd(){
  358.     TOS_MsgPtr pBuf;
  359.     ecnForwardMsgType *recvEcnMsgPtr;
  360.     ecnForwardMsgType *ecnForwardMsgPtr;
  361.     atomic {
  362.       if(pktsLastSync > SYNC_PERIOD){
  363.         atomic{ 
  364.           ackOrig = bAckEnable;
  365.           bAckEnable = FALSE;
  366.         }
  367.         call Send.send(&syncMsgHdr);
  368.         pktsLastSync = 0;
  369.       }
  370.       pktsLastSync++;
  371.       rxbufptr->time = 0;
  372.       pBuf = rxbufptr;
  373.       recvEcnMsgPtr = (ecnForwardMsgType *) rxbufptr->data;
  374.       ecnForwardMsgPtr = (ecnForwardMsgType *) ecnForwardMsgHdr.data;
  375. #ifdef ZMAC_ECN
  376.       if((currentMAC == ZMAC) && (pBuf->type == ECNTYPE)){
  377.         SODbg(DBG_USR2,"Received %u hop ECN from %u, deciding whether significant..n",
  378.               recvEcnMsgPtr->hopCount, recvEcnMsgPtr->senderAddress);
  379.       }
  380. #endif
  381.       if((currentMAC == ZMAC) && (HCLselect) && (pBuf->type == ECNTYPE) && (pBuf->crc != 0) &&
  382.          (recvEcnMsgPtr->senderAddress != TOS_LOCAL_ADDRESS)){ //Message is an ECN
  383.         if((recvEcnMsgPtr->hopCount == 0) && (recvEcnMsgPtr->nextHop == TOS_LOCAL_ADDRESS)){
  384. #ifdef ZMAC_ECN
  385.           SODbg(DBG_USR2,"Received one-hop ECN from %un", recvEcnMsgPtr->senderAddress);
  386. #endif
  387.           ecnForwardMsgPtr->hopCount = 1;
  388.           ecnForwardMsgPtr->nextHop = nextHop;
  389.           ecnForwardMsgPtr->senderAddress = TOS_LOCAL_ADDRESS;
  390.           if(!bTxBusy){
  391.             ackOrig = bAckEnable;
  392.             bAckEnable = FALSE;
  393.             call Send.send(&ecnForwardMsgHdr);  //take care of case where we are not currently sending
  394. #ifdef ZMAC_ECN
  395.             SODbg(DBG_USR2,"Forwarded ECNn");
  396. #endif
  397.           } else
  398.             ecnforward = TRUE;
  399.         } else if(recvEcnMsgPtr->hopCount == 1){ //check if two-hop ECN
  400. #ifdef ZMAC_ECN
  401.           SODbg(DBG_USR2,"Received two hop ECN from %un", recvEcnMsgPtr->senderAddress);
  402. #endif
  403.           atomic enableHCL = TRUE;
  404.           if(recvEcnMsgPtr->senderAddress == nextHop){  //check forwarding node's address
  405.             //suppress ECN
  406. #ifdef ZMAC_ECN
  407.             SODbg(DBG_USR2,"Suppressed own ECNn");
  408. #endif
  409.             atomic ecnPending = FALSE;
  410.             slots_since_ecnsend = 0;
  411.             slots_since_ecnrecv = 0;
  412.           }
  413.         }
  414.       } else if((pBuf->type != SYNCTYPE) && (pBuf->type != ECNTYPE)){
  415. #ifdef ZMAC_ECN
  416.         SODbg(DBG_USR2,"Received packet of type %u, crc = %un", pBuf->type, pBuf->crc);
  417. #endif
  418.         pBuf = signal Receive.receive((TOS_MsgPtr)pBuf);
  419.       }
  420.       
  421.       if (pBuf)
  422.         rxbufptr = pBuf;
  423.       rxbufptr->length = 0;
  424.     }
  425.     call SpiByteFifo.enableIntr();
  426.   }
  427.   
  428.   task void PacketSent() {
  429.     TOS_MsgPtr pBuf; //store buf on stack 
  430.     atomic {
  431.       txbufptr->time = 0;
  432.       pBuf = txbufptr;
  433.     }
  434.       
  435.     if ((txbufptr->type != ECNTYPE) && (txbufptr->type != SYNCTYPE))
  436.       signal Send.sendDone((TOS_MsgPtr)pBuf, SUCCESS);
  437.     atomic bTxBusy = FALSE;
  438.     if(pktsLastSync > SYNC_PERIOD){
  439.       atomic{
  440.         ackOrig = bAckEnable;
  441.         bAckEnable = FALSE;
  442.       }
  443.       call Send.send(&syncMsgHdr);
  444.       pktsLastSync = 0;
  445.     } else if((currentMAC == ZMAC) && (ecnforward == TRUE)){
  446.       atomic{
  447.         ackOrig = bAckEnable;
  448.         bAckEnable = FALSE;
  449.       }
  450.       call Send.send(&ecnForwardMsgHdr);
  451.       atomic ecnforward = FALSE;
  452. #ifdef ZMAC_ECN
  453.       SODbg(DBG_USR2,"Forwarded ECNn");
  454. #endif
  455.     } else if((currentMAC == ZMAC) && (ecnPending == TRUE)){
  456.       atomic{
  457.         ackOrig = bAckEnable;
  458.         bAckEnable = FALSE;
  459.       }
  460.       call Send.send(&ecnMsgHdr);
  461.       atomic ecnPending = FALSE;
  462.       atomic slots_since_ecnsend = 0;
  463. #ifdef ZMAC_ECN
  464.       SODbg(DBG_USR2,"Sent own ECNn");
  465. #endif
  466.     }
  467.   }
  468.   ///**********************************************************
  469.   //* Exported interface functions
  470.   //**********************************************************/
  471.   command void SetDrand.setParent(uint8_t id){ nextHop = id; }
  472.   command result_t SetDrand.Set(nodeInfo *myInfo, uint8_t nHop, nodeInfo *nInfo, uint16_t sSize){
  473.     uint16_t slotOffset = 0, frameSize = 0, globalTimeStamp = 0;
  474.     GTime loctime;
  475.     uint8_t i = 0;
  476.     numSlots = myInfo->frame;
  477.     slotSize = sSize;
  478.     ownSlot = myInfo->slot;
  479.     nextHop = nHop;
  480.     nbrInfo = nInfo;
  481.     frameSize = numSlots * slotSize;
  482.     //currentMAC = ZMAC;
  483.     call SClock.getTime(&loctime);
  484.     globalTimeStamp = (uint16_t)(loctime.mticks * 568.8 + loctime.sticks * 0.00868) ; //in ms
  485.     currentSlot = (uint16_t)((globalTimeStamp % frameSize)/(slotSize));
  486.     slotOffset = (uint16_t)((globalTimeStamp % frameSize)%(slotSize));
  487.     globalSlot = (uint16_t)((globalTimeStamp % (globalFrameSize * slotSize))/(slotSize));
  488.     
  489.     for(i = 0; (i < MAX_NBR) && (nbrInfo[i].nodeID != 0xFF); i++)
  490.       if(nbrInfo[i].bitMap & TWO_HOP)
  491.         Blacklist(nbrInfo[i].slot, nbrInfo[i].frame);
  492.     call TDMATimer.start(TIMER_ONE_SHOT, slotSize - slotOffset);
  493. #ifdef ZMAC_TIMER
  494.     // SODbg(DBG_USR2,"Started timer slotsize - offset is %in",slotSize - slotOffset);
  495. #endif
  496.     return SUCCESS; 
  497.   }
  498.   command result_t StdControl.init() {
  499.     char i;
  500.     ecnMsgType *ecnMsgPtr = (ecnMsgType *) ecnMsgHdr.data;
  501.     atomic {
  502.       RadioState = DISABLED_STATE;
  503.       RadioTxState = TXSTATE_PREAMBLE;
  504.       rxbufptr = &RxBuf;
  505.       rxbufptr->length = 0;
  506.       rxlength = MSG_DATA_SIZE-2;
  507.       RxBitOffset = 0;
  508.       iSquelchCount = 0;
  509.       
  510.       PreambleCount = 0;
  511.       RSSISampleFreq = 0;
  512.       RxShiftBuf.W = 0;
  513.       iRSSIcount = 0;
  514.       bTxPending = FALSE;
  515.       bTxBusy = FALSE;
  516.       bRSSIValid = FALSE;
  517.       bAckEnable = FALSE; // to test for ECN only
  518.       bCCAEnable = TRUE;
  519.       CC1K_PulseLevel = 300;
  520.       sMacDelay = -1;
  521.       usRSSIVal = -1;
  522.       usSquelchIndex = 0;
  523.       pulse_check_count = 0;
  524.       lplpower =  0;//0x87;
  525.       RSSIInitState = NULL_STATE;
  526.       //      if(TOS_LOCAL_ADDRESS == 0) lplpower = 0;
  527.       //      lplpowertx = 7;
  528.       usSquelchVal = CC1K_SquelchInit;
  529.       currentMAC = BMAC;
  530.       congBackOffs = 0;
  531.       packetsSent = 0;
  532.       pktsLastSync = 0;
  533.       avgLoss = 0.0;
  534.       curHCLlist = 0;
  535.       globalFrameSize = GLOBAL_FRAME_SIZE;
  536.       ackOrig = bAckEnable;
  537.       ecnPending = FALSE;
  538.       ecnforward = FALSE;
  539.       enableHCL = FALSE; // ecn flag, set if currently ecn is going on ...
  540.       pureHCL = FALSE;
  541.       HCLselect = SELECTHCL;
  542.       slots_since_ecnsend = 0;
  543.       slots_since_ecnrecv = 0;
  544.       slots_since_ecncheck = 0;
  545.       ecnMsgHdr.type = ECNTYPE;  //set ecnMsg headers
  546.       ecnMsgHdr.addr = TOS_BCAST_ADDR; //ECN Indicator;
  547.       ecnMsgHdr.length = sizeof(ecnMsgType);
  548.       ecnMsgHdr.group = 125;
  549.       ecnMsgHdr.crc = 0;
  550.       ecnForwardMsgHdr.type = ECNTYPE;
  551.       ecnForwardMsgHdr.addr = TOS_BCAST_ADDR; 
  552.       ecnForwardMsgHdr.length = sizeof(ecnMsgType);
  553.       ecnForwardMsgHdr.group = 125;
  554.       ecnForwardMsgHdr.crc = 0;
  555.       syncMsgHdr.type = SYNCTYPE;  //set syncMsg headers
  556.       syncMsgHdr.addr = TOS_BCAST_ADDR; //SYNC Indicator;
  557.       syncMsgHdr.length = sizeof(syncMsgType);
  558.       syncMsgHdr.group = 125;
  559.       syncMsgHdr.crc = 0;
  560.       
  561.       ecnMsgPtr->hopCount = 0; //hopcount
  562.       ecnMsgPtr->nextHop = nextHop; //parent node
  563.       ecnMsgPtr->senderAddress = TOS_LOCAL_ADDRESS;
  564.     }
  565.     for (i = 0; i < CC1K_SquelchTableSize; i++)
  566.       usSquelchTable[(int)i] = CC1K_SquelchInit;
  567.     call SpiByteFifo.initSlave(); // set spi bus to slave mode
  568.    
  569.     call CC1000StdControl.init();
  570.     call CC1000Control.SelectLock(0x9); // Select MANCHESTER VIOLATION
  571.     bInvertRxData = call CC1000Control.GetLOStatus();
  572.     call ADCControl.bindPort(TOS_ADC_CC_RSSI_PORT,TOSH_ACTUAL_CC_RSSI_PORT);
  573.     call ADCControl.init();
  574.     
  575.     call Random.init();
  576.     call TimerControl.init();
  577. #ifdef ZMAC_DEBUG
  578.     init_debug();
  579. #endif
  580.     LocalAddr = TOS_LOCAL_ADDRESS;
  581.     return SUCCESS;
  582.   }
  583.   
  584.   /**
  585.    * Get the current Low Power Listening transmit mode
  586.    * @return mode number (see SetListeningMode)
  587.    */
  588.   async command uint8_t LowPowerListening.GetTransmitMode() {
  589.     return lplpowertx;
  590.   }
  591.   // legacy support
  592.   async command uint8_t GetTransmitMode() {
  593.     return call LowPowerListening.GetTransmitMode();
  594.   }
  595.   /**
  596.    * Set the transmit mode.  This allows for hybrid schemes where
  597.    * the transmit mode is different than the receive mode.
  598.    * Use SetListeningMode first, then change the mode with SetTransmitMode.
  599.    *
  600.    * @param mode mode number (see SetListeningMode)
  601.    * @return SUCCESS if the mode was successfully changed
  602.    */
  603.   async command result_t LowPowerListening.SetTransmitMode(uint8_t power) {
  604.     if ((power >= CC1K_LPL_STATES) || (power == lplpowertx))
  605.       return FAIL;
  606.     // check if the radio is currently doing something
  607.     if ((!bTxPending) && ((RadioState == POWER_DOWN_STATE) || 
  608.                           (RadioState == IDLE_STATE) ||
  609.                           (RadioState == DISABLED_STATE))) {
  610.       atomic {
  611.         lplpowertx = power;
  612.         preamblelen = ((PRG_RDB(&CC1K_LPL_PreambleLength[lplpowertx*2]) << 8)
  613.                        | PRG_RDB(&CC1K_LPL_PreambleLength[(lplpowertx*2)+1]));
  614.       }
  615.       return SUCCESS;
  616.     }
  617.     return FAIL;
  618.   }
  619.   // legacy support
  620.   async command result_t SetTransmitMode(uint8_t power) {
  621.     return call LowPowerListening.SetTransmitMode(power);
  622.   }
  623.   /**
  624.    * Set the current Low Power Listening mode.
  625.    * Setting the LPL mode sets both the check interval and preamble length.
  626.    *
  627.    * Modes include:
  628.    *  0 = Radio full on
  629.    *  1 = 10ms check interval
  630.    *  2 = 25ms check interval
  631.    *  3 = 50ms check interval
  632.    *  4 = 100ms check interval (recommended)
  633.    *  5 = 200ms check interval
  634.    *  6 = 400ms check interval
  635.    *  7 = 800ms check interval
  636.    *  8 = 1600ms check interval
  637.    *
  638.    * @param mode the mode number
  639.    * @return SUCCESS if the mode was successfully changed
  640.    */
  641.   async command result_t LowPowerListening.SetListeningMode(uint8_t power) {
  642.     // valid low power listening values are 0 to 8
  643.     // 0 is "always on" and 8 is lowest duty cycle
  644.     if ((power >= CC1K_LPL_STATES) || (power == lplpower))
  645.       return FAIL;
  646.     // check if the radio is currently doing something
  647.     if ((!bTxPending) && ((RadioState == POWER_DOWN_STATE) || 
  648.                           (RadioState == IDLE_STATE) ||
  649.                           (RadioState == DISABLED_STATE))) {
  650.       // change receiving function in CC1000Radio
  651.       call WakeupTimer.stop();
  652.       atomic {
  653.         if (lplpower == lplpowertx) {
  654.           lplpowertx = power;
  655.         }
  656.         lplpower = power;
  657.       }
  658.       // if successful, change power here
  659.       if (RadioState == IDLE_STATE) {
  660.         RadioState = DISABLED_STATE;
  661.         call StdControl.stop();
  662.         call StdControl.start();
  663.       }
  664.       if (RadioState == POWER_DOWN_STATE) {
  665.         RadioState = DISABLED_STATE;
  666.         call StdControl.start();
  667.         call PowerManagement.adjustPower();
  668.       }
  669.     }
  670.     else {
  671.       return FAIL;
  672.     }
  673.     return SUCCESS;
  674.   }
  675.   // legacy support
  676.   async command result_t SetListeningMode(uint8_t power) {
  677.     return call SetListeningMode(power);
  678.   }
  679.   /**
  680.    * Gets the state of low power listening on the chipcon radio.
  681.    * @return Current low power listening state value
  682.    */
  683.   async command uint8_t LowPowerListening.GetListeningMode() {
  684.     return lplpower;
  685.   }
  686.   // legacy support
  687.   async command uint8_t GetListeningMode() {
  688.     return call LowPowerListening.GetListeningMode();
  689.   } 
  690.   /**
  691.    * Set the preamble length of outgoing packets
  692.    *
  693.    * @param bytes length of the preamble in bytes
  694.    * @return SUCCESS if the preamble length was successfully changed
  695.    */
  696.   async command result_t LowPowerListening.SetPreambleLength(uint16_t bytes) {
  697.     result_t result = FAIL;
  698.     atomic {
  699.       if (RadioState != TX_STATE) {
  700.         preamblelen = bytes;
  701.         result = SUCCESS;
  702.       }
  703.     }
  704.     return result;
  705.   }
  706.   /**
  707.    * Get the preamble length of outgoing packets
  708.    *
  709.    * @return length of the preamble in bytes
  710.    */
  711.   async command uint16_t LowPowerListening.GetPreambleLength() {
  712.     return preamblelen;
  713.   }
  714.   /**
  715.    * Set the check interval (time between waking up and sampling
  716.    * the radio for activity in low power listening)
  717.    *
  718.    * @param ms check interval in milliseconds
  719.    * @return SUCCESS if the check interval was successfully changed
  720.    */
  721.   async command result_t LowPowerListening.SetCheckInterval(uint16_t ms) {
  722.     // sleep time will go into effect after the next wakeup time
  723.     atomic sleeptime = ms;
  724.     return SUCCESS;
  725.   }
  726.   /**
  727.    * Get the check interval currently used by low power listening
  728.    *
  729.    * @return length of the check interval in milliseconds
  730.    */
  731.   async command uint16_t LowPowerListening.GetCheckInterval() {
  732.     return sleeptime;
  733.   }
  734.   event result_t SquelchTimer.fired() {
  735.     char currentRadioState;
  736.     atomic currentRadioState = RadioState;
  737.     if (currentRadioState == IDLE_STATE) {
  738.       atomic RSSIInitState = currentRadioState;
  739.       call RSSIADC.getData();
  740.     }
  741.     return SUCCESS;
  742.   }
  743.   event result_t WakeupTimer.fired() {
  744.     uint8_t currentRadioState;
  745.     if (lplpower == 0)
  746.       return SUCCESS;
  747.     
  748.     atomic currentRadioState = RadioState;
  749.     switch(currentRadioState) {
  750.     case IDLE_STATE:
  751.       if (!bTxPending) {
  752.         atomic {
  753.           RadioState = POWER_DOWN_STATE;
  754.           call SpiByteFifo.disableIntr();
  755.         }
  756.         call WakeupTimer.start(TIMER_ONE_SHOT, sleeptime);
  757.         call SquelchTimer.stop();
  758.         call CC1000StdControl.stop();
  759.       } else {
  760.         call WakeupTimer.start(TIMER_ONE_SHOT, sleeptime);
  761.       }
  762.       break;
  763.     case POWER_DOWN_STATE:
  764.       atomic RadioState = PULSE_CHECK_STATE;
  765.       pulse_check_count = 0;
  766.       call CC1000StdControl.start();
  767.       call CC1000Control.BIASOn();
  768.       call WakeupTimer.start(TIMER_ONE_SHOT, 1);
  769.       return SUCCESS;
  770.       break;
  771.     case PULSE_CHECK_STATE:
  772.       call CC1000Control.RxMode();
  773.       if(!(call RSSIADC.getData())){
  774.         call WakeupTimer.start(TIMER_ONE_SHOT, TIME_BETWEEN_CHECKS);
  775.         atomic RadioState = POWER_DOWN_STATE;
  776.       }
  777.       else {
  778.         TOSH_uwait(80);
  779.       }
  780.       call CC1000StdControl.stop();
  781.       pulse_check_sum ++;
  782.       break;
  783.     default:
  784.       call WakeupTimer.start(TIMER_ONE_SHOT, 5);
  785.     }
  786.     return SUCCESS;
  787.   }
  788.   //added by Mahesh
  789.   event result_t TDMATimer.fired(){
  790.     if(currentMAC == BMAC)
  791.       atomic currentMAC = ZMAC;
  792.     call TDMATimer.start(TIMER_ONE_SHOT,slotSize);
  793.     atomic{
  794.       currentSlot = (currentSlot + 1)%(numSlots);
  795.       globalSlot = (globalSlot + 1)%(globalFrameSize);
  796. #ifdef ZMAC_TIMER
  797.       SODbg(DBG_USR2,"Timer fired with current slot = %u, own slot = %un", currentSlot, ownSlot);
  798. #endif 
  799.       if(HCLselect){
  800.         slots_since_ecnsend ++;
  801.         slots_since_ecnrecv ++;
  802.         slots_since_ecncheck++;
  803.         if((packetsSent > ECNMINPACKETS) && (slots_since_ecncheck >= ECNCHECKPERIOD)){
  804.           double currentLoss = (double)congBackOffs/packetsSent;
  805.           avgLoss = ALPHA * (currentLoss) + (1 - ALPHA) * avgLoss;
  806. #ifdef ZMAC_ECN
  807.           SODbg(DBG_USR2,"Congestion Statistics: %i / %in", congBackOffs, packetsSent);
  808. #endif
  809.           slots_since_ecncheck = 0;
  810.           congBackOffs = 0;
  811.           packetsSent = 0;
  812.           if((avgLoss > ECNTHRESHOLD) && (slots_since_ecnsend >= ECNSENDPERIOD)){
  813.             ecnMsgType *ecnMsgPtr = (ecnMsgType *) ecnMsgHdr.data;
  814. #ifdef ZMAC_ECN
  815.             SODbg(DBG_USR2,"Setting ECN flagn");
  816. #endif
  817.             ecnMsgPtr->nextHop = nextHop;
  818.             if(!pureHCL)
  819.               ecnPending = TRUE;
  820.           }
  821.         }
  822.         if((enableHCL) && (slots_since_ecnrecv >= ECNEXPIREPERIOD)){
  823.           if(!pureHCL)
  824.             enableHCL = FALSE;
  825. #ifdef ZMAC_ECN
  826.           SODbg(DBG_USR2,"ECN expired, into LCL againn");
  827. #endif
  828.         }
  829.         
  830. #ifdef ZMAC_ECN
  831.         //            if(enableHCL)
  832.         // SODbg(DBG_USR2,"Current slot %i **********************n",currentSlot);
  833. #endif
  834. #ifdef ZMAC_TIMER
  835.         if(enableHCL && IsHCL(globalSlot) && ownSlot != currentSlot)
  836.           SODbg(DBG_USR2,"Current slot %i HCLn",currentSlot);
  837. #endif
  838.       }
  839.       if((bTxPending) && (currentSlot == ownSlot)){
  840. #ifdef ZMAC_TIMER
  841.         //                SODbg(DBG_USR2,"**********Owner Slot************* btxpending %i sMacDelay %in",bTxPending,sMacDelay);
  842. #endif
  843.         sMacDelay = signal MacBackoff.congestionBackoff(txbufptr);
  844.       } else{
  845.         if(sMacDelay < 0) // I am non-owner, ready for sending
  846.           sMacDelay = signal MacBackoff.congestionBackoff(txbufptr);
  847.         else{
  848.           if(sMacDelay + T_O < (T_O + T_NO - 1))
  849.             sMacDelay = sMacDelay + T_O;
  850.           else
  851.             sMacDelay = T_O + T_NO - 1;
  852.         }
  853.       }
  854.     }
  855.     return SUCCESS;
  856.   }
  857.  
  858.   command result_t StdControl.stop() {
  859.     atomic RadioState = DISABLED_STATE;
  860.     call SquelchTimer.stop();
  861.     call WakeupTimer.stop();
  862.     call CC1000StdControl.stop();
  863.     call SpiByteFifo.disableIntr(); // disable spi interrupt
  864.     return SUCCESS;
  865.   }
  866.   command result_t StdControl.start() {
  867.     uint8_t currentRadioState;
  868.     atomic currentRadioState = RadioState;
  869.     call SClock.SetRate(MAX_VAL,CLK_DIV_64);
  870.     if (currentRadioState == DISABLED_STATE) {
  871.       atomic {
  872.         rxbufptr->length = 0;
  873.         RadioState  = IDLE_STATE;
  874.         bTxPending = bTxBusy = FALSE;
  875.         sMacDelay = -1;
  876.         sleeptime = ((PRG_RDB(&CC1K_LPL_SleepTime[lplpower*2]) << 8) |
  877.                      PRG_RDB(&CC1K_LPL_SleepTime[(lplpower*2)+1]));
  878.         preamblelen = ((PRG_RDB(&CC1K_LPL_PreambleLength[lplpowertx*2]) << 8) |
  879.                        PRG_RDB(&CC1K_LPL_PreambleLength[(lplpowertx*2)+1]));
  880.       }
  881.       // all power on, captain!
  882.       rxbufptr->length = 0;
  883.       atomic RadioState = IDLE_STATE;
  884.       call CC1000StdControl.start();
  885.       call CC1000Control.BIASOn();
  886.       call SpiByteFifo.rxMode(); // SPI to miso
  887.       call CC1000Control.RxMode();
  888.       if (iSquelchCount > CC1K_SquelchCount)
  889.         call SquelchTimer.start(TIMER_REPEAT, CC1K_SquelchIntervalSlow);
  890.       else
  891.         call SquelchTimer.start(TIMER_REPEAT, CC1K_SquelchIntervalFast);
  892.       call SpiByteFifo.enableIntr(); // enable spi interrupt
  893.       if (lplpower > 0) {
  894.         // set a time to start sleeping after measuring the noise floor
  895.         call WakeupTimer.start(TIMER_ONE_SHOT, CC1K_SquelchIntervalSlow);
  896.       }
  897.     }
  898.     return SUCCESS;
  899.   }
  900.   command result_t Send.send(TOS_MsgPtr pMsg) {
  901.     result_t Result = SUCCESS;
  902.     uint8_t currentRadioState = 0;
  903.    
  904.     atomic {
  905.       if (bTxBusy) {
  906.         Result = FAIL;
  907.       }
  908.       else {
  909.         bTxBusy = TRUE;
  910.         txbufptr = pMsg;
  911.         txlength = pMsg->length + (MSG_DATA_SIZE - DATA_LENGTH - 2); 
  912.         if(bCCAEnable) // initially back off [1,32] bytes (approx 2/3 packet)
  913.           sMacDelay = signal MacBackoff.initialBackoff(pMsg);
  914.         else
  915.           sMacDelay = 0;
  916.         bTxPending = TRUE;
  917.       }
  918.       currentRadioState = RadioState;
  919.     }
  920.     if (Result) {
  921.       if (currentRadioState == POWER_DOWN_STATE) {       // if we're off, start the radio
  922.         atomic RadioState = IDLE_STATE;         // disable wakeup timer
  923.         call WakeupTimer.stop();
  924.         call CC1000StdControl.start();
  925.         call CC1000Control.BIASOn();
  926.         call CC1000Control.RxMode();
  927.         call SpiByteFifo.rxMode(); // SPI to miso
  928.         call SpiByteFifo.enableIntr(); // enable spi interrupt
  929.         if (iSquelchCount > CC1K_SquelchCount)
  930.           call SquelchTimer.start(TIMER_REPEAT, CC1K_SquelchIntervalSlow);
  931.         else
  932.           call SquelchTimer.start(TIMER_REPEAT, CC1K_SquelchIntervalFast);
  933.         call WakeupTimer.start(TIMER_ONE_SHOT, CC1K_LPL_PACKET_TIME*2);
  934.       }
  935.     }
  936.     return Result;
  937.   }
  938.   
  939.   /**********************************************************
  940.    * make a spibus interrupt handler
  941.    * needs to handle interrupts for transmit delay
  942.    * and then go into byte transmit mode with
  943.    *   timer1 baudrate delay as interrupt handler
  944.    * else SODbg(DBG_USR2,"Sending Packet ..");
  945.    * needs to handle interrupts for byte read and detect preamble
  946.    *  then handle reading a packet
  947.    * PB - We can use this interrupt handler as a transmit scheduler
  948.    * because the CC1000 continuously clocks in data, regarless
  949.    * of whether it's good or not.  Thus, this routine will be called
  950.    * on every 8 ticks of DCLK. 
  951.    **********************************************************/
  952.   async event result_t SpiByteFifo.dataReady(uint8_t data_in) {
  953.     GTime loctime;
  954.     signal RadioSendCoordinator.blockTimer();
  955.     signal RadioReceiveCoordinator.blockTimer();
  956.      
  957.     if (bInvertRxData)
  958.       data_in = ~data_in;
  959. #ifdef ENABLE_UART_DEBUG
  960.     UARTPutChar(RadioState);
  961. #endif
  962.     switch (RadioState) {
  963.     case TX_STATE:
  964.       {
  965.         call SpiByteFifo.writeByte(NextTxByte);
  966.         TxByteCnt++;
  967.         switch (RadioTxState) {
  968.           
  969.         case TXSTATE_PREAMBLE:
  970.           send_sum ++;
  971.           if (!(TxByteCnt < preamblelen)||
  972.               (txbufptr->strength == 0xffff && TxByteCnt >= PREAMBLE_LENGTH_TO_BASE)) {
  973.             NextTxByte = SYNC_BYTE;
  974.             RadioTxState = TXSTATE_SYNC;
  975. #ifdef ZMAC_ECN
  976.             SODbg(DBG_USR2,"Sent packet in slot %in",currentSlot);
  977.             SODbg(DBG_USR2, "ishcl = %un", IsHCL(currentSlot));
  978. #endif
  979.           }
  980.           break;
  981.         case TXSTATE_SYNC:
  982.           send_sum ++;
  983.           NextTxByte = NSYNC_BYTE;
  984.           RadioTxState = TXSTATE_DATA;
  985.           TxByteCnt = -1;
  986.           if(txbufptr->type == SYNCTYPE){ // allow sync messages
  987.             syncMsgType *syncMsgPtr = (syncMsgType *) txbufptr->data;
  988.             call SClock.getTime(&loctime);
  989.             syncMsgPtr->mticks = loctime.mticks;
  990.             syncMsgPtr->sticks = loctime.sticks;
  991.             syncMsgPtr->trust = TRUST_FACTOR;
  992.             syncMsgPtr->sender = TOS_LOCAL_ADDRESS;
  993.           }
  994.           // for Time Sync services
  995.           signal RadioSendCoordinator.startSymbol(8, 0, txbufptr);
  996.           break;
  997.         case TXSTATE_DATA:
  998.           send_sum ++;
  999.           if ((uint8_t)(TxByteCnt) < txlength){
  1000.             NextTxByte = ((uint8_t *)txbufptr)[(TxByteCnt)];
  1001.             usRunningCRC = crcByte(usRunningCRC,NextTxByte);
  1002.             signal RadioSendCoordinator.byte(txbufptr, (uint8_t)TxByteCnt); // Time Sync
  1003.           }
  1004.           else {
  1005.             NextTxByte = (uint8_t)(usRunningCRC);
  1006.             RadioTxState = TXSTATE_CRC;
  1007.           }
  1008.           break;
  1009.         case TXSTATE_CRC:
  1010.           send_sum ++;
  1011.           NextTxByte = (uint8_t)(usRunningCRC>>8);
  1012.           RadioTxState = TXSTATE_FLUSH;
  1013.           TxByteCnt = 0;
  1014.           break;
  1015.         case TXSTATE_FLUSH:
  1016.           send_sum ++;
  1017.           if (TxByteCnt > 3) {
  1018.             TxByteCnt = 0;
  1019. #ifdef ZMAC_DEBUG
  1020.             // SODbg(DBG_USR2,"Came heren");
  1021. #endif
  1022.             if (bAckEnable)
  1023.               RadioTxState = TXSTATE_WAIT_FOR_ACK;         
  1024.             else {
  1025. #ifdef ZMAC_DEBUG
  1026.               // SODbg(DBG_USR2,"came inside: current MAC: %i ackenabled :%i,ecnPending: %i ecnforward %i ecnSENT %in",currentMAC,bAckEnable,ecnPending,ecnforward,sentECN);
  1027. #endif
  1028.               packetsSent ++;
  1029.               call SpiByteFifo.rxMode();
  1030.               call CC1000Control.RxMode();
  1031.               RadioTxState = TXSTATE_DONE;
  1032.             }
  1033.           }
  1034.           break;
  1035.         case TXSTATE_WAIT_FOR_ACK:
  1036.           if(TxByteCnt == 1){
  1037.             send_sum ++;
  1038.             call SpiByteFifo.rxMode();
  1039.             call CC1000Control.RxMode();
  1040.             break;
  1041.           }
  1042.           receive_sum ++;
  1043.           if (TxByteCnt > 3) {
  1044.             RadioTxState = TXSTATE_READ_ACK;
  1045.             TxByteCnt = 0;
  1046.             search_word = 0;
  1047.           }
  1048.           break;
  1049.         case TXSTATE_READ_ACK:
  1050.           {
  1051.             uint8_t i;
  1052.             receive_sum ++;
  1053.             for(i = 0; i < 8; i ++){
  1054.               search_word <<= 1;
  1055.               if(data_in & 0x80) search_word |=  0x1;
  1056.               data_in <<= 1;
  1057.               if (search_word == 0xba83){
  1058.                 txbufptr->ack = 1;
  1059.                 RadioTxState = TXSTATE_DONE;
  1060. #ifdef ZMAC_DEBUG
  1061.                 SODbg(DBG_USR2,"received ackn");
  1062. #endif
  1063.                 return SUCCESS;
  1064.               }
  1065.             }
  1066.           }
  1067.           if(TxByteCnt >= MAX_ACK_WAIT){   
  1068.             txbufptr->ack = 0;  
  1069. #ifdef ZMAC_DEBUG
  1070.             //       SODbg(DBG_USR2,"did not receive ack %i %i %in",lostacks,packetsSent,avgLoss * 100);
  1071. #endif
  1072.             RadioTxState = TXSTATE_DONE;
  1073.           }
  1074.           break;
  1075.         case TXSTATE_DONE:
  1076.         default:
  1077.           bTxPending = FALSE;
  1078.           if((txbufptr->type == ECNTYPE) || (txbufptr->type == SYNCTYPE)){
  1079. #ifdef ZMAC_ECN
  1080.             ecnForwardMsgPtr = (ecnForwardMsgType *) txbufptr->data;
  1081.             if(txbufptr->type == ECNTYPE && ecnForwardMsgPtr->hopCount == 1)
  1082.               SODbg(DBG_USR2,"Successfully forwarded ECNn");
  1083. #endif
  1084.             bAckEnable = ackOrig;
  1085.           }
  1086.           if(post PacketSent()) {
  1087.             // If the post operation succeeds, goto Idle
  1088.             // otherwise, we'll try again.
  1089. #ifdef ZMAC_DEBUG
  1090.             //  SODbg(DBG_USR2,"Packet type %in",txbufptr->type);
  1091. #endif
  1092.             RadioState = IDLE_STATE;
  1093.             pktsLastSync++;
  1094.             RSSIInitState = RadioState;
  1095.             call RSSIADC.getData();
  1096.           }
  1097.           break;
  1098.         }
  1099.       }
  1100.       break;
  1101.     case DISABLED_STATE:
  1102.       break;
  1103.     case IDLE_STATE: 
  1104.       {
  1105.         receive_sum ++;
  1106.         if (((data_in == (0xaa)) || (data_in == (0x55)))) {
  1107.           PreambleCount++;
  1108.           if (PreambleCount > CC1K_ValidPrecursor) {
  1109.             PreambleCount = SOFCount = 0;
  1110.             RxBitOffset = RxByteCnt = 0;
  1111.             usRunningCRC = 0;
  1112.             rxlength = MSG_DATA_SIZE-2;
  1113.             RadioState = SYNC_STATE;
  1114.           }
  1115.         } else {
  1116.           if ((currentMAC == BMAC) || (enableHCL == FALSE) || (!IsHCL(currentSlot))) {
  1117.             if((bTxPending) && (--sMacDelay <= 0)){
  1118.               RadioState = PRETX_STATE;
  1119.               RSSIInitState = PRETX_STATE;
  1120.               bRSSIValid = FALSE;
  1121.               iRSSIcount = 0;
  1122.               PreambleCount = 0;
  1123.               call RSSIADC.getData();
  1124.             }
  1125.           }
  1126.         }
  1127.       }
  1128.       break;
  1129.     case PRETX_STATE:
  1130.       {
  1131.         receive_sum ++;
  1132.         if (((data_in == (0xaa)) || (data_in == (0x55)))) {
  1133.           // Back to the penalty box.
  1134.           sMacDelay = signal MacBackoff.congestionBackoff(txbufptr);
  1135.           RadioState = IDLE_STATE;
  1136.         }
  1137.       }
  1138.       break;
  1139.     case SYNC_STATE:
  1140.       {
  1141.         // draw in the preamble bytes and look for a sync byte
  1142.         // save the data in a short with last byte received as msbyte
  1143.         //    and current byte received as the lsbyte.
  1144.         // use a bit shift compare to find the byte boundary for the sync byte
  1145.         // retain the shift value and use it to collect all of the packet data
  1146.         // check for data inversion, and restore proper polarity 
  1147.         // XXX-PB: Don't do this.
  1148.         uint8_t i;
  1149.         receive_sum ++;
  1150.         if ((data_in == 0xaa) || (data_in == 0x55)) {
  1151.           // It is actually possible to have the LAST BIT of the incoming
  1152.           // data be part of the Sync Byte.  SO, we need to store that
  1153.           // However, the next byte should definitely not have this pattern.
  1154.           // XXX-PB: Do we need to check for excessive preamble?
  1155.           RxShiftBuf.MSB = data_in;
  1156.         }
  1157.         else {
  1158.           // TODO: Modify to be tolerant of bad bits in the preamble...
  1159.           uint16_t usTmp;
  1160.           switch (SOFCount) {
  1161.           case 0:
  1162.             RxShiftBuf.LSB = data_in;
  1163.             break;
  1164.   
  1165.           case 1:
  1166.           case 2: 
  1167.           case 3: 
  1168.           case 4: 
  1169.           case 5: 
  1170.             // bit shift the data in with previous sample to find sync
  1171.             usTmp = RxShiftBuf.W;
  1172.             RxShiftBuf.W <<= 8;
  1173.             RxShiftBuf.LSB = data_in;
  1174.             for(i=0;i<8;i++) {
  1175.               usTmp <<= 1;
  1176.               if(data_in & 0x80)
  1177.                 usTmp  |=  0x1;
  1178.               data_in <<= 1;
  1179.               // check for sync bytes
  1180.               if (usTmp == SYNC_WORD) {
  1181.                 if (rxbufptr->length !=0) {
  1182.                   call Leds.redToggle();
  1183.                   RadioState = IDLE_STATE;
  1184.                 }
  1185.                 else {
  1186.                   RadioState = RX_STATE;
  1187.                   RSSIInitState = RX_STATE;
  1188.                   call RSSIADC.getData();
  1189.                   RxBitOffset = 7-i;
  1190.                   // For time sync services
  1191.                   signal RadioReceiveCoordinator.startSymbol(8, RxBitOffset, rxbufptr); 
  1192.                 }
  1193.                 break;
  1194.               }
  1195.             }
  1196.             break;
  1197.           default:
  1198.             // We didn't find it after a reasonable number of tries, so....
  1199.             RadioState = IDLE_STATE;  // Ensures we wait till the end of the transmission
  1200.             break;
  1201.           }
  1202.           SOFCount++;
  1203.         }
  1204.       }
  1205.       break;
  1206.       //  collect the data and shift into double buffer
  1207.       //  shift out data by correct offset
  1208.       //  invert the data if necessary
  1209.       //  stop after the correct packet length is read
  1210.       //  return notification to upper levels
  1211.       //  go back to idle state
  1212.     case RX_STATE:
  1213.       {
  1214.         char Byte;
  1215.         receive_sum ++;
  1216.         RxShiftBuf.W <<=8;
  1217.         RxShiftBuf.LSB = data_in;
  1218.         Byte = (RxShiftBuf.W >> RxBitOffset);
  1219.         ((char*)rxbufptr)[(int)RxByteCnt] = Byte;
  1220.         RxByteCnt++;
  1221.         signal RadioReceiveCoordinator.byte(rxbufptr, (uint8_t)RxByteCnt);
  1222.         if (RxByteCnt < rxlength) {
  1223.           usRunningCRC = crcByte(usRunningCRC,Byte);
  1224.           if (RxByteCnt == (offsetof(struct TOS_Msg,length) + 
  1225.                             sizeof(((struct TOS_Msg *)0)->length))) {
  1226.             rxlength = rxbufptr->length;
  1227.             if (rxlength > TOSH_DATA_LENGTH) {
  1228.               // The packet's screwed up, so just dump it
  1229.               rxbufptr->length = 0;
  1230.               RadioState = IDLE_STATE;  // Waits till end of transmission
  1231.               return SUCCESS;
  1232.             }
  1233.             //Add in the header size
  1234.             rxlength += offsetof(struct TOS_Msg,data);
  1235.           }
  1236.         }
  1237.         else if (RxByteCnt == rxlength) {
  1238.           usRunningCRC = crcByte(usRunningCRC,Byte);
  1239.           // Shift index ahead to the crc field.
  1240.           RxByteCnt = offsetof(struct TOS_Msg,crc);
  1241.         }
  1242.         else if (RxByteCnt >= MSG_DATA_SIZE) { 
  1243.           // Packet filtering based on bad CRC's is done at higher layers.
  1244.           // So sayeth the TOS weenies.
  1245.           if (rxbufptr->crc == usRunningCRC) {
  1246.             if(rxbufptr->type == SYNCTYPE)
  1247.               adjustTime();
  1248.             rxbufptr->crc = 1;
  1249.             
  1250.             if(bAckEnable && (rxbufptr->addr == TOS_LOCAL_ADDRESS)){
  1251.               RadioState = SENDING_ACK; 
  1252.               call CC1000Control.TxMode();
  1253.               call SpiByteFifo.txMode();
  1254.               call SpiByteFifo.writeByte(0xaa);
  1255.               RxByteCnt = 0;
  1256.               return SUCCESS; 
  1257.             }
  1258.           } else {
  1259.             rxbufptr->crc = 0;
  1260.           }
  1261.           call SpiByteFifo.disableIntr();
  1262.   
  1263.           RadioState = IDLE_STATE; //DISABLED_STATE;
  1264.           if((currentMAC == ZMAC) && (bTxPending)){ //Ajit - reset timer when time slot boundary
  1265.             if(currentSlot == ownSlot)
  1266.               sMacDelay = signal MacBackoff.congestionBackoff(rxbufptr);
  1267.             else{
  1268.               if(sMacDelay + T_O < (T_O + T_NO - 1))
  1269.                 sMacDelay = sMacDelay + T_O;
  1270.               else
  1271.                 sMacDelay = T_O + T_NO - 1;
  1272.             }
  1273.           }
  1274.           rxbufptr->strength = usRSSIVal;
  1275.           if (!(post PacketRcvd())) {
  1276.             // If there are insufficient resources to process the incoming packet
  1277.             // we drop it
  1278.             rxbufptr->length = 0;
  1279.             RadioState = IDLE_STATE;
  1280.             call SpiByteFifo.enableIntr();
  1281.           }
  1282.           RSSIInitState = RadioState;
  1283.           call RSSIADC.getData();
  1284.         }
  1285.       }
  1286.       break;
  1287.     case SENDING_ACK:
  1288.       {
  1289.         send_sum ++;
  1290.         RxByteCnt++;
  1291.         if (RxByteCnt >= ACK_LENGTH) { 
  1292.           call CC1000Control.RxMode();
  1293.           call SpiByteFifo.rxMode();
  1294.           call SpiByteFifo.disableIntr();
  1295.           RadioState = IDLE_STATE; //DISABLED_STATE;
  1296.           rxbufptr->strength = usRSSIVal;
  1297.           if (!(post PacketRcvd())) {
  1298.             rxbufptr->length = 0;
  1299.             RadioState = IDLE_STATE;
  1300.             call SpiByteFifo.enableIntr();
  1301.           }
  1302.         }else if(RxByteCnt >= ACK_LENGTH - sizeof(ack_code)){
  1303.           call SpiByteFifo.writeByte(ack_code[RxByteCnt + sizeof(ack_code) - ACK_LENGTH]);
  1304.         }
  1305.       }
  1306.       break;
  1307.     default:
  1308.       break;
  1309.     }
  1310.     if(pulse_check_sum > CHECK_MA_COUNT){
  1311.       power_sum ++;
  1312.       pulse_check_sum -= CHECK_MA_COUNT;
  1313.     }
  1314.     if(send_sum > SEND_MA_COUNT){
  1315.       power_sum ++;
  1316.       send_sum -= SEND_MA_COUNT;
  1317.     }
  1318.     if(receive_sum > RECEIVE_MA_COUNT){
  1319.       power_sum ++;
  1320.       receive_sum -= RECEIVE_MA_COUNT;
  1321.     }
  1322.     return SUCCESS;
  1323.   }
  1324.   task void IdleTimerTask(){
  1325.     if (iSquelchCount > CC1K_SquelchCount)
  1326.       call SquelchTimer.start(TIMER_REPEAT, CC1K_SquelchIntervalSlow);
  1327.     else
  1328.       call SquelchTimer.start(TIMER_REPEAT, CC1K_SquelchIntervalFast);
  1329.     call WakeupTimer.start(TIMER_ONE_SHOT, TIME_AFTER_CHECK);
  1330.     /*if(pulse_check_sum > CHECK_MA_COUNT){
  1331.       power_sum ++;
  1332.       pulse_check_sum -= CHECK_MA_COUNT;
  1333.       }
  1334.       if(send_sum > SEND_MA_COUNT){
  1335.       power_sum ++;
  1336.       send_sum -= SEND_MA_COUNT;
  1337.       }
  1338.       if(receive_sum > RECEIVE_MA_COUNT){
  1339.       power_sum ++;
  1340.       receive_sum -= RECEIVE_MA_COUNT;
  1341.       }*/
  1342.   }
  1343.   task void SleepTimerTask(){
  1344.     call WakeupTimer.start(TIMER_ONE_SHOT, sleeptime);
  1345.   }
  1346.   async event result_t RSSIADC.dataReady(uint16_t data) { 
  1347.     atomic{
  1348.       uint8_t currentRadioState;
  1349.       // TOSH_CLR_PW3_PIN();
  1350.       currentRadioState = RadioState;
  1351.       // find the maximum RSSI value over CC1K_MAX_RSSI_SAMPLES
  1352.       switch(currentRadioState) {
  1353.       case IDLE_STATE:
  1354.         if (RSSIInitState == IDLE_STATE) {
  1355.           atomic usTempSquelch = data;
  1356.           post adjustSquelch();
  1357.         }
  1358.         RSSIInitState = NULL_STATE;
  1359.         break;
  1360.           
  1361.       case RX_STATE:
  1362.         if (RSSIInitState == RX_STATE) {
  1363.           atomic usRSSIVal = data;
  1364.         }
  1365.         RSSIInitState = NULL_STATE;
  1366.         break;
  1367.         
  1368.       case PRETX_STATE:
  1369.         iRSSIcount++;
  1370.         
  1371.         // if the channel is clear or CCA is disabled, GO GO GO!
  1372.         if (((data > (usSquelchVal + CC1K_SquelchBuffer)) ||
  1373.              (!bCCAEnable)) && (RSSIInitState == PRETX_STATE)) { 
  1374.           call SpiByteFifo.writeByte(0xaa);
  1375.           call CC1000Control.TxMode();
  1376.           call SpiByteFifo.txMode();
  1377.           
  1378.           usRSSIVal = data;
  1379.           iRSSIcount = CC1K_MaxRSSISamples;
  1380.           bRSSIValid = TRUE;
  1381.           TxByteCnt = 0;
  1382.           usRunningCRC = 0;
  1383.           RadioState = TX_STATE;
  1384.           RadioTxState = TXSTATE_PREAMBLE;
  1385.           NextTxByte = 0xaa;
  1386.           RSSIInitState = NULL_STATE;
  1387.         }
  1388.         else {
  1389.           RSSIInitState = NULL_STATE;
  1390.           if (iRSSIcount == CC1K_MaxRSSISamples) {
  1391.             sMacDelay = signal MacBackoff.congestionBackoff(txbufptr);
  1392.             RadioState = IDLE_STATE;
  1393.           }
  1394.           else {
  1395.             RSSIInitState = currentRadioState;
  1396.             call RSSIADC.getData();
  1397.           }
  1398.         }
  1399.         break;
  1400.         
  1401.       case PULSE_CHECK_STATE:
  1402.         atomic{
  1403.           uint8_t done = 0;
  1404.           uint16_t threshold = call GetSquelch();
  1405.           threshold = threshold - (call GetSquelch() >> 2);
  1406.           if(data > threshold){
  1407.             // adjust the noise floor level
  1408.             atomic usTempSquelch = data;
  1409.             post adjustSquelch();
  1410.             
  1411.           }else if(pulse_check_count > 5){
  1412.             //go to the idle state since no outliers were found
  1413.             call CC1000Control.RxMode();
  1414.             RadioState = IDLE_STATE;
  1415.             call SpiByteFifo.rxMode();     // SPI to miso
  1416.             call SpiByteFifo.enableIntr(); // enable spi interrupt
  1417.             post IdleTimerTask();
  1418.             done = 1;
  1419.             
  1420.           }else {
  1421.             call CC1000Control.RxMode();
  1422.             if(call RSSIADC.getData()){
  1423.               TOSH_uwait(80);
  1424.               pulse_check_count ++;
  1425.               done = 1;
  1426.             }
  1427.             pulse_check_sum ++;
  1428.             call CC1000StdControl.stop();
  1429.           }
  1430.             
  1431.           if (bTxPending) { // bug fixed by Dr. Rhee
  1432.             //go to the idle state since no outliers were found
  1433.             call CC1000Control.RxMode();
  1434.             RadioState = IDLE_STATE;
  1435.             call SpiByteFifo.rxMode();     // SPI to miso
  1436.             call SpiByteFifo.enableIntr(); // enable spi interrupt
  1437.             post IdleTimerTask();
  1438.             done = 1;
  1439.           }
  1440.           if(done == 0){
  1441.             post SleepTimerTask();
  1442.             RadioState = POWER_DOWN_STATE;
  1443.             call SpiByteFifo.disableIntr();
  1444.           }
  1445.         }
  1446.         //go to the power down state
  1447.         break;
  1448.       default:
  1449.       }
  1450.     }
  1451.     return SUCCESS;
  1452.   }
  1453.   // XXX:JP- for testing the mac layer squlech value
  1454.   async command uint16_t GetSquelch() {
  1455.     return usSquelchVal;
  1456.   }
  1457.   // XXX:JP- for testing the mac layer power consumption
  1458.   async command uint16_t GetPower() {
  1459.     return power_sum;
  1460.   }
  1461.   async command result_t ResetPower() {
  1462.     power_sum = 0;
  1463.     pulse_check_sum = 0;
  1464.     send_sum = 0;
  1465.     receive_sum = 0;
  1466.     return SUCCESS;
  1467.   }
  1468.   async command result_t MacControl.enableAck() {
  1469.     atomic bAckEnable = TRUE;
  1470.     return SUCCESS;
  1471.   }
  1472.   async command result_t MacControl.disableAck() {
  1473.     atomic bAckEnable = FALSE;
  1474.     return SUCCESS;
  1475.   }
  1476.   async command result_t MacControl.enableCCA() {
  1477.     atomic bCCAEnable = TRUE;
  1478.     return SUCCESS;
  1479.   }
  1480.   async command result_t MacControl.disableCCA() {
  1481.     atomic bCCAEnable = FALSE; 
  1482.     return SUCCESS;
  1483.   }
  1484.   // ***Not yet implemented
  1485.   async command TOS_MsgPtr MacControl.HaltTx() {
  1486.     return 0;
  1487.   }
  1488.   // Default events for radio send/receive coordinators do nothing.
  1489.   // Be very careful using these, you'll break the stack.
  1490.   default async event void RadioSendCoordinator.startSymbol(uint8_t bitsPerBlock, uint8_t offset,
  1491.                                                             TOS_MsgPtr msgBuff) { }
  1492.   default async event void RadioSendCoordinator.byte(TOS_MsgPtr msg, uint8_t byteCount) { }
  1493.   default async event void RadioSendCoordinator.blockTimer() { }
  1494.   default async event void RadioReceiveCoordinator.startSymbol(uint8_t bitsPerBlock, uint8_t offset,
  1495.                                                                TOS_MsgPtr msgBuff) { }
  1496.   default async event void RadioReceiveCoordinator.byte(TOS_MsgPtr msg, uint8_t byteCount) { }
  1497.   default async event void RadioReceiveCoordinator.blockTimer() { }
  1498.   default async event int16_t MacBackoff.initialBackoff(TOS_MsgPtr m){
  1499.     uint16_t backoff;
  1500.     if(currentMAC == ZMAC){
  1501.       //    SODbg(DBG_USR2,"current slot is %i own slot %i",currentSlot,ownSlot);    
  1502.       if(currentSlot == ownSlot)
  1503.         backoff = (call Random.rand() & (T_O - 1)) + 1;
  1504.       else
  1505.         backoff = (call Random.rand() & (T_NO - 1)) + 1 + T_O;
  1506.       return(backoff);
  1507.     } else                                         //use 0 initial backoff for optimal BMAC performance
  1508.       return (call Random.rand() & 0x1F) + 1;
  1509.   }
  1510.   default async event int16_t MacBackoff.congestionBackoff(TOS_MsgPtr m){
  1511.     uint16_t backoff;
  1512.     if(currentMAC == ZMAC){
  1513.       congBackOffs++;
  1514.       //    SODbg(DBG_USR2,"current slot is %i own slot %i",currentSlot,ownSlot);
  1515.       if(currentSlot == ownSlot)
  1516.         backoff = (call Random.rand() & (T_O - 1)) + 1;
  1517.       else
  1518.         backoff = (call Random.rand() & (T_NO - 1)) + 1 + T_O;
  1519.       return(backoff);
  1520.     } else
  1521.       return (call Random.rand() & 0xF) + 1;
  1522.   }
  1523.   /**************SClock Interface********/
  1524.   async event result_t SClock.syncDone(){ return SUCCESS; }
  1525.   async event result_t SClock.fire(uint16_t mticks){ return SUCCESS; }  
  1526. }