source: rtems/c/src/libchip/serial/z85c30.c @ e4acf68

4.104.114.84.95
Last change on this file since e4acf68 was e4acf68, checked in by Joel Sherrill <joel.sherrill@…>, on Jun 22, 1998 at 9:59:22 AM

Added comments and corrected spacing.

  • Property mode set to 100644
File size: 18.8 KB
Line 
1/*
2 *  This file contains the console driver chip level routines for the
3 *  Zilog z85c30 chip.
4 *
5 *  The Zilog Z8530 is also available as:
6 *
7 *    + Intel 82530
8 *    + AMD ???
9 *
10 *  COPYRIGHT (c) 1998 by Radstone Technology
11 *
12 *
13 * THIS FILE IS PROVIDED TO YOU, THE USER, "AS IS", WITHOUT WARRANTY OF ANY
14 * KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
15 * IMPLIED WARRANTY OF FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK
16 * AS TO THE QUALITY AND PERFORMANCE OF ALL CODE IN THIS FILE IS WITH YOU.
17 *
18 * You are hereby granted permission to use, copy, modify, and distribute
19 * this file, provided that this notice, plus the above copyright notice
20 * and disclaimer, appears in all copies. Radstone Technology will provide
21 * no support for this code.
22 *
23 *  COPYRIGHT (c) 1989-1997.
24 *  On-Line Applications Research Corporation (OAR).
25 *  Copyright assigned to U.S. Government, 1994.
26 *
27 *  The license and distribution terms for this file may be
28 *  found in the file LICENSE in this distribution or at
29 *  http://www.OARcorp.com/rtems/license.html.
30 *
31 *  $Id$
32 */
33
34#include <rtems.h>
35#include <rtems/libio.h>
36#include <stdlib.h>
37
38#include <libchip/serial.h>
39#include "z85c30_p.h"
40
41/*
42 * Flow control is only supported when using interrupts
43 */
44
45console_flow z85c30_flow_RTSCTS =
46{
47  z85c30_negate_RTS,    /* deviceStopRemoteTx */
48  z85c30_assert_RTS     /* deviceStartRemoteTx */
49};
50
51console_flow z85c30_flow_DTRCTS =
52{
53  z85c30_negate_DTR,    /* deviceStopRemoteTx */
54  z85c30_assert_DTR     /* deviceStartRemoteTx */
55};
56
57/*
58 * Exported driver function table
59 */
60
61console_fns z85c30_fns =
62{
63  z85c30_probe,                  /* deviceProbe */
64  z85c30_open,                   /* deviceFirstOpen */
65  z85c30_flush,                  /* deviceLastClose */
66  NULL,                          /* deviceRead */
67  z85c30_write_support_int,      /* deviceWrite */
68  z85c30_initialize_interrupts,  /* deviceInitialize */
69  z85c30_write_polled,           /* deviceWritePolled */
70  FALSE,                         /* deviceOutputUsesInterrupts */
71};
72
73console_fns z85c30_fns_polled =
74{
75  z85c30_probe,                      /* deviceProbe */
76  z85c30_open,                       /* deviceFirstOpen */
77  z85c30_close,                      /* deviceLastClose */
78  z85c30_inbyte_nonblocking_polled,  /* deviceRead */
79  z85c30_write_support_polled,       /* deviceWrite */
80  z85c30_init,                       /* deviceInitialize */
81  z85c30_write_polled,               /* deviceWritePolled */
82  FALSE,                             /* deviceOutputUsesInterrupts */
83};
84
85extern void set_vector( rtems_isr_entry, rtems_vector_number, int );
86
87/*
88 *  Types for get and set register routines
89 */
90
91typedef unsigned8 (*getRegister_f)(unsigned32 port, unsigned8 register);
92typedef void      (*setRegister_f)(
93                            unsigned32 port, unsigned8 reg, unsigned8 value);
94typedef unsigned8 (*getData_f)(unsigned32 port);
95typedef void      (*setData_f)(unsigned32 port, unsigned8 value);
96
97
98/*
99 * z85c30_initialize_port
100 *
101 * initialize a z85c30 Port
102 */
103
104static void z85c30_initialize_port(
105  int minor
106)
107{
108  unsigned32      ulCtrlPort;
109  unsigned32      ulBaudDivisor;
110  setRegister_f   setReg;
111
112  ulCtrlPort = Console_Port_Tbl[minor].ulCtrlPort1;
113  setReg   = Console_Port_Tbl[minor].setRegister;
114
115  /*
116   * Using register 4
117   * Set up the clock rate is 16 times the data
118   * rate, 8 bit sync char, 1 stop bit, no parity
119   */
120
121  (*setReg)( ulCtrlPort, SCC_WR0_SEL_WR4, SCC_WR4_1_STOP | SCC_WR4_16_CLOCK );
122
123  /*
124   * Set up for 8 bits/character on receive with
125   * receiver disable via register 3
126   */
127  (*setReg)( ulCtrlPort, SCC_WR0_SEL_WR3, SCC_WR3_RX_8_BITS );
128
129  /*
130   * Set up for 8 bits/character on transmit
131   * with transmitter disable via register 5
132   */
133  (*setReg)( ulCtrlPort, SCC_WR0_SEL_WR5, SCC_WR5_TX_8_BITS );
134
135  /*
136   * Clear misc control bits
137   */
138  (*setReg)( ulCtrlPort, SCC_WR0_SEL_WR10, 0x00 );
139
140  /*
141   * Setup the source of the receive and xmit
142   * clock as BRG output and the transmit clock
143   * as the output source for TRxC pin via register 11
144   */
145  (*setReg)(
146    ulCtrlPort,
147    SCC_WR0_SEL_WR11,
148    SCC_WR11_OUT_BR_GEN | SCC_WR11_TRXC_OI | 
149      SCC_WR11_TX_BR_GEN | SCC_WR11_RX_BR_GEN
150  );
151
152  ulBaudDivisor = Z85C30_Baud( 
153    (unsigned32) Console_Port_Tbl[minor].ulClock,
154    (unsigned32) Console_Port_Tbl[minor].pDeviceParams
155  );
156
157  /*
158   * Setup the lower 8 bits time constants=1E.
159   * If the time constans=1E, then the desire
160   * baud rate will be equilvalent to 9600, via register 12.
161   */
162  (*setReg)( ulCtrlPort, SCC_WR0_SEL_WR12, ulBaudDivisor & 0xff );
163
164  /*
165   * using register 13
166   * Setup the upper 8 bits time constant
167   */
168  (*setReg)( ulCtrlPort, SCC_WR0_SEL_WR13, (ulBaudDivisor>>8) & 0xff );
169           
170  /*
171   * Enable the baud rate generator enable with clock from the
172   * SCC's PCLK input via register 14.
173   */
174  (*setReg)(
175    ulCtrlPort,
176    SCC_WR0_SEL_WR14,
177    SCC_WR14_BR_EN | SCC_WR14_BR_SRC | SCC_WR14_NULL
178  );
179
180  /*
181   * We are only interested in CTS state changes
182   */
183  (*setReg)( ulCtrlPort, SCC_WR0_SEL_WR15, SCC_WR15_CTS_IE );
184
185  /*
186   * Reset errors
187   */
188  (*setReg)( ulCtrlPort, SCC_WR0_SEL_WR0, SCC_WR0_RST_INT );
189
190  (*setReg)( ulCtrlPort, SCC_WR0_SEL_WR0, SCC_WR0_ERR_RST );
191
192  /*
193   * Enable the receiver via register 3
194   */
195  (*setReg)( ulCtrlPort, SCC_WR0_SEL_WR3, SCC_WR3_RX_8_BITS | SCC_WR3_RX_EN );
196
197  /*
198   * Enable the transmitter pins set via register 5.
199   */
200  (*setReg)( ulCtrlPort, SCC_WR0_SEL_WR5, SCC_WR5_TX_8_BITS | SCC_WR5_TX_EN );
201
202  /*
203   * Disable interrupts
204   */
205  (*setReg)( ulCtrlPort, SCC_WR0_SEL_WR1, 0 );
206
207  /*
208   * Reset TX CRC
209   */
210  (*setReg)( ulCtrlPort, SCC_WR0_SEL_WR0, SCC_WR0_RST_TX_CRC );
211
212  /*
213   * Reset interrupts
214   */
215  (*setReg)( ulCtrlPort, SCC_WR0_SEL_WR0, SCC_WR0_RST_INT );
216}
217
218static int z85c30_open(
219  int   major,
220  int   minor,
221  void *arg
222)
223{
224  /*
225   * Assert DTR
226   */
227
228  if (Console_Port_Tbl[minor].pDeviceFlow !=&z85c30_flow_DTRCTS) {
229    z85c30_assert_DTR(minor);
230  }
231
232  return(RTEMS_SUCCESSFUL);
233}
234
235static int z85c30_close(
236  int   major,
237  int   minor,
238  void *arg
239)
240{
241  /*
242   * Negate DTR
243   */
244
245  if (Console_Port_Tbl[minor].pDeviceFlow !=&z85c30_flow_DTRCTS) {
246    z85c30_negate_DTR(minor);
247  }
248
249  return(RTEMS_SUCCESSFUL);
250}
251
252/*
253 *  z85c30_write_polled
254 *
255 *  This routine transmits a character using polling.
256 */
257
258static void z85c30_write_polled(
259  int   minor,
260  char  cChar
261)
262{
263  volatile unsigned8 z85c30_status;
264  unsigned32         ulCtrlPort;
265  getRegister_f      getReg;
266  setData_f          setData;
267
268  ulCtrlPort = Console_Port_Tbl[minor].ulCtrlPort1;
269  getReg     = Console_Port_Tbl[minor].getRegister;
270  setData    = Console_Port_Tbl[minor].setData;
271
272  /*
273   * Wait for the Transmit buffer to indicate that it is empty.
274   */
275
276  z85c30_status = (*getReg)( ulCtrlPort, SCC_WR0_SEL_RD0 );
277
278  while (!Z85C30_Status_Is_TX_buffer_empty(z85c30_status)) {
279    /*
280     * Yield while we wait
281     */
282    if (_System_state_Is_up(_System_state_Get())) {
283      rtems_task_wake_after(RTEMS_YIELD_PROCESSOR);
284    }
285    z85c30_status = (*getReg)(ulCtrlPort, SCC_WR0_SEL_RD0);
286  }
287
288  /*
289   * Write the character.
290   */
291
292  (*setData)(Console_Port_Tbl[minor].ulDataPort, cChar);
293}
294
295/*
296 *  Console Device Driver Entry Points
297 */
298
299static boolean z85c30_probe(int minor)
300{
301  /*
302   * If the configuration dependant probe has located the device then
303   * assume it is there
304   */
305
306  return(TRUE);
307}
308
309static void z85c30_init(int minor)
310{
311  unsigned32       ulCtrlPort;
312  unsigned8        dummy;
313  z85c30_context  *pz85c30Context;
314  setRegister_f    setReg;
315  getRegister_f    getReg;
316
317  setReg = Console_Port_Tbl[minor].setRegister;
318  getReg   = Console_Port_Tbl[minor].getRegister;
319
320  pz85c30Context = (z85c30_context *)malloc(sizeof(z85c30_context));
321
322  Console_Port_Data[minor].pDeviceContext=(void *)pz85c30Context;
323
324  pz85c30Context->ucModemCtrl = SCC_WR5_TX_8_BITS | SCC_WR5_TX_EN;
325
326  ulCtrlPort = Console_Port_Tbl[minor].ulCtrlPort1;
327  if (ulCtrlPort == Console_Port_Tbl[minor].ulCtrlPort2) {
328    /*
329     * This is channel A
330     */
331    /*
332     * Ensure port state machine is reset
333     */
334    dummy = (*getReg)(ulCtrlPort, SCC_WR0_SEL_RD0);
335
336    (*setReg)(ulCtrlPort, SCC_WR0_SEL_WR9, SCC_WR9_CH_A_RST);
337
338  } else {
339    /*
340     * This is channel B
341     */
342    /*
343     * Ensure port state machine is reset
344     */
345    dummy = (*getReg)(ulCtrlPort, SCC_WR0_SEL_RD0);
346
347    (*setReg)(ulCtrlPort, SCC_WR0_SEL_WR9, SCC_WR9_CH_B_RST);
348  }
349
350  z85c30_initialize_port(minor);
351}
352
353/*
354 * These routines provide control of the RTS and DTR lines
355 */
356
357/*
358 *  z85c30_assert_RTS
359 */
360
361static int z85c30_assert_RTS(int minor)
362{
363  rtems_interrupt_level  Irql;
364  z85c30_context        *pz85c30Context;
365  setRegister_f          setReg;
366
367  setReg = Console_Port_Tbl[minor].setRegister;
368
369  pz85c30Context = (z85c30_context *) Console_Port_Data[minor].pDeviceContext;
370 
371  /*
372   * Assert RTS
373   */
374
375  rtems_interrupt_disable(Irql);
376    pz85c30Context->ucModemCtrl|=SCC_WR5_RTS;
377    (*setReg)(
378      Console_Port_Tbl[minor].ulCtrlPort1,
379      SCC_WR0_SEL_WR5,
380      pz85c30Context->ucModemCtrl
381    );
382  rtems_interrupt_enable(Irql);
383  return 0;
384}
385
386/*
387 *  z85c30_negate_RTS
388 */
389
390static int z85c30_negate_RTS(int minor)
391{
392  rtems_interrupt_level  Irql;
393  z85c30_context        *pz85c30Context;
394  setRegister_f          setReg;
395
396  setReg = Console_Port_Tbl[minor].setRegister;
397
398  pz85c30Context = (z85c30_context *) Console_Port_Data[minor].pDeviceContext;
399 
400  /*
401   * Negate RTS
402   */
403
404  rtems_interrupt_disable(Irql);
405    pz85c30Context->ucModemCtrl&=~SCC_WR5_RTS;
406    (*setReg)(
407      Console_Port_Tbl[minor].ulCtrlPort1,
408      SCC_WR0_SEL_WR5,
409      pz85c30Context->ucModemCtrl
410    );
411  rtems_interrupt_enable(Irql);
412  return 0;
413}
414
415/*
416 * These flow control routines utilise a connection from the local DTR
417 * line to the remote CTS line
418 */
419
420/*
421 *  z85c30_assert_DTR
422 */
423
424static int z85c30_assert_DTR(int minor)
425{
426  rtems_interrupt_level  Irql;
427  z85c30_context        *pz85c30Context;
428  setRegister_f          setReg;
429
430  setReg = Console_Port_Tbl[minor].setRegister;
431
432  pz85c30Context = (z85c30_context *) Console_Port_Data[minor].pDeviceContext;
433 
434  /*
435   * Assert DTR
436   */
437
438  rtems_interrupt_disable(Irql);
439    pz85c30Context->ucModemCtrl|=SCC_WR5_DTR;
440    (*setReg)(
441      Console_Port_Tbl[minor].ulCtrlPort1,
442      SCC_WR0_SEL_WR5,
443      pz85c30Context->ucModemCtrl
444  );
445  rtems_interrupt_enable(Irql);
446  return 0;
447}
448
449/*
450 *  z85c30_negate_DTR
451 */
452
453static int z85c30_negate_DTR(int minor)
454{
455  rtems_interrupt_level  Irql;
456  z85c30_context        *pz85c30Context;
457  setRegister_f          setReg;
458
459  setReg = Console_Port_Tbl[minor].setRegister;
460
461  pz85c30Context = (z85c30_context *) Console_Port_Data[minor].pDeviceContext;
462 
463  /*
464   * Negate DTR
465   */
466
467  rtems_interrupt_disable(Irql);
468    pz85c30Context->ucModemCtrl&=~SCC_WR5_DTR;
469    (*setReg)(
470      Console_Port_Tbl[minor].ulCtrlPort1,
471      SCC_WR0_SEL_WR5,
472      pz85c30Context->ucModemCtrl
473  );
474  rtems_interrupt_enable(Irql);
475  return 0;
476}
477
478/*
479 *  z85c30_isr
480 *
481 *  This routine is the console interrupt handler for COM3 and COM4
482 *
483 *  Input parameters:
484 *    vector - vector number
485 *
486 *  Output parameters: NONE
487 *
488 *  Return values:     NONE
489 */
490
491static void z85c30_process(
492  int        minor,
493  unsigned8  ucIntPend
494)
495{
496  unsigned32          ulCtrlPort;
497  unsigned32          ulDataPort;
498  volatile unsigned8  z85c30_status;
499  char                cChar;
500  setRegister_f       setReg;
501  getRegister_f       getReg;
502  getData_f           getData;
503  setData_f           setData;
504
505  ulCtrlPort = Console_Port_Tbl[minor].ulCtrlPort1;
506  ulDataPort = Console_Port_Tbl[minor].ulDataPort;
507  setReg     = Console_Port_Tbl[minor].setRegister;
508  getReg     = Console_Port_Tbl[minor].getRegister;
509  getData    = Console_Port_Tbl[minor].getData;
510  getData    = Console_Port_Tbl[minor].getData;
511
512  /*
513   * Deal with any received characters
514   */
515  while (ucIntPend&SCC_RR3_B_RX_IP)
516  {
517    z85c30_status=(*getReg)(ulCtrlPort, SCC_WR0_SEL_RD0);
518    if (!Z85C30_Status_Is_RX_character_available(z85c30_status)) {
519      break;
520    }
521
522    /*
523     * Return the character read.
524     */
525
526    cChar = (*getData)(ulDataPort);
527
528    rtems_termios_enqueue_raw_characters(
529      Console_Port_Data[minor].termios_data,
530      &cChar,
531      1
532    );
533  }
534
535  while (TRUE)
536  {
537    z85c30_status = (*getReg)(ulCtrlPort, SCC_WR0_SEL_RD0);
538    if (!Z85C30_Status_Is_TX_buffer_empty(z85c30_status)) {
539      /*
540       * We'll get another interrupt when
541       * the transmitter holding reg. becomes
542       * free again and we are clear to send
543       */
544      break;
545    }
546 
547    if (!Z85C30_Status_Is_CTS_asserted(z85c30_status)) {
548      /*
549       * We can't transmit yet
550       */
551      (*setReg)(ulCtrlPort, SCC_WR0_SEL_WR0, SCC_WR0_RST_TX_INT);
552      /*
553       * The next state change of CTS will wake us up
554       */
555      break;
556    }
557 
558    if (Ring_buffer_Is_empty(&Console_Port_Data[minor].TxBuffer)) {
559      Console_Port_Data[minor].bActive=FALSE;
560      if (Console_Port_Tbl[minor].pDeviceFlow !=&z85c30_flow_RTSCTS) {
561        z85c30_negate_RTS(minor);
562      }
563      /*
564       * There is no data to transmit
565       */
566      (*setReg)(ulCtrlPort, SCC_WR0_SEL_WR0, SCC_WR0_RST_TX_INT);
567      break;
568    }
569
570    Ring_buffer_Remove_character( &Console_Port_Data[minor].TxBuffer, cChar);
571
572    /*
573     * transmit character
574     */
575    (*setData)(ulDataPort, cChar);
576
577    /*
578     * Interrupt once FIFO has room
579      */
580    (*setReg)(ulCtrlPort, SCC_WR0_SEL_WR0, SCC_WR0_RST_TX_INT);
581    break;
582  }
583
584  if (ucIntPend&SCC_RR3_B_EXT_IP) {
585    /*
586     * Clear the external status interrupt
587     */
588    (*setReg)(ulCtrlPort, SCC_WR0_SEL_WR0, SCC_WR0_RST_INT);
589    z85c30_status=(*getReg)(ulCtrlPort, SCC_WR0_SEL_RD0);
590  }
591
592  /*
593   * Reset interrupts
594   */
595  (*setReg)(ulCtrlPort, SCC_WR0_SEL_WR0, SCC_WR0_RST_HI_IUS);
596}
597
598static rtems_isr z85c30_isr(
599  rtems_vector_number vector
600)
601{
602  int                 minor;
603  unsigned32          ulCtrlPort;
604  volatile unsigned8  ucIntPend;
605  volatile unsigned8  ucIntPendPort;
606  getRegister_f    getReg;
607
608  for (minor=0;minor<Console_Port_Count;minor++) {
609    if (vector==Console_Port_Tbl[minor].ulIntVector) {
610      ulCtrlPort = Console_Port_Tbl[minor].ulCtrlPort2;
611      getReg     = Console_Port_Tbl[minor].getRegister;
612      do {
613        ucIntPend=(*getReg)(ulCtrlPort, SCC_WR0_SEL_RD3);
614
615          /*
616           * If this is channel A select channel A status
617           */
618
619          if (ulCtrlPort == Console_Port_Tbl[minor].ulCtrlPort1) {
620            ucIntPendPort = ucIntPend>>3;
621            ucIntPendPort = ucIntPendPort&=7;
622          } else {
623            ucIntPendPort = ucIntPend &= 7;
624          }
625
626          if (ucIntPendPort) {
627            z85c30_process(minor, ucIntPendPort);
628          }
629      } while (ucIntPendPort);
630    }
631  }
632}
633
634/*
635 *  z85c30_flush
636 */
637
638static int z85c30_flush(
639  int major,
640  int minor,
641  void *arg
642)
643{
644  while (!Ring_buffer_Is_empty(&Console_Port_Data[minor].TxBuffer)) {
645    /*
646     * Yield while we wait
647     */
648    if (_System_state_Is_up(_System_state_Get())) {
649      rtems_task_wake_after(RTEMS_YIELD_PROCESSOR);
650    }
651  }
652
653  z85c30_close(major, minor, arg);
654
655  return(RTEMS_SUCCESSFUL);
656}
657
658/*
659 *  z85c30_initialize_interrupts
660 *
661 *  This routine initializes the console's receive and transmit
662 *  ring buffers and loads the appropriate vectors to handle the interrupts.
663 *
664 *  Input parameters:  NONE
665 *
666 *  Output parameters: NONE
667 *
668 *  Return values:     NONE
669 */
670
671static void z85c30_enable_interrupts(
672  int minor
673)
674{
675  unsigned32     ulCtrlPort;
676  setRegister_f  setReg;
677
678  ulCtrlPort = Console_Port_Tbl[minor].ulCtrlPort1;
679  setReg     = Console_Port_Tbl[minor].setRegister;
680
681  /*
682   * Enable interrupts
683   */
684  (*setReg)(
685    ulCtrlPort,
686    SCC_WR0_SEL_WR1,
687    SCC_WR1_EXT_INT_EN | SCC_WR1_TX_INT_EN | SCC_WR1_INT_ALL_RX
688  );
689  (*setReg)(ulCtrlPort, SCC_WR0_SEL_WR2, 0);
690  (*setReg)(ulCtrlPort, SCC_WR0_SEL_WR9, SCC_WR9_MIE);
691
692  /*
693   * Reset interrupts
694   */
695  (*setReg)(ulCtrlPort, SCC_WR0_SEL_WR0, SCC_WR0_RST_INT);
696}
697
698static void z85c30_initialize_interrupts(
699  int minor
700)
701{
702  z85c30_init(minor);
703
704  Ring_buffer_Initialize(&Console_Port_Data[minor].TxBuffer);
705
706  Console_Port_Data[minor].bActive=FALSE;
707  if (Console_Port_Tbl[minor].pDeviceFlow !=&z85c30_flow_RTSCTS) {
708    z85c30_negate_RTS(minor);
709  }
710
711  if (Console_Port_Tbl[minor].ulCtrlPort1== Console_Port_Tbl[minor].ulCtrlPort2) {
712    /*
713     * Only do this for Channel A
714     */
715
716    set_vector(z85c30_isr, Console_Port_Tbl[minor].ulIntVector, 1);
717  }
718
719  z85c30_enable_interrupts(minor);
720}
721
722/*
723 *  z85c30_write_support_int
724 *
725 *  Console Termios output entry point.
726 *
727 */
728
729static int z85c30_write_support_int(
730  int   minor, 
731  const char *buf, 
732  int   len)
733{
734  int i;
735  unsigned32 Irql;
736
737  for (i=0; i<len;) {
738    if (Ring_buffer_Is_full(&Console_Port_Data[minor].TxBuffer)) {
739      if (!Console_Port_Data[minor].bActive) {
740        /*
741         * Wake up the device
742         */
743        if (Console_Port_Tbl[minor].pDeviceFlow !=&z85c30_flow_RTSCTS) {
744          z85c30_assert_RTS(minor);
745        }
746        rtems_interrupt_disable(Irql);
747        Console_Port_Data[minor].bActive=TRUE;
748        z85c30_process(minor, SCC_RR3_B_TX_IP);
749        rtems_interrupt_enable(Irql);
750      } else {
751        /*
752         * Yield while we await an interrupt
753         */
754        rtems_task_wake_after(RTEMS_YIELD_PROCESSOR);
755      }
756
757      /*
758       * Wait for ring buffer to empty
759       */
760      continue;
761    } else {
762      Ring_buffer_Add_character( &Console_Port_Data[minor].TxBuffer, buf[i]);
763      i++;
764    }
765  }
766
767  /*
768   * Ensure that characters are on the way
769   */
770  if (!Console_Port_Data[minor].bActive) {
771    /*
772     * Wake up the device
773     */
774    if (Console_Port_Tbl[minor].pDeviceFlow !=&z85c30_flow_RTSCTS) {
775            z85c30_assert_RTS(minor);
776    }
777    rtems_interrupt_disable(Irql);
778    Console_Port_Data[minor].bActive=TRUE;
779    z85c30_process(minor, SCC_RR3_B_TX_IP);
780    rtems_interrupt_enable(Irql);
781  }
782
783  return (len);
784}
785
786/*
787 *  z85c30_inbyte_nonblocking_polled
788 *
789 *  This routine polls for a character.
790 */
791
792static int z85c30_inbyte_nonblocking_polled(
793  int  minor
794)
795{
796  volatile unsigned8  z85c30_status;
797  unsigned32          ulCtrlPort;
798  getRegister_f       getReg;
799  getData_f           getData;
800
801  ulCtrlPort = Console_Port_Tbl[minor].ulCtrlPort1;
802  getData    = Console_Port_Tbl[minor].getData;
803  getReg     = Console_Port_Tbl[minor].getRegister;
804
805  /*
806   * return -1 if a character is not available.
807   */
808  z85c30_status=(*getReg)(ulCtrlPort, SCC_WR0_SEL_RD0);
809  if (!Z85C30_Status_Is_RX_character_available(z85c30_status)) {
810    return -1;
811  }
812
813  /*
814   * Return the character read.
815   */
816  return (*getData)(Console_Port_Tbl[minor].ulDataPort);
817}
818
819/*
820 *  z85c30_write_support_polled
821 *
822 *  Console Termios output entry point.
823 *
824 */
825
826static int z85c30_write_support_polled(
827  int   minor,
828  const char *buf,
829  int   len)
830{
831  int nwrite=0;
832
833  /*
834   * poll each byte in the string out of the port.
835   */
836  while (nwrite < len) {
837    z85c30_write_polled(minor, *buf++);
838    nwrite++;
839  }
840
841  /*
842   * return the number of bytes written.
843   */
844  return nwrite;
845}
Note: See TracBrowser for help on using the repository browser.