📄 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
* @version $Revision: 1.2 $ $Date: 2009/09/18 16:35:40 $
*/
#include "printfUART.h"
#include "frame_format.h"
#include "mac_func.h"
module CC2420ReceiveP {
provides interface Init;
provides interface StdControl;
//provides interface CC2420Receive;
//provides interface Receive;
//provides interface ReceiveIndicator as PacketIndicator;
provides interface Receiveframe;
provides interface AddressFilter;
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 CC2420Packet;
//uses interface CC2420PacketBody;
uses interface CC2420Config;
uses interface Leds;
}
implementation {
typedef enum{
S_STOPPED =0,
S_STARTED=1,
S_RX_LENGTH=2,
S_RX_FC=3, //FC - FRAME CONTROL
S_RX_ADDR=4,
S_RX_PAYLOAD=5,
S_RX_DISCARD=6,
}cc2420_receive_state_t;
/*
typedef enum {
S_STOPPED,
S_STARTED,
S_RX_LENGTH,
S_RX_FCF,
S_RX_PAYLOAD,
} cc2420_receive_state_t;
*/
enum {
RXFIFO_SIZE = 128,
TIMESTAMP_QUEUE_SIZE = 8,
SACK_HEADER_LENGTH = 7,
};
//uint16_t m_timestamp_queue[ TIMESTAMP_QUEUE_SIZE ];
//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 */
bool receivingPacket;
/** The length of the frame we're currently receiving */
norace uint8_t rxFrameLength;
//number of bytes left in the FIFO Buffer
norace uint8_t m_bytes_left;
//norace message_t* m_p_rx_buf;
//message_t m_rx_buf;
//already used
//cc2420_receive_state_t m_state;
norace MPDU rxmpdu;
MPDU *rxmpdu_ptr;
cc2420_receive_state_t m_state;
uint8_t rssi;
uint8_t receive_count=0;
/*******************************************/
/**** ADDRESS DECODE VARIABLES ****/
/*******************************************/
//address verification frame control variables
//frame control variables
uint8_t source_address=0;
uint8_t destination_address=0;
//address verification structure pointers
dest_short *dest_short_ptr;
dest_long *dest_long_ptr;
source_short *source_short_ptr;
source_long *source_long_ptr;
beacon_addr_short *beacon_addr_short_ptr;
uint8_t address_decode = 1;
//address verification variables
uint16_t ver_macCoordShortAddress = 0x0000;
uint16_t ver_macShortAddress = 0xffff;
uint32_t ver_aExtendedAddress0=0x00000000;
uint32_t ver_aExtendedAddress1=0x00000000;
uint16_t ver_macPANId=0xffff;
/***************** Prototypes ****************/
void reset_state();
void beginReceive();
void receive();
void waitForNextPacket();
void flush();
// task void receiveDone_task();
/***************** Init Commands ****************/
command error_t Init.init() {
//m_p_rx_buf = &m_rx_buf;
rxmpdu_ptr = &rxmpdu;
printfUART_init();
return SUCCESS;
}
/***************** StdControl ****************/
command error_t StdControl.start() {
atomic {
reset_state();
m_state = S_STARTED;
atomic receivingPacket = FALSE;
call InterruptFIFOP.enableFallingEdge();
}
return SUCCESS;
}
command error_t StdControl.stop() {
atomic {
m_state = S_STOPPED;
reset_state();
call CSN.set();
call InterruptFIFOP.disable();
}
return SUCCESS;
}
command error_t AddressFilter.set_address(uint16_t mac_short_address, uint32_t mac_extended0, uint32_t mac_extended1)
{
ver_macShortAddress = mac_short_address;
ver_aExtendedAddress0=mac_extended0;
ver_aExtendedAddress1=mac_extended1;
address_decode = 1;
//printfUART("sa %i %x %x %x %x\n",address_decode,ver_macShortAddress,ver_aExtendedAddress0,ver_aExtendedAddress1);
return SUCCESS;
}
command error_t AddressFilter.set_coord_address(uint16_t mac_coord_address, uint16_t mac_panid)
{
ver_macCoordShortAddress = mac_coord_address;
ver_macPANId = mac_panid;
//printfUART("sca %i %x %x\n",address_decode,ver_macCoordShortAddress,ver_macPANId);
return SUCCESS;
}
command error_t AddressFilter.enable_address_decode(uint8_t enable)
{
address_decode = enable;
//printfUART("ead %i\n",address_decode);
return SUCCESS;
}
/***************** Receive Commands ****************/
/*
command void* Receive.getPayload(message_t* m, uint8_t* len) {
if (len != NULL) {
*len = ((uint8_t*) (call CC2420PacketBody.getHeader( m_p_rx_buf )))[0];
}
return m->data;
}
command uint8_t Receive.payloadLength(message_t* m) {
uint8_t* buf = (uint8_t*)(call CC2420PacketBody.getHeader( m_p_rx_buf ));
return buf[0];
}
*/
/***************** CC2420Receive Commands ****************/
/**
* Start frame delimiter signifies the beginning/end of a packet
* See the CC2420 datasheet for details.
*/
/*
async command void CC2420Receive.sfd( uint16_t time ) {
if ( m_timestamp_size < TIMESTAMP_QUEUE_SIZE ) {
uint8_t tail = ( ( m_timestamp_head + m_timestamp_size ) %
TIMESTAMP_QUEUE_SIZE );
m_timestamp_queue[ tail ] = time;
m_timestamp_size++;
}
}
async command void CC2420Receive.sfd_dropped() {
if ( m_timestamp_size ) {
m_timestamp_size--;
}
}
*/
/***************** PacketIndicator Commands ****************/
/*
command bool PacketIndicator.isReceiving() {
bool receiving;
atomic {
receiving = receivingPacket;
}
return receiving;
}
*/
/***************** InterruptFIFOP Events ****************/
async event void InterruptFIFOP.fired() {
////printfUART("Int %i\n",m_state);
//call Leds.led1Toggle();
//call Leds.led2Toggle();
if ( m_state == S_STARTED ) {
beginReceive();
/*
if(call SpiResource.isOwner()) {
receive();
} else if (call SpiResource.immediateRequest() == SUCCESS) {
receive();
} else {
call SpiResource.request();
}
*/
} else {
m_missed_packets++;
}
}
/***************** SpiResource Events ****************/
event void SpiResource.granted() {
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 ) {
//int i;
/*
uint8_t len;
//uint8_t rssi;
//uint8_t lqi;
int i;
len = rx_buf[0];
rssi= 255 - rx_buf[len-1];
//lqi = rssi & 0x7f;
*/
/*
//printfUART("r d %i %i\n", len, rssi);
// len = rx_buf[0];
//rssi=rx_buf[len-2];
for (i=0;i<40;i++)
{
//printfUART("r %i %x\n",i,rx_buf[i]);
}
//signal Receiveframe.receive((uint8_t*)rxmpdu_ptr, rssi);
receive_count++;
if (receive_count == 2)
{ flush();
receive_count =0;
}
*/
atomic{
//my code
switch(m_state){
case S_RX_LENGTH:
rxFrameLength = rx_buf[0];
m_state = S_RX_FC;
//verify print
////printfUART("LEN %x %x %i %i\n",rxFrameLength,rxmpdu_ptr->length,m_state,m_bytes_left);
//printfUART("r%i %i %i\n",rxmpdu_ptr->seq_num,rxFrameLength,MAC_PACKET_SIZE);
if ( rxFrameLength + 1 > m_bytes_left )
{
// Length of this packet is bigger than the RXFIFO, flush it out.
//printfUART("pkt too big\n","");
flush();
}
else
{
if ( !call FIFO.get() && !call FIFOP.get() )
{
//printfUART("RED left %x\n",m_bytes_left);
m_bytes_left -= rxFrameLength + 1;
}
//if(rxFrameLength <= MAC_PACKET_SIZE)
//{
if(rxFrameLength > 0)
{
//verify read length and read the frame control field (2 bytes)
if(rxFrameLength > 2) {
// This packet has an FCF byte plus at least one more byte to read
//call RXFIFO.continueRead(buf + 1, SACK_HEADER_LENGTH);
////printfUART("LEN OK\n","");
//read frame control + sequence number
call RXFIFO.continueRead((uint8_t*)rxmpdu_ptr + 1, 3);
}
else
{
// This is really a bad packet, skip FCF and get it out of here.
//m_state = S_RX_PAYLOAD;
m_state = S_RX_DISCARD;
//printfUART("bad len\n","");
call RXFIFO.continueRead((uint8_t*)rxmpdu_ptr + 1, rxFrameLength);
return;
}
}
else
{
// Length == 0; start reading the next packet
atomic receivingPacket = FALSE;
call CSN.set();
call SpiResource.release();
waitForNextPacket();
}
//}
//else
//{
// Length is too large; we have to flush the entire Rx FIFO
// //printfUART("pkt too large\n","");
// flush();
// return;
//}
}
break;
case S_RX_FC:
//verify print
////printfUART("FC %x %x %x %i\n",rxmpdu_ptr->frame_control1,rxmpdu_ptr->frame_control2,rxmpdu_ptr->seq_num, m_state);
if ((rxmpdu_ptr->frame_control1 & 0x7) == TYPE_ACK)
{
m_state = S_RX_PAYLOAD;
//printfUART("r ack \n","");
call RXFIFO.continueRead((uint8_t*)rxmpdu_ptr+4,2);
return;
}
if (address_decode == 1)
{
m_state = S_RX_ADDR;
destination_address=get_fc2_dest_addr(rxmpdu_ptr->frame_control2);
if (destination_address > 1)
{
switch(destination_address)
{
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -