📄 cc2420radiom.nc
字号:
rxbufptr->time = time; signal RadioReceiveCoordinator.startSymbol(8,0,rxbufptr); } return SUCCESS; } /** * Start sending the packet data to the TXFIFO of the CC2420 */ task void startSend() { // flush the tx fifo of stale data if (!(call HPLChipcon.cmd(CC2420_SFLUSHTX))) { sendFailed(); return; } // write the txbuf data to the TXFIFO if (!(call HPLChipconFIFO.writeTXFIFO(txlength+1,(uint8_t*)txbufptr))) { sendFailed(); return; } } /** * Check for a clear channel and try to send the packet if a clear * channel exists using the sendPacket() function */ void tryToSend() { uint8_t currentstate; atomic currentstate = stateRadio; // and the CCA check is good if (currentstate == PRE_TX_STATE) { // if a FIFO overflow occurs or if the data length is invalid, flush // the RXFIFO to get back to a normal state. if ((!TOSH_READ_CC_FIFO_PIN() && !TOSH_READ_CC_FIFOP_PIN())) { flushRXFIFO(); } if (TOSH_READ_RADIO_CCA_PIN()) { atomic stateRadio = TX_STATE; sendPacket(); } else { // if we tried a bunch of times, the radio may be in a bad state // flushing the RXFIFO returns the radio to a non-overflow state // and it continue normal operation (and thus send our packet) if (countRetry-- <= 0) { flushRXFIFO(); countRetry = MAX_SEND_TRIES; if (!post startSend()) sendFailed(); return; } if (!(setBackoffTimer(signal MacBackoff.congestionBackoff(txbufptr) * CC2420_SYMBOL_UNIT))) { sendFailed(); } } } } /** * Multiplexed timer to control initial backoff, * congestion backoff, and delay while waiting for an ACK */ async event result_t BackoffTimerJiffy.fired() { uint8_t currentstate; atomic currentstate = stateRadio; switch (stateTimer) { case TIMER_INITIAL: if (!(post startSend())) { sendFailed(); } break; case TIMER_BACKOFF: tryToSend(); break; case TIMER_ACK: if (currentstate == POST_TX_STATE) { /* MDW 12-July-05: Race condition here: If ACK comes in before * PacketSent() runs, the task can be posted twice (duplicate * sendDone events). Fix: set the state to a different value to * suppress the later task. */ atomic { txbufptr->ack = 0; stateRadio = POST_TX_ACK_STATE; } if (!post PacketSent()) sendFailed(); } break; } return SUCCESS; } /********************************************************** * Send * - Xmit a packet * USE SFD FALLING FOR END OF XMIT !!!!!!!!!!!!!!!!!! interrupt??? * - If in power-down state start timer ? !!!!!!!!!!!!!!!!!!!!!!!!!s * - If !TxBusy then * a) Flush the tx fifo * b) Write Txfifo address * **********************************************************/ command result_t Send.send(TOS_MsgPtr pMsg) { uint8_t currentstate; atomic currentstate = stateRadio; if (currentstate == IDLE_STATE) { // put default FCF values in to get address checking to pass pMsg->fcflo = CC2420_DEF_FCF_LO; if (bAckEnable) pMsg->fcfhi = CC2420_DEF_FCF_HI_ACK; else pMsg->fcfhi = CC2420_DEF_FCF_HI; // destination PAN is broadcast pMsg->destpan = TOS_BCAST_ADDR; // adjust the destination address to be in the right byte order pMsg->addr = toLSB16(pMsg->addr); // adjust the data length to now include the full packet length pMsg->length = pMsg->length + MSG_HEADER_SIZE + MSG_FOOTER_SIZE; // keep the DSN increasing for ACK recognition pMsg->dsn = ++currentDSN; // reset the time field pMsg->time = 0; // FCS bytes generated by CC2420 txlength = pMsg->length - MSG_FOOTER_SIZE; txbufptr = pMsg; countRetry = MAX_SEND_TRIES; if (setInitialTimer(signal MacBackoff.initialBackoff(txbufptr) * CC2420_SYMBOL_UNIT)) { atomic stateRadio = PRE_TX_STATE; return SUCCESS; } } return FAIL; } /** * Delayed RXFIFO is used to read the receive FIFO of the CC2420 * in task context after the uC receives an interrupt that a packet * is in the RXFIFO. Task context is necessary since reading from * the FIFO may take a while and we'd like to get other interrupts * during that time, or notifications of additional packets received * and stored in the CC2420 RXFIFO. */ void delayedRXFIFO(); task void delayedRXFIFOtask() { delayedRXFIFO(); } void delayedRXFIFO() { uint8_t len = MSG_DATA_SIZE; uint8_t _bPacketReceiving; if ((!TOSH_READ_CC_FIFO_PIN()) && (!TOSH_READ_CC_FIFOP_PIN())) { flushRXFIFO(); return; } atomic { _bPacketReceiving = bPacketReceiving; if (_bPacketReceiving) { if (!post delayedRXFIFOtask()) flushRXFIFO(); } else { bPacketReceiving = TRUE; } } // JP NOTE: TODO: move readRXFIFO out of atomic context to permit // high frequency sampling applications and remove delays on // interrupts being processed. There is a race condition // that has not yet been diagnosed when RXFIFO may be interrupted. if (!_bPacketReceiving) { if (!call HPLChipconFIFO.readRXFIFO(len,(uint8_t*)rxbufptr)) { atomic bPacketReceiving = FALSE; if (!post delayedRXFIFOtask()) { flushRXFIFO(); } return; } } flushRXFIFO(); } /********************************************************** * FIFOP lo Interrupt: Rx data avail in CC2420 fifo * Radio must have been in Rx mode to get this interrupt * If FIFO pin =lo then fifo overflow=> flush fifo & exit * * * Things ToDo: * * -Disable FIFOP interrupt until PacketRcvd task complete * until send.done complete * * -Fix mixup: on return * rxbufptr->rssi is CRC + Correlation value * rxbufptr->strength is RSSI **********************************************************/ async event result_t FIFOP.fired() { // call Leds.yellowToggle(); // if we're trying to send a message and a FIFOP interrupt occurs // and acks are enabled, we need to backoff longer so that we don't // interfere with the ACK if (bAckEnable && (stateRadio == PRE_TX_STATE)) { if (call BackoffTimerJiffy.isSet()) { call BackoffTimerJiffy.stop(); call BackoffTimerJiffy.setOneShot((signal MacBackoff.congestionBackoff(txbufptr) * CC2420_SYMBOL_UNIT) + CC2420_ACK_DELAY); } } /** Check for RXFIFO overflow **/ if (!TOSH_READ_CC_FIFO_PIN()){ flushRXFIFO(); return SUCCESS; } atomic { if (post delayedRXFIFOtask()) { call FIFOP.disable(); } else { flushRXFIFO(); } } // return SUCCESS to keep FIFOP events occurring return SUCCESS; } /** * After the buffer is received from the RXFIFO, * process it, then post a task to signal it to the higher layers */ async event result_t HPLChipconFIFO.RXFIFODone(uint8_t length, uint8_t *data) { // JP NOTE: rare known bug in high contention: // radio stack will receive a valid packet, but for some reason the // length field will be longer than normal. The packet data will // be valid up to the correct length, and then will contain garbage // after the correct length. There is no currently known fix. uint8_t currentstate; atomic { currentstate = stateRadio; } // if a FIFO overflow occurs or if the data length is invalid, flush // the RXFIFO to get back to a normal state. if ((!TOSH_READ_CC_FIFO_PIN() && !TOSH_READ_CC_FIFOP_PIN()) || (length == 0) || (length > MSG_DATA_SIZE)) { flushRXFIFO(); atomic bPacketReceiving = FALSE; return SUCCESS; } rxbufptr = (TOS_MsgPtr)data; // check for an acknowledgement that passes the CRC check if (bAckEnable && (currentstate == POST_TX_STATE) && ((rxbufptr->fcfhi & 0x07) == CC2420_DEF_FCF_TYPE_ACK) && (rxbufptr->dsn == currentDSN) && ((data[length-1] >> 7) == 1)) { atomic { txbufptr->ack = 1; txbufptr->strength = data[length-2]; txbufptr->lqi = data[length-1] & 0x7F; /* MDW 12-Jul-05: Need to set the real radio state here... */ stateRadio = POST_TX_ACK_STATE; bPacketReceiving = FALSE; } if (!post PacketSent()) sendFailed(); return SUCCESS; } // check for invalid packets // an invalid packet is a non-data packet with the wrong // addressing mode (FCFLO byte) if (((rxbufptr->fcfhi & 0x07) != CC2420_DEF_FCF_TYPE_DATA) || (rxbufptr->fcflo != CC2420_DEF_FCF_LO)) { flushRXFIFO(); atomic bPacketReceiving = FALSE; return SUCCESS; } rxbufptr->length = rxbufptr->length - MSG_HEADER_SIZE - MSG_FOOTER_SIZE; if (rxbufptr->length > TOSH_DATA_LENGTH) { flushRXFIFO(); atomic bPacketReceiving = FALSE; return SUCCESS; } // adjust destination to the right byte order rxbufptr->addr = fromLSB16(rxbufptr->addr); // if the length is shorter, we have to move the CRC bytes rxbufptr->crc = data[length-1] >> 7; // put in RSSI rxbufptr->strength = data[length-2]; // put in LQI rxbufptr->lqi = data[length-1] & 0x7F; atomic { if (!post PacketRcvd()) { bPacketReceiving = FALSE; } } if ((!TOSH_READ_CC_FIFO_PIN()) && (!TOSH_READ_CC_FIFOP_PIN())) { flushRXFIFO(); return SUCCESS; } if (!(TOSH_READ_CC_FIFOP_PIN())) { if (post delayedRXFIFOtask()) return SUCCESS; } flushRXFIFO(); // call FIFOP.startWait(FALSE); return SUCCESS; } /** * Notification that the TXFIFO has been filled with the data from the packet * Next step is to try to send the packet */ async event result_t HPLChipconFIFO.TXFIFODone(uint8_t length, uint8_t *data) { tryToSend(); return SUCCESS; } /** Enable link layer hardware acknowledgements **/ async command void MacControl.enableAck() { atomic bAckEnable = TRUE; call CC2420Control.enableAddrDecode(); call CC2420Control.enableAutoAck(); } /** Disable link layer hardware acknowledgements **/ async command void MacControl.disableAck() { atomic bAckEnable = FALSE; call CC2420Control.disableAddrDecode(); call CC2420Control.disableAutoAck(); } /** * How many basic time periods to back off. * Each basic time period consists of 20 symbols (16uS per symbol) */ default async event int16_t MacBackoff.initialBackoff(TOS_MsgPtr m) { return (call Random.rand() & 0xF) + 1; } /** * How many symbols to back off when there is congestion * (16uS per symbol * 20 symbols/block) */ default async event int16_t MacBackoff.congestionBackoff(TOS_MsgPtr m) { return (call Random.rand() & 0x3F) + 1; }// Default events for radio send/receive coordinators do nothing.// Be very careful using these, you'll break the stack.// The "byte()" event is never signalled because the CC2420 is a packet// based radio.default async event void RadioSendCoordinator.startSymbol(uint8_t bitsPerBlock, uint8_t offset, TOS_MsgPtr msgBuff) { }default async event void RadioSendCoordinator.byte(TOS_MsgPtr msg, uint8_t byteCount) { }default async event void RadioReceiveCoordinator.startSymbol(uint8_t bitsPerBlock, uint8_t offset, TOS_MsgPtr msgBuff) { }default async event void RadioReceiveCoordinator.byte(TOS_MsgPtr msg, uint8_t byteCount) { }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -