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

4.104.114.9
Last change on this file since 3551166d was 3551166d, checked in by Ralf Corsepius <ralf.corsepius@…>, on Sep 5, 2008 at 11:55:58 AM

Convert to "bool".

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