summaryrefslogtreecommitdiffstats
path: root/src/target/firmware
diff options
context:
space:
mode:
authorAndreas Eversberg <jolly@eversberg.eu>2023-09-05 12:58:41 +0200
committerjolly <andreas@eversberg.eu>2023-09-27 14:02:41 +0000
commit28d9a4880cdbc18195d759e182af3a23e9cfa236 (patch)
treef6c73e7665e0dc1e06b56b242dd097740f685091 /src/target/firmware
parentb7663882c0ad86b7fb709a4e5b136e7c0230a399 (diff)
ASCI: Add a flag to turn transmitter off or on
This flag can be used to turn transmitter off for "group receive mode" or for handover procedure. The flag is stored in the channel description of the mobile application. It is sent to layer 1 when switching to dedicated channel or when changing TCH mode. At the layer 1 the transmitter is turned off while the receiver is still active. This is done by: * scheduling a TX dummy task for TCH bursts * scheduling no TX task for SACCH bursts * not enabling the transmit window Related: OS#5364 Change-Id: I20133523adc3b204cd2181bfe664fe66020a10e3
Diffstat (limited to 'src/target/firmware')
-rw-r--r--src/target/firmware/include/layer1/async.h3
-rw-r--r--src/target/firmware/include/layer1/sync.h1
-rw-r--r--src/target/firmware/layer1/async.c7
-rw-r--r--src/target/firmware/layer1/l23_api.c9
-rw-r--r--src/target/firmware/layer1/prim_tch.c10
5 files changed, 28 insertions, 2 deletions
diff --git a/src/target/firmware/include/layer1/async.h b/src/target/firmware/include/layer1/async.h
index 221ffcf9..b383d477 100644
--- a/src/target/firmware/include/layer1/async.h
+++ b/src/target/firmware/include/layer1/async.h
@@ -47,6 +47,9 @@ uint8_t l1a_tch_mode_set(uint8_t mode);
/* Set Audio routing mode */
uint8_t l1a_audio_mode_set(uint8_t mode);
+/* Set TCH flags */
+uint8_t l1a_tch_flags_set(uint8_t flags);
+
/* Execute pending L1A completions */
void l1a_compl_execute(void);
diff --git a/src/target/firmware/include/layer1/sync.h b/src/target/firmware/include/layer1/sync.h
index dd932421..ff56354b 100644
--- a/src/target/firmware/include/layer1/sync.h
+++ b/src/target/firmware/include/layer1/sync.h
@@ -82,6 +82,7 @@ struct l1s_state {
uint8_t tch_mode;
uint8_t tch_sync;
uint8_t audio_mode;
+ uint8_t tch_flags;
/* 3GPP TS 44.014, section 5.1 (Calypso DSP specific numbers) */
enum l1ctl_tch_loop_mode tch_loop_mode;
diff --git a/src/target/firmware/layer1/async.c b/src/target/firmware/layer1/async.c
index 1f3d6f14..fe8a906c 100644
--- a/src/target/firmware/layer1/async.c
+++ b/src/target/firmware/layer1/async.c
@@ -125,6 +125,13 @@ uint8_t l1a_audio_mode_set(uint8_t mode)
return mode;
}
+/* Set TCH flags */
+uint8_t l1a_tch_flags_set(uint8_t flags)
+{
+ l1s.tch_flags = flags;
+ return flags;
+}
+
/* Initialize asynchronous part of Layer1 */
void l1a_init(void)
{
diff --git a/src/target/firmware/layer1/l23_api.c b/src/target/firmware/layer1/l23_api.c
index 599272f3..68bb2c0e 100644
--- a/src/target/firmware/layer1/l23_api.c
+++ b/src/target/firmware/layer1/l23_api.c
@@ -289,6 +289,7 @@ static void l1ctl_rx_dm_est_req(struct msgb *msg)
/* Mode */
l1a_tch_mode_set(est_req->tch_mode);
l1a_audio_mode_set(est_req->audio_mode);
+ l1a_tch_flags_set(est_req->tch_flags);
/* Sync */
l1s.tch_sync = 1; /* can be set without locking */
@@ -522,7 +523,7 @@ static void l1ctl_rx_ccch_mode_req(struct msgb *msg)
}
/* Transmit a L1CTL_TCH_MODE_CONF */
-static void l1ctl_tx_tch_mode_conf(uint8_t tch_mode, uint8_t audio_mode)
+static void l1ctl_tx_tch_mode_conf(uint8_t tch_mode, uint8_t audio_mode, uint8_t tch_flags)
{
struct msgb *msg = l1ctl_msgb_alloc(L1CTL_TCH_MODE_CONF);
struct l1ctl_tch_mode_conf *mode_conf;
@@ -530,6 +531,7 @@ static void l1ctl_tx_tch_mode_conf(uint8_t tch_mode, uint8_t audio_mode)
msgb_put(msg, sizeof(*mode_conf));
mode_conf->tch_mode = tch_mode;
mode_conf->audio_mode = audio_mode;
+ mode_conf->tch_flags = l1s.tch_flags;
mode_conf->tch_loop_mode = l1s.tch_loop_mode;
l1_queue_for_l2(msg);
@@ -543,11 +545,14 @@ static void l1ctl_rx_tch_mode_req(struct msgb *msg)
(struct l1ctl_tch_mode_req *) l1h->data;
uint8_t tch_mode = tch_mode_req->tch_mode;
uint8_t audio_mode = tch_mode_req->audio_mode;
+ uint8_t tch_flags = tch_mode_req->tch_flags;
printd("L1CTL_TCH_MODE_REQ (tch_mode=0x%02x audio_mode=0x%02x)\n",
tch_mode, audio_mode);
+
tch_mode = l1a_tch_mode_set(tch_mode);
audio_mode = l1a_audio_mode_set(audio_mode);
+ tch_flags = l1a_tch_flags_set(tch_flags);
audio_set_enabled(tch_mode, audio_mode);
@@ -555,7 +560,7 @@ static void l1ctl_rx_tch_mode_req(struct msgb *msg)
l1s.tch_loop_mode = tch_mode_req->tch_loop_mode;
/* TODO: Handle AMR codecs from tch_mode_req if tch_mode_req->tch_mode==GSM48_CMODE_SPEECH_AMR */
- l1ctl_tx_tch_mode_conf(tch_mode, audio_mode);
+ l1ctl_tx_tch_mode_conf(tch_mode, audio_mode, tch_flags);
}
/* receive a L1CTL_NEIGH_PM_REQ from L23 */
diff --git a/src/target/firmware/layer1/prim_tch.c b/src/target/firmware/layer1/prim_tch.c
index 56c32fba..e3cffd1b 100644
--- a/src/target/firmware/layer1/prim_tch.c
+++ b/src/target/firmware/layer1/prim_tch.c
@@ -478,6 +478,12 @@ skip_tx_traffic:
);
l1s_rx_win_ctrl(arfcn, L1_RXWIN_NB, 0);
+ /* If transmission is off, use dummy task for DSP and do not open TX window. */
+ if ((l1s.tch_flags & L1CTL_TCH_FLAG_RXONLY)) {
+ dsp_load_tx_task(TCHD_DSP_TASK, 0, tsc); /* burst_id unused for TCH */
+ return 0;
+ }
+
dsp_load_tx_task(
dsp_task_iq_swap(TCHT_DSP_TASK, arfcn, 1),
0, tsc /* burst_id unused for TCH */
@@ -743,6 +749,10 @@ static int l1s_tch_a_cmd(__unused uint8_t p1, __unused uint8_t p2, uint16_t p3)
);
l1s_rx_win_ctrl(arfcn, L1_RXWIN_NB, 0);
+ /* If transmission is off, schedule no task for DSP and do not open TX window. */
+ if ((l1s.tch_flags & L1CTL_TCH_FLAG_RXONLY))
+ return 0;
+
dsp_load_tx_task(
dsp_task_iq_swap(TCHA_DSP_TASK, arfcn, 1),
0, tsc /* burst_id unused for TCHA */