source: rtems/c/src/libchip/serial/z85c30.c @ 9eef52b

4.104.114.84.95
Last change on this file since 9eef52b was 8a2d4f2b, checked in by Joel Sherrill <joel.sherrill@…>, on Jun 23, 1998 at 2:54:09 PM

Added NULL entry for setAttributes.

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