aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHarald Welte <laforge@gnumonks.org>2012-10-28 10:58:41 +0100
committerHarald Welte <laforge@gnumonks.org>2012-10-28 10:58:41 +0100
commitd1335d878b34eb67d75a6f7ff22e305a573c827f (patch)
tree5f07825dbc56dda26db9c054143672d8c9c96115
parent98a440427968d60163ccace88aa11763649eefa5 (diff)
sysmobts: Add support for reading calibration tables0.1.0
'trx-calibration-path' is the new VTY command indicating the path name where the calibration files can be found. Calibration is only implemented for SUPERFEMTO API version 2.4.0 or later.
-rw-r--r--src/osmo-bts-sysmo/Makefile.am2
-rw-r--r--src/osmo-bts-sysmo/calib_file.c88
-rw-r--r--src/osmo-bts-sysmo/femtobts.c16
-rw-r--r--src/osmo-bts-sysmo/l1_if.c8
-rw-r--r--src/osmo-bts-sysmo/l1_if.h2
-rw-r--r--src/osmo-bts-sysmo/sysmobts_vty.c18
6 files changed, 125 insertions, 9 deletions
diff --git a/src/osmo-bts-sysmo/Makefile.am b/src/osmo-bts-sysmo/Makefile.am
index e69ee2ac..9ffa308a 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 e89588e0..415f0442 100644
--- a/src/osmo-bts-sysmo/calib_file.c
+++ b/src/osmo-bts-sysmo/calib_file.c
@@ -27,9 +27,13 @@
#include <osmocom/core/utils.h>
+#include <osmo-bts/logging.h>
+
#include <sysmocom/femtobts/superfemto.h>
#include <sysmocom/femtobts/gsml1const.h>
+#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 e13fb355..6bd9ce43 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 8bc7a28a..b9c16c9a 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 ed86400a..4afbca00 100644
--- a/src/osmo-bts-sysmo/l1_if.h
+++ b/src/osmo-bts-sysmo/l1_if.h
@@ -4,6 +4,7 @@
#include <osmocom/core/select.h>
#include <osmocom/core/write_queue.h>
#include <osmocom/core/gsmtap_util.h>
+#include <osmocom/core/timer.h>
#include <osmocom/gsm/gsm_utils.h>
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 139f0fae..6c454bf0 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);