diff --git a/Transceiver52M/ms/bladerf_specific.h b/Transceiver52M/ms/bladerf_specific.h index 2ed3766f..d31ea295 100644 --- a/Transceiver52M/ms/bladerf_specific.h +++ b/Transceiver52M/ms/bladerf_specific.h @@ -198,6 +198,7 @@ struct blade_hw { using tx_buf_q_type = spsc_cond_timeout; const unsigned int rxFullScale, txFullScale; const int rxtxdelay; + bool use_agc; static std::atomic stop_lower_threads_flag; double rxfreq_cache, txfreq_cache; @@ -230,7 +231,7 @@ struct blade_hw { close_device(); } blade_hw(struct mssdr_cfg *cfgdata) - : rxFullScale(2047), txFullScale(2047), rxtxdelay(-60), rxfreq_cache(0), + : rxFullScale(2047), txFullScale(2047), rxtxdelay(-60), use_agc(cfgdata->use_agc), rxfreq_cache(0), txfreq_cache(0) { cfg.tx_freq = cfgdata->overrides.ul_freq; @@ -305,7 +306,8 @@ struct blade_hw { blade_check(bladerf_set_bandwidth, dev, BLADERF_CHANNEL_TX(0), (bladerf_bandwidth)cfg.bandwidth, (bladerf_bandwidth *)NULL); - blade_check(bladerf_set_gain_mode, dev, BLADERF_CHANNEL_RX(0), BLADERF_GAIN_MGC); + blade_check(bladerf_set_gain_mode, dev, BLADERF_CHANNEL_RX(0), + use_agc ? BLADERF_GAIN_AUTOMATIC : BLADERF_GAIN_MGC); setRxGain(cfg.rxgain, 0); setTxGain(cfg.txgain, 0); usleep(1000); diff --git a/Transceiver52M/ms/ms.h b/Transceiver52M/ms/ms.h index c972f0a8..e088f73f 100644 --- a/Transceiver52M/ms/ms.h +++ b/Transceiver52M/ms/ms.h @@ -239,7 +239,6 @@ struct ms_trx : public BASET, public sched_hw_info { unsigned int mTSC; unsigned int mBSIC; int timing_advance; - bool do_auto_gain; bool use_va; pthread_t lower_rx_task; @@ -278,7 +277,7 @@ struct ms_trx : public BASET, public sched_hw_info { void maybe_update_gain(one_burst &brst); ms_trx(struct mssdr_cfg *cfgdata) - : BASET(cfgdata), mTSC(0), mBSIC(0), timing_advance(0), do_auto_gain(false), use_va(cfgdata->use_va), rxqueue(), + : BASET(cfgdata), mTSC(0), mBSIC(0), timing_advance(0), use_va(cfgdata->use_va), rxqueue(), first_sch_buf(new blade_sample_type[SCH_LEN_SPS]), burst_copy_buffer(new blade_sample_type[ONE_TS_BURST_LEN]), first_sch_buf_rcv_ts(0), rcv_done{ false }, sch_thread_done{ false }, upper_is_ready(false) diff --git a/Transceiver52M/ms/ms_rx_lower.cpp b/Transceiver52M/ms/ms_rx_lower.cpp index f7788827..b169dd82 100644 --- a/Transceiver52M/ms/ms_rx_lower.cpp +++ b/Transceiver52M/ms/ms_rx_lower.cpp @@ -144,7 +144,7 @@ bool ms_trx::handle_sch_or_nb() while (upper_is_ready && !rxqueue.spsc_push(&brst)) ; - if (do_auto_gain) + if (!use_agc) maybe_update_gain(brst); return false; diff --git a/Transceiver52M/ms/ms_upper.cpp b/Transceiver52M/ms/ms_upper.cpp index e6bc0515..f505eb60 100644 --- a/Transceiver52M/ms/ms_upper.cpp +++ b/Transceiver52M/ms/ms_upper.cpp @@ -160,7 +160,7 @@ static void *static_alloc(size_t newSize) bool upper_trx::pullRadioVector(GSM::Time &wTime, int &RSSI, int &timingOffset) { - float pow, avg = 1.0; + // float pow, avg = 1.0; const auto zero_pad_len = 40; // give the VA some runway for misaligned bursts const auto workbuf_size = zero_pad_len + ONE_TS_BURST_LEN + zero_pad_len; static complex workbuf[workbuf_size]; @@ -184,8 +184,11 @@ bool upper_trx::pullRadioVector(GSM::Time &wTime, int &RSSI, int &timingOffset) trxcon_phyif_rtr_ind i = { static_cast(wTime.FN()), static_cast(wTime.TN()) }; trxcon_phyif_rtr_rsp r = {}; trxcon_phyif_handle_rtr_ind(g_trxcon, &i, &r); - if (!(r.flags & TRXCON_PHYIF_RTR_F_ACTIVE)) + if (!(r.flags & TRXCON_PHYIF_RTR_F_ACTIVE)) { + bladerf_get_rfic_rssi(dev, 0, &meas_p, &meas_rssi); + // std::cerr << "G : \x1B[31m rx fail \033[0m @:" << meas_rssi << std::endl; return false; + } if (is_fcch) { // return trash @@ -203,13 +206,13 @@ bool upper_trx::pullRadioVector(GSM::Time &wTime, int &RSSI, int &timingOffset) if (use_va) { convert_and_scale(ss, e.burst, ONE_TS_BURST_LEN * 2, 1.f / float(rxFullScale)); - pow = energyDetect(sv, 20 * 4 /*sps*/); - if (pow < -1) { - LOG(ALERT) << "Received empty burst"; - return false; - } + // pow = energyDetect(sv, 20 * 4 /*sps*/); + // if (pow < -1) { + // LOG(ALERT) << "Received empty burst"; + // return false; + // } - avg = sqrt(pow); + // avg = sqrt(pow); { float ncmax; std::complex chan_imp_resp[CHAN_IMP_RESP_LENGTH * d_OSR]; @@ -238,14 +241,14 @@ bool upper_trx::pullRadioVector(GSM::Time &wTime, int &RSSI, int &timingOffset) // lower layer sch detection offset, easy to verify by just printing the detected value using both the va+sigproc code. convert_and_scale(ss + 16, e.burst, ONE_TS_BURST_LEN * 2, 15); + // pow = energyDetect(sv, 20 * 4 /*sps*/); + // if (pow < -1) { + // LOG(ALERT) << "Received empty burst"; + // return false; + // } - pow = energyDetect(sv, 20 * 4 /*sps*/); - if (pow < -1) { - LOG(ALERT) << "Received empty burst"; - return false; - } + // avg = sqrt(pow); - avg = sqrt(pow); /* Detect normal or RACH bursts */ CorrType type = CorrType::TSC; struct estim_burst_params ebp; @@ -268,7 +271,7 @@ bool upper_trx::pullRadioVector(GSM::Time &wTime, int &RSSI, int &timingOffset) } delete bits; } - RSSI = (int)floor(20.0 * log10(rxFullScale / avg)); + RSSI = meas_rssi; // (int)floor(20.0 * log10(rxFullScale / avg)); // FIXME: properly handle offset, sch/nb alignment diff? handled by lower anyway... timingOffset = (int)round(0); diff --git a/Transceiver52M/ms/mssdr_vty.c b/Transceiver52M/ms/mssdr_vty.c index eba34649..82f4f31e 100644 --- a/Transceiver52M/ms/mssdr_vty.c +++ b/Transceiver52M/ms/mssdr_vty.c @@ -74,6 +74,7 @@ struct mssdr_ctx *vty_mssdr_ctx_alloc(void *talloc_ctx) { struct mssdr_ctx *trx = talloc_zero(talloc_ctx, struct mssdr_ctx); trx->cfg.use_va = true; + trx->cfg.use_agc = true; return trx; } @@ -98,6 +99,8 @@ static void mssdr_dump_vty(struct vty *vty, struct mssdr_ctx *trx) vty_out(vty, " ul-gain-override %f%s", trx->cfg.overrides.ul_gain, VTY_NEWLINE); if (trx->cfg.use_va) vty_out(vty, " viterbi-eq %s%s", trx->cfg.use_va ? "enable" : "disable", VTY_NEWLINE); + if (trx->cfg.use_agc) + vty_out(vty, " rx-agc %s%s", trx->cfg.use_agc ? "enable" : "disable", VTY_NEWLINE); } static int config_write_mssdr(struct vty *vty) @@ -115,6 +118,8 @@ static int config_write_mssdr(struct vty *vty) vty_out(vty, " ul-gain-override %f%s", trx->cfg.overrides.ul_gain, VTY_NEWLINE); if (trx->cfg.use_va) vty_out(vty, " viterbi-eq %s%s", trx->cfg.use_va ? "enable" : "disable", VTY_NEWLINE); + if (trx->cfg.use_agc) + vty_out(vty, " rx-agc %s%s", trx->cfg.use_agc ? "enable" : "disable", VTY_NEWLINE); return CMD_SUCCESS; } @@ -216,6 +221,25 @@ DEFUN_ATTR(cfg_use_viterbi, cfg_use_viterbi_cmd, return CMD_SUCCESS; } +DEFUN_ATTR(cfg_use_agc, cfg_use_agc_cmd, + "rx-agc (disable|enable)", + "Use the transceiver rx agc (default=enable)\n" + "Disable agc\n" + "Enable agc\n", + CMD_ATTR_HIDDEN) +{ + struct mssdr_ctx *trx = mssdr_from_vty(vty); + + if (strcmp("disable", argv[0]) == 0) + trx->cfg.use_agc = false; + else if (strcmp("enable", argv[0]) == 0) + trx->cfg.use_agc = true; + else + return CMD_WARNING; + + return CMD_SUCCESS; +} + static struct cmd_node mssdr_node = { MSSDR_NODE, "%s(config-mssdr)# ", @@ -234,6 +258,7 @@ int mssdr_vty_init(struct mssdr_ctx *trx) install_element(MSSDR_NODE, &cfg_ul_gain_override_cmd); install_element(MSSDR_NODE, &cfg_dl_gain_override_cmd); install_element(MSSDR_NODE, &cfg_use_viterbi_cmd); + install_element(MSSDR_NODE, &cfg_use_agc_cmd); return 0; } diff --git a/Transceiver52M/ms/mssdr_vty.h b/Transceiver52M/ms/mssdr_vty.h index 4d8f42dd..63757b7a 100644 --- a/Transceiver52M/ms/mssdr_vty.h +++ b/Transceiver52M/ms/mssdr_vty.h @@ -32,6 +32,7 @@ struct mssdr_cfg { double dl_gain; } overrides; bool use_va; + bool use_agc; }; struct mssdr_ctx { diff --git a/doc/examples/osmo-trx-ms-blade/mssdr.cfg b/doc/examples/osmo-trx-ms-blade/mssdr.cfg index 38eee306..01d716c4 100644 --- a/doc/examples/osmo-trx-ms-blade/mssdr.cfg +++ b/doc/examples/osmo-trx-ms-blade/mssdr.cfg @@ -19,4 +19,5 @@ mssdr ul-gain-override 30 dl-gain-override 30 viterbi-eq enable + rx-agc enable