diff --git a/src/osmo-bts-sysmo/Makefile.am b/src/osmo-bts-sysmo/Makefile.am index e69ee2ac9..9ffa308ac 100644 --- a/src/osmo-bts-sysmo/Makefile.am +++ b/src/osmo-bts-sysmo/Makefile.am @@ -6,7 +6,7 @@ EXTRA_DIST = misc/sysmobts_mgr.h misc/sysmobts_misc.h misc/sysmobts_par.h misc/s bin_PROGRAMS = sysmobts sysmobts-remote l1fwd-proxy sysmobts-mgr -COMMON_SOURCES = main.c femtobts.c l1_if.c oml.c sysmobts_vty.c tch.c hw_misc.c +COMMON_SOURCES = main.c femtobts.c l1_if.c oml.c sysmobts_vty.c tch.c hw_misc.c calib_file.c sysmobts_SOURCES = $(COMMON_SOURCES) l1_transp_hw.c sysmobts_LDADD = $(top_builddir)/src/common/libbts.a $(LDADD) diff --git a/src/osmo-bts-sysmo/calib_file.c b/src/osmo-bts-sysmo/calib_file.c index e89588e02..415f0442e 100644 --- a/src/osmo-bts-sysmo/calib_file.c +++ b/src/osmo-bts-sysmo/calib_file.c @@ -27,9 +27,13 @@ #include +#include + #include #include +#include "l1_if.h" + struct calib_file_desc { const char *fname; GsmL1_FreqBand_t band; @@ -104,7 +108,7 @@ static const struct calib_file_desc calib_files[] = { static const unsigned int arrsize_by_band[] = { [GsmL1_FreqBand_850] = 124, - [GsmL1_FreqBand_900] = 195, + [GsmL1_FreqBand_900] = 194, [GsmL1_FreqBand_1800] = 374, [GsmL1_FreqBand_1900] = 299 }; @@ -129,18 +133,20 @@ int calib_file_read(const char *path, const struct calib_file_desc *desc, { FILE *in; char fname[PATH_MAX]; - int rc, i; + int i; fname[0] = '\0'; - rc = snprintf(fname, sizeof(fname)-1, "%s/%s", path, desc->fname); + snprintf(fname, sizeof(fname)-1, "%s/%s", path, desc->fname); fname[sizeof(fname)-1] = '\0'; in = fopen(fname, "r"); if (!in) return -1; +#if SUPERFEMTO_API_VERSION >= SUPERFEMTO_API(2,4,0) if (desc->rx) { SuperFemto_SetRxCalibTblReq_t *rx = &prim->u.setRxCalibTblReq; + memset(rx, 0, sizeof(*rx)); prim->id = SuperFemto_PrimId_SetRxCalibTblReq; @@ -156,13 +162,16 @@ int calib_file_read(const char *path, const struct calib_file_desc *desc, for (i = 0; i < arrsize_by_band[desc->band]; i++) rx->fRxRollOffCorr[i] = read_float(in); - rx->u8IqImbalMode = read_int(in); - - for (i = 0; i < ARRAY_SIZE(rx->u16IqImbalCorr); i++) - rx->u16IqImbalCorr[i] = read_int(in); + if (desc->uplink) { + rx->u8IqImbalMode = read_int(in); + printf("%s: u8IqImbalMode=%d\n", desc->fname, rx->u8IqImbalMode); + for (i = 0; i < ARRAY_SIZE(rx->u16IqImbalCorr); i++) + rx->u16IqImbalCorr[i] = read_int(in); + } } else { SuperFemto_SetTxCalibTblReq_t *tx = &prim->u.setTxCalibTblReq; + memset(tx, 0, sizeof(*tx)); prim->id = SuperFemto_PrimId_SetTxCalibTblReq; @@ -179,12 +188,75 @@ int calib_file_read(const char *path, const struct calib_file_desc *desc, for (i = 0; i < arrsize_by_band[desc->band]; i++) tx->fTxRollOffCorr[i] = read_float(in); } - +#else +#warning Format of calibration tables before API version 2.4.0 not supported +#endif fclose(in); return 0; } +/* iteratively download the calibration data into the L1 */ + +struct calib_send_state { + struct femtol1_hdl *fl1h; + const char *path; + int last_file_idx; +}; + +static int calib_send_compl_cb(struct msgb *l1_msg, void *data); + +/* send the calibration table for a single specified file */ +static int calib_file_send(struct femtol1_hdl *fl1h, + const struct calib_file_desc *desc, void *state) +{ + struct msgb *msg; + int rc; + + msg = sysp_msgb_alloc(); + + rc = calib_file_read(fl1h->calib_path, desc, msgb_sysprim(msg)); + if (rc < 0) { + msgb_free(msg); + return rc; + } + + return l1if_req_compl(fl1h, msg, 1, calib_send_compl_cb, state); +} + +/* completion callback after every SetCalibTbl is confirmed */ +static int calib_send_compl_cb(struct msgb *l1_msg, void *data) +{ + struct calib_send_state *st = data; + + LOGP(DL1C, LOGL_DEBUG, "L1 calibration table %s loaded\n", + calib_files[st->last_file_idx].fname); + + st->last_file_idx++; + + if (st->last_file_idx < ARRAY_SIZE(calib_files)) + return calib_file_send(st->fl1h, + &calib_files[st->last_file_idx], st); + + LOGP(DL1C, LOGL_INFO, "L1 calibration table loading complete!\n"); + + return 0; +} + + +int calib_load(struct femtol1_hdl *fl1h) +{ + static struct calib_send_state st; + + memset(&st, 0, sizeof(st)); + st.fl1h = fl1h; + +#if SUPERFEMTO_API_VERSION < SUPERFEMTO_API(2,4,0) + return -1; +#else + return calib_file_send(fl1h, &calib_files[0], &st); +#endif +} #if 0 diff --git a/src/osmo-bts-sysmo/femtobts.c b/src/osmo-bts-sysmo/femtobts.c index e13fb3559..6bd9ce431 100644 --- a/src/osmo-bts-sysmo/femtobts.c +++ b/src/osmo-bts-sysmo/femtobts.c @@ -123,6 +123,16 @@ const struct value_string femtobts_sysprim_names[SuperFemto_PrimId_NUM+1] = { { SuperFemto_PrimId_RfClockSetupCnf, "RF-CLOCK-SETUP.conf" }, { SuperFemto_PrimId_Layer1ResetReq, "LAYER1-RESET.req" }, { SuperFemto_PrimId_Layer1ResetCnf, "LAYER1-RESET.conf" }, +#if SUPERFEMTO_API_VERSION >= SUPERFEMTO_API(2,1,0) + { SuperFemto_PrimId_GetTxCalibTblReq, "GET-TX-CALIB.req" }, + { SuperFemto_PrimId_GetTxCalibTblCnf, "GET-TX-CALIB.cnf" }, + { SuperFemto_PrimId_SetTxCalibTblReq, "SET-TX-CALIB.req" }, + { SuperFemto_PrimId_SetTxCalibTblCnf, "SET-TX-CALIB.cnf" }, + { SuperFemto_PrimId_GetRxCalibTblReq, "GET-RX-CALIB.req" }, + { SuperFemto_PrimId_GetRxCalibTblCnf, "GET-RX-CALIB.cnf" }, + { SuperFemto_PrimId_SetRxCalibTblReq, "SET-RX-CALIB.req" }, + { SuperFemto_PrimId_SetRxCalibTblCnf, "SET-RX-CALIB.cnf" }, +#endif { 0, NULL } }; @@ -133,6 +143,12 @@ const SuperFemto_PrimId_t femtobts_sysprim_req2conf[SuperFemto_PrimId_NUM] = { [SuperFemto_PrimId_RfClockInfoReq] = SuperFemto_PrimId_RfClockInfoCnf, [SuperFemto_PrimId_RfClockSetupReq] = SuperFemto_PrimId_RfClockSetupCnf, [SuperFemto_PrimId_Layer1ResetReq] = SuperFemto_PrimId_Layer1ResetCnf, +#if SUPERFEMTO_API_VERSION >= SUPERFEMTO_API(2,1,0) + [SuperFemto_PrimId_GetTxCalibTblReq] = SuperFemto_PrimId_GetTxCalibTblCnf, + [SuperFemto_PrimId_SetTxCalibTblReq] = SuperFemto_PrimId_SetTxCalibTblCnf, + [SuperFemto_PrimId_GetRxCalibTblReq] = SuperFemto_PrimId_GetRxCalibTblCnf, + [SuperFemto_PrimId_SetRxCalibTblReq] = SuperFemto_PrimId_SetRxCalibTblCnf, +#endif }; const struct value_string femtobts_l1sapi_names[GsmL1_Sapi_NUM+1] = { diff --git a/src/osmo-bts-sysmo/l1_if.c b/src/osmo-bts-sysmo/l1_if.c index 8bc7a28a5..b9c16c9a0 100644 --- a/src/osmo-bts-sysmo/l1_if.c +++ b/src/osmo-bts-sysmo/l1_if.c @@ -1074,6 +1074,14 @@ static int reset_compl_cb(struct msgb *resp, void *data) /* obtain version information on DSP/FPGA and band capabilities */ l1if_get_info(fl1h); +#if SUPERFEMTO_API_VERSION >= SUPERFEMTO_API(2,1,0) + /* load calibration tables (if we know their path) */ + if (fl1h->calib_path) + calib_load(fl1h); + else +#endif + LOGP(DL1C, LOGL_NOTICE, "Operating without calibration tables!\n"); + /* otherwise, request activation of RF board */ l1if_activate_rf(fl1h, 1); diff --git a/src/osmo-bts-sysmo/l1_if.h b/src/osmo-bts-sysmo/l1_if.h index ed86400a3..4afbca005 100644 --- a/src/osmo-bts-sysmo/l1_if.h +++ b/src/osmo-bts-sysmo/l1_if.h @@ -4,6 +4,7 @@ #include #include #include +#include #include enum { @@ -32,6 +33,7 @@ struct femtol1_hdl { uint32_t dsp_trace_f; int clk_cal; uint8_t clk_src; + char *calib_path; struct llist_head wlc_list; struct gsmtap_inst *gsmtap; diff --git a/src/osmo-bts-sysmo/sysmobts_vty.c b/src/osmo-bts-sysmo/sysmobts_vty.c index 139f0fae3..6c454bf0e 100644 --- a/src/osmo-bts-sysmo/sysmobts_vty.c +++ b/src/osmo-bts-sysmo/sysmobts_vty.c @@ -146,6 +146,21 @@ DEFUN(cfg_trx_clksrc, cfg_trx_clksrc_cmd, return CMD_SUCCESS; } +DEFUN(cfg_trx_cal_path, cfg_trx_cal_path_cmd, + "trx-calibration-path PATH", + "Set the path name to TRX calibration data\n" "Path name\n") +{ + struct gsm_bts_trx *trx = vty->index; + struct femtol1_hdl *fl1h = trx_femtol1_hdl(trx); + + if (fl1h->calib_path) + talloc_free(fl1h->calib_path); + + fl1h->calib_path = talloc_strdup(fl1h, argv[0]); + + return CMD_SUCCESS; +} + /* runtime */ DEFUN(show_trx_clksrc, show_trx_clksrc_cmd, @@ -394,6 +409,8 @@ void bts_model_config_write_trx(struct vty *vty, struct gsm_bts_trx *trx) vty_out(vty, " clock-calibration %d%s", fl1h->clk_cal, VTY_NEWLINE); + vty_out(vty, " trx-calibration-path %s%s", fl1h->calib_path, + VTY_NEWLINE); vty_out(vty, " clock-source %s%s", get_value_string(femtobts_clksrc_names, fl1h->clk_src), VTY_NEWLINE); @@ -455,6 +472,7 @@ int bts_model_vty_init(struct gsm_bts *bts) install_element(TRX_NODE, &cfg_trx_clkcal_cmd); install_element(TRX_NODE, &cfg_trx_clkcal_def_cmd); install_element(TRX_NODE, &cfg_trx_clksrc_cmd); + install_element(TRX_NODE, &cfg_trx_cal_path_cmd); install_element(TRX_NODE, &cfg_trx_gsmtap_sapi_cmd); install_element(TRX_NODE, &cfg_trx_no_gsmtap_sapi_cmd);