*/
#include "IEEE802154.h"
+#include "message.h"
+#include "AM.h"
-module CC2420ReceiveP {
+module CC2420ReceiveP @safe() {
provides interface Init;
provides interface StdControl;
uses interface CC2420Packet;
uses interface CC2420PacketBody;
uses interface CC2420Config;
-
+ uses interface PacketTimeStamp<T32khz,uint32_t>;
+
uses interface Leds;
}
SACK_HEADER_LENGTH = 7,
};
- uint16_t m_timestamp_queue[ TIMESTAMP_QUEUE_SIZE ];
-
+ uint32_t m_timestamp_queue[ TIMESTAMP_QUEUE_SIZE ];
+
uint8_t m_timestamp_head;
uint8_t m_timestamp_size;
norace uint8_t m_bytes_left;
- norace message_t* m_p_rx_buf;
+ norace message_t* ONE_NOK m_p_rx_buf;
message_t m_rx_buf;
void receive();
void waitForNextPacket();
void flush();
+ bool passesAddressCheck(message_t * ONE msg);
task void receiveDone_task();
reset_state();
m_state = S_STARTED;
atomic receivingPacket = FALSE;
+ /* Note:
+ We use the falling edge because the FIFOP polarity is reversed.
+ This is done in CC2420Power.startOscillator from CC2420ControlP.nc.
+ */
call InterruptFIFOP.enableFallingEdge();
}
return SUCCESS;
* Start frame delimiter signifies the beginning/end of a packet
* See the CC2420 datasheet for details.
*/
- async command void CC2420Receive.sfd( uint16_t time ) {
+ async command void CC2420Receive.sfd( uint32_t time ) {
if ( m_timestamp_size < TIMESTAMP_QUEUE_SIZE ) {
uint8_t tail = ( ( m_timestamp_head + m_timestamp_size ) %
TIMESTAMP_QUEUE_SIZE );
async event void RXFIFO.readDone( uint8_t* rx_buf, uint8_t rx_len,
error_t error ) {
cc2420_header_t* header = call CC2420PacketBody.getHeader( m_p_rx_buf );
- cc2420_metadata_t* metadata = call CC2420PacketBody.getMetadata( m_p_rx_buf );
- uint8_t* buf = (uint8_t*) header;
+ uint8_t tmpLen __DEPUTY_UNUSED__ = sizeof(message_t) - (offsetof(message_t, data) - sizeof(cc2420_header_t));
+ uint8_t* COUNT(tmpLen) buf = TCAST(uint8_t* COUNT(tmpLen), header);
rxFrameLength = buf[ 0 ];
switch( m_state ) {
call SpiResource.release();
}
- if ( m_timestamp_size ) {
- if ( rxFrameLength > 10 ) {
- metadata->time = m_timestamp_queue[ m_timestamp_head ];
+ //new packet is buffered up, or we don't have timestamp in fifo, or ack
+ if ( ( m_missed_packets && call FIFO.get() ) || !call FIFOP.get()
+ || !m_timestamp_size
+ || rxFrameLength <= 10) {
+ call PacketTimeStamp.clear(m_p_rx_buf);
+ }
+ else {
+ if (m_timestamp_size==1)
+ call PacketTimeStamp.set(m_p_rx_buf, m_timestamp_queue[ m_timestamp_head ]);
m_timestamp_head = ( m_timestamp_head + 1 ) % TIMESTAMP_QUEUE_SIZE;
m_timestamp_size--;
- }
- } else {
- metadata->time = 0xffff;
+
+ if (m_timestamp_size>0) {
+ call PacketTimeStamp.clear(m_p_rx_buf);
+ m_timestamp_head = 0;
+ m_timestamp_size = 0;
+ }
}
-
+
// We may have received an ack that should be processed by Transmit
// buf[rxFrameLength] >> 7 checks the CRC
if ( ( buf[ rxFrameLength ] >> 7 ) && rx_buf ) {
*/
task void receiveDone_task() {
cc2420_metadata_t* metadata = call CC2420PacketBody.getMetadata( m_p_rx_buf );
- uint8_t* buf = (uint8_t*) call CC2420PacketBody.getHeader( m_p_rx_buf );;
+ cc2420_header_t* header = call CC2420PacketBody.getHeader( m_p_rx_buf);
+ uint8_t length = header->length;
+ uint8_t tmpLen __DEPUTY_UNUSED__ = sizeof(message_t) - (offsetof(message_t, data) - sizeof(cc2420_header_t));
+ uint8_t* COUNT(tmpLen) buf = TCAST(uint8_t* COUNT(tmpLen), header);
+
+ metadata->crc = buf[ length ] >> 7;
+ metadata->lqi = buf[ length ] & 0x7f;
+ metadata->rssi = buf[ length - 1 ];
+
+ if (passesAddressCheck(m_p_rx_buf) && length >= CC2420_SIZE) {
+ m_p_rx_buf = signal Receive.receive( m_p_rx_buf, m_p_rx_buf->data,
+ length - CC2420_SIZE);
+ }
- metadata->crc = buf[ rxFrameLength ] >> 7;
- metadata->rssi = buf[ rxFrameLength - 1 ];
- metadata->lqi = buf[ rxFrameLength ] & 0x7f;
- m_p_rx_buf = signal Receive.receive( m_p_rx_buf, m_p_rx_buf->data,
- rxFrameLength );
-
atomic receivingPacket = FALSE;
waitForNextPacket();
}
}
atomic receivingPacket = FALSE;
+
+ /*
+ * The FIFOP pin here is high when there are 0 bytes in the RX FIFO
+ * and goes low as soon as there are bytes in the RX FIFO. The pin
+ * is inverted from what the datasheet says, and its threshold is 127.
+ * Whenever the FIFOP line goes low, as you can see from the interrupt
+ * handler elsewhere in this module, it means we received a new packet.
+ * If the line stays low without generating an interrupt, that means
+ * there's still more data to be received.
+ */
if ( ( m_missed_packets && call FIFO.get() ) || !call FIFOP.get() ) {
// A new packet is buffered up and ready to go
if ( m_missed_packets ) {
m_missed_packets = 0;
}
+ /**
+ * @return TRUE if the given message passes address recognition
+ */
+ bool passesAddressCheck(message_t *msg) {
+ cc2420_header_t *header = call CC2420PacketBody.getHeader( msg );
+
+ if(!(call CC2420Config.isAddressRecognitionEnabled())) {
+ return TRUE;
+ }
+
+ return (header->dest == call CC2420Config.getShortAddr()
+ || header->dest == AM_BROADCAST_ADDR);
+ }
}