📄 cc1000radiointm.nc
字号:
RadioState = IDLE_STATE; bTxPending = bTxBusy = FALSE; sMacDelay = -1; preamblelen = (((CC1K_LPL_PreambleLength[lplpowertx*2]) << 8) | (CC1K_LPL_PreambleLength[(lplpowertx*2)+1])); } if (lplpower == 0) { // all power on, captain! call CC1000StdControl.start(); call CC1000Control.BIASOn(); call SpiByteFifo.rxMode(); // SPI to miso call CC1000Control.RxMode(); call SpiByteFifo.enableIntr(); // enable spi interrupt } else { uint16_t sleeptime = (((CC1K_LPL_SleepTime[lplpower*2]) << 8) | (CC1K_LPL_SleepTime[(lplpower*2)+1])); atomic RadioState = POWER_DOWN_STATE; call TimerControl.start(); call WakeupTimer.start(TIMER_ONE_SHOT, sleeptime); } } return SUCCESS; } command result_t Send.send(TOS_MsgPtr pMsg) { result_t Result = SUCCESS; atomic { if (bTxBusy) { Result = FAIL; } else { bTxBusy = TRUE; txbufptr = pMsg; txlength = pMsg->length + (MSG_DATA_SIZE - DATA_LENGTH - 2); // initially back off a message + [0,127] radio bytes sMacDelay = MSG_DATA_SIZE + (call Random.rand() & 0x7F); bTxPending = TRUE; } } if (Result) { uint8_t tmpState; atomic tmpState = RadioState; // if we're off, start the radio if (tmpState == 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 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) { if (bInvertRxData) //brchen in simulation, don't need to invert bit //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; RadioTxState = TXSTATE_DATA; TxByteCnt = -1; signal RadioSendCoordinator.startSymbol(); // for Time Sync break; case TXSTATE_DATA: if ((uint8_t)(TxByteCnt) < txlength) { NextTxByte = ((uint8_t *)txbufptr)[(TxByteCnt)]; usRunningCRC = crcByte(usRunningCRC,NextTxByte); signal RadioSendCoordinator.byte(txbufptr, (uint8_t)TxByteCnt); // Time Sync } else { NextTxByte = (uint8_t)(usRunningCRC); RadioTxState = TXSTATE_CRC; } break; case TXSTATE_CRC: NextTxByte = (uint8_t)(usRunningCRC>>8); RadioTxState = TXSTATE_FLUSH; TxByteCnt = 0; break; case TXSTATE_FLUSH: if (TxByteCnt > 3) { RadioTxState = TXSTATE_DONE; } break; case TXSTATE_DONE: default: call SpiByteFifo.rxMode(); call CC1000Control.RxMode(); bTxPending = FALSE; if (post PacketSent()) { // If the post operation succeeds, goto Idle // otherwise, we'll try again. RadioState = IDLE_STATE; } break; } } break; case DISABLED_STATE: break; case IDLE_STATE: { if (((data_in == (0xaa)) || (data_in == (0x55)))) { PreambleCount++; if (PreambleCount > (CC1K_LPL_ValidPrecursor[lplpower])) { PreambleCount = SOFCount = 0; RxBitOffset = RxByteCnt = 0; usRunningCRC = 0; rxlength = MSG_DATA_SIZE-2; RadioState = SYNC_STATE; } } else if (bTxPending && (--sMacDelay <= 0)) { bRSSIValid = FALSE; call RSSIADC.getData(); PreambleCount = 0; RadioState = PRETX_STATE;#if 0 call CC1000Control.TxMode(); call SpiByteFifo.txMode(); TxByteCnt = 0; usRunningCRC = 0; RadioState = TX_STATE; RadioTxState = TXSTATE_PREAMBLE; NextTxByte = 0xaa; call SpiByteFifo.writeByte(0xaa);#endif } } break; case PRETX_STATE: { if (((data_in == (0xaa)) || (data_in == (0x55)))) { // Back to the penalty box. sMacDelay = (((call Random.rand() & 0xf) + 1) * (MSG_DATA_SIZE)); RadioState = IDLE_STATE; } //else if (bRSSIValid) { else if (1) { // because it's simulation , no real RSSI value //if (usRSSIVal > (CC1K_LPL_SquelchInit[lplpower])) { if(1){ // ROCK AND ROLL!!!!! call CC1000Control.TxMode(); call SpiByteFifo.txMode(); TxByteCnt = 0; usRunningCRC = 0; RadioState = TX_STATE; RadioTxState = TXSTATE_PREAMBLE; NextTxByte = 0xaa; call SpiByteFifo.writeByte(0xaa); } else { // Russin frussin freakin frick o frack sMacDelay = (((call Random.rand() & 0xf) + 1) * (MSG_DATA_SIZE)); RadioState = IDLE_STATE; } } } break; case SYNC_STATE: { // draw in the preamble bytes and look for a sync byte // save the data in a short with last byte received as msbyte // and current byte received as the lsbyte. // use a bit shift compare to find the byte boundary for the sync byte // retain the shift value and use it to collect all of the packet data // check for data inversion, and restore proper polarity XXX-PB: Don't do this. uint8_t i; if ((data_in == 0xaa) || (data_in == 0x55)) { // It is actually possible to have the LAST BIT of the incoming // data be part of the Sync Byte. SO, we need to store that // However, the next byte should definitely not have this pattern. // XXX-PB: Do we need to check for excessive preamble? RxShiftBuf.MSB = data_in; } else { // TODO: Modify to be tolerant of bad bits in the preamble... uint16_t usTmp; switch (SOFCount) { case 0: RxShiftBuf.LSB = data_in; break; case 1: case 2: // bit shift the data in with previous sample to find sync usTmp = RxShiftBuf.W; RxShiftBuf.W <<= 8; RxShiftBuf.LSB = data_in; for(i=0;i<8;i++) { usTmp <<= 1; if(data_in & 0x80) usTmp |= 0x1; data_in <<= 1; // check for sync bytes if (usTmp == SYNC_WORD) { if (rxbufptr->length !=0) { call Leds.redToggle(); RadioState = IDLE_STATE; } else { RadioState = RX_STATE; call RSSIADC.getData(); RxBitOffset = 7-i; signal RadioReceiveCoordinator.startSymbol(); // Time sync } break; }#if 0 else if (usTmp == NSYNC_WORD) { RadioState = RX_STATE; RxBitOffset = 7-i; bInvertRxData = TRUE; break; }#endif } break; default: // We didn't find it after a reasonable number of tries, so.... RadioState = IDLE_STATE; // Ensures we wait till the end of the transmission break; } SOFCount++; } } break; // collect the data and shift into double buffer // shift out data by correct offset // invert the data if necessary // stop after the correct packet length is read // return notification to upper levels // go back to idle state case RX_STATE: { char Byte; RxShiftBuf.W <<=8; RxShiftBuf.LSB = data_in; Byte = (RxShiftBuf.W >> RxBitOffset); ((char*)rxbufptr)[(int)RxByteCnt] = Byte; RxByteCnt++; signal RadioReceiveCoordinator.byte(rxbufptr, (uint8_t)RxByteCnt); if (RxByteCnt < rxlength) { usRunningCRC = crcByte(usRunningCRC,Byte); if (RxByteCnt == (offsetof(struct TOS_Msg,length) + sizeof(((struct TOS_Msg *)0)->length))) { rxlength = rxbufptr->length; if (rxlength > TOSH_DATA_LENGTH) { // The packet's screwed up, so just dump it rxbufptr->length = 0; RadioState = IDLE_STATE; // Waits till end of transmission return SUCCESS; } else if (rxlength == 0) { RxByteCnt = offsetof(struct TOS_Msg,crc); } else { //Add in the header size rxlength += offsetof(struct TOS_Msg,data); } } } else if (RxByteCnt == rxlength) { usRunningCRC = crcByte(usRunningCRC,Byte); // Shift index ahead to the crc field. RxByteCnt = offsetof(struct TOS_Msg,crc); } else if (RxByteCnt >= MSG_DATA_SIZE) { // Packet filtering based on bad CRC's is done at higher layers. // So sayeth the TOS weenies. if (rxbufptr->crc == usRunningCRC) { rxbufptr->crc = 1; } else { rxbufptr->crc = 0; } call SpiByteFifo.disableIntr(); RadioState = IDLE_STATE; //DISABLED_STATE; rxbufptr->strength = usRSSIVal; 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(); }#if 0 if (bTxPending) { sMacDelay = (((call Random.rand() & 0xf) +1 ) * (MSG_DATA_SIZE)); }#endif } } break; default: break; }#if 0 // Sample the RSSI value at least twice the maximum possible packet rate // The maximum message rate will be the total number of bytes per packet including // the preamble, sync, TOS_Msg header, 1 byte payload and CRC. // Divide that sum by two to sample at double the packet rate. RSSISampleFreq++; RSSISampleFreq %= (preamblelen + 2 + offsetof(struct TOS_Msg,data) + 3) >> 1); if ((RSSISampleFreq == 0) && (bTxPending || (RadioState == RX_STATE))) { call RSSIADC.getData(); }#endif return SUCCESS;}async event result_t RSSIADC.dataReady(uint16_t data) { //rxbufptr->strength = data; atomic { usRSSIVal = data; bRSSIValid = TRUE; } return SUCCESS;}// Default events for radio send/receive coordinators do nothing.// Be very careful using these, you'll break the stack.default async event void RadioSendCoordinator.startSymbol() { }default async event void RadioSendCoordinator.byte(TOS_MsgPtr msg, uint8_t byteCount) { }default async event void RadioReceiveCoordinator.startSymbol() { }default async event void RadioReceiveCoordinator.byte(TOS_MsgPtr msg, uint8_t byteCount) { }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -