A metronome using the FRDM K64F board

Committer:
ram54288
Date:
Sun May 14 18:40:18 2017 +0000
Revision:
0:a7a43371b306
Initial commit

Who changed what in which revision?

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