diff --git a/openair1/PHY/LTE_TRANSPORT/initial_sync.c b/openair1/PHY/LTE_TRANSPORT/initial_sync.c index bc2a00d8e6c16f587d3af3634a6d375cb3258bb3..5c6b479b2003c6a8ca40938bd0e4be7fe9e0f5b0 100644 --- a/openair1/PHY/LTE_TRANSPORT/initial_sync.c +++ b/openair1/PHY/LTE_TRANSPORT/initial_sync.c @@ -336,7 +336,9 @@ int initial_sync(PHY_VARS_UE *phy_vars_ue, runmode_t mode) #else #ifndef OAI_USRP + #ifndef OAI_BLADERF phy_adjust_gain(phy_vars_ue,0); + #endif #endif #endif diff --git a/openair1/PHY/LTE_TRANSPORT/print_stats.c b/openair1/PHY/LTE_TRANSPORT/print_stats.c index 68b18d35b44fc77901b56d6fd7b9d86f5cac20f4..345982505850f2885a4ba27f51776b7cd58fb0e8 100644 --- a/openair1/PHY/LTE_TRANSPORT/print_stats.c +++ b/openair1/PHY/LTE_TRANSPORT/print_stats.c @@ -50,7 +50,7 @@ #endif extern int mac_get_rrc_status(uint8_t Mod_id,uint8_t eNB_flag,uint8_t index); -#if defined(OAI_USRP) || defined(EXMIMO) +#if defined(OAI_USRP) || defined(EXMIMO) || defined(OAI_BLADERF) #include "common_lib.h" extern openair0_config_t openair0_cfg[]; #endif @@ -97,10 +97,10 @@ int dump_ue_stats(PHY_VARS_UE *phy_vars_ue, char* buffer, int length, runmode_t #ifdef EXMIMO len += sprintf(&buffer[len], "[UE PROC] RX Gain %d dB (LNA %d, vga %d dB)\n",phy_vars_ue->rx_total_gain_dB, openair0_cfg[0].rxg_mode[0],(int)openair0_cfg[0].rx_gain[0]); #endif -#ifdef OAI_USRP +#if defined(OAI_USRP) || defined(OAI_BLADERF) len += sprintf(&buffer[len], "[UE PROC] RX Gain %d dB\n",phy_vars_ue->rx_total_gain_dB); #endif -#if defined(EXMIMO) || defined(OAI_USRP) +#if defined(EXMIMO) || defined(OAI_USRP) || defined(OAI_BLADERF) len += sprintf(&buffer[len], "[UE_PROC] Frequency offset %d Hz (%d), estimated carrier frequency %f Hz\n",phy_vars_ue->lte_ue_common_vars.freq_offset,openair_daq_vars.freq_offset,openair0_cfg[0].rx_freq[0]-phy_vars_ue->lte_ue_common_vars.freq_offset); #endif len += sprintf(&buffer[len], "[UE PROC] UE mode = %s (%d)\n",mode_string[phy_vars_ue->UE_mode[0]],phy_vars_ue->UE_mode[0]); diff --git a/openair1/PHY/TOOLS/signal_energy.c b/openair1/PHY/TOOLS/signal_energy.c index 323a1831dc17cbf1f72fc7df9004fb83a2127113..373fdc0d90acbe35cd3095ee51c25d099e87d780 100755 --- a/openair1/PHY/TOOLS/signal_energy.c +++ b/openair1/PHY/TOOLS/signal_energy.c @@ -197,7 +197,7 @@ int32_t signal_energy(int32_t *input,uint32_t length) for (i=0; i<length>>1; i++) { tmpE = vqaddq_s32(tmpE,vshrq_n_s32(vmull_s16(*in,*in),shift)); - tmpDC = vaddw_s16(tmpDC,vshr_n_s16(*in++,shift_DC)); + //tmpDC = vaddw_s16(tmpDC,vshr_n_s16(*in++,shift_DC)); } diff --git a/openair1/SCHED/phy_procedures_lte_ue.c b/openair1/SCHED/phy_procedures_lte_ue.c index ba79cdfcc6d56ca62607db2158ed1f222e27cfc9..42a42e16b32ce4d6cc843e5c3b94be1ebddee18b 100755 --- a/openair1/SCHED/phy_procedures_lte_ue.c +++ b/openair1/SCHED/phy_procedures_lte_ue.c @@ -1553,7 +1553,9 @@ void lte_ue_measurement_procedures(uint16_t l, PHY_VARS_UE *phy_vars_ue,uint8_t #else #ifndef OAI_USRP + #ifndef OAI_BLADERF phy_adjust_gain (phy_vars_ue,0); + #endif #endif #endif VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_GAIN_CONTROL, VCD_FUNCTION_OUT); diff --git a/targets/ARCH/BLADERF/USERSPACE/LIB/bladerf_lib.c b/targets/ARCH/BLADERF/USERSPACE/LIB/bladerf_lib.c index d515a206ae8e0683ff5ba4529107fe6fbb0b6f5a..c7f2ee7b5e8d8c83a7b74ddbbca02b2ab7a6e116 100644 --- a/targets/ARCH/BLADERF/USERSPACE/LIB/bladerf_lib.c +++ b/targets/ARCH/BLADERF/USERSPACE/LIB/bladerf_lib.c @@ -38,6 +38,14 @@ #include <inttypes.h> #include "bladerf_lib.h" +#ifdef __SSE4_1__ +# include <smmintrin.h> +#endif + +#ifdef __AVX2__ +# include <immintrin.h> +#endif + int num_devices=0; /*These items configure the underlying asynch stream used by the the sync interface. */ @@ -47,16 +55,17 @@ int trx_brf_init(openair0_device *openair0) { } -openair0_timestamp trx_get_timestamp(openair0_device *device) { +openair0_timestamp trx_get_timestamp(openair0_device *device, bladerf_module module) { int status; struct bladerf_metadata meta; brf_state_t *brf = (brf_state_t*)device->priv; + memset(&meta, 0, sizeof(meta)); - if ((status=bladerf_get_timestamp(brf->dev, BLADERF_MODULE_TX, &meta.timestamp)) != 0) { - fprintf(stderr,"Failed to get current RX timestamp: %s\n",bladerf_strerror(status)); - } else { - printf("Current TX timestampe 0x%016"PRIx64"\n", meta.timestamp); - } + if ((status=bladerf_get_timestamp(brf->dev, module, &meta.timestamp)) != 0) { + fprintf(stderr,"Failed to get current %s timestamp: %s\n",(module == BLADERF_MODULE_RX ) ? "RX" : "TX", bladerf_strerror(status)); + return -1; + } // else {printf("Current RX timestampe 0x%016"PRIx64"\n", meta.timestamp); } + return meta.timestamp; } @@ -73,22 +82,26 @@ static void trx_brf_stats(openair0_device *device){ static int trx_brf_write(openair0_device *device,openair0_timestamp ptimestamp, void **buff, int nsamps, int cc) { - int status, i; + int status; brf_state_t *brf = (brf_state_t*)device->priv; /* BRF has only 1 rx/tx chaine : is it correct? */ - void *samples = (void*)buff[0]; + int16_t *samples = (int16_t*)buff[0]; - //brf->meta_tx.flags &= ~BLADERF_META_FLAG_TX_NOW; - brf->meta_tx.flags = BLADERF_META_FLAG_TX_BURST_START | - BLADERF_META_FLAG_TX_NOW | - BLADERF_META_FLAG_TX_BURST_END; - - brf->meta_tx.timestamp= (uint64_t) ptimestamp; - + //memset(&brf->meta_tx, 0, sizeof(brf->meta_tx)); + // When BLADERF_META_FLAG_TX_NOW is used the timestamp is not used, so one can't schedule a tx + if (brf->meta_tx.flags == 0 ) + brf->meta_tx.flags = (BLADERF_META_FLAG_TX_BURST_START);// | BLADERF_META_FLAG_TX_BURST_END);// | BLADERF_META_FLAG_TX_NOW); + + + brf->meta_tx.timestamp= (uint64_t) (ptimestamp); status = bladerf_sync_tx(brf->dev, samples, (unsigned int) nsamps, &brf->meta_tx, 2*brf->tx_timeout_ms); + + if (brf->meta_tx.flags == BLADERF_META_FLAG_TX_BURST_START) + brf->meta_tx.flags = BLADERF_META_FLAG_TX_UPDATE_TIMESTAMP; + if (status != 0) { - fprintf(stderr,"Failed to TX sample: %s\n", bladerf_strerror(status)); + //fprintf(stderr,"Failed to TX sample: %s\n", bladerf_strerror(status)); brf->num_tx_errors++; brf_error(status); } else if (brf->meta_tx.status & BLADERF_META_STATUS_UNDERRUN){ @@ -96,6 +109,8 @@ static int trx_brf_write(openair0_device *device,openair0_timestamp ptimestamp, fprintf(stderr, "TX Underrun detected. %u valid samples were read.\n", brf->meta_tx.actual_count); brf->num_underflows++; } + //printf("Provided TX timestampe %u, meta timestame %u\n", ptimestamp,brf->meta_tx.timestamp); + // printf("tx status %d \n",brf->meta_tx.status); brf->tx_current_ts=brf->meta_tx.timestamp; brf->tx_actual_nsamps+=brf->meta_tx.actual_count; @@ -107,26 +122,28 @@ static int trx_brf_write(openair0_device *device,openair0_timestamp ptimestamp, } static int trx_brf_read(openair0_device *device, openair0_timestamp *ptimestamp, void **buff, int nsamps, int cc) { - int status, ret; - - unsigned int i; + + int status=0; brf_state_t *brf = (brf_state_t*)device->priv; // BRF has only one rx/tx chain - void *samples = (void*)buff[0]; - - brf->meta_rx.flags |= BLADERF_META_FLAG_RX_NOW; + int16_t *samples = (int16_t*)buff[0]; + + brf->meta_rx.flags = BLADERF_META_FLAG_RX_NOW; status = bladerf_sync_rx(brf->dev, samples, (unsigned int) nsamps, &brf->meta_rx, 2*brf->rx_timeout_ms); + // printf("Current RX timestampe %u, nsamps %u, actual %u, cc %d\n", brf->meta_rx.timestamp, nsamps, brf->meta_rx.actual_count, cc); + if (status != 0) { fprintf(stderr, "RX failed: %s\n", bladerf_strerror(status)); + // printf("RX failed: %s\n", bladerf_strerror(status)); brf->num_rx_errors++; } else if ( brf->meta_rx.status & BLADERF_META_STATUS_OVERRUN) { brf->num_overflows++; - fprintf(stderr, "RX overrun (%d) is detected. t=0x%"PRIu64". Got %u samples. nsymps %d\n", - brf->num_overflows,brf->meta_rx.timestamp, brf->meta_rx.actual_count, nsamps); - //brf->meta_rx.timestamp=(unsigned int)(nsamps-brf->meta_rx.actual_count); - } + printf("RX overrun (%d) is detected. t=%u. Got %u samples. nsymps %d\n", + brf->num_overflows,brf->meta_rx.timestamp, brf->meta_rx.actual_count, nsamps); + } + //printf("Current RX timestampe %u\n", brf->meta_rx.timestamp); //printf("[BRF] (buff %p) ts=0x%"PRIu64" %s\n",samples, brf->meta_rx.timestamp,bladerf_strerror(status)); brf->rx_current_ts=brf->meta_rx.timestamp; brf->rx_actual_nsamps+=brf->meta_rx.actual_count; @@ -135,7 +152,7 @@ static int trx_brf_read(openair0_device *device, openair0_timestamp *ptimestamp, *ptimestamp = brf->meta_rx.timestamp; - + return brf->meta_rx.actual_count; } @@ -176,6 +193,23 @@ int trx_brf_stop(openair0_device* device) { int trx_brf_set_freq(openair0_device* device) { + int status; + brf_state_t *brf = (brf_state_t *)device->priv; + openair0_config_t *openair0_cfg = (openair0_config_t *)device->openair0_cfg; + + + if ((status=bladerf_set_frequency(brf->dev, BLADERF_MODULE_TX, (unsigned int) openair0_cfg->tx_freq[0])) != 0){ + fprintf(stderr,"Failed to set TX frequency: %s\n",bladerf_strerror(status)); + brf_error(status); + }else + printf("[BRF] set TX Frequency to %u\n", (unsigned int) openair0_cfg->tx_freq[0]); + + if ((status=bladerf_set_frequency(brf->dev, BLADERF_MODULE_RX, (unsigned int) openair0_cfg->rx_freq[0])) != 0){ + fprintf(stderr,"Failed to set RX frequency: %s\n",bladerf_strerror(status)); + brf_error(status); + } else + printf("[BRF] set RX frequency to %u\n",(unsigned int)openair0_cfg->rx_freq[0]); + return(0); } @@ -185,6 +219,609 @@ int trx_brf_set_gains(openair0_device* device) { } +#define RXDCLENGTH 16384 +int16_t cos_fsover8[8] = {2047, 1447, 0, -1448, -2047, -1448, 0, 1447}; +int16_t cos_3fsover8[8] = {2047, -1448, 0, 1447, -2047, 1447, 0, -1448}; + +rx_gain_calib_table_t calib_table_fx4[] = { + {2300000000.0,53.5}, + {1880000000.0,57.0}, + {816000000.0,73.0}, + {-1,0}}; + +void set_rx_gain_offset(openair0_config_t *openair0_cfg, int chain_index) { + + int i=0; + // loop through calibration table to find best adjustment factor for RX frequency + double min_diff = 6e9,diff; + + while (openair0_cfg->rx_gain_calib_table[i].freq>0) { + diff = fabs(openair0_cfg->rx_freq[chain_index] - openair0_cfg->rx_gain_calib_table[i].freq); + printf("cal %d: freq %f, offset %f, diff %f\n", + i, + openair0_cfg->rx_gain_calib_table[i].freq, + openair0_cfg->rx_gain_calib_table[i].offset,diff); + if (min_diff > diff) { + min_diff = diff; + openair0_cfg->rx_gain_offset[chain_index] = openair0_cfg->rx_gain_calib_table[i].offset; + } + i++; + } + +} + +void calibrate_rf(openair0_device *device) { + + + brf_state_t *brf = (brf_state_t *)device->priv; + openair0_timestamp ptimestamp; + int16_t *calib_buffp,*calib_tx_buffp; + int16_t calib_buff[2*RXDCLENGTH]; + int16_t calib_tx_buff[2*RXDCLENGTH]; + int i,j,offI,offQ,offIold,offQold,offInew,offQnew,offphase,offphaseold,offphasenew,offgain,offgainold,offgainnew; + int32_t meanI,meanQ,meanIold,meanQold; + int cnt=0,loop; + + // put TX on a far-away frequency to avoid interference in RX band + bladerf_set_frequency(brf->dev,BLADERF_MODULE_TX, (unsigned int) device->openair0_cfg->rx_freq[0] + 200e6); + // Set gains to close to max + bladerf_set_gain(brf->dev, BLADERF_MODULE_RX, 60); + bladerf_set_gain(brf->dev, BLADERF_MODULE_TX, 60); + + // fill TX buffer with fs/8 complex sinusoid + j=0; + for (i=0;i<RXDCLENGTH;i++) { + calib_tx_buff[j++] = cos_fsover8[i&7]; + calib_tx_buff[j++] = cos_fsover8[(i+6)&7]; // sin + } + calib_buffp = &calib_buff[0]; + calib_tx_buffp = &calib_tx_buff[0]; + // Calibrate RX DC offset + + offIold=offQold=2048; + bladerf_set_correction(brf->dev,BLADERF_MODULE_RX,BLADERF_CORR_LMS_DCOFF_I,offIold); + bladerf_set_correction(brf->dev,BLADERF_MODULE_RX,BLADERF_CORR_LMS_DCOFF_Q,offQold); + for (i=0;i<10;i++) + trx_brf_read(device, &ptimestamp, (void **)&calib_buffp, RXDCLENGTH, 0); + + for (meanIold=meanQold=i=j=0;i<RXDCLENGTH;i++) { + meanIold+=calib_buff[j++]; + meanQold+=calib_buff[j++]; + } + meanIold/=RXDCLENGTH; + meanQold/=RXDCLENGTH; + printf("[BRF] RX DC: (%d,%d) => (%d,%d)\n",offIold,offQold,meanIold,meanQold); + + offI=offQ=-2048; + bladerf_set_correction(brf->dev,BLADERF_MODULE_RX,BLADERF_CORR_LMS_DCOFF_I,offI); + bladerf_set_correction(brf->dev,BLADERF_MODULE_RX,BLADERF_CORR_LMS_DCOFF_Q,offQ); + for (i=0;i<10;i++) + trx_brf_read(device, &ptimestamp, (void **)&calib_buffp, RXDCLENGTH, 0); + + for (meanI=meanQ=i=j=0;i<RXDCLENGTH;i++) { + meanI+=calib_buff[j++]; + meanQ+=calib_buff[j++]; + } + meanI/=RXDCLENGTH; + meanQ/=RXDCLENGTH; + // printf("[BRF] RX DC: (%d,%d) => (%d,%d)\n",offI,offQ,meanI,meanQ); + + while (cnt++ < 12) { + + offInew=(offIold+offI)>>1; + offQnew=(offQold+offQ)>>1; + + if (meanI*meanI < meanIold*meanIold) { + meanIold = meanI; + offIold = offI; + printf("[BRF] *** RX DC: offI %d => %d\n",offIold,meanI); + } + if (meanQ*meanQ < meanQold*meanQold) { + meanQold = meanQ; + offQold = offQ; + printf("[BRF] *** RX DC: offQ %d => %d\n",offQold,meanQ); + } + offI = offInew; + offQ = offQnew; + bladerf_set_correction(brf->dev,BLADERF_MODULE_RX,BLADERF_CORR_LMS_DCOFF_I,offI); + bladerf_set_correction(brf->dev,BLADERF_MODULE_RX,BLADERF_CORR_LMS_DCOFF_Q,offQ); + + for (i=0;i<10;i++) + trx_brf_read(device, &ptimestamp, (void **)&calib_buffp, RXDCLENGTH, 0); + + for (meanI=meanQ=i=j=0;i<RXDCLENGTH;i++) { + meanI+=calib_buff[j++]; + meanQ+=calib_buff[j++]; + } + meanI/=RXDCLENGTH; + meanQ/=RXDCLENGTH; + printf("[BRF] RX DC: (%d,%d) => (%d,%d)\n",offI,offQ,meanI,meanQ); + } + + printf("[BRF] RX DC: (%d,%d) => (%d,%d)\n",offIold,offQold,meanIold,meanQold); + bladerf_set_correction(brf->dev,BLADERF_MODULE_RX,BLADERF_CORR_LMS_DCOFF_I,offIold); + bladerf_set_correction(brf->dev,BLADERF_MODULE_RX,BLADERF_CORR_LMS_DCOFF_Q,offQold); + + // TX DC offset + // PUT TX as f_RX + fs/4 + // loop back BLADERF_LB_RF_LNA1 + bladerf_set_frequency(brf->dev,BLADERF_MODULE_TX, (unsigned int) device->openair0_cfg->rx_freq[0] + (unsigned int) device->openair0_cfg->sample_rate/4); + bladerf_set_loopback (brf->dev,BLADERF_LB_RF_LNA1); + + offIold=2048; + bladerf_set_correction(brf->dev,BLADERF_MODULE_TX,BLADERF_CORR_LMS_DCOFF_I,offIold); + for (i=0;i<10;i++) { + trx_brf_read(device, &ptimestamp, (void **)&calib_buffp, RXDCLENGTH, 0); + trx_brf_write(device,ptimestamp+5*RXDCLENGTH, (void **)&calib_tx_buffp, RXDCLENGTH, 0); + } + for (meanIold=meanQold=i=j=0;i<RXDCLENGTH;i++) { + switch (i&3) { + case 0: + meanIold+=calib_buff[j++]; + break; + case 1: + meanQold+=calib_buff[j++]; + break; + case 2: + meanIold-=calib_buff[j++]; + break; + case 3: + meanQold-=calib_buff[j++]; + break; + } + } + // meanIold/=RXDCLENGTH; + // meanQold/=RXDCLENGTH; + printf("[BRF] TX DC (offI): %d => (%d,%d)\n",offIold,meanIold,meanQold); + + offI=-2048; + bladerf_set_correction(brf->dev,BLADERF_MODULE_TX,BLADERF_CORR_LMS_DCOFF_I,offI); + for (i=0;i<10;i++) { + trx_brf_read(device, &ptimestamp, (void **)&calib_buffp, RXDCLENGTH, 0); + trx_brf_write(device,ptimestamp+5*RXDCLENGTH, (void **)&calib_tx_buffp, RXDCLENGTH, 0); + } + for (meanI=meanQ=i=j=0;i<RXDCLENGTH;i++) { + switch (i&3) { + case 0: + meanI+=calib_buff[j++]; + break; + case 1: + meanQ+=calib_buff[j++]; + break; + case 2: + meanI-=calib_buff[j++]; + break; + case 3: + meanQ-=calib_buff[j++]; + break; + } + } + // meanI/=RXDCLENGTH; + // meanQ/=RXDCLENGTH; + printf("[BRF] TX DC (offI): %d => (%d,%d)\n",offI,meanI,meanQ); + cnt = 0; + while (cnt++ < 12) { + + offInew=(offIold+offI)>>1; + if (meanI*meanI+meanQ*meanQ < meanIold*meanIold +meanQold*meanQold) { + printf("[BRF] TX DC (offI): ([%d,%d]) => %d : %d\n",offIold,offI,offInew,meanI*meanI+meanQ*meanQ); + meanIold = meanI; + meanQold = meanQ; + offIold = offI; + } + offI = offInew; + bladerf_set_correction(brf->dev,BLADERF_MODULE_TX,BLADERF_CORR_LMS_DCOFF_I,offI); + + for (i=0;i<10;i++) { + trx_brf_read(device, &ptimestamp, (void **)&calib_buffp, RXDCLENGTH, 0); + trx_brf_write(device,ptimestamp+5*RXDCLENGTH, (void **)&calib_tx_buffp, RXDCLENGTH, 0); + } + for (meanI=meanQ=i=j=0;i<RXDCLENGTH;i++) { + switch (i&3) { + case 0: + meanI+=calib_buff[j++]; + break; + case 1: + meanQ+=calib_buff[j++]; + break; + case 2: + meanI-=calib_buff[j++]; + break; + case 3: + meanQ-=calib_buff[j++]; + break; + } + } + // meanI/=RXDCLENGTH; + // meanQ/=RXDCLENGTH; + // printf("[BRF] TX DC (offI): %d => (%d,%d)\n",offI,meanI,meanQ); + } + + bladerf_set_correction(brf->dev,BLADERF_MODULE_TX,BLADERF_CORR_LMS_DCOFF_I,offIold); + + offQold=2048; + bladerf_set_correction(brf->dev,BLADERF_MODULE_TX,BLADERF_CORR_LMS_DCOFF_Q,offQold); + for (i=0;i<10;i++) { + trx_brf_read(device, &ptimestamp, (void **)&calib_buffp, RXDCLENGTH, 0); + trx_brf_write(device,ptimestamp+5*RXDCLENGTH, (void **)&calib_tx_buffp, RXDCLENGTH, 0); + } + // project on fs/4 + for (meanIold=meanQold=i=j=0;i<RXDCLENGTH;i++) { + switch (i&3) { + case 0: + meanIold+=calib_buff[j++]; + break; + case 1: + meanQold+=calib_buff[j++]; + break; + case 2: + meanIold-=calib_buff[j++]; + break; + case 3: + meanQold-=calib_buff[j++]; + break; + } + } + // meanIold/=RXDCLENGTH; + // meanQold/=RXDCLENGTH; + printf("[BRF] TX DC (offQ): %d => (%d,%d)\n",offQold,meanIold,meanQold); + + offQ=-2048; + bladerf_set_correction(brf->dev,BLADERF_MODULE_TX,BLADERF_CORR_LMS_DCOFF_Q,offQ); + for (i=0;i<10;i++) { + trx_brf_read(device, &ptimestamp, (void **)&calib_buffp, RXDCLENGTH, 0); + trx_brf_write(device,ptimestamp+5*RXDCLENGTH, (void **)&calib_tx_buffp, RXDCLENGTH, 0); + } + for (meanI=meanQ=i=j=0;i<RXDCLENGTH;i++) { + switch (i&3) { + case 0: + meanI+=calib_buff[j++]; + break; + case 1: + meanQ+=calib_buff[j++]; + break; + case 2: + meanI-=calib_buff[j++]; + break; + case 3: + meanQ-=calib_buff[j++]; + break; + } + } + // meanI/=RXDCLENGTH; + // meanQ/=RXDCLENGTH; + printf("[BRF] TX DC (offQ): %d => (%d,%d)\n",offQ,meanI,meanQ); + + cnt=0; + while (cnt++ < 12) { + + offQnew=(offQold+offQ)>>1; + if (meanI*meanI+meanQ*meanQ < meanIold*meanIold +meanQold*meanQold) { + printf("[BRF] TX DC (offQ): ([%d,%d]) => %d : %d\n",offQold,offQ,offQnew,meanI*meanI+meanQ*meanQ); + + meanIold = meanI; + meanQold = meanQ; + offQold = offQ; + } + offQ = offQnew; + bladerf_set_correction(brf->dev,BLADERF_MODULE_TX,BLADERF_CORR_LMS_DCOFF_Q,offQ); + + for (i=0;i<10;i++) { + trx_brf_read(device, &ptimestamp, (void **)&calib_buffp, RXDCLENGTH, 0); + trx_brf_write(device,ptimestamp+5*RXDCLENGTH, (void **)&calib_tx_buffp, RXDCLENGTH, 0); + } + for (meanI=meanQ=i=j=0;i<RXDCLENGTH;i++) { + switch (i&3) { + case 0: + meanI+=calib_buff[j++]; + break; + case 1: + meanQ+=calib_buff[j++]; + break; + case 2: + meanI-=calib_buff[j++]; + break; + case 3: + meanQ-=calib_buff[j++]; + break; + } + } + // meanI/=RXDCLENGTH; + // meanQ/=RXDCLENGTH; + // printf("[BRF] TX DC (offQ): %d => (%d,%d)\n",offQ,meanI,meanQ); + } + + printf("[BRF] TX DC: (%d,%d) => (%d,%d)\n",offIold,offQold,meanIold,meanQold); + + bladerf_set_correction(brf->dev,BLADERF_MODULE_TX,BLADERF_CORR_LMS_DCOFF_Q,offQold); + + // TX IQ imbalance + for (loop=0;loop<2;loop++) { + offphaseold=4096; + bladerf_set_correction(brf->dev,BLADERF_MODULE_TX,BLADERF_CORR_FPGA_PHASE,offphaseold); + for (i=0;i<10;i++) { + trx_brf_read(device, &ptimestamp, (void **)&calib_buffp, RXDCLENGTH, 0); + trx_brf_write(device,ptimestamp+5*RXDCLENGTH, (void **)&calib_tx_buffp, RXDCLENGTH, 0); + } + // project on fs/8 (Image of TX signal in +ve frequencies) + for (meanIold=meanQold=i=j=0;i<RXDCLENGTH;i++) { + meanIold+= (calib_buff[j]*cos_fsover8[i&7] - calib_buff[j+1]*cos_fsover8[(i+2)&7])>>11; + meanQold+= (calib_buff[j]*cos_fsover8[(i+2)&7] + calib_buff[j+1]*cos_fsover8[i&7])>>11; + j+=2; + } + + meanIold/=RXDCLENGTH; + meanQold/=RXDCLENGTH; + printf("[BRF] TX IQ (offphase): %d => (%d,%d)\n",offphaseold,meanIold,meanQold); + + offphase=-4096; + bladerf_set_correction(brf->dev,BLADERF_MODULE_TX,BLADERF_CORR_FPGA_PHASE,offphase); + for (i=0;i<10;i++) { + trx_brf_read(device, &ptimestamp, (void **)&calib_buffp, RXDCLENGTH, 0); + trx_brf_write(device,ptimestamp+5*RXDCLENGTH, (void **)&calib_tx_buffp, RXDCLENGTH, 0); + } + // project on fs/8 (Image of TX signal in +ve frequencies) + for (meanI=meanQ=i=j=0;i<RXDCLENGTH;i++) { + meanI+= (calib_buff[j]*cos_fsover8[i&7] - calib_buff[j+1]*cos_fsover8[(i+2)&7])>>11; + meanQ+= (calib_buff[j]*cos_fsover8[(i+2)&7] + calib_buff[j+1]*cos_fsover8[i&7])>>11; + j+=2; + } + + meanI/=RXDCLENGTH; + meanQ/=RXDCLENGTH; + printf("[BRF] TX IQ (offphase): %d => (%d,%d)\n",offphase,meanI,meanQ); + + cnt=0; + while (cnt++ < 13) { + + offphasenew=(offphaseold+offphase)>>1; + printf("[BRF] TX IQ (offphase): ([%d,%d]) => %d : %d\n",offphaseold,offphase,offphasenew,meanI*meanI+meanQ*meanQ); + if (meanI*meanI+meanQ*meanQ < meanIold*meanIold +meanQold*meanQold) { + + + meanIold = meanI; + meanQold = meanQ; + offphaseold = offphase; + } + offphase = offphasenew; + bladerf_set_correction(brf->dev,BLADERF_MODULE_TX,BLADERF_CORR_FPGA_PHASE,offphase); + + for (i=0;i<10;i++) { + trx_brf_read(device, &ptimestamp, (void **)&calib_buffp, RXDCLENGTH, 0); + trx_brf_write(device,ptimestamp+5*RXDCLENGTH, (void **)&calib_tx_buffp, RXDCLENGTH, 0); + } + // project on fs/8 (Image of TX signal in +ve frequencies) + for (meanI=meanQ=i=j=0;i<RXDCLENGTH;i++) { + meanI+= (calib_buff[j]*cos_fsover8[i&7] - calib_buff[j+1]*cos_fsover8[(i+2)&7])>>11; + meanQ+= (calib_buff[j]*cos_fsover8[(i+2)&7] + calib_buff[j+1]*cos_fsover8[i&7])>>11; + j+=2; + } + meanI/=RXDCLENGTH; + meanQ/=RXDCLENGTH; + + // printf("[BRF] TX DC (offQ): %d => (%d,%d)\n",offQ,meanI,meanQ); + } + + printf("[BRF] TX IQ offphase: %d => (%d,%d)\n",offphaseold,meanIold,meanQold); + + bladerf_set_correction(brf->dev,BLADERF_MODULE_TX,BLADERF_CORR_FPGA_PHASE,offphaseold); + + offgainold=4096; + bladerf_set_correction(brf->dev,BLADERF_MODULE_TX,BLADERF_CORR_FPGA_GAIN,offgainold); + for (i=0;i<10;i++) { + trx_brf_read(device, &ptimestamp, (void **)&calib_buffp, RXDCLENGTH, 0); + trx_brf_write(device,ptimestamp+5*RXDCLENGTH, (void **)&calib_tx_buffp, RXDCLENGTH, 0); + } + // project on fs/8 (Image of TX signal in +ve frequencies) + for (meanIold=meanQold=i=j=0;i<RXDCLENGTH;i++) { + meanIold+= (calib_buff[j]*cos_fsover8[i&7] - calib_buff[j+1]*cos_fsover8[(i+2)&7])>>11; + meanQold+= (calib_buff[j]*cos_fsover8[(i+2)&7] + calib_buff[j+1]*cos_fsover8[i&7])>>11; + j+=2; + } + + meanIold/=RXDCLENGTH; + meanQold/=RXDCLENGTH; + printf("[BRF] TX IQ (offgain): %d => (%d,%d)\n",offgainold,meanIold,meanQold); + + offgain=-4096; + bladerf_set_correction(brf->dev,BLADERF_MODULE_TX,BLADERF_CORR_FPGA_GAIN,offgain); + for (i=0;i<10;i++) { + trx_brf_read(device, &ptimestamp, (void **)&calib_buffp, RXDCLENGTH, 0); + trx_brf_write(device,ptimestamp+5*RXDCLENGTH, (void **)&calib_tx_buffp, RXDCLENGTH, 0); + } + // project on fs/8 (Image of TX signal in +ve frequencies) + for (meanI=meanQ=i=j=0;i<RXDCLENGTH;i++) { + meanI+= (calib_buff[j]*cos_fsover8[i&7] - calib_buff[j+1]*cos_fsover8[(i+2)&7])>>11; + meanQ+= (calib_buff[j]*cos_fsover8[(i+2)&7] + calib_buff[j+1]*cos_fsover8[i&7])>>11; + j+=2; + } + + meanI/=RXDCLENGTH; + meanQ/=RXDCLENGTH; + printf("[BRF] TX IQ (offgain): %d => (%d,%d)\n",offgain,meanI,meanQ); + + cnt=0; + while (cnt++ < 13) { + + offgainnew=(offgainold+offgain)>>1; + if (meanI*meanI+meanQ*meanQ < meanIold*meanIold +meanQold*meanQold) { + printf("[BRF] TX IQ (offgain): ([%d,%d]) => %d : %d\n",offgainold,offgain,offgainnew,meanI*meanI+meanQ*meanQ); + + meanIold = meanI; + meanQold = meanQ; + offgainold = offgain; + } + offgain = offgainnew; + bladerf_set_correction(brf->dev,BLADERF_MODULE_TX,BLADERF_CORR_FPGA_GAIN,offgain); + + for (i=0;i<10;i++) { + trx_brf_read(device, &ptimestamp, (void **)&calib_buffp, RXDCLENGTH, 0); + trx_brf_write(device,ptimestamp+5*RXDCLENGTH, (void **)&calib_tx_buffp, RXDCLENGTH, 0); + } + // project on fs/8 (Image of TX signal in +ve frequencies) + for (meanI=meanQ=i=j=0;i<RXDCLENGTH;i++) { + meanI+= (calib_buff[j]*cos_fsover8[i&7] - calib_buff[j+1]*cos_fsover8[(i+2)&7])>>11; + meanQ+= (calib_buff[j]*cos_fsover8[(i+2)&7] + calib_buff[j+1]*cos_fsover8[i&7])>>11; + j+=2; + } + meanI/=RXDCLENGTH; + meanQ/=RXDCLENGTH; + + // printf("[BRF] TX DC (offQ): %d => (%d,%d)\n",offQ,meanI,meanQ); + } + + printf("[BRF] TX IQ offgain: %d => (%d,%d)\n",offgainold,meanIold,meanQold); + + bladerf_set_correction(brf->dev,BLADERF_MODULE_TX,BLADERF_CORR_FPGA_GAIN,offgainold); + } + + // RX IQ imbalance + for (loop=0;loop<2;loop++) { + offphaseold=4096; + bladerf_set_correction(brf->dev,BLADERF_MODULE_RX,BLADERF_CORR_FPGA_PHASE,offphaseold); + for (i=0;i<10;i++) { + trx_brf_read(device, &ptimestamp, (void **)&calib_buffp, RXDCLENGTH, 0); + trx_brf_write(device,ptimestamp+5*RXDCLENGTH, (void **)&calib_tx_buffp, RXDCLENGTH, 0); + } + // project on -3fs/8 (Image of TX signal in -ve frequencies) + for (meanIold=meanQold=i=j=0;i<RXDCLENGTH;i++) { + meanIold+= (calib_buff[j]*cos_3fsover8[i&7] - calib_buff[j+1]*cos_3fsover8[(i+2)&7])>>11; + meanQold+= (calib_buff[j]*cos_3fsover8[(i+2)&7] + calib_buff[j+1]*cos_3fsover8[i&7])>>11; + j+=2; + } + + meanIold/=RXDCLENGTH; + meanQold/=RXDCLENGTH; + printf("[BRF] RX IQ (offphase): %d => (%d,%d)\n",offphaseold,meanIold,meanQold); + + offphase=-4096; + bladerf_set_correction(brf->dev,BLADERF_MODULE_RX,BLADERF_CORR_FPGA_PHASE,offphase); + for (i=0;i<10;i++) { + trx_brf_read(device, &ptimestamp, (void **)&calib_buffp, RXDCLENGTH, 0); + trx_brf_write(device,ptimestamp+5*RXDCLENGTH, (void **)&calib_tx_buffp, RXDCLENGTH, 0); + } + // project on -3fs/8 (Image of TX signal in -ve frequencies) + for (meanI=meanQ=i=j=0;i<RXDCLENGTH;i++) { + meanI+= (calib_buff[j]*cos_3fsover8[i&7] - calib_buff[j+1]*cos_3fsover8[(i+2)&7])>>11; + meanQ+= (calib_buff[j]*cos_3fsover8[(i+2)&7] + calib_buff[j+1]*cos_3fsover8[i&7])>>11; + j+=2; + } + + meanI/=RXDCLENGTH; + meanQ/=RXDCLENGTH; + printf("[BRF] RX IQ (offphase): %d => (%d,%d)\n",offphase,meanI,meanQ); + + cnt=0; + while (cnt++ < 13) { + + offphasenew=(offphaseold+offphase)>>1; + printf("[BRF] RX IQ (offphase): ([%d,%d]) => %d : %d\n",offphaseold,offphase,offphasenew,meanI*meanI+meanQ*meanQ); + if (meanI*meanI+meanQ*meanQ < meanIold*meanIold +meanQold*meanQold) { + + + meanIold = meanI; + meanQold = meanQ; + offphaseold = offphase; + } + offphase = offphasenew; + bladerf_set_correction(brf->dev,BLADERF_MODULE_RX,BLADERF_CORR_FPGA_PHASE,offphase); + + for (i=0;i<10;i++) { + trx_brf_read(device, &ptimestamp, (void **)&calib_buffp, RXDCLENGTH, 0); + trx_brf_write(device,ptimestamp+5*RXDCLENGTH, (void **)&calib_tx_buffp, RXDCLENGTH, 0); + } + // project on -3fs/8 (Image of TX signal in -ve frequencies) + for (meanI=meanQ=i=j=0;i<RXDCLENGTH;i++) { + meanI+= (calib_buff[j]*cos_3fsover8[i&7] - calib_buff[j+1]*cos_3fsover8[(i+2)&7])>>11; + meanQ+= (calib_buff[j]*cos_3fsover8[(i+2)&7] + calib_buff[j+1]*cos_3fsover8[i&7])>>11; + j+=2; + } + meanI/=RXDCLENGTH; + meanQ/=RXDCLENGTH; + + // printf("[BRF] TX DC (offQ): %d => (%d,%d)\n",offQ,meanI,meanQ); + } + + printf("[BRF] RX IQ offphase: %d => (%d,%d)\n",offphaseold,meanIold,meanQold); + + bladerf_set_correction(brf->dev,BLADERF_MODULE_RX,BLADERF_CORR_FPGA_PHASE,offphaseold); + + offgainold=4096; + bladerf_set_correction(brf->dev,BLADERF_MODULE_RX,BLADERF_CORR_FPGA_GAIN,offgainold); + for (i=0;i<10;i++) { + trx_brf_read(device, &ptimestamp, (void **)&calib_buffp, RXDCLENGTH, 0); + trx_brf_write(device,ptimestamp+5*RXDCLENGTH, (void **)&calib_tx_buffp, RXDCLENGTH, 0); + } + // project on -3fs/8 (Image of TX signal in +ve frequencies) + for (meanIold=meanQold=i=j=0;i<RXDCLENGTH;i++) { + meanIold+= (calib_buff[j]*cos_3fsover8[i&7] - calib_buff[j+1]*cos_3fsover8[(i+2)&7])>>11; + meanQold+= (calib_buff[j]*cos_3fsover8[(i+2)&7] + calib_buff[j+1]*cos_3fsover8[i&7])>>11; + j+=2; + } + + meanIold/=RXDCLENGTH; + meanQold/=RXDCLENGTH; + printf("[BRF] RX IQ (offgain): %d => (%d,%d)\n",offgainold,meanIold,meanQold); + + offgain=-4096; + bladerf_set_correction(brf->dev,BLADERF_MODULE_RX,BLADERF_CORR_FPGA_GAIN,offgain); + for (i=0;i<10;i++) { + trx_brf_read(device, &ptimestamp, (void **)&calib_buffp, RXDCLENGTH, 0); + trx_brf_write(device,ptimestamp+5*RXDCLENGTH, (void **)&calib_tx_buffp, RXDCLENGTH, 0); + } + // project on 3fs/8 (Image of TX signal in -ve frequencies) + for (meanI=meanQ=i=j=0;i<RXDCLENGTH;i++) { + meanI+= (calib_buff[j]*cos_3fsover8[i&7] - calib_buff[j+1]*cos_3fsover8[(i+2)&7])>>11; + meanQ+= (calib_buff[j]*cos_3fsover8[(i+2)&7] + calib_buff[j+1]*cos_3fsover8[i&7])>>11; + j+=2; + } + + meanI/=RXDCLENGTH; + meanQ/=RXDCLENGTH; + printf("[BRF] RX IQ (offgain): %d => (%d,%d)\n",offgain,meanI,meanQ); + + cnt=0; + while (cnt++ < 13) { + + offgainnew=(offgainold+offgain)>>1; + if (meanI*meanI+meanQ*meanQ < meanIold*meanIold +meanQold*meanQold) { + printf("[BRF] RX IQ (offgain): ([%d,%d]) => %d : %d\n",offgainold,offgain,offgainnew,meanI*meanI+meanQ*meanQ); + + meanIold = meanI; + meanQold = meanQ; + offgainold = offgain; + } + offgain = offgainnew; + bladerf_set_correction(brf->dev,BLADERF_MODULE_RX,BLADERF_CORR_FPGA_GAIN,offgain); + + for (i=0;i<10;i++) { + trx_brf_read(device, &ptimestamp, (void **)&calib_buffp, RXDCLENGTH, 0); + trx_brf_write(device,ptimestamp+5*RXDCLENGTH, (void **)&calib_tx_buffp, RXDCLENGTH, 0); + } + // project on -3fs/8 (Image of TX signal in -ve frequencies) + for (meanI=meanQ=i=j=0;i<RXDCLENGTH;i++) { + meanI+= (calib_buff[j]*cos_3fsover8[i&7] - calib_buff[j+1]*cos_3fsover8[(i+2)&7])>>11; + meanQ+= (calib_buff[j]*cos_3fsover8[(i+2)&7] + calib_buff[j+1]*cos_3fsover8[i&7])>>11; + j+=2; + } + meanI/=RXDCLENGTH; + meanQ/=RXDCLENGTH; + + // printf("[BRF] TX DC (offQ): %d => (%d,%d)\n",offQ,meanI,meanQ); + } + + printf("[BRF] RX IQ offgain: %d => (%d,%d)\n",offgainold,meanIold,meanQold); + + bladerf_set_correction(brf->dev,BLADERF_MODULE_RX,BLADERF_CORR_FPGA_GAIN,offgainold); + } + + bladerf_set_frequency(brf->dev,BLADERF_MODULE_TX, (unsigned int) device->openair0_cfg->tx_freq[0]); + bladerf_set_loopback(brf->dev,BLADERF_LB_NONE); + bladerf_set_gain(brf->dev, BLADERF_MODULE_RX, (unsigned int) device->openair0_cfg->rx_gain[0]-device->openair0_cfg[0].rx_gain_offset[0]); + bladerf_set_gain(brf->dev, BLADERF_MODULE_TX, (unsigned int) device->openair0_cfg->tx_gain[0]); + // write_output("blade_rf_test.m","rxs",calib_buff,RXDCLENGTH,1,1); +} + int openair0_dev_init_bladerf(openair0_device *device, openair0_config_t *openair0_cfg) { int status; @@ -192,18 +829,52 @@ int openair0_dev_init_bladerf(openair0_device *device, openair0_config_t *openai brf_state_t *brf = (brf_state_t*)malloc(sizeof(brf_state_t)); memset(brf, 0, sizeof(brf_state_t)); - // init required params for BRF - brf->num_buffers = 128; - brf->buffer_size = (unsigned int) openair0_cfg[card].samples_per_packet*sizeof(int32_t); // buffer size = 4096 for sample_len of 1024 - brf->num_transfers = 16; - brf->rx_timeout_ms = 0; - brf->tx_timeout_ms = 0; - brf->sample_rate=(unsigned int)openair0_cfg[card].sample_rate; + // init required params - - printf("\n[BRF] sampling_rate %d, num_buffers %d, buffer_size %d, num transfer %d, timeout_ms (rx %d, tx %d)\n", - brf->sample_rate, brf->num_buffers, brf->buffer_size,brf->num_transfers, brf->rx_timeout_ms, brf->tx_timeout_ms); + switch ((int)openair0_cfg->sample_rate) { + case 30720000: + openair0_cfg->samples_per_packet = 2048; + openair0_cfg->tx_sample_advance = 0; + openair0_cfg->tx_scheduling_advance = 8*openair0_cfg->samples_per_packet; + break; + case 15360000: + openair0_cfg->samples_per_packet = 2048; + openair0_cfg->tx_sample_advance = 0; + openair0_cfg->tx_scheduling_advance = 4*openair0_cfg->samples_per_packet; + break; + case 7680000: + openair0_cfg->samples_per_packet = 1024; + openair0_cfg->tx_sample_advance = 0; + openair0_cfg->tx_scheduling_advance = 4*openair0_cfg->samples_per_packet; + break; + case 1920000: + openair0_cfg->samples_per_packet = 256; + openair0_cfg->tx_sample_advance = 50; + openair0_cfg->tx_scheduling_advance = 8*openair0_cfg->samples_per_packet; + break; + default: + printf("Error: unknown sampling rate %f\n",openair0_cfg->sample_rate); + exit(-1); + break; + } + + openair0_cfg->rx_gain_calib_table = calib_table_fx4; + + // The number of buffers to use in the underlying data stream + brf->num_buffers = 128; + // the size of the underlying stream buffers, in samples + brf->buffer_size = (unsigned int) openair0_cfg->samples_per_packet;//*sizeof(int32_t); // buffer size = 4096 for sample_len of 1024 + brf->num_transfers = 16; + brf->rx_timeout_ms = 0; + brf->tx_timeout_ms = 0; + brf->sample_rate=(unsigned int)openair0_cfg->sample_rate; + + memset(&brf->meta_rx, 0, sizeof(brf->meta_rx)); + memset(&brf->meta_tx, 0, sizeof(brf->meta_tx)); + printf("\n[BRF] sampling_rate %d, num_buffers %d, buffer_size %d, num transfer %d, timeout_ms (rx %d, tx %d)\n", + brf->sample_rate, brf->num_buffers, brf->buffer_size,brf->num_transfers, brf->rx_timeout_ms, brf->tx_timeout_ms); + if ((status=bladerf_open(&brf->dev, "")) != 0 ) { fprintf(stderr,"Failed to open brf device: %s\n",bladerf_strerror(status)); brf_error(status); @@ -217,83 +888,81 @@ int openair0_dev_init_bladerf(openair0_device *device, openair0_config_t *openai printf("[BRF] Device does not operates at max speed, change the USB port\n"); brf_error(BLADERF_ERR_UNSUPPORTED); } - // RX + // RX // Example of CLI output: RX Frequency: 2539999999Hz - if ((status=bladerf_set_frequency(brf->dev, BLADERF_MODULE_RX, (unsigned int) openair0_cfg[card].rx_freq[0])) != 0){ + if ((status=bladerf_set_frequency(brf->dev, BLADERF_MODULE_RX, (unsigned int) openair0_cfg->rx_freq[0])) != 0){ fprintf(stderr,"Failed to set RX frequency: %s\n",bladerf_strerror(status)); brf_error(status); } else - printf("[BRF] set RX frequency to %f\n",openair0_cfg[card].rx_freq[0]); + printf("[BRF] set RX frequency to %u\n",(unsigned int)openair0_cfg->rx_freq[0]); - - if ((status=bladerf_set_sample_rate(brf->dev, BLADERF_MODULE_RX, (unsigned int)openair0_cfg[card].sample_rate, NULL)) != 0){ + + + unsigned int actual_value=0; + if ((status=bladerf_set_sample_rate(brf->dev, BLADERF_MODULE_RX, (unsigned int) openair0_cfg->sample_rate, &actual_value)) != 0){ fprintf(stderr,"Failed to set RX sample rate: %s\n", bladerf_strerror(status)); brf_error(status); - }else - printf("[BRF] set RX sample rate to %f\n",openair0_cfg[card].sample_rate); + }else + printf("[BRF] set RX sample rate to %u, %u\n", (unsigned int) openair0_cfg->sample_rate, actual_value); - if ((status=bladerf_set_bandwidth(brf->dev, BLADERF_MODULE_RX, (unsigned int) openair0_cfg[card].rx_bw, NULL)) != 0){ + + if ((status=bladerf_set_bandwidth(brf->dev, BLADERF_MODULE_RX, (unsigned int) openair0_cfg->rx_bw*2, &actual_value)) != 0){ fprintf(stderr,"Failed to set RX bandwidth: %s\n", bladerf_strerror(status)); brf_error(status); }else - printf("[BRF] set RX bandwidth to %f\n",openair0_cfg[card].rx_bw); + printf("[BRF] set RX bandwidth to %u, %u\n",(unsigned int)openair0_cfg->rx_bw*2, actual_value); - if ((status=bladerf_set_gain(brf->dev, BLADERF_MODULE_RX, (int) openair0_cfg[card].rx_gain[0])) != 0) { + set_rx_gain_offset(&openair0_cfg[0],0); + if ((status=bladerf_set_gain(brf->dev, BLADERF_MODULE_RX, (int) openair0_cfg->rx_gain[0]-openair0_cfg[0].rx_gain_offset[0])) != 0) { fprintf(stderr,"Failed to set RX gain: %s\n",bladerf_strerror(status)); brf_error(status); } else - printf("[BRF] set RX gain to %f\n",openair0_cfg[card].rx_gain[0]); + printf("[BRF] set RX gain to %d (%d)\n",(int)(openair0_cfg->rx_gain[0]-openair0_cfg[0].rx_gain_offset[0]),(int)openair0_cfg[0].rx_gain_offset[0]); - /* Configure the device's RX module for use with the sync interface. - * SC16 Q11 samples *with* metadata are used. */ - if ((status=bladerf_sync_config(brf->dev, BLADERF_MODULE_RX, BLADERF_FORMAT_SC16_Q11_META,brf->num_buffers,brf->buffer_size,brf->num_transfers,brf->rx_timeout_ms)) != 0 ) { - fprintf(stderr,"Failed to configure RX sync interface: %s\n", bladerf_strerror(status)); - brf_error(status); - }else - printf("[BRF] configured Rx for sync interface \n"); - - /* We must always enable the RX module after calling bladerf_sync_config(), and - * before attempting to RX samples via bladerf_sync_rx(). */ - if ((status=bladerf_enable_module(brf->dev, BLADERF_MODULE_RX, true)) != 0) { - fprintf(stderr,"Failed to enable RX module: %s\n", bladerf_strerror(status)); - brf_error(status); - }else - printf("[BRF] RX module enabled \n"); - // TX - if ((status=bladerf_set_frequency(brf->dev, BLADERF_MODULE_TX, (unsigned int) openair0_cfg[card].tx_freq[0])) != 0){ + + if ((status=bladerf_set_frequency(brf->dev, BLADERF_MODULE_TX, (unsigned int) openair0_cfg->tx_freq[0])) != 0){ fprintf(stderr,"Failed to set TX frequency: %s\n",bladerf_strerror(status)); brf_error(status); }else - printf("[BRF] set Tx Frequenct to %f \n", openair0_cfg[card].tx_freq[0]); + printf("[BRF] set TX Frequency to %u\n", (unsigned int) openair0_cfg->tx_freq[0]); - if ((status=bladerf_set_sample_rate(brf->dev, BLADERF_MODULE_TX, (unsigned int) openair0_cfg[card].sample_rate, NULL)) != 0){ + if ((status=bladerf_set_sample_rate(brf->dev, BLADERF_MODULE_TX, (unsigned int) openair0_cfg->sample_rate, NULL)) != 0){ fprintf(stderr,"Failed to set TX sample rate: %s\n", bladerf_strerror(status)); brf_error(status); }else - printf("[BRF] set Tx sampling rate to %f \n", openair0_cfg[card].sample_rate); + printf("[BRF] set TX sampling rate to %u \n", (unsigned int) openair0_cfg->sample_rate); - if ((status=bladerf_set_bandwidth(brf->dev, BLADERF_MODULE_TX,(unsigned int)openair0_cfg[card].tx_bw, NULL)) != 0){ - fprintf(stderr, "Failed to set RX bandwidth: %s\n", bladerf_strerror(status)); + if ((status=bladerf_set_bandwidth(brf->dev, BLADERF_MODULE_TX,(unsigned int)openair0_cfg->tx_bw*2, NULL)) != 0){ + fprintf(stderr, "Failed to set TX bandwidth: %s\n", bladerf_strerror(status)); brf_error(status); }else - printf("[BRF] set Tx sampling ratebandwidth to %f \n", openair0_cfg[card].tx_bw); + printf("[BRF] set TX bandwidth to %u \n", (unsigned int) openair0_cfg->tx_bw*2); - if ((status=bladerf_set_gain(brf->dev, BLADERF_MODULE_TX, (int)openair0_cfg[card].tx_gain[0])) != 0) { + if ((status=bladerf_set_gain(brf->dev, BLADERF_MODULE_TX, (int) openair0_cfg->tx_gain[0])) != 0) { fprintf(stderr,"Failed to set TX gain: %s\n",bladerf_strerror(status)); brf_error(status); }else - printf("[BRF] set the Tx gain to %f \n", openair0_cfg[card].tx_gain[0]); - + printf("[BRF] set the TX gain to %d\n", (int)openair0_cfg->tx_gain[0]); + - /* Configure the device's TX module for use with the sync interface. + /* Configure the device's TX module for use with the sync interface. * SC16 Q11 samples *with* metadata are used. */ if ((status=bladerf_sync_config(brf->dev, BLADERF_MODULE_TX,BLADERF_FORMAT_SC16_Q11_META,brf->num_buffers,brf->buffer_size,brf->num_transfers,brf->tx_timeout_ms)) != 0 ) { fprintf(stderr,"Failed to configure TX sync interface: %s\n", bladerf_strerror(status)); brf_error(status); }else - printf("[BRF] configured tx for sync interface \n"); + printf("[BRF] configured TX sync interface \n"); + +/* Configure the device's RX module for use with the sync interface. + * SC16 Q11 samples *with* metadata are used. */ + if ((status=bladerf_sync_config(brf->dev, BLADERF_MODULE_RX, BLADERF_FORMAT_SC16_Q11_META,brf->num_buffers,brf->buffer_size,brf->num_transfers,brf->rx_timeout_ms)) != 0 ) { + fprintf(stderr,"Failed to configure RX sync interface: %s\n", bladerf_strerror(status)); + brf_error(status); + }else + printf("[BRF] configured Rx sync interface \n"); + /* We must always enable the TX module after calling bladerf_sync_config(), and * before attempting to TX samples via bladerf_sync_tx(). */ @@ -303,7 +972,31 @@ int openair0_dev_init_bladerf(openair0_device *device, openair0_config_t *openai } else printf("[BRF] TX module enabled \n"); - bladerf_log_set_verbosity(get_brf_log_level(openair0_cfg[card].log_level)); + /* We must always enable the RX module after calling bladerf_sync_config(), and + * before attempting to RX samples via bladerf_sync_rx(). */ + if ((status=bladerf_enable_module(brf->dev, BLADERF_MODULE_RX, true)) != 0) { + fprintf(stderr,"Failed to enable RX module: %s\n", bladerf_strerror(status)); + brf_error(status); + }else + printf("[BRF] RX module enabled \n"); + + // calibrate + + if ((status=bladerf_calibrate_dc(brf->dev, BLADERF_MODULE_TX)) != 0) { + fprintf(stderr,"Failed to calibrate TX DC: %s\n", bladerf_strerror(status)); + brf_error(status); + } else + printf("[BRF] TX module calibrated DC \n"); + + if ((status=bladerf_calibrate_dc(brf->dev, BLADERF_MODULE_RX)) != 0) { + fprintf(stderr,"Failed to calibrate RX DC: %s\n", bladerf_strerror(status)); + brf_error(status); + }else + printf("[BRF] RX module calibrated DC \n"); + + + + bladerf_log_set_verbosity(get_brf_log_level(openair0_cfg->log_level)); printf("BLADERF: Initializing openair0_device\n"); device->priv = brf; @@ -317,7 +1010,11 @@ 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; - memcpy((void*)&device->openair0_cfg,(void*)openair0_cfg,sizeof(openair0_config_t)); + device->openair0_cfg = openair0_cfg; + + calibrate_rf(device); + + // memcpy((void*)&device->openair0_cfg,(void*)&openair0_cfg[0],sizeof(openair0_config_t)); return 0; } @@ -359,7 +1056,7 @@ struct bladerf * open_bladerf_from_serial(const char *serial) { int get_brf_log_level(int log_level){ int level=BLADERF_LOG_LEVEL_INFO; - //return BLADERF_LOG_LEVEL_DEBUG; + return BLADERF_LOG_LEVEL_DEBUG; // BLADERF_LOG_LEVEL_VERBOSE;// BLADERF_LOG_LEVEL_DEBUG; // switch(log_level) { case LOG_DEBUG: level=BLADERF_LOG_LEVEL_DEBUG; diff --git a/targets/ARCH/COMMON/common_lib.h b/targets/ARCH/COMMON/common_lib.h index 156da0c4ce6991c3b54c4901650f34d826d8348f..a3fe9e9dbd33973354db652203a8d9e4c6461164 100644 --- a/targets/ARCH/COMMON/common_lib.h +++ b/targets/ARCH/COMMON/common_lib.h @@ -193,7 +193,7 @@ struct openair0_device_t { func_type_t func_type; /* RF frontend parameters set by application */ - openair0_config_t openair0_cfg; + openair0_config_t *openair0_cfg; /* Can be used by driver to hold internal structure*/ void *priv; diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.50PRB.bladerfx40.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.50PRB.bladerfx40.conf new file mode 100644 index 0000000000000000000000000000000000000000..5f7ac3d65f5c066cdf33f8661296ccddd5770f7f --- /dev/null +++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.50PRB.bladerfx40.conf @@ -0,0 +1,171 @@ +Active_eNBs = ( "eNB_Eurecom_LTEBox"); +# Asn1_verbosity, choice in: none, info, annoying +Asn1_verbosity = "none"; + +eNBs = +( + { + ////////// Identification parameters: + eNB_ID = 0xe00; + + cell_type = "CELL_MACRO_ENB"; + + eNB_name = "eNB_Eurecom_LTEBox"; + + // Tracking area code, 0x0000 and 0xfffe are reserved values + tracking_area_code = "1"; + + mobile_country_code = "208"; + + mobile_network_code = "92"; + + ////////// Physical parameters: + + component_carriers = ( + { + frame_type = "FDD"; + tdd_config = 3; + tdd_config_s = 0; + prefix_type = "NORMAL"; + eutra_band = 7; + downlink_frequency = 2680000000L; + uplink_frequency_offset = -120000000; + Nid_cell = 0; + N_RB_DL = 50; + Nid_cell_mbsfn = 0; + nb_antennas_tx = 1; + nb_antennas_rx = 1; + tx_gain = 60; + rx_gain = 60; + prach_root = 0; + prach_config_index = 0; + prach_high_speed = "DISABLE"; + prach_zero_correlation = 1; + prach_freq_offset = 2; + pucch_delta_shift = 1; + pucch_nRB_CQI = 1; + pucch_nCS_AN = 0; + pucch_n1_AN = 32; + pdsch_referenceSignalPower = -26; + pdsch_p_b = 0; + pusch_n_SB = 1; + pusch_enable64QAM = "DISABLE"; + pusch_hoppingMode = "interSubFrame"; + pusch_hoppingOffset = 0; + pusch_groupHoppingEnabled = "ENABLE"; + pusch_groupAssignment = 0; + pusch_sequenceHoppingEnabled = "DISABLE"; + pusch_nDMRS1 = 1; + phich_duration = "NORMAL"; + phich_resource = "ONESIXTH"; + srs_enable = "DISABLE"; + /* srs_BandwidthConfig =; + srs_SubframeConfig =; + srs_ackNackST =; + srs_MaxUpPts =;*/ + + pusch_p0_Nominal = -90; + pusch_alpha = "AL1"; + pucch_p0_Nominal = -108; + msg3_delta_Preamble = 6; + pucch_deltaF_Format1 = "deltaF2"; + pucch_deltaF_Format1b = "deltaF3"; + pucch_deltaF_Format2 = "deltaF0"; + pucch_deltaF_Format2a = "deltaF0"; + pucch_deltaF_Format2b = "deltaF0"; + + rach_numberOfRA_Preambles = 64; + rach_preamblesGroupAConfig = "DISABLE"; +/* + rach_sizeOfRA_PreamblesGroupA = ; + rach_messageSizeGroupA = ; + rach_messagePowerOffsetGroupB = ; +*/ + rach_powerRampingStep = 4; + rach_preambleInitialReceivedTargetPower = -108; + rach_preambleTransMax = 10; + rach_raResponseWindowSize = 10; + rach_macContentionResolutionTimer = 48; + rach_maxHARQ_Msg3Tx = 4; + + pcch_default_PagingCycle = 128; + pcch_nB = "oneT"; + bcch_modificationPeriodCoeff = 2; + ue_TimersAndConstants_t300 = 1000; + ue_TimersAndConstants_t301 = 1000; + ue_TimersAndConstants_t310 = 1000; + ue_TimersAndConstants_t311 = 10000; + ue_TimersAndConstants_n310 = 20; + ue_TimersAndConstants_n311 = 1; + + } + ); + + + srb1_parameters : + { + # timer_poll_retransmit = (ms) [5, 10, 15, 20,... 250, 300, 350, ... 500] + timer_poll_retransmit = 80; + + # timer_reordering = (ms) [0,5, ... 100, 110, 120, ... ,200] + timer_reordering = 35; + + # timer_reordering = (ms) [0,5, ... 250, 300, 350, ... ,500] + timer_status_prohibit = 0; + + # poll_pdu = [4, 8, 16, 32 , 64, 128, 256, infinity(>10000)] + poll_pdu = 4; + + # poll_byte = (kB) [25,50,75,100,125,250,375,500,750,1000,1250,1500,2000,3000,infinity(>10000)] + poll_byte = 99999; + + # max_retx_threshold = [1, 2, 3, 4 , 6, 8, 16, 32] + max_retx_threshold = 4; + } + + # ------- SCTP definitions + SCTP : + { + # Number of streams to use in input/output + SCTP_INSTREAMS = 2; + SCTP_OUTSTREAMS = 2; + }; + + ////////// MME parameters: + mme_ip_address = ( { ipv4 = "192.168.13.11"; + ipv6 = "192:168:30::17"; + active = "yes"; + preference = "ipv4"; + } + ); + + NETWORK_INTERFACES : + { + ENB_INTERFACE_NAME_FOR_S1_MME = "eth0"; + ENB_IPV4_ADDRESS_FOR_S1_MME = "192.168.13.10/24"; + + ENB_INTERFACE_NAME_FOR_S1U = "eth0"; + ENB_IPV4_ADDRESS_FOR_S1U = "192.168.13.10/24"; + ENB_PORT_FOR_S1U = 2152; # Spec 2152 + }; + + log_config : + { + global_log_level ="info"; + global_log_verbosity ="medium"; + hw_log_level ="info"; + hw_log_verbosity ="medium"; + phy_log_level ="info"; + phy_log_verbosity ="medium"; + mac_log_level ="info"; + mac_log_verbosity ="high"; + rlc_log_level ="info"; + rlc_log_verbosity ="medium"; + pdcp_log_level ="info"; + pdcp_log_verbosity ="medium"; + rrc_log_level ="info"; + rrc_log_verbosity ="medium"; + }; + + } +); diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.bladerfx40.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.bladerfx40.conf index bdbb46a98b40fc7e3c272b116b3f1514fab20cec..5c53803c4dd4d9fe9fd822df0b98f6b7c104e44e 100644 --- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.bladerfx40.conf +++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.bladerfx40.conf @@ -17,7 +17,7 @@ eNBs = mobile_country_code = "208"; - mobile_network_code = "92"; + mobile_network_code = "93"; ////////// Physical parameters: @@ -35,8 +35,8 @@ eNBs = Nid_cell_mbsfn = 0; nb_antennas_tx = 1; nb_antennas_rx = 1; - tx_gain = 20; - rx_gain = 20; + tx_gain = 60; + rx_gain = 120; prach_root = 0; prach_config_index = 0; prach_high_speed = "DISABLE"; @@ -46,7 +46,7 @@ eNBs = pucch_nRB_CQI = 1; pucch_nCS_AN = 0; pucch_n1_AN = 32; - pdsch_referenceSignalPower = -26; + pdsch_referenceSignalPower = -29; pdsch_p_b = 0; pusch_n_SB = 1; pusch_enable64QAM = "DISABLE"; @@ -132,7 +132,7 @@ eNBs = }; ////////// MME parameters: - mme_ip_address = ( { ipv4 = "192.168.13.11"; + mme_ip_address = ( { ipv4 = "192.168.12.11"; ipv6 = "192:168:30::17"; active = "yes"; preference = "ipv4"; @@ -142,10 +142,10 @@ eNBs = NETWORK_INTERFACES : { ENB_INTERFACE_NAME_FOR_S1_MME = "eth0"; - ENB_IPV4_ADDRESS_FOR_S1_MME = "192.168.13.10/24"; + ENB_IPV4_ADDRESS_FOR_S1_MME = "192.168.12.212/24"; ENB_INTERFACE_NAME_FOR_S1U = "eth0"; - ENB_IPV4_ADDRESS_FOR_S1U = "192.168.13.10/24"; + ENB_IPV4_ADDRESS_FOR_S1U = "192.168.12.212/24"; ENB_PORT_FOR_S1U = 2152; # Spec 2152 }; diff --git a/targets/RT/USER/lte-softmodem.c b/targets/RT/USER/lte-softmodem.c index 3fde0de43c29ef2769d8de577959c6d1b684f37a..0b651ccb8df2671f18f4c2837c1988ea1bd5ee7c 100644 --- a/targets/RT/USER/lte-softmodem.c +++ b/targets/RT/USER/lte-softmodem.c @@ -951,7 +951,7 @@ void do_OFDM_mod_rt(int subframe,PHY_VARS_eNB *phy_vars_eNB) ((short*)&phy_vars_eNB->lte_eNB_common_vars.txdata[0][aa][tx_offset])[0]= #ifdef EXMIMO ((short*)dummy_tx_b)[2*i]<<4; -#elif OAI_BLADRF +#elif OAI_BLADERF ((short*)dummy_tx_b)[2*i]; #else ((short*)dummy_tx_b)[2*i]<<4; @@ -959,7 +959,7 @@ void do_OFDM_mod_rt(int subframe,PHY_VARS_eNB *phy_vars_eNB) ((short*)&phy_vars_eNB->lte_eNB_common_vars.txdata[0][aa][tx_offset])[1]= #ifdef EXMIMO ((short*)dummy_tx_b)[2*i+1]<<4; -#elif OAI_BLADRF +#elif OAI_BLADERF ((short*)dummy_tx_b)[2*i+1]; #else ((short*)dummy_tx_b)[2*i+1]<<4; @@ -1017,6 +1017,7 @@ static void* eNB_thread_tx( void* param ) eNB_proc_t *proc = (eNB_proc_t*)param; FILE *tx_time_file; char tx_time_name[101]; + if (opp_enabled == 1) { snprintf(tx_time_name, 100,"/tmp/%s_tx_time_thread_sf_%d", "eNB", proc->subframe); tx_time_file = fopen(tx_time_name,"w"); @@ -1156,7 +1157,20 @@ static void* eNB_thread_tx( void* param ) } do_OFDM_mod_rt( proc->subframe_tx, PHY_vars_eNB_g[0][proc->CC_id] ); - + /* + short *txdata = (short*)&PHY_vars_eNB_g[0][proc->CC_id]->lte_eNB_common_vars.txdata[0][0][proc->subframe_tx*PHY_vars_eNB_g[0][proc->CC_id]->lte_frame_parms.samples_per_tti]; + int i; + for (i=0;i<7680*2;i+=8) { + txdata[i] = 2047; + txdata[i+1] = 0; + txdata[i+2] = 0; + txdata[i+3] = 2047; + txdata[i+4] = -2047; + txdata[i+5] = 0; + txdata[i+6] = 0; + txdata[i+7] = -2047; + } + */ if (pthread_mutex_lock(&proc->mutex_tx) != 0) { LOG_E( PHY, "[SCHED][eNB] error locking mutex for eNB TX proc %d\n", proc->subframe ); exit_fun("nothing to add"); @@ -1838,7 +1852,8 @@ static void* eNB_thread( void* arg ) rt_sleep_ns(1000000); #endif - if ((tx_launched == 0) && + if ((frame>50) && + (tx_launched == 0) && (rx_pos >= (((2*hw_subframe)+1)*PHY_vars_eNB_g[0][0]->lte_frame_parms.samples_per_tti>>1))) { tx_launched = 1; @@ -1907,52 +1922,53 @@ static void* eNB_thread( void* arg ) #else int sf = hw_subframe; #endif - - for (int CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) { + if (frame>50) { + for (int CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) { #ifdef EXMIMO - - if (pthread_mutex_lock(&PHY_vars_eNB_g[0][CC_id]->proc[sf].mutex_tx) != 0) { - LOG_E(PHY,"[eNB] ERROR pthread_mutex_lock for eNB TX thread %d (IC %d)\n",sf,PHY_vars_eNB_g[0][CC_id]->proc[sf].instance_cnt_tx); - } else { - // LOG_I(PHY,"[eNB] Waking up eNB process %d (IC %d)\n",sf,PHY_vars_eNB_g[0][CC_id]->proc[sf].instance_cnt); - PHY_vars_eNB_g[0][CC_id]->proc[sf].instance_cnt_tx++; - pthread_mutex_unlock(&PHY_vars_eNB_g[0][CC_id]->proc[sf].mutex_tx); - - if (PHY_vars_eNB_g[0][CC_id]->proc[sf].instance_cnt_tx == 0) { - if (pthread_cond_signal(&PHY_vars_eNB_g[0][CC_id]->proc[sf].cond_tx) != 0) { - LOG_E(PHY,"[eNB] ERROR pthread_cond_signal for eNB TX thread %d\n",sf); + + if (pthread_mutex_lock(&PHY_vars_eNB_g[0][CC_id]->proc[sf].mutex_tx) != 0) { + LOG_E(PHY,"[eNB] ERROR pthread_mutex_lock for eNB TX thread %d (IC %d)\n",sf,PHY_vars_eNB_g[0][CC_id]->proc[sf].instance_cnt_tx); + } else { + // LOG_I(PHY,"[eNB] Waking up eNB process %d (IC %d)\n",sf,PHY_vars_eNB_g[0][CC_id]->proc[sf].instance_cnt); + PHY_vars_eNB_g[0][CC_id]->proc[sf].instance_cnt_tx++; + pthread_mutex_unlock(&PHY_vars_eNB_g[0][CC_id]->proc[sf].mutex_tx); + + if (PHY_vars_eNB_g[0][CC_id]->proc[sf].instance_cnt_tx == 0) { + if (pthread_cond_signal(&PHY_vars_eNB_g[0][CC_id]->proc[sf].cond_tx) != 0) { + LOG_E(PHY,"[eNB] ERROR pthread_cond_signal for eNB TX thread %d\n",sf); + exit_fun("nothing to add"); + } + } else { + LOG_W(PHY,"[eNB] Frame %d, eNB TX thread %d busy!!\n",PHY_vars_eNB_g[0][CC_id]->proc[sf].frame_tx,sf); exit_fun("nothing to add"); - } - } else { - LOG_W(PHY,"[eNB] Frame %d, eNB TX thread %d busy!!\n",PHY_vars_eNB_g[0][CC_id]->proc[sf].frame_tx,sf); - exit_fun("nothing to add"); - } - } - + } + } + #endif - if (pthread_mutex_lock(&PHY_vars_eNB_g[0][CC_id]->proc[sf].mutex_rx) != 0) { - LOG_E( PHY, "[eNB] ERROR pthread_mutex_lock for eNB RX thread %d (IC %d)\n", sf, PHY_vars_eNB_g[0][CC_id]->proc[sf].instance_cnt_rx ); - exit_fun( "error locking mutex_rx" ); - break; - } - - int cnt_rx = ++PHY_vars_eNB_g[0][CC_id]->proc[sf].instance_cnt_rx; - - pthread_mutex_unlock( &PHY_vars_eNB_g[0][CC_id]->proc[sf].mutex_rx ); - - if (cnt_rx == 0) { - // the thread was presumably waiting where it should and can now be woken up - if (pthread_cond_signal(&PHY_vars_eNB_g[0][CC_id]->proc[sf].cond_rx) != 0) { - LOG_E( PHY, "[eNB] ERROR pthread_cond_signal for eNB RX thread %d\n", sf ); - exit_fun( "ERROR pthread_cond_signal" ); - break; - } - } else { - LOG_W( PHY, "[eNB] Frame %d, eNB RX thread %d busy!! instance_cnt %d CC_id %d\n", PHY_vars_eNB_g[0][CC_id]->proc[sf].frame_rx, sf, PHY_vars_eNB_g[0][CC_id]->proc[sf].instance_cnt_rx, CC_id ); - exit_fun( "RX thread busy" ); - break; - } + if (pthread_mutex_lock(&PHY_vars_eNB_g[0][CC_id]->proc[sf].mutex_rx) != 0) { + LOG_E( PHY, "[eNB] ERROR pthread_mutex_lock for eNB RX thread %d (IC %d)\n", sf, PHY_vars_eNB_g[0][CC_id]->proc[sf].instance_cnt_rx ); + exit_fun( "error locking mutex_rx" ); + break; + } + + int cnt_rx = ++PHY_vars_eNB_g[0][CC_id]->proc[sf].instance_cnt_rx; + + pthread_mutex_unlock( &PHY_vars_eNB_g[0][CC_id]->proc[sf].mutex_rx ); + + if (cnt_rx == 0) { + // the thread was presumably waiting where it should and can now be woken up + if (pthread_cond_signal(&PHY_vars_eNB_g[0][CC_id]->proc[sf].cond_rx) != 0) { + LOG_E( PHY, "[eNB] ERROR pthread_cond_signal for eNB RX thread %d\n", sf ); + exit_fun( "ERROR pthread_cond_signal" ); + break; + } + } else { + LOG_W( PHY, "[eNB] Frame %d, eNB RX thread %d busy!! instance_cnt %d CC_id %d\n", PHY_vars_eNB_g[0][CC_id]->proc[sf].frame_rx, sf, PHY_vars_eNB_g[0][CC_id]->proc[sf].instance_cnt_rx, CC_id ); + exit_fun( "RX thread busy" ); + break; + } + } } } @@ -2902,9 +2918,8 @@ int main( int argc, char **argv ) } else if (frame_parms[0]->N_RB_DL == 25) { openair0_cfg[card].sample_rate=7.68e6; openair0_cfg[card].samples_per_frame = 76800; - openair0_cfg[card].tx_bw = 5e6; - openair0_cfg[card].rx_bw = 5e6; - + openair0_cfg[card].tx_bw = 2.5e6; + openair0_cfg[card].rx_bw = 2.5e6; } else if (frame_parms[0]->N_RB_DL == 6) { openair0_cfg[card].sample_rate=1.92e6; openair0_cfg[card].samples_per_frame = 19200; @@ -2973,7 +2988,7 @@ int main( int argc, char **argv ) openair0_cfg[card].rx_gain[i] = PHY_vars_eNB_g[0][0]->rx_total_gain_eNB_dB; } else { - openair0_cfg[card].rx_gain[i] = PHY_vars_UE_g[0][0]->rx_total_gain_dB;// - USRP_GAIN_OFFSET; // calibrated for USRP B210 @ 2.6 GHz, 30.72 MS/s + openair0_cfg[card].rx_gain[i] = PHY_vars_UE_g[0][0]->rx_total_gain_dB; } #if 0 // UHD 3.8 diff --git a/targets/RT/USER/lte-ue.c b/targets/RT/USER/lte-ue.c index 4f722a54cf50fe3d6eedde42ff4c98ec399dec2d..6293ad4264c609d2821c67dfb626ef6b7e647c05 100644 --- a/targets/RT/USER/lte-ue.c +++ b/targets/RT/USER/lte-ue.c @@ -401,7 +401,7 @@ static void *UE_thread_synch(void *arg) case pbch: - + LOG_I(PHY,"[UE thread Synch] Running Initial Synch\n"); if (initial_sync( UE, UE->mode ) == 0) { hw_slot_offset = (UE->rx_offset<<1) / UE->lte_frame_parms.samples_per_tti; @@ -521,10 +521,6 @@ static void *UE_thread_synch(void *arg) for (i=0; i<openair0_cfg[card].rx_num_channels; i++) { openair0_cfg[card].rx_freq[i] = downlink_frequency[card][i]+freq_offset; openair0_cfg[card].tx_freq[i] = downlink_frequency[card][i]+uplink_frequency_offset[card][i]+freq_offset; -#ifdef OAI_USRP - openair0_cfg[card].rx_gain[i] = UE->rx_total_gain_dB;//-USRP_GAIN_OFFSET; - - #ifndef EXMIMO openair0.trx_set_freq_func(&openair0,&openair0_cfg[0],0); @@ -532,6 +528,12 @@ static void *UE_thread_synch(void *arg) openair0_set_frequencies(&openair0,&openair0_cfg[0],0); #endif + +#ifdef OAI_USRP + openair0_cfg[card].rx_gain[i] = UE->rx_total_gain_dB;//-USRP_GAIN_OFFSET; + + + switch(UE->lte_frame_parms.N_RB_DL) { case 6: openair0_cfg[card].rx_gain[i] -= 12; @@ -1105,10 +1107,10 @@ void *UE_thread(void *arg) for (int i=0; i<UE->lte_frame_parms.nb_antennas_rx; i++) rxp[i] = (dummy_dump==0) ? (void*)&rxdata[i][rxpos] : (void*)dummy[i]; - /* - if (dummy_dump == 0) - printf("writing %d samples to %d (first_rx %d)\n",spp - ((first_rx==1) ? rx_off_diff : 0),rxpos,first_rx); - */ + + /* if (dummy_dump == 0) + printf("writing %d samples to %d (first_rx %d)\n",spp - ((first_rx==1) ? rx_off_diff : 0),rxpos,first_rx);*/ + if (UE->mode != loop_through_memory) { rxs = openair0.trx_read_func(&openair0, ×tamp, @@ -1117,8 +1119,11 @@ void *UE_thread(void *arg) UE->lte_frame_parms.nb_antennas_rx); if (rxs != (spp- ((first_rx==1) ? rx_off_diff : 0))) { - exit_fun("problem in rx"); - return &UE_thread_retval; + printf("rx error: asked %d got %d ",spp - ((first_rx==1) ? rx_off_diff : 0),rxs); + if (UE->is_synchronized == 1) { + exit_fun("problem in rx"); + return &UE_thread_retval; + } } } @@ -1335,6 +1340,7 @@ void *UE_thread(void *arg) #ifndef USRP_DEBUG if (UE->mode != loop_through_memory) { + LOG_I(PHY,"Resynchronizing RX by %d samples\n",UE->rx_offset); rxs = openair0.trx_read_func(&openair0, ×tamp, (void**)rxdata,