my customized lib

Committer:
DuyLionTran
Date:
Sun Nov 26 15:08:14 2017 +0000
Revision:
0:8094b249013c
Initial commit

Who changed what in which revision?

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