diff options
author | Holger Hans Peter Freyther <holger@moiji-mobile.com> | 2014-07-25 19:53:21 +0200 |
---|---|---|
committer | Holger Hans Peter Freyther <holger@moiji-mobile.com> | 2014-07-30 18:22:12 +0200 |
commit | eececf5fa96875e93d622299408423766c6e35d0 (patch) | |
tree | d74ed74db47e09c84b669fffbb7808784cf99824 /src | |
parent | bc24955e91f050e904851f589400eac4c3443917 (diff) |
sysmobts: Make it possible to slowly ramp up the output power
For systems with a bigger PA enabling the full output power at
once might draw more current than a power supply can provide. This
code will step up the output power in smaller steps to avoid this
situation.
Diffstat (limited to 'src')
-rw-r--r-- | src/osmo-bts-sysmo/main.c | 5 | ||||
-rw-r--r-- | src/osmo-bts-sysmo/oml.c | 18 | ||||
-rw-r--r-- | src/osmo-bts-sysmo/sysmobts_vty.c | 46 | ||||
-rw-r--r-- | src/osmo-bts-sysmo/utils.c | 87 | ||||
-rw-r--r-- | src/osmo-bts-sysmo/utils.h | 5 |
5 files changed, 150 insertions, 11 deletions
diff --git a/src/osmo-bts-sysmo/main.c b/src/osmo-bts-sysmo/main.c index bd11472b..fac45d9c 100644 --- a/src/osmo-bts-sysmo/main.c +++ b/src/osmo-bts-sysmo/main.c @@ -84,6 +84,11 @@ int bts_model_init(struct gsm_bts *bts) } bts->c0->nominal_power = rc; + /* Initial values for the power adjustments */ + bts->c0->pa.max_initial_power = 23; + bts->c0->pa.step_size = 2; + bts->c0->pa.step_interval = 1; + bts_model_vty_init(bts); return 0; diff --git a/src/osmo-bts-sysmo/oml.c b/src/osmo-bts-sysmo/oml.c index 4ebf6646..e5f9260b 100644 --- a/src/osmo-bts-sysmo/oml.c +++ b/src/osmo-bts-sysmo/oml.c @@ -271,6 +271,9 @@ static int trx_init_compl_cb(struct gsm_bts_trx *trx, struct msgb *l1_msg) trx_rf_lock(trx, 1, trx_mute_on_init_cb); #endif + /* Begin to ramp up the power */ + sysmobts_pa_maybe_step(trx); + return opstart_compl(&trx->mo, l1_msg); } @@ -323,7 +326,10 @@ static int trx_init(struct gsm_bts_trx *trx) dev_par->u16BcchArfcn = trx->bts->c0->arfcn; dev_par->u8NbTsc = trx->bts->bsic & 7; dev_par->fRxPowerLevel = fl1h->ul_power_target; - dev_par->fTxPowerLevel = sysmobts_get_power_trx(trx); + + /* initialize the power */ + sysmobts_pa_pwr_init(trx); + dev_par->fTxPowerLevel = trx->pa.current_power; LOGP(DL1C, LOGL_NOTICE, "Init TRX (ARFCN %u, TSC %u, RxPower % 2f dBm, " "TxPower % 2.2f dBm\n", dev_par->u16Arfcn, dev_par->u8NbTsc, dev_par->fRxPowerLevel, dev_par->fTxPowerLevel); @@ -1068,8 +1074,12 @@ static int chmod_txpower_compl_cb(struct gsm_bts_trx *trx, struct msgb *l1_msg) LOGPC(DL1C, LOGL_INFO, "setTxPower %f dBm\n", cc->cfgParams.setTxPowerLevel.fTxPowerLevel); + trx->pa.current_power = cc->cfgParams.setTxPowerLevel.fTxPowerLevel; msgb_free(l1_msg); + /* Schedule the next step up */ + sysmobts_pa_maybe_step(trx); + return 0; } @@ -1543,8 +1553,10 @@ int bts_model_apply_oml(struct gsm_bts *bts, struct msgb *msg, struct femtol1_hdl *fl1h = trx_femtol1_hdl(trx); /* Did we go through MphInit yet? If yes fire and forget */ - if (fl1h->hLayer1) - l1if_set_txpower(fl1h, sysmobts_get_power_trx(trx)); + if (fl1h->hLayer1) { + sysmobts_pa_pwr_init(trx); + l1if_set_txpower(fl1h, (float) trx->pa.current_power); + } } /* FIXME: we actaully need to send a ACK or NACK for the OML message */ diff --git a/src/osmo-bts-sysmo/sysmobts_vty.c b/src/osmo-bts-sysmo/sysmobts_vty.c index 690ffed9..ed90a234 100644 --- a/src/osmo-bts-sysmo/sysmobts_vty.c +++ b/src/osmo-bts-sysmo/sysmobts_vty.c @@ -254,6 +254,39 @@ DEFUN(cfg_trx_nominal_power, cfg_trx_nominal_power_cmd, return CMD_SUCCESS; } +#define PA_STR "Power-Amplifier settings" +DEFUN(cfg_trx_pa_max_initial, cfg_trx_pa_max_initial_cmd, + "power-amplifier max-initial <0-100>", + PA_STR "Maximum initial power\n" + "Value in dBm\n") +{ + struct gsm_bts_trx *trx = vty->index; + + trx->pa.max_initial_power = atoi(argv[0]); + return CMD_SUCCESS; +} + +DEFUN(cfg_trx_pa_step_size, cfg_trx_pa_step_size_cmd, + "power-amplifier step-size <1-100>", + PA_STR "Power increase by step\n" + "Step size in dB\n") +{ + struct gsm_bts_trx *trx = vty->index; + + trx->pa.step_size = atoi(argv[0]); + return CMD_SUCCESS; +} + +DEFUN(cfg_trx_pa_step_interval, cfg_trx_pa_step_interval_cmd, + "power-amplifier step-interval <1-100>", + PA_STR "Power increase by step\n" + "Step time in seconds\n") +{ + struct gsm_bts_trx *trx = vty->index; + + trx->pa.step_interval = atoi(argv[0]); + return CMD_SUCCESS; +} /* runtime */ @@ -421,7 +454,9 @@ DEFUN(set_tx_power, set_tx_power_cmd, struct gsm_bts_trx *trx = gsm_bts_trx_num(vty_bts, trx_nr); struct femtol1_hdl *fl1h = trx_femtol1_hdl(trx); - l1if_set_txpower(fl1h, (float) power); + trx->pa.current_power = power; + osmo_timer_del(&trx->pa.step_timer); + l1if_set_txpower(fl1h, (float) trx->pa.current_power); return CMD_SUCCESS; } @@ -551,6 +586,12 @@ void bts_model_config_write_trx(struct vty *vty, struct gsm_bts_trx *trx) if (trx->nominal_power != sysmobts_get_nominal_power(trx)) vty_out(vty, " nominal-tx-power %d%s", trx->nominal_power, VTY_NEWLINE); + vty_out(vty, " power-amplifier max-initial %d%s", + trx->pa.max_initial_power, VTY_NEWLINE); + vty_out(vty, " power-amplifier step-size %d%s", + trx->pa.step_size, VTY_NEWLINE); + vty_out(vty, " power-amplifier step-interval %d%s", + trx->pa.step_interval, VTY_NEWLINE); for (i = 0; i < 32; i++) { if (fl1h->gsmtap_sapi_mask & (1 << i)) { @@ -622,6 +663,9 @@ int bts_model_vty_init(struct gsm_bts *bts) install_element(TRX_NODE, &cfg_trx_min_qual_rach_cmd); install_element(TRX_NODE, &cfg_trx_min_qual_norm_cmd); install_element(TRX_NODE, &cfg_trx_nominal_power_cmd); + install_element(TRX_NODE, &cfg_trx_pa_max_initial_cmd); + install_element(TRX_NODE, &cfg_trx_pa_step_size_cmd); + install_element(TRX_NODE, &cfg_trx_pa_step_interval_cmd); return 0; } diff --git a/src/osmo-bts-sysmo/utils.c b/src/osmo-bts-sysmo/utils.c index 106d12bd..afca7730 100644 --- a/src/osmo-bts-sysmo/utils.c +++ b/src/osmo-bts-sysmo/utils.c @@ -137,13 +137,88 @@ int sysmobts_get_nominal_power(struct gsm_bts_trx *trx) return -1; } -int sysmobts_get_power_trx(struct gsm_bts_trx *trx) +int sysmobts_get_target_power(struct gsm_bts_trx *trx) { - int power_transmitter = trx->nominal_power - trx->max_power_red; - power_transmitter -= trx->power_reduce; + int target_power = trx->nominal_power - trx->max_power_red; + target_power -= trx->power_reduce; - if (power_transmitter < 0) - power_transmitter = 0; + if (target_power < 0) + target_power = 0; - return power_transmitter; + return target_power; +} + +void sysmobts_pa_pwr_init(struct gsm_bts_trx *trx) +{ + int target_power = sysmobts_get_target_power(trx); + + /* Cancel any pending request */ + osmo_timer_del(&trx->pa.step_timer); + + /* is this below our initial target */ + if (target_power <= trx->pa.max_initial_power) { + LOGP(DL1C, LOGL_NOTICE, + "PA target_power(%d) is below initial power.\n", + target_power); + trx->pa.current_power = target_power; + return; + } + + /* is this below our current value? */ + if (target_power <= trx->pa.current_power) { + LOGP(DL1C, LOGL_NOTICE, + "PA target_power(%d) is below current_power.\n", + target_power); + trx->pa.current_power = target_power; + return; + } + + if (trx->pa.current_power > trx->pa.max_initial_power) { + LOGP(DL1C, LOGL_NOTICE, + "PA target_power(%d) starting from current_power.\n", + target_power); + return; + } + + /* We need to step it up. Start from the initial value */ + trx->pa.current_power = trx->pa.max_initial_power; + LOGP(DL1C, LOGL_NOTICE, + "PA target_power(%d) starting with %d dBm.\n", + target_power, trx->pa.current_power); +} + +static void pa_trx_cb(void *_trx) +{ + struct gsm_bts_trx *trx = _trx; + + LOGP(DL1C, LOGL_NOTICE, + "PA raising power to %d dBm.\n", trx->pa.current_power); + l1if_set_txpower(trx_femtol1_hdl(trx), (float) trx->pa.current_power); +} + +void sysmobts_pa_maybe_step(struct gsm_bts_trx *trx) +{ + /* it can not have changed */ + int target_power = sysmobts_get_target_power(trx); + + /* We are done */ + if (trx->pa.current_power >= target_power) { + LOGP(DL1C, LOGL_NOTICE, + "PA have reached target power: %d dBm.\n", + target_power); + return; + } + + /* Step up the current power but clamp it */ + trx->pa.current_power += trx->pa.step_size; + if (trx->pa.current_power > target_power) + trx->pa.current_power = target_power; + + LOGP(DL1C, LOGL_NOTICE, + "PA scheduling to step to %d dBm.\n", + trx->pa.current_power); + + trx->pa.step_timer.data = trx; + trx->pa.step_timer.cb = pa_trx_cb; + osmo_timer_schedule(&trx->pa.step_timer, trx->pa.step_interval, 0); } diff --git a/src/osmo-bts-sysmo/utils.h b/src/osmo-bts-sysmo/utils.h index aef774ca..cf5cf7af 100644 --- a/src/osmo-bts-sysmo/utils.h +++ b/src/osmo-bts-sysmo/utils.h @@ -12,5 +12,8 @@ int sysmobts_select_femto_band(struct gsm_bts_trx *trx, uint16_t arfcn); int sysmobts_get_nominal_power(struct gsm_bts_trx *trx); -int sysmobts_get_power_trx(struct gsm_bts_trx *trx); +int sysmobts_get_target_power(struct gsm_bts_trx *trx); + +void sysmobts_pa_pwr_init(struct gsm_bts_trx *trx); +void sysmobts_pa_maybe_step(struct gsm_bts_trx *trx); #endif |