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