📄 cc2420receivep.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>
* @author David Moss
* @author Jung Il Choi
* @author Jan Hauer <hauer@tkn.tu-berlin.de>
* @version $Revision: 1.4 $ $Date: 2009/05/05 16:56:49 $
*/
module CC2420ReceiveP {
provides interface Init;
provides interface CC2420AsyncSplitControl as AsyncSplitControl;
provides interface CC2420Receive;
provides interface CC2420Rx;
uses interface GeneralIO as CSN;
uses interface GeneralIO as FIFO;
uses interface GeneralIO as FIFOP;
uses interface GpioInterrupt as InterruptFIFOP;
uses interface Resource as SpiResource;
uses interface CC2420Fifo as RXFIFO;
uses interface CC2420Strobe as SACK;
uses interface CC2420Strobe as SFLUSHRX;
uses interface CC2420Strobe as SRXON;
uses interface CC2420Strobe as SACKPEND;
uses interface CC2420Register as MDMCTRL1;
uses interface ReferenceTime;
uses interface FrameUtility;
uses interface CC2420Config;
uses interface CC2420Ram as RXFIFO_RAM;
}
implementation {
typedef enum {
S_STOPPED,
S_STARTING,
S_STARTED,
S_RX_LENGTH,
S_RX_FCF,
S_RX_HEADER,
S_RX_PAYLOAD,
} cc2420_receive_state_t;
enum {
RXFIFO_SIZE = 128,
TIMESTAMP_QUEUE_SIZE = 8,
//SACK_HEADER_LENGTH = 7,
SACK_HEADER_LENGTH = 3,
};
ieee154_timestamp_t m_timestamp_queue[ TIMESTAMP_QUEUE_SIZE ];
ieee154_timestamp_t m_timestamp;
norace bool m_timestampValid;
uint8_t m_timestamp_head;
uint8_t m_timestamp_size;
/** Number of packets we missed because we were doing something else */
uint8_t m_missed_packets;
/** TRUE if we are receiving a valid packet into the stack */
norace bool receivingPacket;
/** The length of the frame we're currently receiving */
norace uint8_t rxFrameLength;
norace uint8_t m_bytes_left;
// norace message_t* m_p_rx_buf;
// message_t m_rx_buf;
cc2420_receive_state_t m_state;
// new packet format:
message_t m_frame;
norace message_t *m_rxFramePtr;
norace uint8_t m_mhrLen;
uint8_t m_dummy;
norace bool m_stop;
/***************** Prototypes ****************/
void reset_state();
void beginReceive();
void receive();
void waitForNextPacket();
void flush();
void switchToUnbufferedMode();
void switchToBufferedMode();
void continueStart();
void continueStop();
task void stopContinueTask();
task void receiveDone_task();
/***************** Init Commands ****************/
command error_t Init.init() {
m_rxFramePtr = &m_frame;
atomic m_state = S_STOPPED;
return SUCCESS;
}
/***************** AsyncSplitControl ****************/
/* NOTE: AsyncSplitControl does not switch the state of the radio
* hardware (i.e. it does not put the radio in Rx mode, this has to
* be done by the caller through a separate interface/component).
*/
/**
* AsyncSplitControl.start should be called before radio
* is switched to Rx mode (or at least early enough before
* a packet has been received, i.e. before FIFOP changes)
*/
async command error_t AsyncSplitControl.start()
{
atomic {
if ( !call FIFO.get() && !call FIFOP.get() ){
// RXFIFO has some data (remember: FIFOP is inverted)
// the problem is that this messses up the timestamping
// so why don't we flush here ourselves?
// because we don't own the SPI...
return FAIL;
}
ASSERT(m_state == S_STOPPED);
reset_state();
m_state = S_STARTED;
call InterruptFIFOP.enableFallingEdge(); // ready!
}
return SUCCESS;
}
/* AsyncSplitControl.stop:
*
* IMPORTANT: when AsyncSplitControl.stop is called,
* then either
* 1) the radio MUST still be in RxMode
* 2) it was never put in RxMode after
* AsyncSplitControl.start() was called
*
* => The radio may be switched off only *after* the
* stopDone() event was signalled.
*/
async command error_t AsyncSplitControl.stop()
{
atomic {
if (m_state == S_STOPPED)
return EALREADY;
else {
m_stop = TRUE;
call InterruptFIFOP.disable();
if (!receivingPacket)
continueStop(); // it is safe to stop now
// else continueStop will be called after
// current Rx operation is finished
}
}
return SUCCESS;
}
void continueStop()
{
atomic {
if (!m_stop){
return;
}
m_stop = FALSE;
m_state = S_STOPPED;
}
post stopContinueTask();
}
task void stopContinueTask()
{
ASSERT(receivingPacket != TRUE);
call SpiResource.release(); // may fail
atomic m_state = S_STOPPED;
signal AsyncSplitControl.stopDone(SUCCESS);
}
/***************** CC2420Receive Commands ****************/
/**
* Start frame delimiter signifies the beginning/end of a packet
* See the CC2420 datasheet for details.
*/
async command void CC2420Receive.sfd( ieee154_timestamp_t *time ) {
if (m_state == S_STOPPED)
return;
if ( m_timestamp_size < TIMESTAMP_QUEUE_SIZE ) {
uint8_t tail = ( ( m_timestamp_head + m_timestamp_size ) %
TIMESTAMP_QUEUE_SIZE );
memcpy(&m_timestamp_queue[ tail ], time, sizeof(ieee154_timestamp_t) );
m_timestamp_size++;
}
}
async command void CC2420Receive.sfd_dropped() {
if (m_state == S_STOPPED)
return;
if ( m_timestamp_size ) {
m_timestamp_size--;
}
}
/***************** InterruptFIFOP Events ****************/
async event void InterruptFIFOP.fired() {
atomic {
if ( m_state == S_STARTED ) {
beginReceive();
} else {
m_missed_packets++;
}
}
}
/***************** SpiResource Events ****************/
event void SpiResource.granted() {
atomic {
switch (m_state)
{
case S_STOPPED: ASSERT(0); break; // this should never happen!
default: receive();
}
}
}
/***************** RXFIFO Events ****************/
/**
* We received some bytes from the SPI bus. Process them in the context
* of the state we're in. Remember the length byte is not part of the length
*/
async event void RXFIFO.readDone( uint8_t* rx_buf, uint8_t rx_len,
error_t error ) {
uint8_t* buf;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -