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

Last change on this file since c8f3e82 was 650a5397, checked in by Joel Sherrill <joel.sherrill@…>, on Oct 12, 2001 at 9:01:15 PM

2001-10-12 Joel Sherrill <joel@…>

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