source: rtems/c/src/lib/libcpu/m68k/mcf5272/clock/ckinit.c @ 64bb079

4.104.114.84.95
Last change on this file since 64bb079 was ee5769ad, checked in by Ralf Corsepius <ralf.corsepius@…>, on 10/21/04 at 13:21:26

2004-10-21 Ralf Corsepius <ralf_corsepius@…>

  • clock/ckinit.c, include/mcf5272.h, timer/timer.c: Use POSIX fixed-size types.
  • Property mode set to 100644
File size: 6.3 KB
Line 
1/*
2 *  Clock Driver for MCF5272 CPU
3 *
4 *  This driver initailizes timer1 on the MCF5272 as the
5 *  main system clock
6 *
7 *  Copyright 2004 Cogent Computer Systems
8 *  Author: Jay Monkman <jtm@lopingdog.com>
9 *
10 *  Based on MCF5206 clock driver by
11 *    Victor V. Vengerov <vvv@oktet.ru>
12 *
13 *  Based on work:
14 *    David Fiddes, D.J@fiddes.surfaid.org
15 *    http://www.calm.hw.ac.uk/davidf/coldfire/
16 *
17 *  COPYRIGHT (c) 1989-1998.
18 *  On-Line Applications Research Corporation (OAR).
19 *  Copyright assigned to U.S. Government, 1994.
20 *
21 *  The license and distribution terms for this file may be
22 *  found in the file LICENSE in this distribution or at
23 *
24 *  http://www.OARcorp.com/rtems/license.html.
25 *
26 *  ckinit.c,v 1.1 2001/10/26 19:32:40 joel Exp
27 */
28
29#include <stdlib.h>
30#include <bsp.h>
31#include <rtems/libio.h>
32#include <mcf5272/mcf5272.h>
33
34/*
35 * Clock_driver_ticks is a monotonically increasing counter of the
36 * number of clock ticks since the driver was initialized.
37 */
38volatile uint32_t Clock_driver_ticks;
39
40
41/*
42 * These are set by clock driver during its init
43 */
44 
45rtems_device_major_number rtems_clock_major = ~0;
46rtems_device_minor_number rtems_clock_minor;
47
48rtems_isr (*rtems_clock_hook)(rtems_vector_number) = NULL;
49
50/* Clock_isr --
51 *     This handles the timer interrupt by clearing the timer's interrupt
52 *     flag and announcing the clock tick to the system.
53 *
54 * PARAMETERS:
55 *     vector - timer interrupt vector number
56 
57 * RETURNS:
58 *     none
59 */
60rtems_isr
61Clock_isr (rtems_vector_number vector)
62{
63    /* Clear pending interrupt... */
64    g_timer_regs->ter1 = MCF5272_TER_REF | MCF5272_TER_CAP;
65
66    /* Announce the clock tick */
67    Clock_driver_ticks++;
68    rtems_clock_tick();
69    if (rtems_clock_hook != NULL) {
70        rtems_clock_hook(vector);
71    }
72}
73
74
75/* Clock_exit --
76 *     This shuts down the timer if it was enabled and removes it
77 *     from the MCF5206E interrupt mask.
78 *
79 * PARAMETERS:
80 *     none
81 *
82 * RETURNS:
83 *     none
84 */
85void
86Clock_exit(void)
87{
88    if (BSP_Configuration.ticks_per_timeslice) {
89        uint32_t icr;
90        /* disable all timer1 interrupts */
91        icr = g_intctrl_regs->icr1;
92        icr = icr & ~(MCF5272_ICR1_TMR1_MASK | MCF5272_ICR1_TMR1_PI);
93        icr |= (MCF5272_ICR1_TMR1_IPL(0) | MCF5272_ICR1_TMR1_PI);
94        g_intctrl_regs->icr1 = icr;
95       
96        /* reset timer1 */
97        g_timer_regs->tmr1 = MCF5272_TMR_CLK_STOP;
98       
99        /* clear pending */
100        g_timer_regs->ter1 = MCF5272_TER_REF | MCF5272_TER_CAP;
101    }
102}
103
104
105/* Install_clock --
106 *     This initialises timer1 with the BSP timeslice config value
107 *     as a reference and sets up the interrupt handler for clock ticks.
108 *
109 * PARAMETERS:
110 *     clock_isr - clock interrupt handler routine
111 *
112 * RETURNS:
113 *     none.
114 */
115static void
116Install_clock(rtems_isr_entry clock_isr)
117{
118    uint32_t icr;
119    Clock_driver_ticks = 0;
120    if (BSP_Configuration.ticks_per_timeslice) {
121       
122        /* Register the interrupt handler */
123        set_vector(clock_isr, BSP_INTVEC_TMR1, 1);
124       
125        /* Reset timer 1 */
126        g_timer_regs->tmr1 = MCF5272_TMR_RST;
127        g_timer_regs->tmr1 = MCF5272_TMR_CLK_STOP;
128        g_timer_regs->tmr1 = MCF5272_TMR_RST;
129        g_timer_regs->tcn1 = 0;  /* reset counter */
130        g_timer_regs->ter1 = MCF5272_TER_REF | MCF5272_TER_CAP;
131       
132        /* Set Timer 1 prescaler so that it counts in microseconds */
133        g_timer_regs->tmr1 = (
134            ((((BSP_SYSTEM_FREQUENCY / 1000000) - 1) << MCF5272_TMR_PS_SHIFT) |
135             MCF5272_TMR_CE_DISABLE                                      |
136             MCF5272_TMR_ORI                                             |
137             MCF5272_TMR_FRR                                             |
138             MCF5272_TMR_CLK_MSTR                                        |
139             MCF5272_TMR_RST));
140
141        /* Set the timer timeout value from the BSP config */     
142        g_timer_regs->trr1 = BSP_Configuration.microseconds_per_tick - 1;
143
144        /* Feed system frequency to the timer */
145        g_timer_regs->tmr1 |= MCF5272_TMR_CLK_MSTR;
146           
147        /* Configure timer1 interrupts */
148        icr = g_intctrl_regs->icr1;
149        icr = icr & ~(MCF5272_ICR1_TMR1_MASK | MCF5272_ICR1_TMR1_PI);
150        icr |= (MCF5272_ICR1_TMR1_IPL(BSP_INTLVL_TMR1) | MCF5272_ICR1_TMR1_PI);
151        g_intctrl_regs->icr1 = icr;
152
153        /* Register the driver exit procedure so we can shutdown */
154        atexit(Clock_exit);
155    }
156}
157
158
159/* Clock_initialize --
160 *     This is called to setup the clock driver. It calls the hardware
161 *     setup function and make the driver major/minor values available
162 *     for other.
163 *
164 * PARAMETERS:
165 *     major - clock device major number
166 *     minor - clock device minor number
167 *     pargp - device driver initialization argument (not used)
168 *
169 * RETURNS:
170 *     RTEMS status code
171 */
172rtems_device_driver
173Clock_initialize(rtems_device_major_number major,
174                 rtems_device_minor_number minor,
175                 void *pargp)
176{
177    Install_clock (Clock_isr);
178 
179    /* Make major/minor avail to others such as shared memory driver */
180    rtems_clock_major = major;
181    rtems_clock_minor = minor;
182 
183    return RTEMS_SUCCESSFUL;
184}
185 
186
187/* Clock_control --
188 *     I/O control (IOCTL) function for Clock driver. At this moment this
189 *     just runs the interrupt handler or re-registers the interrupt handler
190 *     on request.
191 *
192 * PARAMETERS:
193 *     major - clock major device number
194 *     minor - clock minor device number
195 *     pargp - pointer to IOCTL arguments
196 *
197 * RETURNS:
198 *     RTEMS status code
199 */
200rtems_device_driver
201Clock_control(rtems_device_major_number major,
202              rtems_device_minor_number minor,
203              void *pargp)
204{
205    uint32_t isrlevel;
206    rtems_libio_ioctl_args_t *args = pargp;
207
208    if (args)
209    {
210        /*
211         * This is hokey, but until we get a defined interface
212         * to do this, it will just be this simple...
213         */
214        if (args->command == rtems_build_name('I', 'S', 'R', ' '))
215        {
216            Clock_isr(BSP_INTVEC_TMR1);
217        }
218        else if (args->command == rtems_build_name('N', 'E', 'W', ' '))
219        {
220            rtems_interrupt_disable( isrlevel );
221            (void) set_vector( args->buffer, BSP_INTVEC_TMR1, 1 );
222            rtems_interrupt_enable( isrlevel );
223        }
224    }
225    return RTEMS_SUCCESSFUL;
226}
Note: See TracBrowser for help on using the repository browser.