1 /******************************************************************************
2 * *
3 * License Agreement *
4 * *
5 * Copyright (c) 2003 Altera Corporation, San Jose, California, USA. *
6 * All rights reserved. *
7 * *
8 * Permission is hereby granted, free of charge, to any person obtaining a *
9 * copy of this software and associated documentation files (the "Software"), *
10 * to deal in the Software without restriction, including without limitation *
11 * the rights to use, copy, modify, merge, publish, distribute, sublicense, *
12 * and/or sell copies of the Software, and to permit persons to whom the *
13 * Software is furnished to do so, subject to the following conditions: *
14 * *
15 * The above copyright notice and this permission notice shall be included in *
16 * all copies or substantial portions of the Software. *
17 * *
18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR *
19 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *
20 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE *
21 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER *
22 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *
23 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *
24 * DEALINGS IN THE SOFTWARE. *
25 * *
26 * *
27 * Altera does not recommend, suggest or require that this reference design *
28 * file be used in conjunction or combination with any other product. *
29 ******************************************************************************/
30
31 #include <string.h>
32
33 #include "sys/alt_alarm.h"
34 #include "sys/alt_irq.h"
35
36 #include "altera_avalon_timer.h"
37 #include "altera_avalon_timer_regs.h"
38
39 #include "alt_types.h"
40 #include "sys/alt_log_printf.h"
41
42 /*
43 * alt_avalon_timer_sc_irq() is the interrupt handler used for the system
44 * clock. This is called periodically when a timer interrupt occurs. The
45 * function first clears the interrupt condition, and then calls the
46 * alt_tick() function to notify the system that a timer tick has occurred.
47 *
48 * alt_tick() increments the system tick count, and updates any registered
49 * alarms, see alt_tick.c for further details.
50 */
51 #ifdef ALT_ENHANCED_INTERRUPT_API_PRESENT
alt_avalon_timer_sc_irq(void * base)52 static void alt_avalon_timer_sc_irq (void* base)
53 #else
54 static void alt_avalon_timer_sc_irq (void* base, alt_u32 id)
55 #endif
56 {
57 alt_irq_context cpu_sr;
58
59 /* clear the interrupt */
60 IOWR_ALTERA_AVALON_TIMER_STATUS (base, 0);
61
62 /*
63 * Dummy read to ensure IRQ is negated before the ISR returns.
64 * The control register is read because reading the status
65 * register has side-effects per the register map documentation.
66 */
67 IORD_ALTERA_AVALON_TIMER_CONTROL (base);
68
69 /* ALT_LOG - see altera_hal/HAL/inc/sys/alt_log_printf.h */
70 ALT_LOG_SYS_CLK_HEARTBEAT();
71
72 /*
73 * Notify the system of a clock tick. disable interrupts
74 * during this time to safely support ISR preemption
75 */
76 cpu_sr = alt_irq_disable_all();
77 alt_tick ();
78 alt_irq_enable_all(cpu_sr);
79 }
80
81 /*
82 * alt_avalon_timer_sc_init() is called to initialise the timer that will be
83 * used to provide the periodic system clock. This is called from the
84 * auto-generated alt_sys_init() function.
85 */
86
alt_avalon_timer_sc_init(void * base,alt_u32 irq_controller_id,alt_u32 irq,alt_u32 freq)87 void alt_avalon_timer_sc_init (void* base, alt_u32 irq_controller_id,
88 alt_u32 irq, alt_u32 freq)
89 {
90 /* set the system clock frequency */
91
92 alt_sysclk_init (freq);
93
94 /* set to free running mode */
95
96 IOWR_ALTERA_AVALON_TIMER_CONTROL (base,
97 ALTERA_AVALON_TIMER_CONTROL_ITO_MSK |
98 ALTERA_AVALON_TIMER_CONTROL_CONT_MSK |
99 ALTERA_AVALON_TIMER_CONTROL_START_MSK);
100
101 /* register the interrupt handler, and enable the interrupt */
102 #ifdef ALT_ENHANCED_INTERRUPT_API_PRESENT
103 alt_ic_isr_register(irq_controller_id, irq, alt_avalon_timer_sc_irq,
104 base, NULL);
105 #else
106 alt_irq_register (irq, base, alt_avalon_timer_sc_irq);
107 #endif
108 }
109