mirror of
https://github.com/oliverschmidt/contiki.git
synced 2024-12-23 16:29:34 +00:00
1792 lines
64 KiB
C
1792 lines
64 KiB
C
/**
|
|
* Copyright (c) 2014, Analog Devices, Inc. All rights reserved.
|
|
*
|
|
* Redistribution and use in source and binary forms, with or without
|
|
* modification, are permitted (subject to the limitations in the
|
|
* disclaimer below) provided that the following conditions are met:
|
|
*
|
|
* - Redistributions of source code must retain the above copyright
|
|
* notice, this list of conditions and the following disclaimer.
|
|
*
|
|
* - Redistributions in binary form must reproduce the above copyright
|
|
* notice, this list of conditions and the following disclaimer in the
|
|
* documentation and/or other materials provided with the
|
|
* distribution.
|
|
*
|
|
* - Neither the name of Analog Devices, Inc. nor the names of its
|
|
* contributors may be used to endorse or promote products derived
|
|
* from this software without specific prior written permission.
|
|
*
|
|
* NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE
|
|
* GRANTED BY THIS LICENSE. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT
|
|
* HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED
|
|
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
|
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
|
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
|
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
|
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
|
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
|
|
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
|
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
|
|
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
|
|
* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
*/
|
|
/**
|
|
@file radioeng.c
|
|
@brief Radio Interface Engine Functions
|
|
@version v1.0
|
|
@author PAD CSE group, Analog Devices Inc
|
|
@date May 08th 2013
|
|
**/
|
|
|
|
#include "aducrf101-include.h"
|
|
|
|
// 1.0 of the Engine
|
|
#define RIE_ENGINE_MAJOR_VERSION 1UL
|
|
#define RIE_ENGINE_MINOR_VERSION 0UL
|
|
|
|
|
|
#define RADIO_SPI_CLK_FREQ 4000000 // 4 MHz SPI CLK for radio interface
|
|
#define SYSTEM_UCLK 16000000 // 16 MHz UCLK
|
|
// Default Radio Parameters
|
|
#define DEFAULT_CHNL_FREQ 915000000
|
|
#define FREQ_CNVRT_VAL 0.00252061538
|
|
// Defines for radio memory mapped areas
|
|
#define PACKETRAM_START 0x10
|
|
#define PACKETRAM_LEN 240
|
|
#define BBRAM_START 0x100
|
|
#define PR_var_tx_mode_ADR 0x00D
|
|
|
|
// PrF Table 35
|
|
#define PARAM_TX_NORMAL_PACKET 0
|
|
#define PARAM_TX_PREAMBLE_FOREVER 2
|
|
#define PARAM_TX_CARRIER_FOREVER 3
|
|
|
|
#define gpio_configure_sport_mode_0 0xA0
|
|
#define gpio_configure_default 0x00
|
|
#define MCR_pa_level_mcr_Adr 0x307
|
|
#define MCR_rssi_readback_Adr 0x312
|
|
#define MCR_gpio_configure_Adr 0x3fa
|
|
#define MCR_ext_uc_clk_divide_Adr 0x32e
|
|
#define MCR_interrupt_source_0_Adr 0x336
|
|
#define MCR_interrupt_source_1_Adr 0x337
|
|
|
|
// Macros for manual GPIO checking of Radio MISO pin P2.0 (SPI0)
|
|
#define RADIO_MISO_IN GP2IN_IN0_BBA
|
|
// Macros for manual GPIO control of P2.3 (Radio SPI CS) (SPI0)
|
|
#define RADIO_CSN_DEASSERT (pADI_GP2->GPSET = GP2SET_SET3)
|
|
#define RADIO_CSN_ASSERT (pADI_GP2->GPCLR = GP2CLR_CLR3)
|
|
// Macros for Sending\Receiving single bytes via SPI
|
|
#define SEND_SPI(x) pADI_SPI0->SPITX = x
|
|
#define WAIT_SPI_RX while((pADI_SPI0->SPISTA & SPISTA_RXFSTA_MSK) == 0x0);
|
|
#define READ_SPI pADI_SPI0->SPIRX
|
|
|
|
// Bit Manipulation Macros
|
|
#define MSKSET_VAL(byte,numbits,offset,value) ((byte & ~(((0x1 << numbits)-1) << offset)) | value)
|
|
|
|
|
|
|
|
/*************************************************************************/
|
|
/* Local Types */
|
|
/*************************************************************************/
|
|
/*************************************************************************/
|
|
/* Radio Command Codes */
|
|
/*************************************************************************/
|
|
typedef enum
|
|
{
|
|
CMD_SYNC = 0xA2, // Synchronizatio
|
|
CMD_PHY_OFF = 0xB0, // Transition to state PHY_OFF
|
|
CMD_PHY_ON = 0xB1, // transition to state PHY_ON
|
|
CMD_PHY_RX = 0xB2, // transition to state PHY_RX
|
|
CMD_PHY_TX = 0xB5, // transition to state PHY_TX
|
|
CMD_PHY_SLEEP = 0xBA, // transition to state PHY_SLEEP
|
|
CMD_CONFIG_DEV = 0xBB, // Apply Radio Configuration
|
|
CMD_GET_RSSI = 0xBC, // Performs an RSSI measurement
|
|
CMD_HW_RESET = 0xC8, // Power Down radio
|
|
SPI_MEM_WR = 0x18, // Sequential SPI Write
|
|
SPI_MEM_RD = 0x38, // Sequential SPI Read
|
|
SPI_NOP = 0xFF // No operation
|
|
} Radio_CmdCodes;
|
|
/*************************************************************************/
|
|
/* Firmware States */
|
|
/*************************************************************************/
|
|
typedef enum
|
|
{
|
|
FW_INIT = 0x0F, // Radio Starting Up
|
|
FW_BUSY = 0x00, // Radio not completed current operation
|
|
FW_RSSI = 0x05, // Performing CMD_GET_RSSI
|
|
FW_OFF = 0x11, // Radio is OFF
|
|
FW_ON = 0x12, // Radio is ON
|
|
FW_RX = 0x13, // Radio is in receive mode
|
|
FW_TX = 0x14, // Radio is in transmit mode
|
|
|
|
} RadioState;
|
|
/*************************************************************************/
|
|
/* Status Byte Masks */
|
|
/*************************************************************************/
|
|
#define STATUS_BYTE_FW_STATE (0x1F << 0)
|
|
#define STATUS_BYTE_CMD_READY (0x1 << 5)
|
|
#define STATUS_BYTE_IRQ_STATUS (0x1 << 6)
|
|
#define STATUS_BYTE_SPI_READY (0x1 << 7)
|
|
/*************************************************************************/
|
|
/* SPI Memory Access Defs */
|
|
/*************************************************************************/
|
|
#define SPI_MEMCMD_BYTE0_ADR_MSK (0x3 << 0)
|
|
#define SPI_MEMCMD_BYTE0_CMD_BITOFFSET 3
|
|
#define SPI_MEMCMD_BYTE0_CMD_MSK (0x1F << SPI_MEMCMD_BYTE0_CMD_BITOFFSET)
|
|
/*************************************************************************/
|
|
/* Radio Configuration Structure */
|
|
/*************************************************************************/
|
|
/**
|
|
\internal Hide from Doxegen
|
|
\var TyRadioConfiguration
|
|
**/
|
|
typedef struct
|
|
{
|
|
RIE_U8 interrupt_mask_0_r; // 0x100
|
|
RIE_U8 cfg_101_r; // 0x101
|
|
RIE_U8 cfg_102_r; // 0x102
|
|
RIE_U8 cfg_103_r; // 0x103
|
|
RIE_U8 cfg_104_r; // 0x104
|
|
RIE_U8 cfg_105_r; // 0x105
|
|
RIE_U8 cfg_106_r; // 0x106
|
|
RIE_U8 cfg_107_r; // 0x107
|
|
RIE_U8 cfg_108_r; // 0x108
|
|
RIE_U8 channel_freq_0_r; // 0x109
|
|
RIE_U8 channel_freq_1_r; // 0x10A
|
|
RIE_U8 channel_freq_2_r; // 0x10B
|
|
RIE_U8 cfg_10C_r; // 0x10C
|
|
RIE_U8 cfg_10D_r; // 0x10D
|
|
RIE_U8 cfg_10E_r; // 0x10E
|
|
RIE_U8 cfg_10F_r; // 0x10F
|
|
RIE_U8 cfg_110_r; // 0x110
|
|
RIE_U8 cfg_111_r; // 0x111
|
|
RIE_U8 cfg_112_r; // 0x112
|
|
RIE_U8 cfg_113_r; // 0x113
|
|
RIE_U8 radio_cfg_8_r; // 0x114
|
|
RIE_U8 radio_cfg_9_r; // 0x115
|
|
RIE_U8 cfg_116_r; // 0x116
|
|
RIE_U8 cfg_117_r; // 0x117
|
|
RIE_U8 image_reject_cal_phase_r; // 0x118
|
|
RIE_U8 image_reject_cal_amplitude_r; // 0x119
|
|
RIE_U8 cfg_11A_r; // 0x11A
|
|
RIE_U8 cfg_11B_r; // 0x11B
|
|
RIE_U8 symbol_mode_r; // 0x11C
|
|
RIE_U8 cfg_11D_r; // 0x11D
|
|
RIE_U8 cfg_11E_r; // 0x11E
|
|
RIE_U8 cfg_11F_r; // 0x11F
|
|
RIE_U8 cfg_120_r; // 0x120
|
|
RIE_U8 cfg_121_r; // 0x121
|
|
RIE_U8 cfg_122_r; // 0x122
|
|
RIE_U8 cfg_123_r; // 0x123
|
|
RIE_U8 tx_base_adr_r; // 0x124
|
|
RIE_U8 rx_base_adr_r; // 0x125
|
|
RIE_U8 packet_length_control_r; // 0x126
|
|
RIE_U8 packet_length_max_r; // 0x127
|
|
RIE_U8 cfg_128_r; // 0x128
|
|
RIE_U8 cfg_129_r; // 0x129
|
|
RIE_U8 cfg_12A_r; // 0x12A
|
|
RIE_U8 cfg_12B_r; // 0x12B
|
|
RIE_U8 cfg_12C_r; // 0x12C
|
|
RIE_U8 cfg_12D_r; // 0x12D
|
|
RIE_U8 cfg_12E_r; // 0x12E
|
|
RIE_U8 cfg_12F_r; // 0x12F
|
|
RIE_U8 cfg_130_r; // 0x130
|
|
RIE_U8 cfg_131_r; // 0x131
|
|
RIE_U8 cfg_132_r; // 0x132
|
|
RIE_U8 cfg_133_r; // 0x133
|
|
RIE_U8 cfg_134_r; // 0x134
|
|
RIE_U8 cfg_135_r; // 0x135
|
|
RIE_U8 cfg_136_r; // 0x136
|
|
RIE_U8 cfg_137_r; // 0x137
|
|
RIE_U8 cfg_138_r; // 0x138
|
|
RIE_U8 cfg_139_r; // 0x139
|
|
RIE_U8 cfg_13A_r; // 0x13A
|
|
RIE_U8 cfg_13B_r; // 0x13B
|
|
RIE_U8 cfg_13C_r; // 0x13C
|
|
RIE_U8 cfg_13D_r; // 0x13D
|
|
RIE_U8 cfg_13E_r; // 0x13E
|
|
RIE_U8 cfg_13F_r; // 0x13F
|
|
} TyRadioConfiguration;
|
|
/*************************************************************************/
|
|
/* Radio Configuration Constants */
|
|
/*************************************************************************/
|
|
#define interrupt_mask_0_interrupt_tx_eof (0x1 << 4)
|
|
#define interrupt_mask_0_interrupt_crc_correct (0x1 << 2)
|
|
|
|
#define packet_length_control_length_offset_offset (0)
|
|
#define packet_length_control_length_offset_minus0 (0x4 << packet_length_control_length_offset_offset)
|
|
#define packet_length_control_data_mode_offset (3)
|
|
#define packet_length_control_data_mode_packet (0x0 << packet_length_control_data_mode_offset)
|
|
#define packet_length_control_crc_en_yes (0x1 << 5)
|
|
#define packet_length_control_packet_len_variable (0x0 << 6)
|
|
#define packet_length_control_packet_len_fixed (0x1 << 6)
|
|
#define packet_length_control_data_byte_lsb (0x0 << 7)
|
|
|
|
#define symbol_mode_symbol_length_8_bit (0 << 0)
|
|
#define symbol_mode_data_whitening_disabled (0 << 3)
|
|
#define symbol_mode_data_whitening_enabled (1 << 3)
|
|
#define symbol_mode_eight_ten_enc_disabled (0 << 4 )
|
|
#define symbol_mode_prog_crc_en_disabled (0 << 5)
|
|
#define symbol_mode_manchester_enc_enabled (1 << 6)
|
|
|
|
#define radio_cfg_8_pa_single_diff_sel_single_ended (0x0 << 7)
|
|
#define radio_cfg_8_pa_single_diff_sel_differential (0x1 << 7)
|
|
#define radio_cfg_8_pa_power_numbits (4)
|
|
#define radio_cfg_8_pa_power_offset (3)
|
|
#define radio_cfg_8_pa_power_setting_63 (0xF << radio_cfg_8_pa_power_offset)
|
|
#define radio_cfg_8_pa_ramp_numbits (3)
|
|
#define radio_cfg_8_pa_ramp_offset (0)
|
|
#define radio_cfg_8_pa_ramp_16 (0x5 << radio_cfg_8_pa_ramp_offset)
|
|
|
|
#define radio_cfg_9_demod_scheme_offset (0)
|
|
#define radio_cfg_9_demod_scheme_FSK (0x0 << radio_cfg_9_demod_scheme_offset)
|
|
#define radio_cfg_9_mod_scheme_numbits (3)
|
|
#define radio_cfg_9_mod_scheme_offset (3)
|
|
#define radio_cfg_9_mod_scheme_2_level_FSK (0x0 << radio_cfg_9_mod_scheme_offset)
|
|
#define radio_cfg_9_mod_scheme_2_level_GFSK (0x1 << radio_cfg_9_mod_scheme_offset)
|
|
#define radio_cfg_9_ifbw_numbits (2)
|
|
#define radio_cfg_9_ifbw_offset (6)
|
|
#define radio_cfg_9_ifbw_100kHz (0x0 << radio_cfg_9_ifbw_offset)
|
|
#define radio_cfg_9_ifbw_150kHz (0x1 << radio_cfg_9_ifbw_offset)
|
|
#define radio_cfg_9_ifbw_200kHz (0x2 << radio_cfg_9_ifbw_offset)
|
|
#define radio_cfg_9_ifbw_300kHz (0x3 << radio_cfg_9_ifbw_offset)
|
|
|
|
/*************************************************************************/
|
|
/* Local Variables */
|
|
/*************************************************************************/
|
|
static TyRadioConfiguration RadioConfiguration;
|
|
static RIE_BOOL bRadioConfigurationChanged = RIE_FALSE;
|
|
static RIE_BOOL bTestModeEnabled = RIE_FALSE;
|
|
static RIE_U32 DataRate = 38400;
|
|
static volatile RIE_BOOL bPacketTx = RIE_FALSE;
|
|
static volatile RIE_BOOL bPacketRx = RIE_FALSE;
|
|
|
|
const RIE_U8 DR_38_4kbps_Dev20kHz_Configuration[] =
|
|
{
|
|
0x14,0x00,0x00,0x00,0x00,0x00,0x00,0x33,0x00,0x76,0x62,0x21,
|
|
|
|
// 0 1 2 3 4 5 6 7 8 9 A B
|
|
0x80,0x01,0xC8,0x20,0x0E,0x00,0x00,0x00,0xFD,0x00,0x0B,0x37,
|
|
0x16,0x07,
|
|
|
|
0x40,0x0C,0x00,0x0C,0x00,0x00,
|
|
0x10,0x00,0xC3,0x36,0x10,0x10,0x24,0xF0,0x2A,0x00,0x2F,0x19,0x5E,0x46,0x5F,0x78,
|
|
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
|
|
};
|
|
|
|
|
|
const RIE_U8 DR_300_0kbps_Dev75_0kHz_Configuration[] =
|
|
{
|
|
0x14,0x00,0x00,0x00,0x00,0x00,0x00,0x33,0x00,0x76,0x62,0x21,
|
|
|
|
// 0 1 2 3 4 5 6 7 8 9 A B
|
|
0xB8,0x2B,0xEE,0x0B,0x70,0x00,0x03,0x00,0xFD,0xC0,0x0B,0x37,
|
|
0x16,0x07,
|
|
|
|
0x40,0x0C,0x00,0x0C,0x00,0x00,
|
|
0x10,0x00,0xC3,0x36,0x10,0x10,0x24,0xF0,0x2A,0x00,0x2F,0x19,0x5E,0x46,0x5F,0x78,
|
|
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
|
|
};
|
|
|
|
|
|
|
|
const RIE_U8 DR_1_0kbps_Dev10_0kHz_Configuration[] =
|
|
{
|
|
0x14,0x00,0x00,0x00,0x00,0x00,0x00,0x33,0x00,0x76,0x62,0x21,
|
|
// 0 1 2 3 4 5 6 7 8 9 A B
|
|
0x0A,0x00,0x64,0x41,0x01,0x00,0x02,0x00,0xFD,0x00,0x0B,0x37,
|
|
0x16,0x07,
|
|
|
|
0x40,0x0C,0x00,0x0C,0x00,0x00,
|
|
0x10,0x00,0xC3,0x36,0x10,0x10,0x24,0xF0,0x2A,0x00,0x2F,0x19,0x5E,0x46,0x5F,0x78,
|
|
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
|
|
};
|
|
|
|
/*************************************************************************/
|
|
/* Local Functions */
|
|
/*************************************************************************/
|
|
static RIE_Responses RadioSPIXferByte (RIE_U8 ucByte,
|
|
RIE_U8 * pData);
|
|
static RIE_Responses RadioSendCommandBytes (RIE_U8 * pCmdBytes,
|
|
RIE_U8 NumBytes);
|
|
static RIE_Responses RadioSendCommandNoWait (Radio_CmdCodes CmdCode);
|
|
static RIE_Responses RadioSendCommandWait (Radio_CmdCodes CmdCode);
|
|
static RIE_Responses RadioMMapRead (RIE_U32 ulAdr,
|
|
RIE_U32 ulLen,
|
|
RIE_U8 * pData);
|
|
static RIE_Responses RadioMMapWrite (RIE_U32 ulAdr,
|
|
RIE_U32 ulLen,
|
|
RIE_U8 * pData);
|
|
static RIE_Responses RadioReadState (RadioState * pState);
|
|
static RIE_Responses RadioWaitOnState (RadioState FinalState);
|
|
static RIE_Responses RadioWaitForPowerUp (void);
|
|
static RIE_Responses RadioSyncComms (void);
|
|
static RIE_Responses SetRadioConfiguration (RIE_BaseConfigs BaseConfig);
|
|
static RIE_Responses RadioCommitRadioConfig (void);
|
|
static RIE_Responses RadioConfigure (void);
|
|
static RIE_Responses RadioToOnMode (void);
|
|
static RIE_Responses RadioToOffMode (void);
|
|
static RIE_Responses RadioWaitOnCmdLdr (void);
|
|
/*************************************************************************/
|
|
/* Functions Implementations - Start */
|
|
/*************************************************************************/
|
|
|
|
/**
|
|
@fn RIE_Responses RadioGetAPIVersion(RIE_U32 *pVersion)
|
|
@brief Return the Radio Interface Engine API Version
|
|
@param pVersion :{}
|
|
pVersion Storage for Radio Interface Engine API version.
|
|
@code
|
|
RIE_U32 Version;
|
|
Response = RadioGetAPIVersion(&Version);
|
|
@endcode
|
|
@return RIE_Responses Error code.
|
|
**/
|
|
|
|
RIE_Responses RadioGetAPIVersion(RIE_U32 *pVersion)
|
|
{
|
|
RIE_Responses Response = RIE_Success;
|
|
|
|
if (pVersion)
|
|
*pVersion = RIE_ENGINE_MINOR_VERSION | (RIE_ENGINE_MAJOR_VERSION << 8);
|
|
return Response;
|
|
}
|
|
|
|
|
|
/**
|
|
@fn RIE_U32 RadioSwitchConfig(RIE_BaseConfigs BaseConfig)
|
|
@brief Change the Radio to using specified configuration.
|
|
@param BaseConfig :{DR_1_0kbps_Dev10_0kHz, DR_38_4kbps_Dev20kHz, DR_300_0kbps_Dev75_0kHz}
|
|
- DR_1_0kbps_Dev10_0kHz Base configuration of 1 kbps datarate, 10.0 kHz frequency deviation.
|
|
- DR_38_4kbps_Dev20kHz Base configuration of 38.4 kbps datarate, 20 kHz frequency deviation.
|
|
- DR_300_0kbps_Dev75_0kHz Base configuration of 300 kbps datarate, 75 kHz frequency deviation.
|
|
@pre
|
|
RadioInit() must be called before this function is called.
|
|
@return RIE_Responses Error code.
|
|
**/
|
|
|
|
RIE_Responses RadioSwitchConfig(RIE_BaseConfigs BaseConfig)
|
|
{
|
|
RIE_Responses Response = RIE_Success;
|
|
if(Response == RIE_Success)
|
|
Response = RadioToOffMode();
|
|
if(Response == RIE_Success)
|
|
Response = SetRadioConfiguration(BaseConfig);
|
|
if(Response == RIE_Success)
|
|
Response = RadioCommitRadioConfig();
|
|
if(Response == RIE_Success)
|
|
Response = RadioToOnMode();
|
|
return Response;
|
|
}
|
|
|
|
|
|
/**
|
|
@fn RIE_U32 RadioInit(RIE_BaseConfigs BaseConfig)
|
|
@brief Initialise the Radio, using specified configuration.
|
|
@param BaseConfig :{DR_1_0kbps_Dev10_0kHz , DR_38_4kbps_Dev20kHz ,DR_300_0kbps_Dev75_0kHz }
|
|
- DR_1_0kbps_Dev10_0kHz Base configuration of 1 kbps datarate, 10.0 kHz frequency deviation.
|
|
- DR_38_4kbps_Dev20kHz Base configuration of 38.4 kbps datarate, 20 kHz frequency deviation.
|
|
- DR_300_0kbps_Dev75_0kHz Base configuration of 300 kbps datarate, 75 kHz frequency deviation.
|
|
@note
|
|
This must be called before any other function is called.
|
|
@return RIE_Responses Error code.
|
|
**/
|
|
|
|
RIE_Responses RadioInit(RIE_BaseConfigs BaseConfig)
|
|
{
|
|
RIE_Responses Response = RIE_Success;
|
|
|
|
// Disable the radio interrupt until we have initialised the radio
|
|
NVIC_DisableIRQ(UHFTRX_IRQn);
|
|
|
|
// Initialise GPIO Port 2 for Radio Use
|
|
pADI_GP2->GPCON = GP2CON_CON0_SPI0MISO | GP2CON_CON1_SPI0SCLK |
|
|
GP2CON_CON2_SPI0MOSI | GP2CON_CON3_GPIO |
|
|
GP2CON_CON4_IRQ8 | GP2CON_CON5_GPIO |
|
|
GP2CON_CON6_GPIO | GP2CON_CON7_GPIOIRQ7;
|
|
|
|
pADI_GP2->GPOEN = GP2OEN_OEN0_IN | GP2OEN_OEN1_IN |
|
|
GP2OEN_OEN2_IN | GP2OEN_OEN3_OUT |
|
|
GP2OEN_OEN4_IN | GP2OEN_OEN5_IN |
|
|
GP2OEN_OEN6_IN | GP2OEN_OEN7_IN;
|
|
|
|
// Disable the PULL-Up on P2.4 which is connected to the radio
|
|
GP2PUL_PUL4_BBA = 0x0;
|
|
|
|
// Configure the SPI Interface to the Radio and flush it
|
|
pADI_SPI0->SPIDIV = ((SYSTEM_UCLK/RADIO_SPI_CLK_FREQ)/2)-0x1;
|
|
pADI_SPI0->SPICON = SPICON_MASEN | // Master mode
|
|
SPICON_TIM | // Interrupt on transmit
|
|
SPICON_TFLUSH | // Flush FIFO
|
|
SPICON_RFLUSH | // Flush FIFO
|
|
SPICON_ENABLE;
|
|
pADI_SPI0->SPICON = SPICON_MASEN | // Master mode
|
|
SPICON_TIM | // Interrupt on transmit
|
|
SPICON_ENABLE;
|
|
|
|
// Initialise the chip select line to starting position
|
|
RADIO_CSN_DEASSERT;
|
|
|
|
|
|
// Power it down and up again to return to a known state
|
|
// which will be PHY_OFF.
|
|
// This will clear any pre-existing radio interrupt before
|
|
// we enable the Cortex interrupt handling of it
|
|
if(Response == RIE_Success)
|
|
Response = RadioPowerOff();
|
|
// Configure a "high level" radio interrupt ...
|
|
pADI_INTERRUPT->EI2CFG = EI2CFG_IRQ8MDE_HIGHLEVEL | EI2CFG_IRQ8EN;
|
|
// ... and set it up in the NVIC so that our interrupt handler is called
|
|
// when the radio wants our attention. Clear any pre-existing condition
|
|
// before enabling the interrupt.
|
|
pADI_INTERRUPT->EICLR = EICLR_IRQ8;
|
|
NVIC_ClearPendingIRQ(UHFTRX_IRQn);
|
|
NVIC_SetPriority (UHFTRX_IRQn,0x0);
|
|
NVIC_EnableIRQ (UHFTRX_IRQn);
|
|
|
|
if(Response == RIE_Success)
|
|
Response = RadioWaitForPowerUp();
|
|
if(Response == RIE_Success)
|
|
Response = RadioSyncComms();
|
|
if(Response == RIE_Success)
|
|
Response = RadioToOffMode();
|
|
if(Response == RIE_Success)
|
|
Response = SetRadioConfiguration(BaseConfig);
|
|
if(Response == RIE_Success)
|
|
Response = RadioCommitRadioConfig();
|
|
if(Response == RIE_Success)
|
|
Response = RadioToOnMode();
|
|
return Response;
|
|
}
|
|
|
|
/**
|
|
@fn RIE_U32 RadioDeInit(void)
|
|
@brief Deinitialise the Radio, and power it down.
|
|
@note
|
|
This can be called independently of all other functions to power down
|
|
the radio
|
|
@return RIE_Responses Error code.
|
|
**/
|
|
|
|
RIE_Responses RadioDeInit(void)
|
|
{
|
|
RIE_Responses Response = RIE_Success;
|
|
|
|
// Disable the radio interrupt
|
|
NVIC_DisableIRQ(UHFTRX_IRQn);
|
|
|
|
// Initialise GPIO Port 2 for Radio Use
|
|
pADI_GP2->GPCON = GP2CON_CON0_SPI0MISO | GP2CON_CON1_SPI0SCLK |
|
|
GP2CON_CON2_SPI0MOSI | GP2CON_CON3_GPIO |
|
|
GP2CON_CON4_IRQ8 | GP2CON_CON5_GPIO |
|
|
GP2CON_CON6_GPIO | GP2CON_CON7_GPIOIRQ7;
|
|
|
|
pADI_GP2->GPOEN = GP2OEN_OEN0_IN | GP2OEN_OEN1_IN |
|
|
GP2OEN_OEN2_IN | GP2OEN_OEN3_OUT |
|
|
GP2OEN_OEN4_IN | GP2OEN_OEN5_IN |
|
|
GP2OEN_OEN6_IN | GP2OEN_OEN7_IN;
|
|
|
|
// Enable the pull-up as we are powering down the radion
|
|
GP2PUL_PUL4_BBA = 0x1;
|
|
|
|
// Configure the SPI Interface to the Radio and flush it
|
|
pADI_SPI0->SPIDIV = ((SYSTEM_UCLK/RADIO_SPI_CLK_FREQ)/2)-0x1;
|
|
pADI_SPI0->SPICON = SPICON_MASEN | // Master mode
|
|
SPICON_TIM | // Interrupt on transmit
|
|
SPICON_TFLUSH | // Flush FIFO
|
|
SPICON_RFLUSH | // Flush FIFO
|
|
SPICON_ENABLE;
|
|
pADI_SPI0->SPICON = SPICON_MASEN | // Master mode
|
|
SPICON_TIM | // Interrupt on transmit
|
|
SPICON_ENABLE;
|
|
|
|
// Initialise the chip select line to starting position
|
|
RADIO_CSN_DEASSERT;
|
|
|
|
// Power it down
|
|
Response = RadioSendCommandNoWait(CMD_HW_RESET);
|
|
|
|
return Response;
|
|
}
|
|
|
|
/**
|
|
@fn RIE_Responses RadioPowerOff(void)
|
|
@brief Shutdown the radio and place it in its lowest power sleep mode.
|
|
@pre
|
|
RadioInit() must be called before this function is called.
|
|
@return RIE_Response Error code.
|
|
**/
|
|
|
|
RIE_Responses RadioPowerOff(void)
|
|
{
|
|
volatile RIE_U32 ulDelay;
|
|
RIE_Responses Response = RIE_Success;
|
|
|
|
Response = RadioSendCommandNoWait(CMD_HW_RESET);
|
|
|
|
// Delay for approximately 1 ms
|
|
ulDelay = 0x1000;
|
|
while (ulDelay--);
|
|
|
|
return Response;
|
|
}
|
|
|
|
/**
|
|
@fn RIE_Responses RadioTerminateRadioOp(void)
|
|
@brief Terminate a currently running radio RX or TX operation.
|
|
@pre RadioInit() must be called before this function is called.
|
|
@code
|
|
if (RIE_Response == RIE_Success)
|
|
RIE_Response = RadioRxPacketFixedLen(12);
|
|
// Delay for a while waiting for a packet
|
|
if (RIE_Response == RIE_Success)
|
|
{
|
|
// Abort the waiting
|
|
RIE_Response = RadioTerminateRadioOp();
|
|
}
|
|
@endcode
|
|
@return RIE_Responses Error code
|
|
**/
|
|
RIE_Responses RadioTerminateRadioOp (void)
|
|
{
|
|
RIE_Responses Response = RIE_Success;
|
|
|
|
Response = RadioToOnMode();
|
|
|
|
return Response;
|
|
}
|
|
|
|
/**
|
|
@fn RIE_Responses RadioSetFrequency(RIE_U32 Frequency)
|
|
@brief Set frequency for radio communications
|
|
@param Frequency :{431000000-928000000}
|
|
- This must be within the available bands of the radio:
|
|
- 431000000Hz to 464000000Hz and
|
|
- 862000000Hz to 928000000Hz.
|
|
@pre RadioInit() must be called before this function is called.
|
|
@code
|
|
if (RIE_Response == RIE_Success)
|
|
RIE_Response = RadioSetFrequency(915000000);
|
|
@endcode
|
|
@return RIE_Responses Error code
|
|
**/
|
|
RIE_Responses RadioSetFrequency(RIE_U32 Frequency)
|
|
{
|
|
RIE_Responses Response = RIE_Success;
|
|
RIE_U32 EncodedFrequency;
|
|
|
|
bRadioConfigurationChanged = RIE_TRUE;
|
|
|
|
EncodedFrequency = (RIE_U32)(Frequency * FREQ_CNVRT_VAL);
|
|
RadioConfiguration.channel_freq_0_r = (EncodedFrequency >> 0) & 0xFF;
|
|
RadioConfiguration.channel_freq_1_r = (EncodedFrequency >> 8) & 0xFF;
|
|
RadioConfiguration.channel_freq_2_r = (EncodedFrequency >> 16)& 0xFF;
|
|
if (Frequency >= 862000000)
|
|
{
|
|
RadioConfiguration.image_reject_cal_amplitude_r = 0x07;
|
|
RadioConfiguration.image_reject_cal_phase_r = 0x16;
|
|
}
|
|
else
|
|
{
|
|
RadioConfiguration.image_reject_cal_amplitude_r = 0x03;
|
|
RadioConfiguration.image_reject_cal_phase_r = 0x08;
|
|
}
|
|
return Response;
|
|
}
|
|
|
|
/**
|
|
@fn RIE_Responses RadioSetModulationType(RIE_ModulationTypes ModulationType)
|
|
@brief Set the Radio Transmitter Modulation Type. Can be FSK_Modulation or GFSK_Modulation.
|
|
@param ModulationType :{DR_1_0kbps_Dev10_0kHz , DR_38_4kbps_Dev20kHz ,DR_300_0kbps_Dev75_0kHz }
|
|
- DR_1_0kbps_Dev10_0kHz Base configuration of 1 kbps datarate, 10.0 kHz frequency deviation.
|
|
- DR_38_4kbps_Dev20kHz Base configuration of 38.4 kbps datarate, 20 kHz frequency deviation.
|
|
- DR_300_0kbps_Dev75_0kHz Base configuration of 300 kbps datarate, 75 kHz frequency deviation.
|
|
@pre RadioInit() must be called before this function is called.
|
|
@code
|
|
Response = RadioSetModulationType(GFSK_Modulation);
|
|
@endcode
|
|
@note FSK_Modulation is used by default.
|
|
@return RIE_Responses Error code
|
|
**/
|
|
RIE_Responses RadioSetModulationType(RIE_ModulationTypes ModulationType)
|
|
{
|
|
RIE_Responses Response = RIE_Success;
|
|
RIE_U8 ucNewCode;
|
|
RIE_U8 ucNewRegVal = RadioConfiguration.radio_cfg_9_r;
|
|
|
|
switch (ModulationType)
|
|
{
|
|
case FSK_Modulation:
|
|
ucNewCode = radio_cfg_9_mod_scheme_2_level_FSK;
|
|
break;
|
|
case GFSK_Modulation:
|
|
ucNewCode = radio_cfg_9_mod_scheme_2_level_GFSK;
|
|
break;
|
|
default:
|
|
Response = RIE_UnsupportedRadioConfig;
|
|
break;
|
|
}
|
|
if(Response == RIE_Success)
|
|
{
|
|
ucNewRegVal = MSKSET_VAL(RadioConfiguration.radio_cfg_9_r,
|
|
radio_cfg_9_mod_scheme_numbits,
|
|
radio_cfg_9_mod_scheme_offset,
|
|
ucNewCode);
|
|
if (ucNewRegVal != RadioConfiguration.radio_cfg_9_r )
|
|
{
|
|
bRadioConfigurationChanged = RIE_TRUE;
|
|
RadioConfiguration.radio_cfg_9_r = ucNewRegVal;
|
|
}
|
|
|
|
}
|
|
return Response;
|
|
}
|
|
|
|
/**
|
|
@fn RIE_Responses RadioPayldManchesterEncode(RIE_BOOL bEnable)
|
|
@brief Enable or Disable Manchester Encoding of payload data.
|
|
|
|
Manchester encoding can be used to ensure a dc-free (zero mean)
|
|
transmission.
|
|
|
|
A Binary 0 is mapped to 10, and a Binary 1 is mapped to 01.
|
|
|
|
Manchester encoding and decoding are applied to the payload data
|
|
and the CRC.
|
|
|
|
@param bEnable :{RIE_FALSE,RIE_TRUE}
|
|
- RIE_TRUE if Manchester Encoding is to be enabled.
|
|
- RIE_FALSE if disabled.
|
|
|
|
@pre RadioInit() must be called before this function is called.
|
|
@code
|
|
Response = RadioPayldManchesterEncode(RIE_TRUE);
|
|
|
|
@endcode
|
|
@note Manchester Encoding is disabled by default.
|
|
@return RIE_Responses Error code
|
|
**/
|
|
RIE_Responses RadioPayldManchesterEncode(RIE_BOOL bEnable)
|
|
{
|
|
RIE_Responses Response = RIE_Success;
|
|
RIE_U8 ucNewRegVal = RadioConfiguration.symbol_mode_r;
|
|
|
|
switch (bEnable)
|
|
{
|
|
case RIE_FALSE:
|
|
ucNewRegVal &= ~symbol_mode_manchester_enc_enabled;
|
|
break;
|
|
case RIE_TRUE:
|
|
ucNewRegVal |= symbol_mode_manchester_enc_enabled;
|
|
break;
|
|
default:
|
|
Response = RIE_UnsupportedRadioConfig;
|
|
break;
|
|
}
|
|
if(Response == RIE_Success)
|
|
{
|
|
if (ucNewRegVal != RadioConfiguration.symbol_mode_r )
|
|
{
|
|
bRadioConfigurationChanged = RIE_TRUE;
|
|
RadioConfiguration.symbol_mode_r = ucNewRegVal;
|
|
}
|
|
}
|
|
return Response;
|
|
}
|
|
/**
|
|
@fn RIE_Responses RadioPayldDataWhitening(RIE_BOOL bEnable)
|
|
@brief Enable or Disable Data Whitening of payload data.
|
|
|
|
Data whitening can be employed to avoid long runs of 1s or 0s
|
|
in the transmitted data stream.
|
|
|
|
This ensures sufficient bit transitions in the packet, which
|
|
aids in receiver clock and data recovery because the encoding
|
|
breaks up long runs of 1s or 0s in the transmit packet.
|
|
|
|
The data, excluding the preamble and sync word, is automatically
|
|
whitened before transmission by XORing the data with an 8-bit
|
|
pseudorandom sequence.
|
|
|
|
At the receiver, the data is XORed with the same pseudorandom
|
|
sequence, thereby reversing the whitening.
|
|
|
|
The linear feedback shift register polynomial used is x7 + x1 + 1.
|
|
|
|
@param bEnable :{RIE_FALSE, RIE_TRUE}
|
|
- RIE_TRUE if Manchester Encoding is to be enabled.
|
|
- RIE_FALSE if disabled.
|
|
|
|
@pre RadioInit() must be called before this function is called.
|
|
@code
|
|
Response = RadioPayldDataWhitening(RIE_TRUE);
|
|
|
|
@endcode
|
|
@note Data Whitening is disabled by default.
|
|
@return RIE_Responses Error code
|
|
**/
|
|
RIE_Responses RadioPayldDataWhitening(RIE_BOOL bEnable)
|
|
{
|
|
RIE_Responses Response = RIE_Success;
|
|
RIE_U8 ucNewRegVal = RadioConfiguration.symbol_mode_r;
|
|
|
|
switch (bEnable)
|
|
{
|
|
case RIE_FALSE:
|
|
ucNewRegVal &= ~symbol_mode_data_whitening_enabled;
|
|
break;
|
|
case RIE_TRUE:
|
|
ucNewRegVal |= symbol_mode_data_whitening_enabled;
|
|
break;
|
|
default:
|
|
Response = RIE_UnsupportedRadioConfig;
|
|
break;
|
|
}
|
|
if(Response == RIE_Success)
|
|
{
|
|
if (ucNewRegVal != RadioConfiguration.symbol_mode_r )
|
|
{
|
|
bRadioConfigurationChanged = RIE_TRUE;
|
|
RadioConfiguration.symbol_mode_r = ucNewRegVal;
|
|
}
|
|
}
|
|
return Response;
|
|
}
|
|
|
|
/**
|
|
@fn RIE_Responses RadioTxPacketFixedLen(RIE_U8 Len, RIE_U8 *pData)
|
|
@brief Transmit a fixed length packet.
|
|
@param Len :{1-240} Length of packet to be transmitted.
|
|
@param pData :{} Data bytes to be transmitted.
|
|
@pre RadioInit() must be called before this function is called.
|
|
@code
|
|
if (RIE_Response == RIE_Success)
|
|
RIE_Response = RadioTxSetPA(DifferentialPA,PowerLevel15);
|
|
if (RIE_Response == RIE_Success)
|
|
RIE_Response = RadioTxPacketFixedLen(12, "HELLO WORLD");
|
|
while (!RadioTxPacketComplete());
|
|
@endcode
|
|
@return RIE_Responses Error code
|
|
**/
|
|
RIE_Responses RadioTxPacketFixedLen(RIE_U8 Len, RIE_U8 *pData)
|
|
{
|
|
RIE_Responses Response = RIE_Success;
|
|
|
|
bPacketTx = RIE_FALSE;
|
|
if (Len > PACKETRAM_LEN)
|
|
Response = RIE_InvalidParamter;
|
|
if (Response == RIE_Success)
|
|
Response = RadioToOnMode();
|
|
if (Response == RIE_Success)
|
|
Response = RadioMMapWrite(PACKETRAM_START, Len, pData);
|
|
if (Response == RIE_Success)
|
|
{
|
|
RadioConfiguration.packet_length_max_r = Len;
|
|
RadioConfiguration.packet_length_control_r |= packet_length_control_packet_len_fixed;
|
|
}
|
|
if(Response == RIE_Success)
|
|
Response = RadioCommitRadioConfig();
|
|
if (Response == RIE_Success)
|
|
Response = RadioToOnMode();
|
|
if (Response == RIE_Success)
|
|
Response = RadioSendCommandWait(CMD_PHY_TX);
|
|
|
|
return Response;
|
|
}
|
|
|
|
/**
|
|
@fn RIE_Responses RadioTxPacketVariableLen(RIE_U8 Len, RIE_U8 *pData)
|
|
@brief Transmit a Variable length packet.
|
|
@param Len :{1-240} Length of packet to be transmitted.
|
|
@param pData :{} Data bytes to be transmitted.
|
|
@pre RadioInit() must be called before this function is called.
|
|
@code
|
|
if (RIE_Response == RIE_Success)
|
|
RIE_Response = RadioTxSetPA(DifferentialPA,PowerLevel15);
|
|
if (RIE_Response == RIE_Success)
|
|
RIE_Response = RadioTxPacketVariableLen(12, "HELLO WORLD");
|
|
while (!RadioTxPacketComplete());
|
|
@endcode
|
|
@return RIE_Responses Error code
|
|
**/
|
|
RIE_Responses RadioTxPacketVariableLen(RIE_U8 Len, RIE_U8 *pData)
|
|
{
|
|
RIE_Responses Response = RIE_Success;
|
|
|
|
bPacketTx = RIE_FALSE;
|
|
|
|
Len += 0x1;
|
|
if (Len > PACKETRAM_LEN)
|
|
Response = RIE_InvalidParamter;
|
|
if (Response == RIE_Success)
|
|
Response = RadioToOnMode();
|
|
if (Response == RIE_Success)
|
|
Response = RadioMMapWrite(PACKETRAM_START, 0x1, &Len);
|
|
if (Response == RIE_Success)
|
|
Response = RadioMMapWrite(PACKETRAM_START+0x1, Len-1, pData);
|
|
if (Response == RIE_Success)
|
|
{
|
|
RadioConfiguration.packet_length_max_r = PACKETRAM_LEN;
|
|
RadioConfiguration.packet_length_control_r &= ~packet_length_control_packet_len_fixed;
|
|
}
|
|
if(Response == RIE_Success)
|
|
Response = RadioCommitRadioConfig();
|
|
if (Response == RIE_Success)
|
|
Response = RadioToOnMode();
|
|
if (Response == RIE_Success)
|
|
Response = RadioSendCommandWait(CMD_PHY_TX);
|
|
|
|
return Response;
|
|
}
|
|
|
|
|
|
/**
|
|
@fn RIE_BOOL RadioTxPacketComplete(void)
|
|
@brief Checks if a packet has finished transmitting
|
|
@pre RadioInit() must be called before this function is called.
|
|
@pre RadioRxPacketFixedLen() or equivalent should be called first.
|
|
@code
|
|
if (RIE_Response == RIE_Success)
|
|
RIE_Response = RadioTxSetPA(DifferentialPA,PowerLevel15);
|
|
if (RIE_Response == RIE_Success)
|
|
RIE_Response = RadioTxPacketFixedLen(12, "HELLO WORLD");
|
|
while (!RadioTxPacketComplete());
|
|
@endcode
|
|
@return RIE_BOOL RIE_TRUE if packet has finished transmitting, else RIE_FALSE
|
|
**/
|
|
RIE_BOOL RadioTxPacketComplete (void)
|
|
{
|
|
return bPacketTx;
|
|
}
|
|
|
|
/**
|
|
@fn RIE_Responses RadioTxSetPA(RIE_PATypes PAType,RIE_PAPowerLevel Power)
|
|
@brief Set PA Type and the Transmit Power Level for Radio Transmission.
|
|
@param PAType :{DifferentialPA, SingleEndedPA} Select Single Ended or Differential PA Type
|
|
@param Power :{PowerLevel0 ,PowerLevel1 ,PowerLevel2 ,PowerLevel3,
|
|
PowerLevel4 ,PowerLevel5 ,PowerLevel6 ,PowerLevel7,
|
|
PowerLevel8 ,PowerLevel9 ,PowerLevel10,PowerLevel11,
|
|
PowerLevel12,PowerLevel13,PowerLevel14,PowerLevel15}
|
|
@pre RadioInit() must be called before this function is called.
|
|
@code
|
|
Response = RadioTxSetPA(SingleEndedPA,PowerLevel8);
|
|
@endcode
|
|
@note Differential PA is enabled by default.
|
|
@note Max TX Power is used by default.
|
|
@return RIE_Responses Error code
|
|
**/
|
|
RIE_Responses RadioTxSetPA(RIE_PATypes PAType,RIE_PAPowerLevel Power)
|
|
{
|
|
RIE_Responses Response = RIE_Success;
|
|
RIE_U8 ucNewRegVal = 0x0;
|
|
unsigned long pa_level_mcr,pa_ramp, codes_per_bit,min_codes_per_bit;
|
|
|
|
switch (PAType)
|
|
{
|
|
case DifferentialPA:
|
|
ucNewRegVal |= radio_cfg_8_pa_single_diff_sel_differential;
|
|
break;
|
|
case SingleEndedPA:
|
|
ucNewRegVal |= radio_cfg_8_pa_single_diff_sel_single_ended;
|
|
break;
|
|
default:
|
|
Response = RIE_UnsupportedRadioConfig;
|
|
break;
|
|
}
|
|
if(Response == RIE_Success)
|
|
{
|
|
switch (Power)
|
|
{
|
|
case PowerLevel0 :
|
|
case PowerLevel1 :
|
|
case PowerLevel2 :
|
|
case PowerLevel3 :
|
|
case PowerLevel4 :
|
|
case PowerLevel5 :
|
|
case PowerLevel6 :
|
|
case PowerLevel7 :
|
|
case PowerLevel8 :
|
|
case PowerLevel9 :
|
|
case PowerLevel10:
|
|
case PowerLevel11:
|
|
case PowerLevel12:
|
|
case PowerLevel13:
|
|
case PowerLevel14:
|
|
case PowerLevel15:
|
|
ucNewRegVal |= ((RIE_U8)Power << radio_cfg_8_pa_power_offset);
|
|
// Calculate the minimum allowable codes per bit
|
|
pa_level_mcr = (((RIE_U8)Power)* 4) + 0x3;
|
|
min_codes_per_bit = (pa_level_mcr * 2500)/(DataRate/100);
|
|
pa_ramp = 0x1;
|
|
codes_per_bit = 256;
|
|
while (codes_per_bit > min_codes_per_bit)
|
|
{
|
|
pa_ramp++;
|
|
codes_per_bit = 512 >> pa_ramp;
|
|
if (pa_ramp >= 7)
|
|
break; // This is the maximum
|
|
}
|
|
ucNewRegVal |= ((RIE_U8)pa_ramp << radio_cfg_8_pa_ramp_offset);
|
|
break;
|
|
default:
|
|
Response = RIE_UnsupportedRadioConfig;
|
|
break;
|
|
}
|
|
}
|
|
|
|
if(Response == RIE_Success)
|
|
{
|
|
if (ucNewRegVal != RadioConfiguration.radio_cfg_8_r )
|
|
{
|
|
bRadioConfigurationChanged = RIE_TRUE;
|
|
RadioConfiguration.radio_cfg_8_r = ucNewRegVal;
|
|
}
|
|
}
|
|
return Response;
|
|
}
|
|
/**
|
|
@fn RIE_Responses RadioTxCarrier(void)
|
|
@brief Transmit a carrier tone
|
|
using the current radio configuration.
|
|
@pre RadioInit() must be called before this function is called.
|
|
@code
|
|
Response = RadioTxCarrier();
|
|
@endcode
|
|
@note Terminate this mode by calling RadioTerminateRadioOp();
|
|
@return RIE_Responses Error code
|
|
**/
|
|
RIE_Responses RadioTxCarrier (void)
|
|
{
|
|
RIE_Responses Response = RIE_Success;
|
|
RIE_U8 ParamTX = PARAM_TX_CARRIER_FOREVER;
|
|
|
|
if(Response == RIE_Success)
|
|
Response = RadioCommitRadioConfig();
|
|
bTestModeEnabled = RIE_TRUE;
|
|
if (Response == RIE_Success)
|
|
Response = RadioToOnMode();
|
|
// Mode needs to be set, before entry to PHY_TX
|
|
if (Response == RIE_Success)
|
|
Response = RadioMMapWrite(PR_var_tx_mode_ADR,sizeof(ParamTX),&ParamTX);
|
|
if (Response == RIE_Success)
|
|
Response = RadioSendCommandWait(CMD_PHY_TX);
|
|
return Response;
|
|
}
|
|
/**
|
|
@fn RIE_Responses RadioTxPreamble(void)
|
|
@brief Transmit a pre-amble (alternating ones and zeros)
|
|
using the current radio configuration.
|
|
@pre RadioInit() must be called before this function is called.
|
|
@code
|
|
Response = RadioTxPreamble();
|
|
@endcode
|
|
@note Terminate this mode by calling RadioTerminateRadioOp();
|
|
@return RIE_Responses Error code
|
|
**/
|
|
RIE_Responses RadioTxPreamble (void)
|
|
{
|
|
RIE_Responses Response = RIE_Success;
|
|
RIE_U8 ParamTX = PARAM_TX_PREAMBLE_FOREVER;
|
|
|
|
if(Response == RIE_Success)
|
|
Response = RadioCommitRadioConfig();
|
|
if (Response == RIE_Success)
|
|
Response = RadioToOnMode();
|
|
bTestModeEnabled = RIE_TRUE;
|
|
// Mode needs to be set, before entry to PHY_TX
|
|
if (Response == RIE_Success)
|
|
Response = RadioMMapWrite(PR_var_tx_mode_ADR,sizeof(ParamTX),&ParamTX);
|
|
if (Response == RIE_Success)
|
|
Response = RadioSendCommandWait(CMD_PHY_TX);
|
|
return Response;
|
|
}
|
|
|
|
/**
|
|
@fn RIE_Responses RadioRxPacketFixedLen(RIE_U8 Len)
|
|
@brief Enter receive mode and wait for a packet to be received.
|
|
|
|
Radio will stay in Receive Mode until
|
|
1) A packet is received.
|
|
2) User manually exits Receive Mode with a call to RadioTerminateRadioOp()
|
|
|
|
@param Len :{1-240} Fixed Length of packet to be received.
|
|
@pre RadioInit() must be called before this function is called.
|
|
@return RIE_Responses Error code
|
|
**/
|
|
RIE_Responses RadioRxPacketFixedLen(RIE_U8 Len)
|
|
{
|
|
RIE_Responses Response = RIE_Success;
|
|
|
|
bPacketRx = RIE_FALSE;
|
|
if (Len > PACKETRAM_LEN)
|
|
Response = RIE_InvalidParamter;
|
|
|
|
if (Response == RIE_Success)
|
|
{
|
|
RadioConfiguration.packet_length_max_r = Len;
|
|
RadioConfiguration.packet_length_control_r |= packet_length_control_packet_len_fixed;
|
|
}
|
|
if(Response == RIE_Success)
|
|
Response = RadioCommitRadioConfig();
|
|
if (Response == RIE_Success)
|
|
Response = RadioToOnMode();
|
|
if (Response == RIE_Success)
|
|
Response = RadioSendCommandWait(CMD_PHY_RX);
|
|
return Response;
|
|
}
|
|
|
|
/**
|
|
@fn RIE_Responses RadioRxPacketVariableLen(void)
|
|
@brief Enter receive mode and wait for a packet to be received.
|
|
|
|
Radio will stay in Receive Mode until
|
|
1) A packet is received.
|
|
2) User manually exits Receive Mode with a call to RadioTerminateRadioOp()
|
|
|
|
@pre RadioInit() must be called before this function is called.
|
|
@return RIE_Responses Error code
|
|
**/
|
|
RIE_Responses RadioRxPacketVariableLen(void)
|
|
{
|
|
RIE_Responses Response = RIE_Success;
|
|
|
|
bPacketRx = RIE_FALSE;
|
|
|
|
if (Response == RIE_Success)
|
|
{
|
|
RadioConfiguration.packet_length_max_r = PACKETRAM_LEN;
|
|
RadioConfiguration.packet_length_control_r &= ~packet_length_control_packet_len_fixed;
|
|
}
|
|
if(Response == RIE_Success)
|
|
Response = RadioCommitRadioConfig();
|
|
if (Response == RIE_Success)
|
|
Response = RadioToOnMode();
|
|
if (Response == RIE_Success)
|
|
Response = RadioSendCommandWait(CMD_PHY_RX);
|
|
return Response;
|
|
}
|
|
|
|
/**
|
|
@fn RIE_BOOL RadioRxPacketAvailable(void)
|
|
@brief Checks if a packet has been received.
|
|
@pre RadioInit() must be called before this function is called.
|
|
@pre RadioRxPacketFixedLen() or equivalent should be called first.
|
|
@code
|
|
if (RIE_Response == RIE_Success)
|
|
RIE_Response = RadioRxPacketFixedLen(12);
|
|
if (RIE_Response == RIE_Success)
|
|
{
|
|
while (!RadioRxPacketAvailable());
|
|
}
|
|
if (RIE_Response == RIE_Success)
|
|
{
|
|
unsigned char Buffer[0x20];
|
|
RIE_U8 PktLen;
|
|
RIE_S8 RSSI;
|
|
RIE_Response = RadioRxPacketRead(sizeof(Buffer),&PktLen,Buffer,&RSSI);
|
|
}
|
|
@endcode
|
|
@return RIE_BOOL RIE_TRUE if packet received, else RIE_FALSE
|
|
**/
|
|
RIE_BOOL RadioRxPacketAvailable(void)
|
|
{
|
|
return bPacketRx;
|
|
|
|
}
|
|
|
|
/**
|
|
@fn RIE_Responses RadioRxPacketRead(RIE_U8 BufferLen,RIE_U8 *pPktLen,RIE_U8 *pData,RIE_S8 *pRSSIdBm)
|
|
@brief Read the packet that was received by the radio.
|
|
@param BufferLen :{1-240} Size of passed in buffer
|
|
@param pPktLen :{1-240} Storage for size of actual received packet
|
|
@param pData :{} Received Packet will be stored here.
|
|
@param pRSSIdBm :{} RSSI of received packet in dBm.
|
|
@pre RadioInit() must be called before this function is called.
|
|
@pre RadioRxPacketFixedLen() or equivalent should be called first.
|
|
@code
|
|
if (RIE_Response == RIE_Success)
|
|
RIE_Response = RadioRxPacketFixedLen(12);
|
|
if (RIE_Response == RIE_Success)
|
|
{
|
|
while (!RadioRxPacketAvailable());
|
|
}
|
|
if (RIE_Response == RIE_Success)
|
|
{
|
|
unsigned char Buffer[0x20];
|
|
RIE_U8 PktLen;
|
|
RIE_S8 RSSI;
|
|
RIE_Response = RadioRxPacketRead(sizeof(Buffer),&PktLen,Buffer,&RSSI);
|
|
}
|
|
@endcode
|
|
@note Check for the presence of a packet by calling RadioRxPacketAvailable();
|
|
@return RIE_Responses Error code
|
|
**/
|
|
RIE_Responses RadioRxPacketRead(RIE_U8 BufferLen,RIE_U8 *pPktLen,RIE_U8 *pData,RIE_S8 *pRSSIdBm)
|
|
{
|
|
RIE_Responses Response = RIE_Success;
|
|
|
|
if (RadioRxPacketAvailable())
|
|
{
|
|
RIE_U8 RdLen;
|
|
if(RadioConfiguration.packet_length_control_r & packet_length_control_packet_len_fixed)
|
|
{
|
|
if (pPktLen)
|
|
*pPktLen = RadioConfiguration.packet_length_max_r;
|
|
RdLen = RadioConfiguration.packet_length_max_r;
|
|
if (RdLen > BufferLen)
|
|
RdLen = BufferLen;
|
|
if (Response == RIE_Success)
|
|
Response = RadioMMapRead(PACKETRAM_START,RdLen, pData);
|
|
}
|
|
else
|
|
{
|
|
if (Response == RIE_Success)
|
|
Response = RadioMMapRead(PACKETRAM_START,0x1, &RdLen);
|
|
RdLen -= 0x1;
|
|
if (pPktLen)
|
|
*pPktLen = RdLen;
|
|
if (RdLen > BufferLen)
|
|
RdLen = BufferLen;
|
|
if (Response == RIE_Success)
|
|
Response = RadioMMapRead(PACKETRAM_START+0x1,RdLen, pData);
|
|
}
|
|
|
|
if (pRSSIdBm)
|
|
{
|
|
if (Response == RIE_Success)
|
|
Response = RadioMMapRead(MCR_rssi_readback_Adr,0x1, (RIE_U8 *)pRSSIdBm);
|
|
|
|
*pRSSIdBm -= 107; // Convert to dBm
|
|
}
|
|
|
|
}
|
|
else
|
|
{
|
|
if (pPktLen)
|
|
*pPktLen = 0x0;
|
|
}
|
|
|
|
return Response;
|
|
}
|
|
|
|
/**
|
|
@fn RIE_Responses RadioRxBERTestMode(void)
|
|
@brief Enter receiver Bit Error Rate (BER) test mode where the
|
|
clock and data appear on GPIO pins.
|
|
Clock on P0.6 and Data on P2.6
|
|
@pre RadioInit() must be called before this function is called.
|
|
@code
|
|
Response = RadioRxBERTestMode();
|
|
@endcode
|
|
@note Terminate this mode by calling RadioTerminateRadioOp();
|
|
@return RIE_Responses Error code
|
|
**/
|
|
RIE_Responses RadioRxBERTestMode(void)
|
|
{
|
|
RIE_Responses Response = RIE_Success;
|
|
RIE_U8 Data;
|
|
// Enables internal radio signals on external pins
|
|
// but overrides some of the standard GPIO muxed
|
|
// functionality (UART?)
|
|
pADI_MISC->RFTST = 0x7E1;
|
|
|
|
if(Response == RIE_Success)
|
|
Response = RadioCommitRadioConfig();
|
|
|
|
bTestModeEnabled = RIE_TRUE;
|
|
// Enable the RX signals on GPIO pins
|
|
Data = gpio_configure_sport_mode_0;
|
|
if (Response == RIE_Success)
|
|
Response = RadioMMapWrite(MCR_gpio_configure_Adr, 0x1, (RIE_U8 *)&Data);
|
|
|
|
// disable ext_uc_clk on GP5
|
|
Data = 0;
|
|
if (Response == RIE_Success)
|
|
Response = RadioMMapWrite(MCR_ext_uc_clk_divide_Adr,
|
|
0x1,
|
|
(RIE_U8 *)&Data);
|
|
if (Response == RIE_Success)
|
|
Response = RadioSendCommandWait(CMD_PHY_RX);
|
|
return Response;
|
|
}
|
|
|
|
/**
|
|
@internal Hide from Doxegen
|
|
@fn RIE_Responses RadioCommitRadioConfig(void)
|
|
@brief Configures the radio if any changes were made
|
|
since the last time.
|
|
@return RIE_Responses Error code
|
|
**/
|
|
static RIE_Responses RadioCommitRadioConfig(void)
|
|
{
|
|
RIE_Responses Response = RIE_Success;
|
|
|
|
if(bTestModeEnabled)
|
|
{
|
|
RIE_U8 Data;
|
|
Data = gpio_configure_default;
|
|
if (Response == RIE_Success)
|
|
Response = RadioMMapWrite(MCR_gpio_configure_Adr, 0x1, (RIE_U8 *)&Data);
|
|
Data = 4;
|
|
if (Response == RIE_Success)
|
|
Response = RadioMMapWrite(MCR_ext_uc_clk_divide_Adr,
|
|
0x1,
|
|
(RIE_U8 *)&Data);
|
|
|
|
Data = PARAM_TX_NORMAL_PACKET;
|
|
if (Response == RIE_Success)
|
|
Response = RadioMMapWrite(PR_var_tx_mode_ADR,sizeof(Data),&Data);
|
|
bTestModeEnabled = RIE_FALSE;
|
|
}
|
|
if (bRadioConfigurationChanged)
|
|
{
|
|
Response = RadioConfigure();
|
|
if(Response == RIE_Success)
|
|
bRadioConfigurationChanged = RIE_FALSE;
|
|
}
|
|
return Response;
|
|
}
|
|
/**
|
|
@fn RIE_Responses RadioReadState(RadioState *pState)
|
|
@brief Read the current state
|
|
@param pState Pointer to return storage of state
|
|
@return RIE_Responses Error code
|
|
**/
|
|
static RIE_Responses RadioReadState(RadioState *pState)
|
|
{
|
|
RIE_Responses Response = RIE_Success;
|
|
RIE_U8 StatusByte;
|
|
|
|
NVIC_DisableIRQ(UHFTRX_IRQn);
|
|
RADIO_CSN_ASSERT;
|
|
if (Response == RIE_Success)
|
|
Response = RadioSPIXferByte(SPI_NOP,NULL);
|
|
if (Response == RIE_Success)
|
|
Response = RadioSPIXferByte(SPI_NOP,&StatusByte);
|
|
RADIO_CSN_DEASSERT;
|
|
NVIC_EnableIRQ (UHFTRX_IRQn);
|
|
if ((Response == RIE_Success) && pState)
|
|
*pState = (RadioState)(StatusByte & STATUS_BYTE_FW_STATE);
|
|
return Response;
|
|
}
|
|
|
|
/**
|
|
@fn RIE_Responses RadioWaitOnState(RadioState FinalState)
|
|
@brief Wait for Final State to be reached
|
|
@param FinalState State to wait on
|
|
@return RIE_Responses Error code
|
|
**/
|
|
static RIE_Responses RadioWaitOnState(RadioState FinalState)
|
|
{
|
|
RIE_Responses Response = RIE_Success;
|
|
RadioState CurrState;
|
|
do
|
|
{
|
|
Response = RadioReadState(&CurrState);
|
|
}
|
|
while((Response == RIE_Success) && (CurrState != FinalState));
|
|
return Response;
|
|
}
|
|
|
|
/**
|
|
@fn RIE_Responses RadioWaitOnCmdLdr(void)
|
|
@brief Wait for Final State to be reached
|
|
@param FinalState State to wait on
|
|
@return RIE_Responses Error code
|
|
**/
|
|
static RIE_Responses RadioWaitOnCmdLdr(void)
|
|
{
|
|
RIE_Responses Response = RIE_Success;
|
|
do
|
|
{
|
|
RIE_U8 StatusByte;
|
|
NVIC_DisableIRQ(UHFTRX_IRQn);
|
|
RADIO_CSN_ASSERT;
|
|
if (Response == RIE_Success)
|
|
Response = RadioSPIXferByte(SPI_NOP,NULL);
|
|
if (Response == RIE_Success)
|
|
Response = RadioSPIXferByte(SPI_NOP,&StatusByte);
|
|
RADIO_CSN_DEASSERT;
|
|
NVIC_EnableIRQ (UHFTRX_IRQn);
|
|
if ((Response == RIE_Success))
|
|
if(StatusByte & STATUS_BYTE_CMD_READY)
|
|
break;
|
|
}
|
|
while((Response == RIE_Success));
|
|
return Response;
|
|
}
|
|
|
|
/**
|
|
@internal Hide from Doxegen
|
|
@fn RIE_Responses RadioToOnMode(void)
|
|
@brief Transition to On Mode
|
|
|
|
Handle all possible states that the radio could be in
|
|
and brings it back to PHY_ON state
|
|
@param None
|
|
@return RIE_Responses Error code
|
|
**/
|
|
static RIE_Responses RadioToOnMode(void)
|
|
{
|
|
RIE_Responses Response = RIE_Success;
|
|
RadioState FwState;
|
|
|
|
if (Response == RIE_Success)
|
|
Response = RadioReadState(&FwState);
|
|
|
|
while ((FwState != FW_ON) && (Response == RIE_Success))
|
|
{
|
|
switch (FwState)
|
|
{
|
|
case FW_BUSY:
|
|
break;
|
|
case FW_TX:
|
|
if(Response == RIE_Success)
|
|
Response = RadioSendCommandNoWait(CMD_PHY_ON);
|
|
if (Response == RIE_Success)
|
|
Response = RadioWaitOnState (FW_ON);
|
|
break;
|
|
case FW_RX:
|
|
if(Response == RIE_Success)
|
|
Response = RadioSendCommandNoWait(CMD_PHY_ON);
|
|
if (Response == RIE_Success)
|
|
Response = RadioWaitOnState (FW_ON);
|
|
break;
|
|
default:
|
|
if(Response == RIE_Success)
|
|
Response = RadioSendCommandNoWait(CMD_PHY_ON);
|
|
if (Response == RIE_Success)
|
|
Response = RadioWaitOnState (FW_ON);
|
|
break;
|
|
}
|
|
if (Response == RIE_Success)
|
|
Response = RadioReadState(&FwState);
|
|
}
|
|
return Response;
|
|
}
|
|
/**
|
|
@internal Hide from Doxegen
|
|
@fn RIE_Responses RadioToOffMode(void)
|
|
@brief Transition to Off Mode
|
|
|
|
Handle all possible states that the radio could be in
|
|
and bring it back to PHY_OFF state.
|
|
|
|
@param None
|
|
@return RIE_Responses Error code
|
|
**/
|
|
static RIE_Responses RadioToOffMode(void)
|
|
{
|
|
RIE_Responses Response = RIE_Success;
|
|
RadioState FwState;
|
|
|
|
if (Response == RIE_Success)
|
|
Response = RadioReadState(&FwState);
|
|
|
|
while ((FwState != FW_OFF) && (Response == RIE_Success))
|
|
{
|
|
switch (FwState)
|
|
{
|
|
case FW_BUSY:
|
|
break;
|
|
case FW_TX:
|
|
if(Response == RIE_Success)
|
|
Response = RadioSendCommandNoWait(CMD_PHY_ON);
|
|
if (Response == RIE_Success)
|
|
Response = RadioWaitOnState (FW_ON);
|
|
break;
|
|
case FW_RX:
|
|
if(Response == RIE_Success)
|
|
Response = RadioSendCommandNoWait(CMD_PHY_ON);
|
|
if (Response == RIE_Success)
|
|
Response = RadioWaitOnState (FW_ON);
|
|
break;
|
|
default:
|
|
if(Response == RIE_Success)
|
|
Response = RadioSendCommandNoWait(CMD_PHY_OFF);
|
|
if (Response == RIE_Success)
|
|
Response = RadioWaitOnState (FW_OFF);
|
|
break;
|
|
}
|
|
if (Response == RIE_Success)
|
|
Response = RadioReadState(&FwState);
|
|
}
|
|
return Response;
|
|
}
|
|
/**
|
|
@internal Hide from Doxegen
|
|
@fn RIE_Responses RadioSyncComms (void)
|
|
@brief Sync comms with the radio
|
|
@param None
|
|
@return RIE_Responses Error code
|
|
**/
|
|
static RIE_Responses RadioSyncComms (void)
|
|
{
|
|
RIE_Responses Response = RIE_Success;
|
|
if (Response == RIE_Success)
|
|
Response = RadioSendCommandWait(CMD_SYNC);
|
|
if (Response == RIE_Success)
|
|
Response = RadioWaitOnCmdLdr();
|
|
return Response;
|
|
}
|
|
/**
|
|
@fn RIE_Responses RadioWaitForPowerUp(void)
|
|
@brief Wake Up the Part
|
|
|
|
Assert SPI chip select which will wake up the radio if asleep
|
|
Wait for MISO line to go high indicating SPI comms now possible
|
|
|
|
@return RIE_Responses Error code
|
|
**/
|
|
static RIE_Responses RadioWaitForPowerUp(void)
|
|
{
|
|
RIE_Responses Response = RIE_Success;
|
|
int i = 0x0;
|
|
RADIO_CSN_ASSERT;
|
|
while (!RADIO_MISO_IN && (i < 1000))
|
|
i++;
|
|
if (1000 == i)// Timed out waiting for MISO high?
|
|
Response = RIE_RadioSPICommsFail;
|
|
RADIO_CSN_DEASSERT;
|
|
return Response;
|
|
}
|
|
|
|
/**
|
|
\internal Hide from Doxegen
|
|
\fn void Ext_Int8_Handler(void)
|
|
\brief Radio Interrupt Handler
|
|
**/
|
|
extern void aducrf101_rx_packet_hook(void);
|
|
void Ext_Int8_Handler (void)
|
|
{
|
|
RIE_Responses Response = RIE_Success;
|
|
RIE_U8 ucInt0;
|
|
RIE_U8 ucInt1;
|
|
|
|
if (Response == RIE_Success)
|
|
Response = RadioMMapRead(MCR_interrupt_source_0_Adr,0x1, &ucInt0);
|
|
if (Response == RIE_Success)
|
|
Response = RadioMMapRead(MCR_interrupt_source_1_Adr,0x1,&ucInt1);
|
|
if (ucInt0 & interrupt_mask_0_interrupt_tx_eof)
|
|
bPacketTx = RIE_TRUE;
|
|
if (ucInt0 & interrupt_mask_0_interrupt_crc_correct) {
|
|
bPacketRx = RIE_TRUE;
|
|
aducrf101_rx_packet_hook();
|
|
}
|
|
// Clear all the interrupts that we have just handleed
|
|
if (Response == RIE_Success)
|
|
Response = RadioMMapWrite(MCR_interrupt_source_0_Adr,0x1, &ucInt0);
|
|
if (Response == RIE_Success)
|
|
Response = RadioMMapWrite(MCR_interrupt_source_1_Adr,0x1,&ucInt1);
|
|
// Clear the interrupt
|
|
pADI_INTERRUPT->EICLR = EICLR_IRQ8;
|
|
}
|
|
/**
|
|
\internal Hide from Doxegen
|
|
\fn void RadioSPIXferByte(RIE_U8 ucByte,RIE_U8 *pData)
|
|
\brief Transfer a byte via SPI to the radio and optionally return
|
|
received byte.
|
|
Chip Select is manually controlled elsewhere.
|
|
\param ucByte Command or data byte to be transferred.
|
|
\param pData NULL, or storage for response
|
|
\return RIE_Responses Error code
|
|
**/
|
|
static RIE_Responses RadioSPIXferByte(RIE_U8 ucByte,RIE_U8 *pData)
|
|
{
|
|
RIE_Responses Response = RIE_Success;
|
|
|
|
SEND_SPI(ucByte); // Send byte
|
|
WAIT_SPI_RX; // wait for data received status bit
|
|
if(pData)
|
|
*pData = READ_SPI;
|
|
else
|
|
(void)READ_SPI;
|
|
return Response;
|
|
}
|
|
/**
|
|
\internal Hide from Doxegen
|
|
\fn RIE_Responses RadioSendCommandBytes(RIE_U8 *pCmdBytes,RIE_U8 NumBytes)
|
|
\brief Send a complete command to the radio.
|
|
|
|
It is neccessary to disable the radio interrupt when doing this
|
|
as a command in progress must finish before a radio interrupt
|
|
can be handled.
|
|
|
|
\param pCmdBytes Pointer to a number of bytes to be transferred.
|
|
\param NumBytes Number of bytes to transfer
|
|
|
|
\return RIE_Responses Error code
|
|
**/
|
|
static RIE_Responses RadioSendCommandBytes(RIE_U8 *pCmdBytes,RIE_U8 NumBytes)
|
|
{
|
|
RIE_Responses Response = RIE_Success;
|
|
|
|
NVIC_DisableIRQ(UHFTRX_IRQn);
|
|
RADIO_CSN_ASSERT;
|
|
while ((NumBytes--) && (Response == RIE_Success))
|
|
Response = RadioSPIXferByte(*(pCmdBytes++),NULL); // Send Command
|
|
RADIO_CSN_DEASSERT; // De-assert SPI chip select
|
|
NVIC_EnableIRQ (UHFTRX_IRQn);
|
|
|
|
return Response;
|
|
}
|
|
/**
|
|
\internal Hide from Doxegen
|
|
\fn RIE_Responses RadioSendCommandNoWait (Radio_CmdCodes CmdCode )
|
|
\brief Send a single byte command to the radio.
|
|
\param CmdCode Command code to be sent
|
|
\return RIE_Responses Error code
|
|
**/
|
|
static RIE_Responses RadioSendCommandNoWait (Radio_CmdCodes CmdCode )
|
|
{
|
|
RIE_U8 Command = (RIE_U8)CmdCode;
|
|
return RadioSendCommandBytes(&Command,0x1);
|
|
}
|
|
/**
|
|
\internal Hide from Doxegen
|
|
\fn RIE_Responses RadioSendCommandWait (Radio_CmdCodes CmdCode )
|
|
\brief Send a single byte command to the radio.
|
|
\param CmdCode Command code to be sent
|
|
\return RIE_Responses Error code
|
|
**/
|
|
static RIE_Responses RadioSendCommandWait (Radio_CmdCodes CmdCode )
|
|
{
|
|
RIE_Responses Response = RIE_Success;
|
|
RIE_U8 Command = (RIE_U8)CmdCode;
|
|
|
|
if (Response == RIE_Success)
|
|
Response = RadioWaitOnCmdLdr();
|
|
if (Response == RIE_Success)
|
|
Response = RadioSendCommandBytes(&Command,0x1);
|
|
return Response;
|
|
}
|
|
/**
|
|
\fn RIE_Responses RadioMMapRead(RIE_U32 ulAdr, RIE_U32 ulLen, RIE_U8 *pData)
|
|
\brief Read bytes from specified memory map address
|
|
\param ulAdr Address to read at.
|
|
\param ulLen Length of data to read.
|
|
\param pData Pointer to location to stored read data.
|
|
\return RIE_Responses Error code
|
|
**/
|
|
static RIE_Responses RadioMMapRead(RIE_U32 ulAdr, RIE_U32 ulLen, RIE_U8 *pData)
|
|
{
|
|
RIE_Responses Response = RIE_Success;
|
|
|
|
NVIC_DisableIRQ(UHFTRX_IRQn);
|
|
RADIO_CSN_ASSERT;
|
|
|
|
if(Response == RIE_Success) // Send first byte (SPI_MEMR_RD + Bytes)
|
|
Response = RadioSPIXferByte(SPI_MEM_RD | ((ulAdr & 0x700) >> 8),NULL);
|
|
if(Response == RIE_Success)// Send Second byte remainder of address
|
|
Response = RadioSPIXferByte((RIE_U8)(ulAdr & 0xFF),NULL);
|
|
if(Response == RIE_Success)
|
|
Response = RadioSPIXferByte((RIE_U8)SPI_NOP,NULL);
|
|
while(ulLen-- && (Response == RIE_Success))
|
|
Response = RadioSPIXferByte(SPI_NOP,pData++);
|
|
RADIO_CSN_DEASSERT;
|
|
NVIC_EnableIRQ (UHFTRX_IRQn);
|
|
|
|
return Response;
|
|
}
|
|
/**
|
|
\fn RIE_Responses RadioMMapWrite(RIE_U32 ulAdr, RIE_U32 ulLen, RIE_U8 *pData)
|
|
\brief Read bytes from specified memory map address
|
|
\param ulAdr Address to read at.
|
|
\param ulLen Length of data to read.
|
|
\param pData Pointer to location of data to write.
|
|
\return RIE_Responses Error code
|
|
**/
|
|
static RIE_Responses RadioMMapWrite(RIE_U32 ulAdr,RIE_U32 ulLen,RIE_U8 * pData)
|
|
{
|
|
RIE_Responses Response = RIE_Success;
|
|
|
|
NVIC_DisableIRQ(UHFTRX_IRQn);
|
|
RADIO_CSN_ASSERT;
|
|
if(Response == RIE_Success) // Send first byte (SPI_MEMR_WR + Bytes)
|
|
Response = RadioSPIXferByte(SPI_MEM_WR | ((ulAdr & 0x700) >> 8),NULL);
|
|
if(Response == RIE_Success) // Send Second byte remainder of addrress
|
|
Response = RadioSPIXferByte((RIE_U8)(ulAdr & 0xFF),NULL);
|
|
while(ulLen-- && (Response == RIE_Success))
|
|
Response = RadioSPIXferByte(*(pData++),NULL);
|
|
RADIO_CSN_DEASSERT;
|
|
NVIC_EnableIRQ (UHFTRX_IRQn);
|
|
|
|
return Response;
|
|
}
|
|
|
|
/**
|
|
\internal Hide from Doxegen
|
|
\fn void SetRadioConfiguration(void)
|
|
\brief Create a default radio configuration that all base configurations
|
|
are derived from.
|
|
|
|
\return RIE_Responses Error code
|
|
**/
|
|
static RIE_Responses SetRadioConfiguration(RIE_BaseConfigs BaseConfig)
|
|
{
|
|
RIE_Responses Response = RIE_Success;
|
|
|
|
bRadioConfigurationChanged = RIE_TRUE;
|
|
switch (BaseConfig)
|
|
{
|
|
case DR_1_0kbps_Dev10_0kHz:
|
|
memcpy((void *)&RadioConfiguration,
|
|
(void *)DR_1_0kbps_Dev10_0kHz_Configuration,
|
|
sizeof(TyRadioConfiguration));
|
|
DataRate = 1000;
|
|
break;
|
|
case DR_38_4kbps_Dev20kHz:
|
|
memcpy((void *)&RadioConfiguration,
|
|
(void *)DR_38_4kbps_Dev20kHz_Configuration,
|
|
sizeof(TyRadioConfiguration));
|
|
DataRate = 38400;
|
|
break;
|
|
case DR_300_0kbps_Dev75_0kHz:
|
|
memcpy((void *)&RadioConfiguration,
|
|
(void *)DR_300_0kbps_Dev75_0kHz_Configuration,
|
|
sizeof(TyRadioConfiguration));
|
|
DataRate = 300000;
|
|
break;
|
|
default:
|
|
Response = RIE_UnsupportedRadioConfig;
|
|
break;
|
|
}
|
|
return Response;
|
|
}
|
|
/**
|
|
@internal Hide from Doxegen
|
|
@fn RIE_Responses RadioConfigure (void)
|
|
@brief Configure the Radio as per the current configuration
|
|
@return RIE_Responses Error code
|
|
**/
|
|
RIE_Responses RadioConfigure (void)
|
|
{
|
|
RIE_Responses Response = RIE_Success;
|
|
if(Response == RIE_Success)
|
|
Response = RadioToOffMode();
|
|
if(Response == RIE_Success) // Write the configuration to the radio memory
|
|
Response = RadioMMapWrite(BBRAM_START,
|
|
sizeof(TyRadioConfiguration),
|
|
(RIE_U8 *)&RadioConfiguration);
|
|
if(Response == RIE_Success) // Apply that configuration to the radio
|
|
Response = RadioSendCommandWait(CMD_CONFIG_DEV);
|
|
if(Response == RIE_Success)
|
|
Response = RadioToOnMode();
|
|
return Response;
|
|
}
|
|
|
|
|
|
/**
|
|
@fn RIE_Responses RadioRadioGetRSSI (RIE_S8 *pRSSIdBm)
|
|
@brief Return a Received Signal Strength Indicator value
|
|
@param pRSSIdBm :{} detected RSSI in dBm.
|
|
@pre RadioInit() must be called before this function is called.
|
|
@code
|
|
RIE_S8 RSSIdBm;
|
|
if (RIE_Response == RIE_Success)
|
|
RIE_Response = RadioRadioGetRSSI(&RSSIdBm);
|
|
@endcode
|
|
@return RIE_Responses Error code
|
|
**/
|
|
RIE_Responses RadioRadioGetRSSI (RIE_S8 *pRSSIdBm)
|
|
{
|
|
RIE_Responses Response = RIE_Success;
|
|
|
|
if(Response == RIE_Success)
|
|
Response = RadioCommitRadioConfig();
|
|
if (Response == RIE_Success)
|
|
Response = RadioToOnMode();
|
|
if (Response == RIE_Success)
|
|
Response = RadioSendCommandWait(CMD_GET_RSSI);
|
|
if (Response == RIE_Success)
|
|
Response = RadioSyncComms(); //
|
|
if (pRSSIdBm)
|
|
{
|
|
if (Response == RIE_Success)
|
|
Response = RadioMMapRead(MCR_rssi_readback_Adr,0x1, (RIE_U8 *)pRSSIdBm);
|
|
*pRSSIdBm -= 107; // Convert to dBm
|
|
}
|
|
return Response;
|
|
}
|
|
|
|
/**
|
|
@fn RIE_Responses RadioTxSetPower(RIE_PAPowerLevel Power)
|
|
@brief Set the Transmit Power Level for Radio Transmission.
|
|
@param Power :{PowerLevel0 ,PowerLevel1 ,PowerLevel2 ,PowerLevel3,
|
|
PowerLevel4 ,PowerLevel5 ,PowerLevel6 ,PowerLevel7,
|
|
PowerLevel8 ,PowerLevel9 ,PowerLevel10,PowerLevel11,
|
|
PowerLevel12,PowerLevel13,PowerLevel14,PowerLevel15}
|
|
@pre RadioInit() must be called before this function is called.
|
|
@code
|
|
Response = RadioTxSetPower(PowerLevel8);
|
|
@endcode
|
|
@note Max TX Power is used by default.
|
|
@return RIE_Responses Error code
|
|
*/
|
|
RIE_Responses RadioTxSetPower (RIE_PAPowerLevel Power)
|
|
{
|
|
RIE_Responses Response = RIE_Success;
|
|
RIE_U8 ucNewRegVal = RadioConfiguration.radio_cfg_8_r;
|
|
unsigned long pa_level_mcr,pa_ramp, codes_per_bit,min_codes_per_bit;
|
|
|
|
if (RadioConfiguration.radio_cfg_8_r & radio_cfg_8_pa_single_diff_sel_differential)
|
|
ucNewRegVal = radio_cfg_8_pa_single_diff_sel_differential;
|
|
else
|
|
ucNewRegVal = radio_cfg_8_pa_single_diff_sel_single_ended;
|
|
|
|
if(Response == RIE_Success)
|
|
{
|
|
switch (Power)
|
|
{
|
|
case PowerLevel0 :
|
|
case PowerLevel1 :
|
|
case PowerLevel2 :
|
|
case PowerLevel3 :
|
|
case PowerLevel4 :
|
|
case PowerLevel5 :
|
|
case PowerLevel6 :
|
|
case PowerLevel7 :
|
|
case PowerLevel8 :
|
|
case PowerLevel9 :
|
|
case PowerLevel10:
|
|
case PowerLevel11:
|
|
case PowerLevel12:
|
|
case PowerLevel13:
|
|
case PowerLevel14:
|
|
case PowerLevel15:
|
|
ucNewRegVal |= ((RIE_U8)Power << radio_cfg_8_pa_power_offset);
|
|
// Calculate the minimum allowable codes per bit
|
|
pa_level_mcr = (((RIE_U8)Power)* 4) + 0x3;
|
|
min_codes_per_bit = (pa_level_mcr * 2500)/(DataRate/100);
|
|
pa_ramp = 0x1;
|
|
codes_per_bit = 256;
|
|
while (codes_per_bit > min_codes_per_bit)
|
|
{
|
|
pa_ramp++;
|
|
codes_per_bit = 512 >> pa_ramp;
|
|
if (pa_ramp >= 7)
|
|
break; // This is the maximum
|
|
}
|
|
ucNewRegVal |= ((RIE_U8)pa_ramp << radio_cfg_8_pa_ramp_offset);
|
|
break;
|
|
default:
|
|
Response = RIE_UnsupportedRadioConfig;
|
|
break;
|
|
}
|
|
}
|
|
|
|
if(Response == RIE_Success)
|
|
{
|
|
if (ucNewRegVal != RadioConfiguration.radio_cfg_8_r )
|
|
{
|
|
// Write directly to the MCR in this case and avoid a reconfigure
|
|
if (Response == RIE_Success)
|
|
Response = RadioMMapWrite(MCR_pa_level_mcr_Adr, 0x1, (RIE_U8 *)&ucNewRegVal);
|
|
RadioConfiguration.radio_cfg_8_r = ucNewRegVal;
|
|
}
|
|
}
|
|
return Response;
|
|
}
|
|
|