source: rtems/c/src/lib/libcpu/sh/sh7045/sci/sci.c @ 1d5039f

4.104.114.84.95
Last change on this file since 1d5039f was 4a238002, checked in by Joel Sherrill <joel.sherrill@…>, on 11/18/99 at 21:22:58

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: 8.8 KB
Line 
1/*
2 * /dev/sci[0|1] for Hitachi SH 704X
3 *
4 * The SH doesn't have a designated console device. Therefore we "alias"
5 * another device as /dev/console and revector all calls to /dev/console
6 * to this device.
7 *
8 * This approach is similar to installing a sym-link from one device to
9 * another device. If rtems once will support sym-links for devices files,
10 * this implementation could be dropped.
11 *
12 *  Author: Ralf Corsepius (corsepiu@faw.uni-ulm.de)
13 *
14 *  COPYRIGHT (c) 1997-1998, FAW Ulm, Germany
15 *
16 *  This program is distributed in the hope that it will be useful,
17 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
18 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
19 *
20 *
21 *  COPYRIGHT (c) 1998.
22 *  On-Line Applications Research Corporation (OAR).
23 *  Copyright assigned to U.S. Government, 1994.
24 *
25 *  The license and distribution terms for this file may be
26 *  found in the file LICENSE in this distribution or at
27 *  http://www.OARcorp.com/rtems/license.html.
28 *
29 *  Modified to reflect sh7045 processor:
30 *  John M. Mills (jmills@tga.com)
31 *  TGA Technologies, Inc.
32 *  100 Pinnacle Way, Suite 140
33 *  Norcross, GA 30071 U.S.A.
34 *
35 *  This modified file may be copied and distributed in accordance
36 *  the above-referenced license. It is provided for critique and
37 *  developmental purposes without any warranty nor representation
38 *  by the authors or by TGA Technologies.
39 *
40 *  $Id$
41 */
42
43#include <rtems.h>
44
45#include <stdlib.h>
46
47#include <rtems/libio.h>
48#include <iosupp.h>
49#include <rtems/score/sh_io.h>
50#include <rtems/score/ispsh7045.h>
51#include <rtems/score/iosh7045.h>
52#include <sh/sh7_sci.h>
53#include <sh/io_types.h>
54#include <sh/sci.h>
55
56struct scidev_t {
57  char *                        name ;
58  rtems_device_minor_number     minor ;
59  unsigned short                opened ;
60  tcflag_t                      cflags ;
61} sci_device[2] =
62{
63  { "/dev/sci0", 0, 0, B9600 | CS8 },
64  { "/dev/sci1", 0, 0, B9600 | CS8 }
65} ;
66
67/*  local data structures maintain hardware configuration */
68extern int _sci_get_brparms(
69  tcflag_t      cflag,
70  unsigned char *smr,
71  unsigned char *brr );
72
73#if UNUSED
74static sci_setup_t sio_param[2];
75#endif
76
77/* local functions operate SCI ports 0 and 1 */
78/* called from polling routines or ISRs */
79rtems_boolean wrtSCI0(unsigned char ch)
80{
81  unsigned8 temp;
82  rtems_boolean result=FALSE;
83
84  if ((read8(SCI_SSR0) & SCI_TDRE) != 0x00) {
85    /* Write the character to the TDR */
86    write8(ch, SCI_TDR0);
87    /* Clear the TDRE bit */
88    temp = read8(SCI_SSR0) & ~SCI_TDRE;
89    write8(temp, SCI_SSR0);
90    result = TRUE;
91  }
92  return result;
93} /* wrtSCI0 */
94
95rtems_boolean wrtSCI1(unsigned char ch)
96{
97  unsigned8 temp;
98  rtems_boolean result=FALSE;
99
100  if ((read8(SCI_SSR1) & SCI_TDRE) != 0x00) {
101     /* Write the character to the TDR */
102     write8(ch, SCI_TDR1);
103     /* Clear the TDRE bit */
104     temp = read8(SCI_SSR1) & ~SCI_TDRE;
105     write8(temp, SCI_SSR1);
106     result = TRUE;
107  }
108  return result;
109} /* wrtSCI1 */
110
111/* polled output steers byte to selected port */
112void sh_sci_outbyte_polled(
113  rtems_device_minor_number  minor,
114  char ch )
115{
116        if (minor == 0) /* blocks until port ready */
117                while (wrtSCI0(ch) != TRUE); /* SCI0*/
118        else
119                while (wrtSCI1(ch) != TRUE); /* SCI1*/
120} /* sh_sci_outbyte_polled */
121
122/* Initial version calls polled output driver and blocks */
123void outbyte(
124  rtems_device_minor_number  minor,
125  char ch)
126{
127        sh_sci_outbyte_polled(minor, (unsigned char)ch);
128} /* outbyte */
129
130rtems_boolean rdSCI0(unsigned char *ch)
131{
132  unsigned8 temp;
133  rtems_boolean result=FALSE;
134
135  if ((read8(SCI_SSR0) & SCI_RDRF) != 0x00) {
136    /* Write the character to the TDR */
137    write8(*ch, SCI_RDR0);
138    /* Clear the TDRE bit */
139    temp = read8(SCI_SSR0) & ~SCI_RDRF;
140    write8(temp, SCI_SSR0);
141    result = TRUE;
142  }
143  return result;
144} /* rdSCI0 */
145
146rtems_boolean rdSCI1(unsigned char *ch)
147{
148  unsigned8 temp;
149  rtems_boolean result=FALSE;
150
151  if ((read8(SCI_SSR1) & SCI_RDRF) != 0x00) {
152    /* Write the character to the TDR */
153    write8(*ch, SCI_RDR1);
154    /* Clear the TDRE bit */
155    temp= read8(SCI_SSR1) & ~SCI_RDRF;
156    write8(temp, SCI_SSR1);
157    result = TRUE;
158    }
159  return result;
160} /* rdSCI1 */
161
162
163/* initial version pulls byte from selected port */
164char sh_sci_inbyte_polled(
165    rtems_device_minor_number  minor )
166{
167        char ch;
168       
169        if (minor == 0) /* blocks until char.ready */
170                while (rdSCI0(&ch) != TRUE); /* SCI0 */
171        else
172                while (rdSCI1(&ch) != TRUE); /* SCI1 */
173        return ch;
174} /* sh_sci_inbyte_polled */
175
176/* Initial version calls polled input driver */
177char inbyte(
178  rtems_device_minor_number  minor )
179{
180        char ch;
181
182        ch = sh_sci_inbyte_polled(minor);
183        return ch;
184} /* inbyte */
185
186
187/*  sh_sci_initialize
188 *
189 *  This routine initializes the sh_sci IO driver.
190 *
191 *  Input parameters: NONE
192 *
193 *  Output parameters:  NONE
194 *
195 *  Return values:
196 */
197
198rtems_device_driver sh_sci_initialize(
199  rtems_device_major_number  major,
200  rtems_device_minor_number  minor,
201  void                      *arg )
202{
203  int a;
204  unsigned16 temp16;
205  rtems_device_driver status ;
206
207  /* register devices */ 
208  for ( a = 0 ; a < 2 ; a++ )
209  {
210    status = rtems_io_register_name(
211      sci_device[a].name,
212      major,
213      sci_device[a].minor );
214    if (status != RTEMS_SUCCESSFUL)
215      rtems_fatal_error_occurred(status);
216  }
217
218  /* default hardware setup */
219
220  /* general setup */
221  temp16 = read16(PFC_PECR1) | 0x0800;  /* General I/O except pin 13 (reset) */
222  write16(temp16, PFC_PECR1);
223  write16(0x00, PFC_PECR2);     /* All I/O lines bits 7-0 */
224  temp16 = read16(PFC_PEIOR) | 0x0020;  /* P5 to out, all other pins in */
225  write16(temp16, PFC_PEIOR);
226
227  temp16 = read16(PFC_PACRL2) | 0x0145;  /* PFC - pins for Tx0-1, Rx0-1 */
228  write16(temp16, PFC_PACRL2);
229 
230  return RTEMS_SUCCESSFUL;
231}
232
233
234/*
235 *  Open entry point
236 */
237
238rtems_device_driver sh_sci_open(
239  rtems_device_major_number major,
240  rtems_device_minor_number minor,
241  void                    * arg )
242{
243  unsigned8 temp8;
244  unsigned char smr ;
245  unsigned char brr ;
246 
247  unsigned      a ;
248 
249  /* device already opened */
250  if ( sci_device[minor].opened > 0 )
251  {
252    sci_device[minor].opened++ ;
253
254    return RTEMS_SUCCESSFUL ;
255  }
256   
257  /* retrieve brr and smr values */
258  _sci_get_brparms( sci_device[minor].cflags, &smr, &brr );
259 
260  if (minor == 0) {
261    write8(0x00, SCI_SCR0);     /* Clear SCR */
262    write8(smr, SCI_SMR0);      /* Clear SMR */
263    write8(brr, SCI_BRR0);      /* Default 9600 baud rate */
264#if 0
265    write8(0x1F, SCI_BRR0);    /* 28800 baud */
266#endif
267/* FIXME: Will get optimized away */
268    for(a=0;a<10000L;a++);      /* One bit delay */
269    write8(0x30, SCI_SCR0);     /* Enable clock output */
270    temp8 = read8(SCI_RDR0);      /* Clear out old input */
271
272  } else {
273    write8(0x00, SCI_SCR1);     /* Clear SCR */
274    write8(smr, SCI_SMR1);      /* Clear SMR */
275    write8(brr, SCI_BRR1);      /* Default 9600 baud rate */
276#if 0
277    write8(0x1F, SCI_BRR1);    /* 28800 baud */
278#endif
279/* FIXME: Will get optimized away */
280    for(a=0;a<10000L;a++);      /* One bit delay */
281    write8(0x30, SCI_SCR1);     /* Enable clock output */
282    temp8 = read8(SCI_RDR1);      /* Clear out old input */
283  } 
284
285  sci_device[minor].opened++ ;
286
287  return RTEMS_SUCCESSFUL ;
288}
289 
290/*
291 *  Close entry point
292 */
293
294rtems_device_driver sh_sci_close(
295  rtems_device_major_number major,
296  rtems_device_minor_number minor,
297  void                    * arg
298)
299{
300  /* FIXME: Incomplete */
301  if ( sci_device[minor].opened > 0 )
302    sci_device[minor].opened-- ;
303  else
304    return RTEMS_INVALID_NUMBER ;
305   
306  return RTEMS_SUCCESSFUL ;
307}
308
309/*
310 * read bytes from the serial port. We only have stdin.
311 */
312
313rtems_device_driver sh_sci_read(
314  rtems_device_major_number major,
315  rtems_device_minor_number minor,
316  void                    * arg
317)
318{
319  rtems_libio_rw_args_t *rw_args;
320  char *buffer;
321  int maximum;
322  int count = 0;
323 
324  rw_args = (rtems_libio_rw_args_t *) arg;
325
326  buffer = rw_args->buffer;
327  maximum = rw_args->count;
328
329  for (count = 0; count < maximum; count++) {
330    buffer[ count ] = inbyte(minor);
331    if (buffer[ count ] == '\n' || buffer[ count ] == '\r') {
332      buffer[ count++ ]  = '\n';
333      break;
334    }
335  }
336
337  rw_args->bytes_moved = count;
338  return (count >= 0) ? RTEMS_SUCCESSFUL : RTEMS_UNSATISFIED;
339}
340
341/*
342 * write bytes to the serial port. Stdout and stderr are the same.
343 */
344
345rtems_device_driver sh_sci_write(
346  rtems_device_major_number major,
347  rtems_device_minor_number minor,
348  void                    * arg
349)
350{
351  int count;
352  int maximum;
353  rtems_libio_rw_args_t *rw_args;
354  char *buffer;
355
356  rw_args = (rtems_libio_rw_args_t *) arg;
357
358  buffer = rw_args->buffer;
359  maximum = rw_args->count;
360
361  for (count = 0; count < maximum; count++) {
362    if ( buffer[ count ] == '\n') {
363      outbyte(minor, '\r');
364    }
365    outbyte( minor, buffer[ count ] );
366  }
367
368  rw_args->bytes_moved = maximum;
369  return 0;
370}
371
372/*
373 *  IO Control entry point
374 */
375
376rtems_device_driver sh_sci_control(
377  rtems_device_major_number major,
378  rtems_device_minor_number minor,
379  void                    * arg
380)
381{
382  /* Not yet supported */
383  return RTEMS_SUCCESSFUL ;
384}
Note: See TracBrowser for help on using the repository browser.