📄 mrfi_radio.c
字号:
/**************************************************************************************************
Revised: $Date: 2007-07-06 11:19:00 -0700 (Fri, 06 Jul 2007) $
Revision: $Revision: 13579 $
Copyright 2007 Texas Instruments Incorporated. All rights reserved.
IMPORTANT: Your use of this Software is limited to those specific rights granted under
the terms of a software license agreement between the user who downloaded the software,
his/her employer (which must be your employer) and Texas Instruments Incorporated (the
"License"). You may not use this Software unless you agree to abide by the terms of the
License. The License limits your use, and you acknowledge, that the Software may not be
modified, copied or distributed unless embedded on a Texas Instruments microcontroller
or used solely and exclusively in conjunction with a Texas Instruments radio frequency
transceiver, which is integrated into your product. Other than for the foregoing purpose,
you may not use, reproduce, copy, prepare derivative works of, modify, distribute,
perform, display or sell this Software and/or its documentation for any purpose.
YOU FURTHER ACKNOWLEDGE AND AGREE THAT THE SOFTWARE AND DOCUMENTATION ARE PROVIDED 揂S IS? WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION, ANY
WARRANTY OF MERCHANTABILITY, TITLE, NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE.
IN NO EVENT SHALL TEXAS INSTRUMENTS OR ITS LICENSORS BE LIABLE OR OBLIGATED UNDER CONTRACT,
NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION, BREACH OF WARRANTY, OR OTHER LEGAL EQUITABLE
THEORY ANY DIRECT OR INDIRECT DAMAGES OR EXPENSES INCLUDING BUT NOT LIMITED TO ANY
INCIDENTAL, SPECIAL, INDIRECT, PUNITIVE OR CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST
DATA, COST OF PROCUREMENT OF SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY CLAIMS BY
THIRD PARTIES (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), OR OTHER SIMILAR COSTS.
Should you have any questions regarding your right to use this Software,
contact Texas Instruments Incorporated at www.TI.com.
**************************************************************************************************/
/* ~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=
* MRFI (Minimal RF Interface)
* Radios: CC2430
* Primary code file for supported radios.
* ~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=
*/
/* ------------------------------------------------------------------------------------------------
* Includes
* ------------------------------------------------------------------------------------------------
*/
#include <string.h>
#include "mrfi.h"
#include "bsp.h"
#include "bsp_macros.h"
//#include "bsp_external/mrfi_board_defs.h"
#include MCU_H
/* ------------------------------------------------------------------------------------------------
* Defines
* ------------------------------------------------------------------------------------------------
*/
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
* Values imported from mrfi_defs.h
* - - - - - - - - - - - - - - - - - -
*/
#define MRFI_LENGTH_FIELD_OFFSET __mrfi_LENGTH_FIELD_OFS__
#define MRFI_LENGTH_FIELD_SIZE __mrfi_LENGTH_FIELD_SIZE__
#define MRFI_HEADER_SIZE __mrfi_HEADER_SIZE__
#define MRFI_DSN_OFFSET __mrfi_DSN_OFS__
#define MRFI_FCF_OFFSET __mrfi_FCF_OFS__
#define MRFI_BACKOFF_PERIOD_USECS __mrfi_BACKOFF_PERIOD_USECS__
#define MRFI_FCF_0_7 (0x01)
#define MRFI_FCF_8_15 (0x88)
#define MRFI_MIN_SMPL_FRAME_SIZE (MRFI_HEADER_SIZE + 3)
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
* Radio Definitions
* - - - - - - - - - -
*/
/* immediate strobe processor command instructions */
#define ISTXCALN 0xE1
#define ISRXON 0xE2
#define ISTXON 0xE3
#define ISTXONCCA 0xE4
#define ISRFOFF 0xE5
#define ISFLUSHRX 0xE6
#define ISFLUSHTX 0xE7
#define ISACK 0xE8
#define ISACKPEND 0xE9
#define MRFI_RADIO_PARTNUM 0x85
#define MRFI_RADIO_MIN_VERSION 3 /* minimum version is Rev D */
/* rx metrics definitions, known as appended "packet status bytes" in datasheet parlance */
#define MRFI_RX_METRICS_RSSI_OFS 0
#define MRFI_RX_METRICS_CRC_LQI_OFS 1
#define MRFI_RX_METRICS_CRC_OK_MASK 0x80
#define MRFI_RX_METRICS_LQI_MASK 0x7F
/* FSCTRLL */
#define FREQ_2405MHZ 0x65
/* MDMCTRL0H */
#define ADDR_DECODE BV(3)
/* RFSTATUS */
#define TX_ACTIVE BV(4)
#define FIFO BV(3)
#define FIFOP BV(2)
#define SFD BV(1)
#define CCA BV(0)
/* RFIF */
#define IRQ_TXDONE BV(6)
/* RFIM */
#define IM_TXDONE BV(6)
/* IEN2 */
#define RFIE BV(0)
/* SLEEP */
#define XOSC_STB BV(6)
#define OSC_PD BV(2)
/* CLKCON */
#define OSC32K BV(7)
#define OSC BV(6)
/* RFPWR */
#define ADI_RADIO_PD BV(4)
#define RREG_RADIO_PD BV(3)
/* RFIF */
#define IRQ_TXDONE BV(6)
#define IRQ_FIFOP BV(5)
#define IRQ_SFD BV(4)
/* RFIM */
#define IM_TXDONE BV(6)
#define IM_FIFOP BV(5)
#define IM_SFD BV(4)
/* MDMCTRL1L */
#define MDMCTRL1L_RESET_VALUE 0x00
#define RX_MODE(x) ((x) << 0)
#define RX_MODE_INFINITE_RECEPTION RX_MODE(2)
#define RX_MODE_NORMAL_OPERATION RX_MODE(0)
/* FSMSTATE */
#define FSM_FFCTRL_STATE_RX_INF 31 /* infinite reception state - not documented in datasheet */
/* T2CNF */
#define CMPIF BV(7)
#define PERIF BV(6)
#define OFCMPIF BV(5)
#define SYNC BV(1)
#define RUN BV(0)
#define T2CNF_IF_BITS (CMPIF | PERIF | OFCMPIF)
/* ADCCON1 */
#define RCTRL1 BV(3)
#define RCTRL0 BV(2)
#define RCTRL_BITS (RCTRL1 | RCTRL0)
#define RCTRL_CLOCK_LFSR RCTRL0
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
* IEEE 802.15.4 definitions
* - - - - - - - - - - - - - - -
*/
#define IEEE_PHY_PACKET_SIZE_MASK 0x7F
#define IEEE_USECS_PER_SYMBOL 16
// -------------------------------------------------------------------
// TBD these need to move to board def file
/* 32 kHz clock source select in CLKCON */
#if !defined (OSC32K_CRYSTAL_INSTALLED) || (defined (OSC32K_CRYSTAL_INSTALLED) && (OSC32K_CRYSTAL_INSTALLED == TRUE))
#define OSC_32KHZ 0x00 /* external 32 KHz xosc */
#else
#define OSC_32KHZ 0x80 /* internal 32 KHz rcosc */
#endif
/* ------------------------------------------------------------------------------------------------
* Macros
* ------------------------------------------------------------------------------------------------
*/
/*
* Microsecond delay macro. This macro delays the specified number of microseconds.
*
* - The MRFI_ASSERT protects against a delay value that is too large.
* - Setting T2CNF=0 stops the timer and clears any pending timer interrupts, sync mode is also turned off.
* - Timer count cleared to zero with T2TLD=0, T2THD=0.
* - Delay time is written to rollover count T2CAPLPL, T2CAPHPH.
* - Timer started with T2CNF=RUN.
* - While loop pends until rollover interrupt flag is set.
* - Timer stopped, T2CNF=0, as last step to conserve power.
*/
#define MRFI_DELAY_USECS(x) st( MRFI_ASSERT((( ((uint32_t)(BSP_CLOCK_MHZ)) * ((uint32_t)(x)) ) >> 16) == 0); \
T2CNF = 0; \
T2TLD = 0; \
T2THD = 0; \
T2CAPLPL = (((uint16_t)(x)) * ((uint16_t)(BSP_CLOCK_MHZ))) & 0xFF; \
T2CAPHPH = (((uint16_t)(x)) * ((uint16_t)(BSP_CLOCK_MHZ))) >> 8; \
T2CNF = RUN; \
while(!(T2CNF & PERIF)); \
T2CNF = 0; )
/* ------------------------------------------------------------------------------------------------
* Global Constants
* ------------------------------------------------------------------------------------------------
*/
const uint8_t mrfiBroadcastAddr[] = { 0xFF, 0xFF, 0xFF, 0xFF };
/*
* Verify number of table entries matches the corresponding #define.
* If this assert is hit, most likely the number of initializers in the
* above array must be adjusted.
*/
BSP_STATIC_ASSERT(MRFI_ADDR_SIZE == ((sizeof(mrfiBroadcastAddr)/sizeof(mrfiBroadcastAddr[0])) * sizeof(mrfiBroadcastAddr[0])));
/* ------------------------------------------------------------------------------------------------
* Local Prototypes
* ------------------------------------------------------------------------------------------------
*/
static void Mrfi_RxModeOn(void);
static void Mrfi_RxModeOff(void);
static void Mrfi_RandomBackoffDelay(void);
static void Mrfi_DelayUsec(uint16_t);
/* ------------------------------------------------------------------------------------------------
* Local Constants
* ------------------------------------------------------------------------------------------------
*/
/*
* Logical channel table - this table translates logical channel into
* actual radio channel number. Channel 0, the default channel, is
* determined by the channel exported from SmartRF Studio. The other
* table entries are derived from that default. Each derived channel is
* masked with 0xFF to prevent generation of an illegal channel number.
*
* This table is easily customized. Just replace or add entries as needed.
* If the number of entries changes, the corresponding #define must also
* be adjusted. It is located in mrfi_defs.h and is called __mrfi_NUM_LOGICAL_CHANS__.
* The static assert below ensures that there is no mismatch.
*/
static const uint8_t mrfiLogicalChanTable[] =
{
15,
20,
25,
26
};
/* verify number of table entries matches the corresponding #define */
BSP_STATIC_ASSERT(__mrfi_NUM_LOGICAL_CHANS__ == ((sizeof(mrfiLogicalChanTable)/sizeof(mrfiLogicalChanTable[0])) * sizeof(mrfiLogicalChanTable[0])));
/* ------------------------------------------------------------------------------------------------
* Local Variables
* ------------------------------------------------------------------------------------------------
*/
static uint8_t mrfiRxOn;
static mrfiPacket_t mrfiIncomingPacket;
static uint8_t mrfiRadioIsAwake;
/**************************************************************************************************
* @fn MRFI_Init
*
* @brief Initialize MRFI.
*
* @param none
*
* @return none
**************************************************************************************************
*/
void MRFI_Init(void)
{
/* ------------------------------------------------------------------
* Run-time integrity checks
* ---------------------------
*/
/* verify the correct radio is installed */
MRFI_ASSERT( CHIPID == MRFI_RADIO_PARTNUM ); /* wrong radio */
MRFI_ASSERT( CHVER >= MRFI_RADIO_MIN_VERSION ); /* obsolete radio version */
/* ------------------------------------------------------------------
* Configure clock to use XOSC
* -----------------------------
*/
SLEEP &= ~OSC_PD; /* turn on 16MHz RC and 32MHz XOSC */
while (!(SLEEP & XOSC_STB)); /* wait for 32MHz XOSC stable */
asm("NOP"); /* chip bug workaround */
{
uint16_t i;
/* Require 63us delay for all revs */
for (i=0; i<504; i++)
{
asm("NOP");
}
}
CLKCON = (0x00 | OSC_32KHZ); /* 32MHz XOSC */
while (CLKCON != (0x00 | OSC_32KHZ));
SLEEP |= OSC_PD; /* turn off 16MHz RC */
/* ------------------------------------------------------------------
* Variable Initialization
* -------------------------
*/
mrfiRxOn = 0;
mrfiRadioIsAwake = 0;
#ifdef MRFI_ASSERTS_ARE_ON
PANIDL = 0xFF;
PANIDH = 0xFF;
#endif
/* ------------------------------------------------------------------
* Initialize Random Seed Value
* -------------------------------
*/
/* turn on radio power, pend for the power-up delay */
RFPWR &= ~RREG_RADIO_PD;
while((RFPWR & ADI_RADIO_PD));
/*
* Set radio for infinite reception. Once radio reaches this state,
* it will stay in receive mode regardless RF activity.
*/
MDMCTRL1L = MDMCTRL1L_RESET_VALUE | RX_MODE_INFINITE_RECEPTION;
/* turn on the receiver */
RFST = ISRXON;
/*
* Wait for radio to reach infinite reception state. Once it does,
* The least significant bit of ADTSTH should be pretty random.
*/
while (FSMSTATE != FSM_FFCTRL_STATE_RX_INF)
/* put 16 random bits into the seed value */
{
uint16_t rndSeed;
uint8_t i;
rndSeed = 0;
for(i=0; i<16; i++)
{
/* use most random bit of analog to digital receive conversion to populate the random seed */
rndSeed = (rndSeed << 1) | (ADCTSTH & 0x01);
}
/*
* The seed value must not be zero. If it is, the pseudo random sequence will be always be zero.
* There is an extremely small chance this seed could randomly be zero (more likely some type of
* hardware problem would cause this). To solve this, a single bit is forced to be one. This
* slightly reduces the randomness but guarantees a good seed value.
*/
rndSeed |= 0x0080;
/*
* Two writes to RNDL will set the random seed. A write to RNDL copies current contents
* of RNDL to RNDH before writing new the value to RNDL.
*/
RNDL = rndSeed & 0xFF;
RNDL = rndSeed >> 8;
}
/* turn off the receiver, flush RX FIFO just in case something got in there */
RFST = ISRFOFF;
RFST = ISFLUSHRX;
/* take receiver out of infinite reception mode; set back to normal operation */
MDMCTRL1L = MDMCTRL1L_RESET_VALUE | RX_MODE_NORMAL_OPERATION;
/* turn radio back off */
RFPWR |= RREG_RADIO_PD;
/* ------------------------------------------------------------------
* Configure Radio Registers
* ---------------------------
*/
/* tuning adjustments for optimal radio performance; details available in datasheet */
RXCTRL0H = 0x32;
RXCTRL0L = 0xF5;
/* disable address filtering */
MDMCTRL0H &= ~ADDR_DECODE;
/* set FIFOP threshold to maximum */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -