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

📄 phyradiom.nc

📁 tinyos最新版
💻 NC
字号:
// $Id: PhyRadioM.nc,v 1.1 2004/03/04 20:21:14 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 * Date created: 1/21/2003 *  * This is the physical layer that sends and receives a packet *   - accept any type and length (<= PHY_MAX_PKT_LEN in phy_radio_msg.h) of packet *   - sending a packet: encoding and byte spooling *   - receiving a packet: decoding, byte buffering *   - Optional CRC check (CRC calculation is based on code from Jason Hill) *   - interface to radio control and physical carrier sense * *//** * @author Wei Ye */includes uartDebug;module PhyRadioM{   provides {      interface StdControl as PhyControl;      interface RadioState as PhyState;      interface PhyComm;      interface PhyStreamByte;   }   uses {      interface StdControl as RadControl;      interface RadioState;      interface RadioByte;      interface StdControl as CodecControl;      interface RadioEncoding as Codec;   }}implementation{#include "PhyRadioMsg.h"#include "smacEvents.h"   // Physical layer states   enum {      IDLE,      RECEIVING,      TRANSMITTING,      TRANSMITTING_LAST,      TRANSMITTING_DONE   };      // buffer states   enum {FREE, BUSY};      char state;   uint8_t pktLength; // pkt length including my header and trailer   PhyPktBuf buffer1;  // 2 buffers for receiving and processing   PhyPktBuf buffer2;   char recvBufState;  // receiving buffer state   char procBufState;  // processing buffer state   char* procBufPtr;   char* sendPtr;   char* recvPtr;   char* procPtr;   uint8_t recvCount;   uint8_t numEncoded;   char txBuffer[3];   uint8_t bufHead;   uint8_t bufEnd;   int16_t crcRx;     // CRC of received pkt   int16_t crcTx;     // CRC of transmitted pkt         int16_t update_crc(char data, int16_t crc)   {      char i;      int16_t tmp;      tmp = (int16_t)(data);      crc = crc ^ (tmp << 8);      for (i = 0; i < 8; i++) {         if (crc & 0x8000)            crc = crc << 1 ^ 0x1021;  // << is done before ^         else            crc = crc << 1;         }      return crc;   }	   task void packet_received()   {      void* tmp;      char error, intEnabled;      uint8_t len;      len = (uint8_t)procPtr[0];      if (crcRx != *(int16_t*)(procPtr + len - 2)) {         error = 1;      } else {         error = 0;      }      tmp = signal PhyComm.rxPktDone(procPtr, error);      if (tmp) {         intEnabled = inp(SREG) & 0x80;         cli();         if (recvBufState == BUSY) { // waiting for a free buffer            procPtr = recvPtr;            recvPtr = (char*)tmp;            recvBufState = FREE;  // can start receive now         } else {            procPtr = NULL;            procBufPtr = (char*)tmp;            procBufState = FREE;         }         if (intEnabled) sei();         if (procPtr) {  // have a buffered packet to signal            if (!post packet_received()) {  // task queue is full               procBufPtr = procPtr;  //drop packet               procBufState = FREE;               signal PhyComm.rxPktDone(NULL, 1); // signal in case MAC is waiting            }         }      }   }   task void packet_sent()   {      signal PhyComm.txPktDone(sendPtr);   }   command result_t PhyControl.init()   {      state = IDLE;      recvPtr = (char*)&buffer1;      procBufPtr = (char*)&buffer2;      recvBufState = FREE;      procBufState = FREE;      call RadControl.init();      return SUCCESS;   }   command result_t PhyControl.start()   {      return SUCCESS;   }         command result_t PhyControl.stop()   {      return SUCCESS;   }         command result_t PhyState.idle()   {      call RadioState.idle();      state = IDLE;      return SUCCESS;   }         command result_t PhyState.sleep()   {      call RadioState.sleep();      state = IDLE;      return SUCCESS;   }   command result_t PhyComm.txPkt(void* packet, uint8_t length)   {      if (length > PHY_MAX_PKT_LEN || length < PHY_MIN_PKT_LEN) return FAIL;      if (state != IDLE && state != RECEIVING) return FAIL;      state = TRANSMITTING;      call RadioByte.startTx(); // tell radio to start sending      sendPtr = (char*)packet;      ((PhyHeader*)sendPtr)->length = length;  // fill my header field      pktLength = length;      // encode first byte of the packet      bufHead = 0;      bufEnd = 0;      call Codec.encode(sendPtr[0]);      numEncoded = 1;      crcTx=update_crc(sendPtr[0], 0);      return SUCCESS;   }   // default do-nothing event handler for PhyComm interface   default event result_t PhyComm.txPktDone(void* packet)   {      return SUCCESS;   }         default event result_t PhyComm.startSymDetected(void* packet)   {      return SUCCESS;   }         default event void* PhyComm.rxPktDone(void* packet, char error)   {      return packet;   }      async event result_t Codec.encodeDone(char data)   {      txBuffer[bufEnd] = data;      bufEnd++;      return SUCCESS;   }   async event result_t Codec.decodeDone(char data, char error)   {      // one byte is decoded      if (recvCount == 0) {  // first byte is packet length         if (error == 1 || (uint8_t)data > PHY_MAX_PKT_LEN             || (uint8_t)data < PHY_MIN_PKT_LEN) {            call RadioState.idle();            state = IDLE;            // signal received an erroneous packet with NULL buffer            // unknown length (0) and error flag setting to 1            signal PhyComm.rxPktDone(NULL, 1);            return FAIL;         }         pktLength = (uint8_t)data;         crcRx = 0;      }      recvPtr[recvCount] = data;      recvCount++;      // pass data for upper layer to stream bytes (e.g. snooper)      signal PhyStreamByte.rxByteDone(data);      if (recvCount < pktLength - 1) {         crcRx=update_crc(data, crcRx);      } else if (recvCount == pktLength) { // Rx packet done         if (procBufState == FREE) {  // have a free buffer, use it now            procPtr = recvPtr;            recvPtr = procBufPtr;            recvBufState = FREE;            if (post packet_received()) { // signal upper layer               procBufState = BUSY;            } else {  // task queue is full               procBufPtr = procPtr;  //drop packet               signal PhyComm.rxPktDone(NULL, 1); // signal in case MAC is waiting            }         } else {  // no buffer to use for Rx            recvBufState = BUSY;         }         call CodecControl.init();         call RadioState.idle();         state = IDLE;      }      return SUCCESS;   }   // default do-nothing handler for PhyStreamByte   default event result_t PhyStreamByte.rxByteDone(char data)   {      return SUCCESS;   }   event result_t RadioByte.txByteReady()   {      // radio asks a byte to transmit      if(state == TRANSMITTING) {         call RadioByte.txNextByte(txBuffer[bufHead]);         bufHead++;         //now check if that was the last byte         if (bufHead == bufEnd) {            bufHead = 0;            bufEnd = 0;            if (numEncoded < pktLength) {               if(numEncoded < pktLength - 2){                  crcTx=update_crc(sendPtr[numEncoded], crcTx);	               }               call Codec.encode(sendPtr[numEncoded]);               numEncoded++;               if(numEncoded == pktLength - 2){                  *(int16_t*)(sendPtr + pktLength - 2) = crcTx;               }            } else {               call Codec.encode_flush();               if (bufHead == bufEnd) {                  // tx is done                  state = TRANSMITTING_LAST;               }            }         }	      } else if (state == TRANSMITTING_LAST) {         state = TRANSMITTING_DONE;      } else if (state == TRANSMITTING_DONE) {         call RadioState.idle();         state = IDLE;         // signal upper layer Tx done         if (!post packet_sent()) {  // try to post task first            signal PhyComm.txPktDone(sendPtr); // signal directly if can't post         }      }               return SUCCESS;    }   event result_t RadioByte.startSymDetected()   {      // Phy must be in IDLE state, otherwise there is a bug      if (state == IDLE && recvBufState == FREE) {         state = RECEIVING;         recvCount = 0;         // signal MAC w/ receiving buffer so that it can put in timestamp         signal PhyComm.startSymDetected(recvPtr);         return SUCCESS;      }      return FAIL;   }   event result_t RadioByte.rxByteDone(char data)   {      if (state == RECEIVING) {         call Codec.decode(data);         return SUCCESS;      }      return FAIL;   }}  // end of implementation

⌨️ 快捷键说明

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