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