source: rtems/c/src/lib/libcpu/sh/sh7045/sci/sci.c @ 0312d81f

4.104.114.84.95
Last change on this file since 0312d81f was 205d5645, checked in by Joel Sherrill <joel.sherrill@…>, on 01/03/00 at 16:44:04

Patch from John Mills <jmills@…> to correct some cut and paste
errors.

  • Property mode set to 100644
File size: 9.1 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", 1, 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/*
123 * Initial version calls polled output driver and blocks
124 */
125void outbyte(
126  rtems_device_minor_number  minor,
127  char ch)
128{
129        sh_sci_outbyte_polled(minor, (unsigned char)ch);
130} /* outbyte */
131
132rtems_boolean rdSCI0(unsigned char *ch)
133{
134  unsigned8 temp;
135  rtems_boolean result=FALSE;
136
137  if ((read8(SCI_SSR0) & SCI_RDRF) != 0x00) {
138    /* read input */
139    *ch = read8(SCI_RDR0);
140    /* Clear RDRF flag */
141    temp = read8(SCI_SSR0) & ~SCI_RDRF;
142    write8(temp, SCI_SSR0);
143    result = TRUE;
144  }
145  return result;
146} /* rdSCI0 */
147
148rtems_boolean rdSCI1(unsigned char *ch)
149{
150  unsigned8 temp;
151  rtems_boolean result=FALSE;
152
153  if ((read8(SCI_SSR1) & SCI_RDRF) != 0x00) {
154    /* read input */
155    *ch = read8(SCI_RDR1);
156    /* Clear RDRF flag */
157    temp= read8(SCI_SSR1) & ~SCI_RDRF;
158    write8(temp, SCI_SSR1);
159    result = TRUE;
160    }
161  return result;
162} /* rdSCI1 */
163
164
165/* initial version pulls byte from selected port */
166char sh_sci_inbyte_polled(
167    rtems_device_minor_number  minor )
168{
169        char ch;
170       
171        if (minor == 0) /* blocks until char.ready */
172                while (rdSCI0(&ch) != TRUE); /* SCI0 */
173        else
174                while (rdSCI1(&ch) != TRUE); /* SCI1 */
175        return ch;
176} /* sh_sci_inbyte_polled */
177
178/* Initial version calls polled input driver */
179char inbyte(
180  rtems_device_minor_number  minor )
181{
182        char ch;
183
184        ch = sh_sci_inbyte_polled(minor);
185        return ch;
186} /* inbyte */
187
188
189/*  sh_sci_initialize
190 *
191 *  This routine initializes (registers) the sh_sci IO drivers.
192 *
193 *  Input parameters: ignored
194 *
195 *  Output parameters:  NONE
196 *
197 *  Return values: RTEMS_SUCCESSFUL
198 *   if all sci[...] register, else calls
199 *   rtems_fatal_error_occurred(status)
200 *
201 */
202
203rtems_device_driver sh_sci_initialize(
204  rtems_device_major_number  major,
205  rtems_device_minor_number  minor,
206  void                      *arg )
207{
208  rtems_device_driver status ;
209  rtems_device_minor_number     i;
210 
211  /*
212   * register all possible devices.
213   * the initialization of the hardware is done by sci_open
214   */
215
216  for ( i = 0 ; i < SCI_MINOR_DEVICES ; i++ )
217  {
218    status = rtems_io_register_name(
219      sci_device[i].name,
220      major,
221      sci_device[i].minor );
222    if (status != RTEMS_SUCCESSFUL)
223      rtems_fatal_error_occurred(status);
224  }
225
226  /* non-default hardware setup occurs in sh_sci_open() */
227
228  return RTEMS_SUCCESSFUL;
229}
230
231
232/*
233 *  Open entry point
234 *   Sets up port and pins for selected sci.
235 *   SCI0 setup is conditional on STANDALONE_EVB == 1
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  unsigned16 temp16;
245  unsigned char smr ;
246  unsigned char brr ;
247 
248  unsigned      a ;
249 
250 /* check for valid minor number */
251   if(( minor > ( SCI_MINOR_DEVICES -1 )) || ( minor < 0 ))
252   {
253     return RTEMS_INVALID_NUMBER;
254   }
255 
256  /* device already opened */
257  if ( sci_device[minor].opened > 0 )
258  {
259    sci_device[minor].opened++ ;
260    return RTEMS_SUCCESSFUL ;
261  }
262   
263  /* enable I/O pins */
264
265  if ((minor == 0) && (STANDALONE_EVB == 1)) {
266    temp16 = read16(PFC_PACRL2) &          /* disable SCK0, Tx0, Rx0 */
267      ~(PA2MD1 | PA2MD0 | PA1MD0 | PA0MD0);
268    temp16 |= (PA_TXD0 | PA_RXD0);       /* assign pins for Tx0, Rx0 */
269    write16(temp16, PFC_PACRL2);
270   
271  } else if (minor == 1) { 
272    temp16 = read16(PFC_PACRL2) &           /* disable SCK1, Tx1, Rx1 */
273      ~(PA5MD1 | PA5MD0 | PA4MD0 | PA3MD0);
274    temp16 |= (PA_TXD1 | PA_RXD1);        /* assign pins for Tx1, Rx1 */
275    write16(temp16, PFC_PACRL2);
276
277  } /* add other devices and pins as req'd. */
278
279  /* set up SCI registers */
280  if ((minor != 0) || (STANDALONE_EVB == 1)) {
281    write8(0x00, sci_device[minor].addr + SCI_SCR);      /* Clear SCR */
282                                                   /* set SCR and BRR */
283    _sci_set_cflags( &sci_device[minor], sci_device[minor].cflags );
284
285    for(a=0; a < 10000L; a++) {                      /* One-bit delay */
286      asm volatile ("nop");
287    }
288
289    write8((SCI_RE | SCI_TE),              /* enable async. Tx and Rx */
290           sci_device[minor].addr + SCI_SCR);
291    temp8 = read8(sci_device[minor].addr + SCI_RDR);   /* flush input */
292   
293    /* add interrupt setup if required */
294
295  }
296
297  sci_device[minor].opened++ ;
298
299  return RTEMS_SUCCESSFUL ;
300}
301 
302/*
303 *  Close entry point
304 */
305
306rtems_device_driver sh_sci_close(
307  rtems_device_major_number major,
308  rtems_device_minor_number minor,
309  void                    * arg
310)
311{
312  /* FIXME: Incomplete */
313  if ( sci_device[minor].opened > 0 )
314    sci_device[minor].opened-- ;
315  else
316    return RTEMS_INVALID_NUMBER ;
317   
318  return RTEMS_SUCCESSFUL ;
319}
320
321/*
322 * read bytes from the serial port. We only have stdin.
323 */
324
325rtems_device_driver sh_sci_read(
326  rtems_device_major_number major,
327  rtems_device_minor_number minor,
328  void                    * arg
329)
330{
331  rtems_libio_rw_args_t *rw_args;
332  char *buffer;
333  int maximum;
334  int count = 0;
335 
336  rw_args = (rtems_libio_rw_args_t *) arg;
337
338  buffer = rw_args->buffer;
339  maximum = rw_args->count;
340
341  for (count = 0; count < maximum; count++) {
342    buffer[ count ] = inbyte(minor);
343    if (buffer[ count ] == '\n' || buffer[ count ] == '\r') {
344      buffer[ count++ ]  = '\n';
345      break;
346    }
347  }
348
349  rw_args->bytes_moved = count;
350  return (count >= 0) ? RTEMS_SUCCESSFUL : RTEMS_UNSATISFIED;
351}
352
353/*
354 * write bytes to the serial port. Stdout and stderr are the same.
355 */
356
357rtems_device_driver sh_sci_write(
358  rtems_device_major_number major,
359  rtems_device_minor_number minor,
360  void                    * arg
361)
362{
363  int count;
364  int maximum;
365  rtems_libio_rw_args_t *rw_args;
366  char *buffer;
367
368  rw_args = (rtems_libio_rw_args_t *) arg;
369
370  buffer = rw_args->buffer;
371  maximum = rw_args->count;
372
373  for (count = 0; count < maximum; count++) {
374    if ( buffer[ count ] == '\n') {
375      outbyte(minor, '\r');
376    }
377    outbyte( minor, buffer[ count ] );
378  }
379
380  rw_args->bytes_moved = maximum;
381  return 0;
382}
383
384/*
385 *  IO Control entry point
386 */
387
388rtems_device_driver sh_sci_control(
389  rtems_device_major_number major,
390  rtems_device_minor_number minor,
391  void                    * arg
392)
393{
394  /* Not yet supported */
395  return RTEMS_SUCCESSFUL ;
396}
Note: See TracBrowser for help on using the repository browser.