summaryrefslogtreecommitdiff
path: root/firmware/timer.c
diff options
context:
space:
mode:
Diffstat (limited to 'firmware/timer.c')
-rw-r--r--firmware/timer.c71
1 files changed, 9 insertions, 62 deletions
diff --git a/firmware/timer.c b/firmware/timer.c
index 044b871b3f..8cd165bd35 100644
--- a/firmware/timer.c
+++ b/firmware/timer.c
@@ -29,64 +29,22 @@
29static int timer_prio = -1; 29static int timer_prio = -1;
30void SHAREDBSS_ATTR (*pfn_timer)(void) = NULL; /* timer callback */ 30void SHAREDBSS_ATTR (*pfn_timer)(void) = NULL; /* timer callback */
31void SHAREDBSS_ATTR (*pfn_unregister)(void) = NULL; /* unregister callback */ 31void SHAREDBSS_ATTR (*pfn_unregister)(void) = NULL; /* unregister callback */
32#if defined CPU_PP
33static long SHAREDBSS_ATTR cycles_new = 0;
34#endif
35 32
36#ifndef __TIMER_SET 33#ifndef __TIMER_SET
37/* Define these if not defined by target to make the #else cases compile 34/* Define these if not defined by target to make the #else cases compile
38 * even if the target doesn't have them implemented. */ 35 * even if the target doesn't have them implemented. */
39#define __TIMER_SET(cycles, set) false 36#define __TIMER_SET(cycles, set) false
40#define __TIMER_START() false 37#if NUM_CORES > 1
41#define __TIMER_STOP(...) 38#define __TIMER_START(int_prio, core) false
39#else
40#define __TIMER_START(int_prio) false
41#endif
42#define __TIMER_STOP()
42#endif 43#endif
43
44/* interrupt handler */
45#if defined(CPU_PP)
46void TIMER2(void)
47{
48 TIMER2_VAL; /* ACK interrupt */
49 if (cycles_new > 0)
50 {
51 TIMER2_CFG = 0xc0000000 | (cycles_new - 1);
52 cycles_new = 0;
53 }
54 if (pfn_timer != NULL)
55 {
56 cycles_new = -1;
57 /* "lock" the variable, in case timer_set_period()
58 * is called within pfn_timer() */
59 pfn_timer();
60 cycles_new = 0;
61 }
62}
63#endif /* CONFIG_CPU */
64 44
65static bool timer_set(long cycles, bool start) 45static bool timer_set(long cycles, bool start)
66{ 46{
67#if defined(CPU_PP)
68 if (cycles > 0x20000000 || cycles < 2)
69 return false;
70
71 if (start)
72 {
73 if (pfn_unregister != NULL)
74 {
75 pfn_unregister();
76 pfn_unregister = NULL;
77 }
78 CPU_INT_DIS = TIMER2_MASK;
79 COP_INT_DIS = TIMER2_MASK;
80 }
81 if (start || (cycles_new == -1)) /* within isr, cycles_new is "locked" */
82 TIMER2_CFG = 0xc0000000 | (cycles - 1); /* enable timer */
83 else
84 cycles_new = cycles;
85
86 return true;
87#else
88 return __TIMER_SET(cycles, start); 47 return __TIMER_SET(cycles, start);
89#endif /* CONFIG_CPU */
90} 48}
91 49
92/* Register a user timer, called every <cycles> TIMER_FREQ cycles */ 50/* Register a user timer, called every <cycles> TIMER_FREQ cycles */
@@ -109,18 +67,12 @@ bool timer_register(int reg_prio, void (*unregister_callback)(void),
109 pfn_unregister = unregister_callback; 67 pfn_unregister = unregister_callback;
110 timer_prio = reg_prio; 68 timer_prio = reg_prio;
111 69
112#if defined(CPU_PP)
113 /* unmask interrupt source */
114#if NUM_CORES > 1 70#if NUM_CORES > 1
115 if (core == COP) 71 return __TIMER_START(int_prio, core);
116 COP_INT_EN = TIMER2_MASK;
117 else
118#endif
119 CPU_INT_EN = TIMER2_MASK;
120 return true;
121#else 72#else
122 return __TIMER_START(int_prio); 73 return __TIMER_START(int_prio);
123#endif 74#endif
75
124 /* Cover for targets that don't use all these */ 76 /* Cover for targets that don't use all these */
125 (void)reg_prio; 77 (void)reg_prio;
126 (void)unregister_callback; 78 (void)unregister_callback;
@@ -137,13 +89,8 @@ bool timer_set_period(long cycles)
137 89
138void timer_unregister(void) 90void timer_unregister(void)
139{ 91{
140#if defined(CPU_PP)
141 TIMER2_CFG = 0; /* stop timer 2 */
142 CPU_INT_DIS = TIMER2_MASK;
143 COP_INT_DIS = TIMER2_MASK;
144#else
145 __TIMER_STOP(); 92 __TIMER_STOP();
146#endif 93
147 pfn_timer = NULL; 94 pfn_timer = NULL;
148 pfn_unregister = NULL; 95 pfn_unregister = NULL;
149 timer_prio = -1; 96 timer_prio = -1;