summaryrefslogtreecommitdiff
path: root/firmware
diff options
context:
space:
mode:
Diffstat (limited to 'firmware')
-rw-r--r--firmware/export/timer.h5
-rw-r--r--firmware/target/hosted/kernel-unix.c16
-rw-r--r--firmware/timer.c4
3 files changed, 21 insertions, 4 deletions
diff --git a/firmware/export/timer.h b/firmware/export/timer.h
index b12ec55881..92b26db216 100644
--- a/firmware/export/timer.h
+++ b/firmware/export/timer.h
@@ -30,6 +30,7 @@
30#define TIMER_FREQ 1000000 30#define TIMER_FREQ 1000000
31#endif 31#endif
32 32
33/* NOTE: if unreg cb is defined you are in charge of calling timer_unregister() */
33bool timer_register(int reg_prio, void (*unregister_callback)(void), 34bool timer_register(int reg_prio, void (*unregister_callback)(void),
34 long cycles, void (*timer_callback)(void) 35 long cycles, void (*timer_callback)(void)
35 IF_COP(,int core)); 36 IF_COP(,int core));
@@ -37,6 +38,10 @@ bool timer_set_period(long cycles);
37#ifdef CPU_COLDFIRE 38#ifdef CPU_COLDFIRE
38void timers_adjust_prescale(int multiplier, bool enable_irq); 39void timers_adjust_prescale(int multiplier, bool enable_irq);
39#endif 40#endif
41
42/* NOTE: unregister callbacks are not called by timer_unregister()
43* the unregister_callback only gets called when your timer gets
44* overwritten by a lower priority timer using timer_register() */
40void timer_unregister(void); 45void timer_unregister(void);
41 46
42/* target-specific interface */ 47/* target-specific interface */
diff --git a/firmware/target/hosted/kernel-unix.c b/firmware/target/hosted/kernel-unix.c
index e3c492a8cc..ed1f83cd8c 100644
--- a/firmware/target/hosted/kernel-unix.c
+++ b/firmware/target/hosted/kernel-unix.c
@@ -113,8 +113,8 @@ void (*global_timer_callback)(void);
113 113
114static void timer_cb(union sigval arg) 114static void timer_cb(union sigval arg)
115{ 115{
116 (void)arg; 116 /* check for spurious callbacks [arg.sival_ptr] */
117 if (global_timer_callback) 117 if (global_timer_callback && global_timer_callback == arg.sival_ptr)
118 global_timer_callback(); 118 global_timer_callback();
119} 119}
120 120
@@ -129,12 +129,18 @@ bool timer_register(int reg_prio, void (*unregister_callback)(void),
129 if (reg_prio <= timer_prio || in_us <= 0) 129 if (reg_prio <= timer_prio || in_us <= 0)
130 return false; 130 return false;
131 131
132 if (timer_prio >= 0 && global_unreg_callback) 132 if(timer_prio >= 0)
133 global_unreg_callback(); 133 {
134 if (global_unreg_callback) /* timer has callback user needs to unreg */
135 global_unreg_callback();
136 else /* no callback -- delete timer */
137 timer_delete(timer_tid);
138 }
134 139
135 memset(&sigev, 0, sizeof(sigevent_t)); 140 memset(&sigev, 0, sizeof(sigevent_t));
136 sigev.sigev_notify = SIGEV_THREAD, 141 sigev.sigev_notify = SIGEV_THREAD,
137 sigev.sigev_notify_function = timer_cb; 142 sigev.sigev_notify_function = timer_cb;
143 sigev.sigev_value.sival_ptr = timer_callback; /* store cb to check later */
138 144
139 div_t q = div(in_us, 1000000); 145 div_t q = div(in_us, 1000000);
140 ts.it_value.tv_sec = ts.it_interval.tv_sec = q.quot; 146 ts.it_value.tv_sec = ts.it_interval.tv_sec = q.quot;
@@ -166,4 +172,6 @@ void timer_unregister(void)
166{ 172{
167 timer_delete(timer_tid); 173 timer_delete(timer_tid);
168 timer_prio = -1; 174 timer_prio = -1;
175 global_unreg_callback = NULL;
176 global_timer_callback = NULL;
169} 177}
diff --git a/firmware/timer.c b/firmware/timer.c
index a923290a94..c618f72e02 100644
--- a/firmware/timer.c
+++ b/firmware/timer.c
@@ -42,6 +42,7 @@ bool timer_register(int reg_prio, void (*unregister_callback)(void),
42 return false; 42 return false;
43 43
44 pfn_timer = timer_callback; 44 pfn_timer = timer_callback;
45 /* NOTE: if unreg cb is defined you are in charge of calling timer_unregister() */
45 pfn_unregister = unregister_callback; 46 pfn_unregister = unregister_callback;
46 timer_prio = reg_prio; 47 timer_prio = reg_prio;
47 48
@@ -53,6 +54,9 @@ bool timer_set_period(long cycles)
53 return timer_set(cycles, false); 54 return timer_set(cycles, false);
54} 55}
55 56
57/* NOTE: unregister callbacks are not called by timer_unregister()
58* the unregister_callback only gets called when your timer gets
59* overwritten by a lower priority timer using timer_register() */
56void timer_unregister(void) 60void timer_unregister(void)
57{ 61{
58 timer_stop(); 62 timer_stop();