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.
virtual_rf_driver.c
00001 /* 00002 * Copyright (c) 2016-2017, 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 = {2405000000, 5000000, 250000, 16, M_OQPSK}; 00042 static const phy_rf_channel_configuration_s phy_subghz = {868300000, 2000000, 250000, 11, M_OQPSK}; 00043 00044 static const phy_rf_channel_configuration_s phy_subghz_8_ch = {868300000, 2000000, 250000, 8, M_OQPSK}; 00045 static const phy_rf_channel_configuration_s phy_subghz_11_ch = {868300000, 2000000, 250000, 11, M_OQPSK}; 00046 static const phy_rf_channel_configuration_s phy_subghz_16_ch = {868300000, 2000000, 250000, 16, M_OQPSK}; 00047 static const phy_rf_channel_configuration_s phy_2_4ghz_14_ch = {2405000000, 1000000, 250000, 14, M_OQPSK}; 00048 static const phy_rf_channel_configuration_s phy_2_4ghz_5_ch = {2405000000, 1000000, 250000, 5, M_OQPSK}; //For FHSS testing only 00049 static const phy_rf_channel_configuration_s phy_2_4ghz_256_ch = {2405000000, 1000000, 250000, 256, 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 if (rf_driver_id != driver_id || !data_ptr) { 00074 return -1; 00075 } 00076 00077 uint8_t data_type = *data_ptr++; 00078 00079 switch (data_type) { 00080 case NAP_DATA_PHY_RAW_INDICATION: { 00081 if (data_len < 4 || !device_driver.phy_rx_cb ) { 00082 return -1; 00083 } 00084 int8_t dbm; 00085 uint8_t link_quality = *data_ptr++; 00086 dbm = *data_ptr++; 00087 return device_driver.phy_rx_cb(data_ptr, data_len - 3, link_quality, dbm, driver_id); 00088 } 00089 case NAP_DATA_PHY_RAW_RESPONSE: { 00090 if (data_len != 4 || !device_driver.phy_tx_done_cb ) { 00091 return -1; 00092 } 00093 uint8_t tx_retry, cca_retry; 00094 phy_link_tx_status_e status; 00095 status = (phy_link_tx_status_e)*data_ptr++; 00096 cca_retry = *data_ptr++; 00097 tx_retry = *data_ptr; 00098 return device_driver.phy_tx_done_cb(driver_id, 1,status, cca_retry, tx_retry); 00099 } 00100 case NAP_CONFIG_INTERNAL: { 00101 if (!device_driver.virtual_config_rx_cb) { 00102 return -1; 00103 } 00104 return device_driver.virtual_config_rx_cb(driver_id, data_ptr, data_len-1); 00105 } 00106 case NAP_MLME_CONFIRM: { 00107 if (!device_driver.virtual_confirmation_rx_cb) { 00108 return -1; 00109 } 00110 return device_driver.virtual_confirmation_rx_cb(driver_id, data_ptr, data_len-1); 00111 } 00112 default: 00113 break; 00114 } 00115 return -1; 00116 } 00117 00118 /** 00119 * \brief This function is used by the network stack library to set the interface state: 00120 * 00121 * \param new_state An interface state: PHY_INTERFACE_RESET, PHY_INTERFACE_DOWN, 00122 * PHY_INTERFACE_UP or PHY_INTERFACE_RX_ENERGY_STATE. 00123 * 00124 * \param channel An RF channel that the command applies to. 00125 * 00126 * \return 0 State update is OK. 00127 * \return -1 An unsupported state or a general failure. 00128 */ 00129 int8_t phy_rf_state_control(phy_interface_state_e new_state, uint8_t channel) 00130 { 00131 (void)new_state; 00132 (void)channel; 00133 return 0; 00134 } 00135 00136 /** 00137 * \brief This function is used give driver data to transfer. 00138 * 00139 * \param data_ptr A pointer to TX data. The platform driver can use the same pointer, but the 00140 * network stack will free the memory when the device driver implementation 00141 * notifies the stack (using the unique tx_handle) that it is allowed to do so. 00142 * 00143 * \param data_len The length of data behind a pointer. 00144 * 00145 * \param tx_handle A unique TX handle defined by the network stack. 00146 * 00147 * \return 0 TX process start is OK. The library must wait for the TX Done callback 00148 * before pushing a new packet. 00149 * \return 1 TX process is OK at the Ethernet side (fast TX phase). 00150 * 00151 * \return -1 PHY is busy. 00152 * 00153 */ 00154 static int8_t phy_rf_tx(uint8_t *data_ptr, uint16_t data_len, uint8_t tx_handle, data_protocol_e protocol) 00155 { 00156 if( !data_ptr ){ 00157 return -1; 00158 } 00159 virtual_data_req_t data_req; 00160 (void)protocol; 00161 (void)tx_handle; 00162 00163 //Push TO LMAC 00164 data_req.parameter_length = 0; 00165 data_req.parameters = NULL; 00166 00167 data_req.msdu = data_ptr; 00168 data_req.msduLength = data_len + 1; 00169 00170 //SET PHY Header and increment length 00171 *data_ptr = NAP_DATA_PHY_RAW_REQUEST; 00172 00173 //Push To LMAC 00174 if (!device_driver.arm_net_virtual_tx_cb) { 00175 tr_debug("Virtual Init not configured"); 00176 return -1; 00177 } 00178 return device_driver.arm_net_virtual_tx_cb(&data_req, rf_driver_id); 00179 00180 } 00181 00182 static void phy_rf_mlme_orserver_tx(const mlme_set_t *set_req) 00183 { 00184 switch (set_req->attr) { 00185 00186 case macBeaconPayload: 00187 case macLoadBalancingBeaconTx: 00188 break; 00189 default: 00190 return; 00191 00192 } 00193 00194 virtual_data_req_t data_req; 00195 uint8_t msg_aram[4]; 00196 uint8_t temp = 0; 00197 msg_aram[0] = NAP_MLME_REQUEST; 00198 msg_aram[1] = MLME_SET; 00199 msg_aram[2] = set_req->attr; 00200 msg_aram[3] = set_req->attr_index; 00201 //Push TO LMAC 00202 data_req.parameter_length = 4; 00203 data_req.parameters = msg_aram; 00204 if (set_req->value_pointer) { 00205 data_req.msdu = (uint8_t*) set_req->value_pointer; 00206 data_req.msduLength = set_req->value_size; 00207 } else { 00208 data_req.msdu = &temp; 00209 data_req.msduLength = 1; 00210 } 00211 00212 //Push To LMAC 00213 if (!device_driver.arm_net_virtual_tx_cb) { 00214 tr_debug("Virtual Init not configured"); 00215 return; 00216 } 00217 device_driver.arm_net_virtual_tx_cb(&data_req, rf_driver_id); 00218 00219 } 00220 00221 /** 00222 * \brief This is the default PHY interface address write API for all interface types. 00223 * 00224 * \param address_type Defines the PHY address type: PHY_MAC_64BIT, PHY_MAC_48BIT, 00225 * PHY_MAC_PANID or PHY_MAC_16BIT. 00226 * 00227 * \param address_ptr A pointer to an address. 00228 * 00229 * \return 0 Write is OK. 00230 * \return -1 PHY is busy. 00231 */ 00232 int8_t phy_rf_address_write(phy_address_type_e address_type,uint8_t *address_ptr) 00233 { 00234 if( address_ptr ){ 00235 switch(address_type) { 00236 case PHY_MAC_64BIT:{ 00237 memcpy(rf_mac_address, address_ptr, 8); 00238 break; 00239 } 00240 default: 00241 break; 00242 } 00243 } 00244 return 0; 00245 } 00246 00247 /** 00248 * \brief This is the default PHY interface address write API for all interface types. 00249 * 00250 * \param extension_type Supported extension types: PHY_EXTENSION_CTRL_PENDING_BIT, 00251 * PHY_EXTENSION_SET_CHANNEL, PHY_EXTENSION_READ_CHANNEL_ENERGY 00252 * or PHY_EXTENSION_READ_LINK_STATUS. 00253 * 00254 * \param data_ptr A pointer to an 8-bit data storage for read or write purpose, 00255 * based on the extension command types. 00256 * 00257 * \return 0 State update is OK. 00258 * \return -1 An unsupported state or a general failure. 00259 */ 00260 static int8_t phy_rf_extension(phy_extension_type_e extension_type, uint8_t *data_ptr) 00261 { 00262 if( data_ptr ){ 00263 switch (extension_type) 00264 { 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 18:18:55 by
