interface ChannelMonitorControl;
interface ChannelMonitorData;
interface BatteryLevel;
-
}
- uses {
- // interface ReadNow<uint16_t> as Rssi;
- interface Read<uint16_t> as Rssi;
+ uses {
+ interface ReadNow<uint16_t> as Rssi;
interface Read<uint16_t> as Voltage;
interface Timer<TMilli> as Timer;
- // interface Resource as RssiAdcResource;
- // interface GeneralIO as Led3;
+#ifdef RSSI_FIXED_DEBUG
+ interface SerialDebug;
+#endif
}
}
implementation
-{
-//#define CM_DEBUG // debug...
- /* Measure internal voltage every 5s */
-#define VOLTAGE_SAMPLE_INTERVALL 5000
+{
+#ifdef RSSI_FIXED_DEBUG
+ void sdDebug(uint16_t p) {
+ call SerialDebug.putPlace(p);
+ }
+#else
+ void sdDebug(uint16_t p) {};
+#endif
+
+ /* Measure internal voltage every 20s */
+#define VOLTAGE_SAMPLE_INTERVALL 20000
/*
* Number of samples for noisefloor estimation
// mu + 3*sigma -> rare event, outlier?
#define THREE_SIGMA 145
- // 93 mV measured against 3V Vcc
-#define INITIAL_BUSY_DELTA 127
+ // 75 mV measured against 3V Vcc
+#define INITIAL_BUSY_DELTA 100
// 3000/2 mV measured against 2.5V Ref
#define INITIAL_BATTERY_LEVEL 2457
/**************** Tasks *******************/
task void UpdateNoiseFloorTask();
- task void GetChannelStateTask();
+ // task void GetChannelStateTask();
task void SnrReadyTask();
task void CalibrateNoiseFloorTask();
- task void GetSnrTask();
+ // task void GetSnrTask();
task void CalibrateTask();
task void GetVoltageTask();
- error_t ccaCheckValue();
/***************** Helper function *************/
-#ifdef CM_DEBUG
- void signalFailure() {
- atomic {
- for(;;) {
- ;
- }
- }
- }
-#else
- inline void signalFailure() {
- };
-#endif
- int16_t computeSNR() {
+ int16_t computeSNR(uint16_t r) {
uint32_t delta;
uint16_t snr;
- uint16_t r;
- atomic r = rssi;
if(r > noisefloor) {
delta = r - noisefloor;
// speedily cacluate
/* call Led3.makeOutput();
call Led3.clr(); */
}
+#ifdef RSSI_FIXED_DEBUG
+ call SerialDebug.putShortDesc("Rssi");
+#endif
return SUCCESS;
}
}
/**************** RSSI *******************/
- void rssiRead() {
- if(call Rssi.read() != SUCCESS) signalFailure();
+
+ inline void addSample(uint16_t data) {
+ if(rssiindex < NSAMPLES) rssisamples[rssiindex++] = data;
+ deadlockCounter = 0;
+ if(rssiindex >= NSAMPLES) post UpdateNoiseFloorTask();
+ }
+
+ error_t rssiRead() {
+ return call Rssi.read();
}
- event void Rssi.readDone(error_t result, uint16_t data) {
- if(result == SUCCESS) {
- // call Led3.clr();
- // call RssiAdcResource.release();
- rssi = data;
- atomic {
- switch(state) {
- case CCA:
- ccaCheckValue();
- break;
- case SNR:
- post SnrReadyTask();
- break;
- case CALIBRATE:
- post CalibrateNoiseFloorTask();
- break;
- default:
- break;
+ async event void Rssi.readDone(error_t result, uint16_t data) {
+ switch(state) {
+ case CCA:
+ state = IDLE;
+ if(data < noisefloor + busyDelta) {
+ signal ChannelMonitor.channelIdle();
+ addSample(data);
}
- }
- } else {
- rssiRead();
+ else {
+ signal ChannelMonitor.channelBusy();
+ if(++deadlockCounter >= DEADLOCK) addSample(data);
+ }
+ break;
+ case SNR:
+ rssi = data;
+ post SnrReadyTask();
+ break;
+ case CALIBRATE:
+ rssi = data;
+ post CalibrateNoiseFloorTask();
+ break;
+ default:
+ break;
}
}
uint16_t nbD;
uint16_t bD;
if(result == SUCCESS) {
- nbl = data;
+ nbl = (data + batteryLevel)>>1;
atomic bD = busyDelta;
d = batteryLevel - nbl;
+ sdDebug(10000 + batteryLevel);
+ sdDebug(20000 + data);
+ sdDebug(30000 + nbl);
+ sdDebug(40000U + busyDelta);
if(d > 75 || d < -75) {
// recalculate busyDelta,
// noisefloor already adapted by floating
atomic busyDelta = nbD;
batteryLevel = nbl;
}
- } else {
+ sdDebug(50000U + busyDelta);
+ }
+ else {
post GetVoltageTask();
}
}
/**************** ChannelMonitor *******************/
async command error_t ChannelMonitor.start() {
- error_t res = SUCCESS;
+ error_t res = FAIL;
atomic {
- if(state != VOID) {
- if(state == IDLE) {
- state = CCA;
- res = SUCCESS;
- }
- post GetChannelStateTask();
+ if(state == IDLE) {
+ res = rssiRead();
+ if(res == SUCCESS) state = CCA;
+ }
+ else if(state == CCA) {
+ res = SUCCESS;
}
}
return res;
}
}
- task void GetChannelStateTask() {
- atomic {
- if((state != IDLE) && (state != CCA)) {
- post GetChannelStateTask();
- } else {
- state = CCA;
- rssiRead();
- //if(call RssiAdcResource.request() != SUCCESS) signalFailure();
- }
- }
- }
-
- void addSample() {
- if(rssiindex < NSAMPLES) rssisamples[rssiindex++] = rssi;
- deadlockCounter = 0;
- if(rssiindex >= NSAMPLES) post UpdateNoiseFloorTask();
- }
-
-
- void channelBusy () {
- atomic {
- if(++deadlockCounter >= DEADLOCK) addSample();
- state = IDLE;
- }
- signal ChannelMonitor.channelBusy();
- }
-
- void channelIdle() {
- atomic {
- addSample();
- state = IDLE;
- }
- signal ChannelMonitor.channelIdle();
- }
-
- error_t ccaCheckValue() {
- uint16_t data;
- atomic data = rssi;
- if(data < noisefloor + busyDelta) {
- channelIdle();
- } else {
- channelBusy();
- }
- return SUCCESS;
- }
-
task void UpdateNoiseFloorTask() {
shellsort(rssisamples,NSAMPLES);
atomic {
- noisefloor = (5*noisefloor + rssisamples[NSAMPLES/2])/6;
+ noisefloor = (5*noisefloor + rssisamples[NSAMPLES/2] + 3)/6;
rssiindex = 0;
}
+ sdDebug(60000U + noisefloor);
}
/**************** ChannelMonitorControl ************/
} else {
shellsort(rssisamples,NSAMPLES);
if(rssisamples[MINIMUM_POSITION] < noisefloor + THREE_SIGMA) {
- noisefloor = (7*noisefloor + rssisamples[NSAMPLES/2])/8;
+ noisefloor = (7*noisefloor + rssisamples[NSAMPLES/2] + 4)/8;
++deadlockCounter;
}
else {
if(s != CALIBRATE) {
readVoltage();
} else {
- rssiRead();
- // call RssiAdcResource.request();
+ rssiRead();
}
}
return v;
}
- /** get SNR in dB **/
-
async command error_t ChannelMonitorData.getSnr() {
- error_t res = SUCCESS;
- if(state != VOID) {
- post GetSnrTask();
- } else {
- res = FAIL;
- }
- return res;
- }
-
- task void GetSnrTask() {
+ error_t res = FAIL;
atomic {
- if(state != IDLE) {
- post GetSnrTask();
- } else {
- state = SNR;
- rssiRead();
- // if(call RssiAdcResource.request() != SUCCESS) signalFailure();
+ if(state == IDLE) {
+ res = rssiRead();
+ if(res == SUCCESS) state = SNR;
+ }
+ else if(state == SNR) {
+ res = SUCCESS;
}
}
+ return res;
}
-
+
task void SnrReadyTask() {
int16_t snr;
- snr = computeSNR();
- atomic state = IDLE;
- signal ChannelMonitorData.getSnrDone(snr);
+ state_t s;
+ uint16_t r;
+ atomic {
+ r = rssi;
+ s = state;
+ if(state == SNR) state = IDLE;
+ }
+ if(s == SNR) {
+ snr = computeSNR(r);
+ signal ChannelMonitorData.getSnrDone(snr);
+ }
}
+ async command uint16_t ChannelMonitorData.readSnr() {
+ uint16_t rval;
+ if(rssi > noisefloor) {
+ rval = (rssi-noisefloor)>>4;
+ } else {
+ rval = 3;
+ }
+ return rval;
+ }
+
default async event void ChannelMonitorData.getSnrDone(int16_t snr) {
}
async command uint16_t BatteryLevel.getLevel() {
uint16_t l;
atomic l = batteryLevel;
- return (uint32_t)l*39>>5;
+ return (uint32_t)(l+3)*6/5;
}
-
}