Fork of my original MQTTGateway

Dependencies:   mbed-http

Committer:
vpcola
Date:
Sat Apr 08 14:43:14 2017 +0000
Revision:
0:a1734fe1ec4b
Initial commit

Who changed what in which revision?

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