source: rtems/c/src/lib/libbsp/powerpc/score603e/console/85c30.c @ b14e2f2

4.104.114.84.95
Last change on this file since b14e2f2 was b14e2f2, checked in by Joel Sherrill <joel.sherrill@…>, on Sep 4, 2003 at 6:52:35 PM

2003-09-04 Joel Sherrill <joel@…>

  • PCI_bus/PCI.h, clock/clock.c, console/85c30.c, console/85c30.h, console/console.c, console/consolebsp.h, console/consolereserveresources.c, console/tbl85c30.c, include/bsp.h, include/coverhd.h, include/gen2.h, include/tod.h, startup/FPGA.c, startup/bspclean.c, startup/bspstart.c, startup/genpvec.c, startup/setvec.c, startup/vmeintr.c, timer/timer.c, tod/tod.c: URL for license changed.
  • Property mode set to 100644
File size: 10.3 KB
Line 
1/*
2 *  This file contains the console driver chip level routines for the
3 *  z85c30 chip.
4 *
5 *  Currently only polled mode is supported.
6 *
7 *  COPYRIGHT (c) 1989-1997.
8 *  On-Line Applications Research Corporation (OAR).
9 *
10 *  The license and distribution terms for this file may be
11 *  found in the file LICENSE in this distribution or at
12 *  http://www.rtems.com/license/LICENSE.
13 *
14 *  $Id:
15 */
16
17#include <rtems.h>
18#include <bsp.h>
19#include <rtems/libio.h>
20#include <assert.h>
21
22#include "85c30.h"
23#include "consolebsp.h"
24
25#define STATUS_REGISTER     0x00
26#define DATA_REGISTER       0x08
27
28
29#define Z8530_Status_Is_RX_character_available( _status ) \
30  ( (_status) & 0x01 )
31
32#define Z8530_Status_Is_TX_buffer_empty( _status ) \
33  ( (_status) & 0x04 )
34
35#define Z8530_Status_Is_break_abort( _status ) \
36  ( (_status) & 0x80 )
37
38typedef struct {
39  unsigned char read_setup;
40  unsigned char write_setup;
41  unsigned char mask_value;
42} char_size_info;
43
44static const char_size_info Char_size_85c30[] = {
45  { Z8530_READ_CHARACTER_BITS_8, Z8530_WRITE_CHARACTER_BITS_8, 0xFF }, 
46  { Z8530_READ_CHARACTER_BITS_7, Z8530_WRITE_CHARACTER_BITS_7, 0x7F }, 
47  { Z8530_READ_CHARACTER_BITS_6, Z8530_WRITE_CHARACTER_BITS_6, 0x3F }, 
48  { Z8530_READ_CHARACTER_BITS_5, Z8530_WRITE_CHARACTER_BITS_5, 0x1F }
49};
50
51static const unsigned char Clock_speed_85c30[] = { 
52  Z8530_x1_CLOCK, Z8530_x16_CLOCK, Z8530_x32_CLOCK,  Z8530_x64_CLOCK };
53
54static const unsigned char Stop_bit_85c30[] = { 
55  Z8530_STOP_BITS_1, Z8530_STOP_BITS_1_AND_A_HALF, Z8530_STOP_BITS_2 };
56
57static const unsigned char Parity_85c30[] = { 
58  Z8530_PARITY_NONE, Z8530_PARITY_ODD, Z8530_PARITY_EVEN };
59
60
61/* PAGE
62 *
63 * Read_85c30_register
64 *
65 * Read a Z85c30 register
66 */
67static unsigned char Read_85c30_register( 
68  volatile unsigned char *csr,                        /* IN  */
69  unsigned char  register_number                      /* IN  */
70)
71{
72  unsigned char Data;
73 
74  *csr = register_number; 
75
76  rtems_bsp_delay_in_bus_cycles( 40 );
77
78  Data = *csr;
79 
80  rtems_bsp_delay_in_bus_cycles( 40 );
81
82  return Data;
83}
84
85/*
86 * Write_85c30_register
87 *
88 *  Write a Z85c30 register
89 */
90static void  Write_85c30_register(
91  volatile unsigned char  *csr,                     /* IN  */
92  unsigned char  register_number,                   /* IN  */
93  unsigned char  data                               /* IN  */
94)
95{
96  *csr = register_number;
97
98  rtems_bsp_delay_in_bus_cycles( 40 );
99
100  *csr = data;
101
102  rtems_bsp_delay_in_bus_cycles( 40 );
103}
104
105
106/* PAGE
107 *
108 *  Reset_85c30_chip
109 *
110 *  Reset a 85c30 chip.  The pointers for the control registers for both
111 *  ports on the chip are used as input.
112 */
113void Reset_85c30_chip(
114  volatile unsigned char *ctrl_0,                     /* IN  */
115  volatile unsigned char *ctrl_1                      /* IN  */
116)
117{
118  Write_85c30_register( ctrl_0, 0x09, 0x80 );
119  Write_85c30_register( ctrl_1, 0x09, 0x40 );
120}
121 
122
123/* PAGE
124 *
125 * initialize_85c30_port
126 *
127 * initialize a z85c30 Port
128 */
129void initialize_85c30_port(
130  const Port_85C30_info *Port
131)
132{
133  rtems_unsigned16        value;
134  volatile unsigned char *ctrl;
135  Console_Protocol        *Setup;
136  rtems_unsigned16        baud_constant;
137
138  Setup = Port->Protocol;
139  ctrl  = Port->ctrl;
140
141  baud_constant = _Score603e_Z8530_Baud( Port->Chip->clock_frequency, 
142    Port->Chip->clock_x, Setup->baud_rate );
143
144  /*
145   * Using register 4
146   * Set up the clock rate.
147   */
148  value = Clock_speed_85c30[ Port->Chip->clock_speed ] |
149          Stop_bit_85c30[ Setup->stop_bits ] |
150          Parity_85c30[ Setup->parity ];
151  Write_85c30_register( ctrl, 0x04, value );
152
153  /*
154   *  Set Write Register 1 to disable all interrupts
155   */
156  Write_85c30_register( ctrl, 1, 0 );
157
158#if CONSOLE_USE_INTERRUPTS
159  /*
160   *  Set Write Register 2 to contain the interrupt vector
161   */
162  Write_85c30_register( ctrl, 2, Port->Chip->vector );
163#endif
164
165  /*
166   *  Set Write Register 3 to disable the Receiver
167   */
168  Write_85c30_register( ctrl, 0x03, 0x00 );
169
170  /*
171   *  Set Write Register 5 to disable the Transmitter
172   */
173  Write_85c30_register( ctrl, 5, 0x00 );
174
175  /* WR 6 -- unneeded in asynchronous mode */
176
177  /* WR 7 -- unneeded in asynchronous mode */
178
179  /*
180   *  Set Write Register 9 to disable all interrupt sources
181   */
182  Write_85c30_register( ctrl, 9, 0x00 );
183
184  /*
185   *  Set Write Register 10 for simple Asynchronous operation
186   */
187  Write_85c30_register( ctrl, 0x0a, 0x00 );
188
189  /*
190   * Setup the source of the receive and xmit
191   * clock as BRG output and the transmit clock
192   * as the output source for TRxC pin via register 11
193   */
194  Write_85c30_register( ctrl, 0x0b, 0x56 );
195
196  value = baud_constant;
197
198  /*
199   * Setup the lower 8 bits time constants = 1E.
200   * If the time constans = 1E, then the desire
201   * baud rate will be equilvalent to 9600, via register 12.
202   */
203  Write_85c30_register( ctrl, 0x0c, value & 0xff );
204
205  /*
206   * using register 13
207   * Setup the upper 8 bits time constants = 0
208   */
209  Write_85c30_register( ctrl, 0x0d, value>>8 );
210
211  /*
212   * Set the DTR/REQ pin goes low when transmit
213   * buffer becomes empty and enable the baud
214   * rate generator enable with clock from the
215   * SCC's PCLK input via register 14.
216   */
217  Write_85c30_register( ctrl, 0x0e, 0x07 );
218
219  /*
220   *  Set Write Register 3 : Base Value is xx00_000x
221   *     D6 - D7 : Receive Character Length               (configured)
222   *     D5      : Auto Enable                            (forced value)
223   *     D4      : Enter Hunt Phase                       (forced value)
224   *     D3      : Receive CRC Enable                     (forced value)
225   *     D2      : Address Search Mode (0 if not SDLC)    (forced value)
226   *     D1      : Sync Character Load Inhibit            (forced value)
227   *     D0      : Receiver Enable                        (configured)
228   */
229  value = 0x01;
230  value = value | Char_size_85c30[ Setup->read_char_bits ].read_setup;
231
232  Write_85c30_register( ctrl, 0x03, value );
233
234  /*
235   *  Set Write Register 5 : Base Value is 0xx0_x000
236   *     D7      : Data Terminal Ready (DTR)              (forced value)
237   *     D5 - D6 : Transmit Character Length              (configured)
238   *     D4      : Send Break                             (forced value)
239   *     D3      : Transmitter Enable                     (configured)
240   *     D2      : CRC Select                             (forced value)
241   *     D1      : Request to Send                        (forced value)
242   *     D0      : Transmit CRC Enable                    (forced value)
243   */
244  value = 0x8a;
245  value = value |  Char_size_85c30[ Setup->write_char_bits ].write_setup;
246  Write_85c30_register( ctrl, 0x05, value );
247 
248  /*
249   * Reset Tx UNDERRUN/EOM LATCH and ERROR
250   * via register 0
251   */
252   Write_85c30_register( ctrl, 0x00, 0xf0 );
253 
254#if CONSOLE_USE_INTERRUPTS
255  /*
256   *  Set Write Register 1 to interrupt on Rx characters or special condition.
257   */
258  Write_85c30_register( ctrl, 1, 0x10 );
259#endif
260
261  /*
262   *  Set Write Register 15 to disable extended functions.
263   */
264
265  Write_85c30_register( ctrl, 15, 0x00 );
266
267  /*
268   *  Set the Command Register to Reset Ext/STATUS.
269   */
270  Write_85c30_register( ctrl, 0x00, 0x10 );
271
272#if CONSOLE_USE_INTERRUPTS
273
274  /*
275   *  Set Write Register 1 : Base Value is 0001_0110
276   *    Enables Rx interrupt on all characters and special conditions.
277   *    Enables parity as a special condition.
278   *    Enables Tx interrupt.
279   */
280  Write_85c30_register( ctrl, 1, 0x16 );
281
282  /*
283   *  Set Write Register 9 to enable all interrupt sources
284   *  Changed from 0 to a
285   */
286  Write_85c30_register( ctrl, 9, 0x0A );
287
288
289  /* XXX */
290
291  /*
292   *  Issue reset highest Interrupt Under Service (IUS) command.
293   */
294  Write_85c30_register( Port->ctrl, STATUS_REGISTER, 0x38 );
295
296#endif
297
298}
299
300/* PAGE
301 *
302 *  outbyte_polled_85c30
303 *
304 *  This routine transmits a character using polling.
305 */
306
307void outbyte_polled_85c30(
308  volatile unsigned char  *csr,                     /* IN  */
309  char ch                                           /* IN  */
310)
311{
312  unsigned char       z8530_status;
313  rtems_unsigned32    isrlevel;
314 
315  rtems_interrupt_disable( isrlevel );
316
317  /*
318   * Wait for the Transmit buffer to indicate that it is empty.
319   */
320  do {
321    z8530_status = Read_85c30_register( csr, STATUS_REGISTER );
322  } while ( !Z8530_Status_Is_TX_buffer_empty( z8530_status ) );
323
324  /*
325   * Write the character.
326   */
327  Write_85c30_register( csr, DATA_REGISTER, (unsigned char) ch ); 
328
329  rtems_interrupt_enable( isrlevel );
330}
331
332/* PAGE
333 *
334 *  inbyte_nonblocking_85c30
335 *
336 *  This routine polls for a character.
337 */
338
339int inbyte_nonblocking_85c30(   
340  const Port_85C30_info      *Port
341)
342{
343  volatile unsigned char  *csr;
344  unsigned char   z8530_status;
345  rtems_unsigned8 data;
346
347  csr = Port->ctrl;
348
349  /*
350   * return -1 if a character is not available.
351   */
352  z8530_status = Read_85c30_register( csr, STATUS_REGISTER );
353  if ( !Z8530_Status_Is_RX_character_available( z8530_status ) )
354    return -1;
355 
356  /*
357   * Return the character read.
358   */
359  data = Read_85c30_register( csr, DATA_REGISTER );
360  data &= Char_size_85c30[ Port->Protocol->read_char_bits ].mask_value;
361
362  return data;
363}
364
365
366/*
367 *  Interrupt driven console IO
368 */
369
370#if CONSOLE_USE_INTERRUPTS
371
372/*PAGE
373 *
374 *  Z8530_Async_Channel_ISR
375 *
376 */
377/* RR0 */
378
379rtems_isr ISR_85c30_Async(
380   const Port_85C30_info   *Port
381)
382{
383  rtems_unsigned16           status;
384  volatile Console_Protocol *Protocol;
385  unsigned char              data;
386  rtems_boolean              did_something = FALSE;
387
388  Protocol = Port->Protocol;
389
390  status = Read_85c30_register( Port->ctrl, 0x00 );
391
392  /*
393   *  Was this a RX interrupt?  If so, then process it.
394   */
395
396  if ( Z8530_Status_Is_RX_character_available( status ) ) {
397    data = Read_85c30_register( Port->ctrl, DATA_REGISTER );
398    data &= Char_size_85c30[ Port->Protocol->read_char_bits ].mask_value;
399   
400    rtems_termios_enqueue_raw_characters( Port->Protocol->console_termios_data,
401       &data, 1 );
402    did_something = TRUE;
403  }
404
405  /*
406   *  Was this a TX empty interrupt?  If so, then process it.
407   */
408
409  if (Z8530_Status_Is_TX_buffer_empty( status ) ) {
410    if ( !Ring_buffer_Is_empty( &Protocol->TX_Buffer ) ) {
411      Ring_buffer_Remove_character( &Protocol->TX_Buffer, data );
412      Write_85c30_register( Port->ctrl, DATA_REGISTER, data );
413
414    } else {
415      Protocol->Is_TX_active = FALSE;
416      Write_85c30_register( Port->ctrl, STATUS_REGISTER, 0x28 );
417    }
418
419    did_something = TRUE;
420  }
421
422  /*
423   *  Issue reset highest Interrupt Under Service (IUS) command.
424   */
425
426  /*
427   if ( did_something )
428   */
429     Write_85c30_register( Port->ctrl, STATUS_REGISTER, 0x38 );
430}
431
432#endif
433
Note: See TracBrowser for help on using the repository browser.