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

📄 cc1000sendreceivep.nc

📁 tinyos2.0版本驱动
💻 NC
📖 第 1 页 / 共 2 页
字号:
// $Id: CC1000SendReceiveP.nc,v 1.10 2008/06/11 00:46:23 razvanm Exp $/* * "Copyright (c) 2000-2005 The Regents of the University  of 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, the following * two paragraphs and the author appear in all copies of this software. *  * IN NO EVENT SHALL THE UNIVERSITY OF 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 * CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. *  * THE UNIVERSITY OF 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 CALIFORNIA HAS NO OBLIGATION TO * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS." * * Copyright (c) 2002-2005 Intel Corporation * All rights reserved. * * This file is distributed under the terms in the attached INTEL-LICENSE      * file. If you do not find these files, copies can be found by writing to * Intel Research Berkeley, 2150 Shattuck Avenue, Suite 1300, Berkeley, CA,  * 94704.  Attention:  Intel License Inquiry. */#include "message.h"#include "crc.h"#include "CC1000Const.h"#include "Timer.h"/** * A rewrite of the low-power-listening CC1000 radio stack. * This file contains the send and receive logic for the CC1000 radio. * It does not do any media-access control. It requests the channel * via the ready-to-send event (rts) and starts transmission on reception * of the clear-to-send command (cts). It listens for packets if the * listen() command is called, and stops listening when off() is called. * <p> * This code has some degree of platform-independence, via the * CC1000Control, RSSIADC and SpiByteFifo interfaces which must be provided * by the platform. However, these interfaces may still reflect some * particularities of the mica2 hardware implementation. * * @author Philip Buonadonna * @author Jaein Jeong * @author Joe Polastre * @author David Gay */  module CC1000SendReceiveP {  provides {    interface Init;    interface StdControl;    interface Send;    interface Receive;    interface RadioTimeStamping;    interface Packet;    interface ByteRadio;    interface PacketAcknowledgements;    interface LinkPacketMetadata;  }  uses {    //interface PowerManagement;    interface CC1000Control;    interface HplCC1000Spi;    interface CC1000Squelch;    interface ReadNow<uint16_t> as RssiRx;    async command am_addr_t amAddress();  }}implementation {  enum {    OFF_STATE,    INACTIVE_STATE,		/* Not listening, but will accept sends */    LISTEN_STATE,		/* Listening for packets */    /* Reception states */    SYNC_STATE,    RX_STATE,    RECEIVED_STATE,    SENDING_ACK,    /* Transmission states */    TXPREAMBLE_STATE,    TXSYNC_STATE,    TXDATA_STATE,    TXCRC_STATE,    TXFLUSH_STATE,    TXWAITFORACK_STATE,    TXREADACK_STATE,    TXDONE_STATE,  };  enum {    SYNC_BYTE1 =	0x33,    SYNC_BYTE2 =	0xcc,    SYNC_WORD =		SYNC_BYTE1 << 8 | SYNC_BYTE2,    ACK_BYTE1 =		0xba,    ACK_BYTE2 =		0x83,    ACK_WORD = 		ACK_BYTE1 << 8 | ACK_BYTE2,    ACK_LENGTH =	16,    MAX_ACK_WAIT =	18  };  uint8_t radioState;  struct {    uint8_t ack : 1; 		/* acks enabled? */    uint8_t txBusy : 1;		/* send pending? */    uint8_t invert : 1;		/* data inverted? (see cc1000 datasheet) */    uint8_t rxBitOffset : 3;	/* bit-offset of received bytes */  } f; // f for flags  uint16_t count;  uint16_t runningCrc;  uint16_t rxShiftBuf;  message_t rxBuf;  message_t * ONE rxBufPtr = &rxBuf;  uint16_t preambleLength;  message_t * ONE_NOK txBufPtr;  uint8_t nextTxByte;  const_uint8_t ackCode[5] = { 0xab, ACK_BYTE1, ACK_BYTE2, 0xaa, 0xaa };  /* Packet structure accessor functions. Note that everything is   * relative to the data field. */  cc1000_header_t * ONE getHeader(message_t * ONE amsg) {    return TCAST(cc1000_header_t * ONE, (uint8_t *)amsg + offsetof(message_t, data) - sizeof(cc1000_header_t));  }  cc1000_footer_t *getFooter(message_t * ONE amsg) {    return (cc1000_footer_t *)(amsg->footer);  }    cc1000_metadata_t * ONE getMetadata(message_t * ONE amsg) {    return TCAST(cc1000_metadata_t * ONE, (uint8_t *)amsg + offsetof(message_t, footer) + sizeof(cc1000_footer_t));  }    /* State transition functions */  /*----------------------------*/  void enterOffState() {    radioState = OFF_STATE;  }  void enterInactiveState() {    radioState = INACTIVE_STATE;  }  void enterListenState() {    radioState = LISTEN_STATE;    count = 0;  }  void enterSyncState() {    radioState = SYNC_STATE;    count = 0;    rxShiftBuf = 0;  }  void enterRxState() {    cc1000_header_t *header = getHeader(rxBufPtr);    radioState = RX_STATE;    header->length = sizeof rxBufPtr->data;    count = sizeof(message_header_t) - sizeof(cc1000_header_t);    runningCrc = 0;  }  void enterReceivedState() {    radioState = RECEIVED_STATE;  }  void enterAckState() {    radioState = SENDING_ACK;    count = 0;  }  void enterTxPreambleState() {    radioState = TXPREAMBLE_STATE;    count = 0;    runningCrc = 0;    nextTxByte = 0xaa;  }  void enterTxSyncState() {    radioState = TXSYNC_STATE;  }  void enterTxDataState() {    radioState = TXDATA_STATE;    // The count increment happens before the first byte is read from the    // packet, so we subtract one from the real packet start point to    // compensate.    count = (sizeof(message_header_t) - sizeof(cc1000_header_t)) -1;   }  void enterTxCrcState() {    radioState = TXCRC_STATE;  }      void enterTxFlushState() {    radioState = TXFLUSH_STATE;    count = 0;  }      void enterTxWaitForAckState() {    radioState = TXWAITFORACK_STATE;    count = 0;  }      void enterTxReadAckState() {    radioState = TXREADACK_STATE;    rxShiftBuf = 0;    count = 0;  }      void enterTxDoneState() {    radioState = TXDONE_STATE;  }  command error_t Init.init() {    f.ack = TRUE; /* We always ack, for now at least */    call HplCC1000Spi.initSlave();    return SUCCESS;  }  command error_t StdControl.start() {    atomic       {	enterInactiveState();	f.txBusy = FALSE;	f.invert = call CC1000Control.getLOStatus();      }    return SUCCESS;  }  command error_t StdControl.stop() {    atomic enterOffState();    return SUCCESS;  }  /* Send side. Outside requests, SPI handlers for each state */  /*----------------------------------------------------------*/  command error_t Send.send(message_t *msg, uint8_t len) {    atomic      {	if (f.txBusy || radioState == OFF_STATE)	  return FAIL;	else {	  cc1000_header_t *header = getHeader(msg);	  f.txBusy = TRUE;	  header->length = len;	  txBufPtr = msg;	}      }    signal ByteRadio.rts(msg);    return SUCCESS;  }  async command void ByteRadio.cts() {    /* We're set to go! Start with our exciting preamble... */    enterTxPreambleState();    call HplCC1000Spi.writeByte(0xaa);    call CC1000Control.txMode();    call HplCC1000Spi.txMode();  }  command error_t Send.cancel(message_t *msg) {    /* We simply ignore cancellations. */    return FAIL;  }  void sendNextByte() {    call HplCC1000Spi.writeByte(nextTxByte);    count++;  }  void txPreamble() {    sendNextByte();    if (count >= preambleLength)      {	nextTxByte = SYNC_BYTE1;	enterTxSyncState();      }  }  void txSync() {    sendNextByte();    nextTxByte = SYNC_BYTE2;    enterTxDataState();    signal RadioTimeStamping.transmittedSFD(0, txBufPtr);   }  void txData() {    cc1000_header_t *txHeader = getHeader(txBufPtr);    sendNextByte();        if (count < txHeader->length + sizeof(message_header_t))      {	nextTxByte = ((uint8_t *)txBufPtr)[count];	runningCrc = crcByte(runningCrc, nextTxByte);      }    else      {	nextTxByte = runningCrc;	enterTxCrcState();      }  }  void txCrc() {    sendNextByte();    nextTxByte = runningCrc >> 8;    enterTxFlushState();  }  void txFlush() {    sendNextByte();    if (count > 3)      if (f.ack)	enterTxWaitForAckState();      else	{	  call HplCC1000Spi.rxMode();	  call CC1000Control.rxMode();	  enterTxDoneState();	}  }  void txWaitForAck() {    sendNextByte();    if (count == 1)      {

⌨️ 快捷键说明

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