X-Git-Url: https://oss.titaniummirror.com/gitweb/?a=blobdiff_plain;f=tos%2Fchips%2Frf230%2FRF230LayerP.nc;h=85058a77ae29271d2bf52797a55947a62ab0623c;hb=e90b80efe22dc89b94b4d032715269849ff6796e;hp=e1d329800a6e9032b582f19a4d37767dff4fe9c0;hpb=67cebf25720a8aabec9aaa1bb335a3bf05169f2e;p=tinyos-2.x.git diff --git a/tos/chips/rf230/RF230LayerP.nc b/tos/chips/rf230/RF230LayerP.nc index e1d32980..85058a77 100644 --- a/tos/chips/rf230/RF230LayerP.nc +++ b/tos/chips/rf230/RF230LayerP.nc @@ -54,14 +54,21 @@ module RF230LayerP interface BusyWait; + interface PacketField as PacketLinkQuality; + interface PacketField as PacketTransmitPower; + interface PacketField as PacketRSSI; + interface PacketField as PacketTimeSyncOffset; + + interface PacketTimeStamp; + interface LocalTime; + interface RF230Config; interface Tasklet; + interface RadioAlarm; #ifdef RF230_DEBUG interface DiagMsg; #endif - - interface RadioAlarm; } } @@ -152,9 +159,7 @@ implementation 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; @@ -231,7 +236,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 ) @@ -250,7 +255,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; @@ -308,15 +313,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; } @@ -378,24 +390,30 @@ implementation uint16_t time; uint8_t length; uint8_t* data; + uint8_t header; + uint32_t time32; if( cmd != CMD_NONE || state != STATE_RX_ON || ! isSpiAcquired() || radioIrq ) return EBUSY; if( call RF230Config.requiresRssiCca(msg) - && readRegister(RF230_PHY_RSSI) > ((rssiClear + rssiBusy) >> 3) ) + && (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 - length = call RF230Config.getTransmitPower(msg) & RF230_TX_PWR_MASK; + length = (call PacketTransmitPower.isSet(msg) ? + call PacketTransmitPower.get(msg) : RF230_DEF_RFPOWER) & RF230_TX_PWR_MASK; + if( length != txPower ) { txPower = length; writeRegister(RF230_PHY_TX_PWR, RF230_TX_AUTO_CRC_ON | txPower); } + time32 = call LocalTime.get(); + // we have missed an incoming message in this short amount of time if( (readRegister(RF230_TRX_STATUS) & RF230_TRX_STATUS_MASK) != RF230_PLL_ON ) { @@ -408,7 +426,7 @@ implementation atomic { call SLP_TR.set(); - time = call RadioAlarm.getNow(); + time = call RadioAlarm.getNow() + TX_SFD_DELAY; } call SLP_TR.clr(); @@ -423,9 +441,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( call PacketTimeSyncOffset.isSet(msg) ) + ((timesync_footer_t*)(msg->data + call PacketTimeSyncOffset.get(msg)))->time_offset += time32; + do { call HplRF230.spiSplitReadWrite(*(data++)); } @@ -435,11 +470,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 @@ -447,28 +477,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 + + if( call PacketTimeSyncOffset.isSet(msg) ) + ((timesync_footer_t*)(msg->data + call PacketTimeSyncOffset.get(msg)))->time_offset -= time32; - time += TX_SFD_DELAY; - call RF230Config.setTimestamp(msg, time); + call PacketTimeStamp.set(msg, time32); // wait for the TRX_END interrupt state = STATE_BUSY_TX_2_RX_ON; @@ -478,6 +511,7 @@ implementation } default tasklet_async event void RadioSend.sendDone(error_t error) { } + default tasklet_async event void RadioSend.ready() { } /*----------------- CCA -----------------*/ @@ -534,8 +568,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) ) { @@ -545,7 +581,7 @@ implementation crc = call HplRF230.crcByte(crc, call HplRF230.spiSplitReadWrite(0)); crc = call HplRF230.crcByte(crc, call HplRF230.spiSplitReadWrite(0)); - call RF230Config.setLinkQuality(rxMsg, call HplRF230.spiSplitRead()); + call PacketLinkQuality.set(rxMsg, call HplRF230.spiSplitRead()); } else crc = 1; @@ -555,6 +591,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 @@ -582,7 +634,9 @@ implementation if( isSpiAcquired() ) { uint16_t time; + uint32_t time32; uint8_t irq; + uint8_t temp; atomic time = capturedTime; radioIrq = FALSE; @@ -590,7 +644,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() ) @@ -636,8 +689,21 @@ 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); + +#ifdef RF230_RSSI_ENERGY + temp = readRegister(RF230_PHY_ED_LEVEL); +#endif + + call PacketRSSI.set(rxMsg, temp); + } + else + call PacketRSSI.clear(rxMsg); /* * The timestamp corresponds to the first event which could not @@ -647,25 +713,19 @@ implementation * we could not be after a transmission, because then cmd = * CMD_TRANSMIT. */ - call RF230Config.setTimestamp(rxMsg, time - RX_SFD_DELAY); - cmd = CMD_RECEIVE; - } - else - { -#ifdef RF230_DEBUG - if( call DiagMsg.record() ) + if( irq == RF230_IRQ_RX_START ) // just to be cautious { - 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(); + time32 = call LocalTime.get(); + time32 += (int16_t)(time - RX_SFD_DELAY) - (int16_t)(time32); + call PacketTimeStamp.set(rxMsg, time32); } -#endif + else + call PacketTimeStamp.clear(rxMsg); + + cmd = CMD_RECEIVE; } + else + ASSERT( cmd == CMD_TURNOFF ); } if( irq & RF230_IRQ_TRX_END ) @@ -695,7 +755,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; @@ -727,7 +787,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();