⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 radiocontrolm.nc

📁 tinyos下的smac源码 tinyos下的smac源码 tinyos下的smac源码
💻 NC
字号:
// $Id: RadioControlM.nc,v 1.14 2005/03/26 19:09:37 weiyeisi Exp $/* Copyright (c) 2002 the University of Southern California. * All rights reserved. * * Permission to use, copy, modify, and distribute this software and its * documentation for any purpose, without fee, and without written agreement is * hereby granted, provided that the above copyright notice and the following * two paragraphs appear in all copies of this software. * * IN NO EVENT SHALL THE UNIVERSITY OF SOUTHERN CALIFORNIA BE LIABLE TO ANY * PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE * UNIVERSITY OF SOUTHERN CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * * THE UNIVERSITY OF SOUTHERN CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES, * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS * ON AN "AS IS" BASIS, AND THE UNIVERSITY OF SOUTHERN CALIFORNIA HAS NO * OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR * MODIFICATIONS. * *//* Authors: Wei Ye, Honghui Chen * Date created: 1/21/2003 * * This module implements the radio control functions: *   1) Put radio into different states: *   	a) idle; b) sleep; c) receive; d) transmit *   2) Start symbol detection in idle state *      (Partially based on CC1000RadioM.nc) *   3) Physical carrier sense *  *//** * @author Wei Ye * @author Honghui Chen *///includes uartDebug;module RadioControlM{   provides {      interface StdControl as RadControl;      interface RadioState;      interface CarrierSense;      interface RadioByte;      interface SignalStrength;   }   uses {      interface StdControl as CC1000StdControl;      interface CC1000Control;      interface ADCControl;      interface ADC as RSSIADC;   }}implementation{// carrier sense threshold that determines a busy channel#ifndef RADIO_BUSY_THRESHOLD#define RADIO_BUSY_THRESHOLD 0xb5#endif   enum {      // early warning threshold      EW_THRESHOLD = RADIO_BUSY_THRESHOLD + 0x1b,      NUM_EXT_BYTES = 3   };   char start[2] __attribute((C)) = {0x33, 0xcc};   // radio states. INIT is a temperary state only at start up   enum { INIT, SLEEP, IDLE, SYNC_START, RECEIVE, TRANSMIT };      uint8_t state;        // radio state   uint8_t stateLock;    // lock for state transition   uint16_t carrSenTime; // carrier sense time   uint16_t csVal1;      // first carrier sense sample   uint16_t csValAve;    // average value of carrier sense   uint8_t extFlag;      // carrier sense extension flag   uint8_t nextByte;     // tx buffer   uint8_t txCount;      // for start symbol tx   uint8_t getRSSI;      // flag if set will return RSSI (signal strength)   bool bManchesterBad;   bool bInvertRxData;	// data inverted      enum {      //SYNC_BYTE = 0x33,      //NSYNC_BYTE = 0xcc,      SYNC_WORD = 0x33cc,      NSYNC_WORD = 0xcc33   };   enum {      PREAMBLE_LEN = 18,      VALID_PRECURSOR = 5   };   uint8_t PreambleCount;  //  found a valid preamble   uint8_t SOFCount;   union {      uint16_t W;      struct {         uint8_t LSB;         uint8_t MSB;      };   } RxShiftBuf;   uint8_t RxBitOffset;	// bit offset for spibus   uint16_t LocalAddr;      static inline result_t lockAcquire(uint8_t* lock)   {      result_t tmp;      atomic {         if (*lock == 0) {            *lock = 1;            tmp = SUCCESS;         } else {            tmp = FAIL;         }      }      return tmp;   }      static inline void lockRelease(uint8_t* lock)   {      *lock = 0;   }      // initialize the radio   command result_t RadControl.init()   {      //uartDebug_init();            state = INIT;      LocalAddr = TOS_LOCAL_ADDRESS;      getRSSI = 0; // only get RSSI upon request      call ADCControl.bindPort(TOS_ADC_CC_RSSI_PORT,TOSH_ACTUAL_CC_RSSI_PORT);      call ADCControl.init();      call CC1000StdControl.init();      call CC1000Control.SelectLock(0x9); // Select MANCHESTER VIOLATION      bInvertRxData = call CC1000Control.GetLOStatus(); //if need to invert Rcvd Data      // set SPI clock pin as input -- clock provided by radio      TOSH_MAKE_SPI_SCK_INPUT();            call RadioState.idle();      return SUCCESS;   }         command result_t RadControl.start()   {      call RadioState.idle();      return SUCCESS;   }         command result_t RadControl.stop()   {      outp(0x00, SPCR);  // turn off SPI      call CC1000StdControl.stop();      state = SLEEP;      stateLock = 0; // clear state lock      return SUCCESS;   }         // set radio into idle state. Automatically detect start symbol   command result_t RadioState.idle()   {      if (state == IDLE) return SUCCESS;      if (!lockAcquire(&stateLock)) return FAIL; // in state transition      // clear state variables      PreambleCount = 0;      SOFCount = 0;      RxBitOffset = 0;      RxShiftBuf.W = 0;      carrSenTime = 0;      if (state == SYNC_START) {         state = IDLE;         lockRelease(&stateLock); // release state lock         return SUCCESS;      }      if (state == SLEEP) {  // wake up radio if in sleep state         call CC1000StdControl.start();         call CC1000Control.BIASOn();      } else {         cbi(SPCR, SPIE);	// disable SPI interrupt         cbi(SPCR, SPE);   // disable SPI      }      call CC1000Control.RxMode(); //set radio to Rx mode      // configure SPI for input      TOSH_MAKE_MISO_INPUT();      TOSH_MAKE_MOSI_INPUT();      outp(0xc0, SPCR);  // start SPI and enable SPI interrupt      state = IDLE;      lockRelease(&stateLock); // release state lock      return SUCCESS;   }         // set radio into sleep mode: can't Tx or Rx   command result_t RadioState.sleep()   {      if (state == SLEEP) return SUCCESS;      if (!lockAcquire(&stateLock)) return FAIL; // in state transition      outp(0x00, SPCR);  // turn off SPI      call CC1000StdControl.stop();      state = SLEEP;      lockRelease(&stateLock); // release state lock      return SUCCESS;   }         // start sending a new packet. Automatically send start symbol first   command result_t RadioByte.startTx()   {      char temp;      if (!lockAcquire(&stateLock)) return FAIL; // in state transition      cbi(SPCR, SPIE);	// disable SPI interrupt      cbi(SPCR, SPE);   // disable SPI      if (state == SLEEP) {  // wake up radio if in sleep state         call CC1000StdControl.start();         call CC1000Control.BIASOn();      }      nextByte = 0xaa; // buffer second byte      txCount = 2;      temp = inp(SPSR);  // clear possible pending SPI interrupt      outp(0xaa, SPDR);  // put first byte into SPI data register      //set radio to Tx mode      call CC1000Control.TxMode();	// radio to tx mode      TOSH_MAKE_MISO_OUTPUT();      TOSH_MAKE_MOSI_OUTPUT();      outp(0xc0, SPCR);  // enable SPI and SPI interrupt      state = TRANSMIT;      lockRelease(&stateLock); // release state lock      return SUCCESS;   }         // send next byte   command result_t RadioByte.txNextByte(char data)   {      nextByte = data;      return SUCCESS;   }   // start carrier sense   command result_t CarrierSense.start(uint16_t numBits)   {      if (state != IDLE) return FAIL;      extFlag = 0;      carrSenTime = numBits >> 3;  // now is counted by number of bytes      csVal1 = 0x180;      return SUCCESS;   }	   // default do-nothing handler for carrier sense   default event result_t CarrierSense.channelIdle()   {      return SUCCESS;   }   default event result_t CarrierSense.channelBusy()   {      return SUCCESS;   }         // Interrupt handler for SPI.   // The signal handler disables globle interrupts by default.   TOSH_SIGNAL(SIG_SPI)   {      uint8_t data;      data = inp(SPDR);      if (bInvertRxData) data = ~data;      if (state == TRANSMIT) {         outp(nextByte, SPDR);  // send buffered byte         if (txCount < PREAMBLE_LEN) {            nextByte = 0xaa;            txCount++;         } else if (txCount < PREAMBLE_LEN + sizeof(start)) {            nextByte = start[txCount - PREAMBLE_LEN];            txCount++;         } else {            signal RadioByte.txByteReady(); // ask a byte from upper layer         }      } else if (state == IDLE) {         bManchesterBad = call CC1000Control.GetLock();         if ((!bManchesterBad) && (data == 0xaa || data == 0x55)) {            PreambleCount++;            if (PreambleCount > VALID_PRECURSOR) {               if (stateLock) return; // radio is in transition               state = SYNC_START;               if (carrSenTime > 0) {  // MAC is in Carrier Sense state                  carrSenTime = 0;  // stop carrier sense                  signal CarrierSense.channelBusy();               }            }         } else {	        PreambleCount = 0;         }         if (carrSenTime > 0) call RSSIADC.getData(); // carrier sense      } else if (state == SYNC_START) {         uint8_t i;         if (data == 0xaa || data == 0x55) {           SOFCount = 0;   //tolerant of bad bits in the preamble...         } else {            uint8_t usTmp;            SOFCount++;            switch (SOFCount) {            case 1:               RxShiftBuf.MSB = data;               break;            case 2:               RxShiftBuf.LSB = data;               if (RxShiftBuf.W == SYNC_WORD) {                  if (stateLock) return; // radio is in transition                  state = RECEIVE;                  RxBitOffset = 0;                  if (signal RadioByte.startSymDetected() == FAIL) {                     call RadioState.idle();                  }               }                break;                        case 3:                // bit shift the data into previous samples to find SOF               usTmp = data;               for(i=0;i<8;i++) {                  RxShiftBuf.W <<= 1;                  if(usTmp & 0x80)                     RxShiftBuf.W |= 0x1;                  usTmp <<= 1;                  // check for SOF bytes                  if (RxShiftBuf.W == SYNC_WORD) {                     if (stateLock) return; // radio is in transition                     state = RECEIVE;                     RxBitOffset = 7-i;                     RxShiftBuf.LSB = data;                     if (signal RadioByte.startSymDetected()== FAIL) {                        call RadioState.idle();                     }                     break;                  }               }               break;            default:               // We didn't find it after a reasonable number of tries, so....               call RadioState.idle();               break;            }         }      }else if (state == RECEIVE) {         char Byte;         RxShiftBuf.W <<=8;         RxShiftBuf.LSB = data;         Byte = (RxShiftBuf.W >> RxBitOffset);         signal RadioByte.rxByteDone(Byte);      }		   }   async event result_t RSSIADC.dataReady(uint16_t data)   {      // ADC got a sample of signal strength      if (state == IDLE && carrSenTime > 0) {         csValAve = (csVal1 + data) >> 1;         if (csValAve < RADIO_BUSY_THRESHOLD) {            carrSenTime = 0;            signal CarrierSense.channelBusy();         } else {            csVal1 = data;            carrSenTime--;            if (carrSenTime == 0) {               if (extFlag == 1) {  // already checked extended bytes                  signal CarrierSense.channelIdle();               } else {                  if (data < EW_THRESHOLD) {                     extFlag = 1;  // set flag for extended bytes                     carrSenTime = NUM_EXT_BYTES;                  } else {  // signal strength is very low                     signal CarrierSense.channelIdle();                  }               }            }         }      }            if (getRSSI) { // upper layer wants signal strength         if (signal SignalStrength.sampleReady(data) == FAIL) {            getRSSI = 0;            return FAIL;  // stop sampling         }      }      return SUCCESS;   }   command result_t SignalStrength.sampleStart()   {      // start continuous sampling on signal strength      if (call RSSIADC.getContinuousData()) {         getRSSI = 1;         return SUCCESS;      } else {         return FAIL;      }   }   default async event result_t SignalStrength.sampleReady(uint16_t data)   {      // default handler for a signal strength sample      getRSSI = 0;      return FAIL;  // stops sampling   }}  // end of implementation

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -