+ void waitBackoffSlottedCsmaCaDone()
+ {
+ bool cca;
+ uint16_t dtTx=0;
+ int8_t dummy;
+ atomic {
+ // CC2420 needs to be in an Rx state for STXONCCA strobe
+ // note: the receive logic of the CC2420 driver is not yet started,
+ // i.e. we will not (yet) receive any packets
+ call CC2420Power.rxOn();
+ m_state = S_TX_ACTIVE;
+ // wait for CC2420 Rx to calibrate + CCA valid time
+ while (call CC2420Power.rssi(&dummy) != SUCCESS)
+ ;
+ // perform CCA on slot boundary (or rather 8 symbols after)
+ call ReliableWait.busyWaitSlotBoundaryCCA(m_t0Tx, &dtTx); // platform-specific implementation
+ cca = call CC2420Tx.cca();
+ if (cca && dtTx <= m_dtMax){
+ // Tx in following slot (STXONCCA)
+ call ReliableWait.busyWaitSlotBoundaryTx(m_t0Tx, dtTx+20); // platform-specific implementation
+ if (call CC2420Tx.send(TRUE) == SUCCESS){
+ checkEnableRxForACK();
+ return;
+ } else
+ cca = FALSE;
+ }
+ // did not transmit the frame
+ call CC2420Power.rfOff();
+ call CC2420Power.flushRxFifo(); // we might have (accidentally) caught something
+ m_state = S_TX_LOADED;
+ if (dtTx > m_dtMax)
+ // frame didn't fit into remaining CAP, this can only
+ // be because we couldn't meet the time-constraints
+ // (in principle the frame should have fitted)
+ signal RadioTx.transmitSlottedCsmaCaDone(m_txframe, NULL, FALSE, 0, m_csmaParams, ERETRY);
+ else {
+ // CCA failed
+ m_csmaParams->NB += 1;
+ if (m_csmaParams->NB > m_csmaParams->macMaxCsmaBackoffs){
+ // CSMA-CA failure, note: we keep owning the SPI
+ signal RadioTx.transmitSlottedCsmaCaDone(m_txframe, NULL, FALSE, 0, m_csmaParams, FAIL);
+ } else {
+ // next iteration of slotted CSMA-CA
+ m_csmaParams->BE += 1;
+ if (m_csmaParams->BE > m_csmaParams->macMaxBE)
+ m_csmaParams->BE = m_csmaParams->macMaxBE;
+ randomDelaySlottedCsmaCa(FALSE, 0);
+ }
+ }
+ }
+ }
+
+ async event void ReliableWait.waitBackoffDone()