source: rtems/c/src/lib/libcpu/sh/sh7032/sci/sci.c @ 400c552

4.104.114.84.95
Last change on this file since 400c552 was 875fbdbb, checked in by Joel Sherrill <joel.sherrill@…>, on 11/22/99 at 13:48:10

Added files missed by previous merger of SH-2 port.

  • Property mode set to 100644
File size: 7.6 KB
Line 
1/*
2 * /dev/sci[0|1] for Hitachi SH 703X
3 *
4 *  Author: Ralf Corsepius (corsepiu@faw.uni-ulm.de)
5 *
6 *  COPYRIGHT (c) 1997-1999, Ralf Corsepius, Ulm, Germany
7 *
8 *  This program is distributed in the hope that it will be useful,
9 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
10 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
11 *
12 *
13 *  COPYRIGHT (c) 1998.
14 *  On-Line Applications Research Corporation (OAR).
15 *  Copyright assigned to U.S. Government, 1994.
16 *
17 *  The license and distribution terms for this file may be
18 *  found in the file LICENSE in this distribution or at
19 *  http://www.OARcorp.com/rtems/license.html.
20 *
21 *  $Id$
22 */
23
24#include <rtems.h>
25
26#include <stdlib.h>
27
28#include <rtems/libio.h>
29#include <iosupp.h>
30#include <rtems/score/sh_io.h>
31#include <rtems/score/ispsh7032.h>
32#include <rtems/score/iosh7032.h>
33#include <sh/sh7_sci.h>
34#include <sh/sh7_pfc.h>
35#include <sh/sci.h>
36
37/*
38 * NOTE: Some SH variants have 3 sci devices
39 */
40 
41#define SCI_MINOR_DEVICES       2
42 
43#define SH_SCI_BASE_0   SCI0_SMR
44#define SH_SCI_BASE_1   SCI1_SMR
45
46struct scidev_t {
47  char *                        name ;
48  unsigned32                    addr ;
49  rtems_device_minor_number     minor ;
50  unsigned short                opened ;
51  tcflag_t                      cflags ;
52} sci_device[SCI_MINOR_DEVICES] =
53{
54  { "/dev/sci0", SH_SCI_BASE_0, 0, 0, B9600 | CS8 },
55  { "/dev/sci1", SH_SCI_BASE_1, 1, 0, B9600 | CS8 }
56} ;
57
58/*  imported from scitab.rel */
59extern int _sci_get_brparms(
60  tcflag_t      cflag,
61  unsigned char *smr,
62  unsigned char *brr );
63
64/* Translate termios' tcflag_t into sci settings */
65static int _sci_set_cflags(
66  struct scidev_t      *sci_dev,
67  tcflag_t      c_cflag )
68{
69  unsigned8     smr ;
70  unsigned8     brr ;
71 
72  if ( c_cflag & CBAUD )
73  {
74    if ( _sci_get_brparms( c_cflag, &smr, &brr ) != 0 )
75      return -1 ;
76  }
77                   
78  if ( c_cflag & CSIZE )
79  {
80    if ( c_cflag & CS8 )
81      smr &= ~SCI_SEVEN_BIT_DATA;
82    else if ( c_cflag & CS7 )
83      smr |= SCI_SEVEN_BIT_DATA;
84    else
85      return -1 ;
86  }
87
88  if ( c_cflag & CSTOPB )
89    smr |= SCI_STOP_BITS_2;
90  else
91    smr &= ~SCI_STOP_BITS_2;
92
93  if ( c_cflag & PARENB )
94    smr |= SCI_PARITY_ON ;
95  else
96    smr &= ~SCI_PARITY_ON ;
97
98  if ( c_cflag & PARODD )
99    smr |= SCI_ODD_PARITY ;
100  else
101    smr &= ~SCI_ODD_PARITY;
102   
103  write8( smr, sci_dev->addr + SCI_SMR );
104  write8( brr, sci_dev->addr + SCI_BRR );
105 
106  return 0 ;
107}
108
109static void _sci_init(
110  rtems_device_minor_number minor )
111{
112  unsigned16    temp16 ;
113
114  /* Pin function controller initialisation for asynchronous mode */ 
115  if( minor == 0)
116    {
117      temp16 = read16( PFC_PBCR1);
118      temp16 &= ~( PB8MD | PB9MD );
119      temp16 |= (PB_TXD0 | PB_RXD0);
120      write16( temp16, PFC_PBCR1);
121    }
122  else
123    {
124      temp16 = read16( PFC_PBCR1);
125      temp16 &= ~( PB10MD | PB11MD);
126      temp16 |= (PB_TXD1 | PB_RXD1);
127      write16( temp16, PFC_PBCR1);
128    }
129
130  /* disable sck-pin */
131  if( minor == 0)
132  {
133          temp16 = read16( PFC_PBCR1);
134          temp16 &= ~(PB12MD);
135          write16( temp16, PFC_PBCR1);
136  }
137  else
138  {
139          temp16 = read16( PFC_PBCR1);
140          temp16 &= ~(PB13MD);
141          write16( temp16, PFC_PBCR1);
142  }
143}
144
145static void _sci_tx_polled(
146  int minor,
147  const char buf )
148{
149  struct scidev_t *scidev = &sci_device[minor] ;
150  signed8         ssr ;
151               
152  while ( !inb((scidev->addr + SCI_SSR) & SCI_TDRE ))
153      ;
154  write8(buf,scidev->addr+SCI_TDR);
155
156  ssr = inb(scidev->addr+SCI_SSR);
157  ssr &= ~SCI_TDRE ;
158  write8(ssr,scidev->addr+SCI_SSR);
159}
160
161static int _sci_rx_polled (
162  int minor)
163{
164  struct scidev_t *scidev = &sci_device[minor] ;
165       
166  unsigned char c;
167  char ssr ;
168  ssr = read8(scidev->addr + SCI_SSR) ;
169
170  if (ssr & (SCI_PER | SCI_FER | SCI_ORER))
171    write8(ssr & ~(SCI_PER | SCI_FER | SCI_ORER), scidev->addr+SCI_SSR);
172
173  if ( !(ssr & SCI_RDRF) )
174    return -1;
175               
176  c = read8(scidev->addr + SCI_RDR) ;
177 
178  write8(ssr & ~SCI_RDRF,scidev->addr + SCI_SSR);
179  return c;
180}
181
182/*
183 * sci_initialize
184 */
185
186rtems_device_driver sh_sci_initialize(
187  rtems_device_major_number  major,
188  rtems_device_minor_number  minor,
189  void                      *arg )
190{
191  rtems_device_driver status ;
192  rtems_device_minor_number     i;
193 
194  /*
195   * register all possible devices.
196   * the initialization of the hardware is done by sci_open
197   */
198
199  for ( i = 0 ; i < SCI_MINOR_DEVICES ; i++ )
200  {
201    status = rtems_io_register_name(
202      sci_device[i].name,
203      major,
204      sci_device[i].minor );
205    if (status != RTEMS_SUCCESSFUL)
206      rtems_fatal_error_occurred(status);
207  }
208
209  /* default hardware setup */
210 
211  return RTEMS_SUCCESSFUL;
212}
213
214
215/*
216 *  Open entry point
217 */
218
219rtems_device_driver sh_sci_open(
220  rtems_device_major_number major,
221  rtems_device_minor_number minor,
222  void                    * arg )
223{
224  unsigned8 temp8;
225 
226 /* check for valid minor number */
227   if(( minor > ( SCI_MINOR_DEVICES -1 )) || ( minor < 0 ))
228   {
229     return RTEMS_INVALID_NUMBER;
230   }
231 
232 /* device already opened */
233  if ( sci_device[minor].opened > 0 )
234  {
235    sci_device[minor].opened++ ;
236    return RTEMS_SUCCESSFUL ;
237  }
238 
239  _sci_init( minor );
240
241  if (minor == 0) {
242    temp8 = read8(sci_device[minor].addr + SCI_SCR);
243    temp8 &= ~(SCI_TE | SCI_RE) ;
244    write8(temp8, sci_device[minor].addr + SCI_SCR);    /* Clear SCR */
245    _sci_set_cflags( &sci_device[minor], sci_device[minor].cflags );
246
247/* FIXME: Should be one bit delay */
248    CPU_delay(50000); /* microseconds */
249
250    temp8 |= SCI_RE | SCI_TE;
251    write8(temp8, sci_device[minor].addr + SCI_SCR);    /* Enable clock output */
252  } else {
253    temp8 = read8(sci_device[minor].addr + SCI_SCR);
254    temp8 &= ~(SCI_TE | SCI_RE) ;
255    write8(temp8, sci_device[minor].addr + SCI_SCR);    /* Clear SCR */
256    _sci_set_cflags( &sci_device[minor], sci_device[minor].cflags );
257
258/* FIXME: Should be one bit delay */
259    CPU_delay(50000); /* microseconds */
260   
261    temp8 |= SCI_RE | SCI_TE;
262    write8(temp8, sci_device[minor].addr + SCI_SCR);    /* Enable clock output */
263  } 
264
265  sci_device[minor].opened++ ;
266
267  return RTEMS_SUCCESSFUL ;
268}
269 
270/*
271 *  Close entry point
272 */
273
274rtems_device_driver sh_sci_close(
275  rtems_device_major_number major,
276  rtems_device_minor_number minor,
277  void                    * arg
278)
279{
280  if( sci_device[minor].opened == 0 )
281    {
282      return RTEMS_INVALID_NUMBER;
283    }
284
285  sci_device[minor].opened-- ;
286   
287  return RTEMS_SUCCESSFUL ;
288}
289
290/*
291 * read bytes from the serial port.
292 */
293
294rtems_device_driver sh_sci_read(
295  rtems_device_major_number major,
296  rtems_device_minor_number minor,
297  void                    * arg
298)
299{
300  int count = 0;
301 
302  rtems_libio_rw_args_t *rw_args = (rtems_libio_rw_args_t *) arg;
303  char * buffer = rw_args->buffer;
304  int maximum = rw_args->count;
305
306  for (count = 0; count < maximum; count++) {
307    buffer[ count ] = _sci_rx_polled(minor);
308    if (buffer[ count ] == '\n' || buffer[ count ] == '\r') {
309      buffer[ count++ ]  = '\n';
310      break;
311    }
312  }
313
314  rw_args->bytes_moved = count;
315  return (count >= 0) ? RTEMS_SUCCESSFUL : RTEMS_UNSATISFIED;
316}
317
318/*
319 * write bytes to the serial port.
320 */
321
322rtems_device_driver sh_sci_write(
323  rtems_device_major_number major,
324  rtems_device_minor_number minor,
325  void                    * arg
326)
327{
328  int count;
329
330  rtems_libio_rw_args_t *rw_args = (rtems_libio_rw_args_t *) arg;
331  char *buffer = rw_args->buffer;
332  int maximum = rw_args->count;
333
334  for (count = 0; count < maximum; count++) {
335#if 0
336    if ( buffer[ count ] == '\n') {
337      outbyte(minor, '\r');
338    }
339#endif
340    _sci_tx_polled( minor, buffer[ count ] );
341  }
342
343  rw_args->bytes_moved = maximum;
344  return 0;
345}
346
347/*
348 *  IO Control entry point
349 */
350
351rtems_device_driver sh_sci_control(
352  rtems_device_major_number major,
353  rtems_device_minor_number minor,
354  void                    * arg
355)
356{
357  /* Not yet supported */
358  return RTEMS_SUCCESSFUL ;
359}
Note: See TracBrowser for help on using the repository browser.