[PATCH] osmo-bts[master]: LC15: TRX nominal TX power can be used from EEPROM or from B...

This is merely a historical archive of years 2008-2021, before the migration to mailman3.

A maintained and still updated list archive can be found at https://lists.osmocom.org/hyperkitty/list/gerrit-log@lists.osmocom.org/.

Minh-Quang Nguyen gerrit-no-reply at lists.osmocom.org
Mon Jun 13 13:29:16 UTC 2016


Review at  https://gerrit.osmocom.org/238

LC15: TRX nominal TX power can be used from EEPROM or from BTS configuration

Change-Id: I173f4126cea41959d48def07bff25fcd29894b7e
---
M include/osmo-bts/phy_link.h
M src/osmo-bts-litecell15/calib_file.c
M src/osmo-bts-litecell15/lc15bts_vty.c
M src/osmo-bts-litecell15/main.c
4 files changed, 226 insertions(+), 4 deletions(-)


  git pull ssh://gerrit.osmocom.org:29418/osmo-bts refs/changes/38/238/1

diff --git a/include/osmo-bts/phy_link.h b/include/osmo-bts/phy_link.h
index edc6cc0..b3db4ce 100644
--- a/include/osmo-bts/phy_link.h
+++ b/include/osmo-bts/phy_link.h
@@ -103,7 +103,8 @@
 			/* configuration */
 			uint32_t dsp_trace_f;
 			char *calib_path;
-
+			int minTxPower;
+			int maxTxPower;
 			struct lc15l1_hdl *hdl;
 		} lc15;
 	} u;
diff --git a/src/osmo-bts-litecell15/calib_file.c b/src/osmo-bts-litecell15/calib_file.c
index c6be4f0..3bc788c 100644
--- a/src/osmo-bts-litecell15/calib_file.c
+++ b/src/osmo-bts-litecell15/calib_file.c
@@ -42,7 +42,11 @@
 #include "lc15bts.h"
 #include "utils.h"
 
-
+/**
+ *  * Maximum calibration data chunk size
+ *   */
+#define MAX_CALIB_TBL_SIZE  65536
+#define CALIB_HDR_V1  0x01
 
 struct calib_file_desc {
 	const char *fname;
@@ -83,9 +87,37 @@
 	},
 };
 
+static struct calTbl_t
+{
+    union
+    {
+        struct
+        {
+            uint8_t u8Version;                // Header version (1)
+            uint8_t u8Parity;                 // Parity byte (xor)
+            uint8_t u8Type;                   // Table type (0:TX Downlink, 1:RX-A Uplink, 2:RX-B Uplink)
+            uint8_t u8Band;                   // GSM Band (0:GSM-850, 1:EGSM-900, 2:DCS-1800, 3:PCS-1900)
+            uint32_t u32Len;                  // Table length in bytes including the header
+            struct
+            {
+                uint32_t u32DescOfst;         // Description section offset
+                uint32_t u32DateOfst;         // Date section offset
+                uint32_t u32StationOfst;      // Calibration test station section offset
+                uint32_t u32FpgaFwVerOfst;    // Calibration FPGA firmware version section offset
+                uint32_t u32DspFwVerOfst;     // Calibration DSP firmware section offset
+                uint32_t u32DataOfst;         // Calibration data section offset
+            } toc;
+        } v1;
+    } hdr;
+
+    uint8_t u8RawData[MAX_CALIB_TBL_SIZE - 32];
+};
+
 
 static int calib_file_send(struct lc15l1_hdl *fl1h,
 			   const struct calib_file_desc *desc);
+static int calib_verify(struct lc15l1_hdl *fl1h,
+			const struct calib_file_desc *desc);
 
 /* determine next calibration file index based on supported bands */
 static int get_next_calib_file_idx(struct lc15l1_hdl *fl1h, int last_idx)
@@ -203,6 +235,20 @@
                 return 0;
 	}
 
+	rc = calib_verify(fl1h, desc);
+	if ( rc < 0 ) {
+		LOGP(DL1C, LOGL_ERROR, "Verify L1 calibration table %s -> failed (%d)\n", desc->fname, rc);
+		st->last_file_idx = get_next_calib_file_idx(fl1h, st->last_file_idx);
+
+		if (st->last_file_idx >= 0)
+			return calib_file_send(fl1h,
+				&calib_files[st->last_file_idx]);
+		return 0;
+
+	}
+
+	LOGP(DL1C, LOGL_INFO, "Verify L1 calibration table %s -> done\n", desc->fname);
+
 	return calib_file_send_next_chunk(fl1h);
 }
 
@@ -258,3 +304,155 @@
 	return calib_file_send(fl1h, &calib_files[st->last_file_idx]);
 }
 
+
+static int calib_verify(struct lc15l1_hdl *fl1h, const struct calib_file_desc *desc)
+{
+       int i, rc, sz;
+       struct calib_send_state *st = &fl1h->st;
+       struct phy_link *plink = fl1h->phy_inst->phy_link;
+       char *rbuf;
+       struct calTbl_t *calTbl;
+       char calChkSum ;
+
+
+       //calculate file size in bytes
+       fseek(st->fp, 0L, SEEK_END);
+       sz = ftell(st->fp);
+
+       //rewind read poiner
+       fseek(st->fp, 0L, SEEK_SET);
+
+       //read file
+       rbuf = (char *) malloc( sizeof(char) * sz );
+
+       rc = fread(rbuf, 1, sizeof(char) * sz, st->fp);
+       if ( rc != sz) {
+
+               LOGP(DL1C, LOGL_ERROR, "%s reading error\n", desc->fname);
+               free(rbuf);
+
+               //close file
+               rc = calib_file_close(fl1h);
+               if (rc < 0 ) {
+                       LOGP(DL1C, LOGL_ERROR, "%s can not close\n", desc->fname);
+                       return rc;
+               }
+
+               return -2;
+       }
+
+
+       calTbl = (struct calTbl_t*) rbuf;
+       //calcualte file checksum
+       calChkSum = 0;
+       while ( sz-- ) {
+               calChkSum ^= rbuf[sz];
+       }
+
+       //validate Tx calibration parity
+       if ( calChkSum ) {
+               LOGP(DL1C, LOGL_ERROR, "%s has invalid checksum %x.\n", desc->fname, calChkSum);
+               return -4;
+       }
+
+       //validate Tx calibration header
+       if ( calTbl->hdr.v1.u8Version != CALIB_HDR_V1 ) {
+               LOGP(DL1C, LOGL_ERROR, "%s has invalid header version %u.\n", desc->fname, calTbl->hdr.v1.u8Version);
+               return -5;
+       }
+
+       //validate calibration description
+       if ( calTbl->hdr.v1.toc.u32DescOfst == 0xFFFFFFFF ) {
+               LOGP(DL1C, LOGL_ERROR, "%s has invalid calibration description  offset.\n", desc->fname);
+               return -6;
+       }
+
+       //validate calibration date
+       if ( calTbl->hdr.v1.toc.u32DateOfst == 0xFFFFFFFF ) {
+               LOGP(DL1C, LOGL_ERROR, "%s has invalid calibration date offset.\n", desc->fname);
+               return -7;
+       }
+
+       LOGP(DL1C, LOGL_INFO, "L1 calibration table %s created on %s\n",
+               desc->fname,
+               calTbl->u8RawData + calTbl->hdr.v1.toc.u32DateOfst);
+
+       //validate calibration station
+       if ( calTbl->hdr.v1.toc.u32StationOfst == 0xFFFFFFFF ) {
+               LOGP(DL1C, LOGL_ERROR, "%s has invalid calibration station ID offset.\n", desc->fname);
+               return -8;
+       }
+
+       //validate FPGA FW version
+       if ( calTbl->hdr.v1.toc.u32FpgaFwVerOfst == 0xFFFFFFFF ) {
+               LOGP(DL1C, LOGL_ERROR, "%s has invalid FPGA FW version offset.\n", desc->fname);
+               return -9;
+       }
+       //validate DSP FW version
+       if ( calTbl->hdr.v1.toc.u32DspFwVerOfst == 0xFFFFFFFF ) {
+               LOGP(DL1C, LOGL_ERROR, "%s has invalid DSP FW version offset.\n", desc->fname);
+               return -10;
+       }
+
+       //validate Tx calibration data offset
+       if ( calTbl->hdr.v1.toc.u32DataOfst == 0xFFFFFFFF ) {
+               LOGP(DL1C, LOGL_ERROR, "%s has invalid calibration data offset.\n", desc->fname);
+               return -11;
+       }
+
+       if ( !desc->rx ) {
+
+               //parse min/max Tx power
+               fl1h->phy_inst->u.lc15.minTxPower = calTbl->u8RawData[calTbl->hdr.v1.toc.u32DataOfst + (5 << 2)];
+               fl1h->phy_inst->u.lc15.maxTxPower = calTbl->u8RawData[calTbl->hdr.v1.toc.u32DataOfst + (6 << 2)];
+
+               //override nominal Tx power of given TRX if needed
+               if ( fl1h->phy_inst->trx->nominal_power > fl1h->phy_inst->u.lc15.maxTxPower) {
+                       LOGP(DL1C, LOGL_INFO, "Set TRX %u nominal Tx power to %d dBm (%d)\n",
+                                       plink->num,
+                                       fl1h->phy_inst->u.lc15.maxTxPower,
+                                       fl1h->phy_inst->trx->nominal_power);
+
+                       fl1h->phy_inst->trx->nominal_power = fl1h->phy_inst->u.lc15.maxTxPower;
+               }
+
+               if ( fl1h->phy_inst->trx->nominal_power < fl1h->phy_inst->u.lc15.minTxPower) {
+                       LOGP(DL1C, LOGL_INFO, "Set TRX %u nominal Tx power to %d dBm (%d)\n",
+                                       plink->num,
+                                       fl1h->phy_inst->u.lc15.minTxPower,
+                                       fl1h->phy_inst->trx->nominal_power);
+
+                       fl1h->phy_inst->trx->nominal_power = fl1h->phy_inst->u.lc15.minTxPower;
+               }
+
+               if ( fl1h->phy_inst->trx->power_params.trx_p_max_out_mdBm > to_mdB(fl1h->phy_inst->u.lc15.maxTxPower) ) {
+                       LOGP(DL1C, LOGL_INFO, "Set TRX %u Tx power parameter to %d dBm (%d)\n",
+                                       plink->num,
+                                       to_mdB(fl1h->phy_inst->u.lc15.maxTxPower),
+                                       fl1h->phy_inst->trx->power_params.trx_p_max_out_mdBm);
+
+                       fl1h->phy_inst->trx->power_params.trx_p_max_out_mdBm = to_mdB(fl1h->phy_inst->u.lc15.maxTxPower);
+               }
+
+               if ( fl1h->phy_inst->trx->power_params.trx_p_max_out_mdBm < to_mdB(fl1h->phy_inst->u.lc15.minTxPower) ) {
+                       LOGP(DL1C, LOGL_INFO, "Set TRX %u Tx power parameter to %d dBm (%d)\n",
+                                       plink->num,
+                                       to_mdB(fl1h->phy_inst->u.lc15.minTxPower),
+                                       fl1h->phy_inst->trx->power_params.trx_p_max_out_mdBm);
+
+                       fl1h->phy_inst->trx->power_params.trx_p_max_out_mdBm = to_mdB(fl1h->phy_inst->u.lc15.minTxPower);
+               }
+
+               LOGP(DL1C, LOGL_DEBUG, "%s: minTxPower=%d, maxTxPower=%d\n",
+                               desc->fname,
+                               fl1h->phy_inst->u.lc15.minTxPower,
+                               fl1h->phy_inst->u.lc15.maxTxPower );
+       }
+
+       //rewind read poiner for subsequence tasks
+       fseek(st->fp, 0L, SEEK_SET);
+       free(rbuf);
+
+       return 0;
+}
+
diff --git a/src/osmo-bts-litecell15/lc15bts_vty.c b/src/osmo-bts-litecell15/lc15bts_vty.c
index d0288ab..8c4364c 100644
--- a/src/osmo-bts-litecell15/lc15bts_vty.c
+++ b/src/osmo-bts-litecell15/lc15bts_vty.c
@@ -218,6 +218,8 @@
 			vty_out(vty, "%s ",  gsm_band_name(1 << i));
 	}
 	vty_out(vty, "%s", VTY_NEWLINE);
+	vty_out(vty, "Min Tx Power: %d dBm%s", fl1h->phy_inst->u.lc15.minTxPower, VTY_NEWLINE);
+	vty_out(vty, "Max Tx Power: %d dBm%s", fl1h->phy_inst->u.lc15.maxTxPower, VTY_NEWLINE);
 
 	return CMD_SUCCESS;
 }
@@ -246,8 +248,9 @@
 }
 
 DEFUN(set_tx_power, set_tx_power_cmd,
-	"trx <0-0> tx-power <-110-100>",
+	"trx nr <0-1> tx-power <-110-100>",
 	TRX_STR
+	"TRX number \n"
 	"Set transmit power (override BSC)\n"
 	"Transmit power in dBm\n")
 {
@@ -298,6 +301,25 @@
 	return CMD_SUCCESS;
 }
 
+DEFUN(cfg_trx_nominal_power, cfg_trx_nominal_power_cmd,
+       "nominal-tx-power <0-40>",
+       "Set the nominal transmit output power in dBm\n"
+       "Nominal transmit output power level in dBm\n")
+{
+	int nominal_power = atoi(argv[0]);
+	struct gsm_bts_trx *trx = vty->index;
+
+	if (( nominal_power >  40 ) ||  ( nominal_power < 0 )) {
+		vty_out(vty, "Nominal Tx power level must be between 0 and 40 dBm (%d) %s",
+		nominal_power, VTY_NEWLINE);
+		return CMD_WARNING;
+	}
+
+	trx->nominal_power = nominal_power;
+	trx->power_params.trx_p_max_out_mdBm = to_mdB(nominal_power);
+
+	return CMD_SUCCESS;
+}
 
 void bts_model_config_write_bts(struct vty *vty, struct gsm_bts *bts)
 {
@@ -305,6 +327,7 @@
 
 void bts_model_config_write_trx(struct vty *vty, struct gsm_bts_trx *trx)
 {
+	vty_out(vty, "  nominal-tx-power %d%s", trx->nominal_power,VTY_NEWLINE);
 }
 
 static void write_phy_inst(struct vty *vty, struct phy_instance *pinst)
diff --git a/src/osmo-bts-litecell15/main.c b/src/osmo-bts-litecell15/main.c
index 2aaacd3..352949b 100644
--- a/src/osmo-bts-litecell15/main.c
+++ b/src/osmo-bts-litecell15/main.c
@@ -81,7 +81,7 @@
 	}
 
 	llist_for_each_entry(trx, &bts->trx_list, list) {
-		trx->nominal_power = 37;
+		trx->nominal_power = 40;
 		trx->power_params.trx_p_max_out_mdBm = to_mdB(bts->c0->nominal_power);
 	}
 

-- 
To view, visit https://gerrit.osmocom.org/238
To unsubscribe, visit https://gerrit.osmocom.org/settings

Gerrit-MessageType: newchange
Gerrit-Change-Id: I173f4126cea41959d48def07bff25fcd29894b7e
Gerrit-PatchSet: 1
Gerrit-Project: osmo-bts
Gerrit-Branch: master
Gerrit-Owner: Minh-Quang Nguyen <minh-quang.nguyen at nutaq.com>



More information about the gerrit-log mailing list