summaryrefslogtreecommitdiff
path: root/firmware/target/mips/ingenic_x1000/timer-x1000.c
diff options
context:
space:
mode:
Diffstat (limited to 'firmware/target/mips/ingenic_x1000/timer-x1000.c')
-rw-r--r--firmware/target/mips/ingenic_x1000/timer-x1000.c85
1 files changed, 85 insertions, 0 deletions
diff --git a/firmware/target/mips/ingenic_x1000/timer-x1000.c b/firmware/target/mips/ingenic_x1000/timer-x1000.c
new file mode 100644
index 0000000000..de97cbb3a3
--- /dev/null
+++ b/firmware/target/mips/ingenic_x1000/timer-x1000.c
@@ -0,0 +1,85 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (C) 2021 Aidan MacDonald
11 *
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
16 *
17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18 * KIND, either express or implied.
19 *
20 ****************************************************************************/
21
22#include "timer.h"
23#include "x1000/tcu.h"
24
25#define TIMER_CHN 5
26
27bool timer_set(long cycles, bool start)
28{
29 if(cycles <= 0)
30 return false;
31
32 /* Calculate timer interval */
33 unsigned long counter = cycles;
34 unsigned prescale = 0;
35 while(counter > 0xffff && prescale < 5) {
36 counter /= 4;
37 prescale += 1;
38 }
39
40 /* Duration too long */
41 if(counter > 0xffff)
42 return false;
43
44 /* Unregister old function */
45 if(start && pfn_unregister) {
46 pfn_unregister();
47 pfn_unregister = 0;
48 }
49
50 /* Configure the timer */
51 jz_clr(TCU_STOP, 1 << TIMER_CHN);
52 jz_clr(TCU_ENABLE, 1 << TIMER_CHN);
53 jz_overwritef(TCU_CTRL(TIMER_CHN), SOURCE_V(EXT), PRESCALE(prescale));
54 jz_write(TCU_CMP_FULL(TIMER_CHN), counter);
55 jz_write(TCU_CMP_HALF(TIMER_CHN), 0);
56 jz_clr(TCU_FLAG, 1 << TIMER_CHN);
57 jz_clr(TCU_MASK, 1 << TIMER_CHN);
58
59 if(start)
60 return timer_start();
61 else
62 return true;
63}
64
65bool timer_start(void)
66{
67 jz_set(TCU_ENABLE, 1 << TIMER_CHN);
68 return true;
69}
70
71void timer_stop(void)
72{
73 jz_clr(TCU_ENABLE, 1 << TIMER_CHN);
74 jz_set(TCU_MASK, 1 << TIMER_CHN);
75 jz_clr(TCU_FLAG, 1 << TIMER_CHN);
76 jz_set(TCU_STOP, 1 << TIMER_CHN);
77}
78
79void TCU1(void)
80{
81 jz_clr(TCU_FLAG, 1 << TIMER_CHN);
82
83 if(pfn_timer)
84 pfn_timer();
85}