2 * Copyright © 2016 Keith Packard <keithp@keithp.com>
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; version 2 of the License.
8 * This program is distributed in the hope that it will be useful, but
9 * WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11 * General Public License for more details.
13 * You should have received a copy of the GNU General Public License along
14 * with this program; if not, write to the Free Software Foundation, Inc.,
15 * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
19 #include <ao_fast_timer.h>
21 static void (*ao_fast_timer_callback[AO_FAST_TIMER_MAX])(void);
22 static uint8_t ao_fast_timer_count;
23 static uint8_t ao_fast_timer_users;
26 ao_fast_timer_enable(void)
28 lpc_ct16b0.tcr = ((1 << LPC_CT16B_TCR_CEN) |
29 (1 << LPC_CT16B_TCR_CRST));
33 ao_fast_timer_disable(void)
35 lpc_ct16b0.tcr = ((0 << LPC_CT16B_TCR_CEN) |
36 (0 << LPC_CT16B_TCR_CRST));
40 ao_fast_timer_on(void (*callback)(void))
42 ao_fast_timer_callback[ao_fast_timer_count] = callback;
43 if (!ao_fast_timer_count++)
44 ao_fast_timer_enable();
48 ao_fast_timer_off(void (*callback)(void))
52 for (n = 0; n < ao_fast_timer_count; n++)
53 if (ao_fast_timer_callback[n] == callback) {
54 for (; n < ao_fast_timer_count-1; n++) {
55 ao_fast_timer_callback[n] = ao_fast_timer_callback[n+1];
57 if (!--ao_fast_timer_count)
58 ao_fast_timer_disable();
63 void lpc_ct16b0_isr(void)
65 uint32_t v = lpc_ct16b0.ir;
69 if (v & (1 << LPC_CT16B_IR_MR0INT)) {
70 for (i = 0; i < ao_fast_timer_count; i++)
71 (*ao_fast_timer_callback[i])();
75 #ifndef FAST_TIMER_FREQ
76 #define FAST_TIMER_FREQ 10000
79 #define TIMER_FAST (AO_LPC_SYSCLK / FAST_TIMER_FREQ)
82 ao_fast_timer_init(void)
84 if (!ao_fast_timer_users) {
86 lpc_nvic_set_enable(LPC_ISR_CT16B0_POS);
87 lpc_nvic_set_priority(LPC_ISR_CT16B0_POS, AO_LPC_NVIC_CLOCK_PRIORITY);
88 /* Turn on 16-bit timer CT16B0 */
90 lpc_scb.sysahbclkctrl |= 1 << LPC_SCB_SYSAHBCLKCTRL_CT16B0;
99 lpc_ct16b0.mcr = ((1 << LPC_CT16B_MCR_MR0I) |
100 (1 << LPC_CT16B_MCR_MR0R));
102 lpc_ct16b0.mr[0] = TIMER_FAST;
104 ao_fast_timer_disable();
106 if (ao_fast_timer_users == AO_FAST_TIMER_MAX)
107 ao_panic(AO_PANIC_FAST_TIMER);
108 ao_fast_timer_users++;