diff options
-rw-r--r-- | include/l1ctl_proto.h | 2 | ||||
-rw-r--r-- | src/target/firmware/include/layer1/sync.h | 2 | ||||
-rw-r--r-- | src/target/firmware/layer1/l23_api.c | 46 | ||||
-rw-r--r-- | src/target/firmware/layer1/prim_bts.c | 31 |
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; } |