Added support for WNC M14A2A Cellular LTE Data Module.

Dependencies:   WNC14A2AInterface

Dependents:   http-example-wnc http-example-wnc-modified

Committer:
JMF
Date:
Wed Apr 19 01:13:10 2017 +0000
Revision:
0:2563b0415d1f
Initial commit

Who changed what in which revision?

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