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

Last change on this file since 1c6926c1 was 1c6926c1, checked in by Kevin Kirspel <kevin-kirspel@…>, on Mar 21, 2017 at 7:39:48 PM

termios: Synchronize with latest FreeBSD headers

Adding modified FreeBSD headers to synchronize RTEMS termios with
FreeBSD. Modify termios to support dedicated input and output baud for
termios structure. Updated BSPs to use dedicated input and output baud
in termios structure. Updated tools to use dedicated input and output
baud in termios structure. Updated termios testsuites to use dedicated
input and output baud in termios structure.

Close #2897.

  • 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.rtems.org/license/LICENSE.
19 */
20
21#include <rtems.h>
22
23#include <stdlib.h>
24
25#include <rtems/libio.h>
26#include <rtems/iosupp.h>
27#include <rtems/score/sh_io.h>
28#include <rtems/score/ispsh7032.h>
29#include <rtems/score/iosh7032.h>
30#include <sh/sh7_sci.h>
31#include <sh/sh7_pfc.h>
32#include <sh/sci.h>
33
34/*
35 * NOTE: Some SH variants have 3 sci devices
36 */
37
38#define SCI_MINOR_DEVICES       2
39
40#define SH_SCI_BASE_0   SCI0_SMR
41#define SH_SCI_BASE_1   SCI1_SMR
42
43struct scidev_t {
44  char *                        name ;
45  uint32_t                      addr ;
46  rtems_device_minor_number     minor ;
47  unsigned short                opened ;
48  tcflag_t                      cflags ;
49  speed_t       spd ;
50} sci_device[SCI_MINOR_DEVICES] =
51{
52  { "/dev/sci0", SH_SCI_BASE_0, 0, 0, CS8, B9600 },
53  { "/dev/sci1", SH_SCI_BASE_1, 1, 0, CS8, B9600 }
54} ;
55
56/*  imported from scitab.rel */
57extern int _sci_get_brparms(
58  speed_t       spd,
59  unsigned char *smr,
60  unsigned char *brr );
61
62/* Translate termios' tcflag_t into sci settings */
63static int _sci_set_cflags(
64  struct scidev_t      *sci_dev,
65  tcflag_t      c_cflag,
66  speed_t       spd )
67{
68  uint8_t       smr ;
69  uint8_t       brr ;
70
71  if ( spd )
72  {
73    if ( _sci_get_brparms( spd, &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  uint16_t      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  int8_t           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  uint8_t   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, sci_device[minor].spd );
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, sci_device[minor].spd );
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.