📄 mrfi_radio.c
字号:
//
// /* Retry ? */
// if (ccaRetries != 0)
// {
// /* delay for a random number of backoffs */
// Mrfi_RandomBackoffDelay();
//
// /* decrement CCA retries before loop continues */
// ccaRetries--;
// }
// else /* No CCA retries are left, abort */
// {
// /* set return value for failed transmit and break */
// returnValue = MRFI_TX_RESULT_FAILED;
// break;
// }
// } /* CCA Failed */
} /* CCA loop */
}/* txType is CCA */
/* Done with TX. Clean up time... */
/* Radio is already in IDLE state */
/*
* Flush the transmit FIFO. It must be flushed so that
* the next transmit can start with a clean slate.
*/
mrfiSpiCmdStrobe( SFTX );
/* Restore GDO_0 to be SYNC signal */
MRFI_CONFIG_GDO0_AS_SYNC_SIGNAL();
/* If the radio was in RX state when transmit was attempted,
* put it back to Rx On state.
*/
if(mrfiRadioState == MRFI_RADIO_STATE_RX)
{
Mrfi_RxModeOn();
}
return( returnValue );
}
/**************************************************************************************************
* @fn MRFI_Receive
*
* @brief Copies last packet received to the location specified.
* This function is meant to be called after the ISR informs
* higher level code that there is a newly received packet.
*
* @param pPacket - pointer to location of where to copy received packet
*
* @return none
**************************************************************************************************
*/
void MRFI_Receive(mrfiPacket_t * pPacket)
{
*pPacket = mrfiIncomingPacket;
}
/**************************************************************************************************
* @fn Mrfi_SyncPinRxIsr
*
* @brief This interrupt is called when the SYNC signal transition from high to low.
* The sync signal is routed to the sync pin which is a GPIO pin. This high-to-low
* transition signifies a receive has completed. The SYNC signal also goes from
* high to low when a transmit completes. This is protected against within the
* transmit function by disabling sync pin interrupts until transmit completes.
*
* @param none
*
* @return none
**************************************************************************************************
*/
void Mrfi_SyncPinRxIsr(void)
{
uint8_t frameLen;
uint8_t rxBytes;
/* We should receive this interrupt only in RX state
* Should never receive it if RX was turned On only for
* some internal mrfi processing like - during CCA.
* Otherwise something is terribly wrong.
*/
//MRFI_ASSERT( mrfiRadioState == MRFI_RADIO_STATE_RX );
if(mrfiRadioState != MRFI_RADIO_STATE_RX)
{
return;
}
/* ------------------------------------------------------------------
* Get RXBYTES
* -------------
*/
/*
* Read the RXBYTES register from the radio.
* Bit description of RXBYTES register:
* bit 7 - RXFIFO_OVERFLOW, set if receive overflow occurred
* bits 6:0 - NUM_BYTES, number of bytes in receive FIFO
*
* Due a chip bug, the RXBYTES register must read the same value twice
* in a row to guarantee an accurate value.
*/
{
uint8_t rxBytesVerify;
rxBytesVerify = mrfiSpiReadReg( RXBYTES );
do
{
rxBytes = rxBytesVerify;
rxBytesVerify = mrfiSpiReadReg( RXBYTES );
}
while (rxBytes != rxBytesVerify);
}
/* ------------------------------------------------------------------
* FIFO empty?
* -------------
*/
/*
* See if the receive FIFIO is empty before attempting to read from it.
* It is possible nothing the FIFO is empty even though the interrupt fired.
* This can happen if address check is enabled and a non-matching packet is
* received. In that case, the radio automatically removes the packet from
* the FIFO.
*/
if (rxBytes == 0)
{
/* receive FIFO is empty - do nothing, skip to end */
}
else
{
/* receive FIFO is not empty, continue processing */
/* ------------------------------------------------------------------
* Process frame length
* ----------------------
*/
/* read the first byte from FIFO - the packet length */
mrfiSpiReadRxFifo(&frameLen, MRFI_LENGTH_FIELD_SIZE);
/*
* Make sure that the frame length just read corresponds to number of bytes in the buffer.
* If these do not match up something is wrong.
*
* This can happen for several reasons:
* 1) Incoming packet has an incorrect format or is corrupted.
* 2) The receive FIFO overflowed. Overflow is indicated by the high
* bit of rxBytes. This guarantees the value of rxBytes value will not
* match the number of bytes in the FIFO for overflow condition.
* 3) Interrupts were blocked for an abnormally long time which
* allowed a following packet to at least start filling the
* receive FIFO. In this case, all received and partially received
* packets will be lost - the packet in the FIFO and the packet coming in.
* This is the price the user pays if they implement a giant
* critical section.
* 4) A failed transmit forced radio to IDLE state to flush the transmit FIFO.
* This could cause an active receive to be cut short.
*
* Also check the sanity of the length to guard against rogue frames.
*/
if ((rxBytes != (frameLen + MRFI_LENGTH_FIELD_SIZE + MRFI_RX_METRICS_SIZE)) ||
((frameLen + MRFI_LENGTH_FIELD_SIZE) > MRFI_MAX_FRAME_SIZE) ||
(frameLen < MRFI_MIN_SMPL_FRAME_SIZE)
)
{
//bspIState_t s;
/* mismatch between bytes-in-FIFO and frame length */
/*
* Flush receive FIFO to reset receive. Must go to IDLE state to do this.
* The critical section guarantees a transmit does not occur while cleaning up.
*/
//BSP_ENTER_CRITICAL_SECTION(s);
MRFI_STROBE_IDLE_AND_WAIT();
mrfiSpiCmdStrobe( SFRX );
mrfiSpiCmdStrobe( SRX );
//BSP_EXIT_CRITICAL_SECTION(s);
/* flush complete, skip to end */
}
else
{
/* bytes-in-FIFO and frame length match up - continue processing */
/* ------------------------------------------------------------------
* Get packet
* ------------
*/
/* clean out buffer to help protect against spurious frames */
memset(mrfiIncomingPacket.frame, 0x00, sizeof(mrfiIncomingPacket.frame));
/* set length field */
mrfiIncomingPacket.frame[MRFI_LENGTH_FIELD_OFS] = frameLen;
/* get packet from FIFO */
mrfiSpiReadRxFifo(&(mrfiIncomingPacket.frame[MRFI_FRAME_BODY_OFS]), frameLen);
/* get receive metrics from FIFO */
mrfiSpiReadRxFifo(&(mrfiIncomingPacket.rxMetrics[0]), MRFI_RX_METRICS_SIZE);
/* ------------------------------------------------------------------
* CRC check
* ------------
*/
/*
* Note! Automatic CRC check is not, and must not, be enabled. This feature
* flushes the *entire* receive FIFO when CRC fails. If this feature is
* enabled it is possible to be reading from the FIFO and have a second
* receive occur that fails CRC and automatically flushes the receive FIFO.
* This could cause reads from an empty receive FIFO which puts the radio
* into an undefined state.
*/
/* determine if CRC failed */
if (!(mrfiIncomingPacket.rxMetrics[MRFI_RX_METRICS_CRC_LQI_OFS] & MRFI_RX_METRICS_CRC_OK_MASK))
{
/* CRC failed - do nothing, skip to end */
}
else
{
/* CRC passed - continue processing */
/* ------------------------------------------------------------------
* Filtering
* -----------
*/
/* if address is not filtered, receive is successful */
if (!MRFI_RxAddrIsFiltered(MRFI_P_DST_ADDR(&mrfiIncomingPacket)))
{
{
/* ------------------------------------------------------------------
* Receive successful
* --------------------
*/
/* Convert the raw RSSI value and do offset compensation for this radio */
mrfiIncomingPacket.rxMetrics[MRFI_RX_METRICS_RSSI_OFS] =
Mrfi_CalculateRssi(mrfiIncomingPacket.rxMetrics[MRFI_RX_METRICS_RSSI_OFS]);
/* Remove the CRC valid bit from the LQI byte */
mrfiIncomingPacket.rxMetrics[MRFI_RX_METRICS_CRC_LQI_OFS] =
(mrfiIncomingPacket.rxMetrics[MRFI_RX_METRICS_CRC_LQI_OFS] & MRFI_RX_METRICS_LQI_MASK);
/* call external, higher level "receive complete" processing routine */
//MRFI_RxCompleteISR();
}
}
}
}
}
/* ------------------------------------------------------------------
* End of function
* -------------------
*/
}
/**************************************************************************************************
* @fn Mrfi_RxModeOn
*
* @brief Put radio into receive mode.
*
* @param none
*
* @return none
**************************************************************************************************
*/
void Mrfi_RxModeOn(void)
{
/* clear any residual receive interrupt */
MRFI_CLEAR_SYNC_PIN_INT_FLAG();
/* send strobe to enter receive mode */
mrfiSpiCmdStrobe( SRX );
/* enable receive interrupts */
MRFI_ENABLE_SYNC_PIN_INT();
}
/**************************************************************************************************
* @fn MRFI_RxOn
*
* @brief Turn on the receiver. No harm is done if this function is called when
* receiver is already on.
*
* @param none
*
* @return none
**************************************************************************************************
*/
void MRFI_RxOn(void)
{
/* radio must be awake before we can move it to RX state */
MRFI_ASSERT( mrfiRadioState != MRFI_RADIO_STATE_OFF );
/* if radio is off, turn it on */
if(mrfiRadioState != MRFI_RADIO_STATE_RX)
{
mrfiRadioState = MRFI_RADIO_STATE_RX;
Mrfi_RxModeOn();
}
}
/**************************************************************************************************
* @fn Mrfi_RxModeOff
*
* @brief -
*
* @param none
*
* @return none
**************************************************************************************************
*/
//static void Mrfi_RxModeOff(void)
void Mrfi_RxModeOff(void)
{
/*disable receive interrupts */
MRFI_DISABLE_SYNC_PIN_INT();
/* turn off radio */
MRFI_STROBE_IDLE_AND_WAIT();
/* flush the receive FIFO of any residual data */
mrfiSpiCmdStrobe( SFRX );
/* clear receive interrupt */
MRFI_CLEAR_SYNC_PIN_INT_FLAG();
}
/**************************************************************************************************
* @fn MRFI_RxIdle
*
* @brief Put radio in idle mode (receiver if off). No harm is done this function is
* called when radio is already idle.
*
* @param none
*
* @return none
**************************************************************************************************
*/
void MRFI_RxIdle(void)
{
/* radio must be awake to move it to idle mode */
MRFI_ASSERT( mrfiRadioState != MRFI_RADIO_STATE_OFF );
/* if radio is on, turn it off */
if(mrfiRadioState == MRFI_RADIO_STATE_RX)
{
Mrfi_RxModeOff();
mrfiRadioState = MRFI_RADIO_STATE_IDLE;
}
}
/**************************************************************************************************
* @fn MRFI_Sleep
*
* @brief Request radio go to sleep.
*
* @param none
*
* @return none
**************************************************************************************************
*/
void MRFI_Sleep(void)
{
// bspIState_t s;
/* Critical section necessary for watertight testing and
* setting of state variables.
*/
// BSP_ENTER_CRITICAL_SECTION(s);
/* If radio is not asleep, put it to sleep */
if(mrfiRadioState != MRFI_RADIO_STATE_OFF)
{
/* go to idle so radio is in a known state before sleeping */
MRFI_RxIdle();
mrfiSpiCmdStrobe( SPWD );
/* Our new state is OFF */
mrfiRadioState = MRFI_RADIO_STATE_OFF;
}
// BSP_EXIT_CRITICAL_SECTION(s);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -