source: rtems/c/src/lib/libbsp/powerpc/ppcn_60x/console/z85c30.c @ 0c04c377

4.104.114.84.95
Last change on this file since 0c04c377 was 0c04c377, checked in by Joel Sherrill <joel.sherrill@…>, on 02/18/99 at 16:48:14

./clock/Makefile.in,v
./clock/clock.c,v
./console/Makefile.in,v
./console/config.c,v
./console/console.c,v
./console/console.h,v
./console/debugio.c,v
./console/i8042.c,v
./console/i8042_p.h,v
./console/i8042vga.c,v
./console/i8042vga.h,v
./console/ns16550.c,v
./console/ns16550.h,v
./console/ns16550_p.h,v
./console/ns16550cfg.c,v
./console/ns16550cfg.h,v
./console/vga.c,v
./console/vga_p.h,v
./console/z85c30.c,v
./console/z85c30.h,v
./console/z85c30_p.h,v
./console/z85c30cfg.c,v
./console/z85c30cfg.h,v
./include/Makefile.in,v
./include/bsp.h,v
./include/chain.h,v
./include/coverhd.h,v
./include/extisrdrv.h,v
./include/nvram.h,v
./include/pci.h,v
./include/tod.h,v
./network/Makefile.in,v
./network/amd79c970.c,v
./network/amd79c970.h,v
./nvram/Makefile.in,v
./nvram/ds1385.h,v
./nvram/mk48t18.h,v
./nvram/nvram.c,v
./nvram/prepnvr.h,v
./nvram/stk11c68.h,v
./pci/Makefile.in,v
./pci/pci.c,v
./start/Makefile.in,v
./start/start.s,v
./startup/Makefile.in,v
./startup/bspclean.c,v
./startup/bspstart.c,v
./startup/bsptrap.s,v
./startup/device-tree,v
./startup/genpvec.c,v
./startup/linkcmds,v
./startup/rtems-ctor.cc,v
./startup/sbrk.c,v
./startup/setvec.c,v
./startup/spurious.c,v
./startup/swap.c,v
./timer/Makefile.in,v
./timer/timer.c,v
./tod/Makefile.in,v
./tod/cmos.h,v
./tod/tod.c,v
./universe/Makefile.in,v
./universe/universe.c,v
./vectors/Makefile.in,v
./vectors/README,v
./vectors/align_h.s,v
./vectors/vectors.s,v
./wrapup/Makefile.in,v
./Makefile.in,v
./README,v
./STATUS,v
./bsp_specs,v

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