X-Git-Url: https://oss.titaniummirror.com/gitweb/?a=blobdiff_plain;f=tos%2Fchips%2Fcc2420_tkn154%2FCC2420ReceiveP.nc;h=fddf5dd68188fa47aff9b99ea45b26ad69a970a8;hb=e9bfab607e051bae6afb47b44892ce37541d1b44;hp=04860924a488ddde3f10208aa7eec13e79484eb1;hpb=adf1de6c009d13b7b52e68535c63b28f59c97400;p=tinyos-2.x.git diff --git a/tos/chips/cc2420_tkn154/CC2420ReceiveP.nc b/tos/chips/cc2420_tkn154/CC2420ReceiveP.nc index 04860924..fddf5dd6 100644 --- a/tos/chips/cc2420_tkn154/CC2420ReceiveP.nc +++ b/tos/chips/cc2420_tkn154/CC2420ReceiveP.nc @@ -42,7 +42,6 @@ module CC2420ReceiveP { provides interface CC2420AsyncSplitControl as AsyncSplitControl; provides interface CC2420Receive; provides interface CC2420Rx; -/* provides interface ReceiveIndicator as PacketIndicator;*/ uses interface GeneralIO as CSN; uses interface GeneralIO as FIFO; @@ -54,15 +53,12 @@ module CC2420ReceiveP { uses interface CC2420Strobe as SACK; uses interface CC2420Strobe as SFLUSHRX; uses interface CC2420Strobe as SRXON; - uses interface CC2420Strobe as SACKPEND; // JH: ACKs must have pending flag set + uses interface CC2420Strobe as SACKPEND; uses interface CC2420Register as MDMCTRL1; uses interface ReferenceTime; uses interface FrameUtility; uses interface CC2420Config; -/* uses interface CC2420Packet;*/ -/* uses interface CC2420PacketBody;*/ - - uses interface Leds; + uses interface CC2420Ram as RXFIFO_RAM; } implementation { @@ -70,7 +66,6 @@ implementation { typedef enum { S_STOPPED, S_STARTING, - S_STARTING_FLUSHRX, S_STARTED, S_RX_LENGTH, S_RX_FCF, @@ -85,8 +80,8 @@ implementation { SACK_HEADER_LENGTH = 3, }; - ieee154_reftime_t m_timestamp_queue[ TIMESTAMP_QUEUE_SIZE ]; - ieee154_reftime_t m_timestamp; + ieee154_timestamp_t m_timestamp_queue[ TIMESTAMP_QUEUE_SIZE ]; + ieee154_timestamp_t m_timestamp; norace bool m_timestampValid; uint8_t m_timestamp_head; @@ -125,7 +120,6 @@ implementation { void flush(); void switchToUnbufferedMode(); void switchToBufferedMode(); - void startingSpiReserved(); void continueStart(); void continueStop(); task void stopContinueTask(); @@ -139,79 +133,45 @@ implementation { return SUCCESS; } - /***************** AsyncSplitControl **************** - * IMPORTANT: when AsyncSplitControl.start is called, - * the radio MUST be off ! + /***************** 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). */ - async command error_t AsyncSplitControl.start() - { - atomic { - if (m_state != S_STOPPED){ - call Leds.led0On(); - return FAIL; - } else { - m_state = S_STARTING; - if (call SpiResource.isOwner()){ - call Leds.led0On(); // internal error (debug) ! - startingSpiReserved(); - } - if (call SpiResource.immediateRequest() == SUCCESS) - startingSpiReserved(); - else - call SpiResource.request(); - } - } - return SUCCESS; - } - void startingSpiReserved() + /** + * 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 FIFOP.get() || call FIFO.get()){ // FIFOP is inverted - // there is something in RXFIFO: flush it out - // the datasheet says at least one byte should - // be read before flushing - m_state = S_STARTING_FLUSHRX; - call CSN.set(); - call CSN.clr(); - call RXFIFO.beginRead( &m_dummy, 1 ); // will continue in continueFlushStart() - return; + 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; } - } - continueStart(); - } - - - void continueFlushStart() - { - atomic { - call CSN.set(); - call CSN.clr(); - call SFLUSHRX.strobe(); - call SFLUSHRX.strobe(); - call CSN.set(); - } - continueStart(); - } - - void continueStart() - { - // RXFIFO is empty - if (!call FIFOP.get() || call FIFO.get()){ - call Leds.led0On(); - } - atomic { + ASSERT(m_state == S_STOPPED); reset_state(); m_state = S_STARTED; + call InterruptFIFOP.enableFallingEdge(); // ready! } - call SpiResource.release(); - call InterruptFIFOP.enableFallingEdge(); - signal AsyncSplitControl.startDone(SUCCESS); + return SUCCESS; } - /***************** AsyncSplitControl **************** + /* AsyncSplitControl.stop: + * * IMPORTANT: when AsyncSplitControl.stop is called, - * the radio MUST NOT be off ! + * 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() { @@ -222,9 +182,9 @@ implementation { m_stop = TRUE; call InterruptFIFOP.disable(); if (!receivingPacket) - continueStop(); - // else stopContinueTask will be posted after - // current Rx operation is finished, because m_stop is set + continueStop(); // it is safe to stop now + // else continueStop will be called after + // current Rx operation is finished } } return SUCCESS; @@ -233,6 +193,9 @@ implementation { void continueStop() { atomic { + if (!m_stop){ + return; + } m_stop = FALSE; m_state = S_STOPPED; } @@ -241,49 +204,24 @@ implementation { task void stopContinueTask() { - if (receivingPacket){ - call Leds.led0On(); - } + ASSERT(receivingPacket != TRUE); call SpiResource.release(); // may fail atomic m_state = S_STOPPED; signal AsyncSplitControl.stopDone(SUCCESS); } - void switchToUnbufferedMode() - { - uint16_t mdmctrol1; - call CSN.set(); - call CSN.clr(); - call MDMCTRL1.read(&mdmctrol1); - mdmctrol1 &= ~0x03; - mdmctrol1 |= 0x01; - call MDMCTRL1.write(mdmctrol1); - call CSN.set(); - } - - void switchToBufferedMode() - { - uint16_t mdmctrol1; - call CSN.set(); - call CSN.clr(); - call MDMCTRL1.read(&mdmctrol1); - mdmctrol1 &= ~0x03; - call MDMCTRL1.write(mdmctrol1); - call CSN.set(); - } - /***************** CC2420Receive Commands ****************/ /** * Start frame delimiter signifies the beginning/end of a packet * See the CC2420 datasheet for details. */ - async command void CC2420Receive.sfd( ieee154_reftime_t *time ) { + 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_reftime_t) ); + memcpy(&m_timestamp_queue[ tail ], time, sizeof(ieee154_timestamp_t) ); m_timestamp_size++; } } @@ -314,39 +252,12 @@ implementation { atomic { switch (m_state) { - case S_STARTING: startingSpiReserved(); break; - case S_STARTING_FLUSHRX: // fall through - case S_STOPPED: call Leds.led0On(); - call SpiResource.release(); break; + case S_STOPPED: ASSERT(0); break; // this should never happen! default: receive(); } } } - uint8_t mhrLength(uint8_t *fcf) - { - uint8_t idCompression; - uint8_t len = MHR_INDEX_ADDRESS; - - if (fcf[MHR_INDEX_FC1] & FC1_SECURITY_ENABLED) - return 0xFF; // not supported - idCompression = (fcf[0] & FC1_PAN_ID_COMPRESSION); - if (fcf[MHR_INDEX_FC2] & 0x08){ // short or ext. address - len += 4; // pan id + short address - if (fcf[MHR_INDEX_FC2] & 0x04) // ext. address - len += 6; // diff to short address - } - if (fcf[MHR_INDEX_FC2] & 0x80){ // short or ext. address - len += 2; - if (!idCompression) - len += 2; - if (fcf[MHR_INDEX_FC2] & 0x40) // ext. address - len += 6; // diff to short address - } - return len; - } - - /***************** RXFIFO Events ****************/ /** * We received some bytes from the SPI bus. Process them in the context @@ -441,9 +352,9 @@ implementation { } if ( m_timestamp_size ) { - if ( rxFrameLength > 10 ) { + if ( rxFrameLength > 4 ) { //((ieee154_metadata_t*) m_rxFramePtr->metadata)->timestamp = m_timestamp_queue[ m_timestamp_head ]; - memcpy(&m_timestamp, &m_timestamp_queue[ m_timestamp_head ], sizeof(ieee154_reftime_t) ); + memcpy(&m_timestamp, &m_timestamp_queue[ m_timestamp_head ], sizeof(ieee154_timestamp_t) ); m_timestampValid = TRUE; m_timestamp_head = ( m_timestamp_head + 1 ) % TIMESTAMP_QUEUE_SIZE; m_timestamp_size--; @@ -471,8 +382,6 @@ implementation { waitForNextPacket(); break; - case S_STARTING_FLUSHRX: continueFlushStart(); break; - default: atomic receivingPacket = FALSE; call CSN.set(); @@ -500,12 +409,7 @@ implementation { uint8_t payloadLen = ((ieee154_header_t*) m_rxFramePtr->header)->length - m_mhrLen - 2; ieee154_metadata_t *metadata = (ieee154_metadata_t*) m_rxFramePtr->metadata; - atomic { - if (m_state == S_STOPPED){ - call Leds.led0On(); - return; - } - } + atomic ASSERT(m_state != S_STOPPED); ((ieee154_header_t*) m_rxFramePtr->header)->length = m_rxFramePtr->data[payloadLen+1] & 0x7f; // temp. LQI metadata->rssi = m_rxFramePtr->data[payloadLen]; metadata->linkQuality = ((ieee154_header_t*) m_rxFramePtr->header)->length; // copy back @@ -538,8 +442,7 @@ implementation { */ void beginReceive() { atomic { - if ( m_state == S_STOPPED){ - call Leds.led0On(); + if (m_state == S_STOPPED || m_stop){ return; } m_state = S_RX_LENGTH; @@ -591,11 +494,11 @@ implementation { */ void waitForNextPacket() { atomic { - receivingPacket = FALSE; if ( m_state == S_STOPPED) { call SpiResource.release(); return; } + receivingPacket = FALSE; if (m_stop){ continueStop(); return;