📄 mrfi_cc2510.c
字号:
*pCfg++ = /* offset 6 : */ RXTX_DMA_WORDSIZE | RXTX_DMA_TMODE | RXTX_DMA_TRIG;
*pCfg = /* offset 7 : */ RXTX_DMA_SRCINC_PLUS_1 | RXTX_DMA_DESTINC_NONE | RXTX_DMA_IRQMASK | RXTX_DMA_M8 | RXTX_DMA_PRIORITY;
}
/* set number of CCA retries */
ccaRetries = MRFI_CCA_RETRIES;
/* ===============================================================================
* Main Loop
* =============
*/
for (;;)
{
/* CCA delay */
MRFI_DELAY(2000);
RFIM &= ~IM_DONE;
// LAF WORKAROUND: Go to IDLE to kill ongoing Rx. This means that CCA test below will
// not do anything but I will leave the skeleton code until it is fixed properly.
RFST = SIDLE;
MRFI_DELAY(20); // very conservative settling...
DMAARM = ABORT | BV( MRFI_DMA_CHAN );
DMAARM |= BV( MRFI_DMA_CHAN );
RFST = STX;
MRFI_DELAY(20); // very conservative settling...
if (MARCSTATE != RX) // check for !Rx instead of RXTX_SWITCH
{
/* ------------------------------------------------------------------
* Clear Channel Assessment passed.
* ----------------------------------
*/
RFIF &= ~IRQ_DONE;
while (!(RFIF & IRQ_DONE));
/* set return value for successful transmit and break */
returnValue = MRFI_TRANSMIT_SUCCESS;
break;
}
/* ------------------------------------------------------------------
* Clear Channel Assessment failed.
* ----------------------------------
*/
/* if no CCA retries are left, transmit failed so abort */
if (ccaRetries == 0)
{
/* set return value for failed transmit and break */
returnValue = MRFI_TRANSMIT_CCA_FAILED;
break;
}
/* decrement CCA retries before loop continues */
ccaRetries--;
}
/*
* =============================================================================== */
MRFI_RxEnable();
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_RxEnable
*
* @brief -
*
* @param none
*
* @return none
**************************************************************************************************
*/
static void MRFI_RxEnable(void)
{
uint8_t XDATA * pCfg;
/* configure DMA channel for receive */
pCfg = MRFI_DMA_CFG_ADDRESS;
*pCfg++ = /* offset 0 : */ HIGH_BYTE_OF_WORD( &X_RFD ); /* SRCADDRH */
*pCfg++ = /* offset 1 : */ LOW_BYTE_OF_WORD ( &X_RFD ); /* SRCADDRL */
*pCfg++ = /* offset 2 : */ HIGH_BYTE_OF_WORD( &(mrfiIncomingPacket.frame[0]) ); /* DSTADDRH */
*pCfg++ = /* offset 3 : */ LOW_BYTE_OF_WORD ( &(mrfiIncomingPacket.frame[0]) ); /* DSTADDRL */
*pCfg++ = /* offset 4 : */ RXTX_DMA_VLEN_XFER_BYTES_PLUS_3;
*pCfg++ = /* offset 5 : */ RXTX_DMA_LEN;
*pCfg++ = /* offset 6 : */ RXTX_DMA_WORDSIZE | RXTX_DMA_TMODE | RXTX_DMA_TRIG;
*pCfg = /* offset 7 : */ RXTX_DMA_SRCINC_NONE | RXTX_DMA_DESTINC_PLUS_1 | RXTX_DMA_IRQMASK | RXTX_DMA_M8 | RXTX_DMA_PRIORITY;
/* abort any DMA transfer that might be in progress */
DMAARM = ABORT | BV( MRFI_DMA_CHAN );
/* arm the dma channel for receive */
DMAARM |= BV( MRFI_DMA_CHAN );
/* send strobe to enter receive mode */
RFST = SRX;
/* clear the "receive/transmit done" interrupt flag; clear the general RF interrupt flag */
RFIF &= ~IRQ_DONE;
S1CON &= ~(RFIF_1 | RFIF_0);
/* enable "receive/transmit done" interrupts */
RFIM |= IM_DONE;
}
/**************************************************************************************************
* @fn MRFI_RfIsr
*
* @brief -
*
* @param none
*
* @return none
**************************************************************************************************
*/
BSP_ISR_FUNCTION( MRFI_RfIsr, RF_VECTOR)
{
/* clear the "receive/transmit done" interrupt flag; clear the general RF interrupt flag */
RFIF &= ~IRQ_DONE;
S1CON &= ~(RFIF_1 | RFIF_0);
/* ------------------------------------------------------------------
* Copy RX Metrics into packet structure
* ---------------------------------------
*/
{
uint8_t offsetToRxMetrics;
offsetToRxMetrics = mrfiIncomingPacket.frame[MRFI_LENGTH_FIELD_OFS] + 1;
mrfiIncomingPacket.rxMetrics[MRFI_RX_METRICS_RSSI_OFS] = mrfiIncomingPacket.frame[offsetToRxMetrics++];
mrfiIncomingPacket.rxMetrics[MRFI_RX_METRICS_CRC_LQI_OFS] = mrfiIncomingPacket.frame[offsetToRxMetrics];
}
/* ------------------------------------------------------------------
* CRC check
* ------------
*/
/* 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
* -----------
*/
/* see if filtering is enabled and, if so, determine if address is a match */
if (mrfiRxFilterEnabled && memcmp(MRFI_P_DST_ADDR(&mrfiIncomingPacket), &mrfiRxFilterAddr[0], MRFI_ADDR_SIZE))
{
/* packet filtered out - do nothing, skip to end */
}
else
{
/* packet not filtered out - receive successful */
/* ------------------------------------------------------------------
* Receive succeeded
* -------------------
*/
/* call external, higher level "receive complete" processing routine */
MRFI_RxCompleteISR();
}
}
/* arm DMA channel for next receive */
DMAARM |= BV( MRFI_DMA_CHAN );
}
/**************************************************************************************************
* @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;
RFST = SIDLE;
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 );
}
}
}
/**************************************************************************************************
* @fn MRFI_WakeUp
*
* @brief Wake up radio from sleep state.
*
* @param none
*
* @return none
**************************************************************************************************
*/
void MRFI_WakeUp(void)
{
/* verify high speed crystal oscillator is selected, required for radio operation */
MRFI_ASSERT( !(CLKCON & OSC) );
/* if radio is already awake, just ignore wakeup request */
if (!mrfiRadioIsSleeping)
{
return;
}
/* restore radio registers that are reset during sleep */
FSCAL3 = SMARTRF_SETTING_FSCAL3;
FSCAL2 = SMARTRF_SETTING_FSCAL2;
FSCAL1 = SMARTRF_SETTING_FSCAL1;
/* enable the receiver */
MRFI_RxEnable();
/* clear sleep flag and enter receive mode */
mrfiRadioIsSleeping = 0;
}
/**************************************************************************************************
* @fn MRFI_SetRxAddrFilter
*
* @brief Set the address used for filtering received packets.
*
* @param pAddr - pointer to address to use for filtering
*
* @return none
**************************************************************************************************
*/
void MRFI_SetRxAddrFilter(uint8_t * pAddr)
{
/* save a copy of the filter address */
memcpy(&mrfiRxFilterAddr[0], pAddr, MRFI_ADDR_SIZE);
}
/**************************************************************************************************
* @fn MRFI_EnableRxAddrFilter
*
* @brief Enable received packet filtering.
*
* @param none
*
* @return none
**************************************************************************************************
*/
void MRFI_EnableRxAddrFilter(void)
{
/* set flag to indicate filtering is enabled */
mrfiRxFilterEnabled = 1;
}
/**************************************************************************************************
* @fn MRFI_DisableRxAddrFilter
*
* @brief Disable received packet filtering.
*
* @param none
*
* @return none
**************************************************************************************************
*/
void MRFI_DisableRxAddrFilter(void)
{
/* clear flag that indicates filtering is enabled */
mrfiRxFilterEnabled = 0;
}
/**************************************************************************************************
* Compile Time Integrity Checks
**************************************************************************************************
*/
#if (MRFI_DMA_CHAN != 0)
#error "ERROR: Code implementation requires use of DMA channel zero."
/* Using a channel other than zero is not difficult to implement. The hardware
* requires channels 1-4 to use a common configuration structure. For this module
* to use a channel other than zero, this data structure would need to be integrated
* with the external code. Hooks are provided to make this as easy as possible.
*/
#endif
/* verify that setting for PKTLEN does not exceed maximum */
#if (MRFI_SETTING_PKTLEN > 0xFF)
#error "ERROR: Maximum possible value for PKTLEN exceeded. Decrease value of maximum payload."
#endif
/* verify that the SmartRF file supplied is compatible */
#if ((!defined SMARTRF_RADIO_CC2510) && \
(!defined SMARTRF_RADIO_CC2511) && \
(!defined SMARTRF_RADIO_CC1110) && \
(!defined SMARTRF_RADIO_CC1111))
#error "ERROR: The SmartRF export file is not compatible."
#endif
/**************************************************************************************************
*/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -