source: rtems/c/src/lib/libcpu/arm/at91rm9200/clock/clock.c @ d3490f27

4.104.114.84.95
Last change on this file since d3490f27 was 77bb84e, checked in by Joel Sherrill <joel.sherrill@…>, on 08/17/05 at 19:25:00

2005-08-17 Lars Munch <lars@…>

PR 727/bsps

  • at91rm9200/clock/clock.c: Correct the equation so 10 milliseconds tick is not 9.365 miliseconds long.
  • Property mode set to 100644
File size: 4.0 KB
Line 
1/*
2 *  AT91RM9200 clock specific using the System Timer
3 *
4 *  Copyright (c) 2003 by Cogent Computer Systems
5 *  Written by Mike Kelly <mike@cogcomp.com>
6 *         and Jay Monkman <jtm@lopingdog.com>
7 *
8 *  The license and distribution terms for this file may be
9 *  found in the file LICENSE in this distribution or at
10 *
11 *  http://www.OARcorp.com/rtems/license.html.
12 *
13 *
14 *  $Id$
15 */
16#include <rtems.h>
17#include <rtems/clockdrv.h>
18#include <rtems/libio.h>
19
20#include <stdlib.h>
21#include <bsp.h>
22#include <irq.h>
23#include <at91rm9200.h>
24#include <at91rm9200_pmc.h>
25
26
27rtems_device_major_number rtems_clock_major = ~0;
28rtems_device_minor_number rtems_clock_minor;
29volatile uint32_t Clock_driver_ticks;
30static unsigned long st_pimr_reload;
31
32rtems_isr clock_isr(rtems_vector_number vector);
33void Clock_exit(void);
34static void clock_isr_on(const rtems_irq_connect_data *unused);
35static void clock_isr_off(const rtems_irq_connect_data *unused);
36static int clock_isr_is_on(const rtems_irq_connect_data *irq);
37
38/* Replace the first value with the clock's interrupt name. */
39rtems_irq_connect_data clock_isr_data = {AT91RM9200_INT_SYSIRQ,   
40                                         (rtems_irq_hdl)clock_isr,
41                                         clock_isr_on,
42                                         clock_isr_off,
43                                         clock_isr_is_on,
44                                         3,     /* unused for ARM cpus */
45                                         0 };   /* unused for ARM cpus */
46
47
48rtems_isr clock_isr(rtems_vector_number vector)
49{
50    uint32_t st_str;
51
52    Clock_driver_ticks++;
53
54    /* read the status to clear the int */
55    st_str = ST_REG(ST_SR);
56
57    /* reload the timer value */
58    ST_REG(ST_PIMR) = st_pimr_reload;
59
60    rtems_clock_tick();
61}
62
63void Install_clock(rtems_isr_entry clock_isr)
64{
65    uint32_t st_str;
66    int slck;
67
68    Clock_driver_ticks = 0;
69
70    BSP_install_rtems_irq_handler(&clock_isr_data);
71
72    /* the system timer is driven from SLCK */
73    slck = at91rm9200_get_slck();
74    st_pimr_reload = ((BSP_Configuration.microseconds_per_tick * slck) /
75                      1000000);
76
77    /* read the status to clear the int */
78    st_str = ST_REG(ST_SR);
79   
80    /* set priority */
81    AIC_SMR_REG(AIC_SMR_SYSIRQ) = AIC_SMR_PRIOR(0x7);
82
83    /* set the timer value */
84    ST_REG(ST_PIMR) = st_pimr_reload;
85
86    atexit( Clock_exit );
87}
88
89void Clock_exit( void )
90{
91    BSP_remove_rtems_irq_handler(&clock_isr_data);
92}
93
94rtems_device_driver Clock_initialize(
95    rtems_device_major_number major,
96    rtems_device_minor_number minor,
97    void *pargp
98    )
99{
100    Install_clock( clock_isr );
101 
102    rtems_clock_major = major;
103    rtems_clock_minor = minor;
104
105    return RTEMS_SUCCESSFUL;
106}
107
108rtems_device_driver Clock_control(
109    rtems_device_major_number major,
110    rtems_device_minor_number minor,
111    void *pargp
112)
113{
114    uint32_t  isrlevel;
115    rtems_libio_ioctl_args_t *args = pargp;
116   
117    if (args == 0) {
118        return RTEMS_SUCCESSFUL;
119    }
120 
121    if (args->command == rtems_build_name('I', 'S', 'R', ' ')) {
122        clock_isr(0);
123    } else if (args->command == rtems_build_name('N', 'E', 'W', ' ')) {
124        rtems_interrupt_disable(isrlevel);
125
126        BSP_install_rtems_irq_handler(args->buffer);
127
128        rtems_interrupt_enable(isrlevel);
129    }
130 
131    return RTEMS_SUCCESSFUL;
132}
133
134/**
135 * Enables clock interrupt.
136 *
137 * If the interrupt is always on, this can be a NOP.
138 */
139static void clock_isr_on(const rtems_irq_connect_data *unused)
140{
141    /* enable timer interrupt */
142    ST_REG(ST_IER) = ST_SR_PITS;
143}
144
145/**
146 * Disables clock interrupts
147 *
148 * If the interrupt is always on, this can be a NOP.
149 */
150static void clock_isr_off(const rtems_irq_connect_data *unused)
151{
152    /* disable timer interrupt */
153    ST_REG(ST_IDR) = ST_SR_PITS;
154    return;
155}
156
157/**
158 * Tests to see if clock interrupt is enabled, and returns 1 if so.
159 * If interrupt is not enabled, returns 0.
160 *
161 * If the interrupt is always on, this always returns 1.
162 */
163static int clock_isr_is_on(const rtems_irq_connect_data *irq)
164{
165    /* check timer interrupt */
166    return ST_REG(ST_IMR) & ST_SR_PITS;
167}
Note: See TracBrowser for help on using the repository browser.