📄 mrfi_radio.c
字号:
mrfiIncomingPacket.rxMetrics[MRFI_RX_METRICS_RSSI_OFS] = RFD;
mrfiIncomingPacket.rxMetrics[MRFI_RX_METRICS_CRC_LQI_OFS] = RFD;
/* Eliminate frames that are the correct size but we can tell are bogus
* by their frame control fields.
*/
if ((p1[MRFI_FCF_OFFSET] == MRFI_FCF_0_7) &&
(p1[MRFI_FCF_OFFSET+1] == MRFI_FCF_8_15))
{
/* call external, higher level "receive complete" (CRC checking is done by hardware) */
MRFI_RxCompleteISR();
}
}
} while (RXFIFOCNT);
/* ------------------------------------------------------------------
* Clean up on exit
* --------------------
*/
/* Clear FIFOP interrupt:
* This is an edge triggered interrupt. The interrupt must be first cleared
* at the MCU before re-enabling the interrupt at the source.
*/
S1CON = 0x00; /* Clear the interrupt at MCU. */
RFIF &= ~IRQ_FIFOP; /* Clear the interrupt source flag. */
}
/**************************************************************************************************
* @fn MRFI_SetLogicalChannel
*
* @brief Set logical channel.
*
* @param chan - logical channel number
*
* @return none
**************************************************************************************************
*/
void MRFI_SetLogicalChannel(uint8_t chan)
{
uint8_t phyChannel;
MRFI_ASSERT( chan < MRFI_NUM_LOGICAL_CHANS ); /* logical channel is not valid */
/* make sure radio is off before changing channels */
Mrfi_RxModeOff();
/* convert logical channel number into physical channel number */
phyChannel = mrfiLogicalChanTable[chan];
/* write frequency value of new channel */
FSCTRLL = FREQ_2405MHZ + (5 * (phyChannel - 11));
/* turn radio back on if it was on before channel change */
if (mrfiRxOn)
{
Mrfi_RxModeOn();
}
}
/**************************************************************************************************
* @fn MRFI_WakeUp
*
* @brief Wake up radio from sleep state.
*
* @param none
*
* @return none
**************************************************************************************************
*/
void MRFI_WakeUp(void)
{
/* if radio is asleep, wake it up */
if (!mrfiRadioIsAwake)
{
/* set flag to indicate radio is awake */
mrfiRadioIsAwake = 1;
/* turn on radio power, pend for the power-up delay */
RFPWR &= ~RREG_RADIO_PD;
while((RFPWR & ADI_RADIO_PD));
}
}
/**************************************************************************************************
* @fn MRFI_Sleep
*
* @brief Request radio go to sleep.
*
* @param none
*
* @return none
**************************************************************************************************
*/
void MRFI_Sleep(void)
{
/* if radio is awake, put it to sleep */
if (mrfiRadioIsAwake)
{
/* go to idle so radio is in a know state before sleeping */
MRFI_RxIdle();
/* turn off power to the radio */
RFPWR |= RREG_RADIO_PD;
/* set flag to indicate radio is asleep */
mrfiRadioIsAwake = 0;
}
}
/**************************************************************************************************
* @fn MRFI_SetRxAddrFilter
*
* @brief Set the address used for filtering received packets.
*
* @param pAddr - pointer to address to use for filtering
*
* @return none
**************************************************************************************************
*/
uint8_t MRFI_SetRxAddrFilter(uint8_t * pAddr)
{
/*
* Determine if filter address is valid. Cannot be a reserved value.
* -Reserved PAN ID's of 0xFFFF and 0xFFFE.
* -Reserved short address of 0xFFFF.
*/
if ((((pAddr[0] == 0xFF) || (pAddr[0] == 0xFE)) && (pAddr[1] == 0xFF)) ||
(pAddr[2] == 0xFF) && ((pAddr[3] == 0xFF)))
{
/* unable to set filter address */
return( 1 );
}
/* set the hardware address registers */
PANIDL = pAddr[0];
PANIDH = pAddr[1];
SHORTADDRL = pAddr[2];
SHORTADDRH = pAddr[3];
/* successfully set filter address */
return( 0 );
}
/**************************************************************************************************
* @fn MRFI_EnableRxAddrFilter
*
* @brief Enable received packet filtering.
*
* @param none
*
* @return none
**************************************************************************************************
*/
void MRFI_EnableRxAddrFilter(void)
{
MRFI_ASSERT( (PANIDL != 0xFF) && (PANIDH != 0xFF) ); /* filter address not set */
/* enable hardware filtering on the radio */
MDMCTRL0H |= ADDR_DECODE;
}
/**************************************************************************************************
* @fn MRFI_DisableRxAddrFilter
*
* @brief Disable received packet filtering.
*
* @param none
*
* @return none
**************************************************************************************************
*/
void MRFI_DisableRxAddrFilter(void)
{
/* disable hardware filtering on the radio */
MDMCTRL0H &= ~ADDR_DECODE;
}
/**************************************************************************************************
* @fn MRFI_Rssi
*
* @brief Returns "live" RSSI value
*
* @param none
*
* @return RSSI value in units of dBm.
**************************************************************************************************
*/
int8_t MRFI_Rssi(void)
{
int8_t rssi;
MRFI_ASSERT( mrfiRxOn ); /* radio must be on to read RSSI value */
/*
* Assuming that the Radio was just turned on, we must wait for
* RSSI to be valid. For that, we need to wait for 20 symbol periods:
* - 12 symbols to go from idle to rx state
* - 8 symbols to calculate the RSSI value
*/
Mrfi_DelayUsec( 20 * IEEE_USECS_PER_SYMBOL );
/* read RSSI value from hardware */
rssi = RSSIL;
/* apply offset given in datasheet */
rssi = rssi + MRFI_BOARD_RSSI_OFFSET;
/* return RSSI value */
return( rssi );
}
/**************************************************************************************************
* @fn MRFI_RandomByte
*
* @brief Returns a random byte using a special hardware feature that generates new
* random values based on the truly random seed set earlier.
*
* @param none
*
* @return a random byte
**************************************************************************************************
*/
uint8_t MRFI_RandomByte(void)
{
/* clock the random generator to get a new random value */
ADCCON1 = (ADCCON1 & ~RCTRL_BITS) | RCTRL_CLOCK_LFSR;
/* return newly randomized value from hardware */
return(RNDH);
}
/**************************************************************************************************
* @fn MRFI_DelayMs
*
* @brief Delay the specified number of milliseconds.
*
* @param milliseconds - delay time
*
* @return none
**************************************************************************************************
*/
void MRFI_DelayMs(uint16_t milliseconds)
{
while (milliseconds)
{
Mrfi_DelayUsec( 1000 );
milliseconds--;
}
}
/**************************************************************************************************
* @fn Mrfi_RxModeOn
*
* @brief Put radio into receive mode.
*
* @param none
*
* @return none
**************************************************************************************************
*/
static void Mrfi_RxModeOn(void)
{
/* send strobe to enter receive mode */
RFST = ISRXON;
/* enable receive interrupts */
RFIM |= IM_FIFOP;
}
/**************************************************************************************************
* @fn Mrfi_RxModeOff
*
* @brief -
*
* @param none
*
* @return none
**************************************************************************************************
*/
static void Mrfi_RxModeOff(void)
{
/*disable receive interrupts */
RFIM &= ~IM_FIFOP;
/* turn off radio */
RFST = ISRFOFF;
/* flush the receive FIFO of any residual data */
RFST = ISFLUSHRX;
/* clear receive interrupt */
RFIF = ~IRQ_FIFOP;
}
/**************************************************************************************************
* @fn Mrfi_RandomBackoffDelay
*
* @brief -
*
* @param none
*
* @return none
**************************************************************************************************
*/
static void Mrfi_RandomBackoffDelay(void)
{
uint8_t backoffs;
uint8_t i;
/* calculate random value for backoffs - 1 to 16 */
backoffs = (MRFI_RandomByte() & 0x0F) + 1;
/* delay for randomly computed number of backoff periods */
for (i=0; i<backoffs; i++)
{
Mrfi_DelayUsec( MRFI_BACKOFF_PERIOD_USECS );
}
}
/****************************************************************************************************
* @fn Mrfi_DelayUsec
*
* @brief Execute a delay loop using the MAC timer. The macro actually used to do the delay
* is not reentrant. This routine makes the delay execution reentrant by breaking up
* the requested delay up into small chunks and executing each chunk as a critical
* section. The chunk size is choosen to be the smallest value used by MRFI. The delay
* is only approximate because of the overhead computations. It errs on the side of
* being too long.
*
* input parameters
* @param howLong - number of microseconds to delay
*
* @return none
****************************************************************************************************
*/
static void Mrfi_DelayUsec(uint16_t howLong)
{
bspIState_t intState;
uint16_t count = howLong/IEEE_USECS_PER_SYMBOL;
if (howLong)
{
do
{
BSP_ENTER_CRITICAL_SECTION(intState);
MRFI_DELAY_USECS(IEEE_USECS_PER_SYMBOL);
BSP_EXIT_CRITICAL_SECTION(intState);
} while (count--);
}
return;
}
/**************************************************************************************************
* Compile Time Integrity Checks
**************************************************************************************************
*/
/*
* The current implementation requires an address size of four bytes. These four bytes are
* spread across the PAN ID and the short address. A larger address size is possible by using
* long address instead of short address. The change is not difficult but it does require
* code modification.
*/
#if (MRFI_ADDR_SIZE != 4)
#error "ERROR: Address size must be four bytes. A different address size requires code modification."
#endif
/* verify that specified frame size fits within radio FIFO */
#if ((MRFI_MAX_FRAME_SIZE + MRFI_RX_METRICS_SIZE) > 127)
#error "ERROR: Maximum possible packet length exceeded. Decrease value of maximum payload."
#endif
/*
* These asserts happen if there is extraneous compiler padding of arrays.
* Modify compiler settings for no padding, or, if that is not possible,
* comment out the offending asserts.
*/
BSP_STATIC_ASSERT(sizeof(mrfiLogicalChanTable) == ((sizeof(mrfiLogicalChanTable)/sizeof(mrfiLogicalChanTable[0])) * sizeof(mrfiLogicalChanTable[0])));
BSP_STATIC_ASSERT(sizeof(mrfiBroadcastAddr) == ((sizeof(mrfiBroadcastAddr)/sizeof(mrfiBroadcastAddr[0])) * sizeof(mrfiBroadcastAddr[0])));
/**************************************************************************************************
*/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -