📄 phyp.nc
字号:
syncStatus = SUCCESS; call SRXON.strobe(); } else{ if(sendStatus != TX_STARTED){ syncStatus = FAIL; } else{ call SRFOFF.strobe(); syncStatus = SUCCESS; } } call SyncResource.release(); post syncDone_task(); return; } atomic { id[0] = phyPib.panId; id[1] = phyPib.shortAddress; } call CSN.clr(); call SRFOFF.strobe(); call CSN.set(); switch(sync_state){ case SYNC_PANID: call CSN.clr(); call PANID.write(0, (uint8_t*)id, 2); call CSN.set(); break; case SYNC_SHORT_ADDRESS: call CSN.clr(); call SHORTADR.write(0, (uint8_t*)(&id[1]), 2); call CSN.set(); break; case SYNC_TX_POWER: call CSN.clr(); call TXCTRL.write(( 2 << CC2420_TXCTRL_TXMIXBUF_CUR) | ( 3 << CC2420_TXCTRL_PA_CURRENT) | ( 1 << CC2420_TXCTRL_RESERVED) | ( (phyPib.transmitPower & 0x1F) << CC2420_TXCTRL_PA_LEVEL ) ); call CSN.set(); break; case SYNC_CURRENT_CHANNEL: call CSN.clr(); call FSCTRL.write(( 1 << CC2420_FSCTRL_LOCK_THR) | ( ( (phyPib.currentChannel - 11)*5+357 ) << CC2420_FSCTRL_FREQ ) ); call CSN.set(); break; case SYNC_CCA_MODE: call CSN.clr(); call MDMCTRL0.write( ( 1 << CC2420_MDMCTRL0_RESERVED_FRAME_MODE ) | ( 1 << CC2420_MDMCTRL0_ADR_DECODE ) | ( 2 << CC2420_MDMCTRL0_CCA_HYST ) | ( (phyPib.CCAMode&0x03) << CC2420_MDMCTRL0_CCA_MOD ) | ( 1 << CC2420_MDMCTRL0_AUTOCRC ) | ( 1 << CC2420_MDMCTRL0_AUTOACK ) | ( 2 << CC2420_MDMCTRL0_PREAMBLE_LENGTH ) ); call CSN.set(); break; case SYNC_ALL: call CSN.clr(); call TXCTRL.write(( 2 << CC2420_TXCTRL_TXMIXBUF_CUR) | ( 3 << CC2420_TXCTRL_PA_CURRENT) | ( 1 << CC2420_TXCTRL_RESERVED) | ( (phyPib.transmitPower & 0x1F) << CC2420_TXCTRL_PA_LEVEL ) ); call FSCTRL.write(( 1 << CC2420_FSCTRL_LOCK_THR) | ( ( (phyPib.currentChannel - 11)*5+357 ) << CC2420_FSCTRL_FREQ ) ); call MDMCTRL0.write( ( 1 << CC2420_MDMCTRL0_RESERVED_FRAME_MODE ) | ( 1 << CC2420_MDMCTRL0_ADR_DECODE ) | ( 2 << CC2420_MDMCTRL0_CCA_HYST ) | ( (phyPib.CCAMode&0x03) << CC2420_MDMCTRL0_CCA_MOD ) | ( 1 << CC2420_MDMCTRL0_AUTOCRC ) | ( 1 << CC2420_MDMCTRL0_AUTOACK ) | ( 2 << CC2420_MDMCTRL0_PREAMBLE_LENGTH ) ); call PANID.write(0, (uint8_t*)id, 4); call CSN.set(); break; default:break; } call CSN.clr(); call SRXON.strobe(); call CSN.set(); // call CSN.clr();// call PANID.read(0, (uint8_t*)panIdShortAddr, 4);// call CSN.set(); call SyncResource.release(); post syncDone_task();} task void syncDone_task(){ switch(sync_state){ case SYNC_PANID: signal PlmeSap.directSetPanIdDone(SUCCESS); break; case SYNC_SHORT_ADDRESS: signal PlmeSap.directSetShortAddrDone(SUCCESS); break; case SYNC_TX_POWER: signal PlmeSap.directSetTxPowerDone(SUCCESS); break; case SYNC_CURRENT_CHANNEL: signal PlmeSap.directSetCurrentChannelDone(SUCCESS); break; case SYNC_CCA_MODE: signal PlmeSap.directSetCCAModeDone(SUCCESS); break; case SYNC_ALL: signal PlmeSap.syncDone(SUCCESS); break; case SYNC_RXON: signal PlmeSap.rxControlDone(syncStatus); default:break; } sync_state = SYNC_IDLE;}/******************************** transmit *******************************************/command error_t PdSap.send(mem_head_t* psdu, bool isAckSend, uint8_t DSN){ uint8_t* pTxBuf; uint8_t pos; if( (transmit_state != TX_STARTED) || control_state != S_XOSC_STARTED ) return FAIL; /* reset CSMA NB and NE */ phyPib.csmaBE = macMinBE; phyPib.csmaNB = 0; phyPib.psdu = psdu; pos = call Mem.getCurrentPos(psdu); /** phyPib.txLength should add 1 byte length field **/ phyPib.txLength = call Mem.getSize(psdu) - pos + 1; /** add length field, note that length include 2 byte FCS and do not include length field itself **/ pTxBuf = (uint8_t*)psdu + pos; pTxBuf--; *pTxBuf = phyPib.txLength + 2 - 1; /** store send parameter **/ isAckSending = isAckSend; macDsn = DSN; transmit_state = TX_LOAD; if(call TransmitResource.immediateRequest() == SUCCESS){ call CSN.clr();// call FMSTATE.read(&fsctrlRead); call CSN.set(); call CSN.clr(); call TXFIFO.write(pTxBuf, phyPib.txLength); } else call TransmitResource.request(); return SUCCESS; }event void TransmitResource.granted() { uint8_t* pTxBuf; switch(transmit_state){ case TX_LOAD: pTxBuf = (uint8_t*)phyPib.psdu + call Mem.getCurrentPos(phyPib.psdu) - 1; call CSN.clr(); call TXFIFO.write(pTxBuf, phyPib.txLength); break; case TX_CSMA_CA: attempSend(); break; default: call TransmitResource.release(); break; }} async event void TXFIFO.writeDone(uint8_t* tx_buf, uint8_t tx_len, error_t error) { call CSN.set(); call CSN.clr();// call TXFIFO_RAM.read(0, txfifo, 20); call CSN.set(); call CSN.clr();// call FMSTATE.read(&fsctrlRead); call CSN.set(); call TransmitResource.release(); transmit_state = TX_CSMA_CA; performCSMA();}void performCSMA(){ uint16_t i = 0; uint16_t backOffTime = 0; if(transmit_state != TX_CSMA_CA) return; if(phyPib.csmaNB >= macMaxCSMABackoffs){ sendStatus = FAIL;// call PhyTimer.stop(); post sendDone_task(); return; } phyPib.csmaNB++; for(i=0; i<phyPib.csmaBE; i++){ backOffTime *= 2; } backOffTime--; backOffTime = backOffTime * ( ( call Random.rand16() ) & (0xf) ); phyPib.csmaBE++; phyPib.csmaBE = (aMaxBE<phyPib.csmaBE) ? aMaxBE : phyPib.csmaBE; call PhyTimer.start(backOffTime);// call PhyTimer.start(100); }async event void PhyTimer.fired(){ /* indicating that VREG have tuning on */ if(control_state == S_VREG_STARTING){ control_state = S_VREG_STARTED;// call PhyTimer.stop(); call RSTN.clr(); call RSTN.set(); startOscillator(); return; } /* below is for CSMA_CA and ack packet receive use */ switch(transmit_state){ case TX_CSMA_CA: if ( call CCA.get() ){ if(call TransmitResource.immediateRequest() == SUCCESS) attempSend(); else call TransmitResource.request(); } else performCSMA();// call PhyTimer.stop(); break; case TX_SFD: // We didn't receive an SFD interrupt within CC2420_ABORT_PERIOD // jiffies. Assume something is wrong. sendStatus = ERETRY; transmit_state = TX_SEND_DONE; // call Leds.led1On();// call PhyTimer.stop(); post sendDone_task(); break; case TX_ACK_WAIT: //receive ack fail sendStatus = FAIL; transmit_state = TX_SEND_DONE;// call Leds.led0Off(); // call PhyTimer.stop(); printf("PhyTimer.fired():ack waiting fail\n"); post sendDone_task(); break; default:break; } }void attempSend(){ uint8_t status = 0; call CSN.clr();// call FMSTATE.read(&fsctrlRead);// call CSN.set(); status = call STXON.strobe(); if( !( status & CC2420_STATUS_TX_ACTIVE ) ){ status = call SNOP.strobe(); if ( !( status & CC2420_STATUS_TX_ACTIVE ) ){ call TransmitResource.release(); performCSMA(); // is congestion } else{ transmit_state = TX_SFD;// call Leds.led1Off(); call PhyTimer.start(SEND_WAIT_SFD_PERIOD);// call PhyTimer.start(10); } } else{ transmit_state = TX_SFD; call Leds.led1Off(); call PhyTimer.start(SEND_WAIT_SFD_PERIOD);// call PhyTimer.start(10); } call CSN.set();}async event void CaptureSFD.captured(uint16_t time) { atomic { switch(transmit_state){ case TX_SFD: call CaptureSFD.captureFallingEdge(); call TransmitResource.release(); call PhyTimer.stop(); transmit_state = TX_EFD; if( call SFD.get() ) break; case TX_EFD: call CaptureSFD.captureRisingEdge(); if(isAckSending){ transmit_state = TX_ACK_WAIT; //macAckWaitDuration is symbol period time (64k) call PhyTimer.start(macAckWaitDuration/2); // printf("CaptureSFD.captured():ack waiting!\n"); } else{ sendStatus = SUCCESS; transmit_state = TX_SEND_DONE; post sendDone_task(); } break; default:break; } }}task void sendDone_task(){ phyPib.csmaNB = 0; phyPib.csmaBE = macMinBE; sendStatus == SUCCESS ? ( printf("sendDone_task(): send success\n") ) : ( printf("sendDone_task(): FAIL\n") ); signal PdSap.sendDone(sendStatus, phyPib.psdu); transmit_state = TX_STARTED;} async event void TXFIFO.readDone( uint8_t* tx_buf, uint8_t tx_len, error_t error ) {}/************************************** receive ***************************************************/async event void InterruptFIFOP.fired() { printf("FIFOP fired, receive_state is %d\n", receive_state);// printf("FIFOP fired, missed_packets is %d\n", missed_packets);// call Leds.led1Toggle(); if( receive_state == RX_STARTED) beginReceive(); else missed_packets++;} void beginReceive() { receive_state = RX_HEADER; if ( call ReceiveResource.immediateRequest() == SUCCESS ) receive(); else call ReceiveResource.request();} event void ReceiveResource.granted() { receive();}void receive() { call CSN.clr(); call RXFIFO.beginRead( (uint8_t*)(&receivePacketLength), 1 );// call RXFIFO.beginRead( (uint8_t*)rxfifo, 1 );}async event void RXFIFO.readDone( uint8_t* rx_buf, uint8_t rx_len, error_t error ) { uint8_t receiveDsn = 0; uint8_t crc = 0; uint8_t fcfLsb = 0; switch(receive_state){ case RX_HEADER: printf("RX_HEADER:receivePacketLength:%d\t*rx_buf:%d\n", receivePacketLength, *rx_buf); if( ( call Mem.malloc( (uint8_t**)(&phyPib.pRxBuf), receivePacketLength ) != SUCCESS ) || /* overflow happen and this is the packet which did not received completely */ receivePacketLength+1 > overflow_buffer_left){ printf("mem malloc %d byte fail!,neet to flush\n", receivePacketLength); flushRxBuf(); receive_state = RX_STARTED; missed_packets = 0; overflow_buffer_left = 128; call ReceiveResource.release(); // call CSN.set(); } else{ if( !call FIFO.get() && !call FIFOP.get() ) overflow_buffer_left -= receivePacketLength + 1; receive_state = RX_PAYLOAD; call Mem.setCurrentPos( phyPib.pRxBuf, ( ( call Mem.getSize(phyPib.pRxBuf) ) - receivePacketLength ) ); call RXFIFO.continueRead( (uint8_t*)( phyPib.pRxBuf + ( call Mem.getCurrentPos(phyPib.pRxBuf) ) ), receivePacketLength ); } break; case RX_PAYLOAD:// flushRxBuf();// missed_packets = 0;// overflow_buffer_left = 128; call CSN.set(); call ReceiveResource.release(); /* have read the packet into phyPib.pRxBuf pointed buf, check if CRC is right */ crc = *(uint8_t*)( phyPib.pRxBuf + ( call Mem.getSize(phyPib.pRxBuf) ) - 1 ); if( (crc & 0x80) == 0 ){ //crc checkout error call Mem.free(phyPib.pRxBuf); //receive next packet // receive_state = RX_STARTED; afterHandleOnePacket(); } else{ //crc checkout right,check if it is ack packet,packet type contain in the first byte of fcf. fcfLsb = *(uint8_t*)( phyPib.pRxBuf + ( call Mem.getSize(phyPib.pRxBuf) ) - receivePacketLength ); // this is ack packet if( (fcfLsb&0x7) == 2 ){ /* dsn is the third byte */ receiveDsn = *(uint8_t*)(phyPib.pRxBuf + ( call Mem.getCurrentPos(phyPib.pRxBuf) ) + 2); //have receive right ack packet if(transmit_state == TX_ACK_WAIT && receiveDsn == macDsn){ printf("RXFIFO.readDone():receive right ack\n"); call PhyTimer.stop(); transmit_state = TX_SEND_DONE; sendStatus = SUCCESS; post sendDone_task(); } call Mem.free(phyPib.pRxBuf); // receive_state = RX_STARTED; afterHandleOnePacket(); } // this is beacon, data, command packet else if( (fcfLsb&0x7) == MAC_FRAME_TYPE_DATA || (fcfLsb&0x7) == MAC_FRAME_TYPE_BEACON || (fcfLsb&0x7) == MAC_FRAME_TYPE_CMD ){ receive_state = RX_HANDLING; post receiveDone_task(); } else{ call Mem.free(phyPib.pRxBuf); afterHandleOnePacket(); } } break; default:break; }} void flushRxBuf() { call CSN.set(); call CSN.clr(); call SFLUSHRX.strobe(); call SFLUSHRX.strobe(); call CSN.set();}/*void afterHandleOnePacket(){// call Leds.led1Toggle(); atomic { if (receive_state == RX_STOPPED) return;// if( ( missed_packets && call FIFO.get() ) || !call FIFOP.get() ){ if( missed_packets || !call FIFOP.get() ){ if(missed_packets) missed_packets--; beginReceive(); } else{ receive_state = RX_STARTED; overflow_buffer_left = 128; missed_packets = 0; } }} */void afterHandleOnePacket(){ printf("afterHandleOnePacket:missed_packets:%d\treceive_state:%d\n", missed_packets, receive_state);// printf("afterHandleOnePacket:overflow_buffer_left is %d\n", overflow_buffer_left); if (receive_state == RX_STOPPED) return; if(missed_packets){ atomic missed_packets--; beginReceive(); } else{ atomic { receive_state = RX_STARTED; overflow_buffer_left = 128; missed_packets = 0; if( !call FIFOP.get() ) beginReceive(); } }} /****** * the two crc byte are replace by cc2420 as follows * | 76543210 | 7 | 6543210 | * | RSSI |CRC| CORR | * RSSI(-60DB~40DB) = RSSI_VAL + RSSI_OFFSET(-45DB) * CORR(110~50) * LQI = (CORR-a)*b * LQI(0~255) */ /** * if we sure receiveDone_task can finish very quickly, shuld not use task, called directly in RXFIFO.readDone. **/ task void receiveDone_task() { uint8_t lqi; lqi = *( phyPib.pRxBuf + call Mem.getSize(phyPib.pRxBuf) - 1 ); lqi &= 0x7f; lqi = ( (lqi-50)/60 )*255; /** physical payload length should minus 2 byte FCS **/ signal PdSap.receive(receivePacketLength-2, phyPib.pRxBuf, lqi);// receive_state = RX_STARTED; afterHandleOnePacket();}async event void RXFIFO.writeDone(uint8_t* tx_buf, uint8_t tx_len, error_t error){} default event void PdSap.receive(uint8_t length, mem_head_t* psdu, uint8_t lqi){} default event void PdSap.sendDone(error_t error, mem_head_t* psdu){}default event void PlmeSap.directSetCurrentChannelDone(error_t error){}default event void PlmeSap.directSetCCAModeDone(error_t error){}default event void PlmeSap.directSetTxPowerDone(error_t error){}default event void PlmeSap.directSetShortAddrDone(error_t error){}default event void PlmeSap.directSetPanIdDone(error_t error){}default event void PlmeSap.syncDone(error_t error){}default event void PlmeSap.rxControlDone(error_t error){}default event void RadioControl.stopDone(error_t error){}/*async event void RXFIFO.writeDone(uint8_t* tx_buf, uint8_t tx_len, error_t error){} event void PdSap.receive(uint8_t length, mem_head_t* psdu, uint8_t lqi){} event void PdSap.sendDone(error_t error){}event void PlmeSap.directSetCurrentChannelDone(error_t error){}event void PlmeSap.directSetCCAModeDone(error_t error){}event void PlmeSap.directSetTxPowerDone(error_t error){}event void PlmeSap.directSetShortAddrDone(error_t error){}event void PlmeSap.syncDone(error_t error){}event void RadioControl.stopDone(error_t error){}*/}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -