📄 cc1000radiointtinysecm.nc
字号:
rxbufptr->length = 0; RadioState = IDLE_STATE; } } return SUCCESS; } async event result_t TinySec.receiveDone(result_t result ) { if (!(post PacketRcvd())) { // If there are insufficient resources to process the incoming packet // we drop it atomic { RadioState = IDLE_STATE; rxbufptr->length = 0; } call SpiByteFifo.enableIntr(); } return SUCCESS; } /**** TinySec ****/ command result_t Send.send(TOS_MsgPtr pMsg) { result_t Result = SUCCESS; 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 a message + [0,127] radio bytes sMacDelay = MSG_DATA_SIZE + (call Random.rand() & 0x7F); 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 *****/ } } 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) 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; 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((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) { 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 > PRG_RDB(&CC1K_LPL_ValidPrecursor[lplpower])) { PreambleCount = SOFCount = 0; RxBitOffset = RxByteCnt = 0; usRunningCRC = 0; rxlength = MSG_DATA_SIZE-2; /**** TinySec ****/ call TinySec.receiveInit(rxbufptr); /**** TinySec ****/ 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) { if (usRSSIVal > PRG_RDB(&CC1K_LPL_SquelchInit[lplpower])) { // 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); // start encrypting packet - re-enables interrupts // check if encrypt enabled bit is set /**** TinySec ****/ if(txbufptr->length & TINYSEC_ENABLED_BIT) { call TinySec.send(); } /**** TinySec ****/ } 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 = HEADER_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; /**** TinySec ****/ case HEADER_RX_STATE: { char Byte; RxShiftBuf.W <<=8; RxShiftBuf.LSB = data_in; Byte = (RxShiftBuf.W >> RxBitOffset); ((char*)rxbufptr)[(int)RxByteCnt] = Byte; RxByteCnt++; signal RadioReceiveCoordinator.byte((TOS_MsgPtr) rxbufptr, (uint8_t)RxByteCnt); usRunningCRC = crcByte(usRunningCRC,Byte); signal TinySecRadio.byteReceived(Byte); } break; case RX_STATE_TINYSEC: { char Byte; RxShiftBuf.W <<=8; RxShiftBuf.LSB = data_in; Byte = (RxShiftBuf.W >> RxBitOffset); RxByteCnt++; signal RadioReceiveCoordinator.byte((TOS_MsgPtr) rxbufptr, (uint8_t)RxByteCnt); if(RxByteCnt == rxlength + TINYSEC_MAC_LENGTH) { call SpiByteFifo.disableIntr(); RadioState = IDLE_STATE; rxbufptr->strength = usRSSIVal;#if 0 if (bTxPending) { sMacDelay = (((call Random.rand() & 0xf) +1 ) * (MSG_DATA_SIZE)); }#endif } signal TinySecRadio.byteReceived(Byte); } break; /**** TinySec ****/ // 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((TOS_MsgPtr) rxbufptr, (uint8_t)RxByteCnt); if (RxByteCnt < rxlength) { usRunningCRC = crcByte(usRunningCRC,Byte); } 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 + -