summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-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 ddead86c..4aa3ad76 100644
--- a/include/l1ctl_proto.h
+++ b/include/l1ctl_proto.h
@@ -310,6 +310,8 @@ struct l1ctl_traffic_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 79124cfc..51fec14c 100644
--- a/src/target/firmware/include/layer1/sync.h
+++ b/src/target/firmware/include/layer1/sync.h
@@ -157,6 +157,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 c6baaabf..7b41d4fa 100644
--- a/src/target/firmware/layer1/l23_api.c
+++ b/src/target/firmware/layer1/l23_api.c
@@ -603,9 +603,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;
@@ -616,11 +613,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;
}