📄 cc1000sendreceivep.nc
字号:
call HplCC1000Spi.rxMode(); call CC1000Control.rxMode(); } else if (count > 3) enterTxReadAckState(); } void txReadAck(uint8_t in) { uint8_t i; sendNextByte(); for (i = 0; i < 8; i ++) { rxShiftBuf <<= 1; if (in & 0x80) rxShiftBuf |= 0x1; in <<= 1; if (rxShiftBuf == ACK_WORD) { getMetadata(txBufPtr)->metadataBits |= CC1000_ACK_BIT; enterTxDoneState(); return; } } if (count >= MAX_ACK_WAIT) { getMetadata(txBufPtr)->metadataBits &= ~CC1000_ACK_BIT; enterTxDoneState(); } } task void signalPacketSent() { message_t *pBuf; atomic { pBuf = txBufPtr; f.txBusy = FALSE; enterListenState(); } signal Send.sendDone(pBuf, SUCCESS); } void txDone() { post signalPacketSent(); signal ByteRadio.sendDone(); } /* Receive */ /*---------*/ void packetReceived(); void packetReceiveDone(); async command void ByteRadio.listen() { enterListenState(); call CC1000Control.rxMode(); call HplCC1000Spi.rxMode(); call HplCC1000Spi.enableIntr(); } async command void ByteRadio.off() { enterInactiveState(); call HplCC1000Spi.disableIntr(); } void listenData(uint8_t in) { bool preamble = in == 0xaa || in == 0x55; // Look for enough preamble bytes if (preamble) { count++; if (count > CC1K_ValidPrecursor) enterSyncState(); } else count = 0; signal ByteRadio.idleByte(preamble); } void syncData(uint8_t in) { // 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. if (in == 0xaa || 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 = in << 8; else if (count++ == 0) rxShiftBuf |= in; else if (count <= 6) { // TODO: Modify to be tolerant of bad bits in the preamble... uint16_t tmp; uint8_t i; // bit shift the data in with previous sample to find sync tmp = rxShiftBuf; rxShiftBuf = rxShiftBuf << 8 | in; for(i = 0; i < 8; i++) { tmp <<= 1; if (in & 0x80) tmp |= 0x1; in <<= 1; // check for sync bytes if (tmp == SYNC_WORD) { enterRxState(); signal ByteRadio.rx(); f.rxBitOffset = 7 - i; signal RadioTimeStamping.receivedSFD(0); call RssiRx.read(); } } } else // We didn't find it after a reasonable number of tries, so.... enterListenState(); } async event void RssiRx.readDone(error_t result, uint16_t data) { cc1000_metadata_t *rxMetadata = getMetadata(rxBufPtr); if (result != SUCCESS) rxMetadata->strength_or_preamble = 0; else rxMetadata->strength_or_preamble = data; } void rxData(uint8_t in) { uint8_t nextByte; cc1000_header_t *rxHeader = getHeader(rxBufPtr); uint8_t rxLength = rxHeader->length; // Reject invalid length packets if (rxLength > TOSH_DATA_LENGTH) { // The packet's screwed up, so just dump it enterListenState(); signal ByteRadio.rxDone(); return; } rxShiftBuf = rxShiftBuf << 8 | in; nextByte = rxShiftBuf >> f.rxBitOffset; ((uint8_t *COUNT(sizeof(message_t)))rxBufPtr)[count++] = nextByte; // Adjust rxLength to correspond to the corresponding offset in message_t rxLength += offsetof(message_t, data); if (count <= rxLength) runningCrc = crcByte(runningCrc, nextByte); // Jump to CRC when we reach the end of data if (count == rxLength) { count = offsetof(message_t, footer) + offsetof(cc1000_footer_t, crc); } if (count == (offsetof(message_t, footer) + sizeof(cc1000_footer_t))) packetReceived(); } void packetReceived() { cc1000_footer_t *rxFooter = getFooter(rxBufPtr); cc1000_header_t *rxHeader = getHeader(rxBufPtr); // Packet filtering based on bad CRC's is done at higher layers. // So sayeth the TOS weenies. rxFooter->crc = (rxFooter->crc == runningCrc); if (f.ack && rxFooter->crc && rxHeader->dest == call amAddress()) { enterAckState(); call CC1000Control.txMode(); call HplCC1000Spi.txMode(); call HplCC1000Spi.writeByte(0xaa); } else packetReceiveDone(); } void ackData(uint8_t in) { if (++count >= ACK_LENGTH) { call CC1000Control.rxMode(); call HplCC1000Spi.rxMode(); packetReceiveDone(); } else if (count >= ACK_LENGTH - sizeof ackCode) call HplCC1000Spi.writeByte(read_uint8_t(&ackCode[count + sizeof ackCode - ACK_LENGTH])); } task void signalPacketReceived() { message_t *pBuf; cc1000_header_t *pHeader; atomic { if (radioState != RECEIVED_STATE) return; pBuf = rxBufPtr; } pHeader = getHeader(pBuf); pBuf = signal Receive.receive(pBuf, pBuf->data, pHeader->length); atomic { if (pBuf) rxBufPtr = pBuf; if (radioState == RECEIVED_STATE) // receiver might've done something enterListenState(); signal ByteRadio.rxDone(); } } void packetReceiveDone() { uint16_t snr; snr = (uint16_t) getMetadata(rxBufPtr)->strength_or_preamble; /* Higher signal strengths have lower voltages. So see if we're CC1000_WHITE_BIT_THRESH *below* the noise floor. */ if ((snr + CC1000_WHITE_BIT_THRESH) < ((call CC1000Squelch.get()))) { getMetadata(rxBufPtr)->metadataBits |= CC1000_WHITE_BIT; } else { getMetadata(rxBufPtr)->metadataBits &= ~CC1000_WHITE_BIT; } post signalPacketReceived(); enterReceivedState(); } async event void HplCC1000Spi.dataReady(uint8_t data) { if (f.invert) data = ~data; switch (radioState) { default: break; case TXPREAMBLE_STATE: txPreamble(); break; case TXSYNC_STATE: txSync(); break; case TXDATA_STATE: txData(); break; case TXCRC_STATE: txCrc(); break; case TXFLUSH_STATE: txFlush(); break; case TXWAITFORACK_STATE: txWaitForAck(); break; case TXREADACK_STATE: txReadAck(data); break; case TXDONE_STATE: txDone(); break; case LISTEN_STATE: listenData(data); break; case SYNC_STATE: syncData(data); break; case RX_STATE: rxData(data); break; case SENDING_ACK: ackData(data); break; } } /* Interaction with rest of stack */ /*--------------------------------*/ async command void ByteRadio.setPreambleLength(uint16_t bytes) { atomic preambleLength = bytes; } async command uint16_t ByteRadio.getPreambleLength() { atomic return preambleLength; } async command message_t *ByteRadio.getTxMessage() { return txBufPtr; } async command bool ByteRadio.syncing() { return radioState == SYNC_STATE; } /* Abstract packet layout */ command void Packet.clear(message_t *msg) { memset(msg, 0, sizeof(message_t)); } command uint8_t Packet.payloadLength(message_t *msg) { cc1000_header_t *header = getHeader(msg); return header->length; } command void Packet.setPayloadLength(message_t *msg, uint8_t len) { getHeader(msg)->length = len; } command uint8_t Packet.maxPayloadLength() { return TOSH_DATA_LENGTH; } command void* Packet.getPayload(message_t *msg, uint8_t len) { if (len <= TOSH_DATA_LENGTH) { return (void* COUNT_NOK(len))msg->data; } else { return NULL; } } async command error_t PacketAcknowledgements.requestAck(message_t *msg) { return SUCCESS; /* We always ack. */ } async command error_t PacketAcknowledgements.noAck(message_t *msg) { return FAIL; /* We always ack */ } command uint8_t Send.maxPayloadLength() { return call Packet.maxPayloadLength(); } command void* Send.getPayload(message_t *m, uint8_t len) { return call Packet.getPayload(m, len); } async command bool PacketAcknowledgements.wasAcked(message_t *msg) { return getMetadata(msg)->metadataBits & CC1000_ACK_BIT; } async command bool LinkPacketMetadata.highChannelQuality(message_t* msg) { return getMetadata(msg)->metadataBits & CC1000_WHITE_BIT; } // Default events for radio send/receive coordinators do nothing. // Be very careful using these, or you'll break the stack. default async event void RadioTimeStamping.transmittedSFD(uint16_t time, message_t *msgBuff) { } default async event void RadioTimeStamping.receivedSFD(uint16_t time) { }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -