FRDM K64F Metronome

Committer:
ram54288
Date:
Sun May 14 18:37:05 2017 +0000
Revision:
0:dbad57390bd1
Initial commit

Who changed what in which revision?

UserRevisionLine numberNew contents of line
ram54288 0:dbad57390bd1 1 /*
ram54288 0:dbad57390bd1 2 * Copyright (c) 2014-2015 ARM Limited. All rights reserved.
ram54288 0:dbad57390bd1 3 * SPDX-License-Identifier: Apache-2.0
ram54288 0:dbad57390bd1 4 * Licensed under the Apache License, Version 2.0 (the License); you may
ram54288 0:dbad57390bd1 5 * not use this file except in compliance with the License.
ram54288 0:dbad57390bd1 6 * You may obtain a copy of the License at
ram54288 0:dbad57390bd1 7 *
ram54288 0:dbad57390bd1 8 * http://www.apache.org/licenses/LICENSE-2.0
ram54288 0:dbad57390bd1 9 *
ram54288 0:dbad57390bd1 10 * Unless required by applicable law or agreed to in writing, software
ram54288 0:dbad57390bd1 11 * distributed under the License is distributed on an AS IS BASIS, WITHOUT
ram54288 0:dbad57390bd1 12 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
ram54288 0:dbad57390bd1 13 * See the License for the specific language governing permissions and
ram54288 0:dbad57390bd1 14 * limitations under the License.
ram54288 0:dbad57390bd1 15 */
ram54288 0:dbad57390bd1 16 #include "NanostackRfPhyMcr20a.h"
ram54288 0:dbad57390bd1 17 #include "ns_types.h"
ram54288 0:dbad57390bd1 18 #include "platform/arm_hal_interrupt.h"
ram54288 0:dbad57390bd1 19 #include "nanostack/platform/arm_hal_phy.h"
ram54288 0:dbad57390bd1 20 #include "toolchain.h"
ram54288 0:dbad57390bd1 21 #include <string.h>
ram54288 0:dbad57390bd1 22
ram54288 0:dbad57390bd1 23 /* Freescale headers which are for C files */
ram54288 0:dbad57390bd1 24 extern "C" {
ram54288 0:dbad57390bd1 25 #include "MCR20Drv.h"
ram54288 0:dbad57390bd1 26 #include "MCR20Reg.h"
ram54288 0:dbad57390bd1 27 #include "MCR20Overwrites.h"
ram54288 0:dbad57390bd1 28 }
ram54288 0:dbad57390bd1 29
ram54288 0:dbad57390bd1 30
ram54288 0:dbad57390bd1 31 #define RF_BUFFER_SIZE 128
ram54288 0:dbad57390bd1 32
ram54288 0:dbad57390bd1 33 /*Radio RX and TX state definitions*/
ram54288 0:dbad57390bd1 34 #define RFF_ON 0x01
ram54288 0:dbad57390bd1 35 #define RFF_RX 0x02
ram54288 0:dbad57390bd1 36 #define RFF_TX 0x04
ram54288 0:dbad57390bd1 37 #define RFF_CCA 0x08
ram54288 0:dbad57390bd1 38
ram54288 0:dbad57390bd1 39 #define RF_MODE_NORMAL 0
ram54288 0:dbad57390bd1 40 #define RF_MODE_SNIFFER 1
ram54288 0:dbad57390bd1 41
ram54288 0:dbad57390bd1 42 #define RF_CCA_THRESHOLD 75 /* -75 dBm */
ram54288 0:dbad57390bd1 43
ram54288 0:dbad57390bd1 44 #define RF_TX_POWER_MAX 0
ram54288 0:dbad57390bd1 45
ram54288 0:dbad57390bd1 46 /* PHY constants in symbols */
ram54288 0:dbad57390bd1 47 #define gPhyWarmUpTime_c 9
ram54288 0:dbad57390bd1 48 #define gPhySHRDuration_c 10
ram54288 0:dbad57390bd1 49 #define gPhySymbolsPerOctet_c 2
ram54288 0:dbad57390bd1 50 #define gPhyAckWaitDuration_c 54
ram54288 0:dbad57390bd1 51
ram54288 0:dbad57390bd1 52 #define gCcaED_c 0
ram54288 0:dbad57390bd1 53 #define gCcaCCA_MODE1_c 1
ram54288 0:dbad57390bd1 54
ram54288 0:dbad57390bd1 55 #define gXcvrRunState_d gXcvrPwrAutodoze_c
ram54288 0:dbad57390bd1 56 #define gXcvrLowPowerState_d gXcvrPwrHibernate_c
ram54288 0:dbad57390bd1 57
ram54288 0:dbad57390bd1 58
ram54288 0:dbad57390bd1 59 /* MCR20A XCVR states */
ram54288 0:dbad57390bd1 60 typedef enum xcvrState_tag{
ram54288 0:dbad57390bd1 61 gIdle_c,
ram54288 0:dbad57390bd1 62 gRX_c,
ram54288 0:dbad57390bd1 63 gTX_c,
ram54288 0:dbad57390bd1 64 gCCA_c,
ram54288 0:dbad57390bd1 65 gTR_c,
ram54288 0:dbad57390bd1 66 gCCCA_c,
ram54288 0:dbad57390bd1 67 }xcvrState_t;
ram54288 0:dbad57390bd1 68
ram54288 0:dbad57390bd1 69 /* MCR20A XCVR low power states */
ram54288 0:dbad57390bd1 70 typedef enum xcvrPwrMode_tag{
ram54288 0:dbad57390bd1 71 gXcvrPwrIdle_c,
ram54288 0:dbad57390bd1 72 gXcvrPwrAutodoze_c,
ram54288 0:dbad57390bd1 73 gXcvrPwrDoze_c,
ram54288 0:dbad57390bd1 74 gXcvrPwrHibernate_c
ram54288 0:dbad57390bd1 75 }xcvrPwrMode_t;
ram54288 0:dbad57390bd1 76
ram54288 0:dbad57390bd1 77
ram54288 0:dbad57390bd1 78 /*RF Part Type*/
ram54288 0:dbad57390bd1 79 typedef enum
ram54288 0:dbad57390bd1 80 {
ram54288 0:dbad57390bd1 81 FREESCALE_UNKNOW_DEV = 0,
ram54288 0:dbad57390bd1 82 FREESCALE_MCR20A
ram54288 0:dbad57390bd1 83 }rf_trx_part_e;
ram54288 0:dbad57390bd1 84
ram54288 0:dbad57390bd1 85 /*Atmel RF states*/
ram54288 0:dbad57390bd1 86 typedef enum
ram54288 0:dbad57390bd1 87 {
ram54288 0:dbad57390bd1 88 NOP = 0x00,
ram54288 0:dbad57390bd1 89 BUSY_RX = 0x01,
ram54288 0:dbad57390bd1 90 RF_TX_START = 0x02,
ram54288 0:dbad57390bd1 91 FORCE_TRX_OFF = 0x03,
ram54288 0:dbad57390bd1 92 FORCE_PLL_ON = 0x04,
ram54288 0:dbad57390bd1 93 RX_ON = 0x06,
ram54288 0:dbad57390bd1 94 TRX_OFF = 0x08,
ram54288 0:dbad57390bd1 95 PLL_ON = 0x09,
ram54288 0:dbad57390bd1 96 BUSY_RX_AACK = 0x11,
ram54288 0:dbad57390bd1 97 SLEEP = 0x0F,
ram54288 0:dbad57390bd1 98 RX_AACK_ON = 0x16,
ram54288 0:dbad57390bd1 99 TX_ARET_ON = 0x19
ram54288 0:dbad57390bd1 100 }rf_trx_states_t;
ram54288 0:dbad57390bd1 101
ram54288 0:dbad57390bd1 102 /*RF receive buffer*/
ram54288 0:dbad57390bd1 103 static uint8_t rf_buffer[RF_BUFFER_SIZE];
ram54288 0:dbad57390bd1 104
ram54288 0:dbad57390bd1 105 /* TX info */
ram54288 0:dbad57390bd1 106 static uint8_t radio_tx_power = 0x17; /* 0 dBm */
ram54288 0:dbad57390bd1 107 static uint8_t mac_tx_handle = 0;
ram54288 0:dbad57390bd1 108 static uint8_t need_ack = 0;
ram54288 0:dbad57390bd1 109 static uint16_t tx_len = 0;
ram54288 0:dbad57390bd1 110
ram54288 0:dbad57390bd1 111 /* RF driver data */
ram54288 0:dbad57390bd1 112 static xcvrState_t mPhySeqState;
ram54288 0:dbad57390bd1 113 static xcvrPwrMode_t mPwrState;
ram54288 0:dbad57390bd1 114 static phy_device_driver_s device_driver;
ram54288 0:dbad57390bd1 115 static uint8_t mStatusAndControlRegs[8];
ram54288 0:dbad57390bd1 116 static uint8_t rf_rnd = 0;
ram54288 0:dbad57390bd1 117 static int8_t rf_radio_driver_id = -1;
ram54288 0:dbad57390bd1 118 static uint8_t MAC_address[8] = {1, 2, 3, 4, 5, 6, 7, 8};
ram54288 0:dbad57390bd1 119
ram54288 0:dbad57390bd1 120 /* Driver instance handle and hardware */
ram54288 0:dbad57390bd1 121 static NanostackRfPhyMcr20a *rf = NULL;
ram54288 0:dbad57390bd1 122 static SPI *spi = NULL;
ram54288 0:dbad57390bd1 123 static DigitalOut *cs = NULL;
ram54288 0:dbad57390bd1 124 static DigitalOut *rst = NULL;
ram54288 0:dbad57390bd1 125 static InterruptIn *irq = NULL;
ram54288 0:dbad57390bd1 126 static DigitalIn *irq_pin = NULL;
ram54288 0:dbad57390bd1 127
ram54288 0:dbad57390bd1 128 /* Channel info */ /* 2405 2410 2415 2420 2425 2430 2435 2440 2445 2450 2455 2460 2465 2470 2475 2480 */
ram54288 0:dbad57390bd1 129 static const uint8_t pll_int[16] = {0x0B, 0x0B, 0x0B, 0x0B, 0x0B, 0x0B, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0D, 0x0D, 0x0D, 0x0D};
ram54288 0:dbad57390bd1 130 static const uint16_t pll_frac[16] = {0x2800, 0x5000, 0x7800, 0xA000, 0xC800, 0xF000, 0x1800, 0x4000, 0x6800, 0x9000, 0xB800, 0xE000, 0x0800, 0x3000, 0x5800, 0x8000};
ram54288 0:dbad57390bd1 131 static uint8_t rf_phy_channel = 0;
ram54288 0:dbad57390bd1 132
ram54288 0:dbad57390bd1 133 /* Channel configurations for 2.4 */
ram54288 0:dbad57390bd1 134 static const phy_rf_channel_configuration_s phy_24ghz = {2405000000U, 5000000U, 250000U, 16U, M_OQPSK};
ram54288 0:dbad57390bd1 135
ram54288 0:dbad57390bd1 136 static const phy_device_channel_page_s phy_channel_pages[] = {
ram54288 0:dbad57390bd1 137 { CHANNEL_PAGE_0, &phy_24ghz},
ram54288 0:dbad57390bd1 138 { CHANNEL_PAGE_0, NULL}
ram54288 0:dbad57390bd1 139 };
ram54288 0:dbad57390bd1 140
ram54288 0:dbad57390bd1 141
ram54288 0:dbad57390bd1 142 static rf_trx_part_e rf_radio_type_read(void);
ram54288 0:dbad57390bd1 143
ram54288 0:dbad57390bd1 144 MBED_UNUSED static void rf_ack_wait_timer_start(uint16_t slots);
ram54288 0:dbad57390bd1 145 MBED_UNUSED static void rf_ack_wait_timer_stop(void);
ram54288 0:dbad57390bd1 146 MBED_UNUSED static void rf_handle_cca_ed_done(void);
ram54288 0:dbad57390bd1 147 MBED_UNUSED static void rf_handle_tx_end(void);
ram54288 0:dbad57390bd1 148 MBED_UNUSED static void rf_handle_rx_end(void);
ram54288 0:dbad57390bd1 149 MBED_UNUSED static void rf_on(void);
ram54288 0:dbad57390bd1 150 MBED_UNUSED static void rf_receive(void);
ram54288 0:dbad57390bd1 151 MBED_UNUSED static void rf_poll_trx_state_change(rf_trx_states_t trx_state);
ram54288 0:dbad57390bd1 152 MBED_UNUSED static void rf_init(void);
ram54288 0:dbad57390bd1 153 MBED_UNUSED static void rf_set_mac_address(const uint8_t *ptr);
ram54288 0:dbad57390bd1 154 MBED_UNUSED static int8_t rf_device_register(void);
ram54288 0:dbad57390bd1 155 MBED_UNUSED static void rf_device_unregister(void);
ram54288 0:dbad57390bd1 156 MBED_UNUSED static int8_t rf_start_cca(uint8_t *data_ptr, uint16_t data_length, uint8_t tx_handle, data_protocol_e data_protocol );
ram54288 0:dbad57390bd1 157 MBED_UNUSED static void rf_cca_abort(void);
ram54288 0:dbad57390bd1 158 MBED_UNUSED static void rf_read_mac_address(uint8_t *ptr);
ram54288 0:dbad57390bd1 159 MBED_UNUSED static int8_t rf_read_random(void);
ram54288 0:dbad57390bd1 160 MBED_UNUSED static void rf_calibration_cb(void);
ram54288 0:dbad57390bd1 161 MBED_UNUSED static void rf_init_phy_mode(void);
ram54288 0:dbad57390bd1 162 MBED_UNUSED static void rf_ack_wait_timer_interrupt(void);
ram54288 0:dbad57390bd1 163 MBED_UNUSED static void rf_calibration_timer_interrupt(void);
ram54288 0:dbad57390bd1 164 MBED_UNUSED static void rf_calibration_timer_start(uint32_t slots);
ram54288 0:dbad57390bd1 165 MBED_UNUSED static void rf_cca_timer_interrupt(void);
ram54288 0:dbad57390bd1 166 MBED_UNUSED static void rf_cca_timer_start(uint32_t slots);
ram54288 0:dbad57390bd1 167 MBED_UNUSED static uint16_t rf_get_phy_mtu_size(void);
ram54288 0:dbad57390bd1 168 MBED_UNUSED static uint8_t rf_scale_lqi(int8_t rssi);
ram54288 0:dbad57390bd1 169
ram54288 0:dbad57390bd1 170 /**
ram54288 0:dbad57390bd1 171 * RF output power write
ram54288 0:dbad57390bd1 172 *
ram54288 0:dbad57390bd1 173 * \brief TX power has to be set before network start.
ram54288 0:dbad57390bd1 174 *
ram54288 0:dbad57390bd1 175 * \param power
ram54288 0:dbad57390bd1 176 * See datasheet for TX power settings
ram54288 0:dbad57390bd1 177 *
ram54288 0:dbad57390bd1 178 * \return 0, Supported Value
ram54288 0:dbad57390bd1 179 * \return -1, Not Supported Value
ram54288 0:dbad57390bd1 180 */
ram54288 0:dbad57390bd1 181 MBED_UNUSED static int8_t rf_tx_power_set(uint8_t power);
ram54288 0:dbad57390bd1 182 MBED_UNUSED static uint8_t rf_tx_power_get(void);
ram54288 0:dbad57390bd1 183 MBED_UNUSED static int8_t rf_enable_antenna_diversity(void);
ram54288 0:dbad57390bd1 184
ram54288 0:dbad57390bd1 185 /* Private functions */
ram54288 0:dbad57390bd1 186 MBED_UNUSED static void rf_abort(void);
ram54288 0:dbad57390bd1 187 MBED_UNUSED static void rf_promiscuous(uint8_t mode);
ram54288 0:dbad57390bd1 188 MBED_UNUSED static void rf_get_timestamp(uint32_t *pRetClk);
ram54288 0:dbad57390bd1 189 MBED_UNUSED static void rf_set_timeout(uint32_t *pEndTime);
ram54288 0:dbad57390bd1 190 MBED_UNUSED static void rf_set_power_state(xcvrPwrMode_t newState);
ram54288 0:dbad57390bd1 191 MBED_UNUSED static uint8_t rf_if_read_rnd(void);
ram54288 0:dbad57390bd1 192 MBED_UNUSED static uint8_t rf_convert_LQI(uint8_t hwLqi);
ram54288 0:dbad57390bd1 193 MBED_UNUSED static uint8_t rf_get_channel_energy(void);
ram54288 0:dbad57390bd1 194 MBED_UNUSED static uint8_t rf_convert_energy_level(uint8_t energyLevel);
ram54288 0:dbad57390bd1 195 MBED_UNUSED static int8_t rf_convert_LQI_to_RSSI(uint8_t lqi);
ram54288 0:dbad57390bd1 196 MBED_UNUSED static int8_t rf_interface_state_control(phy_interface_state_e new_state, uint8_t rf_channel);
ram54288 0:dbad57390bd1 197 MBED_UNUSED static int8_t rf_extension(phy_extension_type_e extension_type,uint8_t *data_ptr);
ram54288 0:dbad57390bd1 198 MBED_UNUSED static int8_t rf_address_write(phy_address_type_e address_type,uint8_t *address_ptr);
ram54288 0:dbad57390bd1 199 MBED_UNUSED static void rf_mac64_read(uint8_t *address);
ram54288 0:dbad57390bd1 200
ram54288 0:dbad57390bd1 201
ram54288 0:dbad57390bd1 202
ram54288 0:dbad57390bd1 203 /*
ram54288 0:dbad57390bd1 204 * \brief Read connected radio part.
ram54288 0:dbad57390bd1 205 *
ram54288 0:dbad57390bd1 206 * This function only return valid information when rf_init() is called
ram54288 0:dbad57390bd1 207 *
ram54288 0:dbad57390bd1 208 * \return
ram54288 0:dbad57390bd1 209 */
ram54288 0:dbad57390bd1 210 static rf_trx_part_e rf_radio_type_read(void)
ram54288 0:dbad57390bd1 211 {
ram54288 0:dbad57390bd1 212 return FREESCALE_MCR20A;
ram54288 0:dbad57390bd1 213 }
ram54288 0:dbad57390bd1 214
ram54288 0:dbad57390bd1 215 /*
ram54288 0:dbad57390bd1 216 * \brief Function initialises and registers the RF driver.
ram54288 0:dbad57390bd1 217 *
ram54288 0:dbad57390bd1 218 * \param none
ram54288 0:dbad57390bd1 219 *
ram54288 0:dbad57390bd1 220 * \return rf_radio_driver_id Driver ID given by NET library
ram54288 0:dbad57390bd1 221 */
ram54288 0:dbad57390bd1 222 static int8_t rf_device_register(void)
ram54288 0:dbad57390bd1 223 {
ram54288 0:dbad57390bd1 224 rf_trx_part_e radio_type;
ram54288 0:dbad57390bd1 225
ram54288 0:dbad57390bd1 226 rf_init();
ram54288 0:dbad57390bd1 227
ram54288 0:dbad57390bd1 228
ram54288 0:dbad57390bd1 229
ram54288 0:dbad57390bd1 230 radio_type = rf_radio_type_read();
ram54288 0:dbad57390bd1 231 if(radio_type == FREESCALE_MCR20A)
ram54288 0:dbad57390bd1 232 {
ram54288 0:dbad57390bd1 233 /*Set pointer to MAC address*/
ram54288 0:dbad57390bd1 234 device_driver.PHY_MAC = MAC_address;
ram54288 0:dbad57390bd1 235 device_driver.driver_description = (char*)"FREESCALE_MAC";
ram54288 0:dbad57390bd1 236
ram54288 0:dbad57390bd1 237 //Create setup Used Radio chips
ram54288 0:dbad57390bd1 238 /*Type of RF PHY is SubGHz*/
ram54288 0:dbad57390bd1 239 device_driver.link_type = PHY_LINK_15_4_2_4GHZ_TYPE;
ram54288 0:dbad57390bd1 240
ram54288 0:dbad57390bd1 241 device_driver.phy_channel_pages = phy_channel_pages;
ram54288 0:dbad57390bd1 242 /*Maximum size of payload is 127*/
ram54288 0:dbad57390bd1 243 device_driver.phy_MTU = 127;
ram54288 0:dbad57390bd1 244 /*No header in PHY*/
ram54288 0:dbad57390bd1 245 device_driver.phy_header_length = 0;
ram54288 0:dbad57390bd1 246 /*No tail in PHY*/
ram54288 0:dbad57390bd1 247 device_driver.phy_tail_length = 0;
ram54288 0:dbad57390bd1 248 /*Set address write function*/
ram54288 0:dbad57390bd1 249 device_driver.address_write = &rf_address_write;
ram54288 0:dbad57390bd1 250 /*Set RF extension function*/
ram54288 0:dbad57390bd1 251 device_driver.extension = &rf_extension;
ram54288 0:dbad57390bd1 252 /*Set RF state control function*/
ram54288 0:dbad57390bd1 253 device_driver.state_control = &rf_interface_state_control;
ram54288 0:dbad57390bd1 254 /*Set transmit function*/
ram54288 0:dbad57390bd1 255 device_driver.tx = &rf_start_cca;
ram54288 0:dbad57390bd1 256 /*Upper layer callbacks init to NULL*/
ram54288 0:dbad57390bd1 257 device_driver.phy_rx_cb = NULL;
ram54288 0:dbad57390bd1 258 device_driver.phy_tx_done_cb = NULL;
ram54288 0:dbad57390bd1 259 /*Virtual upper data callback init to NULL*/
ram54288 0:dbad57390bd1 260 device_driver.arm_net_virtual_rx_cb = NULL;
ram54288 0:dbad57390bd1 261 device_driver.arm_net_virtual_tx_cb = NULL;
ram54288 0:dbad57390bd1 262
ram54288 0:dbad57390bd1 263 /*Register device driver*/
ram54288 0:dbad57390bd1 264 rf_radio_driver_id = arm_net_phy_register(&device_driver);
ram54288 0:dbad57390bd1 265 }
ram54288 0:dbad57390bd1 266
ram54288 0:dbad57390bd1 267 return rf_radio_driver_id;
ram54288 0:dbad57390bd1 268 }
ram54288 0:dbad57390bd1 269
ram54288 0:dbad57390bd1 270 /*
ram54288 0:dbad57390bd1 271 * \brief Function unregisters the RF driver.
ram54288 0:dbad57390bd1 272 *
ram54288 0:dbad57390bd1 273 * \param none
ram54288 0:dbad57390bd1 274 *
ram54288 0:dbad57390bd1 275 * \return none
ram54288 0:dbad57390bd1 276 */
ram54288 0:dbad57390bd1 277 static void rf_device_unregister(void)
ram54288 0:dbad57390bd1 278 {
ram54288 0:dbad57390bd1 279 arm_net_phy_unregister(rf_radio_driver_id);
ram54288 0:dbad57390bd1 280 }
ram54288 0:dbad57390bd1 281
ram54288 0:dbad57390bd1 282 /*
ram54288 0:dbad57390bd1 283 * \brief Function returns the generated 8-bit random value for seeding Pseudo-random generator.
ram54288 0:dbad57390bd1 284 *
ram54288 0:dbad57390bd1 285 * \param none
ram54288 0:dbad57390bd1 286 *
ram54288 0:dbad57390bd1 287 * \return random value
ram54288 0:dbad57390bd1 288 */
ram54288 0:dbad57390bd1 289 static int8_t rf_read_random(void)
ram54288 0:dbad57390bd1 290 {
ram54288 0:dbad57390bd1 291 return rf_rnd;
ram54288 0:dbad57390bd1 292 }
ram54288 0:dbad57390bd1 293
ram54288 0:dbad57390bd1 294 /*
ram54288 0:dbad57390bd1 295 * \brief Function is a call back for ACK wait timeout.
ram54288 0:dbad57390bd1 296 *
ram54288 0:dbad57390bd1 297 * \param none
ram54288 0:dbad57390bd1 298 *
ram54288 0:dbad57390bd1 299 * \return none
ram54288 0:dbad57390bd1 300 */
ram54288 0:dbad57390bd1 301 static void rf_ack_wait_timer_interrupt(void)
ram54288 0:dbad57390bd1 302 {
ram54288 0:dbad57390bd1 303 /* The packet was transmitted successfully, but no ACK was received */
ram54288 0:dbad57390bd1 304 if (device_driver.phy_tx_done_cb) {
ram54288 0:dbad57390bd1 305 device_driver.phy_tx_done_cb(rf_radio_driver_id, mac_tx_handle, PHY_LINK_TX_SUCCESS, 1, 1);
ram54288 0:dbad57390bd1 306 }
ram54288 0:dbad57390bd1 307 rf_receive();
ram54288 0:dbad57390bd1 308 }
ram54288 0:dbad57390bd1 309
ram54288 0:dbad57390bd1 310 /*
ram54288 0:dbad57390bd1 311 * \brief Function is a call back for calibration interval timer.
ram54288 0:dbad57390bd1 312 *
ram54288 0:dbad57390bd1 313 * \param none
ram54288 0:dbad57390bd1 314 *
ram54288 0:dbad57390bd1 315 * \return none
ram54288 0:dbad57390bd1 316 */
ram54288 0:dbad57390bd1 317 static void rf_calibration_timer_interrupt(void)
ram54288 0:dbad57390bd1 318 {
ram54288 0:dbad57390bd1 319 }
ram54288 0:dbad57390bd1 320
ram54288 0:dbad57390bd1 321 /*
ram54288 0:dbad57390bd1 322 * \brief Function is a call back for cca interval timer.
ram54288 0:dbad57390bd1 323 *
ram54288 0:dbad57390bd1 324 * \param none
ram54288 0:dbad57390bd1 325 *
ram54288 0:dbad57390bd1 326 * \return none
ram54288 0:dbad57390bd1 327 */
ram54288 0:dbad57390bd1 328 static void rf_cca_timer_interrupt(void)
ram54288 0:dbad57390bd1 329 {
ram54288 0:dbad57390bd1 330 /* CCA time-out handled by Hardware */
ram54288 0:dbad57390bd1 331 }
ram54288 0:dbad57390bd1 332
ram54288 0:dbad57390bd1 333
ram54288 0:dbad57390bd1 334 /*
ram54288 0:dbad57390bd1 335 * \brief Function starts the ACK wait time-out.
ram54288 0:dbad57390bd1 336 *
ram54288 0:dbad57390bd1 337 * \param slots The ACK wait time-out in [symbols]
ram54288 0:dbad57390bd1 338 *
ram54288 0:dbad57390bd1 339 * \return none
ram54288 0:dbad57390bd1 340 */
ram54288 0:dbad57390bd1 341 static void rf_ack_wait_timer_start(uint16_t time)
ram54288 0:dbad57390bd1 342 {
ram54288 0:dbad57390bd1 343 uint32_t timeout;
ram54288 0:dbad57390bd1 344
ram54288 0:dbad57390bd1 345 rf_get_timestamp(&timeout);
ram54288 0:dbad57390bd1 346 timeout += time;
ram54288 0:dbad57390bd1 347 rf_set_timeout(&timeout);
ram54288 0:dbad57390bd1 348 }
ram54288 0:dbad57390bd1 349
ram54288 0:dbad57390bd1 350 /*
ram54288 0:dbad57390bd1 351 * \brief Function starts the calibration interval.
ram54288 0:dbad57390bd1 352 *
ram54288 0:dbad57390bd1 353 * \param slots Given slots, resolution 50us
ram54288 0:dbad57390bd1 354 *
ram54288 0:dbad57390bd1 355 * \return none
ram54288 0:dbad57390bd1 356 */
ram54288 0:dbad57390bd1 357 static void rf_calibration_timer_start(uint32_t slots)
ram54288 0:dbad57390bd1 358 {
ram54288 0:dbad57390bd1 359 (void)slots;
ram54288 0:dbad57390bd1 360 }
ram54288 0:dbad57390bd1 361
ram54288 0:dbad57390bd1 362 /*
ram54288 0:dbad57390bd1 363 * \brief Function starts the CCA timout.
ram54288 0:dbad57390bd1 364 *
ram54288 0:dbad57390bd1 365 * \param slots Given slots, resolution 50us
ram54288 0:dbad57390bd1 366 *
ram54288 0:dbad57390bd1 367 * \return none
ram54288 0:dbad57390bd1 368 */
ram54288 0:dbad57390bd1 369 static void rf_cca_timer_start(uint32_t slots)
ram54288 0:dbad57390bd1 370 {
ram54288 0:dbad57390bd1 371 (void)slots;
ram54288 0:dbad57390bd1 372 }
ram54288 0:dbad57390bd1 373
ram54288 0:dbad57390bd1 374 /*
ram54288 0:dbad57390bd1 375 * \brief Function stops the ACK wait timeout.
ram54288 0:dbad57390bd1 376 *
ram54288 0:dbad57390bd1 377 * \param none
ram54288 0:dbad57390bd1 378 *
ram54288 0:dbad57390bd1 379 * \return none
ram54288 0:dbad57390bd1 380 */
ram54288 0:dbad57390bd1 381 static void rf_ack_wait_timer_stop(void)
ram54288 0:dbad57390bd1 382 {
ram54288 0:dbad57390bd1 383 }
ram54288 0:dbad57390bd1 384
ram54288 0:dbad57390bd1 385 /*
ram54288 0:dbad57390bd1 386 * \brief Function reads the MAC address array.
ram54288 0:dbad57390bd1 387 *
ram54288 0:dbad57390bd1 388 * \param ptr Pointer to read array
ram54288 0:dbad57390bd1 389 *
ram54288 0:dbad57390bd1 390 * \return none
ram54288 0:dbad57390bd1 391 */
ram54288 0:dbad57390bd1 392 static void rf_read_mac_address(uint8_t *ptr)
ram54288 0:dbad57390bd1 393 {
ram54288 0:dbad57390bd1 394 memcpy(ptr, MAC_address, 8);
ram54288 0:dbad57390bd1 395 }
ram54288 0:dbad57390bd1 396
ram54288 0:dbad57390bd1 397 /*
ram54288 0:dbad57390bd1 398 * \brief Function sets the MAC address array.
ram54288 0:dbad57390bd1 399 *
ram54288 0:dbad57390bd1 400 * \param ptr Pointer to given MAC address array
ram54288 0:dbad57390bd1 401 *
ram54288 0:dbad57390bd1 402 * \return none
ram54288 0:dbad57390bd1 403 */
ram54288 0:dbad57390bd1 404 static void rf_set_mac_address(const uint8_t *ptr)
ram54288 0:dbad57390bd1 405 {
ram54288 0:dbad57390bd1 406 memcpy(MAC_address, ptr, 8);
ram54288 0:dbad57390bd1 407 }
ram54288 0:dbad57390bd1 408
ram54288 0:dbad57390bd1 409 static uint16_t rf_get_phy_mtu_size(void)
ram54288 0:dbad57390bd1 410 {
ram54288 0:dbad57390bd1 411 return device_driver.phy_MTU;
ram54288 0:dbad57390bd1 412 }
ram54288 0:dbad57390bd1 413
ram54288 0:dbad57390bd1 414 /*
ram54288 0:dbad57390bd1 415 * \brief Function writes 16-bit address in RF address filter.
ram54288 0:dbad57390bd1 416 *
ram54288 0:dbad57390bd1 417 * \param short_address Given short address
ram54288 0:dbad57390bd1 418 *
ram54288 0:dbad57390bd1 419 * \return none
ram54288 0:dbad57390bd1 420 */
ram54288 0:dbad57390bd1 421 static void rf_set_short_adr(uint8_t * short_address)
ram54288 0:dbad57390bd1 422 {
ram54288 0:dbad57390bd1 423 /* Write one register at a time to be accessible from hibernate mode */
ram54288 0:dbad57390bd1 424 MCR20Drv_IndirectAccessSPIWrite(MACSHORTADDRS0_MSB, short_address[0]);
ram54288 0:dbad57390bd1 425 MCR20Drv_IndirectAccessSPIWrite(MACSHORTADDRS0_LSB, short_address[1]);
ram54288 0:dbad57390bd1 426 }
ram54288 0:dbad57390bd1 427
ram54288 0:dbad57390bd1 428 /*
ram54288 0:dbad57390bd1 429 * \brief Function writes PAN Id in RF PAN Id filter.
ram54288 0:dbad57390bd1 430 *
ram54288 0:dbad57390bd1 431 * \param pan_id Given PAN Id
ram54288 0:dbad57390bd1 432 *
ram54288 0:dbad57390bd1 433 * \return none
ram54288 0:dbad57390bd1 434 */
ram54288 0:dbad57390bd1 435 static void rf_set_pan_id(uint8_t *pan_id)
ram54288 0:dbad57390bd1 436 {
ram54288 0:dbad57390bd1 437 /* Write one register at a time to be accessible from hibernate mode */
ram54288 0:dbad57390bd1 438 MCR20Drv_IndirectAccessSPIWrite(MACPANID0_MSB, pan_id[0]);
ram54288 0:dbad57390bd1 439 MCR20Drv_IndirectAccessSPIWrite(MACPANID0_LSB, pan_id[1]);
ram54288 0:dbad57390bd1 440 }
ram54288 0:dbad57390bd1 441
ram54288 0:dbad57390bd1 442 /*
ram54288 0:dbad57390bd1 443 * \brief Function writes 64-bit address in RF address filter.
ram54288 0:dbad57390bd1 444 *
ram54288 0:dbad57390bd1 445 * \param address Given 64-bit address
ram54288 0:dbad57390bd1 446 *
ram54288 0:dbad57390bd1 447 * \return none
ram54288 0:dbad57390bd1 448 */
ram54288 0:dbad57390bd1 449 static void rf_set_address(uint8_t *address)
ram54288 0:dbad57390bd1 450 {
ram54288 0:dbad57390bd1 451 /* Write one register at a time to be accessible from hibernate mode */
ram54288 0:dbad57390bd1 452 MCR20Drv_IndirectAccessSPIWrite(MACLONGADDRS0_0, address[7]);
ram54288 0:dbad57390bd1 453 MCR20Drv_IndirectAccessSPIWrite(MACLONGADDRS0_8, address[6]);
ram54288 0:dbad57390bd1 454 MCR20Drv_IndirectAccessSPIWrite(MACLONGADDRS0_16, address[5]);
ram54288 0:dbad57390bd1 455 MCR20Drv_IndirectAccessSPIWrite(MACLONGADDRS0_24, address[4]);
ram54288 0:dbad57390bd1 456 MCR20Drv_IndirectAccessSPIWrite(MACLONGADDRS0_32, address[3]);
ram54288 0:dbad57390bd1 457 MCR20Drv_IndirectAccessSPIWrite(MACLONGADDRS0_40, address[2]);
ram54288 0:dbad57390bd1 458 MCR20Drv_IndirectAccessSPIWrite(MACLONGADDRS0_48, address[1]);
ram54288 0:dbad57390bd1 459 MCR20Drv_IndirectAccessSPIWrite(MACLONGADDRS0_56, address[0]);
ram54288 0:dbad57390bd1 460 }
ram54288 0:dbad57390bd1 461
ram54288 0:dbad57390bd1 462 /*
ram54288 0:dbad57390bd1 463 * \brief Function sets the RF channel.
ram54288 0:dbad57390bd1 464 *
ram54288 0:dbad57390bd1 465 * \param ch New channel
ram54288 0:dbad57390bd1 466 *
ram54288 0:dbad57390bd1 467 * \return none
ram54288 0:dbad57390bd1 468 */
ram54288 0:dbad57390bd1 469 static void rf_channel_set(uint8_t channel)
ram54288 0:dbad57390bd1 470 {
ram54288 0:dbad57390bd1 471 rf_phy_channel = channel;
ram54288 0:dbad57390bd1 472 MCR20Drv_DirectAccessSPIWrite(PLL_INT0, pll_int[channel - 11]);
ram54288 0:dbad57390bd1 473 MCR20Drv_DirectAccessSPIMultiByteWrite(PLL_FRAC0_LSB, (uint8_t *) &pll_frac[channel - 11], 2);
ram54288 0:dbad57390bd1 474 }
ram54288 0:dbad57390bd1 475
ram54288 0:dbad57390bd1 476
ram54288 0:dbad57390bd1 477 /*
ram54288 0:dbad57390bd1 478 * \brief Function initialises the radio driver and resets the radio.
ram54288 0:dbad57390bd1 479 *
ram54288 0:dbad57390bd1 480 * \param none
ram54288 0:dbad57390bd1 481 *
ram54288 0:dbad57390bd1 482 * \return none
ram54288 0:dbad57390bd1 483 */
ram54288 0:dbad57390bd1 484 static void rf_init(void)
ram54288 0:dbad57390bd1 485 {
ram54288 0:dbad57390bd1 486 uint32_t index;
ram54288 0:dbad57390bd1 487 mPhySeqState = gIdle_c;
ram54288 0:dbad57390bd1 488 mPwrState = gXcvrPwrIdle_c;
ram54288 0:dbad57390bd1 489 /*Reset RF module*/
ram54288 0:dbad57390bd1 490 MCR20Drv_RESET();
ram54288 0:dbad57390bd1 491 /* Initialize the transceiver SPI driver */
ram54288 0:dbad57390bd1 492 MCR20Drv_Init();
ram54288 0:dbad57390bd1 493 /* Disable Tristate on MISO for SPI reads */
ram54288 0:dbad57390bd1 494 MCR20Drv_IndirectAccessSPIWrite(MISC_PAD_CTRL, 0x02);
ram54288 0:dbad57390bd1 495 /* Set XCVR clock output settings */
ram54288 0:dbad57390bd1 496 MCR20Drv_Set_CLK_OUT_Freq(gMCR20_ClkOutFreq_d);
ram54288 0:dbad57390bd1 497 /* Set default XCVR power state */
ram54288 0:dbad57390bd1 498 rf_set_power_state(gXcvrRunState_d);
ram54288 0:dbad57390bd1 499
ram54288 0:dbad57390bd1 500 /* PHY_CTRL1 default HW settings + AUTOACK enabled */
ram54288 0:dbad57390bd1 501 mStatusAndControlRegs[PHY_CTRL1] = cPHY_CTRL1_AUTOACK;
ram54288 0:dbad57390bd1 502 /* PHY_CTRL2 : mask all PP interrupts */
ram54288 0:dbad57390bd1 503 mStatusAndControlRegs[PHY_CTRL2] = cPHY_CTRL2_CRC_MSK | \
ram54288 0:dbad57390bd1 504 cPHY_CTRL2_PLL_UNLOCK_MSK | \
ram54288 0:dbad57390bd1 505 /*cPHY_CTRL2_FILTERFAIL_MSK | */ \
ram54288 0:dbad57390bd1 506 cPHY_CTRL2_RX_WMRK_MSK | \
ram54288 0:dbad57390bd1 507 cPHY_CTRL2_CCAMSK | \
ram54288 0:dbad57390bd1 508 cPHY_CTRL2_RXMSK | \
ram54288 0:dbad57390bd1 509 cPHY_CTRL2_TXMSK | \
ram54288 0:dbad57390bd1 510 cPHY_CTRL2_SEQMSK;
ram54288 0:dbad57390bd1 511 /* PHY_CTRL3 : enable timer 3 and disable remaining interrupts */
ram54288 0:dbad57390bd1 512 mStatusAndControlRegs[PHY_CTRL3] = cPHY_CTRL3_ASM_MSK | \
ram54288 0:dbad57390bd1 513 cPHY_CTRL3_PB_ERR_MSK | \
ram54288 0:dbad57390bd1 514 cPHY_CTRL3_WAKE_MSK | \
ram54288 0:dbad57390bd1 515 cPHY_CTRL3_TMR3CMP_EN;
ram54288 0:dbad57390bd1 516 /* PHY_CTRL4 unmask global TRX interrupts, enable 16 bit mode for TC2 - TC2 prime EN */
ram54288 0:dbad57390bd1 517 mStatusAndControlRegs[PHY_CTRL4] = cPHY_CTRL4_TC2PRIME_EN | (gCcaCCA_MODE1_c << cPHY_CTRL4_CCATYPE_Shift_c);
ram54288 0:dbad57390bd1 518 /* Clear all PP IRQ bits to avoid unexpected interrupts immediately after initialization */
ram54288 0:dbad57390bd1 519 mStatusAndControlRegs[IRQSTS1] = cIRQSTS1_PLL_UNLOCK_IRQ | \
ram54288 0:dbad57390bd1 520 cIRQSTS1_FILTERFAIL_IRQ | \
ram54288 0:dbad57390bd1 521 cIRQSTS1_RXWTRMRKIRQ | \
ram54288 0:dbad57390bd1 522 cIRQSTS1_CCAIRQ | \
ram54288 0:dbad57390bd1 523 cIRQSTS1_RXIRQ | \
ram54288 0:dbad57390bd1 524 cIRQSTS1_TXIRQ | \
ram54288 0:dbad57390bd1 525 cIRQSTS1_SEQIRQ;
ram54288 0:dbad57390bd1 526
ram54288 0:dbad57390bd1 527 mStatusAndControlRegs[IRQSTS2] = cIRQSTS2_ASM_IRQ | cIRQSTS2_PB_ERR_IRQ | cIRQSTS2_WAKE_IRQ;
ram54288 0:dbad57390bd1 528 /* Mask and clear all TMR IRQs */
ram54288 0:dbad57390bd1 529 mStatusAndControlRegs[IRQSTS3] = cIRQSTS3_TMR4MSK | cIRQSTS3_TMR3MSK | cIRQSTS3_TMR2MSK | cIRQSTS3_TMR1MSK | \
ram54288 0:dbad57390bd1 530 cIRQSTS3_TMR4IRQ | cIRQSTS3_TMR3IRQ | cIRQSTS3_TMR2IRQ | cIRQSTS3_TMR1IRQ;
ram54288 0:dbad57390bd1 531 /* Write settings to XCVR */
ram54288 0:dbad57390bd1 532 MCR20Drv_DirectAccessSPIMultiByteWrite(PHY_CTRL1, &mStatusAndControlRegs[PHY_CTRL1], 5);
ram54288 0:dbad57390bd1 533 /* Clear all interrupts */
ram54288 0:dbad57390bd1 534 MCR20Drv_DirectAccessSPIMultiByteWrite(IRQSTS1, &mStatusAndControlRegs[IRQSTS1], 3);
ram54288 0:dbad57390bd1 535
ram54288 0:dbad57390bd1 536 /* RX_FRAME_FILTER. Accept FrameVersion 0 and 1 packets, reject all others */
ram54288 0:dbad57390bd1 537 MCR20Drv_IndirectAccessSPIWrite(RX_FRAME_FILTER, (cRX_FRAME_FLT_FRM_VER | \
ram54288 0:dbad57390bd1 538 cRX_FRAME_FLT_BEACON_FT | \
ram54288 0:dbad57390bd1 539 cRX_FRAME_FLT_DATA_FT | \
ram54288 0:dbad57390bd1 540 cRX_FRAME_FLT_CMD_FT ));
ram54288 0:dbad57390bd1 541 /* Direct register overwrites */
ram54288 0:dbad57390bd1 542 for (index = 0; index < sizeof(overwrites_direct)/sizeof(overwrites_t); index++)
ram54288 0:dbad57390bd1 543 MCR20Drv_DirectAccessSPIWrite(overwrites_direct[index].address, overwrites_direct[index].data);
ram54288 0:dbad57390bd1 544 /* Indirect register overwrites */
ram54288 0:dbad57390bd1 545 for (index = 0; index < sizeof(overwrites_indirect)/sizeof(overwrites_t); index++)
ram54288 0:dbad57390bd1 546 MCR20Drv_IndirectAccessSPIWrite(overwrites_indirect[index].address, overwrites_indirect[index].data);
ram54288 0:dbad57390bd1 547
ram54288 0:dbad57390bd1 548 /* Set the CCA energy threshold value */
ram54288 0:dbad57390bd1 549 MCR20Drv_IndirectAccessSPIWrite(CCA1_THRESH, RF_CCA_THRESHOLD);
ram54288 0:dbad57390bd1 550 /* Set prescaller to obtain 1 symbol (16us) timebase */
ram54288 0:dbad57390bd1 551 MCR20Drv_IndirectAccessSPIWrite(TMR_PRESCALE, 0x05);
ram54288 0:dbad57390bd1 552
ram54288 0:dbad57390bd1 553 MCR20Drv_IRQ_Enable();
ram54288 0:dbad57390bd1 554
ram54288 0:dbad57390bd1 555 /*Read random variable. This will be used when seeding pseudo-random generator*/
ram54288 0:dbad57390bd1 556 rf_rnd = rf_if_read_rnd();
ram54288 0:dbad57390bd1 557 /*Read eui64*/
ram54288 0:dbad57390bd1 558 rf_mac64_read(MAC_address);
ram54288 0:dbad57390bd1 559 /*set default channel to 11*/
ram54288 0:dbad57390bd1 560 rf_channel_set(11);
ram54288 0:dbad57390bd1 561 /*Start receiver*/
ram54288 0:dbad57390bd1 562 rf_receive();
ram54288 0:dbad57390bd1 563 }
ram54288 0:dbad57390bd1 564
ram54288 0:dbad57390bd1 565 /**
ram54288 0:dbad57390bd1 566 * \brief Function gets called when MAC is setting radio off.
ram54288 0:dbad57390bd1 567 *
ram54288 0:dbad57390bd1 568 * \param none
ram54288 0:dbad57390bd1 569 *
ram54288 0:dbad57390bd1 570 * \return none
ram54288 0:dbad57390bd1 571 */
ram54288 0:dbad57390bd1 572 static void rf_off(void)
ram54288 0:dbad57390bd1 573 {
ram54288 0:dbad57390bd1 574 /* Abort any ongoing sequences */
ram54288 0:dbad57390bd1 575 rf_abort();
ram54288 0:dbad57390bd1 576 /* Set XCVR in a low power state */
ram54288 0:dbad57390bd1 577 rf_set_power_state(gXcvrLowPowerState_d);
ram54288 0:dbad57390bd1 578 }
ram54288 0:dbad57390bd1 579
ram54288 0:dbad57390bd1 580 /*
ram54288 0:dbad57390bd1 581 * \brief Function polls the RF state until it has changed to desired state.
ram54288 0:dbad57390bd1 582 *
ram54288 0:dbad57390bd1 583 * \param trx_state RF state
ram54288 0:dbad57390bd1 584 *
ram54288 0:dbad57390bd1 585 * \return none
ram54288 0:dbad57390bd1 586 */
ram54288 0:dbad57390bd1 587 static void rf_poll_trx_state_change(rf_trx_states_t trx_state)
ram54288 0:dbad57390bd1 588 {
ram54288 0:dbad57390bd1 589 (void)trx_state;
ram54288 0:dbad57390bd1 590 }
ram54288 0:dbad57390bd1 591
ram54288 0:dbad57390bd1 592 /*
ram54288 0:dbad57390bd1 593 * \brief Function starts the CCA process before starting data transmission and copies the data to RF TX FIFO.
ram54288 0:dbad57390bd1 594 *
ram54288 0:dbad57390bd1 595 * \param data_ptr Pointer to TX data
ram54288 0:dbad57390bd1 596 * \param data_length Length of the TX data
ram54288 0:dbad57390bd1 597 * \param tx_handle Handle to transmission
ram54288 0:dbad57390bd1 598 * \return 0 Success
ram54288 0:dbad57390bd1 599 * \return -1 Busy
ram54288 0:dbad57390bd1 600 */
ram54288 0:dbad57390bd1 601 static int8_t rf_start_cca(uint8_t *data_ptr, uint16_t data_length, uint8_t tx_handle, data_protocol_e data_protocol )
ram54288 0:dbad57390bd1 602 {
ram54288 0:dbad57390bd1 603 uint8_t ccaMode;
ram54288 0:dbad57390bd1 604
ram54288 0:dbad57390bd1 605 /* Parameter validation */
ram54288 0:dbad57390bd1 606 if( !data_ptr || (data_length > 125) || (PHY_LAYER_PAYLOAD != data_protocol) )
ram54288 0:dbad57390bd1 607 {
ram54288 0:dbad57390bd1 608 return -1;
ram54288 0:dbad57390bd1 609 }
ram54288 0:dbad57390bd1 610
ram54288 0:dbad57390bd1 611 if( mPhySeqState == gRX_c )
ram54288 0:dbad57390bd1 612 {
ram54288 0:dbad57390bd1 613 uint8_t phyReg = MCR20Drv_DirectAccessSPIRead(SEQ_STATE) & 0x1F;
ram54288 0:dbad57390bd1 614 /* Check for an Rx in progress. */
ram54288 0:dbad57390bd1 615 if((phyReg <= 0x06) || (phyReg == 0x15) || (phyReg == 0x16))
ram54288 0:dbad57390bd1 616 {
ram54288 0:dbad57390bd1 617 if (device_driver.phy_tx_done_cb) {
ram54288 0:dbad57390bd1 618 device_driver.phy_tx_done_cb(rf_radio_driver_id, mac_tx_handle, PHY_LINK_CCA_FAIL, 1, 1);
ram54288 0:dbad57390bd1 619 }
ram54288 0:dbad57390bd1 620 return -1;
ram54288 0:dbad57390bd1 621 }
ram54288 0:dbad57390bd1 622 rf_abort();
ram54288 0:dbad57390bd1 623 }
ram54288 0:dbad57390bd1 624
ram54288 0:dbad57390bd1 625 /*Check if transmitter is busy*/
ram54288 0:dbad57390bd1 626 if( mPhySeqState != gIdle_c )
ram54288 0:dbad57390bd1 627 {
ram54288 0:dbad57390bd1 628 /*Return busy*/
ram54288 0:dbad57390bd1 629 return -1;
ram54288 0:dbad57390bd1 630 }
ram54288 0:dbad57390bd1 631
ram54288 0:dbad57390bd1 632 /*Store TX handle*/
ram54288 0:dbad57390bd1 633 mac_tx_handle = tx_handle;
ram54288 0:dbad57390bd1 634 /*Check if transmitted data needs to be acked*/
ram54288 0:dbad57390bd1 635 need_ack = (*data_ptr & 0x20) == 0x20;
ram54288 0:dbad57390bd1 636
ram54288 0:dbad57390bd1 637 /* Set XCVR power state in run mode */
ram54288 0:dbad57390bd1 638 rf_set_power_state(gXcvrRunState_d);
ram54288 0:dbad57390bd1 639 /* Load data into XCVR */
ram54288 0:dbad57390bd1 640 tx_len = data_length + 2;
ram54288 0:dbad57390bd1 641 MCR20Drv_PB_SPIBurstWrite(data_ptr - 1, data_length + 1);
ram54288 0:dbad57390bd1 642 MCR20Drv_PB_SPIByteWrite(0,tx_len);
ram54288 0:dbad57390bd1 643
ram54288 0:dbad57390bd1 644 /* Set CCA mode 1 */
ram54288 0:dbad57390bd1 645 ccaMode = (mStatusAndControlRegs[PHY_CTRL4] >> cPHY_CTRL4_CCATYPE_Shift_c) & cPHY_CTRL4_CCATYPE;
ram54288 0:dbad57390bd1 646 if( ccaMode != gCcaCCA_MODE1_c )
ram54288 0:dbad57390bd1 647 {
ram54288 0:dbad57390bd1 648 mStatusAndControlRegs[PHY_CTRL4] &= ~(cPHY_CTRL4_CCATYPE << cPHY_CTRL4_CCATYPE_Shift_c);
ram54288 0:dbad57390bd1 649 mStatusAndControlRegs[PHY_CTRL4] |= gCcaCCA_MODE1_c << cPHY_CTRL4_CCATYPE_Shift_c;
ram54288 0:dbad57390bd1 650 MCR20Drv_DirectAccessSPIWrite(PHY_CTRL4, mStatusAndControlRegs[PHY_CTRL4]);
ram54288 0:dbad57390bd1 651 }
ram54288 0:dbad57390bd1 652
ram54288 0:dbad57390bd1 653 /* Read XCVR registers */
ram54288 0:dbad57390bd1 654 mStatusAndControlRegs[0] = MCR20Drv_DirectAccessSPIMultiByteRead(IRQSTS2, &mStatusAndControlRegs[1], 4);
ram54288 0:dbad57390bd1 655 mStatusAndControlRegs[PHY_CTRL1] &= ~(cPHY_CTRL1_XCVSEQ);
ram54288 0:dbad57390bd1 656 mStatusAndControlRegs[PHY_CTRL1] |= gCCA_c;
ram54288 0:dbad57390bd1 657 mPhySeqState = gCCA_c;
ram54288 0:dbad57390bd1 658
ram54288 0:dbad57390bd1 659 /* Ensure that no spurious interrupts are raised */
ram54288 0:dbad57390bd1 660 mStatusAndControlRegs[IRQSTS3] &= 0xF0; /* do not change other IRQ status */
ram54288 0:dbad57390bd1 661 mStatusAndControlRegs[IRQSTS3] |= (cIRQSTS3_TMR3MSK | cIRQSTS3_TMR3IRQ);
ram54288 0:dbad57390bd1 662 MCR20Drv_DirectAccessSPIMultiByteWrite(IRQSTS1, mStatusAndControlRegs, 3);
ram54288 0:dbad57390bd1 663
ram54288 0:dbad57390bd1 664 /* Write XCVR settings */
ram54288 0:dbad57390bd1 665 MCR20Drv_DirectAccessSPIWrite(PHY_CTRL1, mStatusAndControlRegs[PHY_CTRL1]);
ram54288 0:dbad57390bd1 666
ram54288 0:dbad57390bd1 667 /* Unmask SEQ interrupt */
ram54288 0:dbad57390bd1 668 mStatusAndControlRegs[PHY_CTRL2] &= ~(cPHY_CTRL2_SEQMSK);
ram54288 0:dbad57390bd1 669 MCR20Drv_DirectAccessSPIWrite(PHY_CTRL2, mStatusAndControlRegs[PHY_CTRL2]);
ram54288 0:dbad57390bd1 670
ram54288 0:dbad57390bd1 671 /*Return success*/
ram54288 0:dbad57390bd1 672 return 0;
ram54288 0:dbad57390bd1 673 }
ram54288 0:dbad57390bd1 674
ram54288 0:dbad57390bd1 675 /*
ram54288 0:dbad57390bd1 676 * \brief Function aborts CCA process.
ram54288 0:dbad57390bd1 677 *
ram54288 0:dbad57390bd1 678 * \param none
ram54288 0:dbad57390bd1 679 *
ram54288 0:dbad57390bd1 680 * \return none
ram54288 0:dbad57390bd1 681 */
ram54288 0:dbad57390bd1 682 static void rf_cca_abort(void)
ram54288 0:dbad57390bd1 683 {
ram54288 0:dbad57390bd1 684 rf_abort();
ram54288 0:dbad57390bd1 685 }
ram54288 0:dbad57390bd1 686
ram54288 0:dbad57390bd1 687 /*
ram54288 0:dbad57390bd1 688 * \brief Function starts the transmission of the frame. Called from ISR context!
ram54288 0:dbad57390bd1 689 *
ram54288 0:dbad57390bd1 690 * \param none
ram54288 0:dbad57390bd1 691 *
ram54288 0:dbad57390bd1 692 * \return none
ram54288 0:dbad57390bd1 693 */
ram54288 0:dbad57390bd1 694 static void rf_start_tx(void)
ram54288 0:dbad57390bd1 695 {
ram54288 0:dbad57390bd1 696 /* Perform TxRxAck sequence if required by phyTxMode */
ram54288 0:dbad57390bd1 697 if( need_ack )
ram54288 0:dbad57390bd1 698 {
ram54288 0:dbad57390bd1 699 mStatusAndControlRegs[PHY_CTRL1] |= cPHY_CTRL1_RXACKRQD;
ram54288 0:dbad57390bd1 700 mPhySeqState = gTR_c;
ram54288 0:dbad57390bd1 701 }
ram54288 0:dbad57390bd1 702 else
ram54288 0:dbad57390bd1 703 {
ram54288 0:dbad57390bd1 704 mStatusAndControlRegs[PHY_CTRL1] &= ~(cPHY_CTRL1_RXACKRQD);
ram54288 0:dbad57390bd1 705 mPhySeqState = gTX_c;
ram54288 0:dbad57390bd1 706 }
ram54288 0:dbad57390bd1 707
ram54288 0:dbad57390bd1 708 mStatusAndControlRegs[PHY_CTRL1] &= ~(cPHY_CTRL1_XCVSEQ);
ram54288 0:dbad57390bd1 709 mStatusAndControlRegs[PHY_CTRL1] |= mPhySeqState;
ram54288 0:dbad57390bd1 710
ram54288 0:dbad57390bd1 711 /* Unmask SEQ interrupt */
ram54288 0:dbad57390bd1 712 mStatusAndControlRegs[PHY_CTRL2] &= ~(cPHY_CTRL2_SEQMSK);
ram54288 0:dbad57390bd1 713
ram54288 0:dbad57390bd1 714 /* Start the sequence immediately */
ram54288 0:dbad57390bd1 715 MCR20Drv_DirectAccessSPIMultiByteWrite(PHY_CTRL1, &mStatusAndControlRegs[PHY_CTRL1], 2);
ram54288 0:dbad57390bd1 716
ram54288 0:dbad57390bd1 717 if( need_ack )
ram54288 0:dbad57390bd1 718 {
ram54288 0:dbad57390bd1 719 rf_ack_wait_timer_start(gPhyWarmUpTime_c + gPhySHRDuration_c + tx_len * gPhySymbolsPerOctet_c + gPhyAckWaitDuration_c);
ram54288 0:dbad57390bd1 720 }
ram54288 0:dbad57390bd1 721 }
ram54288 0:dbad57390bd1 722
ram54288 0:dbad57390bd1 723 /*
ram54288 0:dbad57390bd1 724 * \brief Function sets the RF in RX state. Called from ISR context!
ram54288 0:dbad57390bd1 725 *
ram54288 0:dbad57390bd1 726 * \param none
ram54288 0:dbad57390bd1 727 *
ram54288 0:dbad57390bd1 728 * \return none
ram54288 0:dbad57390bd1 729 */
ram54288 0:dbad57390bd1 730 static void rf_receive(void)
ram54288 0:dbad57390bd1 731 {
ram54288 0:dbad57390bd1 732 uint8_t phyRegs[5];
ram54288 0:dbad57390bd1 733
ram54288 0:dbad57390bd1 734 /* RX can start only from Idle state */
ram54288 0:dbad57390bd1 735 if( mPhySeqState != gIdle_c )
ram54288 0:dbad57390bd1 736 {
ram54288 0:dbad57390bd1 737 return;
ram54288 0:dbad57390bd1 738 }
ram54288 0:dbad57390bd1 739
ram54288 0:dbad57390bd1 740 /* Set XCVR power state in run mode */
ram54288 0:dbad57390bd1 741 rf_set_power_state(gXcvrRunState_d);
ram54288 0:dbad57390bd1 742 /* read XVCR settings */
ram54288 0:dbad57390bd1 743 phyRegs[IRQSTS1] = MCR20Drv_DirectAccessSPIMultiByteRead(IRQSTS2, &phyRegs[IRQSTS2], 4);
ram54288 0:dbad57390bd1 744 /* unmask SEQ interrupt */
ram54288 0:dbad57390bd1 745 phyRegs[PHY_CTRL2] &= ~(cPHY_CTRL2_SEQMSK);
ram54288 0:dbad57390bd1 746 /* set XcvrSeq to RX */
ram54288 0:dbad57390bd1 747 phyRegs[PHY_CTRL1] &= ~(cPHY_CTRL1_XCVSEQ);
ram54288 0:dbad57390bd1 748 phyRegs[PHY_CTRL1] |= gRX_c;
ram54288 0:dbad57390bd1 749 mPhySeqState = gRX_c;
ram54288 0:dbad57390bd1 750 /* Ensure that no spurious interrupts are raised */
ram54288 0:dbad57390bd1 751 phyRegs[IRQSTS3] &= 0xF0; /* do not change other IRQ status */
ram54288 0:dbad57390bd1 752 phyRegs[IRQSTS3] |= cIRQSTS3_TMR3MSK | cIRQSTS3_TMR3IRQ;
ram54288 0:dbad57390bd1 753 /* sync settings with XCVR */
ram54288 0:dbad57390bd1 754 MCR20Drv_DirectAccessSPIMultiByteWrite(IRQSTS1, phyRegs, 5);
ram54288 0:dbad57390bd1 755 }
ram54288 0:dbad57390bd1 756
ram54288 0:dbad57390bd1 757 /*
ram54288 0:dbad57390bd1 758 * \brief Function calibrates the radio.
ram54288 0:dbad57390bd1 759 *
ram54288 0:dbad57390bd1 760 * \param none
ram54288 0:dbad57390bd1 761 *
ram54288 0:dbad57390bd1 762 * \return none
ram54288 0:dbad57390bd1 763 */
ram54288 0:dbad57390bd1 764 static void rf_calibration_cb(void)
ram54288 0:dbad57390bd1 765 {
ram54288 0:dbad57390bd1 766 }
ram54288 0:dbad57390bd1 767
ram54288 0:dbad57390bd1 768 /*
ram54288 0:dbad57390bd1 769 * \brief Function sets RF_ON flag when radio is powered.
ram54288 0:dbad57390bd1 770 *
ram54288 0:dbad57390bd1 771 * \param none
ram54288 0:dbad57390bd1 772 *
ram54288 0:dbad57390bd1 773 * \return none
ram54288 0:dbad57390bd1 774 */
ram54288 0:dbad57390bd1 775 static void rf_on(void)
ram54288 0:dbad57390bd1 776 {
ram54288 0:dbad57390bd1 777 }
ram54288 0:dbad57390bd1 778
ram54288 0:dbad57390bd1 779 /*
ram54288 0:dbad57390bd1 780 * \brief Function is a call back for RX end interrupt.
ram54288 0:dbad57390bd1 781 *
ram54288 0:dbad57390bd1 782 * \param none
ram54288 0:dbad57390bd1 783 *
ram54288 0:dbad57390bd1 784 * \return none
ram54288 0:dbad57390bd1 785 */
ram54288 0:dbad57390bd1 786 static void rf_handle_rx_end(void)
ram54288 0:dbad57390bd1 787 {
ram54288 0:dbad57390bd1 788 uint8_t rf_lqi = MCR20Drv_DirectAccessSPIRead(LQI_VALUE);
ram54288 0:dbad57390bd1 789 int8_t rf_rssi = 0;
ram54288 0:dbad57390bd1 790 uint8_t len = mStatusAndControlRegs[RX_FRM_LEN] - 2;
ram54288 0:dbad57390bd1 791
ram54288 0:dbad57390bd1 792
ram54288 0:dbad57390bd1 793 /*Start receiver*/
ram54288 0:dbad57390bd1 794 rf_receive();
ram54288 0:dbad57390bd1 795
ram54288 0:dbad57390bd1 796 /*Check the length is valid*/
ram54288 0:dbad57390bd1 797 if(len > 1 && len < RF_BUFFER_SIZE)
ram54288 0:dbad57390bd1 798 {
ram54288 0:dbad57390bd1 799 rf_lqi = rf_convert_LQI(rf_lqi);
ram54288 0:dbad57390bd1 800 rf_rssi = rf_convert_LQI_to_RSSI(rf_lqi);
ram54288 0:dbad57390bd1 801 /*gcararu: Scale LQI using received RSSI, to match the LQI reported by the ATMEL radio */
ram54288 0:dbad57390bd1 802 rf_lqi = rf_scale_lqi(rf_rssi);
ram54288 0:dbad57390bd1 803
ram54288 0:dbad57390bd1 804 /*Read received packet*/
ram54288 0:dbad57390bd1 805 MCR20Drv_PB_SPIBurstRead(rf_buffer, len);
ram54288 0:dbad57390bd1 806 if (device_driver.phy_rx_cb) {
ram54288 0:dbad57390bd1 807 device_driver.phy_rx_cb(rf_buffer, len, rf_lqi, rf_rssi, rf_radio_driver_id);
ram54288 0:dbad57390bd1 808 }
ram54288 0:dbad57390bd1 809 }
ram54288 0:dbad57390bd1 810 }
ram54288 0:dbad57390bd1 811
ram54288 0:dbad57390bd1 812 /*
ram54288 0:dbad57390bd1 813 * \brief Function is called when MAC is shutting down the radio.
ram54288 0:dbad57390bd1 814 *
ram54288 0:dbad57390bd1 815 * \param none
ram54288 0:dbad57390bd1 816 *
ram54288 0:dbad57390bd1 817 * \return none
ram54288 0:dbad57390bd1 818 */
ram54288 0:dbad57390bd1 819 static void rf_shutdown(void)
ram54288 0:dbad57390bd1 820 {
ram54288 0:dbad57390bd1 821 /*Call RF OFF*/
ram54288 0:dbad57390bd1 822 rf_off();
ram54288 0:dbad57390bd1 823 }
ram54288 0:dbad57390bd1 824
ram54288 0:dbad57390bd1 825 /*
ram54288 0:dbad57390bd1 826 * \brief Function is a call back for TX end interrupt.
ram54288 0:dbad57390bd1 827 *
ram54288 0:dbad57390bd1 828 * \param none
ram54288 0:dbad57390bd1 829 *
ram54288 0:dbad57390bd1 830 * \return none
ram54288 0:dbad57390bd1 831 */
ram54288 0:dbad57390bd1 832 static void rf_handle_tx_end(void)
ram54288 0:dbad57390bd1 833 {
ram54288 0:dbad57390bd1 834 uint8_t rx_frame_pending = mStatusAndControlRegs[IRQSTS1] & cIRQSTS1_RX_FRM_PEND;
ram54288 0:dbad57390bd1 835
ram54288 0:dbad57390bd1 836 /*Start receiver*/
ram54288 0:dbad57390bd1 837 rf_receive();
ram54288 0:dbad57390bd1 838
ram54288 0:dbad57390bd1 839 if (!device_driver.phy_tx_done_cb) {
ram54288 0:dbad57390bd1 840 return;
ram54288 0:dbad57390bd1 841 }
ram54288 0:dbad57390bd1 842
ram54288 0:dbad57390bd1 843 /*Call PHY TX Done API*/
ram54288 0:dbad57390bd1 844 if( need_ack )
ram54288 0:dbad57390bd1 845 {
ram54288 0:dbad57390bd1 846 if( rx_frame_pending )
ram54288 0:dbad57390bd1 847 {
ram54288 0:dbad57390bd1 848 device_driver.phy_tx_done_cb(rf_radio_driver_id, mac_tx_handle, PHY_LINK_TX_DONE_PENDING, 1, 1);
ram54288 0:dbad57390bd1 849 }
ram54288 0:dbad57390bd1 850 else
ram54288 0:dbad57390bd1 851 {
ram54288 0:dbad57390bd1 852 // arm_net_phy_tx_done(rf_radio_driver_id, mac_tx_handle, PHY_LINK_TX_SUCCESS, 1, 1);
ram54288 0:dbad57390bd1 853 device_driver.phy_tx_done_cb(rf_radio_driver_id, mac_tx_handle, PHY_LINK_TX_DONE, 1, 1);
ram54288 0:dbad57390bd1 854 }
ram54288 0:dbad57390bd1 855 }
ram54288 0:dbad57390bd1 856 else
ram54288 0:dbad57390bd1 857 {
ram54288 0:dbad57390bd1 858 device_driver.phy_tx_done_cb(rf_radio_driver_id, mac_tx_handle, PHY_LINK_TX_SUCCESS, 1, 1);
ram54288 0:dbad57390bd1 859 }
ram54288 0:dbad57390bd1 860 }
ram54288 0:dbad57390bd1 861
ram54288 0:dbad57390bd1 862 /*
ram54288 0:dbad57390bd1 863 * \brief Function is a call back for CCA ED done interrupt.
ram54288 0:dbad57390bd1 864 *
ram54288 0:dbad57390bd1 865 * \param none
ram54288 0:dbad57390bd1 866 *
ram54288 0:dbad57390bd1 867 * \return none
ram54288 0:dbad57390bd1 868 */
ram54288 0:dbad57390bd1 869 static void rf_handle_cca_ed_done(void)
ram54288 0:dbad57390bd1 870 {
ram54288 0:dbad57390bd1 871 /*Check the result of CCA process*/
ram54288 0:dbad57390bd1 872 if( !(mStatusAndControlRegs[IRQSTS2] & cIRQSTS2_CCA) )
ram54288 0:dbad57390bd1 873 {
ram54288 0:dbad57390bd1 874 rf_start_tx();
ram54288 0:dbad57390bd1 875 }
ram54288 0:dbad57390bd1 876 else if (device_driver.phy_tx_done_cb)
ram54288 0:dbad57390bd1 877 {
ram54288 0:dbad57390bd1 878 /*Send CCA fail notification*/
ram54288 0:dbad57390bd1 879 device_driver.phy_tx_done_cb(rf_radio_driver_id, mac_tx_handle, PHY_LINK_CCA_FAIL, 1, 1);
ram54288 0:dbad57390bd1 880 }
ram54288 0:dbad57390bd1 881 }
ram54288 0:dbad57390bd1 882
ram54288 0:dbad57390bd1 883 /*
ram54288 0:dbad57390bd1 884 * \brief Function sets the TX power variable.
ram54288 0:dbad57390bd1 885 *
ram54288 0:dbad57390bd1 886 * \param power TX power setting
ram54288 0:dbad57390bd1 887 *
ram54288 0:dbad57390bd1 888 * \return 0 Success
ram54288 0:dbad57390bd1 889 * \return -1 Fail
ram54288 0:dbad57390bd1 890 */
ram54288 0:dbad57390bd1 891 static int8_t rf_tx_power_set(uint8_t power)
ram54288 0:dbad57390bd1 892 {
ram54288 0:dbad57390bd1 893 /* gcapraru: Map MCR20A Tx power levels over ATMEL values */
ram54288 0:dbad57390bd1 894 static uint8_t pwrLevelMapping[16] = {25,25,25,24,24,24,23,23,22,22,21,20,19,18,17,14};
ram54288 0:dbad57390bd1 895
ram54288 0:dbad57390bd1 896 if( power > 15 )
ram54288 0:dbad57390bd1 897 {
ram54288 0:dbad57390bd1 898 return -1;
ram54288 0:dbad57390bd1 899 }
ram54288 0:dbad57390bd1 900
ram54288 0:dbad57390bd1 901 radio_tx_power = power;
ram54288 0:dbad57390bd1 902 MCR20Drv_DirectAccessSPIWrite(PA_PWR, pwrLevelMapping[power]);
ram54288 0:dbad57390bd1 903 return 0;
ram54288 0:dbad57390bd1 904 }
ram54288 0:dbad57390bd1 905
ram54288 0:dbad57390bd1 906 /*
ram54288 0:dbad57390bd1 907 * \brief Function returns the TX power variable.
ram54288 0:dbad57390bd1 908 *
ram54288 0:dbad57390bd1 909 * \param none
ram54288 0:dbad57390bd1 910 *
ram54288 0:dbad57390bd1 911 * \return radio_tx_power TX power variable
ram54288 0:dbad57390bd1 912 */
ram54288 0:dbad57390bd1 913 static uint8_t rf_tx_power_get(void)
ram54288 0:dbad57390bd1 914 {
ram54288 0:dbad57390bd1 915 return radio_tx_power;
ram54288 0:dbad57390bd1 916 }
ram54288 0:dbad57390bd1 917
ram54288 0:dbad57390bd1 918 /*
ram54288 0:dbad57390bd1 919 * \brief Function enables the usage of Antenna diversity.
ram54288 0:dbad57390bd1 920 *
ram54288 0:dbad57390bd1 921 * \param none
ram54288 0:dbad57390bd1 922 *
ram54288 0:dbad57390bd1 923 * \return 0 Success
ram54288 0:dbad57390bd1 924 */
ram54288 0:dbad57390bd1 925 static int8_t rf_enable_antenna_diversity(void)
ram54288 0:dbad57390bd1 926 {
ram54288 0:dbad57390bd1 927 uint8_t phyReg;
ram54288 0:dbad57390bd1 928
ram54288 0:dbad57390bd1 929 phyReg = MCR20Drv_IndirectAccessSPIRead(ANT_AGC_CTRL);
ram54288 0:dbad57390bd1 930 phyReg |= cANT_AGC_CTRL_FAD_EN_Mask_c;
ram54288 0:dbad57390bd1 931 MCR20Drv_IndirectAccessSPIWrite(ANT_AGC_CTRL, phyReg);
ram54288 0:dbad57390bd1 932
ram54288 0:dbad57390bd1 933 phyReg = MCR20Drv_IndirectAccessSPIRead(ANT_PAD_CTRL);
ram54288 0:dbad57390bd1 934 phyReg |= 0x02;
ram54288 0:dbad57390bd1 935 MCR20Drv_IndirectAccessSPIWrite(ANT_PAD_CTRL, phyReg);
ram54288 0:dbad57390bd1 936
ram54288 0:dbad57390bd1 937 return 0;
ram54288 0:dbad57390bd1 938 }
ram54288 0:dbad57390bd1 939
ram54288 0:dbad57390bd1 940 /*
ram54288 0:dbad57390bd1 941 * \brief Function gives the control of RF states to MAC.
ram54288 0:dbad57390bd1 942 *
ram54288 0:dbad57390bd1 943 * \param new_state RF state
ram54288 0:dbad57390bd1 944 * \param rf_channel RF channel
ram54288 0:dbad57390bd1 945 *
ram54288 0:dbad57390bd1 946 * \return 0 Success
ram54288 0:dbad57390bd1 947 */
ram54288 0:dbad57390bd1 948 static int8_t rf_interface_state_control(phy_interface_state_e new_state, uint8_t rf_channel)
ram54288 0:dbad57390bd1 949 {
ram54288 0:dbad57390bd1 950 int8_t ret_val = 0;
ram54288 0:dbad57390bd1 951 switch (new_state)
ram54288 0:dbad57390bd1 952 {
ram54288 0:dbad57390bd1 953 /*Reset PHY driver and set to idle*/
ram54288 0:dbad57390bd1 954 case PHY_INTERFACE_RESET:
ram54288 0:dbad57390bd1 955 break;
ram54288 0:dbad57390bd1 956 /*Disable PHY Interface driver*/
ram54288 0:dbad57390bd1 957 case PHY_INTERFACE_DOWN:
ram54288 0:dbad57390bd1 958 rf_shutdown();
ram54288 0:dbad57390bd1 959 break;
ram54288 0:dbad57390bd1 960 /*Enable PHY Interface driver*/
ram54288 0:dbad57390bd1 961 case PHY_INTERFACE_UP:
ram54288 0:dbad57390bd1 962 rf_channel_set(rf_channel);
ram54288 0:dbad57390bd1 963 rf_receive();
ram54288 0:dbad57390bd1 964 break;
ram54288 0:dbad57390bd1 965 /*Enable wireless interface ED scan mode*/
ram54288 0:dbad57390bd1 966 case PHY_INTERFACE_RX_ENERGY_STATE:
ram54288 0:dbad57390bd1 967 rf_abort();
ram54288 0:dbad57390bd1 968 rf_channel_set(rf_channel);
ram54288 0:dbad57390bd1 969 break;
ram54288 0:dbad57390bd1 970 case PHY_INTERFACE_SNIFFER_STATE: /**< Enable Sniffer state */
ram54288 0:dbad57390bd1 971 rf_promiscuous(1);
ram54288 0:dbad57390bd1 972 rf_channel_set(rf_channel);
ram54288 0:dbad57390bd1 973 rf_receive();
ram54288 0:dbad57390bd1 974 break;
ram54288 0:dbad57390bd1 975 }
ram54288 0:dbad57390bd1 976 return ret_val;
ram54288 0:dbad57390bd1 977 }
ram54288 0:dbad57390bd1 978
ram54288 0:dbad57390bd1 979 /*
ram54288 0:dbad57390bd1 980 * \brief Function controls the ACK pending, channel setting and energy detection.
ram54288 0:dbad57390bd1 981 *
ram54288 0:dbad57390bd1 982 * \param extension_type Type of control
ram54288 0:dbad57390bd1 983 * \param data_ptr Data from NET library
ram54288 0:dbad57390bd1 984 *
ram54288 0:dbad57390bd1 985 * \return 0 Success
ram54288 0:dbad57390bd1 986 */
ram54288 0:dbad57390bd1 987 static int8_t rf_extension(phy_extension_type_e extension_type, uint8_t *data_ptr)
ram54288 0:dbad57390bd1 988 {
ram54288 0:dbad57390bd1 989 switch (extension_type)
ram54288 0:dbad57390bd1 990 {
ram54288 0:dbad57390bd1 991 /*Control MAC pending bit for Indirect data transmission*/
ram54288 0:dbad57390bd1 992 case PHY_EXTENSION_CTRL_PENDING_BIT:
ram54288 0:dbad57390bd1 993 {
ram54288 0:dbad57390bd1 994 uint8_t reg = MCR20Drv_DirectAccessSPIRead(SRC_CTRL);
ram54288 0:dbad57390bd1 995
ram54288 0:dbad57390bd1 996 if(*data_ptr)
ram54288 0:dbad57390bd1 997 {
ram54288 0:dbad57390bd1 998 reg |= cSRC_CTRL_ACK_FRM_PND;
ram54288 0:dbad57390bd1 999 }
ram54288 0:dbad57390bd1 1000 else
ram54288 0:dbad57390bd1 1001 {
ram54288 0:dbad57390bd1 1002 reg &= ~cSRC_CTRL_ACK_FRM_PND;
ram54288 0:dbad57390bd1 1003 }
ram54288 0:dbad57390bd1 1004
ram54288 0:dbad57390bd1 1005 MCR20Drv_DirectAccessSPIWrite(SRC_CTRL, reg);
ram54288 0:dbad57390bd1 1006 break;
ram54288 0:dbad57390bd1 1007
ram54288 0:dbad57390bd1 1008 }
ram54288 0:dbad57390bd1 1009 /*Return frame pending status*/
ram54288 0:dbad57390bd1 1010 case PHY_EXTENSION_READ_LAST_ACK_PENDING_STATUS:
ram54288 0:dbad57390bd1 1011 *data_ptr = MCR20Drv_DirectAccessSPIRead(IRQSTS1 & cIRQSTS1_RX_FRM_PEND);
ram54288 0:dbad57390bd1 1012 break;
ram54288 0:dbad57390bd1 1013 /*Set channel*/
ram54288 0:dbad57390bd1 1014 case PHY_EXTENSION_SET_CHANNEL:
ram54288 0:dbad57390bd1 1015 break;
ram54288 0:dbad57390bd1 1016 /*Read energy on the channel*/
ram54288 0:dbad57390bd1 1017 case PHY_EXTENSION_READ_CHANNEL_ENERGY:
ram54288 0:dbad57390bd1 1018 *data_ptr = rf_get_channel_energy();
ram54288 0:dbad57390bd1 1019 break;
ram54288 0:dbad57390bd1 1020 /*Read status of the link*/
ram54288 0:dbad57390bd1 1021 case PHY_EXTENSION_READ_LINK_STATUS:
ram54288 0:dbad57390bd1 1022 break;
ram54288 0:dbad57390bd1 1023 case PHY_EXTENSION_CONVERT_SIGNAL_INFO:
ram54288 0:dbad57390bd1 1024 break;
ram54288 0:dbad57390bd1 1025 }
ram54288 0:dbad57390bd1 1026 return 0;
ram54288 0:dbad57390bd1 1027 }
ram54288 0:dbad57390bd1 1028
ram54288 0:dbad57390bd1 1029 /*
ram54288 0:dbad57390bd1 1030 * \brief Function sets the addresses to RF address filters.
ram54288 0:dbad57390bd1 1031 *
ram54288 0:dbad57390bd1 1032 * \param address_type Type of address
ram54288 0:dbad57390bd1 1033 * \param address_ptr Pointer to given address
ram54288 0:dbad57390bd1 1034 *
ram54288 0:dbad57390bd1 1035 * \return 0 Success
ram54288 0:dbad57390bd1 1036 */
ram54288 0:dbad57390bd1 1037 static int8_t rf_address_write(phy_address_type_e address_type, uint8_t *address_ptr)
ram54288 0:dbad57390bd1 1038 {
ram54288 0:dbad57390bd1 1039 int8_t ret_val = 0;
ram54288 0:dbad57390bd1 1040 switch (address_type)
ram54288 0:dbad57390bd1 1041 {
ram54288 0:dbad57390bd1 1042 /*Set 48-bit address*/
ram54288 0:dbad57390bd1 1043 case PHY_MAC_48BIT:
ram54288 0:dbad57390bd1 1044 break;
ram54288 0:dbad57390bd1 1045 /*Set 64-bit address*/
ram54288 0:dbad57390bd1 1046 case PHY_MAC_64BIT:
ram54288 0:dbad57390bd1 1047 rf_set_address(address_ptr);
ram54288 0:dbad57390bd1 1048 break;
ram54288 0:dbad57390bd1 1049 /*Set 16-bit address*/
ram54288 0:dbad57390bd1 1050 case PHY_MAC_16BIT:
ram54288 0:dbad57390bd1 1051 rf_set_short_adr(address_ptr);
ram54288 0:dbad57390bd1 1052 break;
ram54288 0:dbad57390bd1 1053 /*Set PAN Id*/
ram54288 0:dbad57390bd1 1054 case PHY_MAC_PANID:
ram54288 0:dbad57390bd1 1055 rf_set_pan_id(address_ptr);
ram54288 0:dbad57390bd1 1056 break;
ram54288 0:dbad57390bd1 1057 }
ram54288 0:dbad57390bd1 1058 return ret_val;
ram54288 0:dbad57390bd1 1059 }
ram54288 0:dbad57390bd1 1060
ram54288 0:dbad57390bd1 1061 static void rf_mac64_read(uint8_t *address)
ram54288 0:dbad57390bd1 1062 {
ram54288 0:dbad57390bd1 1063 /* Write one register at a time to be accessible from hibernate mode */
ram54288 0:dbad57390bd1 1064 address[7] = MCR20Drv_DirectAccessSPIRead(MACLONGADDRS0_0);
ram54288 0:dbad57390bd1 1065 address[6] = MCR20Drv_DirectAccessSPIRead(MACLONGADDRS0_8);
ram54288 0:dbad57390bd1 1066 address[5] = MCR20Drv_DirectAccessSPIRead(MACLONGADDRS0_16);
ram54288 0:dbad57390bd1 1067 address[4] = MCR20Drv_DirectAccessSPIRead(MACLONGADDRS0_24);
ram54288 0:dbad57390bd1 1068 address[3] = MCR20Drv_DirectAccessSPIRead(MACLONGADDRS0_32);
ram54288 0:dbad57390bd1 1069 address[2] = MCR20Drv_DirectAccessSPIRead(MACLONGADDRS0_40);
ram54288 0:dbad57390bd1 1070 address[1] = MCR20Drv_DirectAccessSPIRead(MACLONGADDRS0_48);
ram54288 0:dbad57390bd1 1071 address[0] = MCR20Drv_DirectAccessSPIRead(MACLONGADDRS0_56);
ram54288 0:dbad57390bd1 1072
ram54288 0:dbad57390bd1 1073 }
ram54288 0:dbad57390bd1 1074
ram54288 0:dbad57390bd1 1075 /*
ram54288 0:dbad57390bd1 1076 * \brief Function initialises the ACK wait time and returns the used PHY mode.
ram54288 0:dbad57390bd1 1077 *
ram54288 0:dbad57390bd1 1078 * \param none
ram54288 0:dbad57390bd1 1079 *
ram54288 0:dbad57390bd1 1080 * \return tmp Used PHY mode
ram54288 0:dbad57390bd1 1081 */
ram54288 0:dbad57390bd1 1082 static void rf_init_phy_mode(void)
ram54288 0:dbad57390bd1 1083 {
ram54288 0:dbad57390bd1 1084 }
ram54288 0:dbad57390bd1 1085
ram54288 0:dbad57390bd1 1086 /*
ram54288 0:dbad57390bd1 1087 * \brief Function is a RF interrupt vector. End of frame in RX and TX are handled here as well as CCA process interrupt.
ram54288 0:dbad57390bd1 1088 *
ram54288 0:dbad57390bd1 1089 * \param none
ram54288 0:dbad57390bd1 1090 *
ram54288 0:dbad57390bd1 1091 * \return none
ram54288 0:dbad57390bd1 1092 */
ram54288 0:dbad57390bd1 1093 static void PHY_InterruptHandler(void)
ram54288 0:dbad57390bd1 1094 {
ram54288 0:dbad57390bd1 1095 uint8_t xcvseqCopy;
ram54288 0:dbad57390bd1 1096
ram54288 0:dbad57390bd1 1097 /* Disable and clear transceiver(IRQ_B) interrupt */
ram54288 0:dbad57390bd1 1098 MCR20Drv_IRQ_Disable();
ram54288 0:dbad57390bd1 1099 //MCR20Drv_IRQ_Clear();
ram54288 0:dbad57390bd1 1100
ram54288 0:dbad57390bd1 1101 /* Read transceiver interrupt status and control registers */
ram54288 0:dbad57390bd1 1102 mStatusAndControlRegs[IRQSTS1] =
ram54288 0:dbad57390bd1 1103 MCR20Drv_DirectAccessSPIMultiByteRead(IRQSTS2, &mStatusAndControlRegs[IRQSTS2], 7);
ram54288 0:dbad57390bd1 1104
ram54288 0:dbad57390bd1 1105 xcvseqCopy = mStatusAndControlRegs[PHY_CTRL1] & cPHY_CTRL1_XCVSEQ;
ram54288 0:dbad57390bd1 1106
ram54288 0:dbad57390bd1 1107 /* Flter Fail IRQ */
ram54288 0:dbad57390bd1 1108 if( (mStatusAndControlRegs[IRQSTS1] & cIRQSTS1_FILTERFAIL_IRQ) &&
ram54288 0:dbad57390bd1 1109 !(mStatusAndControlRegs[PHY_CTRL2] & cPHY_CTRL2_FILTERFAIL_MSK) )
ram54288 0:dbad57390bd1 1110 {
ram54288 0:dbad57390bd1 1111 if( xcvseqCopy == gRX_c )
ram54288 0:dbad57390bd1 1112 {
ram54288 0:dbad57390bd1 1113 /* Abort current SEQ */
ram54288 0:dbad57390bd1 1114 mStatusAndControlRegs[PHY_CTRL1] &= ~(cPHY_CTRL1_XCVSEQ);
ram54288 0:dbad57390bd1 1115 MCR20Drv_DirectAccessSPIWrite(PHY_CTRL1, mStatusAndControlRegs[PHY_CTRL1]);
ram54288 0:dbad57390bd1 1116 /* Wait for Sequence Idle */
ram54288 0:dbad57390bd1 1117 while ((MCR20Drv_DirectAccessSPIRead(SEQ_STATE) & 0x1F) != 0);
ram54288 0:dbad57390bd1 1118 /* Clear IRQ flags: */
ram54288 0:dbad57390bd1 1119 MCR20Drv_DirectAccessSPIWrite(IRQSTS1, cIRQSTS1_SEQIRQ);
ram54288 0:dbad57390bd1 1120 /* Restart Rx asap */
ram54288 0:dbad57390bd1 1121 mStatusAndControlRegs[PHY_CTRL1] |= gRX_c;
ram54288 0:dbad57390bd1 1122 MCR20Drv_DirectAccessSPIWrite(PHY_CTRL1, mStatusAndControlRegs[PHY_CTRL1]);
ram54288 0:dbad57390bd1 1123 }
ram54288 0:dbad57390bd1 1124 }
ram54288 0:dbad57390bd1 1125
ram54288 0:dbad57390bd1 1126 /* TMR3 IRQ: ACK wait time-out */
ram54288 0:dbad57390bd1 1127 if( (mStatusAndControlRegs[IRQSTS3] & cIRQSTS3_TMR3IRQ) &&
ram54288 0:dbad57390bd1 1128 !(mStatusAndControlRegs[IRQSTS3] & cIRQSTS3_TMR3MSK) )
ram54288 0:dbad57390bd1 1129 {
ram54288 0:dbad57390bd1 1130 /* Disable TMR3 IRQ */
ram54288 0:dbad57390bd1 1131 mStatusAndControlRegs[IRQSTS3] |= cIRQSTS3_TMR3MSK;
ram54288 0:dbad57390bd1 1132
ram54288 0:dbad57390bd1 1133 if( xcvseqCopy == gTR_c )
ram54288 0:dbad57390bd1 1134 {
ram54288 0:dbad57390bd1 1135 /* Set XCVR to Idle */
ram54288 0:dbad57390bd1 1136 mPhySeqState = gIdle_c;
ram54288 0:dbad57390bd1 1137 mStatusAndControlRegs[PHY_CTRL1] &= ~( cPHY_CTRL1_XCVSEQ );
ram54288 0:dbad57390bd1 1138 /* Mask interrupts */
ram54288 0:dbad57390bd1 1139 mStatusAndControlRegs[PHY_CTRL2] |= cPHY_CTRL2_CCAMSK | cPHY_CTRL2_RXMSK | cPHY_CTRL2_TXMSK | cPHY_CTRL2_SEQMSK;
ram54288 0:dbad57390bd1 1140 /* Sync settings with XCVR */
ram54288 0:dbad57390bd1 1141 MCR20Drv_DirectAccessSPIMultiByteWrite(IRQSTS1, mStatusAndControlRegs, 5);
ram54288 0:dbad57390bd1 1142
ram54288 0:dbad57390bd1 1143 rf_ack_wait_timer_interrupt();
ram54288 0:dbad57390bd1 1144 MCR20Drv_IRQ_Enable();
ram54288 0:dbad57390bd1 1145 return;
ram54288 0:dbad57390bd1 1146 }
ram54288 0:dbad57390bd1 1147 }
ram54288 0:dbad57390bd1 1148
ram54288 0:dbad57390bd1 1149 /* Sequencer interrupt, the autosequence has completed */
ram54288 0:dbad57390bd1 1150 if( (mStatusAndControlRegs[IRQSTS1] & cIRQSTS1_SEQIRQ) &&
ram54288 0:dbad57390bd1 1151 !(mStatusAndControlRegs[PHY_CTRL2] & cPHY_CTRL2_SEQMSK) )
ram54288 0:dbad57390bd1 1152 {
ram54288 0:dbad57390bd1 1153 /* Set XCVR to Idle */
ram54288 0:dbad57390bd1 1154 mPhySeqState = gIdle_c;
ram54288 0:dbad57390bd1 1155 mStatusAndControlRegs[PHY_CTRL1] &= ~( cPHY_CTRL1_XCVSEQ );
ram54288 0:dbad57390bd1 1156 /* Mask interrupts */
ram54288 0:dbad57390bd1 1157 mStatusAndControlRegs[PHY_CTRL2] |= cPHY_CTRL2_CCAMSK | cPHY_CTRL2_RXMSK | cPHY_CTRL2_TXMSK | cPHY_CTRL2_SEQMSK;
ram54288 0:dbad57390bd1 1158 /* Sync settings with XCVR */
ram54288 0:dbad57390bd1 1159 MCR20Drv_DirectAccessSPIMultiByteWrite(IRQSTS1, mStatusAndControlRegs, 5);
ram54288 0:dbad57390bd1 1160
ram54288 0:dbad57390bd1 1161 /* PLL unlock, the autosequence has been aborted due to PLL unlock */
ram54288 0:dbad57390bd1 1162 if( mStatusAndControlRegs[IRQSTS1] & cIRQSTS1_PLL_UNLOCK_IRQ )
ram54288 0:dbad57390bd1 1163 {
ram54288 0:dbad57390bd1 1164 if(xcvseqCopy == gRX_c)
ram54288 0:dbad57390bd1 1165 {
ram54288 0:dbad57390bd1 1166 rf_receive();
ram54288 0:dbad57390bd1 1167 }
ram54288 0:dbad57390bd1 1168 MCR20Drv_IRQ_Enable();
ram54288 0:dbad57390bd1 1169 return;
ram54288 0:dbad57390bd1 1170 }
ram54288 0:dbad57390bd1 1171
ram54288 0:dbad57390bd1 1172 switch(xcvseqCopy)
ram54288 0:dbad57390bd1 1173 {
ram54288 0:dbad57390bd1 1174 case gTX_c:
ram54288 0:dbad57390bd1 1175 case gTR_c:
ram54288 0:dbad57390bd1 1176 rf_handle_tx_end();
ram54288 0:dbad57390bd1 1177 break;
ram54288 0:dbad57390bd1 1178
ram54288 0:dbad57390bd1 1179 case gRX_c:
ram54288 0:dbad57390bd1 1180 rf_handle_rx_end();
ram54288 0:dbad57390bd1 1181 break;
ram54288 0:dbad57390bd1 1182
ram54288 0:dbad57390bd1 1183 case gCCA_c:
ram54288 0:dbad57390bd1 1184 rf_handle_cca_ed_done();
ram54288 0:dbad57390bd1 1185 break;
ram54288 0:dbad57390bd1 1186
ram54288 0:dbad57390bd1 1187 default:
ram54288 0:dbad57390bd1 1188 break;
ram54288 0:dbad57390bd1 1189 }
ram54288 0:dbad57390bd1 1190
ram54288 0:dbad57390bd1 1191 MCR20Drv_IRQ_Enable();
ram54288 0:dbad57390bd1 1192 return;
ram54288 0:dbad57390bd1 1193 }
ram54288 0:dbad57390bd1 1194 /* Other IRQ. Clear XCVR interrupt flags */
ram54288 0:dbad57390bd1 1195 MCR20Drv_DirectAccessSPIMultiByteWrite(IRQSTS1, mStatusAndControlRegs, 3);
ram54288 0:dbad57390bd1 1196 MCR20Drv_IRQ_Enable();
ram54288 0:dbad57390bd1 1197 }
ram54288 0:dbad57390bd1 1198
ram54288 0:dbad57390bd1 1199 /*
ram54288 0:dbad57390bd1 1200 * \brief Function forces the XCVR to Idle state.
ram54288 0:dbad57390bd1 1201 *
ram54288 0:dbad57390bd1 1202 * \param none
ram54288 0:dbad57390bd1 1203 *
ram54288 0:dbad57390bd1 1204 * \return none
ram54288 0:dbad57390bd1 1205 */
ram54288 0:dbad57390bd1 1206 static void rf_abort(void)
ram54288 0:dbad57390bd1 1207 {
ram54288 0:dbad57390bd1 1208 /* Mask XCVR irq */
ram54288 0:dbad57390bd1 1209 MCR20Drv_IRQ_Disable();
ram54288 0:dbad57390bd1 1210
ram54288 0:dbad57390bd1 1211 mPhySeqState = gIdle_c;
ram54288 0:dbad57390bd1 1212
ram54288 0:dbad57390bd1 1213 mStatusAndControlRegs[IRQSTS1] = MCR20Drv_DirectAccessSPIMultiByteRead(IRQSTS2, &mStatusAndControlRegs[IRQSTS2], 5);
ram54288 0:dbad57390bd1 1214
ram54288 0:dbad57390bd1 1215 /* Mask SEQ interrupt */
ram54288 0:dbad57390bd1 1216 mStatusAndControlRegs[PHY_CTRL2] |= cPHY_CTRL2_SEQMSK;
ram54288 0:dbad57390bd1 1217 MCR20Drv_DirectAccessSPIWrite(PHY_CTRL2, mStatusAndControlRegs[PHY_CTRL2]);
ram54288 0:dbad57390bd1 1218
ram54288 0:dbad57390bd1 1219 if( (mStatusAndControlRegs[PHY_CTRL1] & cPHY_CTRL1_XCVSEQ) != gIdle_c )
ram54288 0:dbad57390bd1 1220 {
ram54288 0:dbad57390bd1 1221 /* Abort current SEQ */
ram54288 0:dbad57390bd1 1222 mStatusAndControlRegs[PHY_CTRL1] &= ~(cPHY_CTRL1_XCVSEQ);
ram54288 0:dbad57390bd1 1223 MCR20Drv_DirectAccessSPIWrite(PHY_CTRL1, mStatusAndControlRegs[PHY_CTRL1]);
ram54288 0:dbad57390bd1 1224
ram54288 0:dbad57390bd1 1225 /* Wait for Sequence Idle (if not already) */
ram54288 0:dbad57390bd1 1226 while ((MCR20Drv_DirectAccessSPIRead(SEQ_STATE) & 0x1F) != 0);
ram54288 0:dbad57390bd1 1227 //while ( !(MCR20Drv_DirectAccessSPIRead(IRQSTS1) & cIRQSTS1_SEQIRQ));
ram54288 0:dbad57390bd1 1228 mStatusAndControlRegs[IRQSTS1] |= cIRQSTS1_SEQIRQ;
ram54288 0:dbad57390bd1 1229 }
ram54288 0:dbad57390bd1 1230
ram54288 0:dbad57390bd1 1231 /* Clear all PP IRQ bits to avoid unexpected interrupts and mask TMR3 interrupt.
ram54288 0:dbad57390bd1 1232 Do not change TMR IRQ status. */
ram54288 0:dbad57390bd1 1233 mStatusAndControlRegs[IRQSTS3] &= 0xF0;
ram54288 0:dbad57390bd1 1234 mStatusAndControlRegs[IRQSTS3] |= (cIRQSTS3_TMR3MSK | cIRQSTS3_TMR3IRQ);
ram54288 0:dbad57390bd1 1235 MCR20Drv_DirectAccessSPIMultiByteWrite(IRQSTS1, mStatusAndControlRegs, 3);
ram54288 0:dbad57390bd1 1236
ram54288 0:dbad57390bd1 1237 /* Unmask XCVR irq */
ram54288 0:dbad57390bd1 1238 MCR20Drv_IRQ_Enable();
ram54288 0:dbad57390bd1 1239 }
ram54288 0:dbad57390bd1 1240
ram54288 0:dbad57390bd1 1241 /*
ram54288 0:dbad57390bd1 1242 * \brief Function reads a time-stamp value from XCVR [symbols]
ram54288 0:dbad57390bd1 1243 *
ram54288 0:dbad57390bd1 1244 * \param pEndTime pointer to location where time-stamp will be stored
ram54288 0:dbad57390bd1 1245 *
ram54288 0:dbad57390bd1 1246 * \return none
ram54288 0:dbad57390bd1 1247 */
ram54288 0:dbad57390bd1 1248 static void rf_get_timestamp(uint32_t *pRetClk)
ram54288 0:dbad57390bd1 1249 {
ram54288 0:dbad57390bd1 1250 if(NULL == pRetClk)
ram54288 0:dbad57390bd1 1251 {
ram54288 0:dbad57390bd1 1252 return;
ram54288 0:dbad57390bd1 1253 }
ram54288 0:dbad57390bd1 1254
ram54288 0:dbad57390bd1 1255 platform_enter_critical();
ram54288 0:dbad57390bd1 1256
ram54288 0:dbad57390bd1 1257 *pRetClk = 0;
ram54288 0:dbad57390bd1 1258 MCR20Drv_DirectAccessSPIMultiByteRead(EVENT_TMR_LSB, (uint8_t *) pRetClk, 3);
ram54288 0:dbad57390bd1 1259
ram54288 0:dbad57390bd1 1260 platform_exit_critical();
ram54288 0:dbad57390bd1 1261 }
ram54288 0:dbad57390bd1 1262
ram54288 0:dbad57390bd1 1263 /*
ram54288 0:dbad57390bd1 1264 * \brief Function set a time-out to an XCVR sequence.
ram54288 0:dbad57390bd1 1265 *
ram54288 0:dbad57390bd1 1266 * \param pEndTime pointer to the sequence time-out value [symbols]
ram54288 0:dbad57390bd1 1267 *
ram54288 0:dbad57390bd1 1268 * \return none
ram54288 0:dbad57390bd1 1269 */
ram54288 0:dbad57390bd1 1270 static void rf_set_timeout(uint32_t *pEndTime)
ram54288 0:dbad57390bd1 1271 {
ram54288 0:dbad57390bd1 1272 uint8_t phyReg;
ram54288 0:dbad57390bd1 1273
ram54288 0:dbad57390bd1 1274 if(NULL == pEndTime)
ram54288 0:dbad57390bd1 1275 {
ram54288 0:dbad57390bd1 1276 return;
ram54288 0:dbad57390bd1 1277 }
ram54288 0:dbad57390bd1 1278
ram54288 0:dbad57390bd1 1279 platform_enter_critical();
ram54288 0:dbad57390bd1 1280
ram54288 0:dbad57390bd1 1281 phyReg = MCR20Drv_DirectAccessSPIRead(IRQSTS3);
ram54288 0:dbad57390bd1 1282 phyReg &= 0xF0; /* do not change IRQ status */
ram54288 0:dbad57390bd1 1283 phyReg |= (cIRQSTS3_TMR3MSK); /* mask TMR3 interrupt */
ram54288 0:dbad57390bd1 1284 MCR20Drv_DirectAccessSPIWrite(IRQSTS3, phyReg);
ram54288 0:dbad57390bd1 1285
ram54288 0:dbad57390bd1 1286 MCR20Drv_DirectAccessSPIMultiByteWrite(T3CMP_LSB, (uint8_t *) pEndTime, 3);
ram54288 0:dbad57390bd1 1287
ram54288 0:dbad57390bd1 1288 phyReg &= ~(cIRQSTS3_TMR3MSK); /* unmask TMR3 interrupt */
ram54288 0:dbad57390bd1 1289 phyReg |= (cIRQSTS3_TMR3IRQ); /* aknowledge TMR3 IRQ */
ram54288 0:dbad57390bd1 1290 MCR20Drv_DirectAccessSPIWrite(IRQSTS3, phyReg);
ram54288 0:dbad57390bd1 1291
ram54288 0:dbad57390bd1 1292 platform_exit_critical();
ram54288 0:dbad57390bd1 1293 }
ram54288 0:dbad57390bd1 1294
ram54288 0:dbad57390bd1 1295 /*
ram54288 0:dbad57390bd1 1296 * \brief Function reads a random number from RF.
ram54288 0:dbad57390bd1 1297 *
ram54288 0:dbad57390bd1 1298 * \param none
ram54288 0:dbad57390bd1 1299 *
ram54288 0:dbad57390bd1 1300 * \return 8-bit random number
ram54288 0:dbad57390bd1 1301 */
ram54288 0:dbad57390bd1 1302 static uint8_t rf_if_read_rnd(void)
ram54288 0:dbad57390bd1 1303 {
ram54288 0:dbad57390bd1 1304 uint8_t phyReg;
ram54288 0:dbad57390bd1 1305
ram54288 0:dbad57390bd1 1306 MCR20Drv_IRQ_Disable();
ram54288 0:dbad57390bd1 1307 /* Check if XCVR is idle */
ram54288 0:dbad57390bd1 1308 phyReg = MCR20Drv_DirectAccessSPIRead(PHY_CTRL1);
ram54288 0:dbad57390bd1 1309
ram54288 0:dbad57390bd1 1310 if( (phyReg & cPHY_CTRL1_XCVSEQ) == gIdle_c )
ram54288 0:dbad57390bd1 1311 {
ram54288 0:dbad57390bd1 1312 /* Program a new sequence */
ram54288 0:dbad57390bd1 1313 MCR20Drv_DirectAccessSPIWrite(PHY_CTRL1, phyReg | gCCA_c);
ram54288 0:dbad57390bd1 1314 /* Wait for sequence to finish */
ram54288 0:dbad57390bd1 1315 while( !(MCR20Drv_DirectAccessSPIRead(IRQSTS1) & cIRQSTS1_SEQIRQ) );
ram54288 0:dbad57390bd1 1316 /* Clear interrupt flag */
ram54288 0:dbad57390bd1 1317 MCR20Drv_DirectAccessSPIWrite(IRQSTS1, cIRQSTS1_SEQIRQ);
ram54288 0:dbad57390bd1 1318 }
ram54288 0:dbad57390bd1 1319
ram54288 0:dbad57390bd1 1320 MCR20Drv_IRQ_Enable();
ram54288 0:dbad57390bd1 1321
ram54288 0:dbad57390bd1 1322 return MCR20Drv_IndirectAccessSPIRead(_RNG);
ram54288 0:dbad57390bd1 1323 }
ram54288 0:dbad57390bd1 1324
ram54288 0:dbad57390bd1 1325 /*
ram54288 0:dbad57390bd1 1326 * \brief Function converts LQI into RSSI.
ram54288 0:dbad57390bd1 1327 *
ram54288 0:dbad57390bd1 1328 * \param LQI
ram54288 0:dbad57390bd1 1329 *
ram54288 0:dbad57390bd1 1330 * \return RSSI
ram54288 0:dbad57390bd1 1331 */
ram54288 0:dbad57390bd1 1332 static int8_t rf_convert_LQI_to_RSSI(uint8_t lqi)
ram54288 0:dbad57390bd1 1333 {
ram54288 0:dbad57390bd1 1334 int32_t rssi = (50*lqi - 16820) / 163;
ram54288 0:dbad57390bd1 1335 return (int8_t)rssi;
ram54288 0:dbad57390bd1 1336 }
ram54288 0:dbad57390bd1 1337
ram54288 0:dbad57390bd1 1338 /*
ram54288 0:dbad57390bd1 1339 * \brief Function scale the LQI value reported by RF into a 0-255 value.
ram54288 0:dbad57390bd1 1340 *
ram54288 0:dbad57390bd1 1341 * \param hwLqi - the LQI value reported by RF
ram54288 0:dbad57390bd1 1342 *
ram54288 0:dbad57390bd1 1343 * \return scaled LQI
ram54288 0:dbad57390bd1 1344 */
ram54288 0:dbad57390bd1 1345 static uint8_t rf_convert_LQI(uint8_t hwLqi)
ram54288 0:dbad57390bd1 1346 {
ram54288 0:dbad57390bd1 1347 uint32_t tmpLQI;
ram54288 0:dbad57390bd1 1348
ram54288 0:dbad57390bd1 1349 /* LQI Saturation Level */
ram54288 0:dbad57390bd1 1350 if (hwLqi >= 230)
ram54288 0:dbad57390bd1 1351 {
ram54288 0:dbad57390bd1 1352 return 0xFF;
ram54288 0:dbad57390bd1 1353 }
ram54288 0:dbad57390bd1 1354 else if (hwLqi <= 9)
ram54288 0:dbad57390bd1 1355 {
ram54288 0:dbad57390bd1 1356 return 0;
ram54288 0:dbad57390bd1 1357 }
ram54288 0:dbad57390bd1 1358 else
ram54288 0:dbad57390bd1 1359 {
ram54288 0:dbad57390bd1 1360 /* Rescale the LQI values from min to saturation to the 0x00 - 0xFF range */
ram54288 0:dbad57390bd1 1361 /* The LQI value mst be multiplied by ~1.1087 */
ram54288 0:dbad57390bd1 1362 /* tmpLQI = hwLqi * 7123 ~= hwLqi * 65536 * 0.1087 = hwLqi * 2^16 * 0.1087*/
ram54288 0:dbad57390bd1 1363 tmpLQI = ((uint32_t)hwLqi * (uint32_t)7123 );
ram54288 0:dbad57390bd1 1364 /* tmpLQI = (tmpLQI / 2^16) + hwLqi */
ram54288 0:dbad57390bd1 1365 tmpLQI = (uint32_t)(tmpLQI >> 16) + (uint32_t)hwLqi;
ram54288 0:dbad57390bd1 1366
ram54288 0:dbad57390bd1 1367 return (uint8_t)tmpLQI;
ram54288 0:dbad57390bd1 1368 }
ram54288 0:dbad57390bd1 1369 }
ram54288 0:dbad57390bd1 1370
ram54288 0:dbad57390bd1 1371 /*
ram54288 0:dbad57390bd1 1372 * \brief Function enables/disables Rx promiscuous mode.
ram54288 0:dbad57390bd1 1373 *
ram54288 0:dbad57390bd1 1374 * \param state of XCVR promiscuous mode
ram54288 0:dbad57390bd1 1375 *
ram54288 0:dbad57390bd1 1376 * \return none
ram54288 0:dbad57390bd1 1377 */
ram54288 0:dbad57390bd1 1378 static void rf_promiscuous(uint8_t state)
ram54288 0:dbad57390bd1 1379 {
ram54288 0:dbad57390bd1 1380 uint8_t rxFrameFltReg, phyCtrl4Reg;
ram54288 0:dbad57390bd1 1381
ram54288 0:dbad57390bd1 1382 rxFrameFltReg = MCR20Drv_IndirectAccessSPIRead(RX_FRAME_FILTER);
ram54288 0:dbad57390bd1 1383 phyCtrl4Reg = MCR20Drv_DirectAccessSPIRead(PHY_CTRL4);
ram54288 0:dbad57390bd1 1384
ram54288 0:dbad57390bd1 1385 if( state )
ram54288 0:dbad57390bd1 1386 {
ram54288 0:dbad57390bd1 1387 /* FRM_VER[1:0] = b00. 00: Any FrameVersion accepted (0,1,2 & 3) */
ram54288 0:dbad57390bd1 1388 /* All frame types accepted*/
ram54288 0:dbad57390bd1 1389 phyCtrl4Reg |= cPHY_CTRL4_PROMISCUOUS;
ram54288 0:dbad57390bd1 1390 rxFrameFltReg &= ~(cRX_FRAME_FLT_FRM_VER);
ram54288 0:dbad57390bd1 1391 rxFrameFltReg |= (cRX_FRAME_FLT_ACK_FT | cRX_FRAME_FLT_NS_FT);
ram54288 0:dbad57390bd1 1392 }
ram54288 0:dbad57390bd1 1393 else
ram54288 0:dbad57390bd1 1394 {
ram54288 0:dbad57390bd1 1395 phyCtrl4Reg &= ~cPHY_CTRL4_PROMISCUOUS;
ram54288 0:dbad57390bd1 1396 /* FRM_VER[1:0] = b11. Accept FrameVersion 0 and 1 packets, reject all others */
ram54288 0:dbad57390bd1 1397 /* Beacon, Data and MAC command frame types accepted */
ram54288 0:dbad57390bd1 1398 rxFrameFltReg &= ~(cRX_FRAME_FLT_FRM_VER);
ram54288 0:dbad57390bd1 1399 rxFrameFltReg |= (0x03 << cRX_FRAME_FLT_FRM_VER_Shift_c);
ram54288 0:dbad57390bd1 1400 rxFrameFltReg &= ~(cRX_FRAME_FLT_ACK_FT | cRX_FRAME_FLT_NS_FT);
ram54288 0:dbad57390bd1 1401 }
ram54288 0:dbad57390bd1 1402
ram54288 0:dbad57390bd1 1403 MCR20Drv_IndirectAccessSPIWrite(RX_FRAME_FILTER, rxFrameFltReg);
ram54288 0:dbad57390bd1 1404 MCR20Drv_DirectAccessSPIWrite(PHY_CTRL4, phyCtrl4Reg);
ram54288 0:dbad57390bd1 1405 }
ram54288 0:dbad57390bd1 1406
ram54288 0:dbad57390bd1 1407 /*
ram54288 0:dbad57390bd1 1408 * \brief Function used to switch XCVR power state.
ram54288 0:dbad57390bd1 1409 *
ram54288 0:dbad57390bd1 1410 * \param state The XCVR power mode
ram54288 0:dbad57390bd1 1411 *
ram54288 0:dbad57390bd1 1412 * \return none
ram54288 0:dbad57390bd1 1413 */
ram54288 0:dbad57390bd1 1414 static void rf_set_power_state(xcvrPwrMode_t newState)
ram54288 0:dbad57390bd1 1415 {
ram54288 0:dbad57390bd1 1416 uint8_t pwrMode;
ram54288 0:dbad57390bd1 1417 uint8_t xtalState;
ram54288 0:dbad57390bd1 1418
ram54288 0:dbad57390bd1 1419 if( mPwrState == newState )
ram54288 0:dbad57390bd1 1420 {
ram54288 0:dbad57390bd1 1421 return;
ram54288 0:dbad57390bd1 1422 }
ram54288 0:dbad57390bd1 1423
ram54288 0:dbad57390bd1 1424 /* Read power settings from RF */
ram54288 0:dbad57390bd1 1425 pwrMode = MCR20Drv_DirectAccessSPIRead(PWR_MODES);
ram54288 0:dbad57390bd1 1426 xtalState = pwrMode & cPWR_MODES_XTALEN;
ram54288 0:dbad57390bd1 1427
ram54288 0:dbad57390bd1 1428 switch( newState )
ram54288 0:dbad57390bd1 1429 {
ram54288 0:dbad57390bd1 1430 case gXcvrPwrIdle_c:
ram54288 0:dbad57390bd1 1431 pwrMode &= ~(cPWR_MODES_AUTODOZE);
ram54288 0:dbad57390bd1 1432 pwrMode |= (cPWR_MODES_XTALEN | cPWR_MODES_PMC_MODE);
ram54288 0:dbad57390bd1 1433 break;
ram54288 0:dbad57390bd1 1434 case gXcvrPwrAutodoze_c:
ram54288 0:dbad57390bd1 1435 pwrMode |= (cPWR_MODES_XTALEN | cPWR_MODES_AUTODOZE | cPWR_MODES_PMC_MODE);
ram54288 0:dbad57390bd1 1436 break;
ram54288 0:dbad57390bd1 1437 case gXcvrPwrDoze_c:
ram54288 0:dbad57390bd1 1438 pwrMode &= ~(cPWR_MODES_AUTODOZE | cPWR_MODES_PMC_MODE);
ram54288 0:dbad57390bd1 1439 pwrMode |= cPWR_MODES_XTALEN;
ram54288 0:dbad57390bd1 1440 break;
ram54288 0:dbad57390bd1 1441 case gXcvrPwrHibernate_c:
ram54288 0:dbad57390bd1 1442 pwrMode &= ~(cPWR_MODES_XTALEN | cPWR_MODES_AUTODOZE | cPWR_MODES_PMC_MODE);
ram54288 0:dbad57390bd1 1443 break;
ram54288 0:dbad57390bd1 1444 default:
ram54288 0:dbad57390bd1 1445 return;
ram54288 0:dbad57390bd1 1446 }
ram54288 0:dbad57390bd1 1447
ram54288 0:dbad57390bd1 1448 mPwrState = newState;
ram54288 0:dbad57390bd1 1449 MCR20Drv_DirectAccessSPIWrite(PWR_MODES, pwrMode);
ram54288 0:dbad57390bd1 1450
ram54288 0:dbad57390bd1 1451 if( !xtalState && (pwrMode & cPWR_MODES_XTALEN))
ram54288 0:dbad57390bd1 1452 {
ram54288 0:dbad57390bd1 1453 /* wait for crystal oscillator to complet its warmup */
ram54288 0:dbad57390bd1 1454 while( ( MCR20Drv_DirectAccessSPIRead(PWR_MODES) & cPWR_MODES_XTAL_READY ) != cPWR_MODES_XTAL_READY);
ram54288 0:dbad57390bd1 1455 /* wait for radio wakeup from hibernate interrupt */
ram54288 0:dbad57390bd1 1456 while( ( MCR20Drv_DirectAccessSPIRead(IRQSTS2) & (cIRQSTS2_WAKE_IRQ | cIRQSTS2_TMRSTATUS) ) != (cIRQSTS2_WAKE_IRQ | cIRQSTS2_TMRSTATUS) );
ram54288 0:dbad57390bd1 1457
ram54288 0:dbad57390bd1 1458 MCR20Drv_DirectAccessSPIWrite(IRQSTS2, cIRQSTS2_WAKE_IRQ);
ram54288 0:dbad57390bd1 1459 }
ram54288 0:dbad57390bd1 1460 }
ram54288 0:dbad57390bd1 1461
ram54288 0:dbad57390bd1 1462 /*
ram54288 0:dbad57390bd1 1463 * \brief Function reads the energy level on the preselected channel.
ram54288 0:dbad57390bd1 1464 *
ram54288 0:dbad57390bd1 1465 * \return energy level
ram54288 0:dbad57390bd1 1466 */
ram54288 0:dbad57390bd1 1467 static uint8_t rf_get_channel_energy(void)
ram54288 0:dbad57390bd1 1468 {
ram54288 0:dbad57390bd1 1469 uint8_t ccaMode;
ram54288 0:dbad57390bd1 1470
ram54288 0:dbad57390bd1 1471 MCR20Drv_IRQ_Disable();
ram54288 0:dbad57390bd1 1472 /* RX can start only from Idle state */
ram54288 0:dbad57390bd1 1473 if( mPhySeqState != gIdle_c )
ram54288 0:dbad57390bd1 1474 {
ram54288 0:dbad57390bd1 1475 MCR20Drv_IRQ_Enable();
ram54288 0:dbad57390bd1 1476 return 0;
ram54288 0:dbad57390bd1 1477 }
ram54288 0:dbad57390bd1 1478
ram54288 0:dbad57390bd1 1479 /* Set XCVR power state in run mode */
ram54288 0:dbad57390bd1 1480 rf_set_power_state(gXcvrRunState_d);
ram54288 0:dbad57390bd1 1481
ram54288 0:dbad57390bd1 1482 /* Switch to ED mode */
ram54288 0:dbad57390bd1 1483 ccaMode = (mStatusAndControlRegs[PHY_CTRL4] >> cPHY_CTRL4_CCATYPE_Shift_c) & cPHY_CTRL4_CCATYPE;
ram54288 0:dbad57390bd1 1484 if( ccaMode != gCcaED_c )
ram54288 0:dbad57390bd1 1485 {
ram54288 0:dbad57390bd1 1486 mStatusAndControlRegs[PHY_CTRL4] &= ~(cPHY_CTRL4_CCATYPE << cPHY_CTRL4_CCATYPE_Shift_c);
ram54288 0:dbad57390bd1 1487 mStatusAndControlRegs[PHY_CTRL4] |= gCcaED_c << cPHY_CTRL4_CCATYPE_Shift_c;
ram54288 0:dbad57390bd1 1488 MCR20Drv_DirectAccessSPIWrite(PHY_CTRL4, mStatusAndControlRegs[PHY_CTRL4]);
ram54288 0:dbad57390bd1 1489 }
ram54288 0:dbad57390bd1 1490
ram54288 0:dbad57390bd1 1491 /* Start ED sequence */
ram54288 0:dbad57390bd1 1492 mStatusAndControlRegs[PHY_CTRL1] |= gCCA_c;
ram54288 0:dbad57390bd1 1493 MCR20Drv_DirectAccessSPIWrite(IRQSTS1, cIRQSTS1_CCAIRQ | cIRQSTS1_SEQIRQ);
ram54288 0:dbad57390bd1 1494 MCR20Drv_DirectAccessSPIWrite(PHY_CTRL1, mStatusAndControlRegs[PHY_CTRL1]);
ram54288 0:dbad57390bd1 1495 /* Wait for sequence to finish */
ram54288 0:dbad57390bd1 1496 while ( !(MCR20Drv_DirectAccessSPIRead(IRQSTS1) & cIRQSTS1_SEQIRQ));
ram54288 0:dbad57390bd1 1497 /* Set XCVR to Idle */
ram54288 0:dbad57390bd1 1498 mStatusAndControlRegs[PHY_CTRL1] &= ~(cPHY_CTRL1_XCVSEQ);
ram54288 0:dbad57390bd1 1499 MCR20Drv_DirectAccessSPIWrite(PHY_CTRL1, mStatusAndControlRegs[PHY_CTRL1]);
ram54288 0:dbad57390bd1 1500 MCR20Drv_DirectAccessSPIWrite(IRQSTS1, cIRQSTS1_CCAIRQ | cIRQSTS1_SEQIRQ);
ram54288 0:dbad57390bd1 1501
ram54288 0:dbad57390bd1 1502 MCR20Drv_IRQ_Enable();
ram54288 0:dbad57390bd1 1503
ram54288 0:dbad57390bd1 1504 return rf_convert_energy_level(MCR20Drv_DirectAccessSPIRead(CCA1_ED_FNL));
ram54288 0:dbad57390bd1 1505 }
ram54288 0:dbad57390bd1 1506
ram54288 0:dbad57390bd1 1507 /*
ram54288 0:dbad57390bd1 1508 * \brief Function converts the energy level from dBm to a 0-255 value.
ram54288 0:dbad57390bd1 1509 *
ram54288 0:dbad57390bd1 1510 * \param energyLevel in dBm
ram54288 0:dbad57390bd1 1511 *
ram54288 0:dbad57390bd1 1512 * \return energy level (0-255)
ram54288 0:dbad57390bd1 1513 */
ram54288 0:dbad57390bd1 1514 static uint8_t rf_convert_energy_level(uint8_t energyLevel)
ram54288 0:dbad57390bd1 1515 {
ram54288 0:dbad57390bd1 1516 if(energyLevel >= 90)
ram54288 0:dbad57390bd1 1517 {
ram54288 0:dbad57390bd1 1518 /* ED value is below minimum. Return 0x00. */
ram54288 0:dbad57390bd1 1519 energyLevel = 0x00;
ram54288 0:dbad57390bd1 1520 }
ram54288 0:dbad57390bd1 1521 else if(energyLevel <= 26)
ram54288 0:dbad57390bd1 1522 {
ram54288 0:dbad57390bd1 1523 /* ED value is above maximum. Return 0xFF. */
ram54288 0:dbad57390bd1 1524 energyLevel = 0xFF;
ram54288 0:dbad57390bd1 1525 }
ram54288 0:dbad57390bd1 1526 else
ram54288 0:dbad57390bd1 1527 {
ram54288 0:dbad57390bd1 1528 /* Energy level (-90 dBm to -26 dBm ) --> varies form 0 to 64 */
ram54288 0:dbad57390bd1 1529 energyLevel = (90 - energyLevel);
ram54288 0:dbad57390bd1 1530 /* Rescale the energy level values to the 0x00-0xff range (0 to 64 translates in 0 to 255) */
ram54288 0:dbad57390bd1 1531 /* energyLevel * 3.9844 ~= 4 */
ram54288 0:dbad57390bd1 1532 /* Multiply with 4=2^2 by shifting left.
ram54288 0:dbad57390bd1 1533 The multiplication will not overflow beacause energyLevel has values between 0 and 63 */
ram54288 0:dbad57390bd1 1534 energyLevel <<= 2;
ram54288 0:dbad57390bd1 1535 }
ram54288 0:dbad57390bd1 1536
ram54288 0:dbad57390bd1 1537 return energyLevel;
ram54288 0:dbad57390bd1 1538 }
ram54288 0:dbad57390bd1 1539
ram54288 0:dbad57390bd1 1540 static uint8_t rf_scale_lqi(int8_t rssi)
ram54288 0:dbad57390bd1 1541 {
ram54288 0:dbad57390bd1 1542 uint8_t scaled_lqi;
ram54288 0:dbad57390bd1 1543 /*Worst case sensitivity*/
ram54288 0:dbad57390bd1 1544 const int8_t rf_sensitivity = -98;
ram54288 0:dbad57390bd1 1545
ram54288 0:dbad57390bd1 1546 /*rssi < RF sensitivity*/
ram54288 0:dbad57390bd1 1547 if(rssi < rf_sensitivity)
ram54288 0:dbad57390bd1 1548 scaled_lqi=0;
ram54288 0:dbad57390bd1 1549 /*-91 dBm < rssi < -81 dBm (AT86RF233 XPro)*/
ram54288 0:dbad57390bd1 1550 /*-90 dBm < rssi < -80 dBm (AT86RF212B XPro)*/
ram54288 0:dbad57390bd1 1551 else if(rssi < (rf_sensitivity + 10))
ram54288 0:dbad57390bd1 1552 scaled_lqi=31;
ram54288 0:dbad57390bd1 1553 /*-81 dBm < rssi < -71 dBm (AT86RF233 XPro)*/
ram54288 0:dbad57390bd1 1554 /*-80 dBm < rssi < -70 dBm (AT86RF212B XPro)*/
ram54288 0:dbad57390bd1 1555 else if(rssi < (rf_sensitivity + 20))
ram54288 0:dbad57390bd1 1556 scaled_lqi=207;
ram54288 0:dbad57390bd1 1557 /*-71 dBm < rssi < -61 dBm (AT86RF233 XPro)*/
ram54288 0:dbad57390bd1 1558 /*-70 dBm < rssi < -60 dBm (AT86RF212B XPro)*/
ram54288 0:dbad57390bd1 1559 else if(rssi < (rf_sensitivity + 30))
ram54288 0:dbad57390bd1 1560 scaled_lqi=255;
ram54288 0:dbad57390bd1 1561 /*-61 dBm < rssi < -51 dBm (AT86RF233 XPro)*/
ram54288 0:dbad57390bd1 1562 /*-60 dBm < rssi < -50 dBm (AT86RF212B XPro)*/
ram54288 0:dbad57390bd1 1563 else if(rssi < (rf_sensitivity + 40))
ram54288 0:dbad57390bd1 1564 scaled_lqi=255;
ram54288 0:dbad57390bd1 1565 /*-51 dBm < rssi < -41 dBm (AT86RF233 XPro)*/
ram54288 0:dbad57390bd1 1566 /*-50 dBm < rssi < -40 dBm (AT86RF212B XPro)*/
ram54288 0:dbad57390bd1 1567 else if(rssi < (rf_sensitivity + 50))
ram54288 0:dbad57390bd1 1568 scaled_lqi=255;
ram54288 0:dbad57390bd1 1569 /*-41 dBm < rssi < -31 dBm (AT86RF233 XPro)*/
ram54288 0:dbad57390bd1 1570 /*-40 dBm < rssi < -30 dBm (AT86RF212B XPro)*/
ram54288 0:dbad57390bd1 1571 else if(rssi < (rf_sensitivity + 60))
ram54288 0:dbad57390bd1 1572 scaled_lqi=255;
ram54288 0:dbad57390bd1 1573 /*-31 dBm < rssi < -21 dBm (AT86RF233 XPro)*/
ram54288 0:dbad57390bd1 1574 /*-30 dBm < rssi < -20 dBm (AT86RF212B XPro)*/
ram54288 0:dbad57390bd1 1575 else if(rssi < (rf_sensitivity + 70))
ram54288 0:dbad57390bd1 1576 scaled_lqi=255;
ram54288 0:dbad57390bd1 1577 /*rssi > RF saturation*/
ram54288 0:dbad57390bd1 1578 else if(rssi > (rf_sensitivity + 80))
ram54288 0:dbad57390bd1 1579 scaled_lqi=111;
ram54288 0:dbad57390bd1 1580 /*-21 dBm < rssi < -11 dBm (AT86RF233 XPro)*/
ram54288 0:dbad57390bd1 1581 /*-20 dBm < rssi < -10 dBm (AT86RF212B XPro)*/
ram54288 0:dbad57390bd1 1582 else
ram54288 0:dbad57390bd1 1583 scaled_lqi=255;
ram54288 0:dbad57390bd1 1584
ram54288 0:dbad57390bd1 1585 return scaled_lqi;
ram54288 0:dbad57390bd1 1586 }
ram54288 0:dbad57390bd1 1587
ram54288 0:dbad57390bd1 1588
ram54288 0:dbad57390bd1 1589 /*****************************************************************************/
ram54288 0:dbad57390bd1 1590 /* Layer porting to the Freescale driver */
ram54288 0:dbad57390bd1 1591 /*****************************************************************************/
ram54288 0:dbad57390bd1 1592 extern "C" void xcvr_spi_init(uint32_t instance)
ram54288 0:dbad57390bd1 1593 {
ram54288 0:dbad57390bd1 1594 (void)instance;
ram54288 0:dbad57390bd1 1595 }
ram54288 0:dbad57390bd1 1596
ram54288 0:dbad57390bd1 1597 extern "C" void RF_IRQ_Init(void) {
ram54288 0:dbad57390bd1 1598 MBED_ASSERT(irq != NULL);
ram54288 0:dbad57390bd1 1599 irq->mode(PullUp);
ram54288 0:dbad57390bd1 1600 irq->fall(&PHY_InterruptHandler);
ram54288 0:dbad57390bd1 1601 }
ram54288 0:dbad57390bd1 1602
ram54288 0:dbad57390bd1 1603 extern "C" void RF_IRQ_Enable(void) {
ram54288 0:dbad57390bd1 1604 MBED_ASSERT(irq != NULL);
ram54288 0:dbad57390bd1 1605 irq->enable_irq();
ram54288 0:dbad57390bd1 1606 }
ram54288 0:dbad57390bd1 1607
ram54288 0:dbad57390bd1 1608 extern "C" void RF_IRQ_Disable(void) {
ram54288 0:dbad57390bd1 1609 MBED_ASSERT(irq != NULL);
ram54288 0:dbad57390bd1 1610 irq->disable_irq();
ram54288 0:dbad57390bd1 1611 }
ram54288 0:dbad57390bd1 1612
ram54288 0:dbad57390bd1 1613 extern "C" uint8_t RF_isIRQ_Pending(void) {
ram54288 0:dbad57390bd1 1614 MBED_ASSERT(rf != NULL);
ram54288 0:dbad57390bd1 1615 return !irq_pin->read();
ram54288 0:dbad57390bd1 1616 }
ram54288 0:dbad57390bd1 1617
ram54288 0:dbad57390bd1 1618 extern "C" void RF_RST_Set(int state) {
ram54288 0:dbad57390bd1 1619 MBED_ASSERT(rst != NULL);
ram54288 0:dbad57390bd1 1620 *rst = state;
ram54288 0:dbad57390bd1 1621 }
ram54288 0:dbad57390bd1 1622
ram54288 0:dbad57390bd1 1623 extern "C" void gXcvrAssertCS_d(void)
ram54288 0:dbad57390bd1 1624 {
ram54288 0:dbad57390bd1 1625 MBED_ASSERT(cs != NULL);
ram54288 0:dbad57390bd1 1626 *cs = 0;
ram54288 0:dbad57390bd1 1627 }
ram54288 0:dbad57390bd1 1628
ram54288 0:dbad57390bd1 1629 extern "C" void gXcvrDeassertCS_d(void)
ram54288 0:dbad57390bd1 1630 {
ram54288 0:dbad57390bd1 1631 MBED_ASSERT(cs != NULL);
ram54288 0:dbad57390bd1 1632 *cs = 1;
ram54288 0:dbad57390bd1 1633 }
ram54288 0:dbad57390bd1 1634
ram54288 0:dbad57390bd1 1635 extern "C" void xcvr_spi_configure_speed(uint32_t instance, uint32_t freq)
ram54288 0:dbad57390bd1 1636 {
ram54288 0:dbad57390bd1 1637 MBED_ASSERT(spi != NULL);
ram54288 0:dbad57390bd1 1638 (void)instance;
ram54288 0:dbad57390bd1 1639 spi->frequency(freq);
ram54288 0:dbad57390bd1 1640 }
ram54288 0:dbad57390bd1 1641
ram54288 0:dbad57390bd1 1642 extern "C" void xcvr_spi_transfer(uint32_t instance,
ram54288 0:dbad57390bd1 1643 uint8_t * sendBuffer,
ram54288 0:dbad57390bd1 1644 uint8_t * receiveBuffer,
ram54288 0:dbad57390bd1 1645 size_t transferByteCount)
ram54288 0:dbad57390bd1 1646 {
ram54288 0:dbad57390bd1 1647 MBED_ASSERT(spi != NULL);
ram54288 0:dbad57390bd1 1648 (void)instance;
ram54288 0:dbad57390bd1 1649 volatile uint8_t dummy;
ram54288 0:dbad57390bd1 1650
ram54288 0:dbad57390bd1 1651 if( !transferByteCount )
ram54288 0:dbad57390bd1 1652 return;
ram54288 0:dbad57390bd1 1653
ram54288 0:dbad57390bd1 1654 if( !sendBuffer && !receiveBuffer )
ram54288 0:dbad57390bd1 1655 return;
ram54288 0:dbad57390bd1 1656
ram54288 0:dbad57390bd1 1657 while( transferByteCount-- )
ram54288 0:dbad57390bd1 1658 {
ram54288 0:dbad57390bd1 1659 if( sendBuffer )
ram54288 0:dbad57390bd1 1660 {
ram54288 0:dbad57390bd1 1661 dummy = *sendBuffer;
ram54288 0:dbad57390bd1 1662 sendBuffer++;
ram54288 0:dbad57390bd1 1663 }
ram54288 0:dbad57390bd1 1664 else
ram54288 0:dbad57390bd1 1665 {
ram54288 0:dbad57390bd1 1666 dummy = 0xFF;
ram54288 0:dbad57390bd1 1667 }
ram54288 0:dbad57390bd1 1668
ram54288 0:dbad57390bd1 1669 dummy = spi->write(dummy);
ram54288 0:dbad57390bd1 1670
ram54288 0:dbad57390bd1 1671 if( receiveBuffer )
ram54288 0:dbad57390bd1 1672 {
ram54288 0:dbad57390bd1 1673 *receiveBuffer = dummy;
ram54288 0:dbad57390bd1 1674 receiveBuffer++;
ram54288 0:dbad57390bd1 1675 }
ram54288 0:dbad57390bd1 1676 }
ram54288 0:dbad57390bd1 1677 }
ram54288 0:dbad57390bd1 1678
ram54288 0:dbad57390bd1 1679 /*****************************************************************************/
ram54288 0:dbad57390bd1 1680 /*****************************************************************************/
ram54288 0:dbad57390bd1 1681
ram54288 0:dbad57390bd1 1682 static void rf_if_lock(void)
ram54288 0:dbad57390bd1 1683 {
ram54288 0:dbad57390bd1 1684 platform_enter_critical();
ram54288 0:dbad57390bd1 1685 }
ram54288 0:dbad57390bd1 1686
ram54288 0:dbad57390bd1 1687 static void rf_if_unlock(void)
ram54288 0:dbad57390bd1 1688 {
ram54288 0:dbad57390bd1 1689 platform_exit_critical();
ram54288 0:dbad57390bd1 1690 }
ram54288 0:dbad57390bd1 1691
ram54288 0:dbad57390bd1 1692 NanostackRfPhyMcr20a::NanostackRfPhyMcr20a(PinName spi_mosi, PinName spi_miso,
ram54288 0:dbad57390bd1 1693 PinName spi_sclk, PinName spi_cs, PinName spi_rst, PinName spi_irq)
ram54288 0:dbad57390bd1 1694 : _spi(spi_mosi, spi_miso, spi_sclk), _rf_cs(spi_cs), _rf_rst(spi_rst),
ram54288 0:dbad57390bd1 1695 _rf_irq(spi_irq), _rf_irq_pin(spi_irq)
ram54288 0:dbad57390bd1 1696 {
ram54288 0:dbad57390bd1 1697 // Do nothing
ram54288 0:dbad57390bd1 1698 }
ram54288 0:dbad57390bd1 1699
ram54288 0:dbad57390bd1 1700 NanostackRfPhyMcr20a::~NanostackRfPhyMcr20a()
ram54288 0:dbad57390bd1 1701 {
ram54288 0:dbad57390bd1 1702 // Do nothing
ram54288 0:dbad57390bd1 1703 }
ram54288 0:dbad57390bd1 1704
ram54288 0:dbad57390bd1 1705 int8_t NanostackRfPhyMcr20a::rf_register()
ram54288 0:dbad57390bd1 1706 {
ram54288 0:dbad57390bd1 1707
ram54288 0:dbad57390bd1 1708 rf_if_lock();
ram54288 0:dbad57390bd1 1709
ram54288 0:dbad57390bd1 1710 if (rf != NULL) {
ram54288 0:dbad57390bd1 1711 rf_if_unlock();
ram54288 0:dbad57390bd1 1712 error("Multiple registrations of NanostackRfPhyMcr20a not supported");
ram54288 0:dbad57390bd1 1713 return -1;
ram54288 0:dbad57390bd1 1714 }
ram54288 0:dbad57390bd1 1715
ram54288 0:dbad57390bd1 1716 _pins_set();
ram54288 0:dbad57390bd1 1717 int8_t radio_id = rf_device_register();
ram54288 0:dbad57390bd1 1718 if (radio_id < 0) {
ram54288 0:dbad57390bd1 1719 _pins_clear();
ram54288 0:dbad57390bd1 1720 rf = NULL;
ram54288 0:dbad57390bd1 1721 }
ram54288 0:dbad57390bd1 1722
ram54288 0:dbad57390bd1 1723 rf_if_unlock();
ram54288 0:dbad57390bd1 1724 return radio_id;
ram54288 0:dbad57390bd1 1725 }
ram54288 0:dbad57390bd1 1726
ram54288 0:dbad57390bd1 1727 void NanostackRfPhyMcr20a::rf_unregister()
ram54288 0:dbad57390bd1 1728 {
ram54288 0:dbad57390bd1 1729 rf_if_lock();
ram54288 0:dbad57390bd1 1730
ram54288 0:dbad57390bd1 1731 if (rf != this) {
ram54288 0:dbad57390bd1 1732 rf_if_unlock();
ram54288 0:dbad57390bd1 1733 return;
ram54288 0:dbad57390bd1 1734 }
ram54288 0:dbad57390bd1 1735
ram54288 0:dbad57390bd1 1736 rf_device_unregister();
ram54288 0:dbad57390bd1 1737 rf = NULL;
ram54288 0:dbad57390bd1 1738 _pins_clear();
ram54288 0:dbad57390bd1 1739
ram54288 0:dbad57390bd1 1740 rf_if_unlock();
ram54288 0:dbad57390bd1 1741 }
ram54288 0:dbad57390bd1 1742
ram54288 0:dbad57390bd1 1743 void NanostackRfPhyMcr20a::get_mac_address(uint8_t *mac)
ram54288 0:dbad57390bd1 1744 {
ram54288 0:dbad57390bd1 1745 rf_if_lock();
ram54288 0:dbad57390bd1 1746
ram54288 0:dbad57390bd1 1747 memcpy((void*)mac, (void*)MAC_address, sizeof(MAC_address));
ram54288 0:dbad57390bd1 1748
ram54288 0:dbad57390bd1 1749 rf_if_unlock();
ram54288 0:dbad57390bd1 1750 }
ram54288 0:dbad57390bd1 1751
ram54288 0:dbad57390bd1 1752 void NanostackRfPhyMcr20a::set_mac_address(uint8_t *mac)
ram54288 0:dbad57390bd1 1753 {
ram54288 0:dbad57390bd1 1754 rf_if_lock();
ram54288 0:dbad57390bd1 1755
ram54288 0:dbad57390bd1 1756 if (NULL != rf) {
ram54288 0:dbad57390bd1 1757 error("NanostackRfPhyAtmel cannot change mac address when running");
ram54288 0:dbad57390bd1 1758 rf_if_unlock();
ram54288 0:dbad57390bd1 1759 return;
ram54288 0:dbad57390bd1 1760 }
ram54288 0:dbad57390bd1 1761 memcpy((void*)MAC_address, (void*)mac, sizeof(MAC_address));
ram54288 0:dbad57390bd1 1762
ram54288 0:dbad57390bd1 1763 rf_if_unlock();
ram54288 0:dbad57390bd1 1764 }
ram54288 0:dbad57390bd1 1765
ram54288 0:dbad57390bd1 1766 void NanostackRfPhyMcr20a::_pins_set()
ram54288 0:dbad57390bd1 1767 {
ram54288 0:dbad57390bd1 1768 spi = &_spi;
ram54288 0:dbad57390bd1 1769 cs = &_rf_cs;
ram54288 0:dbad57390bd1 1770 rst = &_rf_rst;
ram54288 0:dbad57390bd1 1771 irq = &_rf_irq;
ram54288 0:dbad57390bd1 1772 irq_pin = &_rf_irq_pin;
ram54288 0:dbad57390bd1 1773 }
ram54288 0:dbad57390bd1 1774
ram54288 0:dbad57390bd1 1775 void NanostackRfPhyMcr20a::_pins_clear()
ram54288 0:dbad57390bd1 1776 {
ram54288 0:dbad57390bd1 1777 spi = NULL;
ram54288 0:dbad57390bd1 1778 cs = NULL;
ram54288 0:dbad57390bd1 1779 rst = NULL;
ram54288 0:dbad57390bd1 1780 irq = NULL;
ram54288 0:dbad57390bd1 1781 irq_pin = NULL;
ram54288 0:dbad57390bd1 1782 }