📄 cc1000radiointm.nc.svn-base
字号:
return FAIL; } /** * Set the state of low power listening on the chipcon radio. * <p> * The default power up state is 0 (radio always on). * See CC1000Const.h for low power duty cycles and bandwidth */ command result_t SetListeningMode(uint8_t power) { // valid low power listening values are 0 to 3 // 0 is "always on" and 3 is lowest duty cycle // 1 and 2 are in the middle if ((power >= CC1K_LPL_STATES) || (power == lplpower)) return FAIL; // check if the radio is currently doing something if ((!bTxPending) && ((RadioState == POWER_DOWN_STATE) || (RadioState == IDLE_STATE) || (RadioState == DISABLED_STATE))) { // change receiving function in CC1000Radio call WakeupTimer.stop(); atomic { if (lplpower == lplpowertx) { lplpowertx = power; } lplpower = power; } // if successful, change power here if (RadioState == IDLE_STATE) { RadioState = DISABLED_STATE; call StdControl.stop(); call StdControl.start(); } if (RadioState == POWER_DOWN_STATE) { RadioState = DISABLED_STATE; call StdControl.start(); call PowerManagement.adjustPower(); } } else { return FAIL; } return SUCCESS; } /** * Gets the state of low power listening on the chipcon radio. * <p> * @return Current low power listening state value */ command uint8_t GetListeningMode() { return lplpower; } event result_t SquelchTimer.fired() { char currentRadioState; atomic currentRadioState = RadioState; if (currentRadioState == IDLE_STATE) call RSSIADC.getData(); return SUCCESS; } event result_t WakeupTimer.fired() { uint16_t sleeptime; bool tempTxPending; uint8_t currentRadioState; if (lplpower == 0) return SUCCESS; atomic { currentRadioState = RadioState; tempTxPending = bTxPending; } switch(currentRadioState) { case IDLE_STATE: sleeptime = ((PRG_RDB(&CC1K_LPL_SleepTime[lplpower*2]) << 8) | PRG_RDB(&CC1K_LPL_SleepTime[(lplpower*2)+1])); if (!tempTxPending) { atomic RadioState = POWER_DOWN_STATE; call WakeupTimer.start(TIMER_ONE_SHOT, sleeptime); call SquelchTimer.stop(); call CC1000StdControl.stop(); call SpiByteFifo.disableIntr(); } else { call WakeupTimer.start(TIMER_ONE_SHOT, CC1K_LPL_PACKET_TIME*2); } break; case POWER_DOWN_STATE: sleeptime = PRG_RDB(&CC1K_LPL_SleepPreamble[lplpower]); atomic RadioState = IDLE_STATE; call CC1000StdControl.start(); call CC1000Control.BIASOn(); call SpiByteFifo.rxMode(); // SPI to miso call CC1000Control.RxMode(); call SpiByteFifo.enableIntr(); // enable spi interrupt if (iSquelchCount > CC1K_SquelchCount) call SquelchTimer.start(TIMER_REPEAT, CC1K_SquelchIntervalSlow); else call SquelchTimer.start(TIMER_REPEAT, CC1K_SquelchIntervalFast); call WakeupTimer.start(TIMER_ONE_SHOT, sleeptime); break; default: call WakeupTimer.start(TIMER_ONE_SHOT, CC1K_LPL_PACKET_TIME*2); } return SUCCESS; } command result_t StdControl.stop() { atomic RadioState = DISABLED_STATE; call SquelchTimer.stop(); call WakeupTimer.stop(); call CC1000StdControl.stop(); call SpiByteFifo.disableIntr(); // disable spi interrupt return SUCCESS; } command result_t StdControl.start() { uint8_t currentRadioState; atomic currentRadioState = RadioState; if (currentRadioState == DISABLED_STATE) { atomic { rxbufptr->length = 0; RadioState = IDLE_STATE; bTxPending = bTxBusy = FALSE; sMacDelay = -1; preamblelen = ((PRG_RDB(&CC1K_LPL_PreambleLength[lplpowertx*2]) << 8) | PRG_RDB(&CC1K_LPL_PreambleLength[(lplpowertx*2)+1])); } if (lplpower == 0) { // all power on, captain! rxbufptr->length = 0; atomic RadioState = IDLE_STATE; call CC1000StdControl.start(); call CC1000Control.BIASOn(); call SpiByteFifo.rxMode(); // SPI to miso call CC1000Control.RxMode(); if (iSquelchCount > CC1K_SquelchCount) call SquelchTimer.start(TIMER_REPEAT, CC1K_SquelchIntervalSlow); else call SquelchTimer.start(TIMER_REPEAT, CC1K_SquelchIntervalFast); call SpiByteFifo.enableIntr(); // enable spi interrupt } else { uint16_t sleeptime = ((PRG_RDB(&CC1K_LPL_SleepTime[lplpower*2]) << 8) | PRG_RDB(&CC1K_LPL_SleepTime[(lplpower*2)+1])); atomic RadioState = POWER_DOWN_STATE; call TimerControl.start(); call SquelchTimer.stop(); call WakeupTimer.start(TIMER_ONE_SHOT, sleeptime); } } return SUCCESS; } /*** TinySec ****/ async event result_t TinySec.sendDone(result_t result) { atomic { TxByteCnt = 0; RadioTxState = TXSTATE_FLUSH; } return result; } async event result_t TinySec.receiveInitDone(result_t result, uint16_t length, bool ts_enabled) { atomic { rxlength = length; if(result == SUCCESS) { if(ts_enabled) RadioState = RX_STATE_TINYSEC; else RadioState = RX_STATE; } else { rxbufptr->length = 0; RadioState = IDLE_STATE; } } return SUCCESS; } async event result_t TinySec.receiveDone(result_t result) { rxbufptr->strength = usRSSIVal; if(rxbufptr->crc == 1 && (rxbufptr->addr == TOS_LOCAL_ADDRESS || rxbufptr->addr == TOS_BCAST_ADDR)){ //call Leds.redToggle(); RadioState = SENDING_ACK; call CC1000Control.TxMode(); call SpiByteFifo.txMode(); call SpiByteFifo.writeByte(0xaa); RxByteCnt = 0; return SUCCESS; } else { call SpiByteFifo.disableIntr(); RadioState = IDLE_STATE; //DISABLED_STATE; if (!(post PacketRcvd())) { // If there are insufficient resources to process the incoming packet // we drop it rxbufptr->length = 0; RadioState = IDLE_STATE; call SpiByteFifo.enableIntr(); } } return SUCCESS; } /**** TinySec ****/ command result_t Send.send(TOS_MsgPtr pMsg) { result_t Result = SUCCESS; uint8_t currentRadioState = 0; atomic { if (bTxBusy) { Result = FAIL; } else { bTxBusy = TRUE; /**** TinySec ****/ // swap TOS_Msg into TOS_Msg_TinySecCompat // don't reference pMsg after here swapLengthAndGroup(pMsg); txbufptr = (TOS_Msg_TinySecCompat*) pMsg; /**** TinySec ****/ // initially back off [1,32] bytes (approx 2/3 packet) sMacDelay = (call Random.rand() & 0x1F) + 1; bTxPending = TRUE; /****** TinySec *****/ // bad form to call a command in atomic, but sendInit is short. // easiest way to lock txbufptr if(txbufptr->length & TINYSEC_ENABLED_BIT) { txlength = call TinySec.sendInit(txbufptr); } else { txlength = txbufptr->length + (MSG_DATA_SIZE - DATA_LENGTH - 2); } /****** TinySec *****/ } currentRadioState = RadioState; } if (Result) { // if we're off, start the radio if (currentRadioState == POWER_DOWN_STATE) { // disable wakeup timer call WakeupTimer.stop(); call CC1000StdControl.start(); call CC1000Control.BIASOn(); call CC1000Control.RxMode(); call SpiByteFifo.rxMode(); // SPI to miso call SpiByteFifo.enableIntr(); // enable spi interrupt if (iSquelchCount > CC1K_SquelchCount) call SquelchTimer.start(TIMER_REPEAT, CC1K_SquelchIntervalSlow); else call SquelchTimer.start(TIMER_REPEAT, CC1K_SquelchIntervalFast); call WakeupTimer.start(TIMER_ONE_SHOT, CC1K_LPL_PACKET_TIME*2); atomic RadioState = IDLE_STATE; } } return Result; } /********************************************************** * make a spibus interrupt handler * needs to handle interrupts for transmit delay * and then go into byte transmit mode with * timer1 baudrate delay as interrupt handler * else * needs to handle interrupts for byte read and detect preamble * then handle reading a packet * PB - We can use this interrupt handler as a transmit scheduler * because the CC1000 continuously clocks in data, regarless * of whether it's good or not. Thus, this routine will be called * on every 8 ticks of DCLK. **********************************************************/ async event result_t SpiByteFifo.dataReady(uint8_t data_in) { signal RadioSendCoordinator.blockTimer(); signal RadioReceiveCoordinator.blockTimer(); if (bInvertRxData) data_in = ~data_in;#ifdef ENABLE_UART_DEBUG UARTPutChar(RadioState);#endif switch (RadioState) { case TX_STATE: { call SpiByteFifo.writeByte(NextTxByte); TxByteCnt++; switch (RadioTxState) { case TXSTATE_PREAMBLE: if (!(TxByteCnt < preamblelen)) { NextTxByte = SYNC_BYTE; RadioTxState = TXSTATE_SYNC; } break; case TXSTATE_SYNC: NextTxByte = NSYNC_BYTE; /**** TinySec ****/ if(txbufptr->length & TINYSEC_ENABLED_BIT) RadioTxState = TXSTATE_DATA_TINYSEC; else RadioTxState = TXSTATE_DATA; /**** TinySec ****/ TxByteCnt = -1; // for Time Sync services signal RadioSendCoordinator.startSymbol(8, 0,(TOS_MsgPtr) txbufptr); break; case TXSTATE_DATA: if ((uint8_t)(TxByteCnt) < txlength) { NextTxByte = ((uint8_t *)txbufptr)[(TxByteCnt)]; usRunningCRC = crcByte(usRunningCRC,NextTxByte); signal RadioSendCoordinator.byte((TOS_MsgPtr) txbufptr, (uint8_t)TxByteCnt); // Time Sync } else { NextTxByte = (uint8_t)(usRunningCRC); RadioTxState = TXSTATE_CRC; } break; /**** TinySec ****/ case TXSTATE_DATA_TINYSEC: signal RadioSendCoordinator.byte((TOS_MsgPtr) txbufptr, (uint8_t)TxByteCnt); // Time Sync NextTxByte = signal TinySecRadio.getTransmitByte(); break; /**** TinySec ****/ case TXSTATE_CRC: NextTxByte = (uint8_t)(usRunningCRC>>8); RadioTxState = TXSTATE_FLUSH; TxByteCnt = 0; break; case TXSTATE_FLUSH: if (TxByteCnt > 3) { TxByteCnt = 0; RadioTxState = TXSTATE_WAIT_FOR_ACK; } break; case TXSTATE_WAIT_FOR_ACK: if(TxByteCnt == 1){ call SpiByteFifo.rxMode(); call CC1000Control.RxMode(); } if (TxByteCnt > 3) { RadioTxState = TXSTATE_READ_ACK; TxByteCnt = 0; search_word = 0; } break; case TXSTATE_READ_ACK: { uint8_t i; for(i = 0; i < 8; i ++){
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -