/************************************************************************************************** * @fn MRFI_Sleep * * @brief Request radio go to sleep. * * @param none * * @return zero : if successfully went to sleep * non-zero : if sleep was not entered ************************************************************************************************** */ uint8_t MRFI_Sleep(void) { /* if radio is already asleep just indicate radio went to sleep successfully */ if (mrfiRadioIsSleeping) { /* return value of zero indicates sleep state was entered */ return( 0 ); } /* determine if sleep is possible and return the corresponding code */ { bspIState_t s; /* critical section necessary for watertight testing and setting of state variables */ BSP_ENTER_CRITICAL_SECTION(s); if (!mrfiTxActive && !mrfiRxActive) { mrfiRadioIsSleeping = 1; MRFI_DISABLE_SYNC_PIN_INT(); mrfiSpiCmdStrobe(MRFI_CC2500_SPI_STROBE_SIDLE); mrfiSpiCmdStrobe(MRFI_CC2500_SPI_STROBE_SPWD); BSP_EXIT_CRITICAL_SECTION(s); /* return value of zero indicates sleep state was entered */ return( 0 ); } else { BSP_EXIT_CRITICAL_SECTION(s); /* return value of non-zero indicates sleep state was *not* entered */ return( 1 ); } } }
void radioISR(void) { unsigned int coreIntSource = RF1AIV; // Radio Core interrupt register // Radio Core interrupt if(coreIntSource) { // Check for SYNC interrupt if(coreIntSource == RF1AIV_RFIFG9) { if(MRFI_SYNC_PIN_INT_IS_ENABLED()) { static CCPACKET ccPacket; /* clear the sync pin interrupt, run sync pin ISR */ /* * NOTE! The following macro clears the interrupt flag but it also *must* * reset the interrupt capture. In other words, if a second interrupt * occurs after the flag is cleared it must be processed, i.e. this interrupt * exits then immediately starts again. Most microcontrollers handle this * naturally but it must be verified for every target. */ MRFI_CLEAR_SYNC_PIN_INT_FLAG(); MRFI_DISABLE_SYNC_PIN_INT(); // Any packet waiting to be read? if (panstamp.radio.receiveData(&ccPacket) > 0) { // Is CRC OK? if (ccPacket.crc_ok) { if (panstamp.ccPacketReceived != NULL) panstamp.ccPacketReceived(&ccPacket); } MRFI_ENABLE_SYNC_PIN_INT(); } } } // Check for RF_RDY (Event1 WOR) interrupt else if(coreIntSource == RF1AIV_RFIFG14) { RF1AIE |= BIT9 + BIT1; RF1AIFG &= ~(BIT9 + BIT1); RF1AIES |= BIT9; // Falling edge of RFIFG9 panstamp.radio.setRxState(); __bic_SR_register_on_exit(LPM3_bits); } } }
/** * rxOff * * Disable RF reception */ void PANSTAMP::rxOff(void) { MRFI_DISABLE_SYNC_PIN_INT(); }
/************************************************************************************************** * @fn MRFI_Transmit * * @brief Transmit a packet using CCA algorithm. * * @param pPacket - pointer to packet to transmit * * @return Return code indicates success or failure of transmit: * MRFI_TRANSMIT_SUCCESS - transmit succeeded * MRFI_TRANSMIT_CCA_FAILED - transmit failed because of CCA check(s) * MRFI_TRANSMIT_RADIO_ASLEEP - transmit failed because radio was asleep ************************************************************************************************** */ uint8_t MRFI_Transmit(mrfiPacket_t * pPacket) { uint8_t ccaRetries; uint8_t txBufLen; uint8_t savedSyncIntState; uint8_t returnValue; /* abort transmit if radio is asleep */ { bspIState_t s; /* critical section necessary for watertight testing and setting of state variables */ BSP_ENTER_CRITICAL_SECTION(s); /* if radio is asleep, abort transmit and return reason for failure */ if (mrfiRadioIsSleeping) { BSP_EXIT_CRITICAL_SECTION(s); return( MRFI_TRANSMIT_RADIO_ASLEEP ); } /* radio is not asleep, set flag that indicates transmit is active */ mrfiTxActive = 1; BSP_EXIT_CRITICAL_SECTION(s); } /* set number of CCA retries */ ccaRetries = MRFI_CCA_RETRIES; /* compute number of bytes to write to transmit FIFO */ txBufLen = pPacket->frame[MRFI_LENGTH_FIELD_OFS] + MRFI_LENGTH_FIELD_SIZE; /* write packet to transmit FIFO */ mrfiSpiWriteTxFifo(&(pPacket->frame[0]), txBufLen); /* =============================================================================== * Main Loop * ============= */ for (;;) { /* CCA delay */ MRFI_DELAY(2000); /* disable sync pin interrupts, necessary because both transmit and receive affect sync signal */ MRFI_DISABLE_SYNC_PIN_INT(); /* store the sync pin interrupt flag, important so original state can be restored */ savedSyncIntState = MRFI_SYNC_PIN_INT_FLAG_IS_SET(); /* * Clear the PA_PD pin interrupt flag. This flag, not the interrupt itself, * is used to capture the transition that indicates a transmit was started. * The pin level cannot be used to indicate transmit success as timing may * prevent the transition from being detected. The interrupt latch captures * the event regardless of timing. */ MRFI_CLEAR_PAPD_PIN_INT_FLAG(); /* send strobe to initiate transmit */ mrfiSpiCmdStrobe(MRFI_CC2500_SPI_STROBE_STX); /* delay long enough for the PA_PD signal to indicate a successful transmit */ MRFI_DELAY(250); /* if the interrupt flag of the PA_PD pin is set, CCA passed and the transmit has started */ if (MRFI_PAPD_INT_FLAG_IS_SET()) { /* ------------------------------------------------------------------ * Clear Channel Assessment passed. * ---------------------------------- */ /* wait for transmit to complete */ while (!MRFI_PAPD_PIN_IS_HIGH()); /* * Restore the original sync interrupt state. The successful transmit just * caused a transition on the sync signal that set the flag (if not already * set). To restore the original state, the flag is simply cleared if it * was clear earlier. */ if (!savedSyncIntState) { MRFI_CLEAR_SYNC_PIN_INT_FLAG(); } /* transmit complete, enable sync pin interrupts */ MRFI_ENABLE_SYNC_PIN_INT(); /* set return value for successful transmit and break */ returnValue = MRFI_TRANSMIT_SUCCESS; break; } /* ------------------------------------------------------------------ * Clear Channel Assessment failed. * ---------------------------------- */ /* CCA failed, safe to enable sync pin interrupts */ MRFI_ENABLE_SYNC_PIN_INT(); /* if no CCA retries are left, transmit failed so abort */ if (ccaRetries == 0) { bspIState_t s; /* * Flush the transmit FIFO. It must be flushed so that * the next transmit can start with a clean slate. * Critical section prevents receive interrupt from * occurring in the middle of clean-up. */ BSP_ENTER_CRITICAL_SECTION(s); mrfiSpiCmdStrobe(MRFI_CC2500_SPI_STROBE_SIDLE); mrfiSpiCmdStrobe(MRFI_CC2500_SPI_STROBE_SFTX); mrfiSpiCmdStrobe(MRFI_CC2500_SPI_STROBE_SRX); BSP_EXIT_CRITICAL_SECTION(s); /* set return value for failed transmit and break */ returnValue = MRFI_TRANSMIT_CCA_FAILED; break; } /* decrement CCA retries before loop continues */ ccaRetries--; } /* * =============================================================================== */ mrfiTxActive = 0; return( returnValue ); }