📄 mrfi_radio.c
字号:
LPC_SSP0->DR = SRES;
while ( LPC_SSP0->SR & SSP_SR_BSY );
while ( (LPC_SSP0->SR & (SSP_SR_BSY|SSP_SR_RNE)) != SSP_SR_RNE );
iTemp = LPC_SSP0->DR;
while ( LPC_SSP0->SR & SSP_SR_BSY );
MRFI_DELAY(80);
/* wait for SO to go low again, reset is complete at that point */
while( GPIO_ReadInput(CSPIPort) & CSPISO );
/* return CSn pin to its default high level */
GPIO_SetBits(CSPort, CSPICSN);
/* ------------------------------------------------------------------
* Run-time integrity checks
* ---------------------------
*/
/* verify that SPI is working, PKTLEN is an arbitrary read/write register used for testing */
#ifdef MRFI_ASSERTS_ARE_ON
#define TEST_VALUE 0xA5
mrfiSpiWriteReg( PKTLEN, TEST_VALUE );
//i=0;
//while(1)
{
iTemp = mrfiSpiReadReg( PKTLEN );
if( iTemp != TEST_VALUE )
{
while(1);
}
// else
{
//break;//i++;
}
}
//MRFI_ASSERT( mrfiSpiReadReg( MRFI_CC2500_SPI_REG_PKTLEN ) == TEST_VALUE ); /* SPI is not responding */
#endif
/* verify the correct radio is installed */
//MRFI_ASSERT( mrfiSpiReadReg( PARTNUM ) == MRFI_RADIO_PARTNUM ); /* incorrect radio specified */
//MRFI_ASSERT( mrfiSpiReadReg( VERSION ) >= MRFI_RADIO_MIN_VERSION ); /* obsolete radio specified */
if(mrfiSpiReadReg( PARTNUM ) != MRFI_RADIO_PARTNUM)
{
while(1);
}
if(mrfiSpiReadReg( VERSION ) != MRFI_RADIO_MIN_VERSION)
{
while(1);
}
/* ------------------------------------------------------------------
* Configure radio
* -----------------
*/
/* initialize radio registers */
{
// uint8_t i;
//for (i=0; i<(sizeof(mrfiRadioCfg)/sizeof(mrfiRadioCfg[0])); i++)
{
//mrfiSpiWriteReg(mrfiRadioCfg[i][0], mrfiRadioCfg[i][1]);
}
}
writeRFSettings();
mrfiSpiWriteReg( PA_TABLE0, 0xFB );
/* Put the radio in RX state */
mrfiSpiCmdStrobe( SRX );
MRFI_CONFIG_SYNC_PIN_RISING_EDGE_INT();
MRFI_CLEAR_SYNC_PIN_INT_FLAG();
//NVIC_EnableIRQ(EINT3_IRQn);
//used for test
return;
/* Initial radio state is IDLE state */
mrfiRadioState = MRFI_RADIO_STATE_IDLE;
/* set default channel */
MRFI_SetLogicalChannel( 0 );
/* set default power */
MRFI_SetRFPwr(MRFI_NUM_POWER_SETTINGS - 1);
/* Generate Random seed:
* We will use the RSSI value to generate our random seed.
*/
/* Put the radio in RX state */
mrfiSpiCmdStrobe( SRX );
/* delay for the rssi to be valid */
MRFI_RSSI_VALID_WAIT();
/* use most random bit of rssi to populate the random seed */
{
uint8_t i;
for(i=0; i<16; i++)
{
mrfiRndSeed = (mrfiRndSeed << 1) | (mrfiSpiReadReg(RSSI) & 0x01);
}
}
/* Force the seed to be non-zero by setting one bit, just in case... */
mrfiRndSeed |= 0x0080;
/* Turn off RF. */
Mrfi_RxModeOff();
/*****************************************************************************************
* Compute reply delay scalar
*
* Formula from data sheet for all the narrow band radios is:
*
* (256 + DATAR_Mantissa) * 2^(DATAR_Exponent)
* DATA_RATE = ------------------------------------------ * f(xosc)
* 2^28
*
* To try and keep some accuracy we change the exponent of the denominator
* to (28 - (exponent from the configuration register)) so we do a division
* by a smaller number. We find the power of 2 by shifting.
*
* The maximum delay needed depends on the MAX_APP_PAYLOAD parameter. Figure
* out how many bits that will be when overhead is included. Bits/bits-per-second
* is seconds to transmit (or receive) the maximum frame. We multiply this number
* by 1000 to find the time in milliseconds. We then additionally multiply by
* 10 so we can add 5 and divide by 10 later, thus rounding up to the number of
* milliseconds. This last won't matter for slow transmissions but for faster ones
* we want to err on the side of being conservative and making sure the radio is on
* to receive the reply. The semaphore monitor will shut it down. The delay adds in
* a platform fudge factor that includes processing time on peer plus lags in Rx and
* processing time on receiver's side. Also includes round trip delays from CCA
* retries. This portion is included in PLATFORM_FACTOR_CONSTANT defined in mrfi.h.
*
* Note that we assume a 26 MHz clock for the radio...
* ***************************************************************************************
*/
#define MRFI_RADIO_OSC_FREQ 26000000
#define PHY_PREAMBLE_SYNC_BYTES 8
{
uint32_t dataRate, bits;
uint16_t exponent, mantissa;
/* mantissa is in MDMCFG3 */
mantissa = 256 + SMARTRF_SETTING_MDMCFG3;
/* exponent is lower nibble of MDMCFG4. */
exponent = 28 - (SMARTRF_SETTING_MDMCFG4 & 0x0F);
/* we can now get data rate */
dataRate = mantissa * (MRFI_RADIO_OSC_FREQ>>exponent);
bits = ((uint32_t)((PHY_PREAMBLE_SYNC_BYTES + MRFI_MAX_FRAME_SIZE)*8))*10000;
/* processing on the peer + the Tx/Rx time plus more */
sReplyDelayScalar = PLATFORM_FACTOR_CONSTANT + (((bits/dataRate)+5)/10);
/* This helper value is used to scale the backoffs during CCA. At very
* low data rates we need to backoff longer to prevent continual sampling
* of valid frames which take longer to send at lower rates. Use the scalar
* we just calculated divided by 32. With the backoff algorithm backing
* off up to 16 periods this will result in waiting up to about 1/2 the total
* scalar value. For high data rates this does not contribute at all. Value
* is in microseconds.
*/
sBackoffHelper = MRFI_BACKOFF_PERIOD_USECS + (sReplyDelayScalar>>5)*1000;
}
/* Clean out buffer to protect against spurious frames */
memset(mrfiIncomingPacket.frame, 0x00, sizeof(mrfiIncomingPacket.frame));
memset(mrfiIncomingPacket.rxMetrics, 0x00, sizeof(mrfiIncomingPacket.rxMetrics));
/* ------------------------------------------------------------------
* Configure interrupts
* ----------------------
*/
/*
* Configure and enable the SYNC signal interrupt.
*
* This interrupt is used to indicate receive. The SYNC signal goes
* high when a receive OR a transmit begins. It goes high once the
* sync word is received or transmitted and then goes low again once
* the packet completes.
*/
// MRFI_CONFIG_SYNC_PIN_EDGE_INT();/*0 edge int. 1 pin int */
// LPC_GPIO0->IBE |= CGDO0; // &= ~(CGDO0);/*0: IEV control, 1 double edge int */
// //MRFI_CONFIG_SYNC_PIN_RISING_EDGE_INT();
//
// //MRFI_CONFIG_SYNC_PIN_FALLING_EDGE_INT();
// MRFI_ENABLE_SYNC_PIN_INT();
// MRFI_CLEAR_SYNC_PIN_INT_FLAG();
LPC_SYSCON->SYSAHBCLKCTRL |= (1<<6);
GPIO_SetDir(CGDOPort, CGDO0|CGDO2, 0);
Event_InitStruct.EVENT_Mode = EVENT_FALLING_EDGE;//EVENT_RISING_EDGE;
Event_InitStruct.pins = (CGDO0|CGDO2);
Event_InitStruct.port = CGDOPort;
Event_InitStruct.INTCmd = ENABLE;
//INIT initial is needed
GPIO_EventInit(&Event_InitStruct);
GPIO_PortIntCmd(CGDOPort, ENABLE);
/* enable global interrupts */
//NVIC_EnableIRQ(EINT0_IRQn|EINT1_IRQn|EINT2_IRQn|EINT3_IRQn);
}
/**************************************************************************************************
* @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_TX_RESULT_SUCCESS - transmit succeeded
* MRFI_TX_RESULT_FAILED - transmit failed because CCA failed
**************************************************************************************************
*/
uint8_t MRFI_Transmit(mrfiPacket_t * pPacket, uint8_t txType)
{
uint8_t ccaRetries;
uint8_t txBufLen;
uint8_t returnValue = MRFI_TX_RESULT_SUCCESS;
// uint32_t i=0,j=0;
/* radio must be awake to transmit */
MRFI_ASSERT( mrfiRadioState != MRFI_RADIO_STATE_OFF );
/* Turn off reciever. We can ignore/drop incoming packets during transmit. */
Mrfi_RxModeOff();
/* 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);
/* ------------------------------------------------------------------
* Immediate transmit
* ---------------------
*/
if (txType == MRFI_TX_TYPE_FORCED)
{
/* Issue the TX strobe. */
mrfiSpiCmdStrobe( STX );
/* Wait for transmit to complete */
while(!MRFI_SYNC_PIN_INT_FLAG_IS_SET());
/* Clear the interrupt flag */
MRFI_CLEAR_SYNC_PIN_INT_FLAG();
}
else
{
/* ------------------------------------------------------------------
* CCA transmit
* ---------------
*/
MRFI_ASSERT( txType == MRFI_TX_TYPE_CCA );
/* set number of CCA retries */
ccaRetries = MRFI_CCA_RETRIES;
/* For CCA algorithm, we need to know the transition from the RX state to
* the TX state. There is no need for SYNC signal in this logic. So we
* can re-configure the GDO_0 output from the radio to be PA_PD signal
* instead of the SYNC signal.
* Since both SYNC and PA_PD are used as falling edge interrupts, we
* don't need to reconfigure the MCU input.
*/
MRFI_CONFIG_GDO0_AS_PAPD_SIGNAL();
/* ===============================================================================
* Main Loop
* =============
*/
for (;;)
{
/* Radio must be in RX mode for CCA to happen.
* Otherwise it will transmit without CCA happening.
*/
/* Can not use the Mrfi_RxModeOn() function here since it turns on the
* Rx interrupt, which we don't want in this case.
*/
mrfiSpiCmdStrobe( SRX );
/* wait for the rssi to be valid. */
MRFI_RSSI_VALID_WAIT();
/*
* 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_SYNC_PIN_INT_FLAG();
u8GDO0Flag = 0;
/* send strobe to initiate transmit */
//mrfiSpiCmdStrobe( STX );
// returnValue = MRFI_PAPD_PIN_IS_HIGH();
mrfiSpiCmdStrobe( STX );
while(!GPIO_ReadInputPin(CGDOPort, CGDO0));
//while(GPIO_ReadInputPin(CGDOPort, CGDO0));
break;
/* Delay long enough for the PA_PD signal to indicate a
* successful transmit. This is the 250 XOSC periods
* (9.6 us for a 26 MHz crystal) See section 19.6 of 2500 datasheet.
* Found out that we need a delay of atleast 20 us on CC2500 and
* 25 us on CC1100 to see the PA_PD signal change.
*/
//Mrfi_DelayUsec(25);
//Mrfi_DelayUsec(20);
//while(txBufLen = GPIO_ReadInputPin(CGDOPort, CGDO0));
/* PA_PD signal goes from HIGH to LOW when going from RX state.
* This transition is trapped as a falling edge interrupt flag
* to indicate that CCA passed and the transmit has started.
*/
//if(!MRFI_PAPD_PIN_IS_HIGH())
//if(!GPIO_ReadInputPin(CGDOPort, CGDO0))
//if(!txBufLen)
if(u8GDO0Flag == 1)
{
/* ------------------------------------------------------------------
* Clear Channel Assessment passed.
* ---------------------------------- */
/* Clear the PA_PD int flag */
//MRFI_CLEAR_PAPD_PIN_INT_FLAG();
u8GDO0Flag = 0;
/* PA_PD signal stays LOW while in TX state and goes back to HIGH when
* the radio transitions to RX state.
*/
/* wait for transmit to complete */
/* if(!MRFI_PAPD_PIN_IS_HIGH())
{
while (!MRFI_PAPD_PIN_IS_HIGH());
}*/
/*if(!MRFI_SYNC_PIN_IS_HIGH())
{
while (!MRFI_SYNC_PIN_IS_HIGH());
}*/
if(!GPIO_ReadInputPin(CGDOPort, CGDO0))
{
while(!GPIO_ReadInputPin(CGDOPort, CGDO0));
}
/* transmit done, break */
break;
}
// else
// {
// /* ------------------------------------------------------------------
// * Clear Channel Assessment failed.
// * ----------------------------------
// */
//
// /* Turn off radio and save some power during backoff */
//
// /* NOTE: Can't use Mrfi_RxModeOff() - since it tries to update the
// * sync signal status which we are not using during the TX operation.
// */
// MRFI_STROBE_IDLE_AND_WAIT();
//
// /* flush the receive FIFO of any residual data */
// mrfiSpiCmdStrobe( SFRX );
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -