OpenCores
URL https://opencores.org/ocsvn/openrisc_me/openrisc_me/trunk

Subversion Repositories openrisc_me

[/] [openrisc/] [trunk/] [rtos/] [rtems/] [c/] [src/] [lib/] [libcpu/] [sh/] [sh7032/] [sci/] [sci.c] - Blame information for rev 173

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 30 unneback
/*
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: sci.c,v 1.2 2001-09-27 12:01:35 chris Exp $
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
 
46
struct 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 */
59
extern 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 */
65
static 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
 
109
static 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
 
145
static 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
 
161
static 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
 
186
rtems_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
 
219
rtems_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
 
274
rtems_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
 
294
rtems_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
 
322
rtems_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
 
351
rtems_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
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.