summaryrefslogtreecommitdiff
path: root/firmware/target/arm/s5l8702/timer-s5l8702.c
diff options
context:
space:
mode:
authorCástor Muñoz <cmvidal@gmail.com>2014-11-10 02:39:16 +0100
committerMarcin Bukat <marcin.bukat@gmail.com>2014-11-16 14:18:32 +0100
commit57969698ced265492d2007d39e350b337e163ea4 (patch)
tree770911d70514598218e5b7790b5cfb4f07bd8d2c /firmware/target/arm/s5l8702/timer-s5l8702.c
parent229a02a4eebb61332e8180692d4415a7d49303fd (diff)
downloadrockbox-57969698ced265492d2007d39e350b337e163ea4.tar.gz
rockbox-57969698ced265492d2007d39e350b337e163ea4.zip
iPod Classic: update timer API using 32-bit timers.
Change-Id: I49dab8ae955a339ad0a27402fa21caa411c4ecf6 Reviewed-on: http://gerrit.rockbox.org/1032 Reviewed-by: Marcin Bukat <marcin.bukat@gmail.com>
Diffstat (limited to 'firmware/target/arm/s5l8702/timer-s5l8702.c')
-rw-r--r--firmware/target/arm/s5l8702/timer-s5l8702.c57
1 files changed, 22 insertions, 35 deletions
diff --git a/firmware/target/arm/s5l8702/timer-s5l8702.c b/firmware/target/arm/s5l8702/timer-s5l8702.c
index 61d4d590e4..7c69ab123a 100644
--- a/firmware/target/arm/s5l8702/timer-s5l8702.c
+++ b/firmware/target/arm/s5l8702/timer-s5l8702.c
@@ -26,13 +26,11 @@
26#include "system.h" 26#include "system.h"
27#include "timer.h" 27#include "timer.h"
28 28
29//TODO: This needs calibration once we figure out the clocking 29void INT_TIMERF(void)
30
31void INT_TIMERC(void)
32{ 30{
33 /* clear interrupt */ 31 /* clear interrupt */
34 TCCON = TCCON; 32 TSTAT = (0x07 << 16);
35 33
36 if (pfn_timer != NULL) { 34 if (pfn_timer != NULL) {
37 pfn_timer(); 35 pfn_timer();
38 } 36 }
@@ -40,12 +38,8 @@ void INT_TIMERC(void)
40 38
41bool timer_set(long cycles, bool start) 39bool timer_set(long cycles, bool start)
42{ 40{
43 static const int cs_table[] = {1, 2, 4, 6}; 41 /* stop timer */
44 int prescale, cs; 42 TFCMD = (0 << 0); /* TF_ENABLE */
45 long count;
46
47 /* stop and clear timer */
48 TCCMD = (1 << 1); /* TD_CLR */
49 43
50 /* optionally unregister any previously registered timer user */ 44 /* optionally unregister any previously registered timer user */
51 if (start) { 45 if (start) {
@@ -55,40 +49,33 @@ bool timer_set(long cycles, bool start)
55 } 49 }
56 } 50 }
57 51
58 /* scale the count down with the clock select */ 52 /* There is an odd behaviour when the 32-bit timers are launched
59 for (cs = 0; cs < 4; cs++) { 53 for the first time, the interrupt status bits are set and an
60 count = cycles >> cs_table[cs]; 54 unexpected interrupt is generated if they are enabled. A way to
61 if ((count < 65536) || (cs == 3)) { 55 workaround this is to write the data registers before clearing
62 break; 56 the counter. */
63 } 57 TFDATA0 = cycles;
64 } 58 TFCMD = (1 << 1); /* TF_CLR */
65
66 /* scale the count down with the prescaler */
67 prescale = 1;
68 while (count >= 65536) {
69 count >>= 1;
70 prescale <<= 1;
71 }
72 59
73 /* configure timer */ 60 /* configure timer */
74 TCCON = (1 << 12) | /* TD_INT0_EN */ 61 TFCON = (1 << 12) | /* TF_INT0_EN */
75 (cs << 8) | /* TS_CS */ 62 (4 << 8) | /* TF_CS, 4 = ECLK / 1 */
76 (0 << 4); /* TD_MODE_SEL, 0 = interval mode */ 63 (1 << 6) | /* use ECLK (12MHz) */
77 TCPRE = prescale - 1; 64 (0 << 4); /* TF_MODE_SEL, 0 = interval mode */
78 TCDATA0 = count; 65 TFPRE = 0; /* no prescaler */
79 TCCMD = (1 << 0); /* TD_ENABLE */ 66
80 67 TFCMD = (1 << 0); /* TF_ENABLE */
68
81 return true; 69 return true;
82} 70}
83 71
84bool timer_start(void) 72bool timer_start(void)
85{ 73{
86 TCCMD = (1 << 0); /* TD_ENABLE */ 74 TFCMD = (1 << 0); /* TF_ENABLE */
87 return true; 75 return true;
88} 76}
89 77
90void timer_stop(void) 78void timer_stop(void)
91{ 79{
92 TCCMD = (0 << 0); /* TD_ENABLE */ 80 TFCMD = (0 << 0); /* TF_ENABLE */
93} 81}
94