diff --git a/targets/ARCH/BLADERF/USERSPACE/LIB/bladerf_lib.c b/targets/ARCH/BLADERF/USERSPACE/LIB/bladerf_lib.c index d515a206ae8e0683ff5ba4529107fe6fbb0b6f5a..c9ca8fedc653962ba217db816904e23b837f127c 100644 --- a/targets/ARCH/BLADERF/USERSPACE/LIB/bladerf_lib.c +++ b/targets/ARCH/BLADERF/USERSPACE/LIB/bladerf_lib.c @@ -185,7 +185,7 @@ int trx_brf_set_gains(openair0_device* device) { } -int openair0_dev_init_bladerf(openair0_device *device, openair0_config_t *openair0_cfg) { +int device_init(openair0_device *device, openair0_config_t *openair0_cfg, char *cfgfile) { int status; int card=0; @@ -308,6 +308,7 @@ int openair0_dev_init_bladerf(openair0_device *device, openair0_config_t *openai printf("BLADERF: Initializing openair0_device\n"); device->priv = brf; device->Mod_id = num_devices++; + device->type = BLADERF_DEV; device->trx_start_func = trx_brf_start; device->trx_end_func = trx_brf_end; device->trx_read_func = trx_brf_read; @@ -317,6 +318,31 @@ int openair0_dev_init_bladerf(openair0_device *device, openair0_config_t *openai device->trx_stop_func = trx_brf_stop; device->trx_set_freq_func = trx_brf_set_freq; device->trx_set_gains_func = trx_brf_set_gains; + + if(brf->sample_rate==30.72e6) { + openair0_cfg->tx_delay = 8; + openair0_cfg->tx_forward_nsamps = 175; + brf->tx_forward_nsamps = 175; + } + if(brf->sample_rate==15.36e6) { + openair0_cfg->tx_delay = 5; + openair0_cfg->tx_forward_nsamps = 95; + brf->tx_forward_nsamps = 95; + } + if(brf->sample_rate==7.68e6) { + openair0_cfg->tx_delay = 8; + openair0_cfg->tx_forward_nsamps = 0; + brf->tx_forward_nsamps = 0; + } + if(brf->sample_rate==1.92e6) { + openair0_cfg->tx_delay = 8; + openair0_cfg->tx_forward_nsamps = 40; + brf->tx_forward_nsamps = 40; + } + + openair0_cfg->iq_txshift= 0; + openair0_cfg->iq_rxrescale = 15; + memcpy((void*)&device->openair0_cfg,(void*)openair0_cfg,sizeof(openair0_config_t)); return 0; diff --git a/targets/ARCH/COMMON/common_lib.c b/targets/ARCH/COMMON/common_lib.c index 8b91a74b4923ec5cc7d3f30c6dc87875a7c6d228..8fb07d7eb5a4f37ecca10a596a4b38c578002f18 100644 --- a/targets/ARCH/COMMON/common_lib.c +++ b/targets/ARCH/COMMON/common_lib.c @@ -37,28 +37,150 @@ * \warning */ #include <stdio.h> +#include <strings.h> +#include <dlfcn.h> +#include <errno.h> +#include <string.h> + #include "common_lib.h" +/* + FT: The device interface is implemented in a shared library, the softmodem knows which kind + of harware is used by parsing the device name returned when calling the trx_getinfo_func function + provided by this shared library +*/ +int set_device(openair0_device *device) { + + switch (device->type) { + + case EXMIMO_DEV: + printf("[%s] has loaded EXPRESS MIMO device.\n",((device->host_type == BBU_HOST) ? "BBU": "RRH")); + return 0; + break; + case USRP_DEV: + printf("[%s] has loaded USRP device.\n",((device->host_type == BBU_HOST) ? "BBU": "RRH")); + return 0; + break; + case BLADERF_DEV: + printf("[%s] has loaded BLADERF device.\n",((device->host_type == BBU_HOST) ? "BBU": "RRH")); + return 0; + break; + case NONE_DEV: + printf("[%s] has not loaded a HW device.\n",((device->host_type == BBU_HOST) ? "BBU": "RRH")); + return 0; + break; + default: + printf("[%s] invalid HW device.\n",((device->host_type == BBU_HOST) ? "BBU": "RRH")); + return -1; + break; + } + +} + +int set_transport(openair0_device *device) { + + switch (device->transp_type) { + + case ETHERNET_TP: + printf("[%s] has loaded ETHERNET trasport protocol.\n",((device->host_type == BBU_HOST) ? "BBU": "RRH")); + return 0; + break; + case NONE_TP: + printf("[%s] has not loaded a transport protocol.\n",((device->host_type == BBU_HOST) ? "BBU": "RRH")); + return 0; + break; + default: + printf("[%s] invalid transport protocol.\n",((device->host_type == BBU_HOST) ? "BBU": "RRH")); + return -1; + break; + } + +} + +/* FT: looking for the rh interface library and load it */ +int load_lib(openair0_device *device, openair0_config_t *openair0_cfg, char *cfgfile, uint8_t flag) { + + void *lib_handle; + char *OAI_RF_LIBNAME; + char *OAI_TP_LIBNAME; + oai_device_initfunc_t fp ; + + if (device->host_type==BBU_HOST) { + OAI_RF_LIBNAME= "/home/guepe/openairinterface5g/cmake_targets/lte_noS1_build_oai/build/liboai_device.so"; + OAI_TP_LIBNAME= "/home/guepe/openairinterface5g/cmake_targets/lte_noS1_build_oai/build/liboai_transpro.so"; + } else { + OAI_RF_LIBNAME= "liboai_device.so"; + OAI_TP_LIBNAME= "liboai_transpro.so"; + } + + if (flag == RF_DEVICE) { + lib_handle = dlopen(OAI_RF_LIBNAME, RTLD_LAZY); + if (!lib_handle) { + printf( "Unable to locate %s: HW device set to NONE_DEV.\n", OAI_RF_LIBNAME); + return 0; + } + + fp = dlsym(lib_handle,"device_init"); + + if (fp != NULL ) { + fp(device,openair0_cfg,cfgfile); + } else { + fprintf(stderr, "%s %d:oai device intializing function not found %s\n", __FILE__, __LINE__, dlerror()); + return -1; + } + } else { + lib_handle = dlopen(OAI_TP_LIBNAME, RTLD_LAZY); + if (!lib_handle) { + printf( "Unable to locate %s: transport protocol set to NONE_TP.\n", OAI_TP_LIBNAME); + return 0; + } + + fp = dlsym(lib_handle,"transport_init"); + + if (fp != NULL ) { + fp(device,openair0_cfg,cfgfile); + } else { + fprintf(stderr, "%s %d:oai device intializing function not found %s\n", __FILE__, __LINE__, dlerror()); + return -1; + } + } + + return 0; +} + + + +int openair0_device_load(openair0_device *device, openair0_config_t *openair0_cfg) { + + int rc; + static char *cfgfile; + uint8_t flag=RF_DEVICE; + /* FT: rewritten for shared library, common, radio head interface implementation */ + rc=load_lib(device, openair0_cfg, NULL,flag); + if ( rc >= 0) { + if ( set_device(device) < 0) { + fprintf(stderr, "%s %d:Unsupported radio head\n",__FILE__, __LINE__); + return -1; + } + } + + return 0; +} + +int openair0_transport_load(openair0_device *device, openair0_config_t *openair0_cfg) { + + int rc; + static char *cfgfile; + uint8_t flag=TRANSPORT_PROTOCOL; -int openair0_device_init(openair0_device *device, openair0_config_t *openair0_cfg) { + /* FT: rewritten for shared library, common, radio head interface implementation */ + rc=load_lib(device, openair0_cfg, NULL,flag); + if ( rc >= 0) { + if ( set_transport(device) < 0) { + fprintf(stderr, "%s %d:Unsupported radio head\n",__FILE__, __LINE__); + return -1; + } + } -#ifdef ETHERNET - device->type=ETH_IF; - device->func_type = BBU_FUNC; - openair0_dev_init_eth(device, openair0_cfg); - printf(" openair0_dev_init_eth ...\n"); -#elif EXMIMO - device->type=EXMIMO_IF; - openair0_dev_init_exmimo(device, openair0_cfg); - printf("openair0_dev_init_exmimo...\n"); -#elif OAI_USRP - device->type=USRP_IF; - openair0_dev_init_usrp(device, openair0_cfg); - printf("openair0_dev_init_usrp ...\n"); -#elif OAI_BLADERF - device->type=BLADERF_IF; - openair0_dev_init_bladerf(device, openair0_cfg); - printf(" openair0_dev_init_bladerf ...\n"); -#endif - + return 0; } diff --git a/targets/ARCH/COMMON/common_lib.h b/targets/ARCH/COMMON/common_lib.h index 8cc7926d4571158f210eb976dd3df102f4d2a510..0b4825714b273d58bd10f0a8b3c50cdf0ac64ae3 100644 --- a/targets/ARCH/COMMON/common_lib.h +++ b/targets/ARCH/COMMON/common_lib.h @@ -42,6 +42,22 @@ #include <stdint.h> #include <sys/types.h> +/* name of shared library implementing the radio front end */ +#define OAI_RF_LIBNAME "liboai_device.so" +/* name of shared library implementing the transport */ +#define OAI_TP_LIBNAME "liboai_transpro.so" + +/* flags for BBU to determine whether RF front end is local or remote +Note: currently lte-softmodem supports either a local RF device or a remote. */ +#define BBU_LOCAL_RF_ENABLED 1 +#define BBU_REMOTE_RF_ENABLED 2 +#define BBU_LOCAL_REMOTE_RF_ENABLED 3 +/*flags for load_lib() used to specify whether a RF device or a transport protocol library is loaded */ +#define TRANSPORT_PROTOCOL 1 +#define RF_DEVICE 2 + + + typedef int64_t openair0_timestamp; typedef volatile int64_t openair0_vtimestamp; @@ -75,7 +91,7 @@ typedef struct { //! Module ID for this configuration int Mod_id; // device log level - int log_level; + unsigned int log_level; //! number of downlink resource blocks int num_rb_dl; //! number of samples per frame @@ -83,12 +99,15 @@ typedef struct { //! the sample rate for both transmit and receive. double sample_rate; //! number of samples per RX/TX packet (USRP + Ethernet) - int samples_per_packet; + unsigned int samples_per_packet; // delay in sending samples (write) due to hardware access, softmodem processing and fronthaul delay if exist int tx_delay; //! adjust the position of the samples after delay when sending unsigned int tx_forward_nsamps; - //! number of RX channels (=RX antennas) + //! configurable tx thread lauch delay + int txlaunch_wait; /* 1 or 0 */ + int txlaunch_wait_slotcount; + //! number of RX channels (=RX antennas) int rx_num_channels; //! number of TX channels (=TX antennas) int tx_num_channels; @@ -114,14 +133,18 @@ typedef struct { double tx_bw; //! Auto calibration flag int autocal[4]; - //! RRH IP addr for Ethernet interface - char *remote_ip; - //! RRH port number for Ethernet interface - int remote_port; - //! my IP addr for Ethernet interface (eNB/BBU, UE) - char *my_ip; - //! my port number for Ethernet interface (eNB/BBU, UE) - int my_port; + //! rf devices work with x bits iqs when oai have its own iq format + //! the two following parameters are used to convert iqs + int iq_txshift; + int iq_rxrescale; + //! remote IP/MAC addr for Ethernet interface + char *remote_addr; + //! remote port number for Ethernet interface + unsigned int remote_port; + //! local IP/MAC addr for Ethernet interface (eNB/BBU, UE) + char *my_addr; + //! local port number for Ethernet interface (eNB/BBU, UE) + unsigned int my_port; } openair0_config_t; @@ -134,55 +157,63 @@ typedef struct { -/*!\brief interface types that apply to modules (RRH_BBU/RRH_UE) created in RRH (rrh_gw.c) - and are defined with respect to the RF device that is present in RRH - -RRH_BBU modules have two devices, one is by default ETHERNET (will have ETH_IF) and the other one is a - RF device (EXMIMO,USRP,BLADERF) or no device (NONE_IF). - -RRH_UE modules have two devices one is by default ETHERNET (will have ETH_IF) - and the other one by default not present so it will have NONE_IF +/*!\brief RF device types */ typedef enum { - MIN_DEV_TYPE = 0, - /*!\brief device is ETH */ - ETH_IF, + MIN_RF_DEV_TYPE = 0, /*!\brief device is ExpressMIMO */ - EXMIMO_IF, + EXMIMO_DEV, /*!\brief device is USRP*/ - USRP_IF, + USRP_DEV, /*!\brief device is BLADE RF*/ - BLADERF_IF, + BLADERF_DEV, /*!\brief device is NONE*/ - NONE_IF, - MAX_DEV_TYPE + NONE_DEV, + MAX_RF_DEV_TYPE } dev_type_t; +/*!\brief transport protocol types + */ +typedef enum { + MIN_TRANSP_TYPE = 0, + /*!\brief transport protocol ETHERNET */ + ETHERNET_TP, + /*!\brief no transport protocol*/ + NONE_TP, + MAX_TRANSP_TYPE + +} transport_type_t; + /*!\brief openair0 device host type */ typedef enum { - MIN_FUNC_TYPE = 0, + MIN_HOST_TYPE = 0, /*!\brief device functions within a BBU */ - BBU_FUNC, + BBU_HOST, /*!\brief device functions within a RRH */ - RRH_FUNC, - MAX_FUNC_TYPE + RRH_HOST, + MAX_HOST_TYPE -}func_type_t; +}host_type_t; struct openair0_device_t { - /* Module ID of this device */ + /*!brief Module ID of this device */ int Mod_id; - /* Type of this device */ + /*!brief Type of this device */ dev_type_t type; - /* Type of the device's host (BBU/RRH) */ - func_type_t func_type; + /*!brief Transport protocol type that the device suppports (in case I/Q samples need to be transported) */ + transport_type_t transp_type; + + /*!brief Type of the device's host (BBU/RRH) */ + host_type_t host_type; - /* RF frontend parameters set by application */ + /*!brief RF frontend parameters set by application */ openair0_config_t openair0_cfg; - /* Can be used by driver to hold internal structure*/ + /*!brief Can be used by driver to hold internal structure*/ void *priv; /* Functions API, which are called by the application*/ @@ -263,28 +294,25 @@ struct openair0_device_t { }; +/* type of device init function, implemented in shared lib */ +typedef int(*oai_device_initfunc_t)(openair0_device *device, openair0_config_t *openair0_cfg, char *cfgfile); #ifdef __cplusplus extern "C" { #endif -/*! \brief Initialize Openair RF target. It returns 0 if OK */ - int openair0_device_init(openair0_device* device, openair0_config_t *openair0_cfg); + /*! \brief Initialize openair RF target. It returns 0 if OK */ + int openair0_device_load(openair0_device *device, openair0_config_t *openair0_cfg); + /*! \brief Initialize transport protocol . It returns 0 if OK */ + int openair0_transport_load(openair0_device *device, openair0_config_t *openair0_cfg); //USRP /*! \brief Get the current timestamp of USRP */ openair0_timestamp get_usrp_time(openair0_device *device); /*! \brief Set the RX frequency of USRP RF TARGET */ int openair0_set_rx_frequencies(openair0_device* device, openair0_config_t *openair0_cfg); - -//extern -/*! \brief Initialize Openair ETHERNET target. It returns 0 if OK */ - int openair0_dev_init_eth(openair0_device *device, openair0_config_t *openair0_cfg); - int openair0_dev_init_bladerf(openair0_device *device, openair0_config_t *openair0_cfg); - int openair0_dev_init_usrp(openair0_device* device, openair0_config_t *openair0_cfg); - int openair0_dev_init_exmimo(openair0_device *device, openair0_config_t *openair0_cfg); -/*@}*/ + #ifdef __cplusplus } diff --git a/targets/ARCH/EXMIMO/USERSPACE/LIB/openair0_lib.c b/targets/ARCH/EXMIMO/USERSPACE/LIB/openair0_lib.c index df9900d3bc98720090143b73c2989a30ad0868ea..05105d60df1c01ea9b39fc52a530ebf171fcc9a0 100644 --- a/targets/ARCH/EXMIMO/USERSPACE/LIB/openair0_lib.c +++ b/targets/ARCH/EXMIMO/USERSPACE/LIB/openair0_lib.c @@ -247,7 +247,7 @@ int openair0_stop_without_reset(int card) #define MY_RF_MODE (RXEN + TXEN + TXLPFNORM + TXLPFEN + TXLPF25 + RXLPFNORM + RXLPFEN + RXLPF25 + LNA1ON +LNAMax + RFBBNORM + DMAMODE_RX + DMAMODE_TX) #define RF_MODE_BASE (LNA1ON + RFBBNORM) -int openair0_dev_init_exmimo(openair0_device *device, openair0_config_t *openair0_cfg) { +int device_init(openair0_device *device, openair0_config_t *openair0_cfg, char *cfgfile) { // Initialize card // exmimo_config_t *p_exmimo_config; @@ -287,6 +287,8 @@ int openair0_dev_init_exmimo(openair0_device *device, openair0_config_t *openair return(-1); } + device->type = EXMIMO_DEV; + return(0); } diff --git a/targets/ARCH/USRP/USERSPACE/LIB/usrp_lib.cpp b/targets/ARCH/USRP/USERSPACE/LIB/usrp_lib.cpp index e57f55720b14fbb7605fc41e6ab091a61cc7755d..00a0a93116d008603ade4fcec99eabbd7f40a254 100644 --- a/targets/ARCH/USRP/USERSPACE/LIB/usrp_lib.cpp +++ b/targets/ARCH/USRP/USERSPACE/LIB/usrp_lib.cpp @@ -329,8 +329,9 @@ int trx_usrp_reset_stats(openair0_device* device) { } -int openair0_dev_init_usrp(openair0_device* device, openair0_config_t *openair0_cfg) -{ +extern "C" { + int device_init(openair0_device* device, openair0_config_t *openair0_cfg, char *cfgfile) { + uhd::set_thread_priority_safe(1.0); usrp_state_t *s = (usrp_state_t*)malloc(sizeof(usrp_state_t)); memset(s, 0, sizeof(usrp_state_t)); @@ -364,7 +365,7 @@ int openair0_dev_init_usrp(openair0_device* device, openair0_config_t *openair0_ } - printf("Found USRP X300\n"); + printf("Found USRP X300\n"); s->usrp = uhd::usrp::multi_usrp::make(args); // s->usrp->set_rx_subdev_spec(rx_subdev); // s->usrp->set_tx_subdev_spec(tx_subdev); @@ -475,6 +476,7 @@ int openair0_dev_init_usrp(openair0_device* device, openair0_config_t *openair0_ std::cout << boost::format("Device timestamp: %f...") % (s->usrp->get_time_now().get_real_secs()) << std::endl; device->priv = s; + device->type = USRP_DEV; device->trx_start_func = trx_usrp_start; device->trx_write_func = trx_usrp_write; device->trx_read_func = trx_usrp_read; @@ -488,11 +490,37 @@ int openair0_dev_init_usrp(openair0_device* device, openair0_config_t *openair0_ s->sample_rate = openair0_cfg[0].sample_rate; // TODO: // init tx_forward_nsamps based usrp_time_offset ex - if(is_equal(s->sample_rate, (double)30.72e6)) + /*if(is_equal(s->sample_rate, (double)30.72e6)) s->tx_forward_nsamps = 176; if(is_equal(s->sample_rate, (double)15.36e6)) s->tx_forward_nsamps = 90; if(is_equal(s->sample_rate, (double)7.68e6)) - s->tx_forward_nsamps = 50; + s->tx_forward_nsamps = 50;*/ +/* move device specific parameters from lte-softmodem.c here */ + if(is_equal(s->sample_rate, (double)30.72e6)) { + openair0_cfg->tx_delay = 8; + s->tx_forward_nsamps = 175; + openair0_cfg->tx_forward_nsamps = 175; + } + if(is_equal(s->sample_rate, (double)15.36e6)) { + openair0_cfg->tx_delay = 5; + s->tx_forward_nsamps = 95; + openair0_cfg->tx_forward_nsamps = 95; + } + if(is_equal(s->sample_rate, (double)7.68e6)) { + openair0_cfg->tx_delay = 5; + s->tx_forward_nsamps = 70; + openair0_cfg->tx_forward_nsamps = 70; + } + if(is_equal(s->sample_rate, (double)1.92e6)) { + openair0_cfg->tx_delay = 8; + s->tx_forward_nsamps = 40; + openair0_cfg->tx_forward_nsamps = 40; + } + openair0_cfg->iq_txshift= 5; + openair0_cfg->iq_rxrescale = 15; + printf("check params %d:%d",openair0_cfg->tx_forward_nsamps, openair0_cfg->tx_delay); + return 0; } +} \ No newline at end of file