summaryrefslogtreecommitdiffstats
path: root/src/target/firmware
diff options
context:
space:
mode:
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.h15
-rw-r--r--src/target/firmware/layer1/async.c23
-rw-r--r--src/target/firmware/layer1/sync.c10
4 files changed, 51 insertions, 0 deletions
diff --git a/src/target/firmware/include/layer1/async.h b/src/target/firmware/include/layer1/async.h
index 33f89bc..03e33ca 100644
--- a/src/target/firmware/include/layer1/async.h
+++ b/src/target/firmware/include/layer1/async.h
@@ -29,6 +29,9 @@ void l1a_mftask_enable(enum mframe_task task);
/* Disable a repeating multiframe task */
void l1a_mftask_disable(enum mframe_task task);
+/* Execute pending L1A completions */
+void l1a_compl_execute(void);
+
/* Initialize asynchronous part of Layer1 */
void l1a_init(void);
diff --git a/src/target/firmware/include/layer1/sync.h b/src/target/firmware/include/layer1/sync.h
index d053c93..fc8b777 100644
--- a/src/target/firmware/include/layer1/sync.h
+++ b/src/target/firmware/include/layer1/sync.h
@@ -28,6 +28,13 @@ enum l1s_chan {
_NUM_L1S_CHAN
};
+enum l1_compl {
+ L1_COMPL_FB,
+};
+
+typedef void l1_compl_cb(enum l1_compl c);
+
+#define L1S_NUM_COMPL 32
#define L1S_NUM_NEIGH_CELL 6
struct l1s_state {
@@ -52,6 +59,11 @@ struct l1s_state {
/* Transmit queues of pending packets for main DCCH and ACCH */
struct llist_head tx_queue[_NUM_L1S_CHAN];
+ /* Which L1A completions are scheduled right now */
+ uint32_t scheduled_compl;
+ /* callbacks for each of the completions */
+ l1_compl_cb *completion[L1S_NUM_COMPL];
+
/* Structures below are for L1-task specific parameters, used
* to communicate between l1-sync and l1-async (l23_api) */
struct {
@@ -126,6 +138,9 @@ void l1s_sb_test(uint8_t base_fn);
void l1s_pm_test(uint8_t base_fn, uint16_t arfcn);
void l1s_nb_test(uint8_t base_fn);
+/* schedule a completion */
+void l1s_compl_sched(enum l1_compl c);
+
void l1s_init(void);
/* reset the layer1 as part of synchronizing to a new cell */
diff --git a/src/target/firmware/layer1/async.c b/src/target/firmware/layer1/async.c
index 3db07e1..dda4bf1 100644
--- a/src/target/firmware/layer1/async.c
+++ b/src/target/firmware/layer1/async.c
@@ -69,3 +69,26 @@ void l1a_init(void)
{
l1a_l23api_init();
}
+
+/* Execute pending L1A completions */
+void l1a_compl_execute(void)
+{
+ unsigned long flags;
+ unsigned int scheduled;
+ unsigned int i;
+
+ /* get and reset the currently scheduled tasks */
+ local_irq_save(flags);
+ scheduled = l1s.scheduled_compl;
+ l1s.scheduled_compl = 0;
+ local_irq_restore(flags);
+
+ /* Iterate over list of scheduled completions, call their
+ * respective completion handler */
+ for (i = 0; i < 32; i++) {
+ if (!(scheduled & (1 << i)))
+ continue;
+ /* call completion function */
+ l1s.completion[i](i);
+ }
+}
diff --git a/src/target/firmware/layer1/sync.c b/src/target/firmware/layer1/sync.c
index f5629cf..9ca37ef 100644
--- a/src/target/firmware/layer1/sync.c
+++ b/src/target/firmware/layer1/sync.c
@@ -200,6 +200,16 @@ static inline void check_lost_frame(void)
last_timestamp = timestamp;
}
+/* schedule a completion */
+void l1s_compl_sched(enum l1_compl c)
+{
+ unsigned long flags;
+
+ local_irq_save(flags);
+ l1s.scheduled_compl |= (1 << c);
+ local_irq_restore(flags);
+}
+
/* main routine for synchronous part of layer 1, called by frame interrupt
* generated by TPU once every TDMA frame */
static void l1_sync(void)