source: rtems/bsps/sh/gensh4/clock/ckinit.c @ bb99cd0d

5
Last change on this file since bb99cd0d was bb99cd0d, checked in by Sebastian Huber <sebastian.huber@…>, on Dec 5, 2019 at 6:22:33 PM

clock: Simplify driver initialization

Use a system initialization handler instead of a legacy IO driver.

Update #3834.

  • Property mode set to 100644
File size: 5.2 KB
Line 
1/*
2 * This file contains the generic RTEMS clock driver the Hitachi SH 7750
3 */
4
5/*
6 * Copyright (C) 2001 OKTET Ltd., St.-Petersburg, Russia
7 * Author: Victor V. Vengerov <vvv@oktet.ru>
8 *
9 *  COPYRIGHT (c) 2001
10 *  On-Line Applications Research Corporation (OAR).
11 *
12 *  The license and distribution terms for this file may be
13 *  found in the file LICENSE in this distribution or at
14 *  http://www.rtems.org/license/LICENSE.
15 */
16
17#include <rtems.h>
18
19#include <stdlib.h>
20
21#include <rtems/clockdrv.h>
22#include <rtems/score/sh_io.h>
23#include <rtems/score/sh.h>
24#include <rtems/score/ispsh7750.h>
25#include <rtems/score/iosh7750.h>
26
27static void Clock_exit( void );
28
29extern uint32_t bsp_clicks_per_second;
30
31#ifndef CLOCKPRIO
32#define CLOCKPRIO 10
33#endif
34
35/* Clock timer prescaler division ratio */
36#define CLOCK_PRESCALER 4
37#define TCR0_TPSC       SH7750_TCR_TPSC_DIV4
38
39/*
40 *  The interrupt vector number associated with the clock tick device
41 *  driver.
42 */
43#define CLOCK_VECTOR SH7750_EVT_TO_NUM(SH7750_EVT_TUNI0)
44
45/*
46 *  Clock_driver_ticks is a monotonically increasing counter of the
47 *  number of clock ticks since the driver was initialized.
48 */
49volatile uint32_t   Clock_driver_ticks;
50
51static rtems_isr Clock_isr( rtems_vector_number vector );
52
53/*
54 *  The previous ISR on this clock tick interrupt vector.
55 */
56rtems_isr_entry  Old_ticker;
57
58/*
59 *  Isr Handler
60 */
61
62/*
63 * Clock_isr
64 *
65 * Clock interrupt handling routine.
66 */
67static rtems_isr Clock_isr(rtems_vector_number vector)
68{
69  uint16_t   tcr;
70
71  /* reset the timer underflow flag */
72  tcr = read16(SH7750_TCR0);
73  write16(tcr & ~SH7750_TCR_UNF, SH7750_TCR0);
74
75  /* Increment the clock interrupt counter */
76  Clock_driver_ticks++ ;
77
78  /* Invoke rtems clock service routine */
79    rtems_clock_tick();
80}
81
82/*
83 * Install_clock
84 *
85 * Install a clock tick handler and reprograms the chip.  This
86 * is used to initially establish the clock tick.
87 *
88 * SIDE EFFECTS:
89 *     Establish clock interrupt handler, configure Timer 0 hardware
90 */
91static void Install_clock(rtems_isr_entry clock_isr)
92{
93  int cpudiv = 1; /* CPU frequency divider */
94  int tidiv = 1;  /* Timer input frequency divider */
95  uint32_t   timer_divider; /* Calculated Timer Divider value */
96  uint8_t   temp8;
97  uint16_t   temp16;
98
99  /*
100   *  Initialize the clock tick device driver variables
101   */
102
103  Clock_driver_ticks = 0;
104
105  /* Get CPU frequency divider from clock unit */
106  switch (read16(SH7750_FRQCR) & SH7750_FRQCR_IFC) {
107    case SH7750_FRQCR_IFCDIV1:
108      cpudiv = 1;
109      break;
110
111    case SH7750_FRQCR_IFCDIV2:
112      cpudiv = 2;
113      break;
114
115    case SH7750_FRQCR_IFCDIV3:
116      cpudiv = 3;
117      break;
118
119    case SH7750_FRQCR_IFCDIV4:
120      cpudiv = 4;
121      break;
122
123    case SH7750_FRQCR_IFCDIV6:
124      cpudiv = 6;
125      break;
126
127    case SH7750_FRQCR_IFCDIV8:
128      cpudiv = 8;
129      break;
130
131      default:
132        rtems_fatal_error_occurred( RTEMS_NOT_CONFIGURED);
133  }
134
135  /* Get peripheral module frequency divider from clock unit */
136  switch (read16(SH7750_FRQCR) & SH7750_FRQCR_PFC) {
137    case SH7750_FRQCR_PFCDIV2:
138      tidiv = 2 * CLOCK_PRESCALER;
139      break;
140
141    case SH7750_FRQCR_PFCDIV3:
142      tidiv = 3 * CLOCK_PRESCALER;
143      break;
144
145    case SH7750_FRQCR_PFCDIV4:
146      tidiv = 4 * CLOCK_PRESCALER;
147      break;
148
149    case SH7750_FRQCR_PFCDIV6:
150      tidiv = 6 * CLOCK_PRESCALER;
151      break;
152
153    case SH7750_FRQCR_PFCDIV8:
154      tidiv = 8 * CLOCK_PRESCALER;
155      break;
156
157    default:
158      rtems_fatal_error_occurred( RTEMS_NOT_CONFIGURED);
159  }
160  timer_divider =
161      (bsp_clicks_per_second * cpudiv / (tidiv*1000000)) *
162      rtems_configuration_get_microseconds_per_tick();
163
164  /*
165   *  Hardware specific initialization
166   */
167
168  /* Stop the Timer 0 */
169  temp8 = read8(SH7750_TSTR);
170  temp8 &= ~SH7750_TSTR_STR0;
171  write8(temp8, SH7750_TSTR);
172
173  /* Establish interrupt handler */
174  rtems_interrupt_catch( Clock_isr, CLOCK_VECTOR, &Old_ticker );
175
176  /* Reset counter */
177  write32(timer_divider, SH7750_TCNT0);
178
179  /* Load divider */
180  write32(timer_divider, SH7750_TCOR0);
181
182  write16(
183      SH7750_TCR_UNIE |        /* Enable Underflow Interrupt */
184      SH7750_TCR_CKEG_RAISE |  /* Count on rising edge */
185      TCR0_TPSC,               /* Timer prescaler ratio */
186      SH7750_TCR0);
187
188  /* Set clock interrupt priority */
189  temp16 = read16(SH7750_IPRA);
190  temp16 = (temp16 & ~SH7750_IPRA_TMU0) | (CLOCKPRIO << SH7750_IPRA_TMU0_S);
191  write16(temp16, SH7750_IPRA);
192
193  /* Start the Timer 0 */
194  temp8 = read8(SH7750_TSTR);
195  temp8 |= SH7750_TSTR_STR0;
196  write8(temp8, SH7750_TSTR);
197
198  /*
199   *  Schedule the clock cleanup routine to execute if the application exits.
200   */
201  atexit( Clock_exit );
202}
203
204/*
205 * Clock_exit
206 *
207 * Clean up before the application exits
208 *
209 * SIDE EFFECTS:
210 *     Stop Timer 0 counting, set timer 0 interrupt priority level to 0.
211 */
212void
213Clock_exit(void)
214{
215  uint8_t   temp8 = 0;
216  uint16_t   temp16 = 0;
217
218  /* turn off the timer interrupts */
219  /* Stop the Timer 0 */
220  temp8 = read8(SH7750_TSTR);
221  temp8 &= ~SH7750_TSTR_STR0;
222  write8(temp8, SH7750_TSTR);
223
224  /* Lower timer interrupt priority to 0 */
225  temp16 = read16(SH7750_IPRA);
226  temp16 = (temp16 & ~SH7750_IPRA_TMU0) | (0 << SH7750_IPRA_TMU0_S);
227  write16(temp16, SH7750_IPRA);
228
229  /* old vector shall not be installed */
230}
231
232void _Clock_Initialize( void )
233{
234    Install_clock( Clock_isr );
235}
Note: See TracBrowser for help on using the repository browser.