blob: ff9beab96c507aa7fadd31d63a961c5b1bfe3a4d [file] [log] [blame]
Karl Kurbjun7b97fe22007-09-20 04:46:41 +00001/***************************************************************************
2* __________ __ ___.
3* Open \______ \ ____ ____ | | _\_ |__ _______ ___
4* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7* \/ \/ \/ \/ \/
Karl Kurbjunbebbac82007-09-22 15:43:38 +00008* $Id$
Karl Kurbjun7b97fe22007-09-20 04:46:41 +00009*
10* Copyright (C) 2007 by Karl Kurbjun
11*
Daniel Stenberg2acc0ac2008-06-28 18:10:04 +000012* 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.
Karl Kurbjun7b97fe22007-09-20 04:46:41 +000016*
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 "config.h"
23#include "cpu.h"
24#include "system.h"
25#include "timer.h"
26#include "logf.h"
27
28/* GPB0/TOUT0 should already have been configured as output so that pin
Maurus Cuelenaere95167e02008-04-24 20:08:28 +000029 should not be a functional pin and TIMER0 output unseen there */
Karl Kurbjun7b97fe22007-09-20 04:46:41 +000030void TIMER0(void)
31{
Maurus Cuelenaere910fd782008-05-07 13:33:29 +000032 IO_INTC_IRQ0 = INTR_IRQ0_TMR0; /* clear TIMER0 interrupt */
Karl Kurbjun7b97fe22007-09-20 04:46:41 +000033 if (pfn_timer != NULL)
34 pfn_timer();
35}
36
Karl Kurbjun5db6b512007-11-07 05:30:31 +000037bool __timer_set(long cycles, bool start)
38{
39 int oldlevel;
40 unsigned int divider=cycles, prescaler=0;
41
42 if(cycles<1)
43 return false;
44
Maurus Cuelenaere95167e02008-04-24 20:08:28 +000045 oldlevel = set_irq_level(HIGHEST_IRQ_LEVEL);
46
47 IO_CLK_MOD2 |= CLK_MOD2_TMR0; //enable TIMER0 clock!!!!!!!!!
48
Karl Kurbjun5db6b512007-11-07 05:30:31 +000049 IO_TIMER0_TMMD = CONFIG_TIMER0_TMMD_STOP;
50
51 if (start && pfn_unregister != NULL)
52 {
53 pfn_unregister();
54 pfn_unregister = NULL;
55 }
56
Michael Sevakisaf395f42008-03-26 01:50:41 +000057 oldlevel = disable_irq_save();
Karl Kurbjun5db6b512007-11-07 05:30:31 +000058
59 /* Increase prescale values starting from 0 to make the cycle count fit */
60 while(divider>65535 && prescaler<1024)
61 {
62 prescaler++;
63 divider=cycles/(prescaler+1);
64 }
65
66 IO_TIMER0_TMPRSCL = prescaler;
67 IO_TIMER0_TMDIV = divider;
68
Michael Sevakisaf395f42008-03-26 01:50:41 +000069 restore_irq(oldlevel);
Karl Kurbjun5db6b512007-11-07 05:30:31 +000070
71 return true;
72}
73
Karl Kurbjun7b97fe22007-09-20 04:46:41 +000074static void stop_timer(void)
75{
Maurus Cuelenaere95167e02008-04-24 20:08:28 +000076 IO_INTC_EINT0 &= ~INTR_EINT0_TMR0; //disable TIMER0 interrupt
Karl Kurbjun67ef4502007-09-22 23:17:52 +000077
Maurus Cuelenaere95167e02008-04-24 20:08:28 +000078 IO_INTC_IRQ0 = INTR_IRQ0_TMR0; //clear TIMER0 interrupt
Karl Kurbjun67ef4502007-09-22 23:17:52 +000079
80 IO_TIMER0_TMMD = CONFIG_TIMER0_TMMD_STOP;
Maurus Cuelenaere95167e02008-04-24 20:08:28 +000081
82 IO_CLK_MOD2 &= ~CLK_MOD2_TMR0; //disable TIMER0 clock
Karl Kurbjun7b97fe22007-09-20 04:46:41 +000083}
84
Karl Kurbjun7b97fe22007-09-20 04:46:41 +000085bool __timer_register(void)
86{
Michael Sevakis75f2d442008-03-31 06:00:23 +000087 int oldstatus = disable_interrupt_save(IRQ_FIQ_STATUS);
Maurus Cuelenaere95167e02008-04-24 20:08:28 +000088
Karl Kurbjun7b97fe22007-09-20 04:46:41 +000089 stop_timer();
Maurus Cuelenaere95167e02008-04-24 20:08:28 +000090
91 IO_CLK_MOD2 |= CLK_MOD2_TMR0; //enable TIMER0 clock!!!!!!!!!
Karl Kurbjun7b97fe22007-09-20 04:46:41 +000092
93 /* Turn Timer0 to Free Run mode */
Karl Kurbjun5db6b512007-11-07 05:30:31 +000094 IO_TIMER0_TMMD = CONFIG_TIMER0_TMMD_FREE_RUN;
Karl Kurbjun67ef4502007-09-22 23:17:52 +000095
Maurus Cuelenaere95167e02008-04-24 20:08:28 +000096 IO_INTC_EINT0 |= INTR_EINT0_TMR0; //enable TIMER0 interrupt
Karl Kurbjun7b97fe22007-09-20 04:46:41 +000097
Michael Sevakis75f2d442008-03-31 06:00:23 +000098 restore_interrupt(oldstatus);
Karl Kurbjun7b97fe22007-09-20 04:46:41 +000099
Karl Kurbjun5db6b512007-11-07 05:30:31 +0000100 return true;
Karl Kurbjun7b97fe22007-09-20 04:46:41 +0000101}
102
103void __timer_unregister(void)
104{
Michael Sevakis75f2d442008-03-31 06:00:23 +0000105 int oldstatus = disable_interrupt_save(IRQ_FIQ_STATUS);
Karl Kurbjun7b97fe22007-09-20 04:46:41 +0000106 stop_timer();
Michael Sevakis75f2d442008-03-31 06:00:23 +0000107 restore_interrupt(oldstatus);
Karl Kurbjun7b97fe22007-09-20 04:46:41 +0000108}