hellomqttt to thingspeak mqtt and ifttt

Dependencies:   Servo MQTTPacket FP

Committer:
jasonberry
Date:
Wed May 05 14:48:01 2021 +0000
Revision:
25:ca1b1098c77f
TEST

Who changed what in which revision?

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