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

📄 cc2420transmitp.nc

📁 Develop Zigbee network real-time Os
💻 NC
字号:
/* * Copyright (c) 2005-2006 Arch Rock Corporation * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * - Redistributions of source code must retain the above copyright *   notice, this list of conditions and the following disclaimer. * - Redistributions in binary form must reproduce the above copyright *   notice, this list of conditions and the following disclaimer in the *   documentation and/or other materials provided with the *   distribution. * - Neither the name of the Arch Rock Corporation nor the names of *   its contributors may be used to endorse or promote products derived *   from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE * ARCHED ROCK OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE *//** * @author Jonathan Hui <jhui@archrock.com> * @version $Revision: 1.1.2.14 $ $Date: 2006/08/15 11:59:08 $ */module CC2420TransmitP {  provides interface Init;  provides interface AsyncStdControl;  provides interface CC2420Transmit as Send;  provides interface CsmaBackoff;  provides interface RadioTimeStamping as TimeStamp;  uses interface Alarm<T32khz,uint32_t> as BackoffTimer;  uses interface GpioCapture as CaptureSFD;  uses interface GeneralIO as CCA;  uses interface GeneralIO as CSN;  uses interface GeneralIO as SFD;  uses interface Resource as SpiResource;  uses interface CC2420Fifo as TXFIFO;  // uses interface CC2420Ram as TXFIFO_RAM; // No such thing in cc2430  uses interface CC2420Register as TXCTRL;  uses interface CC2420Strobe as SNOP;  uses interface CC2420Strobe as STXON;  uses interface CC2420Strobe as STXONCCA;  uses interface CC2420Strobe as SFLUSHTX;  uses interface CC2420Receive;  uses interface Leds;}implementation {  typedef enum {    S_STOPPED,    S_STARTED,    S_LOAD,    S_SAMPLE_CCA,    S_BEGIN_TRANSMIT,    S_SFD,    S_EFD,    S_ACK_WAIT,    S_CANCEL,  } cc2420_transmit_state_t;  // This specifies how many jiffies the stack should wait after a  // TXACTIVE to receive an SFD interrupt before assuming something is  // wrong and aborting the send. There seems to be a condition  // on the micaZ where the SFD interrupt is never handled.  enum {    CC2420_ABORT_PERIOD = 320  };    norace message_t* m_msg;  norace bool m_cca;  norace uint8_t m_tx_power;  cc2420_transmit_state_t m_state = S_STOPPED;  bool m_receiving = FALSE;  uint16_t m_prev_time;  void loadTXFIFO();  void attemptSend();  cc2420_header_t* getHeader( message_t* msg ) {    return (cc2420_header_t*)( msg->data - sizeof( cc2420_header_t ) );  }  cc2420_metadata_t* getMetadata( message_t* msg ) {    return (cc2420_metadata_t*)msg->metadata;  }  void startBackoffTimer(uint16_t time) {    call BackoffTimer.start(time);  }  void stopBackoffTimer() {    call BackoffTimer.stop();  }  error_t acquireSpiResource() {    error_t error = call SpiResource.immediateRequest();    if ( error != SUCCESS )      call SpiResource.request();    return error;  }  error_t releaseSpiResource() {    return call SpiResource.release();  }  void signalDone( error_t err ) {    atomic m_state = S_STARTED;    signal Send.sendDone( m_msg, err );  }  command error_t Init.init() {    call CCA.makeInput();    call CSN.makeOutput();    call SFD.makeInput();    return SUCCESS;  }  async command error_t AsyncStdControl.start() {    atomic {      call CaptureSFD.captureRisingEdge();      m_state = S_STARTED;      m_receiving = FALSE;      m_tx_power = 0;    }    return SUCCESS;  }  async command error_t AsyncStdControl.stop() {    atomic {      m_state = S_STOPPED;      stopBackoffTimer();      call CaptureSFD.disable();    }    return SUCCESS;  }  error_t send( message_t* p_msg, bool cca ) {    atomic {      if ( m_state != S_STARTED )	return FAIL;      m_state = S_LOAD;      m_cca = cca;      m_msg = p_msg;    }    if ( acquireSpiResource() == SUCCESS )      loadTXFIFO();    return SUCCESS;  }  async command error_t Send.sendCCA( message_t* p_msg ) {    return send( p_msg, TRUE );  }  async command error_t Send.send( message_t* p_msg ) {    return send( p_msg, FALSE );  }  error_t resend( bool cca ) {    atomic {      if ( m_state != S_STARTED )	return FAIL;      m_cca = cca;      m_state = cca ? S_SAMPLE_CCA : S_BEGIN_TRANSMIT;    }    if ( m_cca ) {      startBackoffTimer( signal CsmaBackoff.initial( m_msg ) * 			       CC2420_BACKOFF_PERIOD );    }    else if ( acquireSpiResource() == SUCCESS ) {      attemptSend();    }        return SUCCESS;    }    async command error_t Send.resendCCA() {    return resend( TRUE );  }  async command error_t Send.resend() {    return resend( FALSE );  }  async command error_t Send.cancel() {    stopBackoffTimer();    atomic {      switch( m_state ) {      case S_LOAD:	m_state = S_CANCEL;	break;      case S_SAMPLE_CCA: case S_BEGIN_TRANSMIT:	m_state = S_STARTED;	break;      default:	// cancel not allowed while radio is busy transmitting	return FAIL;      }    }    return SUCCESS;  }  void loadTXFIFO() {    cc2420_header_t* header = getHeader( m_msg );    uint8_t tx_power = getMetadata( m_msg )->tx_power;    if ( !tx_power )      tx_power = CC2420_DEF_RFPOWER;    call CSN.clr();    if ( m_tx_power != tx_power )      call TXCTRL.write( ( 2 << CC2420_TXCTRL_TXMIXBUF_CUR ) |			 ( 3 << CC2420_TXCTRL_PA_CURRENT ) |			 ( 1 << CC2420_TXCTRL_RESERVED ) |			 ( tx_power << CC2420_TXCTRL_PA_LEVEL ) );    m_tx_power = tx_power;    call TXFIFO.write( (uint8_t*)header, header->length - 1 );  }    async event void TXFIFO.writeDone( uint8_t* tx_buf, uint8_t tx_len,				     error_t error ) {    call CSN.set();    if ( m_state == S_CANCEL ) {      m_state = S_STARTED;    }    else if ( !m_cca ) {      m_state = S_BEGIN_TRANSMIT;      attemptSend();    }    else {      releaseSpiResource();      m_state = S_SAMPLE_CCA;      startBackoffTimer( signal CsmaBackoff.initial( m_msg ) * 			 CC2420_BACKOFF_PERIOD );    }  }  void congestionBackoff() {    atomic {      uint16_t time = signal CsmaBackoff.congestion( m_msg );      if ( time )	startBackoffTimer( time * CC2420_BACKOFF_PERIOD );      else	m_state = S_STARTED;    }  }  async event void BackoffTimer.fired() {    atomic {      switch( m_state ) {	      case S_SAMPLE_CCA :	// sample CCA and wait a little longer if free, just in case we	// sampled during the ack turn-around window	if ( call CCA.get() ) {	  m_state = S_BEGIN_TRANSMIT;	  startBackoffTimer( CC2420_TIME_ACK_TURNAROUND );	}	else {	  congestionBackoff();	}	break;	      case S_BEGIN_TRANSMIT :	if ( acquireSpiResource() == SUCCESS )	  attemptSend();	break;	      case S_ACK_WAIT :	signalDone( SUCCESS );	break;	#ifdef PLATFORM_MICAZ      case S_SFD:	// We didn't receive an SFD interrupt within CC2420_ABORT_PERIOD	// jiffies. Assume something is wrong.	call SFLUSHTX.strobe();	call CaptureSFD.disable();	call CaptureSFD.captureRisingEdge();	signalDone( ERETRY );	break;#endif      default:	break;      }    }  }    void attemptSend() {    uint8_t status;    bool congestion = TRUE;    call CSN.clr();    status = m_cca ? call STXONCCA.strobe() : call STXON.strobe();    if ( !( status & CC2420_STATUS_TX_ACTIVE ) ) {      status = call SNOP.strobe();      if ( status & CC2420_STATUS_TX_ACTIVE )	congestion = FALSE;    }    atomic m_state = congestion ? S_SAMPLE_CCA : S_SFD;        call CSN.set();    if ( congestion ) {      releaseSpiResource();      congestionBackoff();    }#ifdef PLATFORM_MICAZ    else {      startBackoffTimer(CC2420_ABORT_PERIOD);    }#endif  }  async command error_t Send.modify( uint8_t offset, uint8_t* buf, 				     uint8_t len ) {    //call CSN.clr();    //call TXFIFO_RAM.write( offset, buf, len );    //call CSN.set();    return FAIL;  }  async event void CaptureSFD.captured( uint16_t time ) {    atomic {      switch( m_state ) {	      case S_SFD:	call CaptureSFD.captureFallingEdge();	signal TimeStamp.transmittedSFD( time, m_msg );	releaseSpiResource();	stopBackoffTimer();	m_state = S_EFD;	if ( ( ( getHeader( m_msg )->fcf >> IEEE154_FCF_FRAME_TYPE ) & 7 ) == 	     IEEE154_TYPE_DATA )	  getMetadata( m_msg )->time = time;	if ( call SFD.get() )	  break;	      case S_EFD:	call CaptureSFD.captureRisingEdge();	if ( getHeader( m_msg )->fcf & ( 1 << IEEE154_FCF_ACK_REQ ) ) {	  m_state = S_ACK_WAIT;	  startBackoffTimer( CC2420_ACK_WAIT_DELAY );	}	else {	  signalDone(SUCCESS);	}	if ( !call SFD.get() )	  break;	      default:	if ( !m_receiving ) {	  call CaptureSFD.captureFallingEdge();	  signal TimeStamp.receivedSFD( time );	  call CC2420Receive.sfd( time );	  m_receiving = TRUE;	  m_prev_time = time;	  if ( call SFD.get() )	    return;	}	if ( m_receiving ) {	  call CaptureSFD.captureRisingEdge();	  m_receiving = FALSE;	  if ( time - m_prev_time < 10 )	    call CC2420Receive.sfd_dropped();	}	break;            }    }  }  async event void CC2420Receive.receive( uint8_t type, message_t* ack_msg ) {    if ( type == IEEE154_TYPE_ACK ) {      cc2420_header_t* ack_header = getHeader( ack_msg );      cc2420_header_t* msg_header = getHeader( m_msg );      cc2420_metadata_t* msg_metadata = getMetadata( m_msg );      uint8_t* ack_buf = (uint8_t*)ack_header;      uint8_t length = ack_header->length;            if ( m_state == S_ACK_WAIT &&	   msg_header->dsn == ack_header->dsn ) {	stopBackoffTimer();	msg_metadata->ack = TRUE;	msg_metadata->rssi = ack_buf[ length - 1 ];	msg_metadata->lqi = ack_buf[ length ] & 0x7f;	signalDone(SUCCESS);      }    }  }  event void SpiResource.granted() {    uint8_t cur_state;    atomic {      cur_state = m_state;    }    switch( cur_state ) {    case S_LOAD: loadTXFIFO(); break;    case S_BEGIN_TRANSMIT: attemptSend(); break;    default: releaseSpiResource(); break;    }  }  async event void TXFIFO.readDone( uint8_t* tx_buf, uint8_t tx_len, error_t error ) {}  default async event void TimeStamp.transmittedSFD( uint16_t time, message_t* p_msg ) {}  default async event void TimeStamp.receivedSFD( uint16_t time ) {}}

⌨️ 快捷键说明

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