TCC78x: Enable interrupts/threading in the bootloader (required now that the storage...
[kugel-rb.git] / firmware / target / arm / tcc780x / timer-tcc780x.c
bloba6c8c1c06062e98c62d5bc6cce3a3679c6b4cd3e
1 /***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
10 * Copyright (C) 2008 by Rob Purchase
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.
17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18 * KIND, either express or implied.
20 ****************************************************************************/
22 #include "config.h"
23 #include "cpu.h"
24 #include "system.h"
25 #include "timer.h"
26 #include "logf.h"
28 static const int prescale_shifts[] = {1, 2, 3, 4, 5, 10, 12};
30 bool __timer_set(long cycles, bool start)
32 bool found = false;
34 int prescale_option = 0;
35 int actual_cycles = 0;
37 /* Use the first prescale that fits Timer4's 20-bit counter */
38 while (!found && prescale_option < 7)
40 actual_cycles = cycles >> prescale_shifts[prescale_option];
42 if (actual_cycles < 0x100000)
43 found = true;
44 else
45 prescale_option++;
48 if (!found)
49 return false;
51 /* Stop the timer and set new prescale & ref count */
52 TCFG(4) &= ~TCFG_EN;
53 TCFG(4) = prescale_option << TCFG_SEL;
54 TREF(4) = actual_cycles;
56 if (start && pfn_unregister != NULL)
58 pfn_unregister();
59 pfn_unregister = NULL;
62 return true;
65 bool __timer_register(void)
67 int oldstatus = disable_interrupt_save(IRQ_STATUS);
69 TCFG(4) |= TCFG_CLEAR | TCFG_IEN | TCFG_EN;
71 restore_interrupt(oldstatus);
73 return true;
76 void __timer_unregister(void)
78 int oldstatus = disable_interrupt_save(IRQ_STATUS);
80 TCFG(4) &= ~TCFG_EN;
82 restore_interrupt(oldstatus);