From aa7578fd1472c62c1d22d0801fe0f55b36093bdf Mon Sep 17 00:00:00 2001 From: "R. Steve McKown" Date: Fri, 13 Nov 2009 16:47:49 -0700 Subject: [PATCH] Upstream commits to tos/chips/cc2420, Aug 7 2008 thru Jul 16 2009, except one. commit df004818be0944a5459b2d23dd4b49c55b716448 kusy Thu Aug 7 00:06:53 2008 +0000 Previously reported timestamping bug was only fixed partially: *timesync... NOT COMMITTED f8120ec47efebf578a6edf99882d009ea6dedcd1 kusy Wed Aug 13 07:37:05 2008 +0000 Fixing T32khz to TMilli conversion - coeficient 32 needs to be... commit 42b450d2e6d5eda17245d38f4d2bceb6b60e5400 rincon Mon Aug 18 22:04:15 2008 +0000 Added a length check to make sure we don't try to send a packet that is... commit 62d558a6db9cf823c7926fc74ed5610a0dcbad23 rincon Fri Sep 5 20:39:00 2008 +0000 added more descriptive comments about the header commit 72c8a4f1a2b4f331aeedc6bfd5262253ce8d6d04 janhauer Wed Nov 26 10:13:31 2008 +0000 Added an interface for accessing the RXFIFO in a non-split phase... commit 10c02f9ece9b5ee20aa93c877d70fa6689ef7a7d razvanm Mon Dec 1 19:56:53 2008 +0000 Remove a redundant definition. commit 979965da13886883fe7399d60ff4d025f53bfd4c razvanm Mon Dec 1 23:51:38 2008 +0000 Add a comment about the polarity of FIFOP. commit 98d4eae39755d369b001971ec9c5f1dd741bc82d andreaskoepke Wed Dec 17 17:42:22 2008 +0000 avoid integer overflow commit 31bef23ef3377514af595000d2fa2cce07bd4531 kusy Fri Feb 6 06:38:49 2009 +0000 committing new timestamping code commit 9be3c9111199378d00acd0d946a0c1772947165a kusy Mon Mar 2 07:02:32 2009 +0000 timestamping patch: improved test to fall-through on SFD commit cd6c99ffa038524d2532860acb79e3ba52540ad7 kusy Thu Jul 16 06:41:41 2009 +0000 Using AMSenderC infrastructure to fix CTP+FTSP bug commit fbde8e8b590651b32583d9250bb4921d5b6ab1a3 kusy Thu Jul 16 06:46:07 2009 +0000 thomas's FTSP patch --- tos/chips/cc2420/CC2420.h | 39 +++++++++++- tos/chips/cc2420/CC2420ActiveMessageP.nc | 5 ++ tos/chips/cc2420/CC2420TimeSyncMessageC.nc | 7 ++- tos/chips/cc2420/CC2420TimeSyncMessageP.nc | 16 +++-- tos/chips/cc2420/csma/CC2420CsmaP.nc | 3 +- tos/chips/cc2420/lpl/DefaultLplP.nc | 4 +- tos/chips/cc2420/receive/CC2420ReceiveP.nc | 27 ++++++--- tos/chips/cc2420/spi/CC2420SpiC.nc | 2 + tos/chips/cc2420/transmit/CC2420TransmitP.nc | 64 ++++++++++++-------- 9 files changed, 121 insertions(+), 46 deletions(-) diff --git a/tos/chips/cc2420/CC2420.h b/tos/chips/cc2420/CC2420.h index 1d607b92..798107f0 100644 --- a/tos/chips/cc2420/CC2420.h +++ b/tos/chips/cc2420/CC2420.h @@ -43,8 +43,43 @@ typedef uint8_t cc2420_status_t; #endif /** - * CC2420 header. An I-frame (interoperability frame) header has an - * extra network byte specified by 6LowPAN + * CC2420 header definition. + * + * An I-frame (interoperability frame) header has an extra network + * byte specified by 6LowPAN + * + * Length = length of the header + payload of the packet, minus the size + * of the length byte itself (1). This is what allows for variable + * length packets. + * + * FCF = Frame Control Field, defined in the 802.15.4 specs and the + * CC2420 datasheet. + * + * DSN = Data Sequence Number, a number incremented for each packet sent + * by a particular node. This is used in acknowledging that packet, + * and also filtering out duplicate packets. + * + * DestPan = The destination PAN (personal area network) ID, so your + * network can sit side by side with another TinyOS network and not + * interfere. + * + * Dest = The destination address of this packet. 0xFFFF is the broadcast + * address. + * + * Src = The local node ID that generated the message. + * + * Network = The TinyOS network ID, for interoperability with other types + * of 802.15.4 networks. + * + * Type = TinyOS AM type. When you create a new AMSenderC(AM_MYMSG), + * the AM_MYMSG definition is the type of packet. + * + * TOSH_DATA_LENGTH defaults to 28, it represents the maximum size of + * the payload portion of the packet, and is specified in the + * tos/types/message.h file. + * + * All of these fields will be filled in automatically by the radio stack + * when you attempt to send a message. */ typedef nx_struct cc2420_header_t { nxle_uint8_t length; diff --git a/tos/chips/cc2420/CC2420ActiveMessageP.nc b/tos/chips/cc2420/CC2420ActiveMessageP.nc index be409637..0db2423c 100644 --- a/tos/chips/cc2420/CC2420ActiveMessageP.nc +++ b/tos/chips/cc2420/CC2420ActiveMessageP.nc @@ -62,6 +62,11 @@ implementation { message_t* msg, uint8_t len) { cc2420_header_t* header = call CC2420PacketBody.getHeader( msg ); + + if (len > call Packet.maxPayloadLength()) { + return ESIZE; + } + header->type = id; header->dest = addr; header->destpan = call CC2420Config.getPanAddr(); diff --git a/tos/chips/cc2420/CC2420TimeSyncMessageC.nc b/tos/chips/cc2420/CC2420TimeSyncMessageC.nc index 745bd08e..94ed0c9a 100644 --- a/tos/chips/cc2420/CC2420TimeSyncMessageC.nc +++ b/tos/chips/cc2420/CC2420TimeSyncMessageC.nc @@ -60,8 +60,11 @@ implementation TimeSyncPacketMilli = CC2420TimeSyncMessageP; Packet = CC2420TimeSyncMessageP; - CC2420TimeSyncMessageP.SubSend -> CC2420ActiveMessageC.AMSend; - CC2420TimeSyncMessageP.SubPacket -> CC2420ActiveMessageC.Packet; + // use the AMSenderC infrastructure to avoid concurrent send clashes + components AMQueueP, ActiveMessageC; + CC2420TimeSyncMessageP.SubSend -> AMQueueP.Send[unique(UQ_AMQUEUE_SEND)]; + CC2420TimeSyncMessageP.AMPacket -> ActiveMessageC; + CC2420TimeSyncMessageP.SubPacket -> ActiveMessageC; CC2420TimeSyncMessageP.PacketTimeStamp32khz -> CC2420PacketC; CC2420TimeSyncMessageP.PacketTimeStampMilli -> CC2420PacketC; diff --git a/tos/chips/cc2420/CC2420TimeSyncMessageP.nc b/tos/chips/cc2420/CC2420TimeSyncMessageP.nc index a4e11573..70e677ae 100644 --- a/tos/chips/cc2420/CC2420TimeSyncMessageP.nc +++ b/tos/chips/cc2420/CC2420TimeSyncMessageP.nc @@ -37,7 +37,8 @@ module CC2420TimeSyncMessageP uses { - interface AMSend as SubSend[uint8_t id]; + interface Send as SubSend; + interface AMPacket; interface Packet as SubPacket; interface PacketTimeStamp as PacketTimeStamp32khz; @@ -93,7 +94,9 @@ implementation void * timesync = msg->data + len; *(timesync_radio_t*)timesync = event_time; - err = call SubSend.send[id](addr, msg, len + sizeof(timesync_radio_t)); + call AMPacket.setDestination(msg, addr); + call AMPacket.setType(msg, id); + err = call SubSend.send(msg, len + sizeof(timesync_radio_t)); call PacketTimeSyncOffset.set(msg); return err; } @@ -101,19 +104,19 @@ implementation command error_t TimeSyncAMSend32khz.cancel[am_id_t id](message_t* msg) { call PacketTimeSyncOffset.cancel(msg); - return call SubSend.cancel[id](msg); + return call SubSend.cancel(msg); } default event void TimeSyncAMSend32khz.sendDone[am_id_t id](message_t* msg, error_t error) {} command uint8_t TimeSyncAMSend32khz.maxPayloadLength[am_id_t id]() { - return call SubSend.maxPayloadLength[id]() - sizeof(timesync_radio_t); + return call SubSend.maxPayloadLength() - sizeof(timesync_radio_t); } command void* TimeSyncAMSend32khz.getPayload[am_id_t id](message_t* msg, uint8_t len) { - return call SubSend.getPayload[id](msg, len + sizeof(timesync_radio_t)); + return call SubSend.getPayload(msg, len + sizeof(timesync_radio_t)); } /*----------------- TimeSyncAMSendMilli -----------------*/ @@ -142,8 +145,9 @@ implementation } /*----------------- SubSend.sendDone -------------------*/ - event void SubSend.sendDone[am_id_t id](message_t* msg, error_t error) + event void SubSend.sendDone(message_t* msg, error_t error) { + am_id_t id = call AMPacket.type(msg); signal TimeSyncAMSend32khz.sendDone[id](msg, error); signal TimeSyncAMSendMilli.sendDone[id](msg, error); } diff --git a/tos/chips/cc2420/csma/CC2420CsmaP.nc b/tos/chips/cc2420/csma/CC2420CsmaP.nc index 670b7181..e67f9217 100644 --- a/tos/chips/cc2420/csma/CC2420CsmaP.nc +++ b/tos/chips/cc2420/csma/CC2420CsmaP.nc @@ -72,7 +72,6 @@ implementation { /****************** Prototypes ****************/ task void startDone_task(); - task void startDone_task(); task void stopDone_task(); task void sendDone_task(); @@ -144,7 +143,7 @@ implementation { metadata->ack = FALSE; metadata->rssi = 0; metadata->lqi = 0; - metadata->timesync = FALSE; + //metadata->timesync = FALSE; metadata->timestamp = CC2420_INVALID_TIMESTAMP; ccaOn = TRUE; diff --git a/tos/chips/cc2420/lpl/DefaultLplP.nc b/tos/chips/cc2420/lpl/DefaultLplP.nc index d93debb0..3ada9db6 100644 --- a/tos/chips/cc2420/lpl/DefaultLplP.nc +++ b/tos/chips/cc2420/lpl/DefaultLplP.nc @@ -230,7 +230,7 @@ implementation { return 0; } - return (DUTY_ON_TIME * (10000 - dutyCycle)) / dutyCycle; + return ((uint32_t)DUTY_ON_TIME * (10000 - dutyCycle)) / dutyCycle; } /** @@ -245,7 +245,7 @@ implementation { return 10000; } - return getActualDutyCycle((DUTY_ON_TIME * 10000) + return getActualDutyCycle(((uint32_t)DUTY_ON_TIME * 10000) / (sleepInterval + DUTY_ON_TIME)); } diff --git a/tos/chips/cc2420/receive/CC2420ReceiveP.nc b/tos/chips/cc2420/receive/CC2420ReceiveP.nc index 30a42191..5bd4e852 100644 --- a/tos/chips/cc2420/receive/CC2420ReceiveP.nc +++ b/tos/chips/cc2420/receive/CC2420ReceiveP.nc @@ -126,6 +126,10 @@ implementation { 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; @@ -281,16 +285,25 @@ implementation { call SpiResource.release(); } - if ( m_timestamp_size ) { - if ( rxFrameLength > 10 ) { - call PacketTimeStamp.set(m_p_rx_buf, 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 { - call PacketTimeStamp.clear(m_p_rx_buf); + + 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 ) { diff --git a/tos/chips/cc2420/spi/CC2420SpiC.nc b/tos/chips/cc2420/spi/CC2420SpiC.nc index 13e17c4f..50e015e9 100644 --- a/tos/chips/cc2420/spi/CC2420SpiC.nc +++ b/tos/chips/cc2420/spi/CC2420SpiC.nc @@ -79,6 +79,7 @@ generic configuration CC2420SpiC() { provides interface CC2420Register as MANAND; provides interface CC2420Register as MANOR; provides interface CC2420Register as AGCCTRL; + provides interface CC2420Register as RXFIFO_REGISTER; // ram provides interface CC2420Ram as IEEEADR; @@ -142,6 +143,7 @@ implementation { MANAND = Spi.Reg[ CC2420_MANAND ]; MANOR = Spi.Reg[ CC2420_MANOR ]; AGCCTRL = Spi.Reg[ CC2420_AGCCTRL ]; + RXFIFO_REGISTER = Spi.Reg[ CC2420_RXFIFO ]; // ram IEEEADR = Spi.Ram[ CC2420_RAM_IEEEADR ]; diff --git a/tos/chips/cc2420/transmit/CC2420TransmitP.nc b/tos/chips/cc2420/transmit/CC2420TransmitP.nc index 1b6cd48f..a8367e54 100644 --- a/tos/chips/cc2420/transmit/CC2420TransmitP.nc +++ b/tos/chips/cc2420/transmit/CC2420TransmitP.nc @@ -236,12 +236,10 @@ implementation { } - inline uint32_t time16to32(uint16_t time, uint32_t recent_time) + inline uint32_t getTime32(uint16_t time) { - if ((recent_time&0xFFFF)data + (call PacketTimeSyncOffset.get(m_msg) - sizeof(cc2420_header_t)); - timesync_radio_t *timesync = (timesync_radio_t*)taddr; + uint8_t absOffset = sizeof(message_header_t)-sizeof(cc2420_header_t)+call PacketTimeSyncOffset.get(m_msg); + timesync_radio_t *timesync = (timesync_radio_t *)((nx_uint8_t*)m_msg+absOffset); // set timesync event time as the offset between the event time and the SFD interrupt time (TEP 133) *timesync -= time32; call CSN.clr(); - call TXFIFO_RAM.write( call PacketTimeSyncOffset.get(m_msg), (uint8_t*)timesync, sizeof(timesync_radio_t) ); + call TXFIFO_RAM.write( absOffset, (uint8_t*)timesync, sizeof(timesync_radio_t) ); call CSN.set(); + //restoring the event time to the original value + *timesync += time32; } if ( (call CC2420PacketBody.getHeader( m_msg ))->fcf & ( 1 << IEEE154_FCF_ACK_REQ ) ) { @@ -284,16 +289,11 @@ implementation { releaseSpiResource(); call BackoffTimer.stop(); - - if ( ( ( (call CC2420PacketBody.getHeader( m_msg ))->fcf >> IEEE154_FCF_FRAME_TYPE ) & 7 ) == IEEE154_TYPE_DATA ) { - call PacketTimeStamp.set(m_msg, time32); - } - if ( call SFD.get() ) { break; } /** Fall Through because the next interrupt was already received */ - + case S_EFD: sfdHigh = FALSE; call CaptureSFD.captureRisingEdge(); @@ -311,9 +311,12 @@ implementation { /** Fall Through because the next interrupt was already received */ default: - if ( !m_receiving ) { + /* this is the SFD for received messages */ + if ( !m_receiving && sfdHigh == FALSE ) { sfdHigh = TRUE; call CaptureSFD.captureFallingEdge(); + // safe the SFD pin status for later use + sfd_state = call SFD.get(); call CC2420Receive.sfd( time32 ); m_receiving = TRUE; m_prev_time = time; @@ -321,18 +324,29 @@ implementation { // wait for the next interrupt before moving on return; } + // if SFD.get() = 0, then an other interrupt happened since we + // reconfigured CaptureSFD! Fall through } - sfdHigh = FALSE; - call CaptureSFD.captureRisingEdge(); - m_receiving = FALSE; - if ( time - m_prev_time < 10 ) { - call CC2420Receive.sfd_dropped(); - if (m_msg) - call PacketTimeStamp.clear(m_msg); + if ( sfdHigh == TRUE ) { + sfdHigh = FALSE; + call CaptureSFD.captureRisingEdge(); + m_receiving = FALSE; + /* if sfd_state is 1, then we fell through, but at the time of + * saving the time stamp the SFD was still high. Thus, the timestamp + * is valid. + * if the sfd_state is 0, then either we fell through and SFD + * was low while we safed the time stamp, or we didn't fall through. + * Thus, we check for the time between the two interrupts. + * FIXME: Why 10 tics? Seams like some magic number... + */ + if ((sfd_state == 0) && (time - m_prev_time < 10) ) { + call CC2420Receive.sfd_dropped(); + if (m_msg) + call PacketTimeStamp.clear(m_msg); + } + break; } - break; - } } } -- 2.39.2