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

网络

开发平台:

Others

  1. /* tab:4
  2.  *
  3.  *
  4.  * "Copyright (c) 2000-2002 The Regents of the University  of California.  
  5.  * All rights reserved.
  6.  *
  7.  * Permission to use, copy, modify, and distribute this software and its
  8.  * documentation for any purpose, without fee, and without written agreement is
  9.  * hereby granted, provided that the above copyright notice, the following
  10.  * two paragraphs and the author appear in all copies of this software.
  11.  * 
  12.  * IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY FOR
  13.  * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
  14.  * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE UNIVERSITY OF
  15.  * CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  16.  * 
  17.  * THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES,
  18.  * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
  19.  * AND FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS
  20.  * ON AN "AS IS" BASIS, AND THE UNIVERSITY OF CALIFORNIA HAS NO OBLIGATION TO
  21.  * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS."
  22.  *
  23.  */
  24. /* tab:4
  25.  *  IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.  By
  26.  *  downloading, copying, installing or using the software you agree to
  27.  *  this license.  If you do not agree to this license, do not download,
  28.  *  install, copy or use the software.
  29.  *
  30.  *  Intel Open Source License 
  31.  *
  32.  *  Copyright (c) 2002 Intel Corporation 
  33.  *  All rights reserved. 
  34.  *  Redistribution and use in source and binary forms, with or without
  35.  *  modification, are permitted provided that the following conditions are
  36.  *  met:
  37.  * 
  38.  * Redistributions of source code must retain the above copyright
  39.  *  notice, this list of conditions and the following disclaimer.
  40.  * Redistributions in binary form must reproduce the above copyright
  41.  *  notice, this list of conditions and the following disclaimer in the
  42.  *  documentation and/or other materials provided with the distribution.
  43.  *      Neither the name of the Intel Corporation nor the names of its
  44.  *  contributors may be used to endorse or promote products derived from
  45.  *  this software without specific prior written permission.
  46.  *  
  47.  *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  48.  *  ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  49.  *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
  50.  *  PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE INTEL OR ITS
  51.  *  CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
  52.  *  EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
  53.  *  PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
  54.  *  PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
  55.  *  LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
  56.  *  NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  57.  *  SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  58.  * 
  59.  * 
  60.  */
  61. /*  
  62.  *  Authors: Philip Buonadonna, Jaein Jeong
  63.  *  Date last modified: $Revision: 1.1.1.1 $
  64.  *
  65.  * This module provides the layer2 functionality for the mica2 radio.
  66.  * While the internal architecture of this module is not CC1000 specific,
  67.  * It does make some CC1000 specific calls via CC1000Control.
  68.  * 
  69.  */
  70. module CC1000RadioM {
  71.   provides {
  72.     interface StdControl;
  73.     interface BareSendMsg as Send;
  74.     interface ReceiveMsg as Receive;
  75.     command result_t EnableRSSI();
  76.     command result_t DisableRSSI();
  77.     interface RadioCoordinator as RadioSendCoordinator;
  78.     interface RadioCoordinator as RadioReceiveCoordinator;
  79.   }
  80.   uses {
  81.     interface StdControl as CC1000StdControl;
  82.     interface CC1000Control;
  83.     interface Random;
  84.     interface ADCControl;
  85.     interface ADC as RSSIADC;
  86.     interface SpiByteFifo;
  87.   }
  88. }
  89. implementation {
  90.   enum {
  91.     DISABLED_STATE,
  92.     IDLE_STATE,
  93.     TXPEND_STATE,
  94.     SYNC_STATE,
  95.     RX_STATE,
  96.     TX_STATE
  97.   };
  98.   enum {
  99.     SYNC_BYTE = 0x33,
  100.     NSYNC_BYTE = 0xcc,
  101.     SYNC_WORD = 0x33cc,
  102.     NSYNC_WORD = 0xcc33
  103.   };
  104.   enum {
  105.     PREAMBLE_LEN = 18,
  106.     VALID_PRECURSOR = 5
  107.   };
  108.   
  109.   uint8_t RadioState;
  110.   uint16_t txlength;
  111.   uint16_t rxlength;
  112.   TOS_MsgPtr txbufptr;  // pointer to transmit buffer
  113.   TOS_MsgPtr rxbufptr;  // pointer to receive buffer
  114.   TOS_Msg RxBuf; // save received messages
  115.   uint8_t PreambleCount;  //  found a valid preamble
  116.   uint8_t SOFCount;
  117.   union {
  118.     uint16_t W;
  119.     struct {
  120.       uint8_t LSB;
  121.       uint8_t MSB;
  122.     };
  123.   } RxShiftBuf;
  124.   uint8_t RxBitOffset; // bit offset for spibus
  125.   uint8_t RxByteCnt; // received byte counter
  126.   bool bInvertRxData; // data inverted
  127.   bool bRSSIEnable; // RSSI flag
  128.   uint16_t usRunningCRC; // Running CRC variable
  129.   int16_t sMacDelay;    // MAC delay for the next transmission
  130.   // XXX-PB:
  131.   // Here's the deal, the mica (RFM) radio stacks used TOS_LOCAL_ADDRESS
  132.   // to determine if an L2 ack was reqd.  This stack doesn't do L2 acks
  133.   // and, thus doesn't need it.  HOWEVER, set-mote-id breaks if it 
  134.   // compiles a program that doesn't have the symbol TOS_LOCAL_ADDRESS in
  135.   // the binary.  This occurs in programs such as GenericBase.
  136.   // Thus, I put this LocalAddr here and set it to TOS_LOCAL_ADDRESS
  137.   // to keep things happy for now.
  138.   volatile uint16_t LocalAddr;
  139.   ///**********************************************************
  140.   //* local function definitions
  141.   //**********************************************************/
  142.   
  143.   void TransmitPkt() {
  144.     uint16_t i;
  145.     char byte;
  146.   
  147.     usRunningCRC = 0;
  148.     // time to transmit a packet
  149.     cli(); // XXX-PB We're already in interrupt state, aren't we??
  150.     call CC1000Control.TxMode(); // radio to tx mode
  151.     call SpiByteFifo.txMode(); // SPI to miso
  152.   
  153.     for (i=0;i<PREAMBLE_LEN;i++) {
  154.       call SpiByteFifo.writeByte(0xaa);
  155.     }
  156.     call SpiByteFifo.writeByte(SYNC_BYTE);
  157.     call SpiByteFifo.writeByte(NSYNC_BYTE);
  158.     signal RadioSendCoordinator.startSymbol();
  159.   
  160.     for (i=0;i<txlength;i++) {
  161.       byte = ((char*)txbufptr)[i];
  162.       usRunningCRC = crcByte(usRunningCRC,byte);
  163.       call SpiByteFifo.writeByte(byte);
  164.       signal RadioSendCoordinator.byte();
  165.     }
  166.     byte = (char)(usRunningCRC);
  167.     call SpiByteFifo.writeByte(byte);
  168.     byte = (char)(usRunningCRC>>8);
  169.     call SpiByteFifo.writeByte(byte);
  170.     // wait for byte buffer to empty
  171.     while(call SpiByteFifo.isBufBusy()) ;
  172.   
  173.     call SpiByteFifo.rxMode(); // SPI to miso
  174.     call CC1000Control.RxMode(); // radio to rx mode
  175.   
  176.     RadioState = IDLE_STATE;
  177.     sMacDelay = -1;
  178.     signal Send.sendDone((TOS_MsgPtr)txbufptr, SUCCESS); // signal rfcomm
  179.     call SpiByteFifo.enableIntr(); // enable spi interrupts
  180.     sei();  // enable interrupts
  181.   
  182.   }
  183.   ///**********************************************************
  184.   //* Exported interface functions
  185.   //**********************************************************/
  186.   
  187.   command result_t StdControl.init() {
  188.     RadioState = IDLE_STATE;
  189.     rxbufptr = &RxBuf;
  190.     rxlength = MSG_DATA_SIZE-2;
  191.     RxBitOffset = 0;
  192.     PreambleCount = 0;
  193.     RxShiftBuf.W = 0;
  194.     sMacDelay = -1;
  195.     call SpiByteFifo.initSlave(); // set spi bus to slave mode
  196.     call CC1000StdControl.init();
  197.     call CC1000Control.SelectLock(0x9); // Select MANCHESTER VIOLATION
  198.     bInvertRxData = call CC1000Control.GetLOStatus();  //Do we need to invert Rcvd Data?
  199.     call ADCControl.bindPort(TOS_ADC_CC_RSSI_PORT,TOSH_ACTUAL_CC_RSSI_PORT);
  200.     call ADCControl.init();
  201.     call Random.init();
  202.     call SpiByteFifo.enableIntr(); // enable spi and spi interrupt
  203.     LocalAddr = TOS_LOCAL_ADDRESS;
  204.     bRSSIEnable = TRUE;    // rssi disabled
  205.     return SUCCESS;
  206.   }
  207.   
  208.   command result_t EnableRSSI() {
  209.     bRSSIEnable = TRUE;
  210.     return SUCCESS;
  211.   }
  212.   command result_t DisableRSSI() {
  213.     bRSSIEnable = FALSE;
  214.     return SUCCESS;
  215.   }
  216.   command result_t StdControl.stop() {
  217.     RadioState = DISABLED_STATE;
  218.     call CC1000StdControl.stop();
  219.     call SpiByteFifo.disableIntr(); // disable spi interrupt
  220.     return SUCCESS;
  221.   }
  222.   command result_t StdControl.start() {
  223.     RadioState  = IDLE_STATE;
  224.     sMacDelay = -1;
  225.     //call Chipcon.rf_pwup();
  226.     call CC1000StdControl.start();
  227.     call SpiByteFifo.enableIntr(); // enable spi interrupt
  228.     return SUCCESS;
  229.   }
  230.   command result_t Send.send(TOS_MsgPtr pMsg) {
  231.     //SRM 7.18.03 -- Don't send if the power is off!
  232.     if (RadioState == DISABLED_STATE) return FAIL;
  233.     // msg is pointer to new transmit packet
  234.     if (sMacDelay != -1) {
  235.       return FAIL;
  236.     }
  237.     txbufptr = pMsg;
  238.     txlength = pMsg->length + (MSG_DATA_SIZE - DATA_LENGTH - 2); 
  239.     sMacDelay = ((call Random.rand() & 0x3f) + 100) >> 3;
  240.     return SUCCESS;
  241.   }
  242.   
  243.   /**********************************************************
  244.    * make a spibus interrupt handler
  245.    * needs to handle interrupts for transmit delay
  246.    * and then go into byte transmit mode with
  247.    *   timer1 baudrate delay as interrupt handler
  248.    * else
  249.    * needs to handle interrupts for byte read and detect preamble
  250.    *  then handle reading a packet
  251.    * PB - We can use this interrupt handler as a transmit scheduler
  252.    * because the CC1000 continuously clocks in data, regarless
  253.    * of whether it's good or not.  Thus, this routine will be called
  254.    * on every 8 ticks of DCLK. 
  255.    **********************************************************/
  256.   event result_t SpiByteFifo.dataReady(uint8_t data_in) {
  257.     if (bInvertRxData) 
  258.       data_in = ~data_in;
  259.     switch (RadioState) {
  260.     case DISABLED_STATE:
  261.       break;
  262.     case IDLE_STATE:
  263.       {
  264. bool bManchesterBad;
  265. bManchesterBad = call CC1000Control.GetLock();
  266. if ((!bManchesterBad) && ((data_in == (0xaa)) || (data_in == (0x55)))) {
  267.   PreambleCount++;
  268.   if (PreambleCount > VALID_PRECURSOR) {
  269.     PreambleCount = SOFCount = 0;
  270.     RxBitOffset = RxByteCnt = 0;
  271.     usRunningCRC = 0;
  272.     rxlength = MSG_DATA_SIZE-2;
  273.     RadioState = SYNC_STATE;
  274.     if (bRSSIEnable) {
  275.       // Sample signal strength for this packet.
  276.       call RSSIADC.getData();
  277.     }
  278.   }
  279.   else if (sMacDelay != -1) {
  280.     sMacDelay = ((call Random.rand() & 0x3f) + 100) >> 3;
  281.   }
  282. }
  283. else {
  284.   PreambleCount = 0;
  285.   if ((sMacDelay != -1) && (--sMacDelay == 0)) { // tx timeout go to tx mode
  286.     TransmitPkt();
  287.   }
  288. }
  289.       }
  290.       break;
  291.       
  292.     case SYNC_STATE:
  293.       {
  294. // draw in the preamble bytes and look for a sync byte
  295. // save the data in a short with last byte received as msbyte
  296. //    and current byte received as the lsbyte.
  297. // use a bit shift compare to find the byte boundary for the sync byte
  298. // retain the shift value and use it to collect all of the packet data
  299. // check for data inversion, and restore proper polarity XXX-PB: Don't do this.
  300. uint8_t i;
  301.       
  302. if ((data_in == 0xaa) || (data_in == 0x55)) {
  303.   // It is actually possible to have the LAST BIT of the incoming
  304.   // data be part of the Sync Byte.  SO, we need to store that
  305.   // However, the next byte should definitely not have this pattern.
  306.   // XXX-PB: Do we need to check for excessive preamble?
  307.   RxShiftBuf.MSB = data_in;
  308. }
  309. else {
  310.   // TODO: Modify to be tolerant of bad bits in the preamble...
  311.   uint16_t usTmp;
  312.   switch (SOFCount) {
  313.   case 0:
  314.     RxShiftBuf.LSB = data_in;
  315.     break;
  316.   
  317.   case 1:
  318.   case 2: 
  319.     // bit shift the data in with previous sample to find sync
  320.     usTmp = RxShiftBuf.W;
  321.     RxShiftBuf.W <<= 8;
  322.     RxShiftBuf.LSB = data_in;
  323.     for(i=0;i<8;i++) {
  324.       usTmp <<= 1;
  325.       if(data_in & 0x80)
  326. usTmp  |=  0x1;
  327.       data_in <<= 1;
  328.       // check for sync bytes
  329.       if (usTmp == SYNC_WORD) {
  330. RadioState = RX_STATE;
  331. RxBitOffset = 7-i;
  332. signal RadioSendCoordinator.startSymbol();
  333. break;
  334.       }
  335. #if 0
  336.       else if (usTmp == NSYNC_WORD) {
  337. RadioState = RX_STATE;
  338. RxBitOffset = 7-i;
  339. bInvertRxData = TRUE;
  340. break;
  341.       }
  342. #endif
  343.     }
  344.     break;
  345.   default:
  346.     // We didn't find it after a reasonable number of tries, so....
  347.     RadioState = IDLE_STATE;
  348.     break;
  349.   }
  350.   SOFCount++;
  351. }
  352.       }
  353.       break;
  354.       //  collect the data and shift into double buffer
  355.       //  shift out data by correct offset
  356.       //  invert the data if necessary
  357.       //  stop after the correct packet length is read
  358.       //  return notification to upper levels
  359.       //  go back to idle state
  360.     case RX_STATE:
  361.       {
  362. char Byte;
  363. RxShiftBuf.W <<=8;
  364. RxShiftBuf.LSB = data_in;
  365. #if 0
  366. if (bInvertRxData) {
  367.   Byte= ~(RxShiftBuf.W >> RxBitOffset);
  368. }
  369. else {
  370.   Byte = (RxShiftBuf.W >> RxBitOffset);
  371. }
  372. #endif
  373. Byte = (RxShiftBuf.W >> RxBitOffset);
  374. ((char*)rxbufptr)[(int)RxByteCnt] = Byte;
  375. RxByteCnt++;
  376. if (RxByteCnt < rxlength) {
  377.   usRunningCRC = crcByte(usRunningCRC,Byte);
  378.   if (RxByteCnt == (offsetof(struct TOS_Msg,length) + 
  379.     sizeof(((struct TOS_Msg *)0)->length))) {
  380.     rxlength = rxbufptr->length;
  381.     if (rxlength > TOSH_DATA_LENGTH) {
  382.       // The packet's screwed up, so just dump it
  383.       RadioState = IDLE_STATE;
  384.       return SUCCESS;
  385.     }
  386.     //Add in the header size
  387.     rxlength += offsetof(struct TOS_Msg,data);
  388.   }
  389.   signal RadioSendCoordinator.byte();
  390. }
  391. else if (RxByteCnt == rxlength) {
  392.   // We've reached the end of the header/payload stream. Next two
  393.   // rcvd bytes should be CRC. Advanced counter to 'crc' field.
  394.   usRunningCRC = crcByte(usRunningCRC,Byte);
  395.   // Shift index ahead to the crc field.
  396.   RxByteCnt = offsetof(struct TOS_Msg,crc);
  397.   signal RadioSendCoordinator.byte();
  398. }
  399. else if (RxByteCnt >= MSG_DATA_SIZE) { 
  400.   RadioState = IDLE_STATE;
  401.   if (rxbufptr->crc == usRunningCRC) {
  402.     rxbufptr = signal Receive.receive((TOS_Msg*)rxbufptr); // signal rfcomm
  403.   }
  404.   if (sMacDelay != -1) {
  405.     sMacDelay = ((call Random.rand() & 0x3f) + 100) >> 3;
  406.   }
  407. }
  408.       }
  409.       break;
  410.     default:
  411.       break;
  412.     }
  413.     return SUCCESS;
  414.   }
  415.   event result_t RSSIADC.dataReady(uint16_t data) {
  416.     rxbufptr->strength = data;
  417.     return SUCCESS;
  418.   }
  419.   // Default events for radio send/receive coordinators do nothing.
  420.   // Be very careful using these, you'll break the stack.
  421.   default event void RadioSendCoordinator.startSymbol() { }
  422.   default event void RadioSendCoordinator.byte() { }
  423.   default event void RadioReceiveCoordinator.startSymbol() { }
  424.   default event void RadioReceiveCoordinator.byte() { }
  425. }