Kenji Arai / mbed-os_TYBLE16

Dependents:   TYBLE16_simple_data_logger TYBLE16_MP3_Air

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers virtual_rf_driver.c Source File

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 }