1 /***************************************************************************
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
10 * Copyright (C) 2009 by Michael Sevakis
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 ****************************************************************************/
24 #include "ccm-imx31.h"
25 #include "avic-imx31.h"
27 static void __attribute__((interrupt("IRQ"))) EPIT2_HANDLER(void)
29 EPITSR2
= EPITSR_OCIF
; /* Clear the pending status */
31 if (pfn_timer
!= NULL
)
35 static void stop_timer(bool clock_off
)
37 /* Ensure clock gating on (before touching any module registers) */
38 ccm_module_clock_gating(CG_EPIT2
, CGM_ON_RUN_WAIT
);
39 /* Disable insterrupt */
40 avic_disable_int(INT_EPIT2
);
41 /* Clear wakeup mask */
42 CCM_WIMR0
&= ~CCM_WIMR0_IPI_INT_EPIT2
;
44 EPITCR2
&= ~(EPITCR_OCIEN
| EPITCR_EN
);
46 EPITSR2
= EPITSR_OCIF
;
50 /* Final stop, not reset; don't clock module any longer */
51 ccm_module_clock_gating(CG_EPIT2
, CGM_OFF
);
55 bool _timer_set(long cycles
, bool start
)
57 /* Maximum cycle count expressible in the cycles parameter is 2^31-1
58 * and the modulus counter is capable of 2^32-1 and as a result there is
59 * no requirement to use a prescaler > 1. This gives a frequency range of
60 * ~0.015366822Hz - 66000000Hz. The highest input frequency gives the
61 * greatest possible accuracy anyway. */
62 int oldstatus
= disable_interrupt_save(IRQ_FIQ_STATUS
);
64 /* Halt timer if running - leave module clock enabled */
67 if (start
&& pfn_unregister
!= NULL
)
70 pfn_unregister
= NULL
;
74 * EPIT output disconnected,
75 * Enabled in wait mode
76 * Prescale 1 for 66MHz
77 * Reload from modulus register,
78 * Count from load value */
79 EPITCR2
= EPITCR_CLKSRC_IPG_CLK
| EPITCR_WAITEN
| EPITCR_IOVW
|
80 (1-1) << EPITCR_PRESCALER_POS
| EPITCR_RLD
| EPITCR_ENMOD
;
82 /* Event when counter reaches 0 */
85 restore_interrupt(oldstatus
);
89 bool _timer_register(void)
91 int oldstatus
= disable_interrupt_save(IRQ_FIQ_STATUS
);
93 /* Halt timer if running - leave module clock enabled */
96 /* Enable interrupt */
97 EPITCR2
|= EPITCR_OCIEN
;
98 avic_enable_int(INT_EPIT2
, INT_TYPE_IRQ
, INT_PRIO_DEFAULT
,
101 EPITCR2
|= EPITCR_EN
;
103 restore_interrupt(oldstatus
);
107 void _timer_unregister(void)
109 int oldstatus
= disable_interrupt_save(IRQ_FIQ_STATUS
);
110 /* Halt timer if running - stop module clock */
112 restore_interrupt(oldstatus
);