event based mote interfaces + reimplemented cross level functionality for TR1001
This commit is contained in:
parent
c59fc91487
commit
1c22bf5151
|
@ -26,7 +26,7 @@
|
||||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
* SUCH DAMAGE.
|
* SUCH DAMAGE.
|
||||||
*
|
*
|
||||||
* $Id: SkyByteRadio.java,v 1.11 2009/05/04 15:34:00 fros4943 Exp $
|
* $Id: SkyByteRadio.java,v 1.12 2009/05/26 14:33:30 fros4943 Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package se.sics.cooja.mspmote.interfaces;
|
package se.sics.cooja.mspmote.interfaces;
|
||||||
|
@ -74,7 +74,6 @@ public class SkyByteRadio extends Radio implements CustomDataRadio {
|
||||||
private boolean isTransmitting = false;
|
private boolean isTransmitting = false;
|
||||||
|
|
||||||
private boolean isReceiving = false;
|
private boolean isReceiving = false;
|
||||||
// private boolean hasFailedReception = false;
|
|
||||||
|
|
||||||
private CC2420RadioByte lastOutgoingByte = null;
|
private CC2420RadioByte lastOutgoingByte = null;
|
||||||
|
|
||||||
|
@ -84,10 +83,6 @@ public class SkyByteRadio extends Radio implements CustomDataRadio {
|
||||||
|
|
||||||
private RadioPacket lastIncomingPacket = null;
|
private RadioPacket lastIncomingPacket = null;
|
||||||
|
|
||||||
// private int mode;
|
|
||||||
|
|
||||||
//TODO: HW on/off
|
|
||||||
|
|
||||||
public SkyByteRadio(Mote mote) {
|
public SkyByteRadio(Mote mote) {
|
||||||
this.mote = (SkyMote) mote;
|
this.mote = (SkyMote) mote;
|
||||||
this.cc2420 = this.mote.skyNode.radio;
|
this.cc2420 = this.mote.skyNode.radio;
|
||||||
|
@ -167,15 +162,14 @@ public class SkyByteRadio extends Radio implements CustomDataRadio {
|
||||||
|
|
||||||
private byte[] crossBufferedData = null;
|
private byte[] crossBufferedData = null;
|
||||||
|
|
||||||
private TimeEvent receiveCrosslevelDataEvent = new TimeEvent(0) {
|
private TimeEvent deliverPacketDataEvent = new TimeEvent(0) {
|
||||||
public void execute(long t) {
|
public void execute(long t) {
|
||||||
|
|
||||||
if (crossBufferedData == null) {
|
if (crossBufferedData == null) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*logger.info("Radio is now ready to receive the incoming data");*/
|
/*logger.info("Delivering buffered packet data now: " + mote.getSimulation().getSimulationTime());*/
|
||||||
|
|
||||||
for (byte b: crossBufferedData) {
|
for (byte b: crossBufferedData) {
|
||||||
cc2420.receivedByte(b);
|
cc2420.receivedByte(b);
|
||||||
}
|
}
|
||||||
|
@ -185,31 +179,32 @@ public class SkyByteRadio extends Radio implements CustomDataRadio {
|
||||||
|
|
||||||
private StateListener cc2420StateListener = new StateListener() {
|
private StateListener cc2420StateListener = new StateListener() {
|
||||||
public void newState(RadioState state) {
|
public void newState(RadioState state) {
|
||||||
if (cc2420.getState() == CC2420.RadioState.RX_SFD_SEARCH) {
|
if (cc2420.getState() != CC2420.RadioState.RX_SFD_SEARCH) {
|
||||||
cc2420.setStateListener(null);
|
return;
|
||||||
|
|
||||||
if (crossBufferedData == null) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Receive data very soon (just wait for a radio flush) */
|
|
||||||
mote.getSimulation().scheduleEvent(
|
|
||||||
receiveCrosslevelDataEvent,
|
|
||||||
mote.getSimulation().getSimulationTime()+1
|
|
||||||
);
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
cc2420.setStateListener(null);
|
||||||
|
|
||||||
|
if (crossBufferedData == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*logger.info("Radio was turned on! Short delay before transmitting buffered data: " + mote.getSimulation().getSimulationTime());*/
|
||||||
|
|
||||||
|
/* Deliver data after the radio drivers flush */
|
||||||
|
mote.getSimulation().scheduleEvent(
|
||||||
|
deliverPacketDataEvent,
|
||||||
|
mote.getSimulation().getSimulationTime()+Simulation.MILLISECOND/3
|
||||||
|
);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
public void setReceivedPacket(RadioPacket packet) {
|
public void setReceivedPacket(RadioPacket packet) {
|
||||||
lastIncomingPacket = packet;
|
lastIncomingPacket = packet;
|
||||||
|
|
||||||
/* TODO Receiving all bytes at the same time ok? */
|
|
||||||
byte[] packetData = CC2420RadioPacketConverter.fromCoojaToCC2420(packet);
|
byte[] packetData = CC2420RadioPacketConverter.fromCoojaToCC2420(packet);
|
||||||
|
|
||||||
if (cc2420.getState() != CC2420.RadioState.RX_SFD_SEARCH) {
|
if (cc2420.getState() != CC2420.RadioState.RX_SFD_SEARCH) {
|
||||||
/*logger.info("Radio is not currently active. Let's wait some...");*/
|
/*logger.info("Radio is turned off. Buffering data.");*/
|
||||||
|
|
||||||
crossBufferedData = packetData;
|
crossBufferedData = packetData;
|
||||||
cc2420.setStateListener(cc2420StateListener);
|
cc2420.setStateListener(cc2420StateListener);
|
||||||
|
@ -218,6 +213,7 @@ public class SkyByteRadio extends Radio implements CustomDataRadio {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Delivering data immediately */
|
||||||
for (byte b: packetData) {
|
for (byte b: packetData) {
|
||||||
cc2420.receivedByte(b);
|
cc2420.receivedByte(b);
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,7 +26,7 @@
|
||||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
* SUCH DAMAGE.
|
* SUCH DAMAGE.
|
||||||
*
|
*
|
||||||
* $Id: TR1001Radio.java,v 1.12 2009/04/16 14:28:12 fros4943 Exp $
|
* $Id: TR1001Radio.java,v 1.13 2009/05/26 14:33:30 fros4943 Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package se.sics.cooja.mspmote.interfaces;
|
package se.sics.cooja.mspmote.interfaces;
|
||||||
|
@ -52,19 +52,23 @@ import se.sics.cooja.mspmote.ESBMote;
|
||||||
* @author Fredrik Osterlind
|
* @author Fredrik Osterlind
|
||||||
*/
|
*/
|
||||||
@ClassDescription("TR1001 Radio")
|
@ClassDescription("TR1001 Radio")
|
||||||
public class TR1001Radio extends Radio implements USARTListener, CustomDataRadio {
|
public class TR1001Radio extends Radio implements USARTListener,
|
||||||
|
CustomDataRadio {
|
||||||
private static Logger logger = Logger.getLogger(TR1001Radio.class);
|
private static Logger logger = Logger.getLogger(TR1001Radio.class);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Minimum delay in CPU cycles between each byte fed to USART.
|
* Delay used when feeding packet data to radio chip (us). 416us corresponds
|
||||||
|
* to 19200 bit/s with encoding.
|
||||||
*/
|
*/
|
||||||
public static final long CYCLES_BETWEEN_BYTES = 1200; /* ~19.200 bps */
|
public static final long DELAY_BETWEEN_BYTES = 3 * 416;
|
||||||
|
|
||||||
private ESBMote mote;
|
private ESBMote mote;
|
||||||
|
|
||||||
private boolean radioOn = true;
|
private boolean radioOn = true;
|
||||||
|
|
||||||
private boolean transmitting = false;
|
private boolean isTransmitting = false;
|
||||||
|
|
||||||
|
private boolean isReceiving = false;
|
||||||
|
|
||||||
private boolean isInterfered = false;
|
private boolean isInterfered = false;
|
||||||
|
|
||||||
|
@ -74,7 +78,7 @@ public class TR1001Radio extends Radio implements USARTListener, CustomDataRadio
|
||||||
|
|
||||||
private USART radioUSART = null;
|
private USART radioUSART = null;
|
||||||
|
|
||||||
private RadioPacket packetToMote = null;
|
private RadioPacket lastIncomingPacket = null;
|
||||||
|
|
||||||
private RadioPacket packetFromMote = null;
|
private RadioPacket packetFromMote = null;
|
||||||
|
|
||||||
|
@ -83,27 +87,15 @@ public class TR1001Radio extends Radio implements USARTListener, CustomDataRadio
|
||||||
|
|
||||||
private int outgoingDataLength = 0;
|
private int outgoingDataLength = 0;
|
||||||
|
|
||||||
private int ticksSinceLastSend = -1;
|
private int millisSinceLastSend = -1;
|
||||||
|
|
||||||
/* Incoming byte-to-packet data buffer */
|
|
||||||
private Vector<Byte> bufferedBytes = new Vector<Byte>();
|
|
||||||
|
|
||||||
private Vector<Long> bufferedByteDelays = new Vector<Long>();
|
|
||||||
|
|
||||||
/* Outgoing byte data buffer */
|
/* Outgoing byte data buffer */
|
||||||
private TR1001RadioByte tr1001ByteFromMote = null;
|
private TR1001RadioByte tr1001ByteFromMote = null;
|
||||||
|
|
||||||
private TR1001RadioByte tr1001ByteToMote = null;
|
private TR1001RadioByte lastIncomingByte = null;
|
||||||
|
|
||||||
private long transmissionStartCycles = -1;
|
private long transmissionStartCycles = -1;
|
||||||
|
|
||||||
/* Incoming byte data buffer */
|
|
||||||
private byte lastDeliveredByte = -1;
|
|
||||||
|
|
||||||
private long lastDeliveredByteTimestamp = -1;
|
|
||||||
|
|
||||||
private long lastDeliveredByteDelay = -1;
|
|
||||||
|
|
||||||
private TR1001RadioPacketConverter tr1001PacketConverter = null;
|
private TR1001RadioPacketConverter tr1001PacketConverter = null;
|
||||||
|
|
||||||
private double signalStrength = 0;
|
private double signalStrength = 0;
|
||||||
|
@ -133,28 +125,34 @@ public class TR1001Radio extends Radio implements USARTListener, CustomDataRadio
|
||||||
}
|
}
|
||||||
|
|
||||||
public RadioPacket getLastPacketReceived() {
|
public RadioPacket getLastPacketReceived() {
|
||||||
return packetToMote;
|
return lastIncomingPacket;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setReceivedPacket(RadioPacket packet) {
|
public void setReceivedPacket(RadioPacket packet) {
|
||||||
packetToMote = packet;
|
lastIncomingPacket = packet;
|
||||||
if (packetToMote.getPacketData() == null || packetToMote.getPacketData().length == 0) {
|
|
||||||
logger.fatal("Received null packet");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (isInterfered) {
|
|
||||||
logger.fatal("Received packet when interfered");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Convert to TR1001 packet data */
|
/* Convert to TR1001 packet data */
|
||||||
TR1001RadioByte[] tr1001bytes = TR1001RadioPacketConverter.fromCoojaToTR1001(packetToMote);
|
TR1001RadioByte[] byteArr = TR1001RadioPacketConverter.fromCoojaToTR1001(packet);
|
||||||
|
final ArrayList<TR1001RadioByte> byteList = new ArrayList<TR1001RadioByte>();
|
||||||
/* Feed to the CPU "slowly" */
|
for (TR1001RadioByte b : byteArr) {
|
||||||
for (TR1001RadioByte b : tr1001bytes) {
|
byteList.add(b);
|
||||||
receiveCustomData(b);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Feed incoming bytes to radio "slowly" via time events */
|
||||||
|
TimeEvent receiveCrosslevelDataEvent = new TimeEvent(0) {
|
||||||
|
public void execute(long t) {
|
||||||
|
/* Stop receiving data when buffer is empty */
|
||||||
|
if (byteList.isEmpty() || isInterfered) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
TR1001RadioByte b = byteList.remove(0);
|
||||||
|
radioUSART.byteReceived(b.getByte());
|
||||||
|
|
||||||
|
mote.getSimulation().scheduleEvent(this, t + DELAY_BETWEEN_BYTES);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
receiveCrosslevelDataEvent.execute(mote.getSimulation().getSimulationTime());
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Custom data radio support */
|
/* Custom data radio support */
|
||||||
|
@ -163,84 +161,32 @@ public class TR1001Radio extends Radio implements USARTListener, CustomDataRadio
|
||||||
}
|
}
|
||||||
|
|
||||||
public Object getLastCustomDataReceived() {
|
public Object getLastCustomDataReceived() {
|
||||||
return tr1001ByteToMote;
|
return lastIncomingByte;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void receiveCustomData(Object data) {
|
public void receiveCustomData(Object data) {
|
||||||
if (data instanceof TR1001RadioByte) {
|
if (data instanceof TR1001RadioByte) {
|
||||||
tr1001ByteToMote = ((TR1001RadioByte) data);
|
lastIncomingByte = ((TR1001RadioByte) data);
|
||||||
|
|
||||||
bufferedBytes.add(tr1001ByteToMote.getByte());
|
if (radioUSART.isReceiveFlagCleared()) {
|
||||||
bufferedByteDelays.add(tr1001ByteToMote.getDelay());
|
/*logger.info("----- TR1001 RECEIVED BYTE -----");*/
|
||||||
|
radioUSART.byteReceived(lastIncomingByte.getByte());
|
||||||
|
} else {
|
||||||
|
logger.warn("----- TR1001 RECEIVED BYTE DROPPED -----");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @return True if undelivered bytes exist.
|
|
||||||
*/
|
|
||||||
public boolean hasPendingBytes() {
|
|
||||||
return bufferedBytes.size() > 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* If non-delivered bytes exist, tries to deliver one byte to the CPU by
|
|
||||||
* checking USART receive flag.
|
|
||||||
*
|
|
||||||
* @param cycles
|
|
||||||
* Current CPU cycles
|
|
||||||
*/
|
|
||||||
public void tryDeliverNextByte(long cycles) {
|
|
||||||
// Check that pending bytes exist
|
|
||||||
if (!hasPendingBytes()) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check if time to deliver byte
|
|
||||||
long nextByteDelay = bufferedByteDelays.firstElement();
|
|
||||||
if (cycles - lastDeliveredByteDelay < nextByteDelay) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
lastDeliveredByte = bufferedBytes.firstElement();
|
|
||||||
|
|
||||||
bufferedBytes.remove(0);
|
|
||||||
bufferedByteDelays.remove(0);
|
|
||||||
|
|
||||||
if (radioUSART.isReceiveFlagCleared()) {
|
|
||||||
//logger.info(nextByteDelay + " < "
|
|
||||||
// + (cycles - receptionStartedCycles)
|
|
||||||
// + ":\tDelivering 0x" + Utils.hex8(lastDeliveredByte) + " (TODO="
|
|
||||||
// + bufferedBytes.size() + ")");
|
|
||||||
radioUSART.byteReceived(lastDeliveredByte);
|
|
||||||
} else {
|
|
||||||
/*logger.fatal(nextByteDelay + " < "
|
|
||||||
+ (cycles - receptionStartedCycles)
|
|
||||||
+ ":\tDROPPING 0x" + Utils.hex8(lastDeliveredByte) + " (TODO="
|
|
||||||
+ bufferedBytes.size() + ")");*/
|
|
||||||
}
|
|
||||||
lastDeliveredByteDelay = cycles;
|
|
||||||
|
|
||||||
// /* TODO BUG: Resends last byte, interrupt lost somewhere? */
|
|
||||||
// else if (cycles > lastDeliveredByteTimestamp + CYCLES_BETWEEN_BYTES) {
|
|
||||||
// logger.warn("0x" + Utils.hex16((int) cycles) + ":\tRedelivering 0x"
|
|
||||||
// + Utils.hex8(lastDeliveredByte) + " (TODO=" + bufferedBytes.size()
|
|
||||||
// + ")");
|
|
||||||
// radioUSART.byteReceived(lastDeliveredByte);
|
|
||||||
// lastDeliveredByteTimestamp = cycles;
|
|
||||||
// }
|
|
||||||
}
|
|
||||||
|
|
||||||
/* USART listener support */
|
/* USART listener support */
|
||||||
public void dataReceived(USART source, int data) {
|
public void dataReceived(USART source, int data) {
|
||||||
if (outgoingDataLength == 0 && !isTransmitting()) {
|
if (outgoingDataLength == 0 && !isTransmitting()) {
|
||||||
/* New transmission discovered */
|
/* New transmission discovered */
|
||||||
/*logger.debug("----- NEW TR1001 TRANSMISSION DETECTED -----");*/
|
/*logger.info("----- NEW TR1001 TRANSMISSION DETECTED -----");*/
|
||||||
tr1001PacketConverter = new TR1001RadioPacketConverter();
|
tr1001PacketConverter = new TR1001RadioPacketConverter();
|
||||||
|
|
||||||
transmitting = true;
|
isTransmitting = true;
|
||||||
|
|
||||||
transmissionStartCycles = mote.getCPU().cycles;
|
transmissionStartCycles = mote.getCPU().cycles;
|
||||||
lastDeliveredByteTimestamp = transmissionStartCycles;
|
|
||||||
|
|
||||||
lastEvent = RadioEvent.TRANSMISSION_STARTED;
|
lastEvent = RadioEvent.TRANSMISSION_STARTED;
|
||||||
lastEventTime = mote.getSimulation().getSimulationTime();
|
lastEventTime = mote.getSimulation().getSimulationTime();
|
||||||
|
@ -249,49 +195,51 @@ public class TR1001Radio extends Radio implements USARTListener, CustomDataRadio
|
||||||
}
|
}
|
||||||
|
|
||||||
// Remember recent radio activity
|
// Remember recent radio activity
|
||||||
ticksSinceLastSend = 0;
|
millisSinceLastSend = 0;
|
||||||
mote.getSimulation().scheduleEvent(followupTransmissionEvent, mote.getSimulation().getSimulationTime()+1);
|
mote.getSimulation().scheduleEvent(
|
||||||
|
followupTransmissionEvent,
|
||||||
|
mote.getSimulation().getSimulationTime() + Simulation.MILLISECOND);
|
||||||
|
|
||||||
if (outgoingDataLength >= outgoingData.length) {
|
if (outgoingDataLength >= outgoingData.length) {
|
||||||
logger.fatal("Ignoring byte due to buffer overflow");
|
logger.warn("----- TR1001 DROPPING OUTGOING BYTE (buffer overflow) -----");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Deliver byte to radio medium as custom data
|
// Deliver byte to radio medium as custom data
|
||||||
/*logger.debug("----- TR1001 DELIVERED BYTE -----");*/
|
/* logger.debug("----- TR1001 SENT BYTE -----"); */
|
||||||
lastEvent = RadioEvent.CUSTOM_DATA_TRANSMITTED;
|
lastEvent = RadioEvent.CUSTOM_DATA_TRANSMITTED;
|
||||||
tr1001ByteFromMote = new TR1001RadioByte((byte) data, mote.getCPU().cycles - lastDeliveredByteTimestamp);
|
tr1001ByteFromMote = new TR1001RadioByte((byte) data);
|
||||||
this.setChanged();
|
this.setChanged();
|
||||||
this.notifyObservers();
|
this.notifyObservers();
|
||||||
|
|
||||||
lastDeliveredByteTimestamp = mote.getCPU().cycles;
|
|
||||||
outgoingData[outgoingDataLength++] = tr1001ByteFromMote;
|
outgoingData[outgoingDataLength++] = tr1001ByteFromMote;
|
||||||
|
|
||||||
// Feed to application level immediately
|
// Feed to application level immediately
|
||||||
boolean finished = tr1001PacketConverter.fromTR1001ToCoojaAccumulated(tr1001ByteFromMote);
|
boolean finished = tr1001PacketConverter
|
||||||
|
.fromTR1001ToCoojaAccumulated(tr1001ByteFromMote);
|
||||||
if (finished) {
|
if (finished) {
|
||||||
/* Transmission finished - deliver packet immediately */
|
/* Transmission finished - deliver packet immediately */
|
||||||
if (tr1001PacketConverter.accumulatedConversionIsOk()) {
|
if (tr1001PacketConverter.accumulatedConversionIsOk()) {
|
||||||
packetFromMote = tr1001PacketConverter.getAccumulatedConvertedCoojaPacket();
|
packetFromMote = tr1001PacketConverter.getAccumulatedConvertedCoojaPacket();
|
||||||
|
|
||||||
/* Notify observers of new prepared packet */
|
/* Notify observers of new prepared packet */
|
||||||
/*logger.debug("----- TR1001 DELIVERED PACKET -----");*/
|
/* logger.info("----- TR1001 DELIVERED PACKET -----"); */
|
||||||
lastEvent = RadioEvent.PACKET_TRANSMITTED;
|
lastEvent = RadioEvent.PACKET_TRANSMITTED;
|
||||||
this.setChanged();
|
|
||||||
this.notifyObservers();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Reset counters and wait for next packet
|
|
||||||
outgoingDataLength = 0;
|
|
||||||
ticksSinceLastSend = -1;
|
|
||||||
|
|
||||||
// Signal we are done transmitting
|
|
||||||
transmitting = false;
|
|
||||||
lastEvent = RadioEvent.TRANSMISSION_FINISHED;
|
|
||||||
this.setChanged();
|
this.setChanged();
|
||||||
this.notifyObservers();
|
this.notifyObservers();
|
||||||
|
}
|
||||||
|
|
||||||
/*logger.debug("----- TR1001 TRANSMISSION ENDED -----");*/
|
// Reset counters and wait for next packet
|
||||||
|
outgoingDataLength = 0;
|
||||||
|
millisSinceLastSend = -1;
|
||||||
|
|
||||||
|
// Signal we are done transmitting
|
||||||
|
isTransmitting = false;
|
||||||
|
lastEvent = RadioEvent.TRANSMISSION_FINISHED;
|
||||||
|
this.setChanged();
|
||||||
|
this.notifyObservers();
|
||||||
|
|
||||||
|
/* logger.info("----- TR1001 TRANSMISSION ENDED -----"); */
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -300,11 +248,11 @@ public class TR1001Radio extends Radio implements USARTListener, CustomDataRadio
|
||||||
|
|
||||||
/* General radio support */
|
/* General radio support */
|
||||||
public boolean isTransmitting() {
|
public boolean isTransmitting() {
|
||||||
return transmitting;
|
return isTransmitting;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isReceiving() {
|
public boolean isReceiving() {
|
||||||
return hasPendingBytes();
|
return isReceiving;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isInterfered() {
|
public boolean isInterfered() {
|
||||||
|
@ -317,18 +265,14 @@ public class TR1001Radio extends Radio implements USARTListener, CustomDataRadio
|
||||||
|
|
||||||
public void signalReceptionStart() {
|
public void signalReceptionStart() {
|
||||||
lastEvent = RadioEvent.RECEPTION_STARTED;
|
lastEvent = RadioEvent.RECEPTION_STARTED;
|
||||||
/*receptionStartedCycles = mspMote.getCPU().cycles;*/
|
isReceiving = true;
|
||||||
this.setChanged();
|
this.setChanged();
|
||||||
this.notifyObservers();
|
this.notifyObservers();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void signalReceptionEnd() {
|
public void signalReceptionEnd() {
|
||||||
// TODO Should be done according to serial port instead
|
isInterfered = false;
|
||||||
// TODO Compare times with OS abstraction level
|
isReceiving = false;
|
||||||
if (isInterfered()) {
|
|
||||||
isInterfered = false;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
lastEvent = RadioEvent.RECEPTION_FINISHED;
|
lastEvent = RadioEvent.RECEPTION_FINISHED;
|
||||||
this.setChanged();
|
this.setChanged();
|
||||||
this.notifyObservers();
|
this.notifyObservers();
|
||||||
|
@ -341,12 +285,11 @@ public class TR1001Radio extends Radio implements USARTListener, CustomDataRadio
|
||||||
public void interfereAnyReception() {
|
public void interfereAnyReception() {
|
||||||
if (!isInterfered()) {
|
if (!isInterfered()) {
|
||||||
isInterfered = true;
|
isInterfered = true;
|
||||||
|
lastIncomingPacket = null;
|
||||||
|
|
||||||
bufferedBytes.clear();
|
|
||||||
bufferedByteDelays.clear();
|
|
||||||
|
|
||||||
lastEvent = RadioEvent.RECEPTION_INTERFERED;
|
|
||||||
lastEventTime = mote.getSimulation().getSimulationTime();
|
lastEventTime = mote.getSimulation().getSimulationTime();
|
||||||
|
lastEvent = RadioEvent.RECEPTION_INTERFERED;
|
||||||
|
/*logger.info("----- TR1001 RECEPTION INTERFERED -----");*/
|
||||||
this.setChanged();
|
this.setChanged();
|
||||||
this.notifyObservers();
|
this.notifyObservers();
|
||||||
}
|
}
|
||||||
|
@ -382,19 +325,19 @@ public class TR1001Radio extends Radio implements USARTListener, CustomDataRadio
|
||||||
public void execute(long t) {
|
public void execute(long t) {
|
||||||
|
|
||||||
if (isTransmitting()) {
|
if (isTransmitting()) {
|
||||||
ticksSinceLastSend++;
|
millisSinceLastSend++;
|
||||||
|
|
||||||
// Detect transmission end due to inactivity
|
// Detect transmission end due to inactivity
|
||||||
if (ticksSinceLastSend > 4) {
|
if (millisSinceLastSend > 5) {
|
||||||
/* Dropping packet due to inactivity */
|
/* Dropping packet due to inactivity */
|
||||||
packetFromMote = null;
|
packetFromMote = null;
|
||||||
|
|
||||||
/* Reset counters and wait for next packet */
|
/* Reset counters and wait for next packet */
|
||||||
outgoingDataLength = 0;
|
outgoingDataLength = 0;
|
||||||
ticksSinceLastSend = -1;
|
millisSinceLastSend = -1;
|
||||||
|
|
||||||
/* Signal we are done transmitting */
|
/* Signal we are done transmitting */
|
||||||
transmitting = false;
|
isTransmitting = false;
|
||||||
lastEvent = RadioEvent.TRANSMISSION_FINISHED;
|
lastEvent = RadioEvent.TRANSMISSION_FINISHED;
|
||||||
TR1001Radio.this.setChanged();
|
TR1001Radio.this.setChanged();
|
||||||
TR1001Radio.this.notifyObservers();
|
TR1001Radio.this.notifyObservers();
|
||||||
|
@ -403,7 +346,7 @@ public class TR1001Radio extends Radio implements USARTListener, CustomDataRadio
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Reschedule as long as node is transmitting */
|
/* Reschedule as long as node is transmitting */
|
||||||
mote.getSimulation().scheduleEvent(this, t+1);
|
mote.getSimulation().scheduleEvent(this, t + Simulation.MILLISECOND);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -440,7 +383,9 @@ public class TR1001Radio extends Radio implements USARTListener, CustomDataRadio
|
||||||
|
|
||||||
updateButton.addActionListener(new ActionListener() {
|
updateButton.addActionListener(new ActionListener() {
|
||||||
public void actionPerformed(ActionEvent e) {
|
public void actionPerformed(ActionEvent e) {
|
||||||
powerLabel.setText(getCurrentOutputPower() + " dBm (indicator=" + getCurrentOutputPowerIndicator() + "/" + getOutputPowerIndicatorMax() + ")");
|
powerLabel.setText(getCurrentOutputPower() + " dBm (indicator="
|
||||||
|
+ getCurrentOutputPowerIndicator() + "/"
|
||||||
|
+ getOutputPowerIndicatorMax() + ")");
|
||||||
ssLabel.setText(getCurrentSignalStrength() + " dBm");
|
ssLabel.setText(getCurrentSignalStrength() + " dBm");
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -460,7 +405,9 @@ public class TR1001Radio extends Radio implements USARTListener, CustomDataRadio
|
||||||
|
|
||||||
lastEventLabel.setText(lastEvent + " @ time=" + lastEventTime);
|
lastEventLabel.setText(lastEvent + " @ time=" + lastEventTime);
|
||||||
|
|
||||||
powerLabel.setText(getCurrentOutputPower() + " dBm (indicator=" + getCurrentOutputPowerIndicator() + "/" + getOutputPowerIndicatorMax() + ")");
|
powerLabel.setText(getCurrentOutputPower() + " dBm (indicator="
|
||||||
|
+ getCurrentOutputPowerIndicator() + "/"
|
||||||
|
+ getOutputPowerIndicatorMax() + ")");
|
||||||
ssLabel.setText(getCurrentSignalStrength() + " dBm");
|
ssLabel.setText(getCurrentSignalStrength() + " dBm");
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
|
@ -26,7 +26,7 @@
|
||||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
* SUCH DAMAGE.
|
* SUCH DAMAGE.
|
||||||
*
|
*
|
||||||
* $Id: TR1001RadioByte.java,v 1.1 2008/03/18 13:08:26 fros4943 Exp $
|
* $Id: TR1001RadioByte.java,v 1.2 2009/05/26 14:33:30 fros4943 Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package se.sics.cooja.mspmote.interfaces;
|
package se.sics.cooja.mspmote.interfaces;
|
||||||
|
@ -40,14 +40,11 @@ public class TR1001RadioByte {
|
||||||
|
|
||||||
private byte b;
|
private byte b;
|
||||||
|
|
||||||
private long delay;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates new TR1001 radio byte
|
* Creates new TR1001 radio byte
|
||||||
*/
|
*/
|
||||||
public TR1001RadioByte(byte b, long delay) {
|
public TR1001RadioByte(byte b) {
|
||||||
this.b = b;
|
this.b = b;
|
||||||
this.delay = delay;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -57,11 +54,4 @@ public class TR1001RadioByte {
|
||||||
return b;
|
return b;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @return Cycle delay since previous byte
|
|
||||||
*/
|
|
||||||
public long getDelay() {
|
|
||||||
return delay;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,14 +26,16 @@
|
||||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
* SUCH DAMAGE.
|
* SUCH DAMAGE.
|
||||||
*
|
*
|
||||||
* $Id: TR1001RadioPacketConverter.java,v 1.3 2008/03/18 16:55:44 fros4943 Exp $
|
* $Id: TR1001RadioPacketConverter.java,v 1.4 2009/05/26 14:33:30 fros4943 Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package se.sics.cooja.mspmote.interfaces;
|
package se.sics.cooja.mspmote.interfaces;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
import org.apache.log4j.Logger;
|
import org.apache.log4j.Logger;
|
||||||
|
|
||||||
import se.sics.cooja.COOJARadioPacket;
|
import se.sics.cooja.COOJARadioPacket;
|
||||||
|
import se.sics.cooja.ConvertedRadioPacket;
|
||||||
import se.sics.cooja.RadioPacket;
|
import se.sics.cooja.RadioPacket;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -66,6 +68,7 @@ public class TR1001RadioPacketConverter {
|
||||||
|
|
||||||
final static int ESB_FOOTER_LENGTH = 2;
|
final static int ESB_FOOTER_LENGTH = 2;
|
||||||
|
|
||||||
|
private ArrayList<TR1001RadioByte> originalData = new ArrayList<TR1001RadioByte>();
|
||||||
|
|
||||||
private enum AccumulatedConversionState {
|
private enum AccumulatedConversionState {
|
||||||
TR1001_PREAMBLE, TR1001_SYNCH, ESB_LEN1, ESB_LEN2, ESB_DATA, ESB_CRC1, ESB_CRC2, ESB_POST,
|
TR1001_PREAMBLE, TR1001_SYNCH, ESB_LEN1, ESB_LEN2, ESB_DATA, ESB_CRC1, ESB_CRC2, ESB_POST,
|
||||||
|
@ -141,7 +144,7 @@ public class TR1001RadioPacketConverter {
|
||||||
|
|
||||||
TR1001RadioByte[] tr1001Bytes = new TR1001RadioByte[tr1001Frame.length];
|
TR1001RadioByte[] tr1001Bytes = new TR1001RadioByte[tr1001Frame.length];
|
||||||
for (int i=0; i < tr1001Frame.length; i++) {
|
for (int i=0; i < tr1001Frame.length; i++) {
|
||||||
tr1001Bytes[i] = new TR1001RadioByte(tr1001Frame[i], TR1001Radio.CYCLES_BETWEEN_BYTES);
|
tr1001Bytes[i] = new TR1001RadioByte(tr1001Frame[i]);
|
||||||
}
|
}
|
||||||
return tr1001Bytes;
|
return tr1001Bytes;
|
||||||
}
|
}
|
||||||
|
@ -160,7 +163,7 @@ public class TR1001RadioPacketConverter {
|
||||||
* @param tr1001DataLength TR1001 specified packet length
|
* @param tr1001DataLength TR1001 specified packet length
|
||||||
* @return COOJA radio packet
|
* @return COOJA radio packet
|
||||||
*/
|
*/
|
||||||
public static RadioPacket fromTR1001ToCooja(TR1001RadioByte[] tr1001Bytes, int tr1001DataLength) {
|
public static ConvertedRadioPacket fromTR1001ToCooja(TR1001RadioByte[] tr1001Bytes, int tr1001DataLength) {
|
||||||
|
|
||||||
byte[] tr1001Data = new byte[tr1001Bytes.length];
|
byte[] tr1001Data = new byte[tr1001Bytes.length];
|
||||||
for (int i=0; i < tr1001Bytes.length; i++) {
|
for (int i=0; i < tr1001Bytes.length; i++) {
|
||||||
|
@ -192,11 +195,11 @@ public class TR1001RadioPacketConverter {
|
||||||
System.arraycopy(decodedData, ESB_HEADER_LENGTH, packetData, 0,
|
System.arraycopy(decodedData, ESB_HEADER_LENGTH, packetData, 0,
|
||||||
dataLength);
|
dataLength);
|
||||||
|
|
||||||
return new COOJARadioPacket(packetData);
|
return new ConvertedRadioPacket(packetData, tr1001Data);
|
||||||
}
|
}
|
||||||
|
|
||||||
logger.fatal("Error when converting emulated to application level, returning null packet");
|
logger.warn("No cross-level conversion available: TR1001 GCR decoding failed");
|
||||||
return null;
|
return new ConvertedRadioPacket(new byte[0], tr1001Data);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -241,6 +244,7 @@ public class TR1001RadioPacketConverter {
|
||||||
*/
|
*/
|
||||||
public boolean fromTR1001ToCoojaAccumulated(TR1001RadioByte tr1001Byte) {
|
public boolean fromTR1001ToCoojaAccumulated(TR1001RadioByte tr1001Byte) {
|
||||||
byte b = tr1001Byte.getByte();
|
byte b = tr1001Byte.getByte();
|
||||||
|
originalData.add(tr1001Byte);
|
||||||
|
|
||||||
if (accumulatedConversionState == AccumulatedConversionState.TR1001_PREAMBLE) {
|
if (accumulatedConversionState == AccumulatedConversionState.TR1001_PREAMBLE) {
|
||||||
if (b == (byte) 0xaa || b == (byte) 0xff) {
|
if (b == (byte) 0xaa || b == (byte) 0xff) {
|
||||||
|
@ -311,12 +315,18 @@ public class TR1001RadioPacketConverter {
|
||||||
/**
|
/**
|
||||||
* @return Converted data (application level)
|
* @return Converted data (application level)
|
||||||
*/
|
*/
|
||||||
public RadioPacket getAccumulatedConvertedCoojaPacket() {
|
public ConvertedRadioPacket getAccumulatedConvertedCoojaPacket() {
|
||||||
byte[] dataArrayByte = new byte[accumulatedConversionDataArray.length];
|
byte[] dataArrayByte = new byte[accumulatedConversionDataArray.length];
|
||||||
for (int i = 0; i < accumulatedConversionDataArray.length; i++) {
|
for (int i=0; i < accumulatedConversionDataArray.length; i++) {
|
||||||
dataArrayByte[i] = (byte) accumulatedConversionDataArray[i];
|
dataArrayByte[i] = (byte) accumulatedConversionDataArray[i];
|
||||||
}
|
}
|
||||||
return new COOJARadioPacket(dataArrayByte);
|
|
||||||
|
byte[] originalArr = new byte[originalData.size()];
|
||||||
|
for (int i=0; i < originalArr.length; i++) {
|
||||||
|
originalArr[i] = (byte) originalData.get(i).getByte();
|
||||||
|
}
|
||||||
|
|
||||||
|
return new ConvertedRadioPacket(dataArrayByte, originalArr);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
Loading…
Reference in a new issue