ms: add agc
Change-Id: I914cf20f00092e35283144c98fbffb1ab8bfc8b0
This commit is contained in:
parent
115b0099dd
commit
b440b7024c
|
@ -198,6 +198,7 @@ struct blade_hw {
|
||||||
using tx_buf_q_type = spsc_cond_timeout<BLADE_NUM_BUFFERS, dev_buf_t *, true, false>;
|
using tx_buf_q_type = spsc_cond_timeout<BLADE_NUM_BUFFERS, dev_buf_t *, true, false>;
|
||||||
const unsigned int rxFullScale, txFullScale;
|
const unsigned int rxFullScale, txFullScale;
|
||||||
const int rxtxdelay;
|
const int rxtxdelay;
|
||||||
|
bool use_agc;
|
||||||
|
|
||||||
static std::atomic<bool> stop_lower_threads_flag;
|
static std::atomic<bool> stop_lower_threads_flag;
|
||||||
double rxfreq_cache, txfreq_cache;
|
double rxfreq_cache, txfreq_cache;
|
||||||
|
@ -230,7 +231,7 @@ struct blade_hw {
|
||||||
close_device();
|
close_device();
|
||||||
}
|
}
|
||||||
blade_hw(struct mssdr_cfg *cfgdata)
|
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)
|
txfreq_cache(0)
|
||||||
{
|
{
|
||||||
cfg.tx_freq = cfgdata->overrides.ul_freq;
|
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,
|
blade_check(bladerf_set_bandwidth, dev, BLADERF_CHANNEL_TX(0), (bladerf_bandwidth)cfg.bandwidth,
|
||||||
(bladerf_bandwidth *)NULL);
|
(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);
|
setRxGain(cfg.rxgain, 0);
|
||||||
setTxGain(cfg.txgain, 0);
|
setTxGain(cfg.txgain, 0);
|
||||||
usleep(1000);
|
usleep(1000);
|
||||||
|
|
|
@ -239,7 +239,6 @@ struct ms_trx : public BASET, public sched_hw_info {
|
||||||
unsigned int mTSC;
|
unsigned int mTSC;
|
||||||
unsigned int mBSIC;
|
unsigned int mBSIC;
|
||||||
int timing_advance;
|
int timing_advance;
|
||||||
bool do_auto_gain;
|
|
||||||
bool use_va;
|
bool use_va;
|
||||||
|
|
||||||
pthread_t lower_rx_task;
|
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);
|
void maybe_update_gain(one_burst &brst);
|
||||||
|
|
||||||
ms_trx(struct mssdr_cfg *cfgdata)
|
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]),
|
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),
|
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)
|
rcv_done{ false }, sch_thread_done{ false }, upper_is_ready(false)
|
||||||
|
|
|
@ -144,7 +144,7 @@ bool ms_trx::handle_sch_or_nb()
|
||||||
while (upper_is_ready && !rxqueue.spsc_push(&brst))
|
while (upper_is_ready && !rxqueue.spsc_push(&brst))
|
||||||
;
|
;
|
||||||
|
|
||||||
if (do_auto_gain)
|
if (!use_agc)
|
||||||
maybe_update_gain(brst);
|
maybe_update_gain(brst);
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
|
|
|
@ -160,7 +160,7 @@ static void *static_alloc(size_t newSize)
|
||||||
|
|
||||||
bool upper_trx::pullRadioVector(GSM::Time &wTime, int &RSSI, int &timingOffset)
|
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 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;
|
const auto workbuf_size = zero_pad_len + ONE_TS_BURST_LEN + zero_pad_len;
|
||||||
static complex workbuf[workbuf_size];
|
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<uint32_t>(wTime.FN()), static_cast<uint8_t>(wTime.TN()) };
|
trxcon_phyif_rtr_ind i = { static_cast<uint32_t>(wTime.FN()), static_cast<uint8_t>(wTime.TN()) };
|
||||||
trxcon_phyif_rtr_rsp r = {};
|
trxcon_phyif_rtr_rsp r = {};
|
||||||
trxcon_phyif_handle_rtr_ind(g_trxcon, &i, &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;
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
if (is_fcch) {
|
if (is_fcch) {
|
||||||
// return trash
|
// return trash
|
||||||
|
@ -203,13 +206,13 @@ bool upper_trx::pullRadioVector(GSM::Time &wTime, int &RSSI, int &timingOffset)
|
||||||
if (use_va) {
|
if (use_va) {
|
||||||
convert_and_scale(ss, e.burst, ONE_TS_BURST_LEN * 2, 1.f / float(rxFullScale));
|
convert_and_scale(ss, e.burst, ONE_TS_BURST_LEN * 2, 1.f / float(rxFullScale));
|
||||||
|
|
||||||
pow = energyDetect(sv, 20 * 4 /*sps*/);
|
// pow = energyDetect(sv, 20 * 4 /*sps*/);
|
||||||
if (pow < -1) {
|
// if (pow < -1) {
|
||||||
LOG(ALERT) << "Received empty burst";
|
// LOG(ALERT) << "Received empty burst";
|
||||||
return false;
|
// return false;
|
||||||
}
|
// }
|
||||||
|
|
||||||
avg = sqrt(pow);
|
// avg = sqrt(pow);
|
||||||
{
|
{
|
||||||
float ncmax;
|
float ncmax;
|
||||||
std::complex<float> chan_imp_resp[CHAN_IMP_RESP_LENGTH * d_OSR];
|
std::complex<float> 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.
|
// 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);
|
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*/);
|
// avg = sqrt(pow);
|
||||||
if (pow < -1) {
|
|
||||||
LOG(ALERT) << "Received empty burst";
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
avg = sqrt(pow);
|
|
||||||
/* Detect normal or RACH bursts */
|
/* Detect normal or RACH bursts */
|
||||||
CorrType type = CorrType::TSC;
|
CorrType type = CorrType::TSC;
|
||||||
struct estim_burst_params ebp;
|
struct estim_burst_params ebp;
|
||||||
|
@ -268,7 +271,7 @@ bool upper_trx::pullRadioVector(GSM::Time &wTime, int &RSSI, int &timingOffset)
|
||||||
}
|
}
|
||||||
delete bits;
|
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...
|
// FIXME: properly handle offset, sch/nb alignment diff? handled by lower anyway...
|
||||||
timingOffset = (int)round(0);
|
timingOffset = (int)round(0);
|
||||||
|
|
||||||
|
|
|
@ -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);
|
struct mssdr_ctx *trx = talloc_zero(talloc_ctx, struct mssdr_ctx);
|
||||||
trx->cfg.use_va = true;
|
trx->cfg.use_va = true;
|
||||||
|
trx->cfg.use_agc = true;
|
||||||
return trx;
|
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);
|
vty_out(vty, " ul-gain-override %f%s", trx->cfg.overrides.ul_gain, VTY_NEWLINE);
|
||||||
if (trx->cfg.use_va)
|
if (trx->cfg.use_va)
|
||||||
vty_out(vty, " viterbi-eq %s%s", trx->cfg.use_va ? "enable" : "disable", VTY_NEWLINE);
|
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)
|
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);
|
vty_out(vty, " ul-gain-override %f%s", trx->cfg.overrides.ul_gain, VTY_NEWLINE);
|
||||||
if (trx->cfg.use_va)
|
if (trx->cfg.use_va)
|
||||||
vty_out(vty, " viterbi-eq %s%s", trx->cfg.use_va ? "enable" : "disable", VTY_NEWLINE);
|
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;
|
return CMD_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -216,6 +221,25 @@ DEFUN_ATTR(cfg_use_viterbi, cfg_use_viterbi_cmd,
|
||||||
return CMD_SUCCESS;
|
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 = {
|
static struct cmd_node mssdr_node = {
|
||||||
MSSDR_NODE,
|
MSSDR_NODE,
|
||||||
"%s(config-mssdr)# ",
|
"%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_ul_gain_override_cmd);
|
||||||
install_element(MSSDR_NODE, &cfg_dl_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_viterbi_cmd);
|
||||||
|
install_element(MSSDR_NODE, &cfg_use_agc_cmd);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -32,6 +32,7 @@ struct mssdr_cfg {
|
||||||
double dl_gain;
|
double dl_gain;
|
||||||
} overrides;
|
} overrides;
|
||||||
bool use_va;
|
bool use_va;
|
||||||
|
bool use_agc;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct mssdr_ctx {
|
struct mssdr_ctx {
|
||||||
|
|
|
@ -19,4 +19,5 @@ mssdr
|
||||||
ul-gain-override 30
|
ul-gain-override 30
|
||||||
dl-gain-override 30
|
dl-gain-override 30
|
||||||
viterbi-eq enable
|
viterbi-eq enable
|
||||||
|
rx-agc enable
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue