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

4.104.114.84.95
Last change on this file since ee3b242b was ee3b242b, checked in by Joel Sherrill <joel.sherrill@…>, on Jun 13, 1998 at 4:03:57 PM

Initial incarnation of libchip compiles.

  • Property mode set to 100644
File size: 18.7 KB
Line 
1/*
2 *  This file contains the console driver chip level routines for the
3 *  z85c30 chip.
4 *
5 *  COPYRIGHT (c) 1998 by Radstone Technology
6 *
7 *
8 * THIS FILE IS PROVIDED TO YOU, THE USER, "AS IS", WITHOUT WARRANTY OF ANY
9 * KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
10 * IMPLIED WARRANTY OF FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK
11 * AS TO THE QUALITY AND PERFORMANCE OF ALL CODE IN THIS FILE IS WITH YOU.
12 *
13 * You are hereby granted permission to use, copy, modify, and distribute
14 * this file, provided that this notice, plus the above copyright notice
15 * and disclaimer, appears in all copies. Radstone Technology will provide
16 * no support for this code.
17 *
18 *  COPYRIGHT (c) 1989-1997.
19 *  On-Line Applications Research Corporation (OAR).
20 *  Copyright assigned to U.S. Government, 1994.
21 *
22 *  The license and distribution terms for this file may be
23 *  found in the file LICENSE in this distribution or at
24 *  http://www.OARcorp.com/rtems/license.html.
25 *
26 *  $Id$
27 */
28
29#include <rtems.h>
30#include <rtems/libio.h>
31#include <stdlib.h>
32
33#include <libchip/serial.h>
34#include "z85c30_p.h"
35
36/*
37 * Flow control is only supported when using interrupts
38 */
39console_flow z85c30_flow_RTSCTS =
40{
41  z85c30_negate_RTS,    /* deviceStopRemoteTx */
42  z85c30_assert_RTS     /* deviceStartRemoteTx */
43};
44
45console_flow z85c30_flow_DTRCTS =
46{
47  z85c30_negate_DTR,    /* deviceStopRemoteTx */
48  z85c30_assert_DTR     /* deviceStartRemoteTx */
49};
50
51/*
52 * Exported driver function table
53 */
54console_fns z85c30_fns =
55{
56  z85c30_probe,                  /* deviceProbe */
57  z85c30_open,                   /* deviceFirstOpen */
58  z85c30_flush,                  /* deviceLastClose */
59  NULL,                          /* deviceRead */
60  z85c30_write_support_int,      /* deviceWrite */
61  z85c30_initialize_interrupts,  /* deviceInitialize */
62  z85c30_write_polled,           /* deviceWritePolled */
63  FALSE,                         /* deviceOutputUsesInterrupts */
64};
65
66console_fns z85c30_fns_polled =
67{
68  z85c30_probe,                      /* deviceProbe */
69  z85c30_open,                       /* deviceFirstOpen */
70  z85c30_close,                      /* deviceLastClose */
71  z85c30_inbyte_nonblocking_polled,  /* deviceRead */
72  z85c30_write_support_polled,       /* deviceWrite */
73  z85c30_init,                       /* deviceInitialize */
74  z85c30_write_polled,               /* deviceWritePolled */
75  FALSE,                             /* deviceOutputUsesInterrupts */
76};
77
78extern void set_vector( rtems_isr_entry, rtems_vector_number, int );
79
80/*
81 *  Types for get and set register routines
82 */
83
84typedef unsigned8 (*getRegister_f)(unsigned32 port, unsigned8 register);
85typedef void      (*setRegister_f)(
86                            unsigned32 port, unsigned8 reg, unsigned8 value);
87typedef unsigned8 (*getData_f)(unsigned32 port);
88typedef void      (*setData_f)(unsigned32 port, unsigned8 value);
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 dependant 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 *  z85c30_assert_RTS
351 */
352static int z85c30_assert_RTS(int minor)
353{
354  rtems_interrupt_level  Irql;
355  z85c30_context        *pz85c30Context;
356  setRegister_f          setReg;
357
358  setReg = Console_Port_Tbl[minor].setRegister;
359
360  pz85c30Context = (z85c30_context *) Console_Port_Data[minor].pDeviceContext;
361 
362  /*
363   * Assert RTS
364   */
365
366  rtems_interrupt_disable(Irql);
367    pz85c30Context->ucModemCtrl|=SCC_WR5_RTS;
368    (*setReg)(
369      Console_Port_Tbl[minor].ulCtrlPort1,
370      SCC_WR0_SEL_WR5,
371      pz85c30Context->ucModemCtrl
372    );
373  rtems_interrupt_enable(Irql);
374  return 0;
375}
376
377/*
378 *  z85c30_negate_RTS
379 */
380static int z85c30_negate_RTS(int minor)
381{
382  rtems_interrupt_level  Irql;
383  z85c30_context        *pz85c30Context;
384  setRegister_f          setReg;
385
386  setReg = Console_Port_Tbl[minor].setRegister;
387
388  pz85c30Context = (z85c30_context *) Console_Port_Data[minor].pDeviceContext;
389 
390  /*
391   * Negate RTS
392   */
393
394  rtems_interrupt_disable(Irql);
395    pz85c30Context->ucModemCtrl&=~SCC_WR5_RTS;
396    (*setReg)(
397      Console_Port_Tbl[minor].ulCtrlPort1,
398      SCC_WR0_SEL_WR5,
399      pz85c30Context->ucModemCtrl
400    );
401  rtems_interrupt_enable(Irql);
402  return 0;
403}
404
405/*
406 * These flow control routines utilise a connection from the local DTR
407 * line to the remote CTS line
408 */
409/*
410 *  z85c30_assert_DTR
411 */
412static int z85c30_assert_DTR(int minor)
413{
414  rtems_interrupt_level  Irql;
415  z85c30_context        *pz85c30Context;
416  setRegister_f          setReg;
417
418  setReg = Console_Port_Tbl[minor].setRegister;
419
420  pz85c30Context = (z85c30_context *) Console_Port_Data[minor].pDeviceContext;
421 
422  /*
423   * Assert DTR
424   */
425
426  rtems_interrupt_disable(Irql);
427    pz85c30Context->ucModemCtrl|=SCC_WR5_DTR;
428    (*setReg)(
429      Console_Port_Tbl[minor].ulCtrlPort1,
430      SCC_WR0_SEL_WR5,
431      pz85c30Context->ucModemCtrl
432  );
433  rtems_interrupt_enable(Irql);
434  return 0;
435}
436
437/*
438 *  z85c30_negate_DTR
439 */
440static int z85c30_negate_DTR(int minor)
441{
442  rtems_interrupt_level  Irql;
443  z85c30_context        *pz85c30Context;
444  setRegister_f          setReg;
445
446  setReg = Console_Port_Tbl[minor].setRegister;
447
448  pz85c30Context = (z85c30_context *) Console_Port_Data[minor].pDeviceContext;
449 
450  /*
451   * Negate DTR
452   */
453
454  rtems_interrupt_disable(Irql);
455    pz85c30Context->ucModemCtrl&=~SCC_WR5_DTR;
456    (*setReg)(
457      Console_Port_Tbl[minor].ulCtrlPort1,
458      SCC_WR0_SEL_WR5,
459      pz85c30Context->ucModemCtrl
460  );
461  rtems_interrupt_enable(Irql);
462  return 0;
463}
464
465/*
466 *  z85c30_isr
467 *
468 *  This routine is the console interrupt handler for COM3 and COM4
469 *
470 *  Input parameters:
471 *    vector - vector number
472 *
473 *  Output parameters: NONE
474 *
475 *  Return values:     NONE
476 */
477
478static void z85c30_process(
479  int        minor,
480  unsigned8  ucIntPend
481)
482{
483  unsigned32          ulCtrlPort;
484  unsigned32          ulDataPort;
485  volatile unsigned8  z85c30_status;
486  char                cChar;
487  setRegister_f       setReg;
488  getRegister_f       getReg;
489  getData_f           getData;
490  setData_f           setData;
491
492  ulCtrlPort = Console_Port_Tbl[minor].ulCtrlPort1;
493  ulDataPort = Console_Port_Tbl[minor].ulDataPort;
494  setReg     = Console_Port_Tbl[minor].setRegister;
495  getReg     = Console_Port_Tbl[minor].getRegister;
496  getData    = Console_Port_Tbl[minor].getData;
497  getData    = Console_Port_Tbl[minor].getData;
498
499  /*
500   * Deal with any received characters
501   */
502  while (ucIntPend&SCC_RR3_B_RX_IP)
503  {
504    z85c30_status=(*getReg)(ulCtrlPort, SCC_WR0_SEL_RD0);
505    if (!Z85C30_Status_Is_RX_character_available(z85c30_status)) {
506      break;
507    }
508
509    /*
510     * Return the character read.
511     */
512
513    cChar = (*getData)(ulDataPort);
514
515    rtems_termios_enqueue_raw_characters(
516      Console_Port_Data[minor].termios_data,
517      &cChar,
518      1
519    );
520  }
521
522  while (TRUE)
523  {
524    z85c30_status = (*getReg)(ulCtrlPort, SCC_WR0_SEL_RD0);
525    if (!Z85C30_Status_Is_TX_buffer_empty(z85c30_status)) {
526      /*
527       * We'll get another interrupt when
528       * the transmitter holding reg. becomes
529       * free again and we are clear to send
530       */
531      break;
532    }
533 
534    if (!Z85C30_Status_Is_CTS_asserted(z85c30_status)) {
535      /*
536       * We can't transmit yet
537       */
538      (*setReg)(ulCtrlPort, SCC_WR0_SEL_WR0, SCC_WR0_RST_TX_INT);
539      /*
540       * The next state change of CTS will wake us up
541       */
542      break;
543    }
544 
545    if (Ring_buffer_Is_empty(&Console_Port_Data[minor].TxBuffer)) {
546      Console_Port_Data[minor].bActive=FALSE;
547      if (Console_Port_Tbl[minor].pDeviceFlow !=&z85c30_flow_RTSCTS) {
548        z85c30_negate_RTS(minor);
549      }
550      /*
551       * There is no data to transmit
552       */
553      (*setReg)(ulCtrlPort, SCC_WR0_SEL_WR0, SCC_WR0_RST_TX_INT);
554      break;
555    }
556
557    Ring_buffer_Remove_character( &Console_Port_Data[minor].TxBuffer, cChar);
558
559    /*
560     * transmit character
561     */
562    (*setData)(ulDataPort, cChar);
563
564    /*
565     * Interrupt once FIFO has room
566      */
567    (*setReg)(ulCtrlPort, SCC_WR0_SEL_WR0, SCC_WR0_RST_TX_INT);
568    break;
569  }
570
571  if (ucIntPend&SCC_RR3_B_EXT_IP) {
572    /*
573     * Clear the external status interrupt
574     */
575    (*setReg)(ulCtrlPort, SCC_WR0_SEL_WR0, SCC_WR0_RST_INT);
576    z85c30_status=(*getReg)(ulCtrlPort, SCC_WR0_SEL_RD0);
577  }
578
579  /*
580   * Reset interrupts
581   */
582  (*setReg)(ulCtrlPort, SCC_WR0_SEL_WR0, SCC_WR0_RST_HI_IUS);
583}
584
585static rtems_isr z85c30_isr(
586  rtems_vector_number vector
587)
588{
589  int                 minor;
590  unsigned32          ulCtrlPort;
591  volatile unsigned8  ucIntPend;
592  volatile unsigned8  ucIntPendPort;
593  getRegister_f    getReg;
594
595  for (minor=0;minor<Console_Port_Count;minor++) {
596    if (vector==Console_Port_Tbl[minor].ulIntVector) {
597      ulCtrlPort = Console_Port_Tbl[minor].ulCtrlPort2;
598      getReg     = Console_Port_Tbl[minor].getRegister;
599      do {
600        ucIntPend=(*getReg)(ulCtrlPort, SCC_WR0_SEL_RD3);
601
602          /*
603           * If this is channel A select channel A status
604           */
605
606          if (ulCtrlPort == Console_Port_Tbl[minor].ulCtrlPort1) {
607            ucIntPendPort = ucIntPend>>3;
608            ucIntPendPort = ucIntPendPort&=7;
609          } else {
610            ucIntPendPort = ucIntPend &= 7;
611          }
612
613          if (ucIntPendPort) {
614            z85c30_process(minor, ucIntPendPort);
615          }
616      } while (ucIntPendPort);
617    }
618  }
619}
620
621/*
622 *  z85c30_flush
623 */
624
625static int z85c30_flush(
626  int major,
627  int minor,
628  void *arg
629)
630{
631  while (!Ring_buffer_Is_empty(&Console_Port_Data[minor].TxBuffer)) {
632    /*
633     * Yield while we wait
634     */
635    if (_System_state_Is_up(_System_state_Get())) {
636      rtems_task_wake_after(RTEMS_YIELD_PROCESSOR);
637    }
638  }
639
640  z85c30_close(major, minor, arg);
641
642  return(RTEMS_SUCCESSFUL);
643}
644
645/*
646 *  z85c30_initialize_interrupts
647 *
648 *  This routine initializes the console's receive and transmit
649 *  ring buffers and loads the appropriate vectors to handle the interrupts.
650 *
651 *  Input parameters:  NONE
652 *
653 *  Output parameters: NONE
654 *
655 *  Return values:     NONE
656 */
657
658static void z85c30_enable_interrupts(
659  int minor
660)
661{
662  unsigned32     ulCtrlPort;
663  setRegister_f  setReg;
664
665  ulCtrlPort = Console_Port_Tbl[minor].ulCtrlPort1;
666  setReg     = Console_Port_Tbl[minor].setRegister;
667
668  /*
669   * Enable interrupts
670   */
671  (*setReg)(
672    ulCtrlPort,
673    SCC_WR0_SEL_WR1,
674    SCC_WR1_EXT_INT_EN | SCC_WR1_TX_INT_EN | SCC_WR1_INT_ALL_RX
675  );
676  (*setReg)(ulCtrlPort, SCC_WR0_SEL_WR2, 0);
677  (*setReg)(ulCtrlPort, SCC_WR0_SEL_WR9, SCC_WR9_MIE);
678
679  /*
680   * Reset interrupts
681   */
682  (*setReg)(ulCtrlPort, SCC_WR0_SEL_WR0, SCC_WR0_RST_INT);
683}
684
685static void z85c30_initialize_interrupts(
686  int minor
687)
688{
689  z85c30_init(minor);
690
691  Ring_buffer_Initialize(&Console_Port_Data[minor].TxBuffer);
692
693  Console_Port_Data[minor].bActive=FALSE;
694  if (Console_Port_Tbl[minor].pDeviceFlow !=&z85c30_flow_RTSCTS) {
695    z85c30_negate_RTS(minor);
696  }
697
698  if (Console_Port_Tbl[minor].ulCtrlPort1== Console_Port_Tbl[minor].ulCtrlPort2) {
699    /*
700     * Only do this for Channel A
701     */
702
703    set_vector(z85c30_isr, Console_Port_Tbl[minor].ulIntVector, 1);
704  }
705
706  z85c30_enable_interrupts(minor);
707}
708
709/*
710 *  z85c30_write_support_int
711 *
712 *  Console Termios output entry point.
713 *
714 */
715static int z85c30_write_support_int(
716  int   minor, 
717  const char *buf, 
718  int   len)
719{
720  int i;
721  unsigned32 Irql;
722
723  for (i=0; i<len;) {
724    if (Ring_buffer_Is_full(&Console_Port_Data[minor].TxBuffer)) {
725      if (!Console_Port_Data[minor].bActive) {
726        /*
727         * Wake up the device
728         */
729        if (Console_Port_Tbl[minor].pDeviceFlow !=&z85c30_flow_RTSCTS) {
730          z85c30_assert_RTS(minor);
731        }
732        rtems_interrupt_disable(Irql);
733        Console_Port_Data[minor].bActive=TRUE;
734        z85c30_process(minor, SCC_RR3_B_TX_IP);
735        rtems_interrupt_enable(Irql);
736      } else {
737        /*
738         * Yield while we await an interrupt
739         */
740        rtems_task_wake_after(RTEMS_YIELD_PROCESSOR);
741      }
742
743      /*
744       * Wait for ring buffer to empty
745       */
746      continue;
747    } else {
748      Ring_buffer_Add_character( &Console_Port_Data[minor].TxBuffer, buf[i]);
749      i++;
750    }
751  }
752
753  /*
754   * Ensure that characters are on the way
755   */
756  if (!Console_Port_Data[minor].bActive) {
757    /*
758     * Wake up the device
759     */
760    if (Console_Port_Tbl[minor].pDeviceFlow !=&z85c30_flow_RTSCTS) {
761            z85c30_assert_RTS(minor);
762    }
763    rtems_interrupt_disable(Irql);
764    Console_Port_Data[minor].bActive=TRUE;
765    z85c30_process(minor, SCC_RR3_B_TX_IP);
766    rtems_interrupt_enable(Irql);
767  }
768
769  return (len);
770}
771
772/*
773 *  z85c30_inbyte_nonblocking_polled
774 *
775 *  This routine polls for a character.
776 */
777static int z85c30_inbyte_nonblocking_polled(
778  int  minor
779)
780{
781  volatile unsigned8  z85c30_status;
782  unsigned32          ulCtrlPort;
783  getRegister_f       getReg;
784  getData_f           getData;
785
786  ulCtrlPort = Console_Port_Tbl[minor].ulCtrlPort1;
787  getData    = Console_Port_Tbl[minor].getData;
788  getReg     = Console_Port_Tbl[minor].getRegister;
789
790  /*
791   * return -1 if a character is not available.
792   */
793  z85c30_status=(*getReg)(ulCtrlPort, SCC_WR0_SEL_RD0);
794  if (!Z85C30_Status_Is_RX_character_available(z85c30_status)) {
795    return -1;
796  }
797
798  /*
799   * Return the character read.
800   */
801  return (*getData)(Console_Port_Tbl[minor].ulDataPort);
802}
803
804/*
805 *  z85c30_write_support_polled
806 *
807 *  Console Termios output entry point.
808 *
809 */
810
811static int z85c30_write_support_polled(
812  int   minor,
813  const char *buf,
814  int   len)
815{
816  int nwrite=0;
817
818  /*
819   * poll each byte in the string out of the port.
820   */
821  while (nwrite < len) {
822    z85c30_write_polled(minor, *buf++);
823    nwrite++;
824  }
825
826  /*
827   * return the number of bytes written.
828   */
829  return nwrite;
830}
Note: See TracBrowser for help on using the repository browser.