From: maxmul Date: Tue, 22 Jul 2008 11:21:32 +0000 (+0000) Subject: LPL fixes, thanks to Francois Ingelrest and Roland Flury for the help X-Git-Tag: release_tinyos_2_1_0_0~47 X-Git-Url: https://oss.titaniummirror.com/gitweb/?a=commitdiff_plain;h=7c9cfc86286f6b4db85cf700a6032b3eccdc8ea0;p=tinyos-2.x.git LPL fixes, thanks to Francois Ingelrest and Roland Flury for the help --- diff --git a/tos/chips/xe1205/XE1205CsmaP.nc b/tos/chips/xe1205/XE1205CsmaP.nc index 2ed39422..7389c20b 100644 --- a/tos/chips/xe1205/XE1205CsmaP.nc +++ b/tos/chips/xe1205/XE1205CsmaP.nc @@ -100,8 +100,8 @@ implementation { atomic { if (rState == RADIO_TX) signal Send.sendDone(txMsg,FAIL); - else - signal SplitControl.startDone(FAIL); + else + signal SplitControl.startDone(err); } } else { atomic { @@ -109,9 +109,9 @@ implementation { if(enableCCA==TRUE) { if(SUCCESS != post readRssi()) { signal Send.sendDone(txMsg,FAIL); - return; } - } + return; + } else { post send(); return; @@ -121,8 +121,7 @@ implementation { } } } - if(SUCCESS != post readRssi()) - signal SplitControl.startDone(FAIL); + signal SplitControl.startDone(err); } } } @@ -147,7 +146,7 @@ implementation { switch (maType) { case RSSI_CLR: - if((float)value < MAX(RSSI_RX_MA,RSSI_RX_MA)) + if((float)value < MAX(RSSI_RX_MA,RSSI_CLR_MA)) RSSI_CLR_MA = (RSSI_CLR_MA*(MA_LENGTH - 1)+ value )/(MA_LENGTH); break; @@ -198,7 +197,7 @@ implementation { signal Send.sendDone(msg, err); } - command void* Send.getPayload(message_t* m) { + command void* Send.getPayload(message_t* m,uint8_t len) { return m->data; } @@ -210,14 +209,6 @@ implementation { return FAIL; } - command uint8_t Receive.payloadLength(message_t* msg) { - return call SubReceive.payloadLength(msg); - } - - command void *Receive.getPayload(message_t* msg, uint8_t* len) { - return call SubReceive.getPayload(msg, len); - } - task void readRssi() { if(SUCCESS!=call Rssi.getRssi()) { diff --git a/tos/chips/xe1205/XE1205LowPowerListening.h b/tos/chips/xe1205/XE1205LowPowerListening.h index e34086e8..63a39378 100644 --- a/tos/chips/xe1205/XE1205LowPowerListening.h +++ b/tos/chips/xe1205/XE1205LowPowerListening.h @@ -46,7 +46,7 @@ #endif #ifndef DEFAULT_DUTY_PERIOD -#define DEFAULT_DUTY_PERIOD 1000 +#define DEFAULT_DUTY_PERIOD 80 #endif diff --git a/tos/chips/xe1205/XE1205LowPowerListeningP.nc b/tos/chips/xe1205/XE1205LowPowerListeningP.nc index df2487ad..d8354579 100644 --- a/tos/chips/xe1205/XE1205LowPowerListeningP.nc +++ b/tos/chips/xe1205/XE1205LowPowerListeningP.nc @@ -1,23 +1,23 @@ /* Copyright (c) 2007 Shockfish SA -* All rights reserved. -* -* Permission to use, copy, modify, and distribute this software and its -* documentation for any purpose, without fee, and without written -* agreement is hereby granted, provided that the above copyright -* notice, the (updated) modification history and the author appear in -* all copies of this source code. -* -* 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 COPYRIGHT HOLDERS OR CONTRIBUTORS -* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, LOSS OF USE, DATA, -* OR PROFITS) 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. -*/ + * All rights reserved. + * + * Permission to use, copy, modify, and distribute this software and its + * documentation for any purpose, without fee, and without written + * agreement is hereby granted, provided that the above copyright + * notice, the (updated) modification history and the author appear in + * all copies of this source code. + * + * 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 COPYRIGHT HOLDERS OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, LOSS OF USE, DATA, + * OR PROFITS) 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 Maxime Muller @@ -100,7 +100,8 @@ implementation { } event void SubControl.startDone(error_t err) { - if(!err) { + + if(err==SUCCESS) { if(sleepTime > 0) {// keep radio on for a while call OffTimer.stop(); call OnTimer.startOneShot(DELAY_AFTER_RECEIVE); @@ -145,12 +146,13 @@ implementation { event void OffTimer.fired() { if (SUCCESS==call SubControl.start()) { - if (sleepTime > 0) - call LPLControl.setMode(RX); - if (sleepTime == 0) // radio always on - call LPLControl.setMode(IDLE); - } else call OffTimer.startOneShot(sleepTime); - //} + if (sleepTime > 0) + call LPLControl.setMode(RX); + if (sleepTime == 0) // radio always on + call LPLControl.setMode(IDLE); + } + else + call OffTimer.startOneShot(sleepTime); } event void OnTimer.fired() { @@ -166,9 +168,8 @@ implementation { if(SUCCESS != call SubSend.send(curTxMsg,curTxMsgLength)) { call LPLControl.setMode(IDLE); call OffTimer.startOneShot(sleepTime); - sendDone(FAIL); - } + } } /* @@ -186,9 +187,9 @@ implementation { if(call LowPowerListening.getRxSleepInterval(curTxMsg) > ONE_MESSAGE) { txSeqNo+=0x02; - if (AM_BROADCAST_ADDR != call AMPacket.destination(curTxMsg)) + if (AM_BROADCAST_ADDR != call AMPacket.destination(curTxMsg)) { getHeader(curTxMsg)->ack = txSeqNo|0x01; - else + } else getHeader(curTxMsg)->ack = txSeqNo&0xFE; call CsmaControl.enableCca(); @@ -212,8 +213,8 @@ implementation { event void SendTimeout.fired() { atomic { - if (rState == RADIO_TX) // let sendDone occur - rState = RADIO_ON; + if (rState == RADIO_TX) // let sendDone occur + rState = RADIO_ON; } call OffTimer.startOneShot(DELAY_AFTER_RECEIVE); } @@ -229,20 +230,25 @@ implementation { } event void SubSend.sendDone(message_t *msg, error_t err) { - if(rState == RADIO_TX - && call SendTimeout.isRunning()) - if ( AM_BROADCAST_ADDR != call AMPacket.destination(msg) - && call PacketAcknowledgements.wasAcked(msg)) { + + if(rState == RADIO_TX + && call SendTimeout.isRunning()) { + if ( AM_BROADCAST_ADDR != call AMPacket.destination(msg) + && err==SUCCESS) { + call SendTimeout.stop(); sendDone(err); - return; - } - else { // ack timeout or bcast msg + } else { // ack timeout or bcast msg call CsmaControl.disableCca(); - if(SUCCESS!=post sendPkt()) + if(SUCCESS!=post sendPkt()) { + sendDone(FAIL); - return; + } } - sendDone(err); + } + else { + sendDone(err); + + } } command error_t Send.cancel(message_t *msg) { @@ -257,8 +263,8 @@ implementation { return call SubSend.maxPayloadLength(); } - command void *Send.getPayload(message_t* msg) { - return call SubSend.getPayload(msg); + command void *Send.getPayload(message_t* msg, uint8_t len) { + return call SubSend.getPayload(msg,len); } /* @@ -266,28 +272,20 @@ implementation { */ event message_t *SubReceive.receive(message_t *msg,void *payload, uint8_t len) { - if ((getHeader(msg)->ack & 0xFE ) == lastSeqNo - && call AMPacket.destination(msg) == AM_BROADCAST_ADDR) { - return msg; - } else { - lastSeqNo = getHeader(msg)->ack & 0xFE; - if(!call SendTimeout.isRunning()) { - // catched a packet between pktSend - call OffTimer.startOneShot(DELAY_AFTER_RECEIVE); - } + if ((getHeader(msg)->ack & 0xFE ) == lastSeqNo + && call AMPacket.destination(msg) == AM_BROADCAST_ADDR) { + return msg; + } else { + lastSeqNo = getHeader(msg)->ack & 0xFE; + if(!call SendTimeout.isRunning()) { + // catched a packet between pktSend + call OffTimer.startOneShot(DELAY_AFTER_RECEIVE); + } - return signal Receive.receive(msg,payload,len); + return signal Receive.receive(msg,payload,len); } } - command void *Receive.getPayload(message_t* msg, uint8_t* len) { - return call SubReceive.getPayload(msg, len); - } - - command uint8_t Receive.payloadLength(message_t* msg) { - return call SubReceive.payloadLength(msg); - } - uint16_t getActualDutyCycle(uint16_t dutyCycle) { if(dutyCycle > 10000) { return 10000; diff --git a/tos/chips/xe1205/XE1205SendReceiveP.nc b/tos/chips/xe1205/XE1205SendReceiveP.nc index 2d5f67ff..e8e41e7b 100644 --- a/tos/chips/xe1205/XE1205SendReceiveP.nc +++ b/tos/chips/xe1205/XE1205SendReceiveP.nc @@ -137,7 +137,7 @@ implementation { return call Packet.getPayload(m, len); } - task void sendDoneTask() { + task void sendDoneTask() { txMsgSendDonePtr = txMsgPtr; txMsgPtr=NULL; signal Send.sendDone(txMsgSendDonePtr, SUCCESS); @@ -151,6 +151,13 @@ implementation { } + task void sendDoneNoAckTask() { + txMsgSendDonePtr = txMsgPtr; + txMsgPtr=NULL; + signal Send.sendDone(txMsgSendDonePtr, ENOACK); + } + + command error_t SplitControl.start() { error_t err; err = call PhySplitControl.start(); @@ -193,23 +200,23 @@ implementation { - task void sendAck() { - atomic { - ((xe1205_metadata_t*)((uint8_t*)ackMsgPtr->footer + sizeof(xe1205_footer_t)))->length = sizeof(ackMsg_t); - ((xe1205_header_t*)(&ackMsg.data - sizeof(xe1205_header_t)))->group = \ - (getHeader((message_t*)rxMsgPtr))->group; - ((xe1205_header_t*)(ackMsgPtr->data - sizeof(xe1205_header_t)))->type = \ - ((xe1205_header_t*)(rxMsgPtr->data - sizeof(xe1205_header_t)))->type; - ((xe1205_header_t*)(ackMsgPtr->data - sizeof(xe1205_header_t)))->dest = \ - ((xe1205_header_t*)(rxMsgPtr->data - sizeof(xe1205_header_t)))->source; - ((xe1205_header_t*)(ackMsgPtr->data - sizeof(xe1205_header_t)))->source = TOS_NODE_ID; - ((ackMsg_t*)(ackMsgPtr->data))->pl = ackPayload; - - txMsgPtr = ackMsgPtr; - } - _len = sizeof(ackMsg_t); - sendRadioOn(ACK_CODE); - } + task void sendAck() { + atomic { + ((xe1205_metadata_t*)((uint8_t*)ackMsgPtr->footer + sizeof(xe1205_footer_t)))->length = sizeof(ackMsg_t); + ((xe1205_header_t*)(&ackMsg.data - sizeof(xe1205_header_t)))->group = \ + (getHeader((message_t*)rxMsgPtr))->group; + ((xe1205_header_t*)(ackMsgPtr->data - sizeof(xe1205_header_t)))->type = \ + ((xe1205_header_t*)(rxMsgPtr->data - sizeof(xe1205_header_t)))->type; + ((xe1205_header_t*)(ackMsgPtr->data - sizeof(xe1205_header_t)))->dest = \ + ((xe1205_header_t*)(rxMsgPtr->data - sizeof(xe1205_header_t)))->source; + ((xe1205_header_t*)(ackMsgPtr->data - sizeof(xe1205_header_t)))->source = TOS_NODE_ID; + ((ackMsg_t*)(ackMsgPtr->data))->pl = ackPayload; + + txMsgPtr = ackMsgPtr; + } + _len = sizeof(ackMsg_t); + sendRadioOn(ACK_CODE); + } command error_t Send.cancel(message_t* msg) { /* Cancel is unsupported for now. */ @@ -247,7 +254,7 @@ implementation { txPhyHdr.length = _len; txRunningCRC=0; getMetadata(txMsgPtr)->length = _len; - if (((xe1205_header_t*)( (uint8_t*)txMsgPtr->data - sizeof(xe1205_header_t)))->ack==1) { + if ((((xe1205_header_t*)( (uint8_t*)txMsgPtr->data - sizeof(xe1205_header_t)))->ack & 0x01)==0x01) { call XE1205PhyRxTx.enableAck(TRUE); } txIndex = min(sizeof(xe1205_header_t) + _len + sizeof(xe1205_footer_t), @@ -264,8 +271,7 @@ implementation { sendingAck=TRUE; memcpy(txBuf, ackPreamble, sizeof(ackPreamble)); memcpy(txBuf + sizeof(pktPreamble), &txPhyHdr, sizeof(txPhyHdr)); - - post signalPacketReceived(); + break; } @@ -347,18 +353,29 @@ implementation { uint8_t sendDones = 0; async event void XE1205PhyRxTx.sendFrameDone(error_t err) __attribute__ ((noinline)) { sendDones++; - if(sendingAck==FALSE) - if(err==SUCCESS) { + if(sendingAck==FALSE) { + switch (err) { + + case SUCCESS: if (post sendDoneTask() != SUCCESS) xe1205check(2, FAIL); - } else { + break; + + case ENOACK: + if(post sendDoneNoAckTask() !=SUCCESS) + xe1205check(2, FAIL); + break; + + default: if (post sendDoneFailTask() != SUCCESS) xe1205check(2, FAIL); } - else { + } else { + txMsgPtr = NULL; - sendingAck=FALSE; + sendingAck=FALSE; + post signalPacketReceived(); } } @@ -379,12 +396,12 @@ implementation { } command void* Packet.getPayload(message_t* msg, uint8_t len) { - if (len <= TOSH_DATA_LENGTH) { - return (void*)msg->data; - } - else { - return NULL; - } + if (len <= TOSH_DATA_LENGTH) { + return (void*)msg->data; + } + else { + return NULL; + } } async command error_t PacketAcknowledgements.requestAck(message_t* msg) { @@ -426,6 +443,7 @@ implementation { uint32_t nrxmsgs; + async event void XE1205PhyRxTx.rxFrameEnd(char* data, uint8_t len, error_t status) __attribute__ ((noinline)) { if (status != SUCCESS){ return;} @@ -451,6 +469,42 @@ implementation { } } + + async event void XE1205PhyRxTx.rxAckEnd(char* data, uint8_t len, error_t status) __attribute__ ((noinline)) { + + sendingAck=FALSE; + + if (status != SUCCESS) { + post sendDoneNoAckTask(); + return; + } + + if (rxBufPtr) { + post sendDoneNoAckTask(); + return; // this could happen whenever rxFrameBegin was called with rxBufPtr still active + } + + rxBufPtr = (data + sizeof(xe1205_phy_header_t)); + + checkCrcAndUnwhiten(rxBufPtr, rxPhyHdr.whitening, rxPhyHdr.length); + + if (!getFooter(rxMsgPtr)->crc) { + post sendDoneNoAckTask(); + atomic rxBufPtr = NULL; + return; + } + + getMetadata((message_t*) rxMsgPtr)->strength = call XE1205PhyRssi.readRxRssi(); + getMetadata((message_t*) rxMsgPtr)->length = rxPhyHdr.length; + + if ((getHeader((message_t*)rxMsgPtr))->dest == TOS_NODE_ID) { + post sendDoneTask(); + } else { + post sendDoneNoAckTask(); + } + atomic rxBufPtr = NULL; + } + async event void XE1205PhyRssi.rssiDone(uint8_t _rssi) { } } diff --git a/tos/chips/xe1205/phy/XE1205PhyP.nc b/tos/chips/xe1205/phy/XE1205PhyP.nc index d43dc468..3a8f79f4 100644 --- a/tos/chips/xe1205/phy/XE1205PhyP.nc +++ b/tos/chips/xe1205/phy/XE1205PhyP.nc @@ -142,7 +142,9 @@ implementation { call SpiResourceConfig.release(); atomic { if (state == RADIO_STARTING){ - post startDone();} + + post startDone(); + } if (state == RADIO_RX_ACK) { enableAck=FALSE; signal XE1205PhyRxTx.sendFrameDone(FAIL); @@ -161,17 +163,15 @@ implementation { command error_t SplitControl.start() { - atomic { - if (state == RADIO_LISTEN){ post startDone(); return SUCCESS;} - if (state != RADIO_SLEEP) return EBUSY; - state = RADIO_STARTING; - } - call XE1205PhySwitch.rxMode(); - call XE1205PhySwitch.antennaRx(); - - - call Alarm32khz16.start(usecs_to_jiffies(XE1205_Sleep_to_RX_Time)); - return SUCCESS; + atomic { + if (state == RADIO_LISTEN){ post startDone(); return SUCCESS;} + if (state != RADIO_SLEEP) return EBUSY; + state = RADIO_STARTING; + } + call XE1205PhySwitch.rxMode(); + call XE1205PhySwitch.antennaRx(); + call Alarm32khz16.start(usecs_to_jiffies(XE1205_Sleep_to_RX_Time)); + return SUCCESS; } command error_t SplitControl.stop() @@ -385,19 +385,19 @@ implementation { switch (state) { case RADIO_RX_ACK: - + call Alarm32khz16.stop(); case RADIO_LISTEN: rxByte=1; atomic state = RADIO_RX_HEADER; status = call SpiResourceRX.immediateRequest(); atomic { - if (status != SUCCESS) { - state = RADIO_LISTEN; - call Interrupt0.disable(); // because pattern detector won't be rearmed right away - call SpiResourceConfig.request(); - return; - } + if (status != SUCCESS) { + state = RADIO_LISTEN; + call Interrupt0.disable(); // because pattern detector won't be rearmed right away + call SpiResourceConfig.request(); + return; + } } call Alarm32khz16.start(3000); return; @@ -494,7 +494,6 @@ implementation { call XE1205PatternConf.loadAckPatternHasBus(); armPatternDetect(); call SpiResourceTX.release(); - call Alarm32khz16.start(usecs_to_jiffies(8000)); atomic { call Interrupt0.enableRisingEdge(); @@ -556,12 +555,9 @@ implementation { } else { enableAck = FALSE; - signal XE1205PhyRxTx.sendFrameDone(SUCCESS); + signal XE1205PhyRxTx.rxAckEnd(rxFrame, rxFrameLen + headerLen, SUCCESS); } - - - return; @@ -593,9 +589,9 @@ implementation { case RADIO_RX_HEADER: case RADIO_RX_PACKET: if (rssiRange!=RSSI_OFF) { - readRssi(); - return; - } + readRssi(); + return; + } stats_rxOverruns++; signal XE1205PhyRxTx.rxFrameEnd(NULL, 0, FAIL); @@ -611,7 +607,7 @@ implementation { return; case RADIO_RSSI: - readRssi(); + readRssi(); return; case RADIO_RX_ACK: // ack timeout @@ -633,11 +629,10 @@ implementation { } - signal XE1205PhyRxTx.sendFrameDone(FAIL); + signal XE1205PhyRxTx.sendFrameDone(ENOACK); return; default: - - + return; } diff --git a/tos/chips/xe1205/phy/XE1205PhyRxTx.nc b/tos/chips/xe1205/phy/XE1205PhyRxTx.nc index c3d464d1..872da62e 100644 --- a/tos/chips/xe1205/phy/XE1205PhyRxTx.nc +++ b/tos/chips/xe1205/phy/XE1205PhyRxTx.nc @@ -93,6 +93,17 @@ interface XE1205PhyRxTx { async event void rxFrameEnd(char* data, uint8_t len, error_t status); + /** + * Signalled at end of a Ack reception. + * + * @param data pointer to Ack (at first byte of header) + * @param len length of the Ack + * @param status SUCCESS if packet received ok, ERROR if packet reception was aborted. + * + */ + async event void rxAckEnd(char* data, uint8_t len, error_t status); + + /** * Set header size, ie number of bytes at start of packet to be read and passed along * with the rxFrameBegin() event.