// #define MACM_DEBUG // debug...
module CsmaMacP {
provides {
- interface Init;
interface SplitControl;
interface MacSend;
interface MacReceive;
interface Random;
interface Timer<TMilli> as ReRxTimer;
+ interface Duplicate;
+ interface TimeDiff16;
interface Alarm<T32khz, uint16_t> as Timer;
async command am_addr_t amAddress();
-
+ interface LocalTime<T32khz> as LocalTime32kHz;
+
#ifdef MACM_DEBUG
- interface GeneralIO as Led0;
- interface GeneralIO as Led1;
- interface GeneralIO as Led2;
- interface GeneralIO as Led3;
+ interface SerialDebug;
#endif
}
}
implementation
{
+ /****** debug vars & defs & functions ***********************/
+#ifdef MACM_DEBUG
+ void sdDebug(uint16_t p) {
+ call SerialDebug.putPlace(p);
+ };
+#else
+ void sdDebug(uint16_t p) {};
+#endif
+ /******* constants and type definitions *********************/
enum {
- BYTE_TIME=21, // byte at 23405 kBit/s, 4b6b encoded
- PREAMBLE_BYTE_TIME=14, // byte at 23405 kBit/s, no coding
- PHY_HEADER_TIME=84, // 6 Phy Preamble at 23405 bits/s
+ BYTE_TIME=ENCODED_32KHZ_BYTE_TIME, // phy encoded
+ PREAMBLE_BYTE_TIME=TDA5250_32KHZ_BYTE_TIME, // no coding
+ PHY_HEADER_TIME=6*PREAMBLE_BYTE_TIME, // 6 Phy Preamble
+ TIME_CORRECTION=TDA5250_32KHZ_BYTE_TIME+2, // difference between txSFD and rxSFD
+
+
SUB_HEADER_TIME=PHY_HEADER_TIME + sizeof(tda5250_header_t)*BYTE_TIME,
SUB_FOOTER_TIME=2*BYTE_TIME, // 2 bytes crc
MAXTIMERVALUE=0xFFFF, // helps to compute backoff
MIN_PREAMBLE_BYTES=2,
TOKEN_ACK_FLAG = 64,
TOKEN_ACK_MASK = 0x3f,
- INVALID_SNR = 0xffff,
- MSG_TABLE_ENTRIES=16,
- MAX_AGE=0xff
+ INVALID_SNR = 0xffff
};
/**************** Module Global Variables *****************/
} flags_t;
/* Packet vars */
- message_t* txBufPtr;
+ message_t* txBufPtr = NULL;
message_t ackMsg;
uint8_t txLen;
- uint8_t shortRetryCounter;
+ uint8_t shortRetryCounter = 0;
- uint8_t longRetryCounter;
+ uint8_t longRetryCounter = 0;
unsigned checkCounter;
- macState_t macState;
- uint8_t flags;
+ macState_t macState = INIT;
+ uint8_t flags = 0;
uint8_t seqNo;
uint16_t restLaufzeit;
- /* duplicate suppression */
- typedef struct knownMessage_t {
- am_addr_t src;
- uint8_t token;
- uint8_t age;
- } knownMessage_t;
-
- knownMessage_t knownMsgTable[MSG_TABLE_ENTRIES];
-
- task void ageMsgsTask() {
- unsigned i;
- atomic {
- for(i = 0; i < MSG_TABLE_ENTRIES; i++) {
- if(knownMsgTable[i].age < MAX_AGE) ++knownMsgTable[i].age;
- }
- }
- }
-
- /****** debug vars & defs & functions ***********************/
-#ifdef MACM_DEBUG
-#define HISTORY_ENTRIES 100
- typedef struct {
- int index;
- macState_t state;
- int place;
- } history_t;
-
- history_t history[HISTORY_ENTRIES];
- unsigned histIndex;
- void storeOldState(int p) {
- atomic {
- history[histIndex].index = histIndex;
- history[histIndex].state = macState;
- history[histIndex].place = p;
- histIndex++;
- if(histIndex >= HISTORY_ENTRIES) histIndex = 0;
- }
- }
-#else
- void storeOldState(int p) {};
-#endif
-
- void signalFailure(uint8_t place) {
-#ifdef MACM_DEBUG
- unsigned long i;
- atomic {
- for(;;) {
- call Led0.set();
- call Led1.clr();
- call Led2.clr();
- call Led3.clr();
-
- for(i = 0; i < 1000000; i++) {
- ;
- }
-
- (place & 1) ? call Led0.set() : call Led0.clr();
- (place & 2) ? call Led1.set() : call Led1.clr();
- (place & 4) ? call Led2.set() : call Led2.clr();
- (place & 8) ? call Led3.set() : call Led3.clr();
-
- for(i = 0; i < 1000000; i++) {
- ;
- }
-
- (macState & 1) ? call Led0.set() : call Led0.clr();
- (macState & 2) ? call Led1.set() : call Led1.clr();
- (macState & 4) ? call Led2.set() : call Led2.clr();
- (macState & 8) ? call Led3.set() : call Led3.clr();
-
- for(i = 0; i < 1000000; i++) {
- ;
- }
- }
- }
-#endif
- }
+ uint16_t rssiValue = 0;
- void signalMacState() {
-#ifdef MACM_DEBUG
-/*
- (macState & 1) ? call Led0.set() : call Led0.clr();
- (macState & 2) ? call Led1.set() : call Led1.clr();
- (macState & 4) ? call Led2.set() : call Led2.clr();
- (macState & 8) ? call Led3.set() : call Led3.clr();
-*/
-#endif
- }
+ uint32_t rxTime = 0;
/****** Secure switching of radio modes ***/
}
void setRxMode() {
+ rssiValue = INVALID_SNR;
if(call RadioModes.RxMode() == FAIL) {
post SetRxModeTask();
}
task void postponeReRx() {
call ReRxTimer.startOneShot(5000);
}
-
+
uint16_t backoff(uint8_t counter) {
uint16_t mask = BACKOFF_MASK >> (MAX_LONG_RETRY - counter);
return (call Random.rand16() & mask);
}
void interruptBackoffTimer() {
- uint16_t now;
if(call Timer.isRunning()) {
- restLaufzeit = call Timer.getAlarm();
+ restLaufzeit = call TimeDiff16.computeDelta(call Timer.getAlarm(), call Timer.getNow());
call Timer.stop();
- now = call Timer.getNow();
- if(restLaufzeit >= now) {
- restLaufzeit = restLaufzeit - now;
- }
- else {
- restLaufzeit = (uint16_t)(-1) - restLaufzeit + now;
- }
if(restLaufzeit > BACKOFF_MASK) {
restLaufzeit = call Random.rand16() & 0xFF;
}
setFlag(&flags, RESUME_BACKOFF);
}
}
-
+
+ void storeStrength(message_t *m) {
+ if(rssiValue != INVALID_SNR) {
+ (getMetadata(m))->strength = rssiValue;
+ }
+ else {
+ if(call RssiAdcResource.isOwner()) {
+ (getMetadata(m))->strength = call ChannelMonitorData.readSnr();
+ }
+ else {
+ (getMetadata(m))->strength = 1;
+ }
+ }
+ }
+
void signalSendDone(error_t error) {
message_t *m;
error_t e = error;
if(isFlagSet(&flags, CANCEL_SEND)) {
e = ECANCEL;
}
+ storeStrength(m);
clearFlag(&flags, CANCEL_SEND);
}
signal MacSend.sendDone(m, e);
longRetryCounter++;
shortRetryCounter = 1;
if(longRetryCounter > MAX_LONG_RETRY) {
- storeOldState(13);
+ sdDebug(13);
getMetadata(txBufPtr)->ack = WAS_NOT_ACKED;
signalSendDone(FAIL);
}
setFlag(&flags, RESUME_BACKOFF);
restLaufzeit = backoff(longRetryCounter);
updateRetryCounters();
- storeOldState(92);
+ sdDebug(92);
}
}
bool isNewMsg(message_t* msg) {
- uint8_t i;
- for(i=0; i < MSG_TABLE_ENTRIES; i++) {
- if((getHeader(msg)->src == knownMsgTable[i].src) &&
- (((getHeader(msg)->token) & TOKEN_ACK_MASK) == knownMsgTable[i].token) &&
- (knownMsgTable[i].age < MAX_AGE)) {
- knownMsgTable[i].age = 0;
- return FALSE;
- }
- }
- return TRUE;
- }
-
- unsigned findOldest() {
- unsigned i;
- unsigned oldIndex = 0;
- unsigned age = knownMsgTable[oldIndex].age;
- for(i = 1; i < MSG_TABLE_ENTRIES; i++) {
- if(age < knownMsgTable[i].age) {
- oldIndex = i;
- age = knownMsgTable[i].age;
- }
- }
- return oldIndex;
+ return call Duplicate.isNew(getHeader(msg)->src, getHeader(msg)->dest,
+ (getHeader(msg)->token) & TOKEN_ACK_MASK);
}
void rememberMsg(message_t* msg) {
- unsigned oldest = findOldest();
- knownMsgTable[oldest].src = getHeader(msg)->src;
- knownMsgTable[oldest].token = (getHeader(msg)->token) & TOKEN_ACK_MASK;
- knownMsgTable[oldest].age = 0;
+ call Duplicate.remember(getHeader(msg)->src, getHeader(msg)->dest,
+ (getHeader(msg)->token) & TOKEN_ACK_MASK);
}
void checkSend() {
if((txBufPtr != NULL) && (macState == RX) && (!call Timer.isRunning())) {
macState = CCA;
- signalMacState();
checkCounter = 0;
requestAdc();
call Timer.start(DATA_DETECT_TIME);
- storeOldState(170);
+ sdDebug(170);
}
else {
- storeOldState(171);
+ sdDebug(171);
post ReleaseAdcTask();
}
}
return isFlagSet(&token, TOKEN_ACK_FLAG);
}
- /**************** Init ************************/
-
- command error_t Init.init(){
- unsigned i;
- atomic {
- txBufPtr = NULL;
- macState = INIT;
- signalMacState();
- shortRetryCounter = 0;
- longRetryCounter = 0;
- flags = 0;
- for(i = 0; i < MSG_TABLE_ENTRIES; i++) {
- knownMsgTable[i].age = MAX_AGE;
- }
-#ifdef MACM_DEBUG
- histIndex = 0;
-#endif
- }
- return SUCCESS;
- }
-
/**************** SplitControl *****************/
task void StartDoneTask() {
atomic {
macState = RX;
- signalMacState();
call UartPhyControl.setNumPreambles(MIN_PREAMBLE_BYTES);
}
post ReleaseAdcTask();
call CcaStdControl.start();
atomic {
macState = INIT;
- signalMacState();
+
setRxMode();
- storeOldState(1);
+ sdDebug(1);
}
return SUCCESS;
}
atomic {
if (macState != RX) {
post StopDone();
- storeOldState(2);
+ sdDebug(2);
} else {
- storeOldState(3);
+ sdDebug(3);
call Timer.stop();
- call Init.init();
+ txBufPtr = NULL;
+ macState = INIT;
+ shortRetryCounter = 0;
+ longRetryCounter = 0;
+ flags = 0;
signal SplitControl.stopDone(SUCCESS);
}
}
command error_t SplitControl.stop() {
call CcaStdControl.stop();
- storeOldState(4);
+ sdDebug(4);
post StopDone();
return SUCCESS;
}
return call SubPacket.maxPayloadLength();
}
- command void* Packet.getPayload(message_t* msg, uint8_t* len) {
+ command void* Packet.getPayload(message_t* msg, uint8_t len) {
return call SubPacket.getPayload(msg, len);
}
atomic {
setFlag(&flags, RSSI_STABLE);
if(macState == INIT) {
- storeOldState(11);
+ sdDebug(11);
if(call RssiAdcResource.isOwner()) {
call ChannelMonitorControl.updateNoiseFloor();
}
}
else {
- storeOldState(12);
+ sdDebug(12);
}
}
}
post postponeReRx();
atomic {
if(macState == SW_RX) {
- storeOldState(21);
+ sdDebug(21);
macState = RX;
- signalMacState();
+
if(isFlagSet(&flags, RESUME_BACKOFF)) {
clearFlag(&flags, RESUME_BACKOFF);
call Timer.start(restLaufzeit);
}
}
else if(macState == SW_RX_ACK) {
- storeOldState(22);
+ sdDebug(22);
macState = RX_ACK;
- signalMacState();
}
else if(macState == INIT) {
- storeOldState(24);
+ sdDebug(24);
}
else {
- storeOldState(25);
- signalFailure(1);
+ sdDebug(25);
}
}
}
post postponeReRx();
atomic {
if(macState == SW_TX) {
- storeOldState(30);
+ sdDebug(30);
if(txBufPtr) {
macState = TX;
- signalMacState();
if(call PacketSend.send(txBufPtr, txLen) == SUCCESS) {
- storeOldState(31);
+ sdDebug(31);
} else {
- storeOldState(32);
- signalFailure(2);
+ sdDebug(32);
}
}
}
else if(macState == SW_TX_ACK) {
macState = TX_ACK;
- signalMacState();
+
if(call PacketSend.send(&ackMsg, 0) == SUCCESS) {
- storeOldState(53);
+ sdDebug(53);
} else {
- storeOldState(54);
- signalFailure(6);
+ sdDebug(54);
}
}
else {
- storeOldState(33);
- signalFailure(3);
+ sdDebug(33);
}
}
}
error_t err = SUCCESS;
atomic {
if((shortRetryCounter == 0) && (txBufPtr == NULL) && (macState != INIT)) {
- storeOldState(40);
+ sdDebug(40);
shortRetryCounter = 1;
longRetryCounter = 1;
txBufPtr = msg;
txLen = len;
+ sdDebug(10);
+ sdDebug(len);
seqNo++;
if(seqNo >= TOKEN_ACK_FLAG) seqNo = 1;
getHeader(msg)->token = seqNo;
if(macState != RX_P) checkSend();
}
else {
- storeOldState(41);
+ sdDebug(41);
err = EBUSY;
}
}
error_t err = SUCCESS;
if((shortRetryCounter != 0) && (txBufPtr == msg) &&
(macState != TX) && (macState != RX_ACK) && (macState != SW_RX_ACK)) {
- storeOldState(50);
+ sdDebug(50);
shortRetryCounter = 0;
txBufPtr = NULL;
txLen = 0;
signal MacSend.sendDone(msg, ECANCEL);
}
else {
- storeOldState(51);
+ sdDebug(51);
err = FAIL;
}
return err;
/****** PacketSerializer events **********************/
async event void PacketReceive.receiveDetected() {
+ rssiValue = INVALID_SNR;
if(macState <= RX_ACK) {
- storeOldState(60);
+ sdDebug(60);
interruptBackoffTimer();
if(macState == CCA) computeBackoff();
}
if(macState <= RX) {
- post ReleaseAdcTask();
- storeOldState(61);
+ sdDebug(61);
macState = RX_P;
- signalMacState();
+
+ requestAdc();
}
else if(macState <= RX_ACK) {
- post ReleaseAdcTask();
- storeOldState(62);
+ sdDebug(62);
macState = RX_ACK_P;
- signalMacState();
+
}
else if(macState == INIT) {
- storeOldState(63);
+ sdDebug(63);
}
else {
post ReleaseAdcTask();
- storeOldState(64);
- signalFailure(4);
+ sdDebug(64);
}
}
macState_t action = RX;
if(macState == RX_P) {
if(error == SUCCESS) {
- post ageMsgsTask();
- storeOldState(82);
+ sdDebug(82);
isCnt = isControl(msg);
if(msgIsForMe(msg)) {
if(!isCnt) {
- (getMetadata(m))->strength = 10;
+ storeStrength(msg);
if(isNewMsg(m)) {
m = signal MacReceive.receiveDone(msg);
rememberMsg(m);
}
if(needsAckRx(msg)) {
- storeOldState(87);
+ sdDebug(87);
action = CCA_ACK;
} else {
- storeOldState(88);
+ sdDebug(88);
}
}
else {
- storeOldState(89);
+ sdDebug(89);
}
}
else {
- storeOldState(90);
+ sdDebug(90);
}
}
else {
- storeOldState(91);
+ sdDebug(91);
}
}
else if(macState == RX_ACK_P) {
if(error == SUCCESS) {
if(ackIsForMe(msg)) {
- storeOldState(92);
- (getMetadata(txBufPtr))->strength = 10;
+ sdDebug(92);
(getMetadata(txBufPtr))->ack = WAS_ACKED;
signalSendDone(SUCCESS);
}
else {
- storeOldState(93);
+ sdDebug(93);
updateLongRetryCounters();
}
}
else {
if(call Timer.isRunning()) {
- storeOldState(94);
+ sdDebug(94);
action = RX_ACK;
}
else {
- storeOldState(95);
+ sdDebug(95);
if(needsAckTx(txBufPtr)) {
updateLongRetryCounters();
}
if(action == CCA_ACK) {
prepareAck(msg);
macState = CCA_ACK;
- signalMacState();
+
call Timer.start(RX_SETUP_TIME - TX_SETUP_TIME + ADDED_DELAY);
}
else if(action == RX_ACK) {
macState = RX_ACK;
- signalMacState();
+
}
else if(action == RX) {
macState = RX;
- signalMacState();
+
if(isFlagSet(&flags, RESUME_BACKOFF)) {
clearFlag(&flags, RESUME_BACKOFF);
call Timer.start(restLaufzeit);
}
else if(action == TX) {
macState = SW_TX;
- signalMacState();
+
setTxMode();
}
else if(action == INIT) {
}
else {
- storeOldState(94);
- signalFailure(11);
+ sdDebug(94);
}
+ post ReleaseAdcTask();
return m;
}
async event void PacketSend.sendDone(message_t* msg, error_t error) {
if(macState == TX) {
- if(msg != txBufPtr) signalFailure(12);
if(needsAckTx(msg)) {
- storeOldState(97);
+ sdDebug(97);
macState = SW_RX_ACK;
- signalMacState();
+
call Timer.start(RX_ACK_TIMEOUT);
} else {
- storeOldState(99);
+ sdDebug(99);
signalSendDone(error);
macState = SW_RX;
- signalMacState();
+
}
setRxMode();
}
else if(macState == TX_ACK) {
macState = SW_RX;
- signalMacState();
+
setRxMode();
}
- else {
- signalFailure(13);
- }
+ post ReleaseAdcTask();
}
computeBackoff();
macState = RX;
requestAdc();
- storeOldState(150);
- signalMacState();
+ sdDebug(150);
+
if(!call Timer.isRunning()) call Timer.start(TX_GAP_TIME >> 1);
} else if(macState == RX) {
if(!call Timer.isRunning()) call Timer.start(TX_GAP_TIME + backoff(0));
else if(macState == CCA) {
checkCounter++;
if(checkCounter < 3) {
- storeOldState(158);
+ sdDebug(158);
call Timer.start((TX_GAP_TIME + backoff(0))>>1);
requestAdc();
}
else {
call Timer.stop();
- storeOldState(159);
+ sdDebug(159);
macState = SW_TX;
- signalMacState();
+
setTxMode();
}
}
}
async event void Timer.fired() {
- storeOldState(100);
+ sdDebug(100);
if(macState == CCA) {
if((!call RssiAdcResource.isOwner()) || (call ChannelMonitor.start() != SUCCESS)) {
if(call UartPhyControl.isBusy()) {
- storeOldState(101);
+ sdDebug(101);
checkOnBusy();
}
else {
- storeOldState(102);
+ sdDebug(102);
checkOnIdle();
}
} else {
}
else if(macState == RX_ACK) {
if(needsAckTx(txBufPtr)) {
- storeOldState(103);
+ sdDebug(103);
updateLongRetryCounters();
macState = RX;
call Timer.start(backoff(longRetryCounter));
}
else {
- storeOldState(104);
- signalFailure(7);
+ sdDebug(104);
}
}
else if(macState == CCA_ACK) {
- storeOldState(160);
+ sdDebug(160);
macState = SW_TX_ACK;
- signalMacState();
+
setTxMode();
}
else if((macState == RX_ACK_P) || (macState == RX_P)) {
- storeOldState(108);
+ sdDebug(108);
}
else if(macState == INIT) {
- storeOldState(109);
+ sdDebug(109);
post StartDoneTask();
}
else {
- storeOldState(110);
+ sdDebug(110);
checkSend();
}
}
async event void ChannelMonitor.channelBusy() {
clearFlag(&flags, CCA_PENDING);
- storeOldState(120);
+ sdDebug(120);
checkOnBusy();
}
async event void ChannelMonitor.channelIdle() {
clearFlag(&flags, CCA_PENDING);
- storeOldState(121);
+ sdDebug(121);
checkOnIdle();
}
event void ChannelMonitorControl.updateNoiseFloorDone() {
if(macState == INIT) {
- storeOldState(122);
+ sdDebug(122);
post StartDoneTask();
} else {
- storeOldState(124);
- signalFailure(11);
+ sdDebug(124);
}
}
/***** ChannelMonitorData events ******************/
async event void ChannelMonitorData.getSnrDone(int16_t data) {
+ atomic if((macState == RX_P) || (macState == RX_ACK_P)) rssiValue = data;
+ post ReleaseAdcTask();
}
/***** unused Radio Modes events **************************/
/***** abused TimeStamping events **************************/
async event void RadioTimeStamping.receivedSFD( uint16_t time ) {
- if(macState == RX_P) call ChannelMonitor.rxSuccess();
+ if(call RssiAdcResource.isOwner()) call ChannelMonitorData.getSnr();
+ if(macState == RX_P) {
+ rxTime = call LocalTime32kHz.get();
+ call ChannelMonitor.rxSuccess();
+ }
}
- async event void RadioTimeStamping.transmittedSFD( uint16_t time, message_t* p_msg ) {}
+ async event void RadioTimeStamping.transmittedSFD( uint16_t time, message_t* p_msg ) {
+ if((macState == TX) && (p_msg == txBufPtr)) {
+ // to do
+ }
+ }
/***** Rssi Resource events ******************/
event void RssiAdcResource.granted() {
macState_t ms;
atomic ms = macState;
if((ms == INIT) && isFlagSet(&flags, RSSI_STABLE)) {
- storeOldState(145);
+ sdDebug(145);
call ChannelMonitorControl.updateNoiseFloor();
}
else {
- storeOldState(146);
+ sdDebug(146);
call RssiAdcResource.release();
}
}