summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAndreas Eversberg <jolly@eversberg.eu>2013-02-27 15:40:57 +0100
committerSteve Markgraf <steve@steve-m.de>2021-10-23 18:51:19 +0200
commit48c76f0f65087323753405da2a56acc615efcf3f (patch)
treecf30ebb6078d5f17ca42d4ed89b54f926f46ac22
parentfbefef131ee8edf99ed7617fb52f681b56548f12 (diff)
Calypso BTS uses tx_mask and rx_mask to define which slots to TX or RX
Each mask is used to define first time slot number and number of timeslots per frame. The transceiver needs to choose different masks, depending on single phone or multi phone operation. Note: Currently the code only works with very limited number of mask values.
-rw-r--r--include/l1ctl_proto.h2
-rw-r--r--src/target/firmware/include/layer1/sync.h2
-rw-r--r--src/target/firmware/layer1/l23_api.c46
-rw-r--r--src/target/firmware/layer1/prim_bts.c31
4 files changed, 70 insertions, 11 deletions
diff --git a/include/l1ctl_proto.h b/include/l1ctl_proto.h
index 274a1010..0383a68e 100644
--- a/include/l1ctl_proto.h
+++ b/include/l1ctl_proto.h
@@ -395,6 +395,8 @@ struct l1ctl_tbf_cfg_req {
/* BTS mode: config */
struct l1ctl_bts_mode {
uint8_t enabled;
+ uint8_t tx_mask;
+ uint8_t rx_mask;
uint8_t type[8];
uint8_t bsic;
uint16_t band_arfcn;
diff --git a/src/target/firmware/include/layer1/sync.h b/src/target/firmware/include/layer1/sync.h
index f4b44140..21461bfe 100644
--- a/src/target/firmware/include/layer1/sync.h
+++ b/src/target/firmware/include/layer1/sync.h
@@ -163,6 +163,8 @@ struct l1s_state {
/* bts mode */
struct {
+ uint8_t tx_start, tx_num;
+ uint8_t rx_start, rx_num;
uint8_t type[8];
uint16_t arfcn;
uint8_t bsic;
diff --git a/src/target/firmware/layer1/l23_api.c b/src/target/firmware/layer1/l23_api.c
index 5d1b11bd..e8ebd9c7 100644
--- a/src/target/firmware/layer1/l23_api.c
+++ b/src/target/firmware/layer1/l23_api.c
@@ -641,9 +641,6 @@ static int l1ctl_bts_mode(struct msgb *msg)
l1s.tx_power = ms_pwr_ctl_lvl(gsm_arfcn2band(l1s.bts.arfcn), 15);
- printf("BTS MODE: %u %u {%u}\n", l1s.bts.bsic, l1s.bts.arfcn,
- bm->type[0]);
-
l1a_mftask_set(0);
if (bm->enabled) {
int i;
@@ -654,11 +651,54 @@ static int l1ctl_bts_mode(struct msgb *msg)
l1s.bts.type[i] = bm->type[i];
trx_init();
l1s.bts.gain = bm->gain;
+
+ /* Calculate TX and RX windows by bit masks */
+ for (i = 0; i < 8; i++) {
+ if (!(bm->tx_mask & (1 << ((i-1) & 7)))
+ && (bm->tx_mask & (1 << i))) {
+ l1s.bts.tx_start = i;
+ break;
+ }
+ }
+ if (i == 8)
+ goto error;
+ l1s.bts.tx_num = 0;
+ while ((bm->tx_mask & (1 << i))) {
+ l1s.bts.tx_num++;
+ i = (i+1) & 7;
+ }
+ for (i = 0; i < 8; i++) {
+ if (!(bm->rx_mask & (1 << ((i-1) & 7)))
+ && (bm->rx_mask & (1 << i))) {
+ l1s.bts.rx_start = i;
+ break;
+ }
+ }
+ if (i == 8)
+ goto error;
+ l1s.bts.rx_num = 0;
+ while ((bm->rx_mask & (1 << i))) {
+ l1s.bts.rx_num++;
+ i = (i+1) & 7;
+ }
} else {
mframe_enable(MF_TASK_BCCH_NORM);
}
+ printf("BTS MODE: %u %u {%u,%u,%u,%u,%u,%u,%u,%u} "
+ "TX %d..%d RX %d..%d\n", l1s.bts.bsic, l1s.bts.arfcn,
+ bm->type[0], bm->type[1], bm->type[2], bm->type[3],
+ bm->type[4], bm->type[5], bm->type[6], bm->type[7],
+ l1s.bts.tx_start, (l1s.bts.tx_start + l1s.bts.tx_num - 1) & 7,
+ l1s.bts.rx_start, (l1s.bts.rx_start + l1s.bts.rx_num - 1) & 7);
+
return 0;
+
+error:
+ printf("BTS MODE: invalid bit masks 0x%02x, 0x%02x\n",
+ bm->tx_mask, bm->rx_mask);
+
+ return -EINVAL;
}
static int l1ctl_bts_burst_req(struct msgb *msg)
diff --git a/src/target/firmware/layer1/prim_bts.c b/src/target/firmware/layer1/prim_bts.c
index 36b830e5..5564f803 100644
--- a/src/target/firmware/layer1/prim_bts.c
+++ b/src/target/firmware/layer1/prim_bts.c
@@ -171,7 +171,7 @@ l1s_bts_resp(uint8_t p1, uint8_t p2, uint16_t p3)
energy[i] = 0;
}
- printf("### RACH ### (%04x %04x)\n", energy_max, energy_avg);
+// printf("### RACH ### (%04x %04x)\n", energy_max, energy_avg);
/* Create message */
msg = l1ctl_msgb_alloc(L1CTL_BTS_BURST_AB_IND);
@@ -197,7 +197,7 @@ l1s_bts_resp(uint8_t p1, uint8_t p2, uint16_t p3)
struct l1ctl_bts_burst_nb_ind *bi;
int i;
- printf("### NB ### (%04x %04x)\n", d[1], d[3]);
+// printf("### NB ### (%04x %04x)\n", d[1], d[3]);
/* Create message */
msg = l1ctl_msgb_alloc(L1CTL_BTS_BURST_NB_IND);
@@ -210,7 +210,7 @@ l1s_bts_resp(uint8_t p1, uint8_t p2, uint16_t p3)
bi->fn = htonl(rx_time.fn);
/* Timeslot */
- bi->tn = 0;
+ bi->tn = l1s.bts.rx_start;
/* TOA */
if (toa > -32 && toa < 32)
@@ -278,7 +278,7 @@ l1s_bts_cmd(uint8_t p1, uint8_t p2, uint16_t p3)
t3 = t3 - 1;
/* Select which type of burst */
- if ((l1s.bts.type[0] >> 1) != 2) /* not type 4,5 */
+ if ((l1s.bts.type[l1s.bts.rx_start] >> 1) != 2) /* not type 4,5 */
db->rx[0].cmd = DSP_EXT_RX_CMD_NB;
else if (l1s.bts.type[0] == 4) /* type 4 */
db->rx[0].cmd = DSP_EXT_RX_CMD_AB;
@@ -303,7 +303,7 @@ l1s_bts_cmd(uint8_t p1, uint8_t p2, uint16_t p3)
rffe_compute_gain(-47 - l1s.bts.gain, CAL_DSP_TGT_BB_LVL);
/* Open RX window */
- l1s_rx_win_ctrl(l1s.bts.arfcn | ARFCN_UPLINK, L1_RXWIN_NB, 0);
+ l1s_rx_win_ctrl(l1s.bts.arfcn | ARFCN_UPLINK, L1_RXWIN_NB, l1s.bts.rx_start);
/* restore last gain */
rffe_set_gain(last_gain);
@@ -313,16 +313,28 @@ l1s_bts_cmd(uint8_t p1, uint8_t p2, uint16_t p3)
/* TX side */
/* ------- */
- #define SLOT 3
+ // FIXME put that in a loop over all TX bursts
+ static uint8_t SLOT, tn;
+ if (l1s.bts.tx_start == 5) {
+ SLOT = 3;
+ tn = 0;
+ } else {
+ SLOT = 0;
+ tn = 1;
+ }
/* Reset all commands to dummy burst */
for (i=0; i<8; i++)
db->tx[i].cmd = DSP_EXT_TX_CMD_DUMMY;
/* Get the next burst */
- type = trx_get_burst(l1s.next_time.fn, 0, data);
+ type = trx_get_burst(l1s.next_time.fn, tn, data);
/* Program the TX commands */
+ if (t3 == 2 && (l1s.bts.type[tn] >> 1) != 2) {
+ // FIXME use dummy until TSC will be set individually
+ db->tx[SLOT].cmd = DSP_EXT_TX_CMD_DUMMY;
+ } else
switch (type) {
case BURST_FB:
db->tx[SLOT].cmd = DSP_EXT_TX_CMD_FB;
@@ -366,7 +378,10 @@ l1s_bts_cmd(uint8_t p1, uint8_t p2, uint16_t p3)
/* Open TX window */
l1s_tx_apc_helper(l1s.bts.arfcn);
- l1s_tx_multi_win_ctrl(l1s.bts.arfcn, 0, 2, 5);
+ if (l1s.bts.tx_num > 1)
+ l1s_tx_multi_win_ctrl(l1s.bts.arfcn, 0, (l1s.bts.tx_start + 5) & 7, l1s.bts.tx_num);
+ else
+ l1s_tx_win_ctrl(l1s.bts.arfcn, L1_TXWIN_NB, 0, (l1s.bts.tx_start + 5) & 7);
return 0;
}