source: rtems/c/src/lib/libcpu/sh/sh7045/clock/ckinit.c @ 4a238002

4.104.114.84.95
Last change on this file since 4a238002 was 4a238002, checked in by Joel Sherrill <joel.sherrill@…>, on Nov 18, 1999 at 9:22:58 PM

Patch from "John M. Mills" <jmills@…> with subsequent cleanup from
Ralf Corsepius <corsepiu@…> that adds initial Hitachi SH-2
support to RTEMS. Ralf's comments are:

Changes:
------

  1. SH-Port:
  • Many files renamed.
  • CONSOLE_DEVNAME and MHZ defines removed from libcpu.
  • console.c moved to libbsp/sh/shared, build in libbsp/sh/<BSP>/console applying VPATH.
  • CONSOLE_DEVNAME made BSP-specific, replacement is defined in bsp.h
  • MHZ define replaced with HZ (extendent resolution) in custom/*.cfg
  • -DHZ=HZ used in bspstart.c, only
  • Makefile variable HZ used in bsp-dependent directories only.
  1. SH1-Port
  • clock-driver rewritten to provide better resolution for odd CPU frequencies. This driver is only partially tested on hardware, ie. sightly experimental, but I don't expect severe problems with it.
  • Polling SCI-driver added. This driver is experimental and completly untested yet. Therefore it is not yet used for the console (/dev/console is still pointing to /dev/null, cf. gensh1/bsp.h).
  • minor changes to the timer driver
  • SH1 specific delay()/CPU_delay() now is implemented as a function
  1. SH2-Port
  • Merged
  • IMO, the code is still in its infancy. Therefore I have interspersed comments (FIXME) it for items which I think John should look after.
  • sci and console drivers partially rewritten and extended (John, I hope you don't mind).
  • Copyright notices are not yet adapted
  • Property mode set to 100644
File size: 7.3 KB
Line 
1/*
2 *  This file contains the clock driver the Hitachi SH 704X
3 *
4 *  Authors: Ralf Corsepius (corsepiu@faw.uni-ulm.de) and
5 *           Bernd Becker (becker@faw.uni-ulm.de)
6 *
7 *  COPYRIGHT (c) 1997-1998, FAW Ulm, Germany
8 *
9 *  This program is distributed in the hope that it will be useful,
10 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
11 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
12 *
13 *
14 *  COPYRIGHT (c) 1998.
15 *  On-Line Applications Research Corporation (OAR).
16 *  Copyright assigned to U.S. Government, 1994.
17 *
18 *      Modified to reflect registers of sh7045 processor:
19 *      John M. Mills (jmills@tga.com)
20 *      TGA Technologies, Inc.
21 *      100 Pinnacle Way, Suite 140
22 *      Norcross, GA 30071 U.S.A.
23 *      August, 1999
24 *
25 *      This modified file may be copied and distributed in accordance
26 *      the above-referenced license. It is provided for critique and
27 *      developmental purposes without any warranty nor representation
28 *      by the authors or by TGA Technologies.
29 *
30 *  The license and distribution terms for this file may be
31 *  found in the file LICENSE in this distribution or at
32 *  http://www.OARcorp.com/rtems/license.html.
33 *
34 *  $Id$
35 */
36
37#include <rtems.h>
38
39#include <stdlib.h>
40
41#include <rtems/libio.h>
42#include <rtems/score/sh_io.h>
43#include <rtems/score/sh.h>
44#include <rtems/score/ispsh7045.h>
45#include <rtems/score/iosh7045.h>
46
47#define _MTU_COUNTER0_MICROSECOND (Clock_MHZ/4)
48
49#ifndef CLOCKPRIO
50#define CLOCKPRIO 10
51#endif
52
53#define MTU0_STARTMASK  0xfe
54#define MTU0_SYNCMASK   0xfe
55#define MTU0_MODEMASK   0xc0
56#define MTU0_TCRMASK    0x01 /* bit 7 also used, vs 703x */
57#define MTU0_STAT_MASK  0xc0
58#define MTU0_IRQMASK    0xfe
59#define MTU0_TIERMASK   0x01
60#define IPRC_MTU0_MASK  0xff0f
61#define MTU0_TIORVAL    0x08
62
63/*
64 *  The interrupt vector number associated with the clock tick device
65 *  driver.
66 */
67
68#define CLOCK_VECTOR MTUA0_ISP_V
69
70/*
71 *  Clock_driver_ticks is a monotonically increasing counter of the
72 *  number of clock ticks since the driver was initialized.
73 */
74
75volatile rtems_unsigned32 Clock_driver_ticks;
76
77static void Clock_exit( void );
78static rtems_isr Clock_isr( rtems_vector_number vector );
79static rtems_unsigned32 Clock_MHZ ;
80
81/*
82 *  Clock_isrs is the number of clock ISRs until the next invocation of
83 *  the RTEMS clock tick routine.  The clock tick device driver
84 *  gets an interrupt once a millisecond and counts down until the
85 *  length of time between the user configured microseconds per tick
86 *  has passed.
87 */
88
89rtems_unsigned32 Clock_isrs;              /* ISRs until next tick */
90static rtems_unsigned32 Clock_isrs_const;        /* only calculated once */
91
92/*
93 * These are set by clock driver during its init
94 */
95 
96rtems_device_major_number rtems_clock_major = ~0;
97rtems_device_minor_number rtems_clock_minor;
98
99/*
100 *  The previous ISR on this clock tick interrupt vector.
101 */
102
103rtems_isr_entry  Old_ticker;
104
105/*
106 *  Isr Handler
107 */
108
109rtems_isr Clock_isr(
110  rtems_vector_number vector
111)
112{
113  /*
114   * bump the number of clock driver ticks since initialization
115   *
116
117   * determine if it is time to announce the passing of tick as configured
118   * to RTEMS through the rtems_clock_tick directive
119   *
120   * perform any timer dependent tasks
121   */
122  unsigned8 temp;
123
124  /* reset the flags of the status register */
125  temp = read8( MTU_TSR0) & MTU0_STAT_MASK;
126  write8( temp, MTU_TSR0);
127
128  Clock_driver_ticks++ ;
129
130  if( Clock_isrs == 1)
131    {
132      rtems_clock_tick();
133      Clock_isrs = Clock_isrs_const;
134    }
135  else
136    {
137      Clock_isrs-- ;
138    }
139}
140
141/*
142 *  Install_clock
143 *
144 *  Install a clock tick handler and reprograms the chip.  This
145 *  is used to initially establish the clock tick.
146 */
147
148void Install_clock(
149  rtems_isr_entry clock_isr
150)
151{
152  unsigned8 temp8 = 0;
153 
154  /*
155   *  Initialize the clock tick device driver variables
156   */
157
158  Clock_driver_ticks = 0;
159  Clock_isrs_const = rtems_configuration_get_microseconds_per_tick() / 10000;
160  Clock_isrs = Clock_isrs_const;
161
162  Clock_MHZ = rtems_cpu_configuration_get_clicks_per_second() / 1000000 ;
163
164  /*
165   *  If ticks_per_timeslice is configured as non-zero, then the user
166   *  wants a clock tick.
167   */
168
169  if ( rtems_configuration_get_ticks_per_timeslice() ) {
170    rtems_interrupt_catch( Clock_isr, CLOCK_VECTOR, &Old_ticker );
171    /*
172     *  Hardware specific initialize goes here
173     */
174   
175    /* stop Timer 0 */
176    temp8 = read8( MTU_TSTR) & MTU0_STARTMASK;
177    write8( temp8, MTU_TSTR);
178
179    /* set initial counter value to 0 */
180    write16( 0, MTU_TCNT0);
181
182    /* Timer 0 runs independent */
183    temp8 = read8( MTU_TSYR) & MTU0_SYNCMASK;
184    write8( temp8, MTU_TSYR);
185
186    /* Timer 0 normal mode */
187    temp8 = read8( MTU_TMDR0) & MTU0_MODEMASK;
188    write8( temp8, MTU_TMDR0);
189
190    /* TCNT is cleared by GRA ; internal clock /4 */
191    write8( MTU0_TCRMASK , MTU_TCR0);
192
193    /* use GRA without I/O - pins  */
194    write8( MTU0_TIORVAL, MTU_TIORL0); 
195   
196    /* reset flags of the status register */
197    temp8 = read8( MTU_TSR0) & MTU0_STAT_MASK;
198    write8( temp8, MTU_TSR0);
199
200    /* Irq if is equal GRA */
201    temp8 = read8( MTU_TIER0) | MTU0_TIERMASK;
202    write8( temp8, MTU_TIER0);
203
204    /* set interrupt priority */
205    if( sh_set_irq_priority( CLOCK_VECTOR, CLOCKPRIO ) != RTEMS_SUCCESSFUL)
206      rtems_fatal_error_occurred( RTEMS_NOT_CONFIGURED);
207
208    /* set counter limits */
209    write16( _MTU_COUNTER0_MICROSECOND * 
210      rtems_configuration_get_microseconds_per_tick(),
211
212             MTU_GR0A);
213   
214    /* start counter */
215    temp8 = read8( MTU_TSTR) |~MTU0_STARTMASK;
216    write8( temp8, MTU_TSTR);
217   
218  }
219
220  /*
221   *  Schedule the clock cleanup routine to execute if the application exits.
222   */
223
224  atexit( Clock_exit );
225}
226
227/*
228 *  Clean up before the application exits
229 */
230
231void Clock_exit( void )
232{
233  unsigned8 temp8 = 0;
234  if ( rtems_configuration_get_ticks_per_timeslice() ) {
235
236    /* turn off the timer interrupts */
237    /* set interrupt priority to 0 */
238    if( sh_set_irq_priority( CLOCK_VECTOR, 0 ) != RTEMS_SUCCESSFUL)
239      rtems_fatal_error_occurred( RTEMS_UNSATISFIED);
240
241/*
242 *   temp16 = read16( MTU_TIER0) & IPRC_MTU0_IRQMASK;
243 *   write16( temp16, MTU_TIER0);
244 */
245
246    /* stop counter */
247    temp8 = read8( MTU_TSTR) & MTU0_STARTMASK;
248    write8( temp8, MTU_TSTR);
249
250    /* old vector shall not be installed */
251  }
252}
253
254/*
255 *  Clock_initialize
256 *
257 *  Device driver entry point for clock tick driver initialization.
258 */
259
260rtems_device_driver Clock_initialize(
261  rtems_device_major_number major,
262  rtems_device_minor_number minor,
263  void *pargp
264)
265{
266  Install_clock( Clock_isr );
267 
268  /*
269   * make major/minor avail to others such as shared memory driver
270   */
271 
272  rtems_clock_major = major;
273  rtems_clock_minor = minor;
274 
275  return RTEMS_SUCCESSFUL;
276}
277
278rtems_device_driver Clock_control(
279  rtems_device_major_number major,
280  rtems_device_minor_number minor,
281  void *pargp
282)
283{
284  rtems_unsigned32 isrlevel;
285  rtems_libio_ioctl_args_t *args = pargp;
286 
287  if (args != 0)
288    {
289      /*
290       * This is hokey, but until we get a defined interface
291       * to do this, it will just be this simple...
292       */
293     
294      if (args->command == rtems_build_name('I', 'S', 'R', ' '))
295        {
296          Clock_isr(CLOCK_VECTOR);
297        }
298      else if (args->command == rtems_build_name('N', 'E', 'W', ' '))
299        {
300          rtems_isr_entry       ignored ;
301          rtems_interrupt_disable( isrlevel );
302          rtems_interrupt_catch( args->buffer, CLOCK_VECTOR, &ignored );
303         
304          rtems_interrupt_enable( isrlevel );
305        }
306    }
307  return RTEMS_SUCCESSFUL;
308}
Note: See TracBrowser for help on using the repository browser.