X-Git-Url: https://oss.titaniummirror.com/gitweb/?a=blobdiff_plain;f=tos%2Fchips%2Frf230%2FRF230LayerP.nc;h=4ba79fca8bf74f60d948f3f78c71a38f29e0186e;hb=adf1de6c009d13b7b52e68535c63b28f59c97400;hp=2796fd4e17a1f213be99b5375a87fad66ecebb87;hpb=dfc42b47c11051bae3026948c390e7bbeae4b854;p=tinyos-2.x.git diff --git a/tos/chips/rf230/RF230LayerP.nc b/tos/chips/rf230/RF230LayerP.nc index 2796fd4e..4ba79fca 100644 --- a/tos/chips/rf230/RF230LayerP.nc +++ b/tos/chips/rf230/RF230LayerP.nc @@ -25,6 +25,7 @@ #include #include #include +#include module RF230LayerP { @@ -54,10 +55,15 @@ module RF230LayerP interface BusyWait; - interface RF230Config; interface PacketField as PacketLinkQuality; interface PacketField as PacketTransmitPower; - interface PacketTimeStamp; + interface PacketField as PacketRSSI; + interface PacketField as PacketTimeSyncOffset; + + interface PacketTimeStamp; + interface LocalTime; + + interface RF230Config; interface Tasklet; interface RadioAlarm; @@ -144,19 +150,17 @@ implementation enum { - SLEEP_WAKEUP_TIME = (uint16_t)(880 * RF230_ALARM_MICROSEC), - CCA_REQUEST_TIME = (uint16_t)(140 * RF230_ALARM_MICROSEC), + SLEEP_WAKEUP_TIME = (uint16_t)(880 * RF230_ALARM_SEC / 1000000UL), + CCA_REQUEST_TIME = (uint16_t)(140 * RF230_ALARM_SEC / 1000000UL), - TX_SFD_DELAY = (uint16_t)(176 * RF230_ALARM_MICROSEC), - RX_SFD_DELAY = (uint16_t)(8 * RF230_ALARM_MICROSEC), + TX_SFD_DELAY = (uint16_t)(176 * RF230_ALARM_SEC / 1000000UL), + RX_SFD_DELAY = (uint16_t)(8 * RF230_ALARM_SEC / 1000000UL), }; tasklet_async event void RadioAlarm.fired() { if( state == STATE_SLEEP_2_TRX_OFF ) - { state = STATE_TRX_OFF; - } else if( cmd == CMD_CCA ) { uint8_t cca; @@ -233,7 +237,7 @@ implementation event void SpiResource.granted() { - // TODO: this should not be here, see my comment in HplRF230C.nc + call SELN.makeOutput(); call SELN.set(); if( state == STATE_P_ON ) @@ -252,7 +256,7 @@ implementation if( call SpiResource.immediateRequest() == SUCCESS ) { - // TODO: this should not be here, see my comment in HplRF230C.nc + call SELN.makeOutput(); call SELN.set(); return TRUE; @@ -310,15 +314,22 @@ implementation } else if( cmd == CMD_TURNON && state == STATE_TRX_OFF && isSpiAcquired() ) { + ASSERT( ! radioIrq ); + + readRegister(RF230_IRQ_STATUS); // clear the interrupt register call IRQ.captureRisingEdge(); + writeRegister(RF230_TRX_STATE, RF230_RX_ON); state = STATE_TRX_OFF_2_RX_ON; } else if( (cmd == CMD_TURNOFF || cmd == CMD_STANDBY) && state == STATE_RX_ON && isSpiAcquired() ) { - call IRQ.disable(); writeRegister(RF230_TRX_STATE, RF230_FORCE_TRX_OFF); + + call IRQ.disable(); + radioIrq = FALSE; + state = STATE_TRX_OFF; } @@ -380,17 +391,13 @@ implementation uint16_t time; uint8_t length; uint8_t* data; + uint8_t header; + uint32_t time32; + void* timesync; if( cmd != CMD_NONE || state != STATE_RX_ON || ! isSpiAcquired() || radioIrq ) return EBUSY; - if( call RF230Config.requiresRssiCca(msg) - && readRegister(RF230_PHY_RSSI) > ((rssiClear + rssiBusy) >> 3) ) - return EBUSY; - - writeRegister(RF230_TRX_STATE, RF230_PLL_ON); - - // do something useful, just to wait a little length = (call PacketTransmitPower.isSet(msg) ? call PacketTransmitPower.get(msg) : RF230_DEF_RFPOWER) & RF230_TX_PWR_MASK; @@ -400,6 +407,16 @@ implementation writeRegister(RF230_PHY_TX_PWR, RF230_TX_AUTO_CRC_ON | txPower); } + if( call RF230Config.requiresRssiCca(msg) + && (readRegister(RF230_PHY_RSSI) & RF230_RSSI_MASK) > ((rssiClear + rssiBusy) >> 3) ) + return EBUSY; + + writeRegister(RF230_TRX_STATE, RF230_PLL_ON); + + // do something useful, just to wait a little + time32 = call LocalTime.get(); + timesync = call PacketTimeSyncOffset.isSet(msg) ? msg->data + call PacketTimeSyncOffset.get(msg) : 0; + // we have missed an incoming message in this short amount of time if( (readRegister(RF230_TRX_STATUS) & RF230_TRX_STATUS_MASK) != RF230_PLL_ON ) { @@ -427,9 +444,26 @@ implementation // length | data[0] ... data[length-3] | automatically generated FCS call HplRF230.spiSplitReadWrite(length); - // the FCS is atomatically generated + // the FCS is atomatically generated (2 bytes) length -= 2; + header = call RF230Config.getHeaderLength(); + if( header > length ) + header = length; + + length -= header; + + // first upload the header to gain some time + do { + call HplRF230.spiSplitReadWrite(*(data++)); + } + while( --header != 0 ); + + time32 += (int16_t)(time) - (int16_t)(time32); + + if( timesync != 0 ) + *(timesync_relative_t*)timesync = (*(timesync_absolute_t*)timesync) - time32; + do { call HplRF230.spiSplitReadWrite(*(data++)); } @@ -439,11 +473,6 @@ implementation call HplRF230.spiSplitRead(); call SELN.set(); - length = readRegister(RF230_TRX_STATUS); - - // go back to RX_ON state when finished - writeRegister(RF230_TRX_STATE, RF230_RX_ON); - /* * There is a very small window (~1 microsecond) when the RF230 went * into PLL_ON state but was somehow not properly initialized because @@ -451,27 +480,31 @@ implementation * radio can even receive a message, and generate a TRX_UR interrupt * because of concurrent access, but that message probably cannot be * recovered. + * + * TODO: this needs to be verified, and make sure that the chip is + * not locked up in this case. */ - if( (length & RF230_TRX_STATUS_MASK) != RF230_BUSY_TX ) + + // go back to RX_ON state when finished + writeRegister(RF230_TRX_STATE, RF230_RX_ON); + +#ifdef RF230_DEBUG_MESSAGES + if( call DiagMsg.record() ) { -#ifdef RF230_DEBUG - if( call DiagMsg.record() ) - { - call DiagMsg.str("assert tx"); - call DiagMsg.uint16(call RadioAlarm.getNow()); - call DiagMsg.hex8(readRegister(RF230_TRX_STATUS)); - call DiagMsg.hex8(readRegister(RF230_TRX_STATE)); - call DiagMsg.hex8(radioIrq); - call DiagMsg.uint8(state); - call DiagMsg.uint8(cmd); - call DiagMsg.send(); - } -#endif - ASSERT( (length & RF230_TRX_STATUS_MASK) == RF230_PLL_ON ); - return FAIL; + length = call RF230Config.getLength(msg); + + call DiagMsg.str("tx"); + call DiagMsg.uint16(time); + call DiagMsg.uint8(length); + call DiagMsg.hex8s(data, length - 2); + call DiagMsg.send(); } +#endif - call PacketTimeStamp.set(msg, time); + if( timesync != 0 ) + *(timesync_absolute_t*)timesync = (*(timesync_relative_t*)timesync) + time32; + + call PacketTimeStamp.set(msg, time32); // wait for the TRX_END interrupt state = STATE_BUSY_TX_2_RX_ON; @@ -481,6 +514,7 @@ implementation } default tasklet_async event void RadioSend.sendDone(error_t error) { } + default tasklet_async event void RadioSend.ready() { } /*----------------- CCA -----------------*/ @@ -537,8 +571,10 @@ implementation length -= read; - while( read-- != 0 ) + do { crc = call HplRF230.crcByte(crc, *(data++) = call HplRF230.spiSplitReadWrite(0)); + } + while( --read != 0 ); if( signal RadioReceive.header(rxMsg) ) { @@ -558,6 +594,22 @@ implementation call SELN.set(); state = STATE_RX_ON; + +#ifdef RF230_DEBUG_MESSAGES + if( call DiagMsg.record() ) + { + length = call RF230Config.getLength(rxMsg); + + call DiagMsg.str("rx"); + call DiagMsg.uint32(call PacketTimeStamp.isValid(rxMsg) ? call PacketTimeStamp.timestamp(rxMsg) : 0); + call DiagMsg.uint16(call RadioAlarm.getNow()); + call DiagMsg.uint8(crc != 0); + call DiagMsg.uint8(length); + call DiagMsg.hex8s(call RF230Config.getPayload(rxMsg), length - 2); + call DiagMsg.send(); + } +#endif + cmd = CMD_NONE; // signal only if it has passed the CRC check @@ -585,7 +637,9 @@ implementation if( isSpiAcquired() ) { uint16_t time; + uint32_t time32; uint8_t irq; + uint8_t temp; atomic time = capturedTime; radioIrq = FALSE; @@ -593,7 +647,6 @@ implementation #ifdef RF230_DEBUG // TODO: handle this interrupt -// ASSERT( ! (irq & RF230_IRQ_TRX_UR) ); if( irq & RF230_IRQ_TRX_UR ) { if( call DiagMsg.record() ) @@ -639,8 +692,19 @@ implementation { ASSERT( state == STATE_RX_ON || state == STATE_PLL_ON_2_RX_ON ); - // the most likely place for busy channel - rssiBusy += readRegister(RF230_PHY_RSSI) - (rssiBusy >> 2); + // the most likely place for busy channel, with no TRX_END interrupt + if( irq == RF230_IRQ_RX_START ) + { + temp = readRegister(RF230_PHY_RSSI) & RF230_RSSI_MASK; + rssiBusy += temp - (rssiBusy >> 2); +#ifndef RF230_RSSI_ENERGY + call PacketRSSI.set(rxMsg, temp); + } + else + { + call PacketRSSI.clear(rxMsg); +#endif + } /* * The timestamp corresponds to the first event which could not @@ -651,28 +715,18 @@ implementation * CMD_TRANSMIT. */ if( irq == RF230_IRQ_RX_START ) // just to be cautious - call PacketTimeStamp.set(rxMsg, time - RX_SFD_DELAY); + { + time32 = call LocalTime.get(); + time32 += (int16_t)(time - RX_SFD_DELAY) - (int16_t)(time32); + call PacketTimeStamp.set(rxMsg, time32); + } else call PacketTimeStamp.clear(rxMsg); cmd = CMD_RECEIVE; } else - { -#ifdef RF230_DEBUG - if( call DiagMsg.record() ) - { - call DiagMsg.str("assert irq"); - call DiagMsg.uint16(call RadioAlarm.getNow()); - call DiagMsg.hex8(readRegister(RF230_TRX_STATUS)); - call DiagMsg.hex8(readRegister(RF230_TRX_STATE)); - call DiagMsg.hex8(irq); - call DiagMsg.uint8(state); - call DiagMsg.uint8(cmd); - call DiagMsg.send(); - } -#endif - } + ASSERT( cmd == CMD_TURNOFF ); } if( irq & RF230_IRQ_TRX_END ) @@ -691,7 +745,12 @@ implementation else if( cmd == CMD_RECEIVE ) { ASSERT( state == STATE_RX_ON || state == STATE_PLL_ON_2_RX_ON ); - +#ifdef RF230_RSSI_ENERGY + if( irq == RF230_IRQ_TRX_END ) + call PacketRSSI.set(rxMsg, readRegister(RF230_PHY_ED_LEVEL)); + else + call PacketRSSI.clear(rxMsg); +#endif if( state == STATE_PLL_ON_2_RX_ON ) { ASSERT( (readRegister(RF230_TRX_STATUS) & RF230_TRX_STATUS_MASK) == RF230_PLL_ON ); @@ -702,7 +761,7 @@ implementation else { // the most likely place for clear channel (hope to avoid acks) - rssiClear += readRegister(RF230_PHY_RSSI) - (rssiClear >> 2); + rssiClear += (readRegister(RF230_PHY_RSSI) & RF230_RSSI_MASK) - (rssiClear >> 2); } cmd = CMD_DOWNLOAD; @@ -734,7 +793,7 @@ implementation { if( cmd == CMD_DOWNLOAD ) downloadMessage(); - else if( cmd <= CMD_TURNON && CMD_TURNOFF <= cmd ) + else if( CMD_TURNOFF <= cmd && cmd <= CMD_TURNON ) changeState(); else if( cmd == CMD_CHANNEL ) changeChannel();