📄 xe1205phyp.nc
字号:
if (frameLen == 0 || frameLen > xe1205_mtu + 7) return EINVAL; // 7 = 4 preamble + 3 sync
call XE1205PhySwitch.txMode(); // it takes 100us to switch from rx to tx, ie less than one byte at 76kbps
call Interrupt0.disable();
status = call SpiResourceTX.immediateRequest();
xe1205check(3, status);
if (status != SUCCESS) {
call XE1205PhySwitch.rxMode();
call SpiResourceConfig.request();
return status;
}
call XE1205PhySwitch.antennaTx();
state = RADIO_TX;
}
call XE1205Fifo.write(data, frameLen);
atomic {
txBuf = signal XE1205PhyRxTx.continueSend(&nextTxLen);
}
if (nextTxLen) {
call Interrupt0.enableFallingEdge();
} else {
call Interrupt0.disable();
call Interrupt1.enableRisingEdge();
}
// cannot happen with current SPI implementation (at least with NoDma)
#if 0
if (status != SUCCESS) {
xe1205error(8, status);
call XE1205PhySwitch.rxMode();
call XE1205PhySwitch.antennaRx();
call XE1205PatternConf.loadDataPatternHasBus();
armPatternDetect();
call SpiResourceTX.release();
atomic {
call Interrupt0.enableRisingEdge();
state = RADIO_LISTEN;
}
return status;
}
#endif
return SUCCESS;
}
uint16_t rxByte=0;
/**
* In transmit: nTxFifoEmpty. (ie after the last byte has been *read out of the fifo*)
* In receive: write_byte.
*/
async event void Interrupt0.fired() __attribute__ ((noinline))
{
error_t status;
switch (state) {
case RADIO_RX_ACK:
call Alarm32khz16.stop();
case RADIO_LISTEN:
rxByte=1;
atomic state = RADIO_RX_HEADER;
status = call SpiResourceRX.immediateRequest();
atomic {
if (status != SUCCESS) {
state = RADIO_LISTEN;
call Interrupt0.disable(); // because pattern detector won't be rearmed right away
call SpiResourceConfig.request();
return;
}
}
call Alarm32khz16.start(3000);
return;
case RADIO_RX_HEADER:
rxByte++;
if (rxByte == 2) {
call Alarm32khz16.start(3000);
}
if (rxByte == headerLen + 1) {
call Interrupt0.disable();
call XE1205Fifo.read(rxFrame, headerLen);
call Interrupt1.enableRisingEdge();
}
return;
case RADIO_TX:
call Interrupt0.disable(); // avoid spurious IRQ0s from nTxFifoEmpty rebounding briefly after first byte is written.
// note that we should really wait till writedone() to re-enable either interrupt.
call XE1205Fifo.write(txBuf, nextTxLen);
txBuf = signal XE1205PhyRxTx.continueSend(&nextTxLen);
if (nextTxLen) {
call Interrupt0.enableFallingEdge();
} else {
call Interrupt0.disable();
call Interrupt1.enableRisingEdge();
}
return;
case RADIO_RSSI: // trigged while getting rssi
call Interrupt0.disable(); // because pattern detector won't be rearmed right away
return;
default:
return;
}
}
/**
* In transmit: TxStopped. (ie after the last byte has been *sent*)
* In receive: Fifofull.
*/
async event void Interrupt1.fired() __attribute__ ((noinline))
{
switch (state) {
case RADIO_RX_PACKET:
call Interrupt1.disable(); // in case it briefly goes back to full just after we read first byte
call XE1205Fifo.read(&rxFrame[rxFrameIndex], nextRxLen);
rxFrameIndex += nextRxLen;
computeNextRxLength();
if (nextRxLen==0) {
state = RADIO_RX_PACKET_LAST;
}
return;
case RADIO_RX_HEADER: // somehow the FIFO has filled before we finished reading the header bytes
call Interrupt1.disable();
call Alarm32khz16.stop();
signal XE1205PhyRxTx.rxFrameEnd(NULL, 0, FAIL);
call XE1205PatternConf.loadDataPatternHasBus();
armPatternDetect();
call SpiResourceRX.release();
atomic {
call Interrupt0.enableRisingEdge();
state = RADIO_LISTEN;
}
return;
case RADIO_TX:
call Interrupt1.disable();
call XE1205PhySwitch.rxMode();
call XE1205PhySwitch.antennaRx();
if (enableAck==FALSE) {
call XE1205PatternConf.loadDataPatternHasBus();
armPatternDetect();
signal XE1205PhyRxTx.sendFrameDone(SUCCESS);
call SpiResourceTX.release();
atomic {
call Interrupt0.enableRisingEdge();
state = RADIO_LISTEN;
}
} else {
call XE1205PatternConf.loadAckPatternHasBus();
armPatternDetect();
call SpiResourceTX.release();
call Alarm32khz16.start(usecs_to_jiffies(8000));
atomic {
call Interrupt0.enableRisingEdge();
state = RADIO_RX_ACK;
}
}
return;
default:
return;
}
}
async event void XE1205Fifo.readDone(error_t error) {
switch(state) {
case RADIO_RX_HEADER:
rxFrameLen = signal XE1205PhyRxTx.rxFrameBegin(rxFrame, headerLen);
if (rxFrameLen <= headerLen) {
call Interrupt1.disable();
call Alarm32khz16.stop();
signal XE1205PhyRxTx.rxFrameEnd(NULL, 0, FAIL);
call XE1205PatternConf.loadDataPatternHasBus();
armPatternDetect();
call SpiResourceRX.release();
atomic {
state = RADIO_LISTEN;
call Interrupt0.enableRisingEdge();
}
return;
}
atomic {
if(rssiRange==RSSI_OFF) {
getRssi();
}
}
rxFrameIndex = headerLen;
computeNextRxLength();
state = RADIO_RX_PACKET;
return;
case RADIO_RX_PACKET_LAST:
call Alarm32khz16.stop();
atomic {
call XE1205PatternConf.loadDataPatternHasBus();
armPatternDetect();
state = RADIO_LISTEN;
call Interrupt0.enableRisingEdge();
call SpiResourceRX.release();
}
if( enableAck == FALSE) {
signal XE1205PhyRxTx.rxFrameEnd(rxFrame, rxFrameLen + headerLen, SUCCESS);
} else {
enableAck = FALSE;
signal XE1205PhyRxTx.rxAckEnd(rxFrame, rxFrameLen + headerLen, SUCCESS);
}
return;
case RADIO_RX_PACKET:
call Interrupt1.enableRisingEdge();
return;
default:
xe1205check(10, FAIL);
return;
}
}
async event void XE1205Fifo.writeDone(error_t error) __attribute__ ((noinline)) {
}
async event void Alarm32khz16.fired() {
switch(state) {
case RADIO_STARTING:
call SpiResourceConfig.request();
return;
case RADIO_LISTEN:
case RADIO_RX_HEADER:
case RADIO_RX_PACKET:
if (rssiRange!=RSSI_OFF) {
readRssi();
return;
}
stats_rxOverruns++;
signal XE1205PhyRxTx.rxFrameEnd(NULL, 0, FAIL);
call XE1205PatternConf.loadDataPatternHasBus();
armPatternDetect();
call SpiResourceRX.release();
atomic {
state = RADIO_LISTEN;
call Interrupt0.enableRisingEdge();
}
return;
case RADIO_RSSI:
readRssi();
return;
case RADIO_RX_ACK: // ack timeout
enableAck = FALSE;
call SpiResourceRX.immediateRequest();
signal XE1205PhyRxTx.rxFrameEnd(NULL, 0, FAIL);
call XE1205PatternConf.loadDataPatternHasBus();
armPatternDetect();
call SpiResourceRX.release();
atomic {
state = RADIO_LISTEN;
call Interrupt0.enableRisingEdge();
}
signal XE1205PhyRxTx.sendFrameDone(ENOACK);
return;
default:
return;
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -