[Tinyos-contrib-commits] CVS: tinyos-1.x/contrib/vu/tos/lib/CC2420 CC2420RadioM.nc, NONE, 1.1 SysTimeStampingM.nc, 1.3, 1.4 TimeStampingC.nc, 1.1, 1.2 TimeStampingM.nc, 1.1, 1.2

Brano Kusy kusyb at users.sourceforge.net
Tue Jun 27 07:46:40 PDT 2006


Update of /cvsroot/tinyos/tinyos-1.x/contrib/vu/tos/lib/CC2420
In directory sc8-pr-cvs10.sourceforge.net:/tmp/cvs-serv10920

Modified Files:
	SysTimeStampingM.nc TimeStampingC.nc TimeStampingM.nc 
Added Files:
	CC2420RadioM.nc 
Log Message:
Radio stack implementation problems fix, SFD interrupts and radio msgs are not in sync - could happen that timestamp was assigned to a wrong msg. This fix seems to work for micaz, but still does not work perfect with telos - under high radio/computation load. Boomerang stack should solve these problems, so much cleaner stamping should be available soon.

--- NEW FILE: CC2420RadioM.nc ---
// $Id: CC2420RadioM.nc,v 1.1 2006/06/27 14:46:38 kusyb Exp $

/*									tab:4
 * "Copyright (c) 2000-2003 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-2003 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.
 */

/*  
 *  Authors: Joe Polastre
 *  Date last modified: $Revision: 1.1 $
 *
 * This module provides the layer2 functionality for the mica2 radio.
 * While the internal architecture of this module is not CC2420 specific,
 * It does make some CC2420 specific calls via CC2420Control.
 * 
 * $Id: CC2420RadioM.nc,v 1.1 2006/06/27 14:46:38 kusyb Exp $
 */

/**
 * @author Joe Polastre
 * @author Alan Broad, Crossbow
 */

includes byteorder;

module CC2420RadioM {
  provides {
    interface StdControl;
    interface SplitControl;
    interface BareSendMsg as Send;
    interface ReceiveMsg as Receive;
    interface RadioCoordinator as RadioSendCoordinator;
    interface RadioCoordinator as RadioReceiveCoordinator;
    interface MacControl;
    interface MacBackoff;
  }
  uses {
    interface SplitControl as CC2420SplitControl;
    interface CC2420Control;
    interface HPLCC2420 as HPLChipcon;
    interface HPLCC2420FIFO as HPLChipconFIFO; 
    interface HPLCC2420Interrupt as FIFOP;
    interface HPLCC2420Capture as SFD;
    interface StdControl as TimerControl;
    interface TimerJiffyAsync as BackoffTimerJiffy;
    interface Random;
    interface Leds;
  }
}

implementation {
  enum {
    DISABLED_STATE = 0,
    DISABLED_STATE_STARTTASK,
    IDLE_STATE,
    TX_STATE,
    TX_WAIT,
    PRE_TX_STATE,
    POST_TX_STATE,
    POST_TX_ACK_STATE,
    RX_STATE,
    POWER_DOWN_STATE,
    WARMUP_STATE,

    TIMER_INITIAL = 0,
    TIMER_BACKOFF,
    TIMER_ACK
  };

#define MAX_SEND_TRIES 8

  norace uint8_t countRetry;
  uint8_t stateRadio;
  norace uint8_t stateTimer;
  norace uint8_t currentDSN;
  norace bool bAckEnable;
  bool bPacketReceiving;
  uint8_t txlength;
  norace TOS_MsgPtr txbufptr;  // pointer to transmit buffer
  norace TOS_MsgPtr rxbufptr;  // pointer to receive buffer
  TOS_Msg RxBuf;	// save received messages

  volatile uint16_t LocalAddr;

  ///**********************************************************
  //* local function definitions
  //**********************************************************/

   void sendFailed() {
     atomic stateRadio = IDLE_STATE;
     txbufptr->length = txbufptr->length - MSG_HEADER_SIZE - MSG_FOOTER_SIZE;
     signal Send.sendDone(txbufptr, FAIL);
   }

   void flushRXFIFO() {
     call FIFOP.disable();
     call HPLChipcon.read(CC2420_RXFIFO);          //flush Rx fifo
     call HPLChipcon.cmd(CC2420_SFLUSHRX);
     call HPLChipcon.cmd(CC2420_SFLUSHRX);
     atomic bPacketReceiving = FALSE;
     call FIFOP.startWait(FALSE);
   }

   inline result_t setInitialTimer( uint16_t jiffy ) {
     stateTimer = TIMER_INITIAL;
     if (jiffy == 0)
       // set the minimum timer time
       return call BackoffTimerJiffy.setOneShot(2);
     return call BackoffTimerJiffy.setOneShot(jiffy);
   }

   inline result_t setBackoffTimer( uint16_t jiffy ) {
     stateTimer = TIMER_BACKOFF;
     if (jiffy == 0)
       // set the minimum timer time
       return call BackoffTimerJiffy.setOneShot(2);
     return call BackoffTimerJiffy.setOneShot(jiffy);
   }

   inline result_t setAckTimer( uint16_t jiffy ) {
     stateTimer = TIMER_ACK;
     return call BackoffTimerJiffy.setOneShot(jiffy);
   }

  /***************************************************************************
   * PacketRcvd
   * - Radio packet rcvd, signal 
   ***************************************************************************/
   task void PacketRcvd() {
     TOS_MsgPtr pBuf;

     atomic {
       pBuf = rxbufptr;
     }
     pBuf = signal Receive.receive((TOS_MsgPtr)pBuf);
     atomic {
       if (pBuf) rxbufptr = pBuf;
       rxbufptr->length = 0;
       bPacketReceiving = FALSE;
     }
   }

  
  task void PacketSent() {
    TOS_MsgPtr pBuf; //store buf on stack 

    atomic {
      stateRadio = IDLE_STATE;
      pBuf = txbufptr;
      pBuf->length = pBuf->length - MSG_HEADER_SIZE - MSG_FOOTER_SIZE;
    }

    signal Send.sendDone(pBuf,SUCCESS);
  }

  //**********************************************************
  //* Exported interface functions for Std/SplitControl
  //* StdControl is deprecated, use SplitControl
  //**********************************************************/
  
  // This interface is depricated, please use SplitControl instead
  command result_t StdControl.init() {
    return call SplitControl.init();
  }

  // Split-phase initialization of the radio
  command result_t SplitControl.init() {

    atomic {
      stateRadio = DISABLED_STATE;
      currentDSN = 0;
      bAckEnable = FALSE;
      bPacketReceiving = FALSE;
      rxbufptr = &RxBuf;
      rxbufptr->length = 0;
    }

    call TimerControl.init();
    call Random.init();
    LocalAddr = TOS_LOCAL_ADDRESS;
    return call CC2420SplitControl.init();
  }

  event result_t CC2420SplitControl.initDone() {
    return signal SplitControl.initDone();
  }

  default event result_t SplitControl.initDone() {
    return SUCCESS;
  }
  
  // This interface is depricated, please use SplitControl instead
  command result_t StdControl.stop() {
    return call SplitControl.stop();
  }

  // split phase stop of the radio stack
  command result_t SplitControl.stop() {
    atomic stateRadio = DISABLED_STATE;

    call SFD.disable();
    call FIFOP.disable();
    call TimerControl.stop();
    return call CC2420SplitControl.stop();
  }

  event result_t CC2420SplitControl.stopDone() {
    return signal SplitControl.stopDone();
  }

  default event result_t SplitControl.stopDone() {
    return SUCCESS;
  }

  task void startRadio() {
    result_t success = FAIL;
    atomic {
      if (stateRadio == DISABLED_STATE_STARTTASK) {
	stateRadio = DISABLED_STATE;
	success = SUCCESS;
      }
    }

    if (success == SUCCESS) 
      call SplitControl.start();
  }

  // This interface is depricated, please use SplitControl instead
  command result_t StdControl.start() {
    // if we put starting the radio from StdControl in a task, then it
    // delays executing until the other "start" functions are done.
    // the bug occurs when other components use the underlying bus in their
    // start() functions.  since the radio is split phase, it acquires
    // the bus during SplitControl.start() but doesn't release it until
    // SplitControl.startDone().  Ideally, Main would be changed to
    // understand SplitControl and run each SplitControl serially.
    result_t success = FAIL;

    atomic {
      if (stateRadio == DISABLED_STATE) {
	// only allow the task to be posted once.
	if (post startRadio()) {
	  success = SUCCESS;
	  stateRadio = DISABLED_STATE_STARTTASK;
	}
      }
    }

    return success;
  }

  // split phase start of the radio stack (wait for oscillator to start)
  command result_t SplitControl.start() {
    uint8_t chkstateRadio;

    atomic chkstateRadio = stateRadio;

    if (chkstateRadio == DISABLED_STATE) {
      atomic {
	stateRadio = WARMUP_STATE;
        countRetry = 0;
        rxbufptr->length = 0;
      }
      call TimerControl.start();
      return call CC2420SplitControl.start();
    }
    return FAIL;
  }

  event result_t CC2420SplitControl.startDone() {
    uint8_t chkstateRadio;

    atomic chkstateRadio = stateRadio;

    if (chkstateRadio == WARMUP_STATE) {
      call CC2420Control.RxMode();
      //enable interrupt when pkt rcvd
      call FIFOP.startWait(FALSE);
      // enable start of frame delimiter timer capture (timestamping)
      call SFD.enableCapture(TRUE);
      
      atomic stateRadio  = IDLE_STATE;
    }
    signal SplitControl.startDone();
    return SUCCESS;
  }

  default event result_t SplitControl.startDone() {
    return SUCCESS;
  }

  /************* END OF STDCONTROL/SPLITCONTROL INIT FUNCITONS **********/

  /**
   * Try to send a packet.  If unsuccessful, backoff again
   **/
  void sendPacket() {
    uint8_t status;

    call HPLChipcon.cmd(CC2420_STXONCCA);
    status = call HPLChipcon.cmd(CC2420_SNOP);
    if ((status >> CC2420_TX_ACTIVE) & 0x01) {
      // wait for the SFD to go high for the transmit SFD
      call SFD.enableCapture(TRUE);
    }
    else {
      // try again to send the packet
      atomic stateRadio = PRE_TX_STATE;
      if (!(setBackoffTimer(signal MacBackoff.congestionBackoff(txbufptr) * CC2420_SYMBOL_UNIT))) {
        sendFailed();
      }
    }
  }

  /**
   * Captured an edge transition on the SFD pin
   * Useful for time synchronization as well as determining
   * when a packet has finished transmission
   */
  async event result_t SFD.captured(uint16_t time) {
    switch (stateRadio) {
    case TX_STATE:
      // wait for SFD to fall--indicates end of packet
      call SFD.enableCapture(FALSE);
      // if the pin already fell, disable the capture and let the next
      // state enable the cpature (bug fix from Phil Buonadonna)
      if (!TOSH_READ_CC_SFD_PIN()) {
	call SFD.disable();
      }
      else {
	stateRadio = TX_WAIT;
      }
      // fire TX SFD event
      txbufptr->time = time;
      signal RadioSendCoordinator.startSymbol(8,0,txbufptr);
      // if the pin hasn't fallen, break out and wait for the interrupt
      // if it fell, continue on the to the TX_WAIT state
      if (stateRadio == TX_WAIT) {
	break;
      }
    case TX_WAIT:
      // end of packet reached
      stateRadio = POST_TX_STATE;
      call SFD.disable();
      // revert to receive SFD capture
      call SFD.enableCapture(TRUE);
      // if acks are enabled and it is a unicast packet, wait for the ack
      if ((bAckEnable) && (txbufptr->addr != TOS_BCAST_ADDR)) {
        if (!(setAckTimer(CC2420_ACK_DELAY)))
          sendFailed();
      }
      // if no acks or broadcast, post packet send done event
      else {
        if (!post PacketSent())
          sendFailed();
      }
      break;
    default:
      // fire RX SFD handler
      rxbufptr->time = time;
      signal RadioReceiveCoordinator.startSymbol(8,0,rxbufptr);
    }
    return SUCCESS;
  }

  /**
   * Start sending the packet data to the TXFIFO of the CC2420
   */
  task void startSend() {
    // flush the tx fifo of stale data
    if (!(call HPLChipcon.cmd(CC2420_SFLUSHTX))) {
      sendFailed();
      return;
    }
    // write the txbuf data to the TXFIFO
    if (!(call HPLChipconFIFO.writeTXFIFO(txlength+1,(uint8_t*)txbufptr))) {
      sendFailed();
      return;
    }
  }

  /**
   * Check for a clear channel and try to send the packet if a clear
   * channel exists using the sendPacket() function
   */
  void tryToSend() {
     uint8_t currentstate;
     atomic currentstate = stateRadio;

     // and the CCA check is good
     if (currentstate == PRE_TX_STATE) {

       // if a FIFO overflow occurs or if the data length is invalid, flush
       // the RXFIFO to get back to a normal state.
       if ((!TOSH_READ_CC_FIFO_PIN() && !TOSH_READ_CC_FIFOP_PIN())) {
         flushRXFIFO();
       }

       if (TOSH_READ_RADIO_CCA_PIN()) {
         atomic stateRadio = TX_STATE;
         sendPacket();
       }
       else {
	 // if we tried a bunch of times, the radio may be in a bad state
	 // flushing the RXFIFO returns the radio to a non-overflow state
	 // and it continue normal operation (and thus send our packet)
         if (countRetry-- <= 0) {
	   flushRXFIFO();
	   countRetry = MAX_SEND_TRIES;
	   if (!post startSend())
	     sendFailed();
           return;
         }
         if (!(setBackoffTimer(signal MacBackoff.congestionBackoff(txbufptr) * CC2420_SYMBOL_UNIT))) {
           sendFailed();
         }
       }
     }
  }

  /**
   * Multiplexed timer to control initial backoff, 
   * congestion backoff, and delay while waiting for an ACK
   */
  async event result_t BackoffTimerJiffy.fired() {
    uint8_t currentstate;
    atomic currentstate = stateRadio;

    switch (stateTimer) {
    case TIMER_INITIAL:
      if (!(post startSend())) {
        sendFailed();
      }
      break;
    case TIMER_BACKOFF:
      tryToSend();
      break;
    case TIMER_ACK:
      if (currentstate == POST_TX_STATE) {
	/* MDW 12-July-05: Race condition here: If ACK comes in before
	 * PacketSent() runs, the task can be posted twice (duplicate
	 * sendDone events). Fix: set the state to a different value to
	 * suppress the later task.
	 */
	atomic {
	  txbufptr->ack = 0;
	  stateRadio = POST_TX_ACK_STATE;
	}
        if (!post PacketSent())
	  sendFailed();
      }
      break;
    }
    return SUCCESS;
  }

 /**********************************************************
   * Send
   * - Xmit a packet
   *    USE SFD FALLING FOR END OF XMIT !!!!!!!!!!!!!!!!!! interrupt???
   * - If in power-down state start timer ? !!!!!!!!!!!!!!!!!!!!!!!!!s
   * - If !TxBusy then 
   *   a) Flush the tx fifo 
   *   b) Write Txfifo address
   *    
   **********************************************************/
  command result_t Send.send(TOS_MsgPtr pMsg) {
    uint8_t currentstate;
    atomic currentstate = stateRadio;

    if (currentstate == IDLE_STATE) {
      // put default FCF values in to get address checking to pass
      pMsg->fcflo = CC2420_DEF_FCF_LO;
      if (bAckEnable) 
        pMsg->fcfhi = CC2420_DEF_FCF_HI_ACK;
      else 
        pMsg->fcfhi = CC2420_DEF_FCF_HI;
      // destination PAN is broadcast
      pMsg->destpan = TOS_BCAST_ADDR;
      // adjust the destination address to be in the right byte order
      pMsg->addr = toLSB16(pMsg->addr);
      // adjust the data length to now include the full packet length
      pMsg->length = pMsg->length + MSG_HEADER_SIZE + MSG_FOOTER_SIZE;
      // keep the DSN increasing for ACK recognition
      pMsg->dsn = ++currentDSN;
      // reset the time field
      pMsg->time = 0;
      // FCS bytes generated by CC2420
      txlength = pMsg->length - MSG_FOOTER_SIZE;  
      txbufptr = pMsg;
      countRetry = MAX_SEND_TRIES;

      if (setInitialTimer(signal MacBackoff.initialBackoff(txbufptr) * CC2420_SYMBOL_UNIT)) {
        atomic stateRadio = PRE_TX_STATE;
        return SUCCESS;
      }
    }
    return FAIL;

  }
  
  /**
   * Delayed RXFIFO is used to read the receive FIFO of the CC2420
   * in task context after the uC receives an interrupt that a packet
   * is in the RXFIFO.  Task context is necessary since reading from
   * the FIFO may take a while and we'd like to get other interrupts
   * during that time, or notifications of additional packets received
   * and stored in the CC2420 RXFIFO.
   */
  void delayedRXFIFO();

  task void delayedRXFIFOtask() {
    delayedRXFIFO();
  }

  void delayedRXFIFO() {
    uint8_t len = MSG_DATA_SIZE;  
    uint8_t _bPacketReceiving;

    if ((!TOSH_READ_CC_FIFO_PIN()) && (!TOSH_READ_CC_FIFOP_PIN())) {
        flushRXFIFO();
	return;
    }

    atomic {
      _bPacketReceiving = bPacketReceiving;
      
      if (_bPacketReceiving) {
	if (!post delayedRXFIFOtask())
	  flushRXFIFO();
      } else {
	bPacketReceiving = TRUE;
      }
    }
    
    // JP NOTE: TODO: move readRXFIFO out of atomic context to permit
    // high frequency sampling applications and remove delays on
    // interrupts being processed.  There is a race condition
    // that has not yet been diagnosed when RXFIFO may be interrupted.
    if (!_bPacketReceiving) {
      if (!call HPLChipconFIFO.readRXFIFO(len,(uint8_t*)rxbufptr)) {
	atomic bPacketReceiving = FALSE;
	if (!post delayedRXFIFOtask()) {
	  flushRXFIFO();
	}
	return;
      }      
    }
    flushRXFIFO();
  }
  
  /**********************************************************
   * FIFOP lo Interrupt: Rx data avail in CC2420 fifo
   * Radio must have been in Rx mode to get this interrupt
   * If FIFO pin =lo then fifo overflow=> flush fifo & exit
   * 
   *
   * Things ToDo:
   *
   * -Disable FIFOP interrupt until PacketRcvd task complete 
   * until send.done complete
   *
   * -Fix mixup: on return
   *  rxbufptr->rssi is CRC + Correlation value
   *  rxbufptr->strength is RSSI
   **********************************************************/
   async event result_t FIFOP.fired() {

     //     call Leds.yellowToggle();

     // if we're trying to send a message and a FIFOP interrupt occurs
     // and acks are enabled, we need to backoff longer so that we don't
     // interfere with the ACK
     if (bAckEnable && (stateRadio == PRE_TX_STATE)) {
       if (call BackoffTimerJiffy.isSet()) {
         call BackoffTimerJiffy.stop();
         call BackoffTimerJiffy.setOneShot((signal MacBackoff.congestionBackoff(txbufptr) * CC2420_SYMBOL_UNIT) + CC2420_ACK_DELAY);
       }
     }

     /** Check for RXFIFO overflow **/     
     if (!TOSH_READ_CC_FIFO_PIN()){
       flushRXFIFO();
       return SUCCESS;
     }

     atomic {
	 if (post delayedRXFIFOtask()) {
	   call FIFOP.disable();

		// added by miklos maroti
		signal RadioReceiveCoordinator.byte(rxbufptr, 0);
	 }
	 else {
	   flushRXFIFO();
	 }
     }

     // return SUCCESS to keep FIFOP events occurring
     return SUCCESS;
  }

  /**
   * After the buffer is received from the RXFIFO,
   * process it, then post a task to signal it to the higher layers
   */
  async event result_t HPLChipconFIFO.RXFIFODone(uint8_t length, uint8_t *data) {
    // JP NOTE: rare known bug in high contention:
    // radio stack will receive a valid packet, but for some reason the
    // length field will be longer than normal.  The packet data will
    // be valid up to the correct length, and then will contain garbage
    // after the correct length.  There is no currently known fix.
    uint8_t currentstate;
    atomic { 
      currentstate = stateRadio;
    }

    // if a FIFO overflow occurs or if the data length is invalid, flush
    // the RXFIFO to get back to a normal state.
    if ((!TOSH_READ_CC_FIFO_PIN() && !TOSH_READ_CC_FIFOP_PIN()) 
        || (length == 0) || (length > MSG_DATA_SIZE)) {
      flushRXFIFO();
      atomic bPacketReceiving = FALSE;
      return SUCCESS;
    }

    rxbufptr = (TOS_MsgPtr)data;

    // check for an acknowledgement that passes the CRC check
    if (bAckEnable && (currentstate == POST_TX_STATE) &&
         ((rxbufptr->fcfhi & 0x07) == CC2420_DEF_FCF_TYPE_ACK) &&
         (rxbufptr->dsn == currentDSN) &&
         ((data[length-1] >> 7) == 1)) {
      atomic {
        txbufptr->ack = 1;
        txbufptr->strength = data[length-2];
        txbufptr->lqi = data[length-1] & 0x7F;
	/* MDW 12-Jul-05: Need to set the real radio state here... */
        stateRadio = POST_TX_ACK_STATE;
        bPacketReceiving = FALSE;
      }
      if (!post PacketSent())
	sendFailed();
      return SUCCESS;
    }

    // check for invalid packets
    // an invalid packet is a non-data packet with the wrong
    // addressing mode (FCFLO byte)
    if (((rxbufptr->fcfhi & 0x07) != CC2420_DEF_FCF_TYPE_DATA) ||
         (rxbufptr->fcflo != CC2420_DEF_FCF_LO)) {
      flushRXFIFO();
      atomic bPacketReceiving = FALSE;
      return SUCCESS;
    }

    rxbufptr->length = rxbufptr->length - MSG_HEADER_SIZE - MSG_FOOTER_SIZE;

    if (rxbufptr->length > TOSH_DATA_LENGTH) {
      flushRXFIFO();
      atomic bPacketReceiving = FALSE;
      return SUCCESS;
    }

    // adjust destination to the right byte order
    rxbufptr->addr = fromLSB16(rxbufptr->addr);
 
    // if the length is shorter, we have to move the CRC bytes
    rxbufptr->crc = data[length-1] >> 7;
    // put in RSSI
    rxbufptr->strength = data[length-2];
    // put in LQI
    rxbufptr->lqi = data[length-1] & 0x7F;

	// added by miklos maroti
	signal RadioReceiveCoordinator.byte(rxbufptr, 1);

    atomic {
      if (!post PacketRcvd()) {
	bPacketReceiving = FALSE;
      }
    }

    if ((!TOSH_READ_CC_FIFO_PIN()) && (!TOSH_READ_CC_FIFOP_PIN())) {
        flushRXFIFO();
	return SUCCESS;
    }

    if (!(TOSH_READ_CC_FIFOP_PIN())) {
      if (post delayedRXFIFOtask())
	return SUCCESS;
    }
    flushRXFIFO();
    //    call FIFOP.startWait(FALSE);

    return SUCCESS;
  }

  /**
   * Notification that the TXFIFO has been filled with the data from the packet
   * Next step is to try to send the packet
   */
  async event result_t HPLChipconFIFO.TXFIFODone(uint8_t length, uint8_t *data) { 
     tryToSend();
     return SUCCESS;
  }

  /** Enable link layer hardware acknowledgements **/
  async command void MacControl.enableAck() {
    atomic bAckEnable = TRUE;
    call CC2420Control.enableAddrDecode();
    call CC2420Control.enableAutoAck();
  }

  /** Disable link layer hardware acknowledgements **/
  async command void MacControl.disableAck() {
    atomic bAckEnable = FALSE;
    call CC2420Control.disableAddrDecode();
    call CC2420Control.disableAutoAck();
  }

  /**
   * How many basic time periods to back off.
   * Each basic time period consists of 20 symbols (16uS per symbol)
   */
  default async event int16_t MacBackoff.initialBackoff(TOS_MsgPtr m) {
    return (call Random.rand() & 0xF) + 1;
  }
  /**
   * How many symbols to back off when there is congestion 
   * (16uS per symbol * 20 symbols/block)
   */
  default async event int16_t MacBackoff.congestionBackoff(TOS_MsgPtr m) {
    return (call Random.rand() & 0x3F) + 1;
  }

// Default events for radio send/receive coordinators do nothing.
// Be very careful using these, you'll break the stack.
// The "byte()" event is never signalled because the CC2420 is a packet
// based radio.
default async event void RadioSendCoordinator.startSymbol(uint8_t bitsPerBlock, uint8_t offset, TOS_MsgPtr msgBuff) { }
default async event void RadioSendCoordinator.byte(TOS_MsgPtr msg, uint8_t byteCount) { }
default async event void RadioReceiveCoordinator.startSymbol(uint8_t bitsPerBlock, uint8_t offset, TOS_MsgPtr msgBuff) { }
default async event void RadioReceiveCoordinator.byte(TOS_MsgPtr msg, uint8_t byteCount) { }

}

Index: SysTimeStampingM.nc
===================================================================
RCS file: /cvsroot/tinyos/tinyos-1.x/contrib/vu/tos/lib/CC2420/SysTimeStampingM.nc,v
retrieving revision 1.3
retrieving revision 1.4
diff -C2 -d -r1.3 -r1.4
*** SysTimeStampingM.nc	17 Jun 2005 16:33:20 -0000	1.3
--- SysTimeStampingM.nc	27 Jun 2006 14:46:38 -0000	1.4
***************
*** 1,5 ****
  /*
   * @author: Brano Kusy, kusy at isis.vanderbilt.edu
!  * Date last modified: jan05
   *
   * provides timestamping on transmitting/receiving SFD interrupt,uses 
--- 1,6 ----
  /*
   * @author: Brano Kusy, kusy at isis.vanderbilt.edu
!  * @author: Miklos Maroti, mmaroti at gmail.com
!  * Date last modified: April 2006
   *
   * provides timestamping on transmitting/receiving SFD interrupt,uses 
***************
*** 27,118 ****
  implementation
  {
! 	// the offset of the time-stamp field in the message, 
! 	// or -1 if no stamp is necessariy.
! 	norace int8_t sendStampOffset = -1;
! 	uint32_t rcv_time;
! 	norace TOS_MsgPtr ptosMsg;
! 	
      enum{
          TX_FIFO_MSG_START = 10,
!         SEND_TIME_CORRECTION = 2,
      };
!         
  	async event void RadioSendCoordinator.startSymbol(uint8_t bitsPerBlock, uint8_t offset, TOS_MsgPtr msgBuff)
  	{
! 		uint32_t send_time;
! 		if (ptosMsg != 0 && ptosMsg != msgBuff)
! 			return; 
! 
! 		atomic send_time = call SysTime.getTime32()  - SEND_TIME_CORRECTION;
! 		call Leds.redToggle();
! 				
! 		if( sendStampOffset < 0 )
! 			return;
  
! 	    *(uint32_t*)((void*)msgBuff->data + sendStampOffset) += send_time;
  
! 		call HPLCC2420RAM.write(TX_FIFO_MSG_START + sendStampOffset, 4, (void*)msgBuff->data + sendStampOffset);
! 		sendStampOffset = -1;	
  	}
  
  	async event void RadioReceiveCoordinator.startSymbol(uint8_t bitsPerBlock, uint8_t offset, TOS_MsgPtr msgBuff)
  	{
! 			atomic rcv_time = call SysTime.getTime32();
  			call Leds.greenToggle();
  	}
  
! 	command uint32_t TimeStamping.getStamp()
  	{
! 	    uint32_t tmp;
! 	    atomic tmp=rcv_time;
! 		return tmp;
  	}
  
! 
!     //this needs to be called right after SendMsg.send() returned success, so 
!     //the code in addStamp() method runs before a task in the radio stack is 
!     //posted that writes to fifo -> which triggers coordinator event 
!     
!     //if a msg is     already being served by the radio, (sendStampOffset is 
!     //defined),     timestamping returns fail
! 
! 	command result_t TimeStamping.addStamp(int8_t offset)
  	{
! 		if(sendStampOffset<0 && 0 <= offset && offset <= TOSH_DATA_LENGTH-4 ){
! 			atomic sendStampOffset = offset;
! 			ptosMsg = 0;
! 			return SUCCESS;
! 		}
! 		else
! 			sendStampOffset = -1;
  		
! 		return FAIL;
  	}
  
! 	command result_t TimeStamping.addStamp2(TOS_MsgPtr msg, int8_t offset)
! 	{
! 		if(sendStampOffset<0 && 0 <= offset && offset <= TOSH_DATA_LENGTH-4 ){
! 			atomic sendStampOffset = offset;
! 			ptosMsg = msg;
! 			return SUCCESS;
! 		}
! 		else
! 			sendStampOffset = -1;
! 		
! 		return FAIL;
! 	}
! 
!     async event result_t HPLCC2420RAM.readDone(uint16_t addr, uint8_t length, uint8_t* buffer){
          return SUCCESS;
      }
      
!     async event result_t HPLCC2420RAM.writeDone(uint16_t addr, uint8_t length, uint8_t* buffer){
          return SUCCESS;
      }
-     async event void RadioSendCoordinator.byte(TOS_MsgPtr msg, uint8_t byteCount) { }
-     async event void RadioSendCoordinator.blockTimer() { }
  
!     async event void RadioReceiveCoordinator.byte(TOS_MsgPtr msg, uint8_t byteCount) { }
      async event void RadioReceiveCoordinator.blockTimer() { }
- 
  }
--- 28,133 ----
  implementation
  {
! 	int8_t sendStampOffset = -1;
! 	TOS_MsgPtr sendMsg;
! 
! 	uint32_t captureTime;
! 	uint32_t downloadTime;
! 	uint32_t receiveTime;
! 	TOS_MsgPtr receiveMsg;
! 
      enum{
          TX_FIFO_MSG_START = 10,
!         SEND_TIME_CORRECTION = 6,
      };
! 
! 	command result_t TimeStamping.addStamp2(TOS_MsgPtr msg, int8_t offset)
! 	{
! 		uint8_t ret = FAIL;
! 
! 		if( 0 <= offset && offset <= TOSH_DATA_LENGTH - 4  )
! 		{
! 			atomic
! 			{
! 				sendStampOffset = offset;
! 				sendMsg = msg;
! 				ret = SUCCESS;
! 			}
! 		}
! 
! 		return ret;
! 	}
! 
  	async event void RadioSendCoordinator.startSymbol(uint8_t bitsPerBlock, uint8_t offset, TOS_MsgPtr msgBuff)
  	{
! 		int8_t offsetCopy = -1;
  
! 		atomic
! 		{
! 			if( sendStampOffset >= 0 && msgBuff == sendMsg )
! 				offsetCopy = sendStampOffset;
! 			else
! 				offsetCopy = -1;
! 		}
  
! 		if( offsetCopy >= 0 )
! 		{
! 		    *(uint32_t*)((void*)msgBuff->data + offsetCopy) += call SysTime.getTime32();
! 		    call Leds.redToggle();
! 			call HPLCC2420RAM.write(TX_FIFO_MSG_START + offsetCopy, 4, (void*)msgBuff->data + offsetCopy);
! 
! 			atomic sendStampOffset = -1;
! 		}
  	}
  
  	async event void RadioReceiveCoordinator.startSymbol(uint8_t bitsPerBlock, uint8_t offset, TOS_MsgPtr msgBuff)
  	{
! 		atomic
! 		{
! 			captureTime = call SysTime.getTime32() + SEND_TIME_CORRECTION;
  			call Leds.greenToggle();
+ 		}
  	}
  
!     async event void RadioReceiveCoordinator.byte(TOS_MsgPtr msg, uint8_t byteCount)
  	{
! 		if( byteCount == 0 )	// fired when FIFOP is fired
! 		{
! 			atomic downloadTime = captureTime;
! 		}
! 		else					// fired when RXFIFODONE is fired
! 		{
! 			atomic
! 			{
! 				receiveTime = downloadTime;
! 				receiveMsg = msg;
! 			}
! 		}
  	}
  
! 	command uint32_t TimeStamping.getStamp2(TOS_MsgPtr msg)
  	{
! 		uint32_t time = 0;
  		
! 		atomic
! 		{
! 			if( receiveMsg == msg )
! 				time = receiveTime;
! 		}
! 
! 		return time;
  	}
  
!     async event result_t HPLCC2420RAM.readDone(uint16_t addr, uint8_t length, uint8_t* buffer)
! 	{
          return SUCCESS;
      }
      
!     async event result_t HPLCC2420RAM.writeDone(uint16_t addr, uint8_t length, uint8_t* buffer)
! 	{
          return SUCCESS;
      }
  
! 	async event void RadioSendCoordinator.byte(TOS_MsgPtr msg, uint8_t byteCount) { }
!     async event void RadioSendCoordinator.blockTimer() { }
      async event void RadioReceiveCoordinator.blockTimer() { }
  }

Index: TimeStampingC.nc
===================================================================
RCS file: /cvsroot/tinyos/tinyos-1.x/contrib/vu/tos/lib/CC2420/TimeStampingC.nc,v
retrieving revision 1.1
retrieving revision 1.2
diff -C2 -d -r1.1 -r1.2
*** TimeStampingC.nc	25 Feb 2006 01:47:12 -0000	1.1
--- TimeStampingC.nc	27 Jun 2006 14:46:38 -0000	1.2
***************
*** 1,5 ****
  /*
   * @author: Brano Kusy, kusy at isis.vanderbilt.edu
!  * Date last modified: jan05
   *
   * provides timestamping on transmitting/receiving SFD interrupt in CC2420.
--- 1,5 ----
  /*
   * @author: Brano Kusy, kusy at isis.vanderbilt.edu
!  * Date last modified: apr06
   *
   * provides timestamping on transmitting/receiving SFD interrupt in CC2420.
***************
*** 16,20 ****
  implementation
  {
!     components TimeStampingM, CC2420RadioM, NoLeds as LedsC, HPLCC2420M, MSP430TimerC,
      #ifdef TIMESYNC_SYSTIME
          LocalTimeMicroC as TimerC;
--- 16,20 ----
  implementation
  {
!     components TimeStampingM, CC2420RadioM, NoLeds as LedsC, HPLCC2420M, 
      #ifdef TIMESYNC_SYSTIME
          LocalTimeMicroC as TimerC;
***************
*** 30,33 ****
      TimeStampingM.Leds   -> LedsC;
      TimeStampingM.HPLCC2420RAM    -> HPLCC2420M;
-     TimeStampingM.Timer    -> MSP430TimerC.TimerB;
  }
--- 30,32 ----

Index: TimeStampingM.nc
===================================================================
RCS file: /cvsroot/tinyos/tinyos-1.x/contrib/vu/tos/lib/CC2420/TimeStampingM.nc,v
retrieving revision 1.1
retrieving revision 1.2
diff -C2 -d -r1.1 -r1.2
*** TimeStampingM.nc	25 Feb 2006 01:47:12 -0000	1.1
--- TimeStampingM.nc	27 Jun 2006 14:46:38 -0000	1.2
***************
*** 1,5 ****
  /*
   * @author: Brano Kusy, kusy at isis.vanderbilt.edu
!  * Date last modified: jan05
   *
   * provides timestamping on transmitting/receiving SFD interrupt.
--- 1,6 ----
  /*
   * @author: Brano Kusy, kusy at isis.vanderbilt.edu
!  * @author: Miklos Maroti, mmaroti at gmail.com
!  * Date last modified: April 2006
   *
   * provides timestamping on transmitting/receiving SFD interrupt.
***************
*** 21,25 ****
          interface Leds;
          interface HPLCC2420RAM;
-         interface MSP430Timer as Timer;
      }
  }
--- 22,25 ----
***************
*** 29,36 ****
      // the offset of the time-stamp field in the message, 
      // or -1 if no stamp is necessariy.
!     norace int8_t sendStampOffset = -1;
!     uint32_t rcv_time;
!  	norace TOS_MsgPtr pTxMsg = 0;
!  	norace TOS_MsgPtr pRxMsg = 0;
     
      enum{
--- 29,39 ----
      // the offset of the time-stamp field in the message, 
      // or -1 if no stamp is necessariy.
!     int8_t sendStampOffset = -1;
! 	TOS_MsgPtr sendMsg;
! 
! 	uint32_t captureTime;
! 	uint32_t downloadTime;
! 	uint32_t receiveTime;
! 	TOS_MsgPtr receiveMsg;
     
      enum{
***************
*** 39,136 ****
      };
          
      async event void RadioSendCoordinator.startSymbol(uint8_t bitsPerBlock, uint8_t offset, TOS_MsgPtr msgBuff)
      {
!         uint32_t send_time;
!         atomic {
!             send_time = call LocalTime.read() - SEND_TIME_CORRECTION;
!             msgBuff->time = call Timer.read() - msgBuff->time;
!         }
!         call Leds.redToggle();
!                 
!         if (pTxMsg != 0 && pTxMsg != msgBuff)
!             return; 
! 			
!         if( sendStampOffset < 0 )
!             return;
  
!         *(uint32_t*)((void*)msgBuff->data + sendStampOffset) += send_time;
  
!         call HPLCC2420RAM.write(TX_FIFO_MSG_START + sendStampOffset, 4, (void*)msgBuff->data + sendStampOffset);
!         sendStampOffset = -1;   
!     }
  
!     async event void RadioReceiveCoordinator.startSymbol(uint8_t bitsPerBlock, uint8_t offset, TOS_MsgPtr msgBuff)
!     {
!             atomic { 
!                 rcv_time = call LocalTime.read();
!                 msgBuff->time = call Timer.read() - msgBuff->time;
!             }
!             pRxMsg = msgBuff;
!             call Leds.greenToggle();
      }
  
!     command uint32_t TimeStamping.getStamp()
      {
!         uint32_t tmp;
!         atomic tmp=rcv_time;
!         return tmp;
      }
  
!     //this needs to be called right after SendMsg.send() returned success, so 
!     //the code in addStamp() method runs before a task in the radio stack is 
!     //posted that writes to fifo -> which triggers coordinator event 
!     
!     //if a msg is already being served by the radio, (sendStampOffset is 
!     //defined), timestamping returns fail
  
!     command result_t TimeStamping.addStamp(int8_t offset)
!     {
!         result_t tmp;
!         
!         atomic{
!             tmp = FAIL;
!             if(sendStampOffset<0 && 0 <= offset && offset <= TOSH_DATA_LENGTH-4 ){
!                 sendStampOffset = offset;
! 			    pTxMsg = 0;
!                 tmp = SUCCESS;
!             }
!             else
!                 sendStampOffset = -1;
!         }
!         
!         return tmp;
!     }
  
!     command result_t TimeStamping.addStamp2(TOS_MsgPtr msg, int8_t offset)
      {
-         result_t tmp;
-         
-         atomic{
-             tmp = FAIL;
-             if(sendStampOffset<0 && 0 <= offset && offset <= TOSH_DATA_LENGTH-4 ){
-                 atomic sendStampOffset = offset;
- 		    	pTxMsg = msg;
-                 tmp = SUCCESS;
-             }
-             else
-                 sendStampOffset = -1;
-         }
-         return tmp;
-     }
- 
-     async event result_t HPLCC2420RAM.readDone(uint16_t addr, uint8_t length, uint8_t* buffer){
          return SUCCESS;
      }
      
!     async event result_t HPLCC2420RAM.writeDone(uint16_t addr, uint8_t length, uint8_t* buffer){
          return SUCCESS;
      }
      async event void RadioSendCoordinator.byte(TOS_MsgPtr msg, uint8_t byteCount) { }
      async event void RadioSendCoordinator.blockTimer() { }
- 
-     async event void RadioReceiveCoordinator.byte(TOS_MsgPtr msg, uint8_t byteCount) { }
      async event void RadioReceiveCoordinator.blockTimer() { }
! 
!     async event void Timer.overflow() { }
! 
! }
--- 42,135 ----
      };
          
+     //this needs to be called right after SendMsg.send() returned success, so 
+     //the code in addStamp() method runs before a task in the radio stack is 
+     //posted that writes to fifo -> which triggers coordinator event 
+ 	command result_t TimeStamping.addStamp2(TOS_MsgPtr msg, int8_t offset)
+ 	{
+ 		uint8_t ret = FAIL;
+ 
+ 		if( 0 <= offset && offset <= TOSH_DATA_LENGTH - 4  )
+ 		{
+ 			atomic
+ 			{
+ 				sendStampOffset = offset;
+ 				sendMsg = msg;
+ 				ret = SUCCESS;
+ 			}
+ 		}
+ 
+ 		return ret;
+ 	}
+ 
      async event void RadioSendCoordinator.startSymbol(uint8_t bitsPerBlock, uint8_t offset, TOS_MsgPtr msgBuff)
      {
! 		int8_t offsetCopy = -1;
  
! 		atomic
! 		{
! 			if( sendStampOffset >= 0 && msgBuff == sendMsg )
! 				offsetCopy = sendStampOffset;
! 			else
! 				offsetCopy = -1;
! 		}
  
! 		if( offsetCopy >= 0 )
! 		{
! 		    *(uint32_t*)((void*)msgBuff->data + offsetCopy) += call LocalTime.read();
! 			call HPLCC2420RAM.write(TX_FIFO_MSG_START + offsetCopy, 4, (void*)msgBuff->data + offsetCopy);
  
! 			atomic sendStampOffset = -1;
! 		}
      }
  
!     async event void RadioReceiveCoordinator.startSymbol(uint8_t bitsPerBlock, uint8_t offset, TOS_MsgPtr msgBuff)
      {
! 		atomic
! 		{
! 			captureTime = call LocalTime.read() + SEND_TIME_CORRECTION;
! 		}
      }
  
!     async event void RadioReceiveCoordinator.byte(TOS_MsgPtr msg, uint8_t byteCount)
! 	{
! 		if( byteCount == 0 )	// fired when FIFOP is fired
! 		{
! 			atomic downloadTime = captureTime;
! 		}
! 		else					// fired when RXFIFODONE is fired
! 		{
! 			atomic
! 			{
! 				receiveTime = downloadTime;
! 				receiveMsg = msg;
! 			}
! 		}
! 	}
  
! 	command uint32_t TimeStamping.getStamp2(TOS_MsgPtr msg)
! 	{
! 		uint32_t time = 0;
! 		
! 		atomic
! 		{
! 			if( receiveMsg == msg )
! 				time = receiveTime;
! 		}
  
! 		return time;
! 	}
!     
!     async event result_t HPLCC2420RAM.readDone(uint16_t addr, uint8_t length, uint8_t* buffer)
      {
          return SUCCESS;
      }
      
!     async event result_t HPLCC2420RAM.writeDone(uint16_t addr, uint8_t length, uint8_t* buffer)
!     {
          return SUCCESS;
      }
+ 
      async event void RadioSendCoordinator.byte(TOS_MsgPtr msg, uint8_t byteCount) { }
      async event void RadioSendCoordinator.blockTimer() { }
      async event void RadioReceiveCoordinator.blockTimer() { }
!     }



More information about the Tinyos-contrib-commits mailing list