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 <string.h>
DuyLionTran 0:8094b249013c 17 #include "platform/arm_hal_interrupt.h"
DuyLionTran 0:8094b249013c 18 #include "nanostack/platform/arm_hal_phy.h"
DuyLionTran 0:8094b249013c 19 #include "ns_types.h"
DuyLionTran 0:8094b249013c 20 #include "NanostackRfPhyAtmel.h"
DuyLionTran 0:8094b249013c 21 #include "randLIB.h"
DuyLionTran 0:8094b249013c 22 #include "AT86RFReg.h"
DuyLionTran 0:8094b249013c 23 #include "nanostack/platform/arm_hal_phy.h"
DuyLionTran 0:8094b249013c 24 #include "toolchain.h"
DuyLionTran 0:8094b249013c 25
DuyLionTran 0:8094b249013c 26 /*Worst case sensitivity*/
DuyLionTran 0:8094b249013c 27 #define RF_DEFAULT_SENSITIVITY -88
DuyLionTran 0:8094b249013c 28 /*Run calibration every 5 minutes*/
DuyLionTran 0:8094b249013c 29 #define RF_CALIBRATION_INTERVAL 6000000
DuyLionTran 0:8094b249013c 30 /*Wait ACK for 2.5ms*/
DuyLionTran 0:8094b249013c 31 #define RF_ACK_WAIT_DEFAULT_TIMEOUT 50
DuyLionTran 0:8094b249013c 32 /*Base CCA backoff (50us units) - substitutes for Inter-Frame Spacing*/
DuyLionTran 0:8094b249013c 33 #define RF_CCA_BASE_BACKOFF 13 /* 650us */
DuyLionTran 0:8094b249013c 34 /*CCA random backoff (50us units)*/
DuyLionTran 0:8094b249013c 35 #define RF_CCA_RANDOM_BACKOFF 51 /* 2550us */
DuyLionTran 0:8094b249013c 36
DuyLionTran 0:8094b249013c 37 #define RF_BUFFER_SIZE 128
DuyLionTran 0:8094b249013c 38
DuyLionTran 0:8094b249013c 39 #define RF_PHY_MODE OQPSK_SIN_250
DuyLionTran 0:8094b249013c 40
DuyLionTran 0:8094b249013c 41 /*Radio RX and TX state definitions*/
DuyLionTran 0:8094b249013c 42 #define RFF_ON 0x01
DuyLionTran 0:8094b249013c 43 #define RFF_RX 0x02
DuyLionTran 0:8094b249013c 44 #define RFF_TX 0x04
DuyLionTran 0:8094b249013c 45 #define RFF_CCA 0x08
DuyLionTran 0:8094b249013c 46
DuyLionTran 0:8094b249013c 47 typedef enum
DuyLionTran 0:8094b249013c 48 {
DuyLionTran 0:8094b249013c 49 RF_MODE_NORMAL = 0,
DuyLionTran 0:8094b249013c 50 RF_MODE_SNIFFER = 1,
DuyLionTran 0:8094b249013c 51 RF_MODE_ED = 2
DuyLionTran 0:8094b249013c 52 }rf_mode_t;
DuyLionTran 0:8094b249013c 53
DuyLionTran 0:8094b249013c 54 /*Atmel RF Part Type*/
DuyLionTran 0:8094b249013c 55 typedef enum
DuyLionTran 0:8094b249013c 56 {
DuyLionTran 0:8094b249013c 57 ATMEL_UNKNOW_DEV = 0,
DuyLionTran 0:8094b249013c 58 ATMEL_AT86RF212,
DuyLionTran 0:8094b249013c 59 ATMEL_AT86RF231,
DuyLionTran 0:8094b249013c 60 ATMEL_AT86RF233
DuyLionTran 0:8094b249013c 61 }rf_trx_part_e;
DuyLionTran 0:8094b249013c 62
DuyLionTran 0:8094b249013c 63 /*Atmel RF states*/
DuyLionTran 0:8094b249013c 64 typedef enum
DuyLionTran 0:8094b249013c 65 {
DuyLionTran 0:8094b249013c 66 NOP = 0x00,
DuyLionTran 0:8094b249013c 67 BUSY_RX = 0x01,
DuyLionTran 0:8094b249013c 68 RF_TX_START = 0x02,
DuyLionTran 0:8094b249013c 69 FORCE_TRX_OFF = 0x03,
DuyLionTran 0:8094b249013c 70 FORCE_PLL_ON = 0x04,
DuyLionTran 0:8094b249013c 71 RX_ON = 0x06,
DuyLionTran 0:8094b249013c 72 TRX_OFF = 0x08,
DuyLionTran 0:8094b249013c 73 PLL_ON = 0x09,
DuyLionTran 0:8094b249013c 74 BUSY_RX_AACK = 0x11,
DuyLionTran 0:8094b249013c 75 SLEEP = 0x0F,
DuyLionTran 0:8094b249013c 76 RX_AACK_ON = 0x16,
DuyLionTran 0:8094b249013c 77 TX_ARET_ON = 0x19
DuyLionTran 0:8094b249013c 78 }rf_trx_states_t;
DuyLionTran 0:8094b249013c 79
DuyLionTran 0:8094b249013c 80 /*RF receive buffer*/
DuyLionTran 0:8094b249013c 81 static uint8_t rf_buffer[RF_BUFFER_SIZE];
DuyLionTran 0:8094b249013c 82 /*ACK wait duration changes depending on data rate*/
DuyLionTran 0:8094b249013c 83 static uint16_t rf_ack_wait_duration = RF_ACK_WAIT_DEFAULT_TIMEOUT;
DuyLionTran 0:8094b249013c 84
DuyLionTran 0:8094b249013c 85 static int8_t rf_sensitivity = RF_DEFAULT_SENSITIVITY;
DuyLionTran 0:8094b249013c 86 static rf_mode_t rf_mode = RF_MODE_NORMAL;
DuyLionTran 0:8094b249013c 87 static uint8_t radio_tx_power = 0x00; // Default to +4dBm
DuyLionTran 0:8094b249013c 88 static uint8_t rf_phy_channel = 12;
DuyLionTran 0:8094b249013c 89 static uint8_t rf_tuned = 1;
DuyLionTran 0:8094b249013c 90 static uint8_t rf_use_antenna_diversity = 0;
DuyLionTran 0:8094b249013c 91 static uint8_t tx_sequence = 0xff;
DuyLionTran 0:8094b249013c 92 static uint8_t need_ack = 0;
DuyLionTran 0:8094b249013c 93 static uint8_t rf_rx_mode = 0;
DuyLionTran 0:8094b249013c 94 static uint8_t rf_flags = 0;
DuyLionTran 0:8094b249013c 95 static uint8_t rf_rnd_rssi = 0;
DuyLionTran 0:8094b249013c 96 static int8_t rf_radio_driver_id = -1;
DuyLionTran 0:8094b249013c 97 static phy_device_driver_s device_driver;
DuyLionTran 0:8094b249013c 98 static uint8_t mac_tx_handle = 0;
DuyLionTran 0:8094b249013c 99
DuyLionTran 0:8094b249013c 100 /* Channel configurations for 2.4 and sub-GHz */
DuyLionTran 0:8094b249013c 101 static const phy_rf_channel_configuration_s phy_24ghz = {2405000000U, 5000000U, 250000U, 16U, M_OQPSK};
DuyLionTran 0:8094b249013c 102 static const phy_rf_channel_configuration_s phy_subghz = {868300000U, 2000000U, 250000U, 11U, M_OQPSK};
DuyLionTran 0:8094b249013c 103
DuyLionTran 0:8094b249013c 104 static const phy_device_channel_page_s phy_channel_pages[] = {
DuyLionTran 0:8094b249013c 105 { CHANNEL_PAGE_0, &phy_24ghz},
DuyLionTran 0:8094b249013c 106 { CHANNEL_PAGE_2, &phy_subghz},
DuyLionTran 0:8094b249013c 107 { CHANNEL_PAGE_0, NULL}
DuyLionTran 0:8094b249013c 108 };
DuyLionTran 0:8094b249013c 109
DuyLionTran 0:8094b249013c 110 /**
DuyLionTran 0:8094b249013c 111 * RF output power write
DuyLionTran 0:8094b249013c 112 *
DuyLionTran 0:8094b249013c 113 * \brief TX power has to be set before network start.
DuyLionTran 0:8094b249013c 114 *
DuyLionTran 0:8094b249013c 115 * \param power
DuyLionTran 0:8094b249013c 116 * AT86RF233
DuyLionTran 0:8094b249013c 117 * 0 = 4 dBm
DuyLionTran 0:8094b249013c 118 * 1 = 3.7 dBm
DuyLionTran 0:8094b249013c 119 * 2 = 3.4 dBm
DuyLionTran 0:8094b249013c 120 * 3 = 3 dBm
DuyLionTran 0:8094b249013c 121 * 4 = 2.5 dBm
DuyLionTran 0:8094b249013c 122 * 5 = 2 dBm
DuyLionTran 0:8094b249013c 123 * 6 = 1 dBm
DuyLionTran 0:8094b249013c 124 * 7 = 0 dBm
DuyLionTran 0:8094b249013c 125 * 8 = -1 dBm
DuyLionTran 0:8094b249013c 126 * 9 = -2 dBm
DuyLionTran 0:8094b249013c 127 * 10 = -3 dBm
DuyLionTran 0:8094b249013c 128 * 11 = -4 dBm
DuyLionTran 0:8094b249013c 129 * 12 = -6 dBm
DuyLionTran 0:8094b249013c 130 * 13 = -8 dBm
DuyLionTran 0:8094b249013c 131 * 14 = -12 dBm
DuyLionTran 0:8094b249013c 132 * 15 = -17 dBm
DuyLionTran 0:8094b249013c 133 *
DuyLionTran 0:8094b249013c 134 * AT86RF212B
DuyLionTran 0:8094b249013c 135 * See datasheet for TX power settings
DuyLionTran 0:8094b249013c 136 *
DuyLionTran 0:8094b249013c 137 * \return 0, Supported Value
DuyLionTran 0:8094b249013c 138 * \return -1, Not Supported Value
DuyLionTran 0:8094b249013c 139 */
DuyLionTran 0:8094b249013c 140 static int8_t rf_tx_power_set(uint8_t power);
DuyLionTran 0:8094b249013c 141 static rf_trx_part_e rf_radio_type_read(void);
DuyLionTran 0:8094b249013c 142 static void rf_ack_wait_timer_start(uint16_t slots);
DuyLionTran 0:8094b249013c 143 static void rf_ack_wait_timer_stop(void);
DuyLionTran 0:8094b249013c 144 static void rf_handle_cca_ed_done(void);
DuyLionTran 0:8094b249013c 145 static void rf_handle_tx_end(void);
DuyLionTran 0:8094b249013c 146 static void rf_handle_rx_end(void);
DuyLionTran 0:8094b249013c 147 static void rf_on(void);
DuyLionTran 0:8094b249013c 148 static void rf_receive(void);
DuyLionTran 0:8094b249013c 149 static void rf_poll_trx_state_change(rf_trx_states_t trx_state);
DuyLionTran 0:8094b249013c 150 static void rf_init(void);
DuyLionTran 0:8094b249013c 151 static int8_t rf_device_register(const uint8_t *mac_addr);
DuyLionTran 0:8094b249013c 152 static void rf_device_unregister(void);
DuyLionTran 0:8094b249013c 153 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 154 static void rf_cca_abort(void);
DuyLionTran 0:8094b249013c 155 static void rf_calibration_cb(void);
DuyLionTran 0:8094b249013c 156 static void rf_init_phy_mode(void);
DuyLionTran 0:8094b249013c 157 static void rf_ack_wait_timer_interrupt(void);
DuyLionTran 0:8094b249013c 158 static void rf_calibration_timer_interrupt(void);
DuyLionTran 0:8094b249013c 159 static void rf_calibration_timer_start(uint32_t slots);
DuyLionTran 0:8094b249013c 160 static void rf_cca_timer_interrupt(void);
DuyLionTran 0:8094b249013c 161 static void rf_cca_timer_start(uint32_t slots);
DuyLionTran 0:8094b249013c 162 static uint8_t rf_scale_lqi(int8_t rssi);
DuyLionTran 0:8094b249013c 163
DuyLionTran 0:8094b249013c 164 static int8_t rf_interface_state_control(phy_interface_state_e new_state, uint8_t rf_channel);
DuyLionTran 0:8094b249013c 165 static int8_t rf_extension(phy_extension_type_e extension_type,uint8_t *data_ptr);
DuyLionTran 0:8094b249013c 166 static int8_t rf_address_write(phy_address_type_e address_type,uint8_t *address_ptr);
DuyLionTran 0:8094b249013c 167
DuyLionTran 0:8094b249013c 168 static void rf_if_cca_timer_start(uint32_t slots);
DuyLionTran 0:8094b249013c 169 static void rf_if_enable_promiscuous_mode(void);
DuyLionTran 0:8094b249013c 170 static void rf_if_lock(void);
DuyLionTran 0:8094b249013c 171 static void rf_if_unlock(void);
DuyLionTran 0:8094b249013c 172 static uint8_t rf_if_read_rnd(void);
DuyLionTran 0:8094b249013c 173 static void rf_if_calibration_timer_start(uint32_t slots);
DuyLionTran 0:8094b249013c 174 static void rf_if_interrupt_handler(void);
DuyLionTran 0:8094b249013c 175 static void rf_if_ack_wait_timer_start(uint16_t slots);
DuyLionTran 0:8094b249013c 176 static void rf_if_ack_wait_timer_stop(void);
DuyLionTran 0:8094b249013c 177 static void rf_if_ack_pending_ctrl(uint8_t state);
DuyLionTran 0:8094b249013c 178 static void rf_if_calibration(void);
DuyLionTran 0:8094b249013c 179 static uint8_t rf_if_read_register(uint8_t addr);
DuyLionTran 0:8094b249013c 180 static void rf_if_set_bit(uint8_t addr, uint8_t bit, uint8_t bit_mask);
DuyLionTran 0:8094b249013c 181 static void rf_if_clear_bit(uint8_t addr, uint8_t bit);
DuyLionTran 0:8094b249013c 182 static void rf_if_write_register(uint8_t addr, uint8_t data);
DuyLionTran 0:8094b249013c 183 static void rf_if_reset_radio(void);
DuyLionTran 0:8094b249013c 184 static void rf_if_enable_ant_div(void);
DuyLionTran 0:8094b249013c 185 static void rf_if_disable_ant_div(void);
DuyLionTran 0:8094b249013c 186 static void rf_if_enable_slptr(void);
DuyLionTran 0:8094b249013c 187 static void rf_if_disable_slptr(void);
DuyLionTran 0:8094b249013c 188 static void rf_if_write_antenna_diversity_settings(void);
DuyLionTran 0:8094b249013c 189 static void rf_if_write_set_tx_power_register(uint8_t value);
DuyLionTran 0:8094b249013c 190 static void rf_if_write_rf_settings(void);
DuyLionTran 0:8094b249013c 191 static uint8_t rf_if_check_cca(void);
DuyLionTran 0:8094b249013c 192 static uint8_t rf_if_check_crc(void);
DuyLionTran 0:8094b249013c 193 static uint8_t rf_if_read_trx_state(void);
DuyLionTran 0:8094b249013c 194 static void rf_if_read_packet(uint8_t *ptr, uint8_t len);
DuyLionTran 0:8094b249013c 195 static void rf_if_write_short_addr_registers(uint8_t *short_address);
DuyLionTran 0:8094b249013c 196 static uint8_t rf_if_last_acked_pending(void);
DuyLionTran 0:8094b249013c 197 static void rf_if_write_pan_id_registers(uint8_t *pan_id);
DuyLionTran 0:8094b249013c 198 static void rf_if_write_ieee_addr_registers(uint8_t *address);
DuyLionTran 0:8094b249013c 199 static void rf_if_write_frame_buffer(uint8_t *ptr, uint8_t length);
DuyLionTran 0:8094b249013c 200 static void rf_if_change_trx_state(rf_trx_states_t trx_state);
DuyLionTran 0:8094b249013c 201 static void rf_if_enable_tx_end_interrupt(void);
DuyLionTran 0:8094b249013c 202 static void rf_if_enable_rx_end_interrupt(void);
DuyLionTran 0:8094b249013c 203 static void rf_if_enable_cca_ed_done_interrupt(void);
DuyLionTran 0:8094b249013c 204 static void rf_if_start_cca_process(void);
DuyLionTran 0:8094b249013c 205 static uint8_t rf_if_read_received_frame_length(void);
DuyLionTran 0:8094b249013c 206 static int8_t rf_if_read_rssi(void);
DuyLionTran 0:8094b249013c 207 static uint8_t rf_if_read_rx_status(void);
DuyLionTran 0:8094b249013c 208 static void rf_if_set_channel_register(uint8_t channel);
DuyLionTran 0:8094b249013c 209 static void rf_if_enable_promiscuous_mode(void);
DuyLionTran 0:8094b249013c 210 static void rf_if_disable_promiscuous_mode(void);
DuyLionTran 0:8094b249013c 211 static uint8_t rf_if_read_part_num(void);
DuyLionTran 0:8094b249013c 212 static void rf_if_enable_irq(void);
DuyLionTran 0:8094b249013c 213 static void rf_if_disable_irq(void);
DuyLionTran 0:8094b249013c 214
DuyLionTran 0:8094b249013c 215 #ifdef MBED_CONF_RTOS_PRESENT
DuyLionTran 0:8094b249013c 216 #include "mbed.h"
DuyLionTran 0:8094b249013c 217 #include "rtos.h"
DuyLionTran 0:8094b249013c 218
DuyLionTran 0:8094b249013c 219 static void rf_if_irq_task_process_irq();
DuyLionTran 0:8094b249013c 220
DuyLionTran 0:8094b249013c 221 #define SIG_RADIO 1
DuyLionTran 0:8094b249013c 222 #define SIG_TIMER_ACK 2
DuyLionTran 0:8094b249013c 223 #define SIG_TIMER_CAL 4
DuyLionTran 0:8094b249013c 224 #define SIG_TIMER_CCA 8
DuyLionTran 0:8094b249013c 225
DuyLionTran 0:8094b249013c 226 #define SIG_TIMERS (SIG_TIMER_ACK|SIG_TIMER_CAL|SIG_TIMER_CCA)
DuyLionTran 0:8094b249013c 227 #define SIG_ALL (SIG_RADIO|SIG_TIMERS)
DuyLionTran 0:8094b249013c 228 #endif
DuyLionTran 0:8094b249013c 229
DuyLionTran 0:8094b249013c 230 // HW pins to RF chip
DuyLionTran 0:8094b249013c 231 #define SPI_SPEED 7500000
DuyLionTran 0:8094b249013c 232
DuyLionTran 0:8094b249013c 233 class UnlockedSPI : public SPI {
DuyLionTran 0:8094b249013c 234 public:
DuyLionTran 0:8094b249013c 235 UnlockedSPI(PinName mosi, PinName miso, PinName sclk) :
DuyLionTran 0:8094b249013c 236 SPI(mosi, miso, sclk) { }
DuyLionTran 0:8094b249013c 237 virtual void lock() { }
DuyLionTran 0:8094b249013c 238 virtual void unlock() { }
DuyLionTran 0:8094b249013c 239 };
DuyLionTran 0:8094b249013c 240
DuyLionTran 0:8094b249013c 241 class RFBits {
DuyLionTran 0:8094b249013c 242 public:
DuyLionTran 0:8094b249013c 243 RFBits(PinName spi_mosi, PinName spi_miso,
DuyLionTran 0:8094b249013c 244 PinName spi_sclk, PinName spi_cs,
DuyLionTran 0:8094b249013c 245 PinName spi_rst, PinName spi_slp, PinName spi_irq);
DuyLionTran 0:8094b249013c 246 UnlockedSPI spi;
DuyLionTran 0:8094b249013c 247 DigitalOut CS;
DuyLionTran 0:8094b249013c 248 DigitalOut RST;
DuyLionTran 0:8094b249013c 249 DigitalOut SLP_TR;
DuyLionTran 0:8094b249013c 250 InterruptIn IRQ;
DuyLionTran 0:8094b249013c 251 Timeout ack_timer;
DuyLionTran 0:8094b249013c 252 Timeout cal_timer;
DuyLionTran 0:8094b249013c 253 Timeout cca_timer;
DuyLionTran 0:8094b249013c 254 #ifdef MBED_CONF_RTOS_PRESENT
DuyLionTran 0:8094b249013c 255 Thread irq_thread;
DuyLionTran 0:8094b249013c 256 Mutex mutex;
DuyLionTran 0:8094b249013c 257 void rf_if_irq_task();
DuyLionTran 0:8094b249013c 258 #endif
DuyLionTran 0:8094b249013c 259 };
DuyLionTran 0:8094b249013c 260
DuyLionTran 0:8094b249013c 261 RFBits::RFBits(PinName spi_mosi, PinName spi_miso,
DuyLionTran 0:8094b249013c 262 PinName spi_sclk, PinName spi_cs,
DuyLionTran 0:8094b249013c 263 PinName spi_rst, PinName spi_slp, PinName spi_irq)
DuyLionTran 0:8094b249013c 264 : spi(spi_mosi, spi_miso, spi_sclk),
DuyLionTran 0:8094b249013c 265 CS(spi_cs),
DuyLionTran 0:8094b249013c 266 RST(spi_rst),
DuyLionTran 0:8094b249013c 267 SLP_TR(spi_slp),
DuyLionTran 0:8094b249013c 268 IRQ(spi_irq)
DuyLionTran 0:8094b249013c 269 #ifdef MBED_CONF_RTOS_PRESENT
DuyLionTran 0:8094b249013c 270 ,irq_thread(osPriorityRealtime, 1024)
DuyLionTran 0:8094b249013c 271 #endif
DuyLionTran 0:8094b249013c 272 {
DuyLionTran 0:8094b249013c 273 #ifdef MBED_CONF_RTOS_PRESENT
DuyLionTran 0:8094b249013c 274 irq_thread.start(this, &RFBits::rf_if_irq_task);
DuyLionTran 0:8094b249013c 275 #endif
DuyLionTran 0:8094b249013c 276 }
DuyLionTran 0:8094b249013c 277
DuyLionTran 0:8094b249013c 278 static RFBits *rf;
DuyLionTran 0:8094b249013c 279 static uint8_t rf_part_num = 0;
DuyLionTran 0:8094b249013c 280 static uint8_t rf_rx_lqi;
DuyLionTran 0:8094b249013c 281 static int8_t rf_rx_rssi;
DuyLionTran 0:8094b249013c 282 static uint8_t rf_rx_status;
DuyLionTran 0:8094b249013c 283 /*TODO: RSSI Base value setting*/
DuyLionTran 0:8094b249013c 284 static int8_t rf_rssi_base_val = -91;
DuyLionTran 0:8094b249013c 285
DuyLionTran 0:8094b249013c 286 static uint8_t rf_if_spi_exchange(uint8_t out);
DuyLionTran 0:8094b249013c 287
DuyLionTran 0:8094b249013c 288 static void rf_if_lock(void)
DuyLionTran 0:8094b249013c 289 {
DuyLionTran 0:8094b249013c 290 platform_enter_critical();
DuyLionTran 0:8094b249013c 291 }
DuyLionTran 0:8094b249013c 292
DuyLionTran 0:8094b249013c 293 static void rf_if_unlock(void)
DuyLionTran 0:8094b249013c 294 {
DuyLionTran 0:8094b249013c 295 platform_exit_critical();
DuyLionTran 0:8094b249013c 296 }
DuyLionTran 0:8094b249013c 297
DuyLionTran 0:8094b249013c 298 #ifdef MBED_CONF_RTOS_PRESENT
DuyLionTran 0:8094b249013c 299 static void rf_if_cca_timer_signal(void)
DuyLionTran 0:8094b249013c 300 {
DuyLionTran 0:8094b249013c 301 rf->irq_thread.signal_set(SIG_TIMER_CCA);
DuyLionTran 0:8094b249013c 302 }
DuyLionTran 0:8094b249013c 303
DuyLionTran 0:8094b249013c 304 static void rf_if_cal_timer_signal(void)
DuyLionTran 0:8094b249013c 305 {
DuyLionTran 0:8094b249013c 306 rf->irq_thread.signal_set(SIG_TIMER_CAL);
DuyLionTran 0:8094b249013c 307 }
DuyLionTran 0:8094b249013c 308
DuyLionTran 0:8094b249013c 309 static void rf_if_ack_timer_signal(void)
DuyLionTran 0:8094b249013c 310 {
DuyLionTran 0:8094b249013c 311 rf->irq_thread.signal_set(SIG_TIMER_ACK);
DuyLionTran 0:8094b249013c 312 }
DuyLionTran 0:8094b249013c 313 #endif
DuyLionTran 0:8094b249013c 314
DuyLionTran 0:8094b249013c 315
DuyLionTran 0:8094b249013c 316 /* Delay functions for RF Chip SPI access */
DuyLionTran 0:8094b249013c 317 #ifdef __CC_ARM
DuyLionTran 0:8094b249013c 318 __asm static void delay_loop(uint32_t count)
DuyLionTran 0:8094b249013c 319 {
DuyLionTran 0:8094b249013c 320 1
DuyLionTran 0:8094b249013c 321 SUBS a1, a1, #1
DuyLionTran 0:8094b249013c 322 BCS %BT1
DuyLionTran 0:8094b249013c 323 BX lr
DuyLionTran 0:8094b249013c 324 }
DuyLionTran 0:8094b249013c 325 #elif defined (__ICCARM__)
DuyLionTran 0:8094b249013c 326 static void delay_loop(uint32_t count)
DuyLionTran 0:8094b249013c 327 {
DuyLionTran 0:8094b249013c 328 __asm volatile(
DuyLionTran 0:8094b249013c 329 "loop: \n"
DuyLionTran 0:8094b249013c 330 " SUBS %0, %0, #1 \n"
DuyLionTran 0:8094b249013c 331 " BCS.n loop\n"
DuyLionTran 0:8094b249013c 332 : "+r" (count)
DuyLionTran 0:8094b249013c 333 :
DuyLionTran 0:8094b249013c 334 : "cc"
DuyLionTran 0:8094b249013c 335 );
DuyLionTran 0:8094b249013c 336 }
DuyLionTran 0:8094b249013c 337 #else // GCC
DuyLionTran 0:8094b249013c 338 static void delay_loop(uint32_t count)
DuyLionTran 0:8094b249013c 339 {
DuyLionTran 0:8094b249013c 340 __asm__ volatile (
DuyLionTran 0:8094b249013c 341 "%=:\n\t"
DuyLionTran 0:8094b249013c 342 #if defined(__thumb__) && !defined(__thumb2__)
DuyLionTran 0:8094b249013c 343 "SUB %0, #1\n\t"
DuyLionTran 0:8094b249013c 344 #else
DuyLionTran 0:8094b249013c 345 "SUBS %0, %0, #1\n\t"
DuyLionTran 0:8094b249013c 346 #endif
DuyLionTran 0:8094b249013c 347 "BCS %=b\n\t"
DuyLionTran 0:8094b249013c 348 : "+l" (count)
DuyLionTran 0:8094b249013c 349 :
DuyLionTran 0:8094b249013c 350 : "cc"
DuyLionTran 0:8094b249013c 351 );
DuyLionTran 0:8094b249013c 352 }
DuyLionTran 0:8094b249013c 353 #endif
DuyLionTran 0:8094b249013c 354
DuyLionTran 0:8094b249013c 355 static void delay_ns(uint32_t ns)
DuyLionTran 0:8094b249013c 356 {
DuyLionTran 0:8094b249013c 357 uint32_t cycles_per_us = SystemCoreClock / 1000000;
DuyLionTran 0:8094b249013c 358 // Cortex-M0 takes 4 cycles per loop (SUB=1, BCS=3)
DuyLionTran 0:8094b249013c 359 // Cortex-M3 and M4 takes 3 cycles per loop (SUB=1, BCS=2)
DuyLionTran 0:8094b249013c 360 // Cortex-M7 - who knows?
DuyLionTran 0:8094b249013c 361 // Cortex M3-M7 have "CYCCNT" - would be better than a software loop, but M0 doesn't
DuyLionTran 0:8094b249013c 362 // Assume 3 cycles per loop for now - will be 33% slow on M0. No biggie,
DuyLionTran 0:8094b249013c 363 // as original version of code was 300% slow on M4.
DuyLionTran 0:8094b249013c 364 // [Note that this very calculation, plus call overhead, will take multiple
DuyLionTran 0:8094b249013c 365 // cycles. Could well be 100ns on its own... So round down here, startup is
DuyLionTran 0:8094b249013c 366 // worth at least one loop iteration.]
DuyLionTran 0:8094b249013c 367 uint32_t count = (cycles_per_us * ns) / 3000;
DuyLionTran 0:8094b249013c 368
DuyLionTran 0:8094b249013c 369 delay_loop(count);
DuyLionTran 0:8094b249013c 370 }
DuyLionTran 0:8094b249013c 371
DuyLionTran 0:8094b249013c 372 // t1 = 180ns, SEL falling edge to MISO active [SPI setup assumed slow enough to not need manual delay]
DuyLionTran 0:8094b249013c 373 #define CS_SELECT() {rf->CS = 0; /* delay_ns(180); */}
DuyLionTran 0:8094b249013c 374 // t9 = 250ns, last clock to SEL rising edge, t8 = 250ns, SPI idle time between consecutive access
DuyLionTran 0:8094b249013c 375 #define CS_RELEASE() {delay_ns(250); rf->CS = 1; delay_ns(250);}
DuyLionTran 0:8094b249013c 376
DuyLionTran 0:8094b249013c 377 /*
DuyLionTran 0:8094b249013c 378 * \brief Function sets the TX power variable.
DuyLionTran 0:8094b249013c 379 *
DuyLionTran 0:8094b249013c 380 * \param power TX power setting
DuyLionTran 0:8094b249013c 381 *
DuyLionTran 0:8094b249013c 382 * \return 0 Success
DuyLionTran 0:8094b249013c 383 * \return -1 Fail
DuyLionTran 0:8094b249013c 384 */
DuyLionTran 0:8094b249013c 385 MBED_UNUSED static int8_t rf_tx_power_set(uint8_t power)
DuyLionTran 0:8094b249013c 386 {
DuyLionTran 0:8094b249013c 387 int8_t ret_val = -1;
DuyLionTran 0:8094b249013c 388
DuyLionTran 0:8094b249013c 389 radio_tx_power = power;
DuyLionTran 0:8094b249013c 390 rf_if_lock();
DuyLionTran 0:8094b249013c 391 rf_if_write_set_tx_power_register(radio_tx_power);
DuyLionTran 0:8094b249013c 392 rf_if_unlock();
DuyLionTran 0:8094b249013c 393 ret_val = 0;
DuyLionTran 0:8094b249013c 394
DuyLionTran 0:8094b249013c 395 return ret_val;
DuyLionTran 0:8094b249013c 396 }
DuyLionTran 0:8094b249013c 397
DuyLionTran 0:8094b249013c 398 /*
DuyLionTran 0:8094b249013c 399 * \brief Read connected radio part.
DuyLionTran 0:8094b249013c 400 *
DuyLionTran 0:8094b249013c 401 * This function only return valid information when rf_init() is called
DuyLionTran 0:8094b249013c 402 *
DuyLionTran 0:8094b249013c 403 * \return
DuyLionTran 0:8094b249013c 404 */
DuyLionTran 0:8094b249013c 405 static rf_trx_part_e rf_radio_type_read(void)
DuyLionTran 0:8094b249013c 406 {
DuyLionTran 0:8094b249013c 407 rf_trx_part_e ret_val = ATMEL_UNKNOW_DEV;
DuyLionTran 0:8094b249013c 408
DuyLionTran 0:8094b249013c 409 switch (rf_part_num)
DuyLionTran 0:8094b249013c 410 {
DuyLionTran 0:8094b249013c 411 case PART_AT86RF212:
DuyLionTran 0:8094b249013c 412 ret_val = ATMEL_AT86RF212;
DuyLionTran 0:8094b249013c 413 break;
DuyLionTran 0:8094b249013c 414
DuyLionTran 0:8094b249013c 415 case PART_AT86RF231:
DuyLionTran 0:8094b249013c 416 ret_val = ATMEL_AT86RF231;
DuyLionTran 0:8094b249013c 417 break;
DuyLionTran 0:8094b249013c 418 case PART_AT86RF233:
DuyLionTran 0:8094b249013c 419 ret_val = ATMEL_AT86RF231;
DuyLionTran 0:8094b249013c 420 break;
DuyLionTran 0:8094b249013c 421 default:
DuyLionTran 0:8094b249013c 422 break;
DuyLionTran 0:8094b249013c 423 }
DuyLionTran 0:8094b249013c 424
DuyLionTran 0:8094b249013c 425 return ret_val;
DuyLionTran 0:8094b249013c 426 }
DuyLionTran 0:8094b249013c 427
DuyLionTran 0:8094b249013c 428
DuyLionTran 0:8094b249013c 429 /*
DuyLionTran 0:8094b249013c 430 * \brief Function starts the ACK wait timeout.
DuyLionTran 0:8094b249013c 431 *
DuyLionTran 0:8094b249013c 432 * \param slots Given slots, resolution 50us
DuyLionTran 0:8094b249013c 433 *
DuyLionTran 0:8094b249013c 434 * \return none
DuyLionTran 0:8094b249013c 435 */
DuyLionTran 0:8094b249013c 436 static void rf_if_ack_wait_timer_start(uint16_t slots)
DuyLionTran 0:8094b249013c 437 {
DuyLionTran 0:8094b249013c 438 #ifdef MBED_CONF_RTOS_PRESENT
DuyLionTran 0:8094b249013c 439 rf->ack_timer.attach(rf_if_ack_timer_signal, slots*50e-6);
DuyLionTran 0:8094b249013c 440 #else
DuyLionTran 0:8094b249013c 441 rf->ack_timer.attach(rf_ack_wait_timer_interrupt, slots*50e-6);
DuyLionTran 0:8094b249013c 442 #endif
DuyLionTran 0:8094b249013c 443 }
DuyLionTran 0:8094b249013c 444
DuyLionTran 0:8094b249013c 445 /*
DuyLionTran 0:8094b249013c 446 * \brief Function starts the calibration interval.
DuyLionTran 0:8094b249013c 447 *
DuyLionTran 0:8094b249013c 448 * \param slots Given slots, resolution 50us
DuyLionTran 0:8094b249013c 449 *
DuyLionTran 0:8094b249013c 450 * \return none
DuyLionTran 0:8094b249013c 451 */
DuyLionTran 0:8094b249013c 452 static void rf_if_calibration_timer_start(uint32_t slots)
DuyLionTran 0:8094b249013c 453 {
DuyLionTran 0:8094b249013c 454 #ifdef MBED_CONF_RTOS_PRESENT
DuyLionTran 0:8094b249013c 455 rf->cal_timer.attach(rf_if_cal_timer_signal, slots*50e-6);
DuyLionTran 0:8094b249013c 456 #else
DuyLionTran 0:8094b249013c 457 rf->cal_timer.attach(rf_calibration_timer_interrupt, slots*50e-6);
DuyLionTran 0:8094b249013c 458 #endif
DuyLionTran 0:8094b249013c 459 }
DuyLionTran 0:8094b249013c 460
DuyLionTran 0:8094b249013c 461 /*
DuyLionTran 0:8094b249013c 462 * \brief Function starts the CCA interval.
DuyLionTran 0:8094b249013c 463 *
DuyLionTran 0:8094b249013c 464 * \param slots Given slots, resolution 50us
DuyLionTran 0:8094b249013c 465 *
DuyLionTran 0:8094b249013c 466 * \return none
DuyLionTran 0:8094b249013c 467 */
DuyLionTran 0:8094b249013c 468 static void rf_if_cca_timer_start(uint32_t slots)
DuyLionTran 0:8094b249013c 469 {
DuyLionTran 0:8094b249013c 470 #ifdef MBED_CONF_RTOS_PRESENT
DuyLionTran 0:8094b249013c 471 rf->cca_timer.attach(rf_if_cca_timer_signal, slots*50e-6);
DuyLionTran 0:8094b249013c 472 #else
DuyLionTran 0:8094b249013c 473 rf->cca_timer.attach(rf_cca_timer_interrupt, slots*50e-6);
DuyLionTran 0:8094b249013c 474 #endif
DuyLionTran 0:8094b249013c 475 }
DuyLionTran 0:8094b249013c 476
DuyLionTran 0:8094b249013c 477 /*
DuyLionTran 0:8094b249013c 478 * \brief Function stops the ACK wait timeout.
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_if_ack_wait_timer_stop(void)
DuyLionTran 0:8094b249013c 485 {
DuyLionTran 0:8094b249013c 486 rf->ack_timer.detach();
DuyLionTran 0:8094b249013c 487 }
DuyLionTran 0:8094b249013c 488
DuyLionTran 0:8094b249013c 489 /*
DuyLionTran 0:8094b249013c 490 * \brief Function reads data from the given RF SRAM address.
DuyLionTran 0:8094b249013c 491 *
DuyLionTran 0:8094b249013c 492 * \param ptr Read pointer
DuyLionTran 0:8094b249013c 493 * \param sram_address Read address in SRAM
DuyLionTran 0:8094b249013c 494 * \param len Length of the read
DuyLionTran 0:8094b249013c 495 *
DuyLionTran 0:8094b249013c 496 * \return none
DuyLionTran 0:8094b249013c 497 */
DuyLionTran 0:8094b249013c 498 static void rf_if_read_payload(uint8_t *ptr, uint8_t sram_address, uint8_t len)
DuyLionTran 0:8094b249013c 499 {
DuyLionTran 0:8094b249013c 500 uint8_t i;
DuyLionTran 0:8094b249013c 501
DuyLionTran 0:8094b249013c 502 CS_SELECT();
DuyLionTran 0:8094b249013c 503 rf_if_spi_exchange(0x20);
DuyLionTran 0:8094b249013c 504 rf_if_spi_exchange(sram_address);
DuyLionTran 0:8094b249013c 505 for(i=0; i<len; i++)
DuyLionTran 0:8094b249013c 506 *ptr++ = rf_if_spi_exchange(0);
DuyLionTran 0:8094b249013c 507
DuyLionTran 0:8094b249013c 508 /*Read LQI and RSSI in variable*/
DuyLionTran 0:8094b249013c 509 rf_rx_lqi = rf_if_spi_exchange(0);
DuyLionTran 0:8094b249013c 510 rf_rx_rssi = rf_if_spi_exchange(0);
DuyLionTran 0:8094b249013c 511 rf_rx_status = rf_if_spi_exchange(0);
DuyLionTran 0:8094b249013c 512 CS_RELEASE();
DuyLionTran 0:8094b249013c 513 }
DuyLionTran 0:8094b249013c 514
DuyLionTran 0:8094b249013c 515 /*
DuyLionTran 0:8094b249013c 516 * \brief Function sets bit(s) in given RF register.
DuyLionTran 0:8094b249013c 517 *
DuyLionTran 0:8094b249013c 518 * \param addr Address of the register to set
DuyLionTran 0:8094b249013c 519 * \param bit Bit(s) to set
DuyLionTran 0:8094b249013c 520 * \param bit_mask Masks the field inside the register
DuyLionTran 0:8094b249013c 521 *
DuyLionTran 0:8094b249013c 522 * \return none
DuyLionTran 0:8094b249013c 523 */
DuyLionTran 0:8094b249013c 524 static void rf_if_set_bit(uint8_t addr, uint8_t bit, uint8_t bit_mask)
DuyLionTran 0:8094b249013c 525 {
DuyLionTran 0:8094b249013c 526 uint8_t reg = rf_if_read_register(addr);
DuyLionTran 0:8094b249013c 527 reg &= ~bit_mask;
DuyLionTran 0:8094b249013c 528 reg |= bit;
DuyLionTran 0:8094b249013c 529 rf_if_write_register(addr, reg);
DuyLionTran 0:8094b249013c 530 }
DuyLionTran 0:8094b249013c 531
DuyLionTran 0:8094b249013c 532 /*
DuyLionTran 0:8094b249013c 533 * \brief Function clears bit(s) in given RF register.
DuyLionTran 0:8094b249013c 534 *
DuyLionTran 0:8094b249013c 535 * \param addr Address of the register to clear
DuyLionTran 0:8094b249013c 536 * \param bit Bit(s) to clear
DuyLionTran 0:8094b249013c 537 *
DuyLionTran 0:8094b249013c 538 * \return none
DuyLionTran 0:8094b249013c 539 */
DuyLionTran 0:8094b249013c 540 static void rf_if_clear_bit(uint8_t addr, uint8_t bit)
DuyLionTran 0:8094b249013c 541 {
DuyLionTran 0:8094b249013c 542 uint8_t reg = rf_if_read_register(addr);
DuyLionTran 0:8094b249013c 543 reg &= ~bit;
DuyLionTran 0:8094b249013c 544 rf_if_write_register(addr, reg);
DuyLionTran 0:8094b249013c 545 }
DuyLionTran 0:8094b249013c 546
DuyLionTran 0:8094b249013c 547 /*
DuyLionTran 0:8094b249013c 548 * \brief Function writes register in RF.
DuyLionTran 0:8094b249013c 549 *
DuyLionTran 0:8094b249013c 550 * \param addr Address on the RF
DuyLionTran 0:8094b249013c 551 * \param data Written data
DuyLionTran 0:8094b249013c 552 *
DuyLionTran 0:8094b249013c 553 * \return none
DuyLionTran 0:8094b249013c 554 */
DuyLionTran 0:8094b249013c 555 static void rf_if_write_register(uint8_t addr, uint8_t data)
DuyLionTran 0:8094b249013c 556 {
DuyLionTran 0:8094b249013c 557 uint8_t cmd = 0xC0;
DuyLionTran 0:8094b249013c 558 CS_SELECT();
DuyLionTran 0:8094b249013c 559 rf_if_spi_exchange(cmd | addr);
DuyLionTran 0:8094b249013c 560 rf_if_spi_exchange(data);
DuyLionTran 0:8094b249013c 561 CS_RELEASE();
DuyLionTran 0:8094b249013c 562 }
DuyLionTran 0:8094b249013c 563
DuyLionTran 0:8094b249013c 564 /*
DuyLionTran 0:8094b249013c 565 * \brief Function reads RF register.
DuyLionTran 0:8094b249013c 566 *
DuyLionTran 0:8094b249013c 567 * \param addr Address on the RF
DuyLionTran 0:8094b249013c 568 *
DuyLionTran 0:8094b249013c 569 * \return Read data
DuyLionTran 0:8094b249013c 570 */
DuyLionTran 0:8094b249013c 571 static uint8_t rf_if_read_register(uint8_t addr)
DuyLionTran 0:8094b249013c 572 {
DuyLionTran 0:8094b249013c 573 uint8_t cmd = 0x80;
DuyLionTran 0:8094b249013c 574 uint8_t data;
DuyLionTran 0:8094b249013c 575 CS_SELECT();
DuyLionTran 0:8094b249013c 576 rf_if_spi_exchange(cmd | addr);
DuyLionTran 0:8094b249013c 577 data = rf_if_spi_exchange(0);
DuyLionTran 0:8094b249013c 578 CS_RELEASE();
DuyLionTran 0:8094b249013c 579 return data;
DuyLionTran 0:8094b249013c 580 }
DuyLionTran 0:8094b249013c 581
DuyLionTran 0:8094b249013c 582 /*
DuyLionTran 0:8094b249013c 583 * \brief Function resets the RF.
DuyLionTran 0:8094b249013c 584 *
DuyLionTran 0:8094b249013c 585 * \param none
DuyLionTran 0:8094b249013c 586 *
DuyLionTran 0:8094b249013c 587 * \return none
DuyLionTran 0:8094b249013c 588 */
DuyLionTran 0:8094b249013c 589 static void rf_if_reset_radio(void)
DuyLionTran 0:8094b249013c 590 {
DuyLionTran 0:8094b249013c 591 rf->spi.frequency(SPI_SPEED);
DuyLionTran 0:8094b249013c 592 rf->IRQ.rise(0);
DuyLionTran 0:8094b249013c 593 rf->RST = 1;
DuyLionTran 0:8094b249013c 594 wait(10e-4);
DuyLionTran 0:8094b249013c 595 rf->RST = 0;
DuyLionTran 0:8094b249013c 596 wait(10e-3);
DuyLionTran 0:8094b249013c 597 CS_RELEASE();
DuyLionTran 0:8094b249013c 598 rf->SLP_TR = 0;
DuyLionTran 0:8094b249013c 599 wait(10e-3);
DuyLionTran 0:8094b249013c 600 rf->RST = 1;
DuyLionTran 0:8094b249013c 601 wait(10e-3);
DuyLionTran 0:8094b249013c 602
DuyLionTran 0:8094b249013c 603 rf->IRQ.rise(&rf_if_interrupt_handler);
DuyLionTran 0:8094b249013c 604 }
DuyLionTran 0:8094b249013c 605
DuyLionTran 0:8094b249013c 606 /*
DuyLionTran 0:8094b249013c 607 * \brief Function enables the promiscuous mode.
DuyLionTran 0:8094b249013c 608 *
DuyLionTran 0:8094b249013c 609 * \param none
DuyLionTran 0:8094b249013c 610 *
DuyLionTran 0:8094b249013c 611 * \return none
DuyLionTran 0:8094b249013c 612 */
DuyLionTran 0:8094b249013c 613 static void rf_if_enable_promiscuous_mode(void)
DuyLionTran 0:8094b249013c 614 {
DuyLionTran 0:8094b249013c 615 /*Set AACK_PROM_MODE to enable the promiscuous mode*/
DuyLionTran 0:8094b249013c 616 rf_if_set_bit(XAH_CTRL_1, AACK_PROM_MODE, AACK_PROM_MODE);
DuyLionTran 0:8094b249013c 617 }
DuyLionTran 0:8094b249013c 618
DuyLionTran 0:8094b249013c 619 /*
DuyLionTran 0:8094b249013c 620 * \brief Function enables the promiscuous mode.
DuyLionTran 0:8094b249013c 621 *
DuyLionTran 0:8094b249013c 622 * \param none
DuyLionTran 0:8094b249013c 623 *
DuyLionTran 0:8094b249013c 624 * \return none
DuyLionTran 0:8094b249013c 625 */
DuyLionTran 0:8094b249013c 626 static void rf_if_disable_promiscuous_mode(void)
DuyLionTran 0:8094b249013c 627 {
DuyLionTran 0:8094b249013c 628 /*Set AACK_PROM_MODE to enable the promiscuous mode*/
DuyLionTran 0:8094b249013c 629 rf_if_clear_bit(XAH_CTRL_1, AACK_PROM_MODE);
DuyLionTran 0:8094b249013c 630 }
DuyLionTran 0:8094b249013c 631
DuyLionTran 0:8094b249013c 632 /*
DuyLionTran 0:8094b249013c 633 * \brief Function enables the Antenna diversity usage.
DuyLionTran 0:8094b249013c 634 *
DuyLionTran 0:8094b249013c 635 * \param none
DuyLionTran 0:8094b249013c 636 *
DuyLionTran 0:8094b249013c 637 * \return none
DuyLionTran 0:8094b249013c 638 */
DuyLionTran 0:8094b249013c 639 static void rf_if_enable_ant_div(void)
DuyLionTran 0:8094b249013c 640 {
DuyLionTran 0:8094b249013c 641 /*Set ANT_EXT_SW_EN to enable controlling of antenna diversity*/
DuyLionTran 0:8094b249013c 642 rf_if_set_bit(ANT_DIV, ANT_EXT_SW_EN, ANT_EXT_SW_EN);
DuyLionTran 0:8094b249013c 643 }
DuyLionTran 0:8094b249013c 644
DuyLionTran 0:8094b249013c 645 /*
DuyLionTran 0:8094b249013c 646 * \brief Function disables the Antenna diversity usage.
DuyLionTran 0:8094b249013c 647 *
DuyLionTran 0:8094b249013c 648 * \param none
DuyLionTran 0:8094b249013c 649 *
DuyLionTran 0:8094b249013c 650 * \return none
DuyLionTran 0:8094b249013c 651 */
DuyLionTran 0:8094b249013c 652 static void rf_if_disable_ant_div(void)
DuyLionTran 0:8094b249013c 653 {
DuyLionTran 0:8094b249013c 654 rf_if_clear_bit(ANT_DIV, ANT_EXT_SW_EN);
DuyLionTran 0:8094b249013c 655 }
DuyLionTran 0:8094b249013c 656
DuyLionTran 0:8094b249013c 657 /*
DuyLionTran 0:8094b249013c 658 * \brief Function sets the SLP TR pin.
DuyLionTran 0:8094b249013c 659 *
DuyLionTran 0:8094b249013c 660 * \param none
DuyLionTran 0:8094b249013c 661 *
DuyLionTran 0:8094b249013c 662 * \return none
DuyLionTran 0:8094b249013c 663 */
DuyLionTran 0:8094b249013c 664 static void rf_if_enable_slptr(void)
DuyLionTran 0:8094b249013c 665 {
DuyLionTran 0:8094b249013c 666 rf->SLP_TR = 1;
DuyLionTran 0:8094b249013c 667 }
DuyLionTran 0:8094b249013c 668
DuyLionTran 0:8094b249013c 669 /*
DuyLionTran 0:8094b249013c 670 * \brief Function clears the SLP TR pin.
DuyLionTran 0:8094b249013c 671 *
DuyLionTran 0:8094b249013c 672 * \param none
DuyLionTran 0:8094b249013c 673 *
DuyLionTran 0:8094b249013c 674 * \return none
DuyLionTran 0:8094b249013c 675 */
DuyLionTran 0:8094b249013c 676 static void rf_if_disable_slptr(void)
DuyLionTran 0:8094b249013c 677 {
DuyLionTran 0:8094b249013c 678 rf->SLP_TR = 0;
DuyLionTran 0:8094b249013c 679 }
DuyLionTran 0:8094b249013c 680
DuyLionTran 0:8094b249013c 681 /*
DuyLionTran 0:8094b249013c 682 * \brief Function writes the antenna diversity settings.
DuyLionTran 0:8094b249013c 683 *
DuyLionTran 0:8094b249013c 684 * \param none
DuyLionTran 0:8094b249013c 685 *
DuyLionTran 0:8094b249013c 686 * \return none
DuyLionTran 0:8094b249013c 687 */
DuyLionTran 0:8094b249013c 688 static void rf_if_write_antenna_diversity_settings(void)
DuyLionTran 0:8094b249013c 689 {
DuyLionTran 0:8094b249013c 690 /*Recommended setting of PDT_THRES is 3 when antenna diversity is used*/
DuyLionTran 0:8094b249013c 691 rf_if_set_bit(RX_CTRL, 0x03, 0x0f);
DuyLionTran 0:8094b249013c 692 rf_if_write_register(ANT_DIV, ANT_DIV_EN | ANT_EXT_SW_EN | ANT_CTRL_DEFAULT);
DuyLionTran 0:8094b249013c 693 }
DuyLionTran 0:8094b249013c 694
DuyLionTran 0:8094b249013c 695 /*
DuyLionTran 0:8094b249013c 696 * \brief Function writes the TX output power register.
DuyLionTran 0:8094b249013c 697 *
DuyLionTran 0:8094b249013c 698 * \param value Given register value
DuyLionTran 0:8094b249013c 699 *
DuyLionTran 0:8094b249013c 700 * \return none
DuyLionTran 0:8094b249013c 701 */
DuyLionTran 0:8094b249013c 702 static void rf_if_write_set_tx_power_register(uint8_t value)
DuyLionTran 0:8094b249013c 703 {
DuyLionTran 0:8094b249013c 704 rf_if_write_register(PHY_TX_PWR, value);
DuyLionTran 0:8094b249013c 705 }
DuyLionTran 0:8094b249013c 706
DuyLionTran 0:8094b249013c 707 /*
DuyLionTran 0:8094b249013c 708 * \brief Function returns the RF part number.
DuyLionTran 0:8094b249013c 709 *
DuyLionTran 0:8094b249013c 710 * \param none
DuyLionTran 0:8094b249013c 711 *
DuyLionTran 0:8094b249013c 712 * \return part number
DuyLionTran 0:8094b249013c 713 */
DuyLionTran 0:8094b249013c 714 static uint8_t rf_if_read_part_num(void)
DuyLionTran 0:8094b249013c 715 {
DuyLionTran 0:8094b249013c 716 return rf_if_read_register(PART_NUM);
DuyLionTran 0:8094b249013c 717 }
DuyLionTran 0:8094b249013c 718
DuyLionTran 0:8094b249013c 719 /*
DuyLionTran 0:8094b249013c 720 * \brief Function writes the RF settings and initialises SPI interface.
DuyLionTran 0:8094b249013c 721 *
DuyLionTran 0:8094b249013c 722 * \param none
DuyLionTran 0:8094b249013c 723 *
DuyLionTran 0:8094b249013c 724 * \return none
DuyLionTran 0:8094b249013c 725 */
DuyLionTran 0:8094b249013c 726 static void rf_if_write_rf_settings(void)
DuyLionTran 0:8094b249013c 727 {
DuyLionTran 0:8094b249013c 728 /*Reset RF module*/
DuyLionTran 0:8094b249013c 729 rf_if_reset_radio();
DuyLionTran 0:8094b249013c 730
DuyLionTran 0:8094b249013c 731 rf_part_num = rf_if_read_part_num();
DuyLionTran 0:8094b249013c 732
DuyLionTran 0:8094b249013c 733 rf_if_write_register(XAH_CTRL_0,0);
DuyLionTran 0:8094b249013c 734 rf_if_write_register(TRX_CTRL_1, 0x20);
DuyLionTran 0:8094b249013c 735
DuyLionTran 0:8094b249013c 736 /*CCA Mode - Carrier sense OR energy above threshold. Channel list is set separately*/
DuyLionTran 0:8094b249013c 737 rf_if_write_register(PHY_CC_CCA, 0x05);
DuyLionTran 0:8094b249013c 738
DuyLionTran 0:8094b249013c 739 /*Read transceiver PART_NUM*/
DuyLionTran 0:8094b249013c 740 rf_part_num = rf_if_read_register(PART_NUM);
DuyLionTran 0:8094b249013c 741
DuyLionTran 0:8094b249013c 742 /*Sub-GHz RF settings*/
DuyLionTran 0:8094b249013c 743 if(rf_part_num == PART_AT86RF212)
DuyLionTran 0:8094b249013c 744 {
DuyLionTran 0:8094b249013c 745 /*GC_TX_OFFS mode-dependent setting - OQPSK*/
DuyLionTran 0:8094b249013c 746 rf_if_write_register(RF_CTRL_0, 0x32);
DuyLionTran 0:8094b249013c 747
DuyLionTran 0:8094b249013c 748 if(rf_if_read_register(VERSION_NUM) == VERSION_AT86RF212B)
DuyLionTran 0:8094b249013c 749 {
DuyLionTran 0:8094b249013c 750 /*TX Output Power setting - 0 dBm North American Band*/
DuyLionTran 0:8094b249013c 751 rf_if_write_register(PHY_TX_PWR, 0x03);
DuyLionTran 0:8094b249013c 752 }
DuyLionTran 0:8094b249013c 753 else
DuyLionTran 0:8094b249013c 754 {
DuyLionTran 0:8094b249013c 755 /*TX Output Power setting - 0 dBm North American Band*/
DuyLionTran 0:8094b249013c 756 rf_if_write_register(PHY_TX_PWR, 0x24);
DuyLionTran 0:8094b249013c 757 }
DuyLionTran 0:8094b249013c 758
DuyLionTran 0:8094b249013c 759 /*PHY Mode: IEEE 802.15.4-2006/2011 - OQPSK-SIN-250*/
DuyLionTran 0:8094b249013c 760 rf_if_write_register(TRX_CTRL_2, RF_PHY_MODE);
DuyLionTran 0:8094b249013c 761 /*Based on receiver Characteristics. See AT86RF212B Datasheet where RSSI BASE VALUE in range -97 - -100 dBm*/
DuyLionTran 0:8094b249013c 762 rf_rssi_base_val = -98;
DuyLionTran 0:8094b249013c 763 }
DuyLionTran 0:8094b249013c 764 /*2.4GHz RF settings*/
DuyLionTran 0:8094b249013c 765 else
DuyLionTran 0:8094b249013c 766 {
DuyLionTran 0:8094b249013c 767 /*Set RPC register*/
DuyLionTran 0:8094b249013c 768 rf_if_write_register(TRX_RPC, 0xef);
DuyLionTran 0:8094b249013c 769 /*PHY Mode: IEEE 802.15.4 - Data Rate 250 kb/s*/
DuyLionTran 0:8094b249013c 770 rf_if_write_register(TRX_CTRL_2, 0);
DuyLionTran 0:8094b249013c 771 rf_rssi_base_val = -91;
DuyLionTran 0:8094b249013c 772 }
DuyLionTran 0:8094b249013c 773 }
DuyLionTran 0:8094b249013c 774
DuyLionTran 0:8094b249013c 775 /*
DuyLionTran 0:8094b249013c 776 * \brief Function checks the channel availability
DuyLionTran 0:8094b249013c 777 *
DuyLionTran 0:8094b249013c 778 * \param none
DuyLionTran 0:8094b249013c 779 *
DuyLionTran 0:8094b249013c 780 * \return 1 Channel clear
DuyLionTran 0:8094b249013c 781 * \return 0 Channel not clear
DuyLionTran 0:8094b249013c 782 */
DuyLionTran 0:8094b249013c 783 static uint8_t rf_if_check_cca(void)
DuyLionTran 0:8094b249013c 784 {
DuyLionTran 0:8094b249013c 785 uint8_t retval = 0;
DuyLionTran 0:8094b249013c 786 if(rf_if_read_register(TRX_STATUS) & CCA_STATUS)
DuyLionTran 0:8094b249013c 787 {
DuyLionTran 0:8094b249013c 788 retval = 1;
DuyLionTran 0:8094b249013c 789 }
DuyLionTran 0:8094b249013c 790 return retval;
DuyLionTran 0:8094b249013c 791 }
DuyLionTran 0:8094b249013c 792
DuyLionTran 0:8094b249013c 793 /*
DuyLionTran 0:8094b249013c 794 * \brief Function checks if the CRC is valid in received frame
DuyLionTran 0:8094b249013c 795 *
DuyLionTran 0:8094b249013c 796 * \param none
DuyLionTran 0:8094b249013c 797 *
DuyLionTran 0:8094b249013c 798 * \return 1 CRC ok
DuyLionTran 0:8094b249013c 799 * \return 0 CRC failed
DuyLionTran 0:8094b249013c 800 */
DuyLionTran 0:8094b249013c 801 static uint8_t rf_if_check_crc(void)
DuyLionTran 0:8094b249013c 802 {
DuyLionTran 0:8094b249013c 803 uint8_t retval = 0;
DuyLionTran 0:8094b249013c 804 if(rf_if_read_register(PHY_RSSI) & CRC_VALID)
DuyLionTran 0:8094b249013c 805 {
DuyLionTran 0:8094b249013c 806 retval = 1;
DuyLionTran 0:8094b249013c 807 }
DuyLionTran 0:8094b249013c 808 return retval;
DuyLionTran 0:8094b249013c 809 }
DuyLionTran 0:8094b249013c 810
DuyLionTran 0:8094b249013c 811 /*
DuyLionTran 0:8094b249013c 812 * \brief Function returns the RF state
DuyLionTran 0:8094b249013c 813 *
DuyLionTran 0:8094b249013c 814 * \param none
DuyLionTran 0:8094b249013c 815 *
DuyLionTran 0:8094b249013c 816 * \return RF state
DuyLionTran 0:8094b249013c 817 */
DuyLionTran 0:8094b249013c 818 static uint8_t rf_if_read_trx_state(void)
DuyLionTran 0:8094b249013c 819 {
DuyLionTran 0:8094b249013c 820 return rf_if_read_register(TRX_STATUS) & 0x1F;
DuyLionTran 0:8094b249013c 821 }
DuyLionTran 0:8094b249013c 822
DuyLionTran 0:8094b249013c 823 /*
DuyLionTran 0:8094b249013c 824 * \brief Function reads data from RF SRAM.
DuyLionTran 0:8094b249013c 825 *
DuyLionTran 0:8094b249013c 826 * \param ptr Read pointer
DuyLionTran 0:8094b249013c 827 * \param len Length of the read
DuyLionTran 0:8094b249013c 828 *
DuyLionTran 0:8094b249013c 829 * \return none
DuyLionTran 0:8094b249013c 830 */
DuyLionTran 0:8094b249013c 831 static void rf_if_read_packet(uint8_t *ptr, uint8_t len)
DuyLionTran 0:8094b249013c 832 {
DuyLionTran 0:8094b249013c 833 if(rf_part_num == PART_AT86RF231 || rf_part_num == PART_AT86RF212)
DuyLionTran 0:8094b249013c 834 rf_if_read_payload(ptr, 0, len);
DuyLionTran 0:8094b249013c 835 else if(rf_part_num == PART_AT86RF233)
DuyLionTran 0:8094b249013c 836 rf_if_read_payload(ptr, 1, len);
DuyLionTran 0:8094b249013c 837 }
DuyLionTran 0:8094b249013c 838
DuyLionTran 0:8094b249013c 839 /*
DuyLionTran 0:8094b249013c 840 * \brief Function writes RF short address registers
DuyLionTran 0:8094b249013c 841 *
DuyLionTran 0:8094b249013c 842 * \param short_address Given short address
DuyLionTran 0:8094b249013c 843 *
DuyLionTran 0:8094b249013c 844 * \return none
DuyLionTran 0:8094b249013c 845 */
DuyLionTran 0:8094b249013c 846 static void rf_if_write_short_addr_registers(uint8_t *short_address)
DuyLionTran 0:8094b249013c 847 {
DuyLionTran 0:8094b249013c 848 rf_if_write_register(SHORT_ADDR_1, *short_address++);
DuyLionTran 0:8094b249013c 849 rf_if_write_register(SHORT_ADDR_0, *short_address);
DuyLionTran 0:8094b249013c 850 }
DuyLionTran 0:8094b249013c 851
DuyLionTran 0:8094b249013c 852 /*
DuyLionTran 0:8094b249013c 853 * \brief Function sets the frame pending in ACK message
DuyLionTran 0:8094b249013c 854 *
DuyLionTran 0:8094b249013c 855 * \param state Given frame pending state
DuyLionTran 0:8094b249013c 856 *
DuyLionTran 0:8094b249013c 857 * \return none
DuyLionTran 0:8094b249013c 858 */
DuyLionTran 0:8094b249013c 859 static void rf_if_ack_pending_ctrl(uint8_t state)
DuyLionTran 0:8094b249013c 860 {
DuyLionTran 0:8094b249013c 861 rf_if_lock();
DuyLionTran 0:8094b249013c 862 if(state)
DuyLionTran 0:8094b249013c 863 {
DuyLionTran 0:8094b249013c 864 rf_if_set_bit(CSMA_SEED_1, (1 << AACK_SET_PD), (1 << AACK_SET_PD));
DuyLionTran 0:8094b249013c 865 }
DuyLionTran 0:8094b249013c 866 else
DuyLionTran 0:8094b249013c 867 {
DuyLionTran 0:8094b249013c 868 rf_if_clear_bit(CSMA_SEED_1, (1 << AACK_SET_PD));
DuyLionTran 0:8094b249013c 869 }
DuyLionTran 0:8094b249013c 870 rf_if_unlock();
DuyLionTran 0:8094b249013c 871 }
DuyLionTran 0:8094b249013c 872
DuyLionTran 0:8094b249013c 873 /*
DuyLionTran 0:8094b249013c 874 * \brief Function returns the state of frame pending control
DuyLionTran 0:8094b249013c 875 *
DuyLionTran 0:8094b249013c 876 * \param none
DuyLionTran 0:8094b249013c 877 *
DuyLionTran 0:8094b249013c 878 * \return Frame pending state
DuyLionTran 0:8094b249013c 879 */
DuyLionTran 0:8094b249013c 880 static uint8_t rf_if_last_acked_pending(void)
DuyLionTran 0:8094b249013c 881 {
DuyLionTran 0:8094b249013c 882 uint8_t last_acked_data_pending;
DuyLionTran 0:8094b249013c 883
DuyLionTran 0:8094b249013c 884 rf_if_lock();
DuyLionTran 0:8094b249013c 885 if(rf_if_read_register(CSMA_SEED_1) & 0x20)
DuyLionTran 0:8094b249013c 886 last_acked_data_pending = 1;
DuyLionTran 0:8094b249013c 887 else
DuyLionTran 0:8094b249013c 888 last_acked_data_pending = 0;
DuyLionTran 0:8094b249013c 889 rf_if_unlock();
DuyLionTran 0:8094b249013c 890
DuyLionTran 0:8094b249013c 891 return last_acked_data_pending;
DuyLionTran 0:8094b249013c 892 }
DuyLionTran 0:8094b249013c 893
DuyLionTran 0:8094b249013c 894 /*
DuyLionTran 0:8094b249013c 895 * \brief Function calibrates the RF part.
DuyLionTran 0:8094b249013c 896 *
DuyLionTran 0:8094b249013c 897 * \param none
DuyLionTran 0:8094b249013c 898 *
DuyLionTran 0:8094b249013c 899 * \return none
DuyLionTran 0:8094b249013c 900 */
DuyLionTran 0:8094b249013c 901 static void rf_if_calibration(void)
DuyLionTran 0:8094b249013c 902 {
DuyLionTran 0:8094b249013c 903 rf_if_set_bit(FTN_CTRL, FTN_START, FTN_START);
DuyLionTran 0:8094b249013c 904 /*Wait while calibration is running*/
DuyLionTran 0:8094b249013c 905 while(rf_if_read_register(FTN_CTRL) & FTN_START);
DuyLionTran 0:8094b249013c 906 }
DuyLionTran 0:8094b249013c 907
DuyLionTran 0:8094b249013c 908 /*
DuyLionTran 0:8094b249013c 909 * \brief Function writes RF PAN Id registers
DuyLionTran 0:8094b249013c 910 *
DuyLionTran 0:8094b249013c 911 * \param pan_id Given PAN Id
DuyLionTran 0:8094b249013c 912 *
DuyLionTran 0:8094b249013c 913 * \return none
DuyLionTran 0:8094b249013c 914 */
DuyLionTran 0:8094b249013c 915 static void rf_if_write_pan_id_registers(uint8_t *pan_id)
DuyLionTran 0:8094b249013c 916 {
DuyLionTran 0:8094b249013c 917 rf_if_write_register(PAN_ID_1, *pan_id++);
DuyLionTran 0:8094b249013c 918 rf_if_write_register(PAN_ID_0, *pan_id);
DuyLionTran 0:8094b249013c 919 }
DuyLionTran 0:8094b249013c 920
DuyLionTran 0:8094b249013c 921 /*
DuyLionTran 0:8094b249013c 922 * \brief Function writes RF IEEE Address registers
DuyLionTran 0:8094b249013c 923 *
DuyLionTran 0:8094b249013c 924 * \param address Given IEEE Address
DuyLionTran 0:8094b249013c 925 *
DuyLionTran 0:8094b249013c 926 * \return none
DuyLionTran 0:8094b249013c 927 */
DuyLionTran 0:8094b249013c 928 static void rf_if_write_ieee_addr_registers(uint8_t *address)
DuyLionTran 0:8094b249013c 929 {
DuyLionTran 0:8094b249013c 930 uint8_t i;
DuyLionTran 0:8094b249013c 931 uint8_t temp = IEEE_ADDR_0;
DuyLionTran 0:8094b249013c 932
DuyLionTran 0:8094b249013c 933 for(i=0; i<8; i++)
DuyLionTran 0:8094b249013c 934 rf_if_write_register(temp++, address[7-i]);
DuyLionTran 0:8094b249013c 935 }
DuyLionTran 0:8094b249013c 936
DuyLionTran 0:8094b249013c 937 /*
DuyLionTran 0:8094b249013c 938 * \brief Function writes data in RF frame buffer.
DuyLionTran 0:8094b249013c 939 *
DuyLionTran 0:8094b249013c 940 * \param ptr Pointer to data
DuyLionTran 0:8094b249013c 941 * \param length Pointer to length
DuyLionTran 0:8094b249013c 942 *
DuyLionTran 0:8094b249013c 943 * \return none
DuyLionTran 0:8094b249013c 944 */
DuyLionTran 0:8094b249013c 945 static void rf_if_write_frame_buffer(uint8_t *ptr, uint8_t length)
DuyLionTran 0:8094b249013c 946 {
DuyLionTran 0:8094b249013c 947 uint8_t i;
DuyLionTran 0:8094b249013c 948 uint8_t cmd = 0x60;
DuyLionTran 0:8094b249013c 949
DuyLionTran 0:8094b249013c 950 CS_SELECT();
DuyLionTran 0:8094b249013c 951 rf_if_spi_exchange(cmd);
DuyLionTran 0:8094b249013c 952 rf_if_spi_exchange(length + 2);
DuyLionTran 0:8094b249013c 953 for(i=0; i<length; i++)
DuyLionTran 0:8094b249013c 954 rf_if_spi_exchange(*ptr++);
DuyLionTran 0:8094b249013c 955
DuyLionTran 0:8094b249013c 956 CS_RELEASE();
DuyLionTran 0:8094b249013c 957 }
DuyLionTran 0:8094b249013c 958
DuyLionTran 0:8094b249013c 959 /*
DuyLionTran 0:8094b249013c 960 * \brief Function returns 8-bit random value.
DuyLionTran 0:8094b249013c 961 *
DuyLionTran 0:8094b249013c 962 * \param none
DuyLionTran 0:8094b249013c 963 *
DuyLionTran 0:8094b249013c 964 * \return random value
DuyLionTran 0:8094b249013c 965 */
DuyLionTran 0:8094b249013c 966 static uint8_t rf_if_read_rnd(void)
DuyLionTran 0:8094b249013c 967 {
DuyLionTran 0:8094b249013c 968 uint8_t temp;
DuyLionTran 0:8094b249013c 969 uint8_t tmp_rpc_val = 0;
DuyLionTran 0:8094b249013c 970 /*RPC must be disabled while reading the random number*/
DuyLionTran 0:8094b249013c 971 if(rf_part_num == PART_AT86RF233)
DuyLionTran 0:8094b249013c 972 {
DuyLionTran 0:8094b249013c 973 tmp_rpc_val = rf_if_read_register(TRX_RPC);
DuyLionTran 0:8094b249013c 974 rf_if_write_register(TRX_RPC, 0xc1);
DuyLionTran 0:8094b249013c 975 }
DuyLionTran 0:8094b249013c 976
DuyLionTran 0:8094b249013c 977 wait(1e-3);
DuyLionTran 0:8094b249013c 978 temp = ((rf_if_read_register(PHY_RSSI)>>5) << 6);
DuyLionTran 0:8094b249013c 979 wait(1e-3);
DuyLionTran 0:8094b249013c 980 temp |= ((rf_if_read_register(PHY_RSSI)>>5) << 4);
DuyLionTran 0:8094b249013c 981 wait(1e-3);
DuyLionTran 0:8094b249013c 982 temp |= ((rf_if_read_register(PHY_RSSI)>>5) << 2);
DuyLionTran 0:8094b249013c 983 wait(1e-3);
DuyLionTran 0:8094b249013c 984 temp |= ((rf_if_read_register(PHY_RSSI)>>5));
DuyLionTran 0:8094b249013c 985 wait(1e-3);
DuyLionTran 0:8094b249013c 986 if(rf_part_num == PART_AT86RF233)
DuyLionTran 0:8094b249013c 987 rf_if_write_register(TRX_RPC, tmp_rpc_val);
DuyLionTran 0:8094b249013c 988 return temp;
DuyLionTran 0:8094b249013c 989 }
DuyLionTran 0:8094b249013c 990
DuyLionTran 0:8094b249013c 991 /*
DuyLionTran 0:8094b249013c 992 * \brief Function changes the state of the RF.
DuyLionTran 0:8094b249013c 993 *
DuyLionTran 0:8094b249013c 994 * \param trx_state Given RF state
DuyLionTran 0:8094b249013c 995 *
DuyLionTran 0:8094b249013c 996 * \return none
DuyLionTran 0:8094b249013c 997 */
DuyLionTran 0:8094b249013c 998 static void rf_if_change_trx_state(rf_trx_states_t trx_state)
DuyLionTran 0:8094b249013c 999 {
DuyLionTran 0:8094b249013c 1000 rf_if_lock();
DuyLionTran 0:8094b249013c 1001 rf_if_write_register(TRX_STATE, trx_state);
DuyLionTran 0:8094b249013c 1002 /*Wait while not in desired state*/
DuyLionTran 0:8094b249013c 1003 rf_poll_trx_state_change(trx_state);
DuyLionTran 0:8094b249013c 1004 rf_if_unlock();
DuyLionTran 0:8094b249013c 1005 }
DuyLionTran 0:8094b249013c 1006
DuyLionTran 0:8094b249013c 1007 /*
DuyLionTran 0:8094b249013c 1008 * \brief Function enables the TX END interrupt
DuyLionTran 0:8094b249013c 1009 *
DuyLionTran 0:8094b249013c 1010 * \param none
DuyLionTran 0:8094b249013c 1011 *
DuyLionTran 0:8094b249013c 1012 * \return none
DuyLionTran 0:8094b249013c 1013 */
DuyLionTran 0:8094b249013c 1014 static void rf_if_enable_tx_end_interrupt(void)
DuyLionTran 0:8094b249013c 1015 {
DuyLionTran 0:8094b249013c 1016 rf_if_set_bit(IRQ_MASK, TRX_END, 0x08);
DuyLionTran 0:8094b249013c 1017 }
DuyLionTran 0:8094b249013c 1018
DuyLionTran 0:8094b249013c 1019 /*
DuyLionTran 0:8094b249013c 1020 * \brief Function enables the RX END interrupt
DuyLionTran 0:8094b249013c 1021 *
DuyLionTran 0:8094b249013c 1022 * \param none
DuyLionTran 0:8094b249013c 1023 *
DuyLionTran 0:8094b249013c 1024 * \return none
DuyLionTran 0:8094b249013c 1025 */
DuyLionTran 0:8094b249013c 1026 static void rf_if_enable_rx_end_interrupt(void)
DuyLionTran 0:8094b249013c 1027 {
DuyLionTran 0:8094b249013c 1028 rf_if_set_bit(IRQ_MASK, TRX_END, 0x08);
DuyLionTran 0:8094b249013c 1029 }
DuyLionTran 0:8094b249013c 1030
DuyLionTran 0:8094b249013c 1031 /*
DuyLionTran 0:8094b249013c 1032 * \brief Function enables the CCA ED interrupt
DuyLionTran 0:8094b249013c 1033 *
DuyLionTran 0:8094b249013c 1034 * \param none
DuyLionTran 0:8094b249013c 1035 *
DuyLionTran 0:8094b249013c 1036 * \return none
DuyLionTran 0:8094b249013c 1037 */
DuyLionTran 0:8094b249013c 1038 static void rf_if_enable_cca_ed_done_interrupt(void)
DuyLionTran 0:8094b249013c 1039 {
DuyLionTran 0:8094b249013c 1040 rf_if_set_bit(IRQ_MASK, CCA_ED_DONE, 0x10);
DuyLionTran 0:8094b249013c 1041 }
DuyLionTran 0:8094b249013c 1042
DuyLionTran 0:8094b249013c 1043 /*
DuyLionTran 0:8094b249013c 1044 * \brief Function starts the CCA process
DuyLionTran 0:8094b249013c 1045 *
DuyLionTran 0:8094b249013c 1046 * \param none
DuyLionTran 0:8094b249013c 1047 *
DuyLionTran 0:8094b249013c 1048 * \return none
DuyLionTran 0:8094b249013c 1049 */
DuyLionTran 0:8094b249013c 1050 static void rf_if_start_cca_process(void)
DuyLionTran 0:8094b249013c 1051 {
DuyLionTran 0:8094b249013c 1052 rf_if_set_bit(PHY_CC_CCA, CCA_REQUEST, 0x80);
DuyLionTran 0:8094b249013c 1053 }
DuyLionTran 0:8094b249013c 1054
DuyLionTran 0:8094b249013c 1055 /*
DuyLionTran 0:8094b249013c 1056 * \brief Function returns the length of the received packet
DuyLionTran 0:8094b249013c 1057 *
DuyLionTran 0:8094b249013c 1058 * \param none
DuyLionTran 0:8094b249013c 1059 *
DuyLionTran 0:8094b249013c 1060 * \return packet length
DuyLionTran 0:8094b249013c 1061 */
DuyLionTran 0:8094b249013c 1062 static uint8_t rf_if_read_received_frame_length(void)
DuyLionTran 0:8094b249013c 1063 {
DuyLionTran 0:8094b249013c 1064 uint8_t length;
DuyLionTran 0:8094b249013c 1065
DuyLionTran 0:8094b249013c 1066 CS_SELECT();
DuyLionTran 0:8094b249013c 1067 rf_if_spi_exchange(0x20);
DuyLionTran 0:8094b249013c 1068 length = rf_if_spi_exchange(0);
DuyLionTran 0:8094b249013c 1069 CS_RELEASE();
DuyLionTran 0:8094b249013c 1070
DuyLionTran 0:8094b249013c 1071 return length;
DuyLionTran 0:8094b249013c 1072 }
DuyLionTran 0:8094b249013c 1073
DuyLionTran 0:8094b249013c 1074 /*
DuyLionTran 0:8094b249013c 1075 * \brief Function returns the RSSI of the received packet
DuyLionTran 0:8094b249013c 1076 *
DuyLionTran 0:8094b249013c 1077 * \param none
DuyLionTran 0:8094b249013c 1078 *
DuyLionTran 0:8094b249013c 1079 * \return packet RSSI
DuyLionTran 0:8094b249013c 1080 */
DuyLionTran 0:8094b249013c 1081 static int8_t rf_if_read_rssi(void)
DuyLionTran 0:8094b249013c 1082 {
DuyLionTran 0:8094b249013c 1083 int16_t rssi_calc_tmp;
DuyLionTran 0:8094b249013c 1084 if(rf_part_num == PART_AT86RF212)
DuyLionTran 0:8094b249013c 1085 rssi_calc_tmp = rf_rx_rssi * 103;
DuyLionTran 0:8094b249013c 1086 else
DuyLionTran 0:8094b249013c 1087 rssi_calc_tmp = rf_rx_rssi * 100;
DuyLionTran 0:8094b249013c 1088 rssi_calc_tmp /= 100;
DuyLionTran 0:8094b249013c 1089 rssi_calc_tmp = (rf_rssi_base_val + rssi_calc_tmp);
DuyLionTran 0:8094b249013c 1090 return (int8_t)rssi_calc_tmp;
DuyLionTran 0:8094b249013c 1091 }
DuyLionTran 0:8094b249013c 1092
DuyLionTran 0:8094b249013c 1093 /*
DuyLionTran 0:8094b249013c 1094 * \brief Function returns the RSSI of the received packet
DuyLionTran 0:8094b249013c 1095 *
DuyLionTran 0:8094b249013c 1096 * \param none
DuyLionTran 0:8094b249013c 1097 *
DuyLionTran 0:8094b249013c 1098 * \return packet RSSI
DuyLionTran 0:8094b249013c 1099 */
DuyLionTran 0:8094b249013c 1100 MBED_UNUSED uint8_t rf_if_read_rx_status(void)
DuyLionTran 0:8094b249013c 1101 {
DuyLionTran 0:8094b249013c 1102 return rf_rx_status;
DuyLionTran 0:8094b249013c 1103 }
DuyLionTran 0:8094b249013c 1104
DuyLionTran 0:8094b249013c 1105 /*
DuyLionTran 0:8094b249013c 1106 * \brief Function sets the RF channel field
DuyLionTran 0:8094b249013c 1107 *
DuyLionTran 0:8094b249013c 1108 * \param Given channel
DuyLionTran 0:8094b249013c 1109 *
DuyLionTran 0:8094b249013c 1110 * \return none
DuyLionTran 0:8094b249013c 1111 */
DuyLionTran 0:8094b249013c 1112 static void rf_if_set_channel_register(uint8_t channel)
DuyLionTran 0:8094b249013c 1113 {
DuyLionTran 0:8094b249013c 1114 rf_if_set_bit(PHY_CC_CCA, channel, 0x1f);
DuyLionTran 0:8094b249013c 1115 }
DuyLionTran 0:8094b249013c 1116
DuyLionTran 0:8094b249013c 1117 /*
DuyLionTran 0:8094b249013c 1118 * \brief Function enables RF irq pin interrupts in RF interface.
DuyLionTran 0:8094b249013c 1119 *
DuyLionTran 0:8094b249013c 1120 * \param none
DuyLionTran 0:8094b249013c 1121 *
DuyLionTran 0:8094b249013c 1122 * \return none
DuyLionTran 0:8094b249013c 1123 */
DuyLionTran 0:8094b249013c 1124 static void rf_if_enable_irq(void)
DuyLionTran 0:8094b249013c 1125 {
DuyLionTran 0:8094b249013c 1126 rf->IRQ.enable_irq();
DuyLionTran 0:8094b249013c 1127 }
DuyLionTran 0:8094b249013c 1128
DuyLionTran 0:8094b249013c 1129 /*
DuyLionTran 0:8094b249013c 1130 * \brief Function disables RF irq pin interrupts in RF interface.
DuyLionTran 0:8094b249013c 1131 *
DuyLionTran 0:8094b249013c 1132 * \param none
DuyLionTran 0:8094b249013c 1133 *
DuyLionTran 0:8094b249013c 1134 * \return none
DuyLionTran 0:8094b249013c 1135 */
DuyLionTran 0:8094b249013c 1136 static void rf_if_disable_irq(void)
DuyLionTran 0:8094b249013c 1137 {
DuyLionTran 0:8094b249013c 1138 rf->IRQ.disable_irq();
DuyLionTran 0:8094b249013c 1139 }
DuyLionTran 0:8094b249013c 1140
DuyLionTran 0:8094b249013c 1141 #ifdef MBED_CONF_RTOS_PRESENT
DuyLionTran 0:8094b249013c 1142 static void rf_if_interrupt_handler(void)
DuyLionTran 0:8094b249013c 1143 {
DuyLionTran 0:8094b249013c 1144 rf->irq_thread.signal_set(SIG_RADIO);
DuyLionTran 0:8094b249013c 1145 }
DuyLionTran 0:8094b249013c 1146
DuyLionTran 0:8094b249013c 1147 // Started during construction of rf, so variable
DuyLionTran 0:8094b249013c 1148 // rf isn't set at the start. Uses 'this' instead.
DuyLionTran 0:8094b249013c 1149 void RFBits::rf_if_irq_task(void)
DuyLionTran 0:8094b249013c 1150 {
DuyLionTran 0:8094b249013c 1151 for (;;) {
DuyLionTran 0:8094b249013c 1152 osEvent event = irq_thread.signal_wait(0);
DuyLionTran 0:8094b249013c 1153 if (event.status != osEventSignal) {
DuyLionTran 0:8094b249013c 1154 continue;
DuyLionTran 0:8094b249013c 1155 }
DuyLionTran 0:8094b249013c 1156 rf_if_lock();
DuyLionTran 0:8094b249013c 1157 if (event.value.signals & SIG_RADIO) {
DuyLionTran 0:8094b249013c 1158 rf_if_irq_task_process_irq();
DuyLionTran 0:8094b249013c 1159 }
DuyLionTran 0:8094b249013c 1160 if (event.value.signals & SIG_TIMER_ACK) {
DuyLionTran 0:8094b249013c 1161 rf_ack_wait_timer_interrupt();
DuyLionTran 0:8094b249013c 1162 }
DuyLionTran 0:8094b249013c 1163 if (event.value.signals & SIG_TIMER_CCA) {
DuyLionTran 0:8094b249013c 1164 rf_cca_timer_interrupt();
DuyLionTran 0:8094b249013c 1165 }
DuyLionTran 0:8094b249013c 1166 if (event.value.signals & SIG_TIMER_CAL) {
DuyLionTran 0:8094b249013c 1167 rf_calibration_timer_interrupt();
DuyLionTran 0:8094b249013c 1168 }
DuyLionTran 0:8094b249013c 1169 rf_if_unlock();
DuyLionTran 0:8094b249013c 1170 }
DuyLionTran 0:8094b249013c 1171 }
DuyLionTran 0:8094b249013c 1172
DuyLionTran 0:8094b249013c 1173 static void rf_if_irq_task_process_irq(void)
DuyLionTran 0:8094b249013c 1174 #else
DuyLionTran 0:8094b249013c 1175 /*
DuyLionTran 0:8094b249013c 1176 * \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 1177 *
DuyLionTran 0:8094b249013c 1178 * \param none
DuyLionTran 0:8094b249013c 1179 *
DuyLionTran 0:8094b249013c 1180 * \return none
DuyLionTran 0:8094b249013c 1181 */
DuyLionTran 0:8094b249013c 1182 static void rf_if_interrupt_handler(void)
DuyLionTran 0:8094b249013c 1183 #endif
DuyLionTran 0:8094b249013c 1184 {
DuyLionTran 0:8094b249013c 1185 uint8_t irq_status;
DuyLionTran 0:8094b249013c 1186
DuyLionTran 0:8094b249013c 1187 /*Read interrupt flag*/
DuyLionTran 0:8094b249013c 1188 irq_status = rf_if_read_register(IRQ_STATUS);
DuyLionTran 0:8094b249013c 1189
DuyLionTran 0:8094b249013c 1190 /*Disable interrupt on RF*/
DuyLionTran 0:8094b249013c 1191 rf_if_clear_bit(IRQ_MASK, irq_status);
DuyLionTran 0:8094b249013c 1192 /*RX start interrupt*/
DuyLionTran 0:8094b249013c 1193 if(irq_status & RX_START)
DuyLionTran 0:8094b249013c 1194 {
DuyLionTran 0:8094b249013c 1195 }
DuyLionTran 0:8094b249013c 1196 /*Address matching interrupt*/
DuyLionTran 0:8094b249013c 1197 if(irq_status & AMI)
DuyLionTran 0:8094b249013c 1198 {
DuyLionTran 0:8094b249013c 1199 }
DuyLionTran 0:8094b249013c 1200 if(irq_status & TRX_UR)
DuyLionTran 0:8094b249013c 1201 {
DuyLionTran 0:8094b249013c 1202 }
DuyLionTran 0:8094b249013c 1203 /*Frame end interrupt (RX and TX)*/
DuyLionTran 0:8094b249013c 1204 if(irq_status & TRX_END)
DuyLionTran 0:8094b249013c 1205 {
DuyLionTran 0:8094b249013c 1206 /*TX done interrupt*/
DuyLionTran 0:8094b249013c 1207 if(rf_if_read_trx_state() == PLL_ON || rf_if_read_trx_state() == TX_ARET_ON)
DuyLionTran 0:8094b249013c 1208 {
DuyLionTran 0:8094b249013c 1209 rf_handle_tx_end();
DuyLionTran 0:8094b249013c 1210 }
DuyLionTran 0:8094b249013c 1211 /*Frame received interrupt*/
DuyLionTran 0:8094b249013c 1212 else
DuyLionTran 0:8094b249013c 1213 {
DuyLionTran 0:8094b249013c 1214 rf_handle_rx_end();
DuyLionTran 0:8094b249013c 1215 }
DuyLionTran 0:8094b249013c 1216 }
DuyLionTran 0:8094b249013c 1217 if(irq_status & CCA_ED_DONE)
DuyLionTran 0:8094b249013c 1218 {
DuyLionTran 0:8094b249013c 1219 rf_handle_cca_ed_done();
DuyLionTran 0:8094b249013c 1220 }
DuyLionTran 0:8094b249013c 1221 }
DuyLionTran 0:8094b249013c 1222
DuyLionTran 0:8094b249013c 1223 /*
DuyLionTran 0:8094b249013c 1224 * \brief Function writes/read data in SPI interface
DuyLionTran 0:8094b249013c 1225 *
DuyLionTran 0:8094b249013c 1226 * \param out Output data
DuyLionTran 0:8094b249013c 1227 *
DuyLionTran 0:8094b249013c 1228 * \return Input data
DuyLionTran 0:8094b249013c 1229 */
DuyLionTran 0:8094b249013c 1230 static uint8_t rf_if_spi_exchange(uint8_t out)
DuyLionTran 0:8094b249013c 1231 {
DuyLionTran 0:8094b249013c 1232 uint8_t v;
DuyLionTran 0:8094b249013c 1233 v = rf->spi.write(out);
DuyLionTran 0:8094b249013c 1234 // t9 = t5 = 250ns, delay between LSB of last byte to next MSB or delay between LSB & SEL rising
DuyLionTran 0:8094b249013c 1235 // [SPI setup assumed slow enough to not need manual delay]
DuyLionTran 0:8094b249013c 1236 // delay_ns(250);
DuyLionTran 0:8094b249013c 1237 return v;
DuyLionTran 0:8094b249013c 1238 }
DuyLionTran 0:8094b249013c 1239
DuyLionTran 0:8094b249013c 1240 /*
DuyLionTran 0:8094b249013c 1241 * \brief Function sets given RF flag on.
DuyLionTran 0:8094b249013c 1242 *
DuyLionTran 0:8094b249013c 1243 * \param x Given RF flag
DuyLionTran 0:8094b249013c 1244 *
DuyLionTran 0:8094b249013c 1245 * \return none
DuyLionTran 0:8094b249013c 1246 */
DuyLionTran 0:8094b249013c 1247 static void rf_flags_set(uint8_t x)
DuyLionTran 0:8094b249013c 1248 {
DuyLionTran 0:8094b249013c 1249 rf_flags |= x;
DuyLionTran 0:8094b249013c 1250 }
DuyLionTran 0:8094b249013c 1251
DuyLionTran 0:8094b249013c 1252 /*
DuyLionTran 0:8094b249013c 1253 * \brief Function clears given RF flag on.
DuyLionTran 0:8094b249013c 1254 *
DuyLionTran 0:8094b249013c 1255 * \param x Given RF flag
DuyLionTran 0:8094b249013c 1256 *
DuyLionTran 0:8094b249013c 1257 * \return none
DuyLionTran 0:8094b249013c 1258 */
DuyLionTran 0:8094b249013c 1259 static void rf_flags_clear(uint8_t x)
DuyLionTran 0:8094b249013c 1260 {
DuyLionTran 0:8094b249013c 1261 rf_flags &= ~x;
DuyLionTran 0:8094b249013c 1262 }
DuyLionTran 0:8094b249013c 1263
DuyLionTran 0:8094b249013c 1264 /*
DuyLionTran 0:8094b249013c 1265 * \brief Function checks if given RF flag is on.
DuyLionTran 0:8094b249013c 1266 *
DuyLionTran 0:8094b249013c 1267 * \param x Given RF flag
DuyLionTran 0:8094b249013c 1268 *
DuyLionTran 0:8094b249013c 1269 * \return states of the given flags
DuyLionTran 0:8094b249013c 1270 */
DuyLionTran 0:8094b249013c 1271 static uint8_t rf_flags_check(uint8_t x)
DuyLionTran 0:8094b249013c 1272 {
DuyLionTran 0:8094b249013c 1273 return (rf_flags & x);
DuyLionTran 0:8094b249013c 1274 }
DuyLionTran 0:8094b249013c 1275
DuyLionTran 0:8094b249013c 1276 /*
DuyLionTran 0:8094b249013c 1277 * \brief Function clears all RF flags.
DuyLionTran 0:8094b249013c 1278 *
DuyLionTran 0:8094b249013c 1279 * \param none
DuyLionTran 0:8094b249013c 1280 *
DuyLionTran 0:8094b249013c 1281 * \return none
DuyLionTran 0:8094b249013c 1282 */
DuyLionTran 0:8094b249013c 1283 static void rf_flags_reset(void)
DuyLionTran 0:8094b249013c 1284 {
DuyLionTran 0:8094b249013c 1285 rf_flags = 0;
DuyLionTran 0:8094b249013c 1286 }
DuyLionTran 0:8094b249013c 1287
DuyLionTran 0:8094b249013c 1288 /*
DuyLionTran 0:8094b249013c 1289 * \brief Function initialises and registers the RF driver.
DuyLionTran 0:8094b249013c 1290 *
DuyLionTran 0:8094b249013c 1291 * \param none
DuyLionTran 0:8094b249013c 1292 *
DuyLionTran 0:8094b249013c 1293 * \return rf_radio_driver_id Driver ID given by NET library
DuyLionTran 0:8094b249013c 1294 */
DuyLionTran 0:8094b249013c 1295 static int8_t rf_device_register(const uint8_t *mac_addr)
DuyLionTran 0:8094b249013c 1296 {
DuyLionTran 0:8094b249013c 1297 rf_trx_part_e radio_type;
DuyLionTran 0:8094b249013c 1298
DuyLionTran 0:8094b249013c 1299 rf_init();
DuyLionTran 0:8094b249013c 1300
DuyLionTran 0:8094b249013c 1301 radio_type = rf_radio_type_read();
DuyLionTran 0:8094b249013c 1302 if(radio_type != ATMEL_UNKNOW_DEV)
DuyLionTran 0:8094b249013c 1303 {
DuyLionTran 0:8094b249013c 1304 /*Set pointer to MAC address*/
DuyLionTran 0:8094b249013c 1305 device_driver.PHY_MAC = (uint8_t *)mac_addr;
DuyLionTran 0:8094b249013c 1306 device_driver.driver_description = (char*)"ATMEL_MAC";
DuyLionTran 0:8094b249013c 1307 //Create setup Used Radio chips
DuyLionTran 0:8094b249013c 1308 if(radio_type == ATMEL_AT86RF212)
DuyLionTran 0:8094b249013c 1309 {
DuyLionTran 0:8094b249013c 1310 device_driver.link_type = PHY_LINK_15_4_SUBGHZ_TYPE;
DuyLionTran 0:8094b249013c 1311 }
DuyLionTran 0:8094b249013c 1312 else
DuyLionTran 0:8094b249013c 1313 {
DuyLionTran 0:8094b249013c 1314 device_driver.link_type = PHY_LINK_15_4_2_4GHZ_TYPE;
DuyLionTran 0:8094b249013c 1315 }
DuyLionTran 0:8094b249013c 1316 device_driver.phy_channel_pages = phy_channel_pages;
DuyLionTran 0:8094b249013c 1317 /*Maximum size of payload is 127*/
DuyLionTran 0:8094b249013c 1318 device_driver.phy_MTU = 127;
DuyLionTran 0:8094b249013c 1319 /*No header in PHY*/
DuyLionTran 0:8094b249013c 1320 device_driver.phy_header_length = 0;
DuyLionTran 0:8094b249013c 1321 /*No tail in PHY*/
DuyLionTran 0:8094b249013c 1322 device_driver.phy_tail_length = 0;
DuyLionTran 0:8094b249013c 1323 /*Set address write function*/
DuyLionTran 0:8094b249013c 1324 device_driver.address_write = &rf_address_write;
DuyLionTran 0:8094b249013c 1325 /*Set RF extension function*/
DuyLionTran 0:8094b249013c 1326 device_driver.extension = &rf_extension;
DuyLionTran 0:8094b249013c 1327 /*Set RF state control function*/
DuyLionTran 0:8094b249013c 1328 device_driver.state_control = &rf_interface_state_control;
DuyLionTran 0:8094b249013c 1329 /*Set transmit function*/
DuyLionTran 0:8094b249013c 1330 device_driver.tx = &rf_start_cca;
DuyLionTran 0:8094b249013c 1331 /*NULLIFY rx and tx_done callbacks*/
DuyLionTran 0:8094b249013c 1332 device_driver.phy_rx_cb = NULL;
DuyLionTran 0:8094b249013c 1333 device_driver.phy_tx_done_cb = NULL;
DuyLionTran 0:8094b249013c 1334 /*Register device driver*/
DuyLionTran 0:8094b249013c 1335 rf_radio_driver_id = arm_net_phy_register(&device_driver);
DuyLionTran 0:8094b249013c 1336 }
DuyLionTran 0:8094b249013c 1337 return rf_radio_driver_id;
DuyLionTran 0:8094b249013c 1338 }
DuyLionTran 0:8094b249013c 1339
DuyLionTran 0:8094b249013c 1340 /*
DuyLionTran 0:8094b249013c 1341 * \brief Function unregisters the RF driver.
DuyLionTran 0:8094b249013c 1342 *
DuyLionTran 0:8094b249013c 1343 * \param none
DuyLionTran 0:8094b249013c 1344 *
DuyLionTran 0:8094b249013c 1345 * \return none
DuyLionTran 0:8094b249013c 1346 */
DuyLionTran 0:8094b249013c 1347 static void rf_device_unregister()
DuyLionTran 0:8094b249013c 1348 {
DuyLionTran 0:8094b249013c 1349 if (rf_radio_driver_id >= 0) {
DuyLionTran 0:8094b249013c 1350 arm_net_phy_unregister(rf_radio_driver_id);
DuyLionTran 0:8094b249013c 1351 rf_radio_driver_id = -1;
DuyLionTran 0:8094b249013c 1352 }
DuyLionTran 0:8094b249013c 1353 }
DuyLionTran 0:8094b249013c 1354
DuyLionTran 0:8094b249013c 1355 /*
DuyLionTran 0:8094b249013c 1356 * \brief Function is a call back for ACK wait timeout.
DuyLionTran 0:8094b249013c 1357 *
DuyLionTran 0:8094b249013c 1358 * \param none
DuyLionTran 0:8094b249013c 1359 *
DuyLionTran 0:8094b249013c 1360 * \return none
DuyLionTran 0:8094b249013c 1361 */
DuyLionTran 0:8094b249013c 1362 static void rf_ack_wait_timer_interrupt(void)
DuyLionTran 0:8094b249013c 1363 {
DuyLionTran 0:8094b249013c 1364 rf_if_lock();
DuyLionTran 0:8094b249013c 1365 /*Force PLL state*/
DuyLionTran 0:8094b249013c 1366 rf_if_change_trx_state(FORCE_PLL_ON);
DuyLionTran 0:8094b249013c 1367 rf_poll_trx_state_change(PLL_ON);
DuyLionTran 0:8094b249013c 1368 /*Start receiver in RX_AACK_ON state*/
DuyLionTran 0:8094b249013c 1369 rf_rx_mode = 0;
DuyLionTran 0:8094b249013c 1370 rf_flags_clear(RFF_RX);
DuyLionTran 0:8094b249013c 1371 rf_receive();
DuyLionTran 0:8094b249013c 1372 rf_if_unlock();
DuyLionTran 0:8094b249013c 1373 }
DuyLionTran 0:8094b249013c 1374
DuyLionTran 0:8094b249013c 1375 /*
DuyLionTran 0:8094b249013c 1376 * \brief Function is a call back for calibration interval timer.
DuyLionTran 0:8094b249013c 1377 *
DuyLionTran 0:8094b249013c 1378 * \param none
DuyLionTran 0:8094b249013c 1379 *
DuyLionTran 0:8094b249013c 1380 * \return none
DuyLionTran 0:8094b249013c 1381 */
DuyLionTran 0:8094b249013c 1382 static void rf_calibration_timer_interrupt(void)
DuyLionTran 0:8094b249013c 1383 {
DuyLionTran 0:8094b249013c 1384 /*Calibrate RF*/
DuyLionTran 0:8094b249013c 1385 rf_calibration_cb();
DuyLionTran 0:8094b249013c 1386 /*Start new calibration timeout*/
DuyLionTran 0:8094b249013c 1387 rf_calibration_timer_start(RF_CALIBRATION_INTERVAL);
DuyLionTran 0:8094b249013c 1388 }
DuyLionTran 0:8094b249013c 1389
DuyLionTran 0:8094b249013c 1390 /*
DuyLionTran 0:8094b249013c 1391 * \brief Function is a call back for cca interval timer.
DuyLionTran 0:8094b249013c 1392 *
DuyLionTran 0:8094b249013c 1393 * \param none
DuyLionTran 0:8094b249013c 1394 *
DuyLionTran 0:8094b249013c 1395 * \return none
DuyLionTran 0:8094b249013c 1396 */
DuyLionTran 0:8094b249013c 1397 static void rf_cca_timer_interrupt(void)
DuyLionTran 0:8094b249013c 1398 {
DuyLionTran 0:8094b249013c 1399 /*Start CCA process*/
DuyLionTran 0:8094b249013c 1400 if(rf_if_read_trx_state() == BUSY_RX_AACK)
DuyLionTran 0:8094b249013c 1401 {
DuyLionTran 0:8094b249013c 1402 if(device_driver.phy_tx_done_cb){
DuyLionTran 0:8094b249013c 1403 device_driver.phy_tx_done_cb(rf_radio_driver_id, mac_tx_handle, PHY_LINK_CCA_FAIL, 1, 1);
DuyLionTran 0:8094b249013c 1404 }
DuyLionTran 0:8094b249013c 1405 }
DuyLionTran 0:8094b249013c 1406 else
DuyLionTran 0:8094b249013c 1407 {
DuyLionTran 0:8094b249013c 1408 /*Set radio in RX state to read channel*/
DuyLionTran 0:8094b249013c 1409 rf_receive();
DuyLionTran 0:8094b249013c 1410 rf_if_enable_cca_ed_done_interrupt();
DuyLionTran 0:8094b249013c 1411 rf_if_start_cca_process();
DuyLionTran 0:8094b249013c 1412 }
DuyLionTran 0:8094b249013c 1413 }
DuyLionTran 0:8094b249013c 1414
DuyLionTran 0:8094b249013c 1415 /*
DuyLionTran 0:8094b249013c 1416 * \brief Function starts the ACK wait timeout.
DuyLionTran 0:8094b249013c 1417 *
DuyLionTran 0:8094b249013c 1418 * \param slots Given slots, resolution 50us
DuyLionTran 0:8094b249013c 1419 *
DuyLionTran 0:8094b249013c 1420 * \return none
DuyLionTran 0:8094b249013c 1421 */
DuyLionTran 0:8094b249013c 1422 static void rf_ack_wait_timer_start(uint16_t slots)
DuyLionTran 0:8094b249013c 1423 {
DuyLionTran 0:8094b249013c 1424 rf_if_ack_wait_timer_start(slots);
DuyLionTran 0:8094b249013c 1425 }
DuyLionTran 0:8094b249013c 1426
DuyLionTran 0:8094b249013c 1427 /*
DuyLionTran 0:8094b249013c 1428 * \brief Function starts the calibration interval.
DuyLionTran 0:8094b249013c 1429 *
DuyLionTran 0:8094b249013c 1430 * \param slots Given slots, resolution 50us
DuyLionTran 0:8094b249013c 1431 *
DuyLionTran 0:8094b249013c 1432 * \return none
DuyLionTran 0:8094b249013c 1433 */
DuyLionTran 0:8094b249013c 1434 static void rf_calibration_timer_start(uint32_t slots)
DuyLionTran 0:8094b249013c 1435 {
DuyLionTran 0:8094b249013c 1436 rf_if_calibration_timer_start(slots);
DuyLionTran 0:8094b249013c 1437 }
DuyLionTran 0:8094b249013c 1438
DuyLionTran 0:8094b249013c 1439 /*
DuyLionTran 0:8094b249013c 1440 * \brief Function starts the CCA timout.
DuyLionTran 0:8094b249013c 1441 *
DuyLionTran 0:8094b249013c 1442 * \param slots Given slots, resolution 50us
DuyLionTran 0:8094b249013c 1443 *
DuyLionTran 0:8094b249013c 1444 * \return none
DuyLionTran 0:8094b249013c 1445 */
DuyLionTran 0:8094b249013c 1446 static void rf_cca_timer_start(uint32_t slots)
DuyLionTran 0:8094b249013c 1447 {
DuyLionTran 0:8094b249013c 1448 rf_if_cca_timer_start(slots);
DuyLionTran 0:8094b249013c 1449 }
DuyLionTran 0:8094b249013c 1450
DuyLionTran 0:8094b249013c 1451 /*
DuyLionTran 0:8094b249013c 1452 * \brief Function stops the ACK wait timeout.
DuyLionTran 0:8094b249013c 1453 *
DuyLionTran 0:8094b249013c 1454 * \param none
DuyLionTran 0:8094b249013c 1455 *
DuyLionTran 0:8094b249013c 1456 * \return none
DuyLionTran 0:8094b249013c 1457 */
DuyLionTran 0:8094b249013c 1458 static void rf_ack_wait_timer_stop(void)
DuyLionTran 0:8094b249013c 1459 {
DuyLionTran 0:8094b249013c 1460 rf_if_ack_wait_timer_stop();
DuyLionTran 0:8094b249013c 1461 }
DuyLionTran 0:8094b249013c 1462
DuyLionTran 0:8094b249013c 1463 /*
DuyLionTran 0:8094b249013c 1464 * \brief Function writes various RF settings in startup.
DuyLionTran 0:8094b249013c 1465 *
DuyLionTran 0:8094b249013c 1466 * \param none
DuyLionTran 0:8094b249013c 1467 *
DuyLionTran 0:8094b249013c 1468 * \return none
DuyLionTran 0:8094b249013c 1469 */
DuyLionTran 0:8094b249013c 1470 static void rf_write_settings(void)
DuyLionTran 0:8094b249013c 1471 {
DuyLionTran 0:8094b249013c 1472 rf_if_lock();
DuyLionTran 0:8094b249013c 1473 rf_if_write_rf_settings();
DuyLionTran 0:8094b249013c 1474 /*Set output power*/
DuyLionTran 0:8094b249013c 1475 rf_if_write_set_tx_power_register(radio_tx_power);
DuyLionTran 0:8094b249013c 1476 /*Initialise Antenna Diversity*/
DuyLionTran 0:8094b249013c 1477 if(rf_use_antenna_diversity)
DuyLionTran 0:8094b249013c 1478 rf_if_write_antenna_diversity_settings();
DuyLionTran 0:8094b249013c 1479 rf_if_unlock();
DuyLionTran 0:8094b249013c 1480 }
DuyLionTran 0:8094b249013c 1481
DuyLionTran 0:8094b249013c 1482 /*
DuyLionTran 0:8094b249013c 1483 * \brief Function writes 16-bit address in RF address filter.
DuyLionTran 0:8094b249013c 1484 *
DuyLionTran 0:8094b249013c 1485 * \param short_address Given short address
DuyLionTran 0:8094b249013c 1486 *
DuyLionTran 0:8094b249013c 1487 * \return none
DuyLionTran 0:8094b249013c 1488 */
DuyLionTran 0:8094b249013c 1489 static void rf_set_short_adr(uint8_t * short_address)
DuyLionTran 0:8094b249013c 1490 {
DuyLionTran 0:8094b249013c 1491 rf_if_lock();
DuyLionTran 0:8094b249013c 1492 /*Wake up RF if sleeping*/
DuyLionTran 0:8094b249013c 1493 if(rf_flags_check(RFF_ON) == 0)
DuyLionTran 0:8094b249013c 1494 {
DuyLionTran 0:8094b249013c 1495 rf_if_disable_slptr();
DuyLionTran 0:8094b249013c 1496 rf_poll_trx_state_change(TRX_OFF);
DuyLionTran 0:8094b249013c 1497 }
DuyLionTran 0:8094b249013c 1498 /*Write address filter registers*/
DuyLionTran 0:8094b249013c 1499 rf_if_write_short_addr_registers(short_address);
DuyLionTran 0:8094b249013c 1500 /*RF back to sleep*/
DuyLionTran 0:8094b249013c 1501 if(rf_flags_check(RFF_ON) == 0)
DuyLionTran 0:8094b249013c 1502 {
DuyLionTran 0:8094b249013c 1503 rf_if_enable_slptr();
DuyLionTran 0:8094b249013c 1504 }
DuyLionTran 0:8094b249013c 1505 rf_if_unlock();
DuyLionTran 0:8094b249013c 1506 }
DuyLionTran 0:8094b249013c 1507
DuyLionTran 0:8094b249013c 1508 /*
DuyLionTran 0:8094b249013c 1509 * \brief Function writes PAN Id in RF PAN Id filter.
DuyLionTran 0:8094b249013c 1510 *
DuyLionTran 0:8094b249013c 1511 * \param pan_id Given PAN Id
DuyLionTran 0:8094b249013c 1512 *
DuyLionTran 0:8094b249013c 1513 * \return none
DuyLionTran 0:8094b249013c 1514 */
DuyLionTran 0:8094b249013c 1515 static void rf_set_pan_id(uint8_t *pan_id)
DuyLionTran 0:8094b249013c 1516 {
DuyLionTran 0:8094b249013c 1517 rf_if_lock();
DuyLionTran 0:8094b249013c 1518 /*Wake up RF if sleeping*/
DuyLionTran 0:8094b249013c 1519 if(rf_flags_check(RFF_ON) == 0)
DuyLionTran 0:8094b249013c 1520 {
DuyLionTran 0:8094b249013c 1521 rf_if_disable_slptr();
DuyLionTran 0:8094b249013c 1522 rf_poll_trx_state_change(TRX_OFF);
DuyLionTran 0:8094b249013c 1523 }
DuyLionTran 0:8094b249013c 1524 /*Write address filter registers*/
DuyLionTran 0:8094b249013c 1525 rf_if_write_pan_id_registers(pan_id);
DuyLionTran 0:8094b249013c 1526 /*RF back to sleep*/
DuyLionTran 0:8094b249013c 1527 if(rf_flags_check(RFF_ON) == 0)
DuyLionTran 0:8094b249013c 1528 {
DuyLionTran 0:8094b249013c 1529 rf_if_enable_slptr();
DuyLionTran 0:8094b249013c 1530 }
DuyLionTran 0:8094b249013c 1531 rf_if_unlock();
DuyLionTran 0:8094b249013c 1532 }
DuyLionTran 0:8094b249013c 1533
DuyLionTran 0:8094b249013c 1534 /*
DuyLionTran 0:8094b249013c 1535 * \brief Function writes 64-bit address in RF address filter.
DuyLionTran 0:8094b249013c 1536 *
DuyLionTran 0:8094b249013c 1537 * \param address Given 64-bit address
DuyLionTran 0:8094b249013c 1538 *
DuyLionTran 0:8094b249013c 1539 * \return none
DuyLionTran 0:8094b249013c 1540 */
DuyLionTran 0:8094b249013c 1541 static void rf_set_address(uint8_t *address)
DuyLionTran 0:8094b249013c 1542 {
DuyLionTran 0:8094b249013c 1543 rf_if_lock();
DuyLionTran 0:8094b249013c 1544 /*Wake up RF if sleeping*/
DuyLionTran 0:8094b249013c 1545 if(rf_flags_check(RFF_ON) == 0)
DuyLionTran 0:8094b249013c 1546 {
DuyLionTran 0:8094b249013c 1547 rf_if_disable_slptr();
DuyLionTran 0:8094b249013c 1548 rf_poll_trx_state_change(TRX_OFF);
DuyLionTran 0:8094b249013c 1549 }
DuyLionTran 0:8094b249013c 1550 /*Write address filter registers*/
DuyLionTran 0:8094b249013c 1551 rf_if_write_ieee_addr_registers(address);
DuyLionTran 0:8094b249013c 1552 /*RF back to sleep*/
DuyLionTran 0:8094b249013c 1553 if(rf_flags_check(RFF_ON) == 0)
DuyLionTran 0:8094b249013c 1554 {
DuyLionTran 0:8094b249013c 1555 rf_if_enable_slptr();
DuyLionTran 0:8094b249013c 1556 }
DuyLionTran 0:8094b249013c 1557 rf_if_unlock();
DuyLionTran 0:8094b249013c 1558 }
DuyLionTran 0:8094b249013c 1559
DuyLionTran 0:8094b249013c 1560 /*
DuyLionTran 0:8094b249013c 1561 * \brief Function sets the RF channel.
DuyLionTran 0:8094b249013c 1562 *
DuyLionTran 0:8094b249013c 1563 * \param ch New channel
DuyLionTran 0:8094b249013c 1564 *
DuyLionTran 0:8094b249013c 1565 * \return none
DuyLionTran 0:8094b249013c 1566 */
DuyLionTran 0:8094b249013c 1567 static void rf_channel_set(uint8_t ch)
DuyLionTran 0:8094b249013c 1568 {
DuyLionTran 0:8094b249013c 1569 rf_if_lock();
DuyLionTran 0:8094b249013c 1570 rf_phy_channel = ch;
DuyLionTran 0:8094b249013c 1571 if(ch < 0x1f)
DuyLionTran 0:8094b249013c 1572 rf_if_set_channel_register(ch);
DuyLionTran 0:8094b249013c 1573 rf_if_unlock();
DuyLionTran 0:8094b249013c 1574 }
DuyLionTran 0:8094b249013c 1575
DuyLionTran 0:8094b249013c 1576
DuyLionTran 0:8094b249013c 1577 /*
DuyLionTran 0:8094b249013c 1578 * \brief Function initialises the radio driver and resets the radio.
DuyLionTran 0:8094b249013c 1579 *
DuyLionTran 0:8094b249013c 1580 * \param none
DuyLionTran 0:8094b249013c 1581 *
DuyLionTran 0:8094b249013c 1582 * \return none
DuyLionTran 0:8094b249013c 1583 */
DuyLionTran 0:8094b249013c 1584 static void rf_init(void)
DuyLionTran 0:8094b249013c 1585 {
DuyLionTran 0:8094b249013c 1586 /*Reset RF module*/
DuyLionTran 0:8094b249013c 1587 rf_if_reset_radio();
DuyLionTran 0:8094b249013c 1588
DuyLionTran 0:8094b249013c 1589 rf_if_lock();
DuyLionTran 0:8094b249013c 1590
DuyLionTran 0:8094b249013c 1591 /*Write RF settings*/
DuyLionTran 0:8094b249013c 1592 rf_write_settings();
DuyLionTran 0:8094b249013c 1593 /*Initialise PHY mode*/
DuyLionTran 0:8094b249013c 1594 rf_init_phy_mode();
DuyLionTran 0:8094b249013c 1595 /*Clear RF flags*/
DuyLionTran 0:8094b249013c 1596 rf_flags_reset();
DuyLionTran 0:8094b249013c 1597 /*Set RF in TRX OFF state*/
DuyLionTran 0:8094b249013c 1598 rf_if_change_trx_state(TRX_OFF);
DuyLionTran 0:8094b249013c 1599 /*Set RF in PLL_ON state*/
DuyLionTran 0:8094b249013c 1600 rf_if_change_trx_state(PLL_ON);
DuyLionTran 0:8094b249013c 1601 /*Start receiver*/
DuyLionTran 0:8094b249013c 1602 rf_receive();
DuyLionTran 0:8094b249013c 1603 /*Read random variable. This will be used when seeding pseudo-random generator*/
DuyLionTran 0:8094b249013c 1604 rf_rnd_rssi = rf_if_read_rnd();
DuyLionTran 0:8094b249013c 1605 /*Start RF calibration timer*/
DuyLionTran 0:8094b249013c 1606 rf_calibration_timer_start(RF_CALIBRATION_INTERVAL);
DuyLionTran 0:8094b249013c 1607
DuyLionTran 0:8094b249013c 1608 rf_if_unlock();
DuyLionTran 0:8094b249013c 1609 }
DuyLionTran 0:8094b249013c 1610
DuyLionTran 0:8094b249013c 1611 /**
DuyLionTran 0:8094b249013c 1612 * \brief Function gets called when MAC is setting radio off.
DuyLionTran 0:8094b249013c 1613 *
DuyLionTran 0:8094b249013c 1614 * \param none
DuyLionTran 0:8094b249013c 1615 *
DuyLionTran 0:8094b249013c 1616 * \return none
DuyLionTran 0:8094b249013c 1617 */
DuyLionTran 0:8094b249013c 1618 static void rf_off(void)
DuyLionTran 0:8094b249013c 1619 {
DuyLionTran 0:8094b249013c 1620 if(rf_flags_check(RFF_ON))
DuyLionTran 0:8094b249013c 1621 {
DuyLionTran 0:8094b249013c 1622 rf_if_lock();
DuyLionTran 0:8094b249013c 1623 rf_cca_abort();
DuyLionTran 0:8094b249013c 1624 uint16_t while_counter = 0;
DuyLionTran 0:8094b249013c 1625 /*Wait while receiving*/
DuyLionTran 0:8094b249013c 1626 while(rf_if_read_trx_state() == BUSY_RX_AACK)
DuyLionTran 0:8094b249013c 1627 {
DuyLionTran 0:8094b249013c 1628 while_counter++;
DuyLionTran 0:8094b249013c 1629 if(while_counter == 0xffff)
DuyLionTran 0:8094b249013c 1630 break;
DuyLionTran 0:8094b249013c 1631 }
DuyLionTran 0:8094b249013c 1632 /*RF state change: RX_AACK_ON->PLL_ON->TRX_OFF->SLEEP*/
DuyLionTran 0:8094b249013c 1633 if(rf_if_read_trx_state() == RX_AACK_ON)
DuyLionTran 0:8094b249013c 1634 {
DuyLionTran 0:8094b249013c 1635 rf_if_change_trx_state(PLL_ON);
DuyLionTran 0:8094b249013c 1636 }
DuyLionTran 0:8094b249013c 1637 rf_if_change_trx_state(TRX_OFF);
DuyLionTran 0:8094b249013c 1638 rf_if_enable_slptr();
DuyLionTran 0:8094b249013c 1639
DuyLionTran 0:8094b249013c 1640 /*Disable Antenna Diversity*/
DuyLionTran 0:8094b249013c 1641 if(rf_use_antenna_diversity)
DuyLionTran 0:8094b249013c 1642 rf_if_disable_ant_div();
DuyLionTran 0:8094b249013c 1643 rf_if_unlock();
DuyLionTran 0:8094b249013c 1644 }
DuyLionTran 0:8094b249013c 1645
DuyLionTran 0:8094b249013c 1646 /*Clears all flags*/
DuyLionTran 0:8094b249013c 1647 rf_flags_reset();
DuyLionTran 0:8094b249013c 1648 }
DuyLionTran 0:8094b249013c 1649
DuyLionTran 0:8094b249013c 1650 /*
DuyLionTran 0:8094b249013c 1651 * \brief Function polls the RF state until it has changed to desired state.
DuyLionTran 0:8094b249013c 1652 *
DuyLionTran 0:8094b249013c 1653 * \param trx_state RF state
DuyLionTran 0:8094b249013c 1654 *
DuyLionTran 0:8094b249013c 1655 * \return none
DuyLionTran 0:8094b249013c 1656 */
DuyLionTran 0:8094b249013c 1657 static void rf_poll_trx_state_change(rf_trx_states_t trx_state)
DuyLionTran 0:8094b249013c 1658 {
DuyLionTran 0:8094b249013c 1659 uint16_t while_counter = 0;
DuyLionTran 0:8094b249013c 1660 rf_if_lock();
DuyLionTran 0:8094b249013c 1661
DuyLionTran 0:8094b249013c 1662 if(trx_state != RF_TX_START)
DuyLionTran 0:8094b249013c 1663 {
DuyLionTran 0:8094b249013c 1664 if(trx_state == FORCE_PLL_ON)
DuyLionTran 0:8094b249013c 1665 trx_state = PLL_ON;
DuyLionTran 0:8094b249013c 1666 else if(trx_state == FORCE_TRX_OFF)
DuyLionTran 0:8094b249013c 1667 trx_state = TRX_OFF;
DuyLionTran 0:8094b249013c 1668
DuyLionTran 0:8094b249013c 1669 while(rf_if_read_trx_state() != trx_state)
DuyLionTran 0:8094b249013c 1670 {
DuyLionTran 0:8094b249013c 1671 while_counter++;
DuyLionTran 0:8094b249013c 1672 if(while_counter == 0x1ff)
DuyLionTran 0:8094b249013c 1673 break;
DuyLionTran 0:8094b249013c 1674 }
DuyLionTran 0:8094b249013c 1675 }
DuyLionTran 0:8094b249013c 1676 rf_if_unlock();
DuyLionTran 0:8094b249013c 1677 }
DuyLionTran 0:8094b249013c 1678
DuyLionTran 0:8094b249013c 1679 /*
DuyLionTran 0:8094b249013c 1680 * \brief Function starts the CCA process before starting data transmission and copies the data to RF TX FIFO.
DuyLionTran 0:8094b249013c 1681 *
DuyLionTran 0:8094b249013c 1682 * \param data_ptr Pointer to TX data
DuyLionTran 0:8094b249013c 1683 * \param data_length Length of the TX data
DuyLionTran 0:8094b249013c 1684 * \param tx_handle Handle to transmission
DuyLionTran 0:8094b249013c 1685 * \return 0 Success
DuyLionTran 0:8094b249013c 1686 * \return -1 Busy
DuyLionTran 0:8094b249013c 1687 */
DuyLionTran 0:8094b249013c 1688 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 1689 {
DuyLionTran 0:8094b249013c 1690 (void)data_protocol;
DuyLionTran 0:8094b249013c 1691 /*Check if transmitter is busy*/
DuyLionTran 0:8094b249013c 1692 if(rf_if_read_trx_state() == BUSY_RX_AACK)
DuyLionTran 0:8094b249013c 1693 {
DuyLionTran 0:8094b249013c 1694 /*Return busy*/
DuyLionTran 0:8094b249013c 1695 return -1;
DuyLionTran 0:8094b249013c 1696 }
DuyLionTran 0:8094b249013c 1697 else
DuyLionTran 0:8094b249013c 1698 {
DuyLionTran 0:8094b249013c 1699 rf_if_lock();
DuyLionTran 0:8094b249013c 1700 /*Check if transmitted data needs to be acked*/
DuyLionTran 0:8094b249013c 1701 if(*data_ptr & 0x20)
DuyLionTran 0:8094b249013c 1702 need_ack = 1;
DuyLionTran 0:8094b249013c 1703 else
DuyLionTran 0:8094b249013c 1704 need_ack = 0;
DuyLionTran 0:8094b249013c 1705 /*Store the sequence number for ACK handling*/
DuyLionTran 0:8094b249013c 1706 tx_sequence = *(data_ptr + 2);
DuyLionTran 0:8094b249013c 1707
DuyLionTran 0:8094b249013c 1708 /*Write TX FIFO*/
DuyLionTran 0:8094b249013c 1709 rf_if_write_frame_buffer(data_ptr, (uint8_t)data_length);
DuyLionTran 0:8094b249013c 1710 rf_flags_set(RFF_CCA);
DuyLionTran 0:8094b249013c 1711 /*Start CCA timeout*/
DuyLionTran 0:8094b249013c 1712 rf_cca_timer_start(RF_CCA_BASE_BACKOFF + randLIB_get_random_in_range(0, RF_CCA_RANDOM_BACKOFF));
DuyLionTran 0:8094b249013c 1713 /*Store TX handle*/
DuyLionTran 0:8094b249013c 1714 mac_tx_handle = tx_handle;
DuyLionTran 0:8094b249013c 1715 rf_if_unlock();
DuyLionTran 0:8094b249013c 1716 }
DuyLionTran 0:8094b249013c 1717
DuyLionTran 0:8094b249013c 1718 /*Return success*/
DuyLionTran 0:8094b249013c 1719 return 0;
DuyLionTran 0:8094b249013c 1720 }
DuyLionTran 0:8094b249013c 1721
DuyLionTran 0:8094b249013c 1722 /*
DuyLionTran 0:8094b249013c 1723 * \brief Function aborts CCA process.
DuyLionTran 0:8094b249013c 1724 *
DuyLionTran 0:8094b249013c 1725 * \param none
DuyLionTran 0:8094b249013c 1726 *
DuyLionTran 0:8094b249013c 1727 * \return none
DuyLionTran 0:8094b249013c 1728 */
DuyLionTran 0:8094b249013c 1729 static void rf_cca_abort(void)
DuyLionTran 0:8094b249013c 1730 {
DuyLionTran 0:8094b249013c 1731 /*Clear RFF_CCA RF flag*/
DuyLionTran 0:8094b249013c 1732 rf_flags_clear(RFF_CCA);
DuyLionTran 0:8094b249013c 1733 }
DuyLionTran 0:8094b249013c 1734
DuyLionTran 0:8094b249013c 1735 /*
DuyLionTran 0:8094b249013c 1736 * \brief Function starts the transmission of the frame.
DuyLionTran 0:8094b249013c 1737 *
DuyLionTran 0:8094b249013c 1738 * \param none
DuyLionTran 0:8094b249013c 1739 *
DuyLionTran 0:8094b249013c 1740 * \return none
DuyLionTran 0:8094b249013c 1741 */
DuyLionTran 0:8094b249013c 1742 static void rf_start_tx(void)
DuyLionTran 0:8094b249013c 1743 {
DuyLionTran 0:8094b249013c 1744 /*Only start transmitting from RX state*/
DuyLionTran 0:8094b249013c 1745 uint8_t trx_state = rf_if_read_trx_state();
DuyLionTran 0:8094b249013c 1746 if(trx_state != RX_AACK_ON)
DuyLionTran 0:8094b249013c 1747 {
DuyLionTran 0:8094b249013c 1748 if(device_driver.phy_tx_done_cb){
DuyLionTran 0:8094b249013c 1749 device_driver.phy_tx_done_cb(rf_radio_driver_id, mac_tx_handle, PHY_LINK_CCA_FAIL, 1, 1);
DuyLionTran 0:8094b249013c 1750 }
DuyLionTran 0:8094b249013c 1751 }
DuyLionTran 0:8094b249013c 1752 else
DuyLionTran 0:8094b249013c 1753 {
DuyLionTran 0:8094b249013c 1754 /*RF state change: ->PLL_ON->RF_TX_START*/
DuyLionTran 0:8094b249013c 1755 rf_if_change_trx_state(FORCE_PLL_ON);
DuyLionTran 0:8094b249013c 1756 rf_flags_clear(RFF_RX);
DuyLionTran 0:8094b249013c 1757 rf_if_enable_tx_end_interrupt();
DuyLionTran 0:8094b249013c 1758 rf_flags_set(RFF_TX);
DuyLionTran 0:8094b249013c 1759 rf_if_change_trx_state(RF_TX_START);
DuyLionTran 0:8094b249013c 1760 }
DuyLionTran 0:8094b249013c 1761 }
DuyLionTran 0:8094b249013c 1762
DuyLionTran 0:8094b249013c 1763 /*
DuyLionTran 0:8094b249013c 1764 * \brief Function sets the RF in RX state.
DuyLionTran 0:8094b249013c 1765 *
DuyLionTran 0:8094b249013c 1766 * \param none
DuyLionTran 0:8094b249013c 1767 *
DuyLionTran 0:8094b249013c 1768 * \return none
DuyLionTran 0:8094b249013c 1769 */
DuyLionTran 0:8094b249013c 1770 static void rf_receive(void)
DuyLionTran 0:8094b249013c 1771 {
DuyLionTran 0:8094b249013c 1772 uint16_t while_counter = 0;
DuyLionTran 0:8094b249013c 1773 if(rf_flags_check(RFF_ON) == 0)
DuyLionTran 0:8094b249013c 1774 {
DuyLionTran 0:8094b249013c 1775 rf_on();
DuyLionTran 0:8094b249013c 1776 }
DuyLionTran 0:8094b249013c 1777 /*If not yet in RX state set it*/
DuyLionTran 0:8094b249013c 1778 if(rf_flags_check(RFF_RX) == 0)
DuyLionTran 0:8094b249013c 1779 {
DuyLionTran 0:8094b249013c 1780 rf_if_lock();
DuyLionTran 0:8094b249013c 1781 /*Wait while receiving data*/
DuyLionTran 0:8094b249013c 1782 while(rf_if_read_trx_state() == BUSY_RX_AACK)
DuyLionTran 0:8094b249013c 1783 {
DuyLionTran 0:8094b249013c 1784 while_counter++;
DuyLionTran 0:8094b249013c 1785 if(while_counter == 0xffff)
DuyLionTran 0:8094b249013c 1786 {
DuyLionTran 0:8094b249013c 1787 break;
DuyLionTran 0:8094b249013c 1788 }
DuyLionTran 0:8094b249013c 1789 }
DuyLionTran 0:8094b249013c 1790
DuyLionTran 0:8094b249013c 1791 rf_if_change_trx_state(PLL_ON);
DuyLionTran 0:8094b249013c 1792
DuyLionTran 0:8094b249013c 1793 if((rf_mode == RF_MODE_SNIFFER) || (rf_mode == RF_MODE_ED))
DuyLionTran 0:8094b249013c 1794 {
DuyLionTran 0:8094b249013c 1795 rf_if_change_trx_state(RX_ON);
DuyLionTran 0:8094b249013c 1796 }
DuyLionTran 0:8094b249013c 1797 else
DuyLionTran 0:8094b249013c 1798 {
DuyLionTran 0:8094b249013c 1799 /*ACK is always received in promiscuous mode to bypass address filters*/
DuyLionTran 0:8094b249013c 1800 if(rf_rx_mode)
DuyLionTran 0:8094b249013c 1801 {
DuyLionTran 0:8094b249013c 1802 rf_rx_mode = 0;
DuyLionTran 0:8094b249013c 1803 rf_if_enable_promiscuous_mode();
DuyLionTran 0:8094b249013c 1804 }
DuyLionTran 0:8094b249013c 1805 else
DuyLionTran 0:8094b249013c 1806 {
DuyLionTran 0:8094b249013c 1807 rf_if_disable_promiscuous_mode();
DuyLionTran 0:8094b249013c 1808 }
DuyLionTran 0:8094b249013c 1809 rf_if_change_trx_state(RX_AACK_ON);
DuyLionTran 0:8094b249013c 1810 }
DuyLionTran 0:8094b249013c 1811 /*If calibration timer was unable to calibrate the RF, run calibration now*/
DuyLionTran 0:8094b249013c 1812 if(!rf_tuned)
DuyLionTran 0:8094b249013c 1813 {
DuyLionTran 0:8094b249013c 1814 /*Start calibration. This can be done in states TRX_OFF, PLL_ON or in any receive state*/
DuyLionTran 0:8094b249013c 1815 rf_if_calibration();
DuyLionTran 0:8094b249013c 1816 /*RF is tuned now*/
DuyLionTran 0:8094b249013c 1817 rf_tuned = 1;
DuyLionTran 0:8094b249013c 1818 }
DuyLionTran 0:8094b249013c 1819
DuyLionTran 0:8094b249013c 1820 rf_channel_set(rf_phy_channel);
DuyLionTran 0:8094b249013c 1821 rf_flags_set(RFF_RX);
DuyLionTran 0:8094b249013c 1822 // Don't receive packets when ED mode enabled
DuyLionTran 0:8094b249013c 1823 if (rf_mode != RF_MODE_ED)
DuyLionTran 0:8094b249013c 1824 {
DuyLionTran 0:8094b249013c 1825 rf_if_enable_rx_end_interrupt();
DuyLionTran 0:8094b249013c 1826 }
DuyLionTran 0:8094b249013c 1827 rf_if_unlock();
DuyLionTran 0:8094b249013c 1828 }
DuyLionTran 0:8094b249013c 1829 /*Stop the running CCA process*/
DuyLionTran 0:8094b249013c 1830 if(rf_flags_check(RFF_CCA))
DuyLionTran 0:8094b249013c 1831 rf_cca_abort();
DuyLionTran 0:8094b249013c 1832 }
DuyLionTran 0:8094b249013c 1833
DuyLionTran 0:8094b249013c 1834 /*
DuyLionTran 0:8094b249013c 1835 * \brief Function calibrates the radio.
DuyLionTran 0:8094b249013c 1836 *
DuyLionTran 0:8094b249013c 1837 * \param none
DuyLionTran 0:8094b249013c 1838 *
DuyLionTran 0:8094b249013c 1839 * \return none
DuyLionTran 0:8094b249013c 1840 */
DuyLionTran 0:8094b249013c 1841 static void rf_calibration_cb(void)
DuyLionTran 0:8094b249013c 1842 {
DuyLionTran 0:8094b249013c 1843 /*clear tuned flag to start tuning in rf_receive*/
DuyLionTran 0:8094b249013c 1844 rf_tuned = 0;
DuyLionTran 0:8094b249013c 1845 /*If RF is in default receive state, start calibration*/
DuyLionTran 0:8094b249013c 1846 if(rf_if_read_trx_state() == RX_AACK_ON)
DuyLionTran 0:8094b249013c 1847 {
DuyLionTran 0:8094b249013c 1848 rf_if_lock();
DuyLionTran 0:8094b249013c 1849 /*Set RF in PLL_ON state*/
DuyLionTran 0:8094b249013c 1850 rf_if_change_trx_state(PLL_ON);
DuyLionTran 0:8094b249013c 1851 /*Set RF in TRX_OFF state to start PLL tuning*/
DuyLionTran 0:8094b249013c 1852 rf_if_change_trx_state(TRX_OFF);
DuyLionTran 0:8094b249013c 1853 /*Set RF in RX_ON state to calibrate*/
DuyLionTran 0:8094b249013c 1854 rf_if_change_trx_state(RX_ON);
DuyLionTran 0:8094b249013c 1855 /*Calibrate FTN*/
DuyLionTran 0:8094b249013c 1856 rf_if_calibration();
DuyLionTran 0:8094b249013c 1857 /*RF is tuned now*/
DuyLionTran 0:8094b249013c 1858 rf_tuned = 1;
DuyLionTran 0:8094b249013c 1859 /*Back to default receive state*/
DuyLionTran 0:8094b249013c 1860 rf_flags_clear(RFF_RX);
DuyLionTran 0:8094b249013c 1861 rf_receive();
DuyLionTran 0:8094b249013c 1862 rf_if_unlock();
DuyLionTran 0:8094b249013c 1863 }
DuyLionTran 0:8094b249013c 1864 }
DuyLionTran 0:8094b249013c 1865
DuyLionTran 0:8094b249013c 1866 /*
DuyLionTran 0:8094b249013c 1867 * \brief Function sets RF_ON flag when radio is powered.
DuyLionTran 0:8094b249013c 1868 *
DuyLionTran 0:8094b249013c 1869 * \param none
DuyLionTran 0:8094b249013c 1870 *
DuyLionTran 0:8094b249013c 1871 * \return none
DuyLionTran 0:8094b249013c 1872 */
DuyLionTran 0:8094b249013c 1873 static void rf_on(void)
DuyLionTran 0:8094b249013c 1874 {
DuyLionTran 0:8094b249013c 1875 /*Set RFF_ON flag*/
DuyLionTran 0:8094b249013c 1876 if(rf_flags_check(RFF_ON) == 0)
DuyLionTran 0:8094b249013c 1877 {
DuyLionTran 0:8094b249013c 1878 rf_if_lock();
DuyLionTran 0:8094b249013c 1879 rf_flags_set(RFF_ON);
DuyLionTran 0:8094b249013c 1880 /*Enable Antenna diversity*/
DuyLionTran 0:8094b249013c 1881 if(rf_use_antenna_diversity)
DuyLionTran 0:8094b249013c 1882 /*Set ANT_EXT_SW_EN to enable controlling of antenna diversity*/
DuyLionTran 0:8094b249013c 1883 rf_if_enable_ant_div();
DuyLionTran 0:8094b249013c 1884
DuyLionTran 0:8094b249013c 1885 /*Wake up from sleep state*/
DuyLionTran 0:8094b249013c 1886 rf_if_disable_slptr();
DuyLionTran 0:8094b249013c 1887 rf_poll_trx_state_change(TRX_OFF);
DuyLionTran 0:8094b249013c 1888 rf_if_unlock();
DuyLionTran 0:8094b249013c 1889 }
DuyLionTran 0:8094b249013c 1890 }
DuyLionTran 0:8094b249013c 1891
DuyLionTran 0:8094b249013c 1892 /*
DuyLionTran 0:8094b249013c 1893 * \brief Function handles the received ACK frame.
DuyLionTran 0:8094b249013c 1894 *
DuyLionTran 0:8094b249013c 1895 * \param seq_number Sequence number of received ACK
DuyLionTran 0:8094b249013c 1896 * \param data_pending Pending bit state in received ACK
DuyLionTran 0:8094b249013c 1897 *
DuyLionTran 0:8094b249013c 1898 * \return none
DuyLionTran 0:8094b249013c 1899 */
DuyLionTran 0:8094b249013c 1900 static void rf_handle_ack(uint8_t seq_number, uint8_t data_pending)
DuyLionTran 0:8094b249013c 1901 {
DuyLionTran 0:8094b249013c 1902 phy_link_tx_status_e phy_status;
DuyLionTran 0:8094b249013c 1903 rf_if_lock();
DuyLionTran 0:8094b249013c 1904 /*Received ACK sequence must be equal with transmitted packet sequence*/
DuyLionTran 0:8094b249013c 1905 if(tx_sequence == seq_number)
DuyLionTran 0:8094b249013c 1906 {
DuyLionTran 0:8094b249013c 1907 rf_ack_wait_timer_stop();
DuyLionTran 0:8094b249013c 1908 /*When data pending bit in ACK frame is set, inform NET library*/
DuyLionTran 0:8094b249013c 1909 if(data_pending)
DuyLionTran 0:8094b249013c 1910 phy_status = PHY_LINK_TX_DONE_PENDING;
DuyLionTran 0:8094b249013c 1911 else
DuyLionTran 0:8094b249013c 1912 phy_status = PHY_LINK_TX_DONE;
DuyLionTran 0:8094b249013c 1913 /*Call PHY TX Done API*/
DuyLionTran 0:8094b249013c 1914 if(device_driver.phy_tx_done_cb){
DuyLionTran 0:8094b249013c 1915 device_driver.phy_tx_done_cb(rf_radio_driver_id, mac_tx_handle,phy_status, 1, 1);
DuyLionTran 0:8094b249013c 1916 }
DuyLionTran 0:8094b249013c 1917 }
DuyLionTran 0:8094b249013c 1918 rf_if_unlock();
DuyLionTran 0:8094b249013c 1919 }
DuyLionTran 0:8094b249013c 1920
DuyLionTran 0:8094b249013c 1921 /*
DuyLionTran 0:8094b249013c 1922 * \brief Function is a call back for RX end interrupt.
DuyLionTran 0:8094b249013c 1923 *
DuyLionTran 0:8094b249013c 1924 * \param none
DuyLionTran 0:8094b249013c 1925 *
DuyLionTran 0:8094b249013c 1926 * \return none
DuyLionTran 0:8094b249013c 1927 */
DuyLionTran 0:8094b249013c 1928 static void rf_handle_rx_end(void)
DuyLionTran 0:8094b249013c 1929 {
DuyLionTran 0:8094b249013c 1930 uint8_t rf_lqi = 0;
DuyLionTran 0:8094b249013c 1931 int8_t rf_rssi = 0;
DuyLionTran 0:8094b249013c 1932
DuyLionTran 0:8094b249013c 1933 /*Start receiver*/
DuyLionTran 0:8094b249013c 1934 rf_flags_clear(RFF_RX);
DuyLionTran 0:8094b249013c 1935 rf_receive();
DuyLionTran 0:8094b249013c 1936
DuyLionTran 0:8094b249013c 1937 /*Frame received interrupt*/
DuyLionTran 0:8094b249013c 1938 if(rf_flags_check(RFF_RX))
DuyLionTran 0:8094b249013c 1939 {
DuyLionTran 0:8094b249013c 1940 /*Check CRC_valid bit*/
DuyLionTran 0:8094b249013c 1941 if(rf_if_check_crc())
DuyLionTran 0:8094b249013c 1942 {
DuyLionTran 0:8094b249013c 1943 uint8_t *rf_rx_ptr;
DuyLionTran 0:8094b249013c 1944 uint8_t receiving_ack = 0;
DuyLionTran 0:8094b249013c 1945 /*Read length*/
DuyLionTran 0:8094b249013c 1946 uint8_t len = rf_if_read_received_frame_length();
DuyLionTran 0:8094b249013c 1947
DuyLionTran 0:8094b249013c 1948 rf_rx_ptr = rf_buffer;
DuyLionTran 0:8094b249013c 1949 /*ACK frame*/
DuyLionTran 0:8094b249013c 1950 if(len == 5)
DuyLionTran 0:8094b249013c 1951 {
DuyLionTran 0:8094b249013c 1952 /*Read ACK in static ACK buffer*/
DuyLionTran 0:8094b249013c 1953 receiving_ack = 1;
DuyLionTran 0:8094b249013c 1954 }
DuyLionTran 0:8094b249013c 1955 /*Check the length is valid*/
DuyLionTran 0:8094b249013c 1956 if(len > 1 && len < RF_BUFFER_SIZE)
DuyLionTran 0:8094b249013c 1957 {
DuyLionTran 0:8094b249013c 1958 /*Read received packet*/
DuyLionTran 0:8094b249013c 1959 rf_if_read_packet(rf_rx_ptr, len);
DuyLionTran 0:8094b249013c 1960
DuyLionTran 0:8094b249013c 1961 if(!receiving_ack)
DuyLionTran 0:8094b249013c 1962 {
DuyLionTran 0:8094b249013c 1963 rf_rssi = rf_if_read_rssi();
DuyLionTran 0:8094b249013c 1964 /*Scale LQI using received RSSI*/
DuyLionTran 0:8094b249013c 1965 rf_lqi = rf_scale_lqi(rf_rssi);
DuyLionTran 0:8094b249013c 1966 }
DuyLionTran 0:8094b249013c 1967 if(rf_mode == RF_MODE_SNIFFER)
DuyLionTran 0:8094b249013c 1968 {
DuyLionTran 0:8094b249013c 1969 if( device_driver.phy_rx_cb ){
DuyLionTran 0:8094b249013c 1970 device_driver.phy_rx_cb(rf_buffer,len - 2, rf_lqi, rf_rssi, rf_radio_driver_id);
DuyLionTran 0:8094b249013c 1971 }
DuyLionTran 0:8094b249013c 1972 }
DuyLionTran 0:8094b249013c 1973 else
DuyLionTran 0:8094b249013c 1974 {
DuyLionTran 0:8094b249013c 1975 /*Handle received ACK*/
DuyLionTran 0:8094b249013c 1976 if(receiving_ack && ((rf_buffer[0] & 0x07) == 0x02))
DuyLionTran 0:8094b249013c 1977 {
DuyLionTran 0:8094b249013c 1978 uint8_t pending = 0;
DuyLionTran 0:8094b249013c 1979 /*Check if data is pending*/
DuyLionTran 0:8094b249013c 1980 if ((rf_buffer[0] & 0x10))
DuyLionTran 0:8094b249013c 1981 {
DuyLionTran 0:8094b249013c 1982 pending=1;
DuyLionTran 0:8094b249013c 1983 }
DuyLionTran 0:8094b249013c 1984 /*Send sequence number in ACK handler*/
DuyLionTran 0:8094b249013c 1985 rf_handle_ack(rf_buffer[2], pending);
DuyLionTran 0:8094b249013c 1986 }
DuyLionTran 0:8094b249013c 1987 else
DuyLionTran 0:8094b249013c 1988 {
DuyLionTran 0:8094b249013c 1989 if( device_driver.phy_rx_cb ){
DuyLionTran 0:8094b249013c 1990 device_driver.phy_rx_cb(rf_buffer,len - 2, rf_lqi, rf_rssi, rf_radio_driver_id);
DuyLionTran 0:8094b249013c 1991 }
DuyLionTran 0:8094b249013c 1992 }
DuyLionTran 0:8094b249013c 1993 }
DuyLionTran 0:8094b249013c 1994 }
DuyLionTran 0:8094b249013c 1995 }
DuyLionTran 0:8094b249013c 1996 }
DuyLionTran 0:8094b249013c 1997 }
DuyLionTran 0:8094b249013c 1998
DuyLionTran 0:8094b249013c 1999 /*
DuyLionTran 0:8094b249013c 2000 * \brief Function is called when MAC is shutting down the radio.
DuyLionTran 0:8094b249013c 2001 *
DuyLionTran 0:8094b249013c 2002 * \param none
DuyLionTran 0:8094b249013c 2003 *
DuyLionTran 0:8094b249013c 2004 * \return none
DuyLionTran 0:8094b249013c 2005 */
DuyLionTran 0:8094b249013c 2006 static void rf_shutdown(void)
DuyLionTran 0:8094b249013c 2007 {
DuyLionTran 0:8094b249013c 2008 /*Call RF OFF*/
DuyLionTran 0:8094b249013c 2009 rf_off();
DuyLionTran 0:8094b249013c 2010 }
DuyLionTran 0:8094b249013c 2011
DuyLionTran 0:8094b249013c 2012 /*
DuyLionTran 0:8094b249013c 2013 * \brief Function is a call back for TX end interrupt.
DuyLionTran 0:8094b249013c 2014 *
DuyLionTran 0:8094b249013c 2015 * \param none
DuyLionTran 0:8094b249013c 2016 *
DuyLionTran 0:8094b249013c 2017 * \return none
DuyLionTran 0:8094b249013c 2018 */
DuyLionTran 0:8094b249013c 2019 static void rf_handle_tx_end(void)
DuyLionTran 0:8094b249013c 2020 {
DuyLionTran 0:8094b249013c 2021 phy_link_tx_status_e phy_status = PHY_LINK_TX_SUCCESS;
DuyLionTran 0:8094b249013c 2022
DuyLionTran 0:8094b249013c 2023 rf_rx_mode = 0;
DuyLionTran 0:8094b249013c 2024 /*If ACK is needed for this transmission*/
DuyLionTran 0:8094b249013c 2025 if(need_ack && rf_flags_check(RFF_TX))
DuyLionTran 0:8094b249013c 2026 {
DuyLionTran 0:8094b249013c 2027 rf_ack_wait_timer_start(rf_ack_wait_duration);
DuyLionTran 0:8094b249013c 2028 rf_rx_mode = 1;
DuyLionTran 0:8094b249013c 2029 }
DuyLionTran 0:8094b249013c 2030 rf_flags_clear(RFF_RX);
DuyLionTran 0:8094b249013c 2031 /*Start receiver*/
DuyLionTran 0:8094b249013c 2032 rf_receive();
DuyLionTran 0:8094b249013c 2033
DuyLionTran 0:8094b249013c 2034 /*Call PHY TX Done API*/
DuyLionTran 0:8094b249013c 2035 if(device_driver.phy_tx_done_cb){
DuyLionTran 0:8094b249013c 2036 device_driver.phy_tx_done_cb(rf_radio_driver_id, mac_tx_handle, phy_status, 1, 1);
DuyLionTran 0:8094b249013c 2037 }
DuyLionTran 0:8094b249013c 2038 }
DuyLionTran 0:8094b249013c 2039
DuyLionTran 0:8094b249013c 2040 /*
DuyLionTran 0:8094b249013c 2041 * \brief Function is a call back for CCA ED done interrupt.
DuyLionTran 0:8094b249013c 2042 *
DuyLionTran 0:8094b249013c 2043 * \param none
DuyLionTran 0:8094b249013c 2044 *
DuyLionTran 0:8094b249013c 2045 * \return none
DuyLionTran 0:8094b249013c 2046 */
DuyLionTran 0:8094b249013c 2047 static void rf_handle_cca_ed_done(void)
DuyLionTran 0:8094b249013c 2048 {
DuyLionTran 0:8094b249013c 2049 rf_flags_clear(RFF_CCA);
DuyLionTran 0:8094b249013c 2050 /*Check the result of CCA process*/
DuyLionTran 0:8094b249013c 2051 if(rf_if_check_cca())
DuyLionTran 0:8094b249013c 2052 {
DuyLionTran 0:8094b249013c 2053 rf_start_tx();
DuyLionTran 0:8094b249013c 2054 }
DuyLionTran 0:8094b249013c 2055 else
DuyLionTran 0:8094b249013c 2056 {
DuyLionTran 0:8094b249013c 2057 /*Send CCA fail notification*/
DuyLionTran 0:8094b249013c 2058 if(device_driver.phy_tx_done_cb){
DuyLionTran 0:8094b249013c 2059 device_driver.phy_tx_done_cb(rf_radio_driver_id, mac_tx_handle, PHY_LINK_CCA_FAIL, 1, 1);
DuyLionTran 0:8094b249013c 2060 }
DuyLionTran 0:8094b249013c 2061 }
DuyLionTran 0:8094b249013c 2062 }
DuyLionTran 0:8094b249013c 2063
DuyLionTran 0:8094b249013c 2064 /*
DuyLionTran 0:8094b249013c 2065 * \brief Function returns the TX power variable.
DuyLionTran 0:8094b249013c 2066 *
DuyLionTran 0:8094b249013c 2067 * \param none
DuyLionTran 0:8094b249013c 2068 *
DuyLionTran 0:8094b249013c 2069 * \return radio_tx_power TX power variable
DuyLionTran 0:8094b249013c 2070 */
DuyLionTran 0:8094b249013c 2071 MBED_UNUSED static uint8_t rf_tx_power_get(void)
DuyLionTran 0:8094b249013c 2072 {
DuyLionTran 0:8094b249013c 2073 return radio_tx_power;
DuyLionTran 0:8094b249013c 2074 }
DuyLionTran 0:8094b249013c 2075
DuyLionTran 0:8094b249013c 2076 /*
DuyLionTran 0:8094b249013c 2077 * \brief Function enables the usage of Antenna diversity.
DuyLionTran 0:8094b249013c 2078 *
DuyLionTran 0:8094b249013c 2079 * \param none
DuyLionTran 0:8094b249013c 2080 *
DuyLionTran 0:8094b249013c 2081 * \return 0 Success
DuyLionTran 0:8094b249013c 2082 */
DuyLionTran 0:8094b249013c 2083 MBED_UNUSED static int8_t rf_enable_antenna_diversity(void)
DuyLionTran 0:8094b249013c 2084 {
DuyLionTran 0:8094b249013c 2085 int8_t ret_val = 0;
DuyLionTran 0:8094b249013c 2086 rf_use_antenna_diversity = 1;
DuyLionTran 0:8094b249013c 2087 return ret_val;
DuyLionTran 0:8094b249013c 2088 }
DuyLionTran 0:8094b249013c 2089
DuyLionTran 0:8094b249013c 2090 /*
DuyLionTran 0:8094b249013c 2091 * \brief Function gives the control of RF states to MAC.
DuyLionTran 0:8094b249013c 2092 *
DuyLionTran 0:8094b249013c 2093 * \param new_state RF state
DuyLionTran 0:8094b249013c 2094 * \param rf_channel RF channel
DuyLionTran 0:8094b249013c 2095 *
DuyLionTran 0:8094b249013c 2096 * \return 0 Success
DuyLionTran 0:8094b249013c 2097 */
DuyLionTran 0:8094b249013c 2098 static int8_t rf_interface_state_control(phy_interface_state_e new_state, uint8_t rf_channel)
DuyLionTran 0:8094b249013c 2099 {
DuyLionTran 0:8094b249013c 2100 int8_t ret_val = 0;
DuyLionTran 0:8094b249013c 2101 switch (new_state)
DuyLionTran 0:8094b249013c 2102 {
DuyLionTran 0:8094b249013c 2103 /*Reset PHY driver and set to idle*/
DuyLionTran 0:8094b249013c 2104 case PHY_INTERFACE_RESET:
DuyLionTran 0:8094b249013c 2105 break;
DuyLionTran 0:8094b249013c 2106 /*Disable PHY Interface driver*/
DuyLionTran 0:8094b249013c 2107 case PHY_INTERFACE_DOWN:
DuyLionTran 0:8094b249013c 2108 rf_shutdown();
DuyLionTran 0:8094b249013c 2109 break;
DuyLionTran 0:8094b249013c 2110 /*Enable PHY Interface driver*/
DuyLionTran 0:8094b249013c 2111 case PHY_INTERFACE_UP:
DuyLionTran 0:8094b249013c 2112 rf_mode = RF_MODE_NORMAL;
DuyLionTran 0:8094b249013c 2113 rf_channel_set(rf_channel);
DuyLionTran 0:8094b249013c 2114 rf_receive();
DuyLionTran 0:8094b249013c 2115 rf_if_enable_irq();
DuyLionTran 0:8094b249013c 2116 break;
DuyLionTran 0:8094b249013c 2117 /*Enable wireless interface ED scan mode*/
DuyLionTran 0:8094b249013c 2118 case PHY_INTERFACE_RX_ENERGY_STATE:
DuyLionTran 0:8094b249013c 2119 rf_mode = RF_MODE_ED;
DuyLionTran 0:8094b249013c 2120 rf_channel_set(rf_channel);
DuyLionTran 0:8094b249013c 2121 rf_receive();
DuyLionTran 0:8094b249013c 2122 rf_if_disable_irq();
DuyLionTran 0:8094b249013c 2123 // Read status to clear pending flags.
DuyLionTran 0:8094b249013c 2124 rf_if_read_register(IRQ_STATUS);
DuyLionTran 0:8094b249013c 2125 // Must set interrupt mask to be able to read IRQ status. GPIO interrupt is disabled.
DuyLionTran 0:8094b249013c 2126 rf_if_set_bit(IRQ_MASK, CCA_ED_DONE, CCA_ED_DONE);
DuyLionTran 0:8094b249013c 2127 // ED can be initiated by writing arbitrary value to PHY_ED_LEVEL
DuyLionTran 0:8094b249013c 2128 rf_if_write_register(PHY_ED_LEVEL, 0xff);
DuyLionTran 0:8094b249013c 2129 break;
DuyLionTran 0:8094b249013c 2130 case PHY_INTERFACE_SNIFFER_STATE: /**< Enable Sniffer state */
DuyLionTran 0:8094b249013c 2131 rf_mode = RF_MODE_SNIFFER;
DuyLionTran 0:8094b249013c 2132 rf_channel_set(rf_channel);
DuyLionTran 0:8094b249013c 2133 rf_flags_clear(RFF_RX);
DuyLionTran 0:8094b249013c 2134 rf_receive();
DuyLionTran 0:8094b249013c 2135 break;
DuyLionTran 0:8094b249013c 2136 }
DuyLionTran 0:8094b249013c 2137 return ret_val;
DuyLionTran 0:8094b249013c 2138 }
DuyLionTran 0:8094b249013c 2139
DuyLionTran 0:8094b249013c 2140 /*
DuyLionTran 0:8094b249013c 2141 * \brief Function controls the ACK pending, channel setting and energy detection.
DuyLionTran 0:8094b249013c 2142 *
DuyLionTran 0:8094b249013c 2143 * \param extension_type Type of control
DuyLionTran 0:8094b249013c 2144 * \param data_ptr Data from NET library
DuyLionTran 0:8094b249013c 2145 *
DuyLionTran 0:8094b249013c 2146 * \return 0 Success
DuyLionTran 0:8094b249013c 2147 */
DuyLionTran 0:8094b249013c 2148 static int8_t rf_extension(phy_extension_type_e extension_type, uint8_t *data_ptr)
DuyLionTran 0:8094b249013c 2149 {
DuyLionTran 0:8094b249013c 2150 switch (extension_type)
DuyLionTran 0:8094b249013c 2151 {
DuyLionTran 0:8094b249013c 2152 /*Control MAC pending bit for Indirect data transmission*/
DuyLionTran 0:8094b249013c 2153 case PHY_EXTENSION_CTRL_PENDING_BIT:
DuyLionTran 0:8094b249013c 2154 if(*data_ptr)
DuyLionTran 0:8094b249013c 2155 {
DuyLionTran 0:8094b249013c 2156 rf_if_ack_pending_ctrl(1);
DuyLionTran 0:8094b249013c 2157 }
DuyLionTran 0:8094b249013c 2158 else
DuyLionTran 0:8094b249013c 2159 {
DuyLionTran 0:8094b249013c 2160 rf_if_ack_pending_ctrl(0);
DuyLionTran 0:8094b249013c 2161 }
DuyLionTran 0:8094b249013c 2162 break;
DuyLionTran 0:8094b249013c 2163 /*Return frame pending status*/
DuyLionTran 0:8094b249013c 2164 case PHY_EXTENSION_READ_LAST_ACK_PENDING_STATUS:
DuyLionTran 0:8094b249013c 2165 *data_ptr = rf_if_last_acked_pending();
DuyLionTran 0:8094b249013c 2166 break;
DuyLionTran 0:8094b249013c 2167 /*Set channel*/
DuyLionTran 0:8094b249013c 2168 case PHY_EXTENSION_SET_CHANNEL:
DuyLionTran 0:8094b249013c 2169 break;
DuyLionTran 0:8094b249013c 2170 /*Read energy on the channel*/
DuyLionTran 0:8094b249013c 2171 case PHY_EXTENSION_READ_CHANNEL_ENERGY:
DuyLionTran 0:8094b249013c 2172 // End of the ED measurement is indicated by CCA_ED_DONE
DuyLionTran 0:8094b249013c 2173 while (!(rf_if_read_register(IRQ_STATUS) & CCA_ED_DONE));
DuyLionTran 0:8094b249013c 2174 // RF input power: RSSI base level + 1[db] * PHY_ED_LEVEL
DuyLionTran 0:8094b249013c 2175 *data_ptr = rf_sensitivity + rf_if_read_register(PHY_ED_LEVEL);
DuyLionTran 0:8094b249013c 2176 // Read status to clear pending flags.
DuyLionTran 0:8094b249013c 2177 rf_if_read_register(IRQ_STATUS);
DuyLionTran 0:8094b249013c 2178 // Next ED measurement is started, next PHY_EXTENSION_READ_CHANNEL_ENERGY call will return the result.
DuyLionTran 0:8094b249013c 2179 rf_if_write_register(PHY_ED_LEVEL, 0xff);
DuyLionTran 0:8094b249013c 2180 break;
DuyLionTran 0:8094b249013c 2181 /*Read status of the link*/
DuyLionTran 0:8094b249013c 2182 case PHY_EXTENSION_READ_LINK_STATUS:
DuyLionTran 0:8094b249013c 2183 break;
DuyLionTran 0:8094b249013c 2184 default:
DuyLionTran 0:8094b249013c 2185 break;
DuyLionTran 0:8094b249013c 2186 }
DuyLionTran 0:8094b249013c 2187 return 0;
DuyLionTran 0:8094b249013c 2188 }
DuyLionTran 0:8094b249013c 2189
DuyLionTran 0:8094b249013c 2190 /*
DuyLionTran 0:8094b249013c 2191 * \brief Function sets the addresses to RF address filters.
DuyLionTran 0:8094b249013c 2192 *
DuyLionTran 0:8094b249013c 2193 * \param address_type Type of address
DuyLionTran 0:8094b249013c 2194 * \param address_ptr Pointer to given address
DuyLionTran 0:8094b249013c 2195 *
DuyLionTran 0:8094b249013c 2196 * \return 0 Success
DuyLionTran 0:8094b249013c 2197 */
DuyLionTran 0:8094b249013c 2198 static int8_t rf_address_write(phy_address_type_e address_type, uint8_t *address_ptr)
DuyLionTran 0:8094b249013c 2199 {
DuyLionTran 0:8094b249013c 2200 int8_t ret_val = 0;
DuyLionTran 0:8094b249013c 2201 switch (address_type)
DuyLionTran 0:8094b249013c 2202 {
DuyLionTran 0:8094b249013c 2203 /*Set 48-bit address*/
DuyLionTran 0:8094b249013c 2204 case PHY_MAC_48BIT:
DuyLionTran 0:8094b249013c 2205 break;
DuyLionTran 0:8094b249013c 2206 /*Set 64-bit address*/
DuyLionTran 0:8094b249013c 2207 case PHY_MAC_64BIT:
DuyLionTran 0:8094b249013c 2208 rf_set_address(address_ptr);
DuyLionTran 0:8094b249013c 2209 break;
DuyLionTran 0:8094b249013c 2210 /*Set 16-bit address*/
DuyLionTran 0:8094b249013c 2211 case PHY_MAC_16BIT:
DuyLionTran 0:8094b249013c 2212 rf_set_short_adr(address_ptr);
DuyLionTran 0:8094b249013c 2213 break;
DuyLionTran 0:8094b249013c 2214 /*Set PAN Id*/
DuyLionTran 0:8094b249013c 2215 case PHY_MAC_PANID:
DuyLionTran 0:8094b249013c 2216 rf_set_pan_id(address_ptr);
DuyLionTran 0:8094b249013c 2217 break;
DuyLionTran 0:8094b249013c 2218 }
DuyLionTran 0:8094b249013c 2219 return ret_val;
DuyLionTran 0:8094b249013c 2220 }
DuyLionTran 0:8094b249013c 2221
DuyLionTran 0:8094b249013c 2222 /*
DuyLionTran 0:8094b249013c 2223 * \brief Function initialises the ACK wait time and returns the used PHY mode.
DuyLionTran 0:8094b249013c 2224 *
DuyLionTran 0:8094b249013c 2225 * \param none
DuyLionTran 0:8094b249013c 2226 *
DuyLionTran 0:8094b249013c 2227 * \return tmp Used PHY mode
DuyLionTran 0:8094b249013c 2228 */
DuyLionTran 0:8094b249013c 2229 static void rf_init_phy_mode(void)
DuyLionTran 0:8094b249013c 2230 {
DuyLionTran 0:8094b249013c 2231 uint8_t tmp = 0;
DuyLionTran 0:8094b249013c 2232 uint8_t part = rf_if_read_part_num();
DuyLionTran 0:8094b249013c 2233 /*Read used PHY Mode*/
DuyLionTran 0:8094b249013c 2234 tmp = rf_if_read_register(TRX_CTRL_2);
DuyLionTran 0:8094b249013c 2235 /*Set ACK wait time for used data rate*/
DuyLionTran 0:8094b249013c 2236 if(part == PART_AT86RF212)
DuyLionTran 0:8094b249013c 2237 {
DuyLionTran 0:8094b249013c 2238 if((tmp & 0x1f) == 0x00)
DuyLionTran 0:8094b249013c 2239 {
DuyLionTran 0:8094b249013c 2240 rf_sensitivity = -110;
DuyLionTran 0:8094b249013c 2241 rf_ack_wait_duration = 938;
DuyLionTran 0:8094b249013c 2242 tmp = BPSK_20;
DuyLionTran 0:8094b249013c 2243 }
DuyLionTran 0:8094b249013c 2244 else if((tmp & 0x1f) == 0x04)
DuyLionTran 0:8094b249013c 2245 {
DuyLionTran 0:8094b249013c 2246 rf_sensitivity = -108;
DuyLionTran 0:8094b249013c 2247 rf_ack_wait_duration = 469;
DuyLionTran 0:8094b249013c 2248 tmp = BPSK_40;
DuyLionTran 0:8094b249013c 2249 }
DuyLionTran 0:8094b249013c 2250 else if((tmp & 0x1f) == 0x14)
DuyLionTran 0:8094b249013c 2251 {
DuyLionTran 0:8094b249013c 2252 rf_sensitivity = -108;
DuyLionTran 0:8094b249013c 2253 rf_ack_wait_duration = 469;
DuyLionTran 0:8094b249013c 2254 tmp = BPSK_40_ALT;
DuyLionTran 0:8094b249013c 2255 }
DuyLionTran 0:8094b249013c 2256 else if((tmp & 0x1f) == 0x08)
DuyLionTran 0:8094b249013c 2257 {
DuyLionTran 0:8094b249013c 2258 rf_sensitivity = -101;
DuyLionTran 0:8094b249013c 2259 rf_ack_wait_duration = 50;
DuyLionTran 0:8094b249013c 2260 tmp = OQPSK_SIN_RC_100;
DuyLionTran 0:8094b249013c 2261 }
DuyLionTran 0:8094b249013c 2262 else if((tmp & 0x1f) == 0x09)
DuyLionTran 0:8094b249013c 2263 {
DuyLionTran 0:8094b249013c 2264 rf_sensitivity = -99;
DuyLionTran 0:8094b249013c 2265 rf_ack_wait_duration = 30;
DuyLionTran 0:8094b249013c 2266 tmp = OQPSK_SIN_RC_200;
DuyLionTran 0:8094b249013c 2267 }
DuyLionTran 0:8094b249013c 2268 else if((tmp & 0x1f) == 0x18)
DuyLionTran 0:8094b249013c 2269 {
DuyLionTran 0:8094b249013c 2270 rf_sensitivity = -102;
DuyLionTran 0:8094b249013c 2271 rf_ack_wait_duration = 50;
DuyLionTran 0:8094b249013c 2272 tmp = OQPSK_RC_100;
DuyLionTran 0:8094b249013c 2273 }
DuyLionTran 0:8094b249013c 2274 else if((tmp & 0x1f) == 0x19)
DuyLionTran 0:8094b249013c 2275 {
DuyLionTran 0:8094b249013c 2276 rf_sensitivity = -100;
DuyLionTran 0:8094b249013c 2277 rf_ack_wait_duration = 30;
DuyLionTran 0:8094b249013c 2278 tmp = OQPSK_RC_200;
DuyLionTran 0:8094b249013c 2279 }
DuyLionTran 0:8094b249013c 2280 else if((tmp & 0x1f) == 0x0c)
DuyLionTran 0:8094b249013c 2281 {
DuyLionTran 0:8094b249013c 2282 rf_sensitivity = -100;
DuyLionTran 0:8094b249013c 2283 rf_ack_wait_duration = 20;
DuyLionTran 0:8094b249013c 2284 tmp = OQPSK_SIN_250;
DuyLionTran 0:8094b249013c 2285 }
DuyLionTran 0:8094b249013c 2286 else if((tmp & 0x1f) == 0x0d)
DuyLionTran 0:8094b249013c 2287 {
DuyLionTran 0:8094b249013c 2288 rf_sensitivity = -98;
DuyLionTran 0:8094b249013c 2289 rf_ack_wait_duration = 25;
DuyLionTran 0:8094b249013c 2290 tmp = OQPSK_SIN_500;
DuyLionTran 0:8094b249013c 2291 }
DuyLionTran 0:8094b249013c 2292 else if((tmp & 0x1f) == 0x0f)
DuyLionTran 0:8094b249013c 2293 {
DuyLionTran 0:8094b249013c 2294 rf_sensitivity = -98;
DuyLionTran 0:8094b249013c 2295 rf_ack_wait_duration = 25;
DuyLionTran 0:8094b249013c 2296 tmp = OQPSK_SIN_500_ALT;
DuyLionTran 0:8094b249013c 2297 }
DuyLionTran 0:8094b249013c 2298 else if((tmp & 0x1f) == 0x1c)
DuyLionTran 0:8094b249013c 2299 {
DuyLionTran 0:8094b249013c 2300 rf_sensitivity = -101;
DuyLionTran 0:8094b249013c 2301 rf_ack_wait_duration = 20;
DuyLionTran 0:8094b249013c 2302 tmp = OQPSK_RC_250;
DuyLionTran 0:8094b249013c 2303 }
DuyLionTran 0:8094b249013c 2304 else if((tmp & 0x1f) == 0x1d)
DuyLionTran 0:8094b249013c 2305 {
DuyLionTran 0:8094b249013c 2306 rf_sensitivity = -99;
DuyLionTran 0:8094b249013c 2307 rf_ack_wait_duration = 25;
DuyLionTran 0:8094b249013c 2308 tmp = OQPSK_RC_500;
DuyLionTran 0:8094b249013c 2309 }
DuyLionTran 0:8094b249013c 2310 else if((tmp & 0x1f) == 0x1f)
DuyLionTran 0:8094b249013c 2311 {
DuyLionTran 0:8094b249013c 2312 rf_sensitivity = -99;
DuyLionTran 0:8094b249013c 2313 rf_ack_wait_duration = 25;
DuyLionTran 0:8094b249013c 2314 tmp = OQPSK_RC_500_ALT;
DuyLionTran 0:8094b249013c 2315 }
DuyLionTran 0:8094b249013c 2316 else if((tmp & 0x3f) == 0x2A)
DuyLionTran 0:8094b249013c 2317 {
DuyLionTran 0:8094b249013c 2318 rf_sensitivity = -91;
DuyLionTran 0:8094b249013c 2319 rf_ack_wait_duration = 25;
DuyLionTran 0:8094b249013c 2320 tmp = OQPSK_SIN_RC_400_SCR_ON;
DuyLionTran 0:8094b249013c 2321 }
DuyLionTran 0:8094b249013c 2322 else if((tmp & 0x3f) == 0x0A)
DuyLionTran 0:8094b249013c 2323 {
DuyLionTran 0:8094b249013c 2324 rf_sensitivity = -91;
DuyLionTran 0:8094b249013c 2325 rf_ack_wait_duration = 25;
DuyLionTran 0:8094b249013c 2326 tmp = OQPSK_SIN_RC_400_SCR_OFF;
DuyLionTran 0:8094b249013c 2327 }
DuyLionTran 0:8094b249013c 2328 else if((tmp & 0x3f) == 0x3A)
DuyLionTran 0:8094b249013c 2329 {
DuyLionTran 0:8094b249013c 2330 rf_sensitivity = -97;
DuyLionTran 0:8094b249013c 2331 rf_ack_wait_duration = 25;
DuyLionTran 0:8094b249013c 2332 tmp = OQPSK_RC_400_SCR_ON;
DuyLionTran 0:8094b249013c 2333 }
DuyLionTran 0:8094b249013c 2334 else if((tmp & 0x3f) == 0x1A)
DuyLionTran 0:8094b249013c 2335 {
DuyLionTran 0:8094b249013c 2336 rf_sensitivity = -97;
DuyLionTran 0:8094b249013c 2337 rf_ack_wait_duration = 25;
DuyLionTran 0:8094b249013c 2338 tmp = OQPSK_RC_400_SCR_OFF;
DuyLionTran 0:8094b249013c 2339 }
DuyLionTran 0:8094b249013c 2340 else if((tmp & 0x3f) == 0x2E)
DuyLionTran 0:8094b249013c 2341 {
DuyLionTran 0:8094b249013c 2342 rf_sensitivity = -93;
DuyLionTran 0:8094b249013c 2343 rf_ack_wait_duration = 13;
DuyLionTran 0:8094b249013c 2344 tmp = OQPSK_SIN_1000_SCR_ON;
DuyLionTran 0:8094b249013c 2345 }
DuyLionTran 0:8094b249013c 2346 else if((tmp & 0x3f) == 0x0E)
DuyLionTran 0:8094b249013c 2347 {
DuyLionTran 0:8094b249013c 2348 rf_sensitivity = -93;
DuyLionTran 0:8094b249013c 2349 rf_ack_wait_duration = 13;
DuyLionTran 0:8094b249013c 2350 tmp = OQPSK_SIN_1000_SCR_OFF;
DuyLionTran 0:8094b249013c 2351 }
DuyLionTran 0:8094b249013c 2352 else if((tmp & 0x3f) == 0x3E)
DuyLionTran 0:8094b249013c 2353 {
DuyLionTran 0:8094b249013c 2354 rf_sensitivity = -95;
DuyLionTran 0:8094b249013c 2355 rf_ack_wait_duration = 13;
DuyLionTran 0:8094b249013c 2356 tmp = OQPSK_RC_1000_SCR_ON;
DuyLionTran 0:8094b249013c 2357 }
DuyLionTran 0:8094b249013c 2358 else if((tmp & 0x3f) == 0x1E)
DuyLionTran 0:8094b249013c 2359 {
DuyLionTran 0:8094b249013c 2360 rf_sensitivity = -95;
DuyLionTran 0:8094b249013c 2361 rf_ack_wait_duration = 13;
DuyLionTran 0:8094b249013c 2362 tmp = OQPSK_RC_1000_SCR_OFF;
DuyLionTran 0:8094b249013c 2363 }
DuyLionTran 0:8094b249013c 2364 }
DuyLionTran 0:8094b249013c 2365 else
DuyLionTran 0:8094b249013c 2366 {
DuyLionTran 0:8094b249013c 2367 rf_sensitivity = -101;
DuyLionTran 0:8094b249013c 2368 rf_ack_wait_duration = 20;
DuyLionTran 0:8094b249013c 2369 }
DuyLionTran 0:8094b249013c 2370 /*Board design might reduces the sensitivity*/
DuyLionTran 0:8094b249013c 2371 //rf_sensitivity += RF_SENSITIVITY_CALIBRATION;
DuyLionTran 0:8094b249013c 2372 }
DuyLionTran 0:8094b249013c 2373
DuyLionTran 0:8094b249013c 2374
DuyLionTran 0:8094b249013c 2375 static uint8_t rf_scale_lqi(int8_t rssi)
DuyLionTran 0:8094b249013c 2376 {
DuyLionTran 0:8094b249013c 2377 uint8_t scaled_lqi;
DuyLionTran 0:8094b249013c 2378
DuyLionTran 0:8094b249013c 2379 /*rssi < RF sensitivity*/
DuyLionTran 0:8094b249013c 2380 if(rssi < rf_sensitivity)
DuyLionTran 0:8094b249013c 2381 scaled_lqi=0;
DuyLionTran 0:8094b249013c 2382 /*-91 dBm < rssi < -81 dBm (AT86RF233 XPro)*/
DuyLionTran 0:8094b249013c 2383 /*-90 dBm < rssi < -80 dBm (AT86RF212B XPro)*/
DuyLionTran 0:8094b249013c 2384 else if(rssi < (rf_sensitivity + 10))
DuyLionTran 0:8094b249013c 2385 scaled_lqi=31;
DuyLionTran 0:8094b249013c 2386 /*-81 dBm < rssi < -71 dBm (AT86RF233 XPro)*/
DuyLionTran 0:8094b249013c 2387 /*-80 dBm < rssi < -70 dBm (AT86RF212B XPro)*/
DuyLionTran 0:8094b249013c 2388 else if(rssi < (rf_sensitivity + 20))
DuyLionTran 0:8094b249013c 2389 scaled_lqi=207;
DuyLionTran 0:8094b249013c 2390 /*-71 dBm < rssi < -61 dBm (AT86RF233 XPro)*/
DuyLionTran 0:8094b249013c 2391 /*-70 dBm < rssi < -60 dBm (AT86RF212B XPro)*/
DuyLionTran 0:8094b249013c 2392 else if(rssi < (rf_sensitivity + 30))
DuyLionTran 0:8094b249013c 2393 scaled_lqi=255;
DuyLionTran 0:8094b249013c 2394 /*-61 dBm < rssi < -51 dBm (AT86RF233 XPro)*/
DuyLionTran 0:8094b249013c 2395 /*-60 dBm < rssi < -50 dBm (AT86RF212B XPro)*/
DuyLionTran 0:8094b249013c 2396 else if(rssi < (rf_sensitivity + 40))
DuyLionTran 0:8094b249013c 2397 scaled_lqi=255;
DuyLionTran 0:8094b249013c 2398 /*-51 dBm < rssi < -41 dBm (AT86RF233 XPro)*/
DuyLionTran 0:8094b249013c 2399 /*-50 dBm < rssi < -40 dBm (AT86RF212B XPro)*/
DuyLionTran 0:8094b249013c 2400 else if(rssi < (rf_sensitivity + 50))
DuyLionTran 0:8094b249013c 2401 scaled_lqi=255;
DuyLionTran 0:8094b249013c 2402 /*-41 dBm < rssi < -31 dBm (AT86RF233 XPro)*/
DuyLionTran 0:8094b249013c 2403 /*-40 dBm < rssi < -30 dBm (AT86RF212B XPro)*/
DuyLionTran 0:8094b249013c 2404 else if(rssi < (rf_sensitivity + 60))
DuyLionTran 0:8094b249013c 2405 scaled_lqi=255;
DuyLionTran 0:8094b249013c 2406 /*-31 dBm < rssi < -21 dBm (AT86RF233 XPro)*/
DuyLionTran 0:8094b249013c 2407 /*-30 dBm < rssi < -20 dBm (AT86RF212B XPro)*/
DuyLionTran 0:8094b249013c 2408 else if(rssi < (rf_sensitivity + 70))
DuyLionTran 0:8094b249013c 2409 scaled_lqi=255;
DuyLionTran 0:8094b249013c 2410 /*rssi > RF saturation*/
DuyLionTran 0:8094b249013c 2411 else if(rssi > (rf_sensitivity + 80))
DuyLionTran 0:8094b249013c 2412 scaled_lqi=111;
DuyLionTran 0:8094b249013c 2413 /*-21 dBm < rssi < -11 dBm (AT86RF233 XPro)*/
DuyLionTran 0:8094b249013c 2414 /*-20 dBm < rssi < -10 dBm (AT86RF212B XPro)*/
DuyLionTran 0:8094b249013c 2415 else
DuyLionTran 0:8094b249013c 2416 scaled_lqi=255;
DuyLionTran 0:8094b249013c 2417
DuyLionTran 0:8094b249013c 2418 return scaled_lqi;
DuyLionTran 0:8094b249013c 2419 }
DuyLionTran 0:8094b249013c 2420
DuyLionTran 0:8094b249013c 2421 NanostackRfPhyAtmel::NanostackRfPhyAtmel(PinName spi_mosi, PinName spi_miso,
DuyLionTran 0:8094b249013c 2422 PinName spi_sclk, PinName spi_cs, PinName spi_rst, PinName spi_slp, PinName spi_irq,
DuyLionTran 0:8094b249013c 2423 PinName i2c_sda, PinName i2c_scl)
DuyLionTran 0:8094b249013c 2424 : _mac(i2c_sda, i2c_scl), _mac_addr(), _rf(NULL), _mac_set(false),
DuyLionTran 0:8094b249013c 2425 _spi_mosi(spi_mosi), _spi_miso(spi_miso), _spi_sclk(spi_sclk),
DuyLionTran 0:8094b249013c 2426 _spi_cs(spi_cs), _spi_rst(spi_rst), _spi_slp(spi_slp), _spi_irq(spi_irq)
DuyLionTran 0:8094b249013c 2427 {
DuyLionTran 0:8094b249013c 2428 _rf = new RFBits(_spi_mosi, _spi_miso, _spi_sclk, _spi_cs, _spi_rst, _spi_slp, _spi_irq);
DuyLionTran 0:8094b249013c 2429 }
DuyLionTran 0:8094b249013c 2430
DuyLionTran 0:8094b249013c 2431 NanostackRfPhyAtmel::~NanostackRfPhyAtmel()
DuyLionTran 0:8094b249013c 2432 {
DuyLionTran 0:8094b249013c 2433 delete _rf;
DuyLionTran 0:8094b249013c 2434 }
DuyLionTran 0:8094b249013c 2435
DuyLionTran 0:8094b249013c 2436 int8_t NanostackRfPhyAtmel::rf_register()
DuyLionTran 0:8094b249013c 2437 {
DuyLionTran 0:8094b249013c 2438 if (NULL == _rf) {
DuyLionTran 0:8094b249013c 2439 return -1;
DuyLionTran 0:8094b249013c 2440 }
DuyLionTran 0:8094b249013c 2441
DuyLionTran 0:8094b249013c 2442 rf_if_lock();
DuyLionTran 0:8094b249013c 2443
DuyLionTran 0:8094b249013c 2444 if (rf != NULL) {
DuyLionTran 0:8094b249013c 2445 rf_if_unlock();
DuyLionTran 0:8094b249013c 2446 error("Multiple registrations of NanostackRfPhyAtmel not supported");
DuyLionTran 0:8094b249013c 2447 return -1;
DuyLionTran 0:8094b249013c 2448 }
DuyLionTran 0:8094b249013c 2449
DuyLionTran 0:8094b249013c 2450 // Read the mac address if it hasn't been set by a user
DuyLionTran 0:8094b249013c 2451 rf = _rf;
DuyLionTran 0:8094b249013c 2452 if (!_mac_set) {
DuyLionTran 0:8094b249013c 2453 int ret = _mac.read_eui64((void*)_mac_addr);
DuyLionTran 0:8094b249013c 2454 if (ret < 0) {
DuyLionTran 0:8094b249013c 2455 rf = NULL;
DuyLionTran 0:8094b249013c 2456 rf_if_unlock();
DuyLionTran 0:8094b249013c 2457 return -1;
DuyLionTran 0:8094b249013c 2458 }
DuyLionTran 0:8094b249013c 2459 }
DuyLionTran 0:8094b249013c 2460
DuyLionTran 0:8094b249013c 2461 int8_t radio_id = rf_device_register(_mac_addr);
DuyLionTran 0:8094b249013c 2462 if (radio_id < 0) {
DuyLionTran 0:8094b249013c 2463 rf = NULL;
DuyLionTran 0:8094b249013c 2464 }
DuyLionTran 0:8094b249013c 2465
DuyLionTran 0:8094b249013c 2466 rf_if_unlock();
DuyLionTran 0:8094b249013c 2467 return radio_id;
DuyLionTran 0:8094b249013c 2468 }
DuyLionTran 0:8094b249013c 2469
DuyLionTran 0:8094b249013c 2470 void NanostackRfPhyAtmel::rf_unregister()
DuyLionTran 0:8094b249013c 2471 {
DuyLionTran 0:8094b249013c 2472 rf_if_lock();
DuyLionTran 0:8094b249013c 2473
DuyLionTran 0:8094b249013c 2474 if (NULL == rf) {
DuyLionTran 0:8094b249013c 2475 rf_if_unlock();
DuyLionTran 0:8094b249013c 2476 return;
DuyLionTran 0:8094b249013c 2477 }
DuyLionTran 0:8094b249013c 2478
DuyLionTran 0:8094b249013c 2479 rf_device_unregister();
DuyLionTran 0:8094b249013c 2480 rf = NULL;
DuyLionTran 0:8094b249013c 2481
DuyLionTran 0:8094b249013c 2482 rf_if_unlock();
DuyLionTran 0:8094b249013c 2483 }
DuyLionTran 0:8094b249013c 2484
DuyLionTran 0:8094b249013c 2485 void NanostackRfPhyAtmel::get_mac_address(uint8_t *mac)
DuyLionTran 0:8094b249013c 2486 {
DuyLionTran 0:8094b249013c 2487 rf_if_lock();
DuyLionTran 0:8094b249013c 2488
DuyLionTran 0:8094b249013c 2489 if (NULL == rf) {
DuyLionTran 0:8094b249013c 2490 error("NanostackRfPhyAtmel Must be registered to read mac address");
DuyLionTran 0:8094b249013c 2491 rf_if_unlock();
DuyLionTran 0:8094b249013c 2492 return;
DuyLionTran 0:8094b249013c 2493 }
DuyLionTran 0:8094b249013c 2494 memcpy((void*)mac, (void*)_mac_addr, sizeof(_mac_addr));
DuyLionTran 0:8094b249013c 2495
DuyLionTran 0:8094b249013c 2496 rf_if_unlock();
DuyLionTran 0:8094b249013c 2497 }
DuyLionTran 0:8094b249013c 2498
DuyLionTran 0:8094b249013c 2499 void NanostackRfPhyAtmel::set_mac_address(uint8_t *mac)
DuyLionTran 0:8094b249013c 2500 {
DuyLionTran 0:8094b249013c 2501 rf_if_lock();
DuyLionTran 0:8094b249013c 2502
DuyLionTran 0:8094b249013c 2503 if (NULL != rf) {
DuyLionTran 0:8094b249013c 2504 error("NanostackRfPhyAtmel cannot change mac address when running");
DuyLionTran 0:8094b249013c 2505 rf_if_unlock();
DuyLionTran 0:8094b249013c 2506 return;
DuyLionTran 0:8094b249013c 2507 }
DuyLionTran 0:8094b249013c 2508 memcpy((void*)_mac_addr, (void*)mac, sizeof(_mac_addr));
DuyLionTran 0:8094b249013c 2509 _mac_set = true;
DuyLionTran 0:8094b249013c 2510
DuyLionTran 0:8094b249013c 2511 rf_if_unlock();
DuyLionTran 0:8094b249013c 2512 }
DuyLionTran 0:8094b249013c 2513