summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAndreas Eversberg <jolly@eversberg.eu>2013-02-27 15:40:57 +0100
committerAndreas Eversberg <jolly@eversberg.eu>2013-02-27 16:40:37 +0100
commit828c5130645bfde08c7b40c1f901f15701a669b4 (patch)
tree1960057d38afd1340c5d9dc1780135b798947cfe
parent906f1826e7250be259228e13eb7b323a3a1d035b (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 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;
}