Easily add all supported connectivity methods to your mbed OS project

Dependencies:   type-yd-driver

Committer:
MACRUM
Date:
Wed Jul 12 10:52:58 2017 +0000
Revision:
0:615f90842ce8
Initial commit

Who changed what in which revision?

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