Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependents: TYBLE16_simple_data_logger TYBLE16_MP3_Air
virtual_rf_driver.c
00001 /* 00002 * Copyright (c) 2016-2019, Arm Limited and affiliates. 00003 * SPDX-License-Identifier: Apache-2.0 00004 * 00005 * Licensed under the Apache License, Version 2.0 (the "License"); 00006 * you may not use this file except in compliance with the License. 00007 * You may obtain a copy of the License at 00008 * 00009 * http://www.apache.org/licenses/LICENSE-2.0 00010 * 00011 * Unless required by applicable law or agreed to in writing, software 00012 * distributed under the License is distributed on an "AS IS" BASIS, 00013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 00014 * See the License for the specific language governing permissions and 00015 * limitations under the License. 00016 */ 00017 #include "nsconfig.h" 00018 #include <stdio.h> 00019 #include <string.h> 00020 00021 #include "ns_types.h" 00022 #include "ns_trace.h" 00023 #include "platform/arm_hal_phy.h" 00024 #include "mlme.h" 00025 #include "net_interface.h" 00026 #include "serial_mac_api.h" 00027 #include "virtual_rf_defines.h" 00028 #include "MAC/rf_driver_storage.h" 00029 #include "mac_api.h" 00030 00031 00032 00033 #define TRACE_GROUP "vrf" 00034 00035 static phy_device_driver_s device_driver; 00036 static uint8_t rf_mac_address[8]; 00037 static int8_t rf_driver_id = (-1); 00038 static bool data_request_pending_flag = false; 00039 00040 /** XXX: dummy values copied from Atmel RF driver */ 00041 static const phy_rf_channel_configuration_s phy_2_4ghz = {.channel_0_center_frequency = 2405000000, .channel_spacing = 5000000, .datarate = 250000, .number_of_channels = 16, .modulation = M_OQPSK}; 00042 static const phy_rf_channel_configuration_s phy_subghz = {.channel_0_center_frequency = 868300000, .channel_spacing = 2000000, .datarate = 250000, .number_of_channels = 11, .modulation = M_OQPSK}; 00043 00044 static const phy_rf_channel_configuration_s phy_subghz_8_ch = {.channel_0_center_frequency = 868300000, .channel_spacing = 2000000, .datarate = 250000, .number_of_channels = 8, .modulation = M_OQPSK}; 00045 static const phy_rf_channel_configuration_s phy_subghz_11_ch = {.channel_0_center_frequency = 868300000, .channel_spacing = 2000000, .datarate = 250000, .number_of_channels = 11, .modulation = M_OQPSK}; 00046 static const phy_rf_channel_configuration_s phy_subghz_16_ch = {.channel_0_center_frequency = 868300000, .channel_spacing = 2000000, .datarate = 250000, .number_of_channels = 16, .modulation = M_OQPSK}; 00047 static const phy_rf_channel_configuration_s phy_2_4ghz_14_ch = {.channel_0_center_frequency = 2405000000, .channel_spacing = 1000000, .datarate = 250000, .number_of_channels = 14, .modulation = M_OQPSK}; 00048 static const phy_rf_channel_configuration_s phy_2_4ghz_5_ch = {.channel_0_center_frequency = 2405000000, .channel_spacing = 1000000, .datarate = 250000, .number_of_channels = 5, .modulation = M_OQPSK}; //For FHSS testing only 00049 static const phy_rf_channel_configuration_s phy_2_4ghz_256_ch = {.channel_0_center_frequency = 2405000000, .channel_spacing = 1000000, .datarate = 250000, .number_of_channels = 256, .modulation = M_OQPSK}; //For FHSS testing only 00050 00051 static phy_device_channel_page_s phy_channel_pages[] = { 00052 {CHANNEL_PAGE_0, &phy_2_4ghz}, // this will be modified to contain 11 or 16 channels, depending on radio type 00053 {CHANNEL_PAGE_1, &phy_subghz_11_ch}, // channel 0&ASK or 1..10&ASK 00054 {CHANNEL_PAGE_2, &phy_subghz_11_ch}, // 0&O-QPSK, or 1-10&O-QPSK 00055 // following are based on 202.15.2009 additional channel pages: 00056 {CHANNEL_PAGE_3, &phy_2_4ghz_14_ch}, // 0.13&CSSS 00057 {CHANNEL_PAGE_4, &phy_subghz_16_ch}, // 0&UWB, 1-4&UWB or 5-15&UWB 00058 {CHANNEL_PAGE_5, &phy_subghz_8_ch}, // this would need to be either 0..3&O-QPSK or 4-7&MPSK 00059 {CHANNEL_PAGE_6, &phy_subghz_11_ch}, // this would need to be either 0..9&BPSK or 1-10&GFSK 00060 // just for testing fhss 00061 {CHANNEL_PAGE_9, &phy_2_4ghz_256_ch}, 00062 {CHANNEL_PAGE_10, &phy_2_4ghz_5_ch}, // 5 channels, just as in cmd_network.c 00063 {CHANNEL_PAGE_0, NULL} 00064 }; 00065 00066 static int8_t phy_rf_state_control(phy_interface_state_e new_state, uint8_t channel); 00067 static int8_t phy_rf_tx(uint8_t *data_ptr, uint16_t data_len, uint8_t tx_handle, data_protocol_e protocol); 00068 static int8_t phy_rf_address_write(phy_address_type_e address_type, uint8_t *address_ptr); 00069 static int8_t phy_rf_extension(phy_extension_type_e extension_type, uint8_t *data_ptr); 00070 00071 00072 static int8_t phy_rf_virtual_rx(const uint8_t *data_ptr, uint16_t data_len, int8_t driver_id) 00073 { 00074 if (rf_driver_id != driver_id || !data_ptr) { 00075 return -1; 00076 } 00077 00078 uint8_t data_type = *data_ptr++; 00079 00080 switch (data_type) { 00081 case NAP_DATA_PHY_RAW_INDICATION: { 00082 if (data_len < 4 || !device_driver.phy_rx_cb) { 00083 return -1; 00084 } 00085 int8_t dbm; 00086 uint8_t link_quality = *data_ptr++; 00087 dbm = *data_ptr++; 00088 return device_driver.phy_rx_cb(data_ptr, data_len - 3, link_quality, dbm, driver_id); 00089 } 00090 case NAP_DATA_PHY_RAW_RESPONSE: { 00091 if (data_len != 4 || !device_driver.phy_tx_done_cb) { 00092 return -1; 00093 } 00094 uint8_t tx_retry, cca_retry; 00095 phy_link_tx_status_e status; 00096 status = (phy_link_tx_status_e) * data_ptr++; 00097 cca_retry = *data_ptr++; 00098 tx_retry = *data_ptr; 00099 return device_driver.phy_tx_done_cb(driver_id, 1, status, cca_retry, tx_retry); 00100 } 00101 case NAP_CONFIG_INTERNAL: { 00102 if (!device_driver.virtual_config_rx_cb) { 00103 return -1; 00104 } 00105 return device_driver.virtual_config_rx_cb(driver_id, data_ptr, data_len - 1); 00106 } 00107 case NAP_MLME_CONFIRM: { 00108 if (!device_driver.virtual_confirmation_rx_cb) { 00109 return -1; 00110 } 00111 return device_driver.virtual_confirmation_rx_cb(driver_id, data_ptr, data_len - 1); 00112 } 00113 default: 00114 break; 00115 } 00116 return -1; 00117 } 00118 00119 /** 00120 * \brief This function is used by the network stack library to set the interface state: 00121 * 00122 * \param new_state An interface state: PHY_INTERFACE_RESET, PHY_INTERFACE_DOWN, 00123 * PHY_INTERFACE_UP or PHY_INTERFACE_RX_ENERGY_STATE. 00124 * 00125 * \param channel An RF channel that the command applies to. 00126 * 00127 * \return 0 State update is OK. 00128 * \return -1 An unsupported state or a general failure. 00129 */ 00130 int8_t phy_rf_state_control(phy_interface_state_e new_state, uint8_t channel) 00131 { 00132 (void)new_state; 00133 (void)channel; 00134 return 0; 00135 } 00136 00137 /** 00138 * \brief This function is used give driver data to transfer. 00139 * 00140 * \param data_ptr A pointer to TX data. The platform driver can use the same pointer, but the 00141 * network stack will free the memory when the device driver implementation 00142 * notifies the stack (using the unique tx_handle) that it is allowed to do so. 00143 * 00144 * \param data_len The length of data behind a pointer. 00145 * 00146 * \param tx_handle A unique TX handle defined by the network stack. 00147 * 00148 * \return 0 TX process start is OK. The library must wait for the TX Done callback 00149 * before pushing a new packet. 00150 * \return 1 TX process is OK at the Ethernet side (fast TX phase). 00151 * 00152 * \return -1 PHY is busy. 00153 * 00154 */ 00155 static int8_t phy_rf_tx(uint8_t *data_ptr, uint16_t data_len, uint8_t tx_handle, data_protocol_e protocol) 00156 { 00157 if (!data_ptr) { 00158 return -1; 00159 } 00160 virtual_data_req_t data_req; 00161 (void)protocol; 00162 (void)tx_handle; 00163 00164 //Push TO LMAC 00165 data_req.parameter_length = 0; 00166 data_req.parameters = NULL; 00167 00168 data_req.msdu = data_ptr; 00169 data_req.msduLength = data_len + 1; 00170 00171 //SET PHY Header and increment length 00172 *data_ptr = NAP_DATA_PHY_RAW_REQUEST; 00173 00174 //Push To LMAC 00175 if (!device_driver.arm_net_virtual_tx_cb) { 00176 tr_debug("Virtual Init not configured"); 00177 return -1; 00178 } 00179 return device_driver.arm_net_virtual_tx_cb(&data_req, rf_driver_id); 00180 00181 } 00182 00183 static void phy_rf_mlme_orserver_tx(const mlme_set_t *set_req) 00184 { 00185 switch (set_req->attr) { 00186 00187 case macBeaconPayload: 00188 case macLoadBalancingBeaconTx: 00189 break; 00190 default: 00191 return; 00192 00193 } 00194 00195 virtual_data_req_t data_req; 00196 uint8_t msg_aram[4]; 00197 uint8_t temp = 0; 00198 msg_aram[0] = NAP_MLME_REQUEST; 00199 msg_aram[1] = MLME_SET; 00200 msg_aram[2] = set_req->attr; 00201 msg_aram[3] = set_req->attr_index; 00202 //Push TO LMAC 00203 data_req.parameter_length = 4; 00204 data_req.parameters = msg_aram; 00205 if (set_req->value_pointer) { 00206 data_req.msdu = (uint8_t *) set_req->value_pointer; 00207 data_req.msduLength = set_req->value_size; 00208 } else { 00209 data_req.msdu = &temp; 00210 data_req.msduLength = 1; 00211 } 00212 00213 //Push To LMAC 00214 if (!device_driver.arm_net_virtual_tx_cb) { 00215 tr_debug("Virtual Init not configured"); 00216 return; 00217 } 00218 device_driver.arm_net_virtual_tx_cb(&data_req, rf_driver_id); 00219 00220 } 00221 00222 /** 00223 * \brief This is the default PHY interface address write API for all interface types. 00224 * 00225 * \param address_type Defines the PHY address type: PHY_MAC_64BIT, PHY_MAC_48BIT, 00226 * PHY_MAC_PANID or PHY_MAC_16BIT. 00227 * 00228 * \param address_ptr A pointer to an address. 00229 * 00230 * \return 0 Write is OK. 00231 * \return -1 PHY is busy. 00232 */ 00233 int8_t phy_rf_address_write(phy_address_type_e address_type, uint8_t *address_ptr) 00234 { 00235 if (address_ptr) { 00236 switch (address_type) { 00237 case PHY_MAC_64BIT: { 00238 memcpy(rf_mac_address, address_ptr, 8); 00239 break; 00240 } 00241 default: 00242 break; 00243 } 00244 } 00245 return 0; 00246 } 00247 00248 /** 00249 * \brief This is the default PHY interface address write API for all interface types. 00250 * 00251 * \param extension_type Supported extension types: PHY_EXTENSION_CTRL_PENDING_BIT, 00252 * PHY_EXTENSION_SET_CHANNEL, PHY_EXTENSION_READ_CHANNEL_ENERGY 00253 * or PHY_EXTENSION_READ_LINK_STATUS. 00254 * 00255 * \param data_ptr A pointer to an 8-bit data storage for read or write purpose, 00256 * based on the extension command types. 00257 * 00258 * \return 0 State update is OK. 00259 * \return -1 An unsupported state or a general failure. 00260 */ 00261 static int8_t phy_rf_extension(phy_extension_type_e extension_type, uint8_t *data_ptr) 00262 { 00263 if (data_ptr) { 00264 switch (extension_type) { 00265 /*Control MAC pending bit for Indirect data transmission*/ 00266 case PHY_EXTENSION_CTRL_PENDING_BIT: { 00267 data_request_pending_flag = *data_ptr; 00268 break; 00269 } 00270 /*Return frame pending status*/ 00271 case PHY_EXTENSION_READ_LAST_ACK_PENDING_STATUS: { 00272 *data_ptr = data_request_pending_flag; 00273 break; 00274 } 00275 default: 00276 break; 00277 } 00278 } 00279 00280 return 0; 00281 } 00282 00283 // XXX: the phy_channel_pages needs to match the config at cmd_network.c, or the RF init fails 00284 int8_t virtual_rf_device_register(phy_link_type_e link_type, uint16_t mtu_size) 00285 { 00286 if (rf_driver_id < 0) { 00287 memset(&device_driver, 0, sizeof(phy_device_driver_s)); 00288 /*Set pointer to MAC address*/ 00289 device_driver.PHY_MAC = rf_mac_address; 00290 device_driver.arm_net_virtual_rx_cb = &phy_rf_virtual_rx; 00291 device_driver.driver_description = "VSND"; 00292 00293 device_driver.link_type = link_type; 00294 00295 if (link_type == PHY_LINK_15_4_SUBGHZ_TYPE) { 00296 /*Type of RF PHY is SubGHz*/ 00297 phy_channel_pages[0].rf_channel_configuration = &phy_subghz; 00298 device_driver.phy_channel_pages = phy_channel_pages; 00299 } else if (link_type == PHY_LINK_15_4_2_4GHZ_TYPE) { 00300 /*Type of RF PHY is 2.4GHz*/ 00301 phy_channel_pages[0].rf_channel_configuration = &phy_2_4ghz; 00302 device_driver.phy_channel_pages = phy_channel_pages; 00303 } else { 00304 device_driver.phy_channel_pages = NULL; 00305 } 00306 00307 device_driver.phy_MTU = mtu_size; 00308 /*Set 1 byte header in PHY*/ 00309 device_driver.phy_header_length = 1; 00310 /* Register handler functions */ 00311 device_driver.state_control = &phy_rf_state_control; 00312 device_driver.tx = &phy_rf_tx; 00313 device_driver.address_write = phy_rf_address_write; 00314 device_driver.extension = &phy_rf_extension; 00315 00316 rf_driver_id = arm_net_phy_register(&device_driver); 00317 00318 arm_net_observer_cb_set(rf_driver_id, phy_rf_mlme_orserver_tx); 00319 } 00320 00321 return rf_driver_id; 00322 }
Generated on Tue Jul 12 2022 13:55:03 by
