source: rtems/c/src/lib/libbsp/m68k/mrm332/console/sci.c @ 0b6d74d0

4.104.114.84.95
Last change on this file since 0b6d74d0 was 0b6d74d0, checked in by Joel Sherrill <joel.sherrill@…>, on 11/04/02 at 14:26:48

2002-11-04 Joel Sherrill <joel@…>

  • console/sci.c, spurious/spinit.c: Removed warnings.
  • Property mode set to 100644
File size: 51.8 KB
Line 
1/*****************************************************************************
2* File:     sci.c
3*
4* Desc:     This file contains the console IO routines for the SCI port.
5*           There are two interfaces in this module. One is for the rtems
6*           termios/console code and the other is a device driver interface.
7*           This module works together with the termio module which is
8*           sometimes referred to as the "line disciplines" which implements
9*           terminal i/o processing like tabs, backspaces, and newlines.
10*           The rtems printf uses interrupt io and the rtems printk routine
11*           uses polled io which is better for debugging.
12*
13* Index:    Documentation
14*           Section A  - Include Files
15*           Section B  - Manifest Constants
16*           Section C  - External Data
17*           Section D  - External Functions
18*           Section E  - Local Functions
19*           Section F  - Local Variables
20*           Section G  - A circular data buffer for rcv chars
21*           Section H  - RTEMS termios callbacks for the interrupt api
22*           Section I  - RTEMS termios callbacks for the polled api
23
24*           Section 0  - Miscellaneous routines
25*           Section 1  - Routines to manipulate the circular buffer
26*           Section 2  - Interrupt based entry points for the termios module
27*           Section 3  - Polling based entry points for the termios module
28*           Section 4  - Device driver public api entry points
29*           Section 5  - Hardware level routines
30*           Section 6  - Testing and debugging code
31*
32* Refer:    Motorola QSM Reference Manual - Chapter 5 - SCI sub-module
33*
34* Note:     See bsp.h,confdefs.h,system.h for installing drivers into RTEMS.
35*
36* $Id$
37*
38* $Log$
39* Revision 1.1  2002/02/28 23:10:39  joel
40* 2002-02-28    Mike Panetta <ahuitzot@mindspring.com>
41*
42*       * console/sci.c, console/sci.h,
43*       console/console.c: Added new SCI driver.
44*       * start/start.c: Removed file.
45*       * start/start.S: New file, the asm portion of the updated start code.
46*       * start/configure.am: Added start.S, removed start.c
47*       * startup/start_c.c: New file, the C portion of the updated start code.         Contains most of the code that was in the old start.c.
48*       * startup/configure.am: Added start_c.c to C_FILES.
49*       * include/bsp.h: Added include <rtems/bspIo.h>
50*
51*****************************************************************************/
52
53
54/*****************************************************************************
55  Compiler Options for the incurably curious
56*****************************************************************************/
57
58/*
59/opt/rtems/bin/m68k-rtems-gcc
60    --pipe                                      # use pipes, not tmp files
61    -B../../../../../../../../opti/lib/         # where the library is
62    -specs bsp_specs                            # ???
63    -qrtems                                     # ???
64    -g                                          # add debugging info
65    -Wall                                       # issue all warnings
66    -fasm                                       # allow inline asm???
67    -DCONSOLE_SCI                               # for opti-r box/rev b proto
68    -mcpu32                                     # machine = motorola cpu 32
69    -c                                          # compile, don't link
70    -O4                                         # max optimization
71    -fomit-frame-pointer                        # stack frames are optional
72    -o o-optimize/sci.o                         # the object file
73    ../../../../../../../../../rtems/c/src/lib/libbsp/m68k/opti/console/sci.c
74*/
75
76
77/*****************************************************************************
78  Overview of serial port console terminal input/output
79*****************************************************************************/
80
81/*
82   +-----------+                               +---------+
83   |    app    |                               |   app   |
84   +-----------+                               +---------+
85         |                                          |
86         | (printf,scanf,etc.)                      |
87         v                                          |
88   +-----------+                                    |
89   |    libc   |                                    |
90   +-----------+                                    |
91         |                                          |
92         |                                          |
93         |     (open,close,read,write,ioctl)        |
94   ======|==========================================|========================
95         | /dev/console                             | /dev/sci
96         | (stdin,stdout,stderr)                    |
97   ======|==========================================|========================
98         |                                          |
99         |                                          |
100         v                                          v
101   +-----------+         +-----------+         +---------+
102   |  console  |  <--->  |  termios  |  <--->  |   sci   |
103   |  driver   |         |  module   |         |  driver |
104   +-----------+         +-----------+         +---------+
105                                                    |
106                                                    |
107                                                    v
108                                               +---------+
109                                               |         |
110                                               |  uart   |
111                                               |         |
112                                               +---------+
113*/
114
115
116/*****************************************************************************
117  Section A - Include Files
118*****************************************************************************/
119
120#include <bsp.h>
121#include <rtems/bspIo.h>
122#include <stdio.h>
123#include <rtems/libio.h>
124#include <libchip/serial.h>
125#include <libchip/sersupp.h>
126#include "sci.h"
127//#include "../misc/include/cpu332.h"
128
129
130/*****************************************************************************
131  Section B - Manifest Constants
132*****************************************************************************/
133
134#define SCI_MINOR       0                   // minor device number
135
136
137// IMPORTANT - if the device driver api is opened, it means the sci is being
138// used for direct hardware access, so other users (like termios) get ignored
139
140#define DRIVER_CLOSED   0                   // the device driver api is closed
141#define DRIVER_OPENED   1                   // the device driver api is opened
142
143
144// system clock definitions, i dont have documentation on this...
145
146#if 0 // Not needed, this is provided in mrm332.h
147#define XTAL            32768.0                 // crystal frequency in Hz
148#define NUMB_W          0                               // system clock parameters
149#define NUMB_X          1
150//efine NUMB_Y          0x38                    // for 14.942 Mhz
151#define NUMB_Y          0x3F                        // for 16.777 Mhz
152
153#define SYS_CLOCK       (XTAL * 4.0 * (NUMB_Y+1) * (1 << (2 * NUMB_W + NUMB_X)))
154
155#endif
156
157
158/*****************************************************************************
159  Section C - External Data
160*****************************************************************************/
161
162
163
164
165/*****************************************************************************
166  Section D - External Functions
167*****************************************************************************/
168
169
170
171/*****************************************************************************
172  Section E - Local Functions
173*****************************************************************************/
174
175void SCI_output_char(char c);
176
177rtems_isr SciIsr( rtems_vector_number vector );         // interrupt handler
178
179const rtems_termios_callbacks * SciGetTermiosHandlers( signed32 polled );
180
181rtems_device_driver SciInitialize ();                   // device driver api
182rtems_device_driver SciOpen ();                         // device driver api
183rtems_device_driver SciClose ();                        // device driver api
184rtems_device_driver SciRead ();                         // device driver api
185rtems_device_driver SciWrite ();                        // device driver api
186rtems_device_driver SciControl ();                      // device driver api
187
188signed32 SciInterruptOpen();                            // termios api
189signed32 SciInterruptClose();                           // termios api
190signed32 SciInterruptWrite();                           // termios api
191
192signed32 SciSetAttributes();                            // termios api
193
194signed32 SciPolledOpen();                               // termios api
195signed32 SciPolledClose();                              // termios api
196signed32 SciPolledRead();                               // termios api
197signed32 SciPolledWrite();                              // termios api
198
199static void SciSetBaud(unsigned32 rate);                // hardware routine
200static void SciSetDataBits(unsigned16 bits);            // hardware routine
201static void SciSetParity(unsigned16 parity);            // hardware routine
202
203static void inline SciDisableAllInterrupts( void );     // hardware routine
204static void inline SciDisableTransmitInterrupts( void );// hardware routine
205static void inline SciDisableReceiveInterrupts( void ); // hardware routine
206
207static void inline SciEnableTransmitInterrupts( void ); // hardware routine
208static void inline SciEnableReceiveInterrupts( void );  // hardware routine
209
210static void inline SciDisableReceiver( void );          // hardware routine
211static void inline SciDisableTransmitter( void );       // hardware routine
212
213static void inline SciEnableReceiver( void );           // hardware routine
214static void inline SciEnableTransmitter( void );        // hardware routine
215
216void SciWriteCharWait  ( unsigned8 );                   // hardware routine
217void SciWriteCharNoWait( unsigned8 );                   // hardware routine
218
219unsigned8 inline SciCharAvailable( void );              // hardware routine
220
221unsigned8 inline SciReadCharWait( void );               // hardware routine
222unsigned8 inline SciReadCharNoWait( void );             // hardware routine
223
224void SciSendBreak( void );                              // test routine
225
226static signed8 SciRcvBufGetChar();                      // circular rcv buf
227static void    SciRcvBufPutChar( unsigned8 );           // circular rcv buf
228//atic void    SciRcvBufFlush( void );                  // circular rcv buf
229
230void SciUnitTest();                                     // test routine
231void SciPrintStats();                                   // test routine
232
233
234/*****************************************************************************
235  Section F - Local Variables
236*****************************************************************************/
237
238static struct rtems_termios_tty *SciTermioTty;
239
240
241static unsigned8 SciInited = 0;             // has the driver been inited
242
243static unsigned8 SciOpened;                 // has the driver been opened
244
245static unsigned8 SciMajor;                  // major device number
246
247static unsigned16 SciBaud;                  // current value in baud register
248
249static unsigned32 SciBytesIn  = 0;          // bytes received
250static unsigned32 SciBytesOut = 0;          // bytes transmitted
251
252static unsigned32 SciErrorsParity  = 0;     // error counter
253static unsigned32 SciErrorsNoise   = 0;     // error counter
254static unsigned32 SciErrorsFraming = 0;     // error counter
255static unsigned32 SciErrorsOverrun = 0;     // error counter
256
257#if defined(CONSOLE_SCI)
258
259// this is what rtems printk uses to do polling based output
260
261BSP_output_char_function_type      BSP_output_char = SCI_output_char;
262BSP_polling_getchar_function_type  BSP_poll_char   = NULL;
263
264#endif
265
266
267// cvs id string so you can use the unix ident command on the object
268
269#ifdef ID_STRINGS
270static const char SciIdent[]="$Id$";
271#endif
272
273
274/*****************************************************************************
275  Section G - A circular buffer for rcv chars when the driver interface is used.
276*****************************************************************************/
277
278// it is trivial to wrap your buffer pointers when size is a power of two
279
280#define SCI_RCV_BUF_SIZE        256         // must be a power of 2 !!!
281
282// if someone opens the sci device using the device driver interface,
283// then the receive data interrupt handler will put characters in this buffer
284// instead of sending them up to the termios module for the console
285
286static unsigned8 SciRcvBuffer[SCI_RCV_BUF_SIZE];
287
288static unsigned8 SciRcvBufPutIndex = 0;     // array index to put in next char
289
290static unsigned8 SciRcvBufGetIndex = 0;     // array index to take out next char
291
292static unsigned8 SciRcvBufCount = 0;        // how many bytes are in the buffer
293
294
295
296/*****************************************************************************
297  Section H - RTEMS termios callbacks for the interrupt version of the driver
298*****************************************************************************/
299
300static const rtems_termios_callbacks SciInterruptCallbacks =
301{
302    SciInterruptOpen,                       // first open
303    SciInterruptClose,                      // last close
304    NULL,                                   // polled read (not required)
305    SciInterruptWrite,                      // write
306    SciSetAttributes,                       // set attributes
307    NULL,                                   // stop remote xmit
308    NULL,                                   // start remote xmit
309    TRUE                                    // output uses interrupts
310};
311
312
313/*****************************************************************************
314  Section I - RTEMS termios callbacks for the polled version of the driver
315*****************************************************************************/
316
317static const rtems_termios_callbacks SciPolledCallbacks =
318{
319    SciPolledOpen,                          // first open
320    SciPolledClose,                         // last close
321    SciPolledRead,                          // polled read
322    SciPolledWrite,                         // write
323    SciSetAttributes,                       // set attributes
324    NULL,                                   // stop remote xmit
325    NULL,                                   // start remote xmit
326    FALSE                                   // output uses interrupts
327};
328
329
330/////////////////////////////////////////////////////////////////////////////
331//
332//                              SECTION 0
333//                        MISCELLANEOUS ROUTINES
334//
335/////////////////////////////////////////////////////////////////////////////
336
337
338/****************************************************************************
339* Func:     SCI_output_char
340* Desc:     used by rtems printk function to send a char to the uart
341* Inputs:   the character to transmit
342* Outputs:  none
343* Errors:   none
344* Scope:    public
345****************************************************************************/
346
347void SCI_output_char(char c)
348{
349//  ( minor device number, pointer to the character, length )
350
351    SciPolledWrite( SCI_MINOR, &c, 1);
352
353    return;
354}
355
356
357/****************************************************************************
358* Func:     SciGetTermiosHandlers
359* Desc:     returns a pointer to the table of serial io functions
360*           this is called from console_open with polled set to false
361* Inputs:   flag indicating whether we want polled or interrupt driven io
362* Outputs:  pointer to function table
363* Errors:   none
364* Scope:    public
365****************************************************************************/
366
367const rtems_termios_callbacks * SciGetTermiosHandlers( signed32 polled )
368{
369    if ( polled )
370    {
371        return &SciPolledCallbacks;             // polling based
372    }
373    else
374    {
375        return &SciInterruptCallbacks;          // interrupt driven
376    }
377}
378
379
380/****************************************************************************
381* Func:     SciIsr
382* Desc:     interrupt handler for serial communications interface
383* Inputs:   vector number - unused
384* Outputs:  none
385* Errors:   none
386* Scope:    public API
387****************************************************************************/
388
389rtems_isr SciIsr( rtems_vector_number vector )
390{
391    unsigned8 ch;
392
393
394    if ( (*SCSR) & SCI_ERROR_PARITY  )   SciErrorsParity  ++;
395    if ( (*SCSR) & SCI_ERROR_FRAMING )   SciErrorsFraming ++;
396    if ( (*SCSR) & SCI_ERROR_NOISE   )   SciErrorsNoise   ++;
397    if ( (*SCSR) & SCI_ERROR_OVERRUN )   SciErrorsOverrun ++;
398
399
400    // see if it was a transmit interrupt
401
402    if ( (*SCSR) & SCI_XMTR_AVAILABLE )         // data reg empty, xmt complete
403    {
404        SciDisableTransmitInterrupts();
405
406        // tell termios module that the charcter was sent
407        // he will call us later to transmit more if there are any
408
409        if (rtems_termios_dequeue_characters( SciTermioTty, 1 ))
410        {
411            // there are more bytes to transmit so enable TX interrupt
412
413            SciEnableTransmitInterrupts();
414        }
415    }
416
417    // see if it was a receive interrupt
418    // on the sci uart we just get one character per interrupt
419
420    while (  SciCharAvailable() )               // char in data register?
421    {
422        ch = SciReadCharNoWait();               // get the char from the uart
423
424        // IMPORTANT!!!
425        // either send it to the termios module or keep it locally
426
427        if ( SciOpened == DRIVER_OPENED )       // the driver is open
428        {
429            SciRcvBufPutChar(ch);               // keep it locally
430        }
431        else                                    // put in termios buffer
432        {
433            rtems_termios_enqueue_raw_characters( SciTermioTty, &ch, 1 );
434        }
435
436        *SCSR &= SCI_CLEAR_RX_INT;              // clear the interrupt
437    }
438}
439
440
441/////////////////////////////////////////////////////////////////////////////
442//
443//                              SECTION 1
444//                ROUTINES TO MANIPULATE THE CIRCULAR BUFFER
445//
446/////////////////////////////////////////////////////////////////////////////
447
448
449/****************************************************************************
450* Func:     SciRcvBufGetChar
451* Desc:     read a character from the circular buffer
452*           make sure there is data before you call this!
453* Inputs:   none
454* Outputs:  the character or -1
455* Errors:   none
456* Scope:    private
457****************************************************************************/
458
459static signed8 SciRcvBufGetChar()
460{
461    rtems_interrupt_level level;
462    unsigned8 ch;
463   
464    if ( SciRcvBufCount == 0 )
465    {
466        rtems_fatal_error_occurred(0xDEAD);     // check the count first!
467    }
468
469    rtems_interrupt_disable( level );           // disable interrupts
470
471    ch = SciRcvBuffer[SciRcvBufGetIndex];       // get next byte
472
473    SciRcvBufGetIndex++;                        // bump the index
474
475    SciRcvBufGetIndex &= SCI_RCV_BUF_SIZE - 1;  // and wrap it
476
477    SciRcvBufCount--;                           // decrement counter
478
479    rtems_interrupt_enable( level );            // restore interrupts
480
481    return ch;                                  // return the char
482}
483
484
485
486/****************************************************************************
487* Func:     SciRcvBufPutChar
488* Desc:     put a character into the rcv data circular buffer
489* Inputs:   the character
490* Outputs:  none
491* Errors:   none
492* Scope:    private
493****************************************************************************/
494
495static void SciRcvBufPutChar( unsigned8 ch )
496{
497    rtems_interrupt_level level;
498   
499    if ( SciRcvBufCount == SCI_RCV_BUF_SIZE )   // is there room?
500    {
501        return;                                 // no, throw it away
502    }
503
504    rtems_interrupt_disable( level );           // disable interrupts
505
506    SciRcvBuffer[SciRcvBufPutIndex] = ch;       // put it in the buf
507
508    SciRcvBufPutIndex++;                        // bump the index
509
510    SciRcvBufPutIndex &= SCI_RCV_BUF_SIZE - 1;  // and wrap it
511
512    SciRcvBufCount++;                           // increment counter
513
514    rtems_interrupt_enable( level );            // restore interrupts
515
516    return;                                     // return
517}
518
519
520/****************************************************************************
521* Func:     SciRcvBufFlush
522* Desc:     completely reset and clear the rcv buffer
523* Inputs:   none
524* Outputs:  none
525* Errors:   none
526* Scope:    private
527****************************************************************************/
528
529#if 0                                           // prevents compiler warning
530static void SciRcvBufFlush( void )
531{
532    rtems_interrupt_level level;
533   
534    rtems_interrupt_disable( level );           // disable interrupts
535
536    memset( SciRcvBuffer, 0, sizeof(SciRcvBuffer) );
537
538    SciRcvBufPutIndex = 0;                      // clear
539
540    SciRcvBufGetIndex = 0;                      // clear
541
542    SciRcvBufCount = 0;                         // clear
543
544    rtems_interrupt_enable( level );            // restore interrupts
545
546    return;                                     // return
547}
548#endif
549
550
551/////////////////////////////////////////////////////////////////////////////
552//
553//                              SECTION 2
554//            INTERRUPT BASED ENTRY POINTS FOR THE TERMIOS MODULE
555//
556/////////////////////////////////////////////////////////////////////////////
557
558
559/****************************************************************************
560* Func:     SciInterruptOpen
561* Desc:     open routine for the interrupt based device driver
562*           Default state is 9600 baud, 8 bits, No parity, and 1 stop bit. ??
563*           called from rtems_termios_open which is called from console_open
564* Inputs:   major - device number
565*           minor - device number
566*           args - points to terminal info
567* Outputs:  success/fail
568* Errors:   none
569* Scope:    public API
570****************************************************************************/
571
572signed32 SciInterruptOpen(
573    signed32  major,
574    signed32  minor,
575    void     *arg
576)
577{
578    rtems_libio_open_close_args_t * args = arg;
579    rtems_isr_entry old_vector;
580
581    if ( minor != SCI_MINOR )                   // check minor device num
582    {
583        return -1;
584    }
585
586    if ( !args )                                // must have args
587    {
588        return -1;
589    }
590
591    SciTermioTty = args->iop->data1;            // save address of struct
592
593    SciDisableAllInterrupts();                  // turn off sci interrupts
594
595    // THIS IS ACTUALLY A BAD THING - SETTING LINE PARAMETERS HERE
596    // IT SHOULD BE DONE THROUGH TCSETATTR() WHEN THE CONSOLE IS OPENED!!!
597
598//  SciSetBaud(115200);                         // set the baud rate
599//  SciSetBaud( 57600);                         // set the baud rate
600//  SciSetBaud( 38400);                         // set the baud rate
601//  SciSetBaud( 19200);                         // set the baud rate
602    SciSetBaud(  9600);                         // set the baud rate
603
604    SciSetParity(SCI_PARITY_NONE);              // set parity to none
605
606    SciSetDataBits(SCI_8_DATA_BITS);            // set data bits to 8
607
608
609    // Install our interrupt handler into RTEMS, where does 66 come from?
610
611    rtems_interrupt_catch( SciIsr, 66, &old_vector );
612
613    *QIVR  = 66;
614    *QIVR &= 0xf8;
615    *QILR |= 0x06 & 0x07;
616
617    SciEnableTransmitter();                     // enable the transmitter
618
619    SciEnableReceiver();                        // enable the receiver
620
621    SciEnableReceiveInterrupts();               // enable rcv interrupts
622
623    return RTEMS_SUCCESSFUL;
624}
625
626
627/****************************************************************************
628* Func:     SciInterruptClose
629* Desc:     close routine called by the termios module
630* Inputs:   major - device number
631*           minor - device number
632*           args - unused
633* Outputs:  success/fail
634* Errors:   none
635* Scope:    public - termio entry point
636****************************************************************************/
637
638signed32 SciInterruptClose(
639    signed32  major,
640    signed32  minor,
641    void     *arg
642)
643{
644    SciDisableAllInterrupts();
645
646    return RTEMS_SUCCESSFUL;
647}
648
649
650/****************************************************************************
651* Func:     SciInterruptWrite
652* Desc:     writes data to the uart using transmit interrupts
653* Inputs:   minor - device number
654*           buf - points to the data
655*           len - number of bytes to send
656* Outputs:  success/fail
657* Errors:   none
658* Scope:    public API
659****************************************************************************/
660
661signed32 SciInterruptWrite(
662    signed32    minor,
663    const char *buf,
664    signed32    len
665)
666{
667    // We are using interrupt driven output so termios only sends us
668    // one character at a time. The sci does not have a fifo.
669
670    if ( !len )                                 // no data?
671    {
672        return 0;                               // return error
673    }
674
675    if ( minor != SCI_MINOR )                   // check the minor dev num
676    {
677        return 0;                               // return error
678    }
679
680    if ( SciOpened == DRIVER_OPENED )           // is the driver api open?
681    {
682        return 1;                               // yep, throw this away
683    }
684
685    SciWriteCharNoWait(*buf);                   // try to send a char
686
687    *SCSR &= SCI_CLEAR_TDRE;                    // clear tx data reg empty flag
688
689    SciEnableTransmitInterrupts();              // enable the tx interrupt
690
691    return 1;                                   // return success
692}
693
694
695/****************************************************************************
696* Func:     SciSetAttributes
697* Desc:     setup the uart based on the termios modules requests
698* Inputs:   minor - device number
699*           t - pointer to the termios info struct
700* Outputs:  none
701* Errors:   none
702* Scope:    public API
703****************************************************************************/
704
705signed32 SciSetAttributes(
706    signed32 minor,
707    const struct termios *t
708)
709{
710    unsigned32  baud_requested;
711    unsigned32  sci_rate = 0;
712    unsigned16  sci_parity = 0;
713    unsigned16  sci_databits = 0;
714
715    if ( minor != SCI_MINOR )                   // check the minor dev num
716    {     
717        return -1;                              // return error
718    }
719
720    // if you look closely you will see this is the only thing we use
721    // set the baud rate
722
723    baud_requested = t->c_cflag & CBAUD;        // baud rate
724
725    if (!baud_requested)
726    {
727        baud_requested = B9600;                 // default to 9600 baud
728    }
729   
730    sci_rate = termios_baud_to_number( baud_requested );
731
732    // parity error detection
733
734    if (t->c_cflag & PARENB)                    // enable parity detection?
735    {
736        if (t->c_cflag & PARODD)
737        {
738            sci_parity = SCI_PARITY_ODD;        // select odd parity
739        }
740        else
741        {
742            sci_parity = SCI_PARITY_EVEN;       // select even parity
743        }
744    }
745    else
746    {
747        sci_parity = SCI_PARITY_NONE;           // no parity, most common
748    }
749
750
751    //  set the number of data bits, 8 is most common
752
753    if (t->c_cflag & CSIZE)                     // was it specified?
754    {
755        switch (t->c_cflag & CSIZE)
756        {
757            case CS8:   sci_databits = SCI_8_DATA_BITS;   break;
758            default :   sci_databits = SCI_9_DATA_BITS;   break;
759        }
760    }
761    else
762    {
763        sci_databits = SCI_8_DATA_BITS;         // default to 8 data bits
764    }
765
766
767    //  the number of stop bits; always 1 for SCI
768
769    if (t->c_cflag & CSTOPB)
770    {
771        // do nothing
772    }
773
774
775    // setup the hardware with these serial port parameters
776
777    SciSetBaud(sci_rate);                       // set the baud rate
778
779    SciSetParity(sci_parity);                   // set the parity type
780
781    SciSetDataBits(sci_databits);               // set the data bits
782
783
784    return RTEMS_SUCCESSFUL;
785}
786
787
788/////////////////////////////////////////////////////////////////////////////
789//
790//                              SECTION 3
791//            POLLING BASED ENTRY POINTS FOR THE TERMIOS MODULE
792//
793/////////////////////////////////////////////////////////////////////////////
794
795/****************************************************************************
796* Func:     SciPolledOpen
797* Desc:     open routine for the polled i/o version of the driver
798*           called from rtems_termios_open which is called from console_open
799* Inputs:   major - device number
800*           minor - device number
801*           args - points to terminal info struct
802* Outputs:  success/fail
803* Errors:   none
804* Scope:    public - termios entry point
805****************************************************************************/
806
807signed32 SciPolledOpen(
808    signed32 major,
809    signed32 minor,
810    void    *arg
811)
812{
813    rtems_libio_open_close_args_t * args = arg;
814
815    if ( minor != SCI_MINOR )                   // check minor device num
816    {
817        return -1;
818    }
819
820    if ( !args )                                // must have args
821    {
822        return -1;
823    }
824
825    SciTermioTty = args->iop->data1;            // Store tty pointer
826
827    SciDisableAllInterrupts();                  // don't generate interrupts
828
829    // THIS IS ACTUALLY A BAD THING - SETTING LINE PARAMETERS HERE
830    // IT SHOULD BE DONE THROUGH TCSETATTR() WHEN THE CONSOLE IS OPENED!!!
831
832//  SciSetBaud(115200);                         // set the baud rate
833//  SciSetBaud( 57600);                         // set the baud rate
834//  SciSetBaud( 38400);                         // set the baud rate
835//  SciSetBaud( 19200);                         // set the baud rate
836  SciSetBaud(  9600);                         // set the baud rate
837
838    SciSetParity(SCI_PARITY_NONE);              // set no parity
839
840    SciSetDataBits(SCI_8_DATA_BITS);            // set 8 data bits
841
842    SciEnableTransmitter();                     // enable the xmitter
843
844    SciEnableReceiver();                        // enable the rcvr
845
846    return RTEMS_SUCCESSFUL;
847}
848
849
850/****************************************************************************
851* Func:     SciPolledClose
852* Desc:     close routine for the device driver, same for both
853* Inputs:   major - device number
854*           minor - device number
855*           args - unused
856* Outputs:  success/fail
857* Errors:   none
858* Scope:    public termios API
859****************************************************************************/
860
861signed32 SciPolledClose(
862    signed32  major,
863    signed32  minor,
864    void     *arg
865)
866{
867    SciDisableAllInterrupts();
868
869    return RTEMS_SUCCESSFUL;
870}
871
872
873/****************************************************************************
874* Func:     SciPolledRead
875* Desc:     polling based read routine for the uart
876* Inputs:   minor - device number
877* Outputs:  error or the character read
878* Errors:   none
879* Scope:    public API
880****************************************************************************/
881
882signed32 SciPolledRead(
883    signed32 minor
884)
885{
886    if ( minor != SCI_MINOR )               // check the minor dev num
887    {
888        return -1;                          // return error
889    }
890
891    if ( SciCharAvailable() )               // if a char is available
892    {
893        return SciReadCharNoWait();         // read the rx data register
894    }
895
896    return -1;                              // return error
897}
898
899
900/****************************************************************************
901* Func:     SciPolledWrite
902* Desc:     writes out characters in polled mode, waiting for the uart
903*           check in console_open, but we only seem to use interrupt mode
904* Inputs:   minor - device number
905*           buf - points to the data
906*           len - how many bytes
907* Outputs:  error or number of bytes written
908* Errors:   none
909* Scope:    public termios API
910****************************************************************************/
911
912signed32 SciPolledWrite(
913    signed32      minor,
914    const char   *buf,
915    signed32      len
916)
917{
918    signed32 written = 0;
919
920    if ( minor != SCI_MINOR )                   // check minor device num
921    {
922        return -1;
923    }
924
925    if ( SciOpened == DRIVER_OPENED )           // is the driver api open?
926    {
927        return -1;                              // toss the data
928    }
929
930    // send each byte in the string out the port
931
932    while ( written < len )
933    {
934        SciWriteCharWait(*buf++);               // send a byte
935
936        written++;                              // increment counter
937    }
938
939    return written;                             // return count
940}
941
942
943/////////////////////////////////////////////////////////////////////////////
944//
945//                              SECTION 4
946//                 DEVICE DRIVER PUBLIC API ENTRY POINTS
947//
948/////////////////////////////////////////////////////////////////////////////
949
950
951/****************************************************************************
952* Func:     SciInit
953* Desc:     Initialize the lasers device driver and hardware
954* Inputs:   major - the major device number which is assigned by rtems
955*           minor - the minor device number which is undefined at this point
956*           arg - ?????
957* Outputs:  RTEMS_SUCCESSFUL
958* Errors:   None.
959* Scope:    public API
960****************************************************************************/
961
962rtems_device_driver SciInitialize (
963    rtems_device_major_number major,
964    rtems_device_minor_number minor,
965    void * arg
966)
967{
968//     rtems_status_code status;
969
970//printk("%s\r\n", __FUNCTION__);
971
972
973    // register the SCI device name for termios console i/o
974    // this is done over in console.c which doesn't seem exactly right
975    // but there were problems doing it here...
976
977//  status = rtems_io_register_name( "/dev/sci", major, 0 );
978
979//  if (status != RTEMS_SUCCESSFUL)
980//      rtems_fatal_error_occurred(status);
981
982
983    SciMajor = major;                           // save the rtems major number
984
985    SciOpened = DRIVER_CLOSED;                  // initial state is closed
986
987
988    // if you have an interrupt handler, install it here
989
990
991    SciInited = 1;                              // set the inited flag
992
993    return RTEMS_SUCCESSFUL;
994}
995
996
997/****************************************************************************
998* Func:     SciOpen
999* Desc:     device driver open routine
1000*           you must open a device before you can anything else
1001*           only one process can have the device opened at a time
1002*           you could look at the task id to restrict access if you want
1003* Inputs:   major - the major device number assigned by rtems
1004*           minor - the minor device number assigned by us
1005*           arg - ?????
1006* Outputs:  see below
1007* Errors:   none
1008* Scope:    public API
1009****************************************************************************/
1010
1011rtems_device_driver SciOpen (
1012    rtems_device_major_number major,
1013    rtems_device_minor_number minor,
1014    void * arg
1015)
1016{
1017//printk("%s major=%d minor=%d\r\n", __FUNCTION__,major,minor);
1018
1019    if (SciInited == 0)                         // must be initialized first!
1020    {
1021        return RTEMS_NOT_CONFIGURED;
1022    }
1023
1024    if (minor != SCI_MINOR)
1025    {
1026        return RTEMS_INVALID_NAME;              // verify minor number
1027    }
1028
1029    if (SciOpened == DRIVER_OPENED)
1030    {
1031        return RTEMS_RESOURCE_IN_USE;           // already opened!
1032    }
1033
1034    SciOpened = DRIVER_OPENED;                  // set the opened flag
1035
1036    return RTEMS_SUCCESSFUL;
1037}
1038
1039
1040/****************************************************************************
1041* Func:     SciClose
1042* Desc:     device driver close routine
1043*           the device must be opened before you can close it
1044*           the device must be closed before someone (else) can open it
1045* Inputs:   major - the major device number
1046*           minor - the minor device number
1047*           arg - ?????
1048* Outputs:  see below
1049* Errors:   none
1050* Scope:    public API
1051****************************************************************************/
1052
1053rtems_device_driver SciClose (
1054    rtems_device_major_number major,
1055    rtems_device_minor_number minor,
1056    void * arg
1057)
1058{
1059//printk("%s major=%d minor=%d\r\n", __FUNCTION__,major,minor);
1060
1061    if (minor != SCI_MINOR)
1062    {
1063        return RTEMS_INVALID_NAME;              // check the minor number
1064    }
1065
1066    if (SciOpened != DRIVER_OPENED)
1067    {
1068        return RTEMS_INCORRECT_STATE;           // must be opened first
1069    }
1070
1071    SciOpened = DRIVER_CLOSED;                  // set the flag
1072
1073    return RTEMS_SUCCESSFUL;
1074}
1075
1076
1077/****************************************************************************
1078* Func:     SciRead
1079* Desc:     device driver read routine
1080*           this function is not meaningful for the laser devices
1081* Inputs:   major - the major device number
1082*           minor - the minor device number
1083*           arg - read/write arguments
1084* Outputs:  see below
1085* Errors:   none
1086* Scope:    public API
1087****************************************************************************/
1088
1089rtems_device_driver SciRead (
1090    rtems_device_major_number major,
1091    rtems_device_minor_number minor,
1092    void *arg
1093)
1094{
1095    rtems_libio_rw_args_t *rw_args;             // ptr to argument struct
1096    unsigned8 *buffer;
1097    unsigned16 length;
1098 
1099    rw_args = (rtems_libio_rw_args_t *) arg;    // arguments to read()
1100
1101
1102    if (minor != SCI_MINOR)
1103    {
1104        return RTEMS_INVALID_NAME;              // check the minor number
1105    }
1106
1107    if (SciOpened == DRIVER_CLOSED)
1108    {
1109        return RTEMS_INCORRECT_STATE;           // must be opened first
1110    }
1111
1112    buffer = rw_args->buffer;                   // points to user's buffer
1113
1114    length = rw_args->count;                    // how many bytes they want
1115
1116//  *buffer = SciReadCharWait();                // wait for a character
1117
1118    // if there isn't a character available, wait until one shows up
1119    // or the timeout period expires, which ever happens first
1120
1121    if ( SciRcvBufCount == 0 )                  // no chars
1122    {
1123        // wait for someone to wake me up...
1124        //rtems_task_wake_after(SciReadTimeout);
1125    }
1126
1127    if ( SciRcvBufCount )                       // any characters locally?
1128    {
1129        *buffer = SciRcvBufGetChar();           // get the character
1130
1131        rw_args->bytes_moved = 1;               // how many we actually read
1132    }
1133
1134    return RTEMS_SUCCESSFUL;
1135}
1136
1137
1138/****************************************************************************
1139* Func:     SciWrite
1140* Desc:     device driver write routine
1141*           this function is not meaningful for the laser devices
1142* Inputs:   major - the major device number
1143*           minor - the minor device number
1144*           arg - read/write arguments
1145* Outputs:  see below
1146* Errors:   non3
1147* Scope:    public API
1148****************************************************************************/
1149
1150rtems_device_driver SciWrite (
1151    rtems_device_major_number major,
1152    rtems_device_minor_number minor,
1153    void * arg
1154)
1155{
1156    rtems_libio_rw_args_t *rw_args;             // ptr to argument struct
1157    unsigned8 *buffer;
1158    unsigned16 length;
1159 
1160    rw_args = (rtems_libio_rw_args_t *) arg;
1161
1162    if (minor != SCI_MINOR)
1163    {
1164        return RTEMS_INVALID_NAME;              // check the minor number
1165    }
1166
1167    if (SciOpened == DRIVER_CLOSED)
1168    {
1169        return RTEMS_INCORRECT_STATE;           // must be opened first
1170    }
1171
1172    buffer = (unsigned8*)rw_args->buffer;       // points to data
1173
1174    length = rw_args->count;                    // how many bytes
1175
1176    while (length--)
1177    {
1178        SciWriteCharWait(*buffer++);            // send the bytes out
1179    }
1180
1181    rw_args->bytes_moved = rw_args->count;      // how many we wrote
1182
1183    return RTEMS_SUCCESSFUL;
1184}
1185
1186
1187/****************************************************************************
1188* Func:     SciControl
1189* Desc:     device driver control routine
1190*           see below for an example of how to use the ioctl interface
1191* Inputs:   major - the major device number
1192*           minor - the minor device number
1193*           arg - io control args
1194* Outputs:  see below
1195* Errors:   none
1196* Scope:    public API
1197****************************************************************************/
1198
1199rtems_device_driver SciControl (
1200    rtems_device_major_number major,
1201    rtems_device_minor_number minor,
1202    void * arg
1203)
1204{
1205    rtems_libio_ioctl_args_t *args = arg;       // rtems arg struct
1206    unsigned16 command;                         // the cmd to execute
1207    unsigned16 unused;                          // maybe later
1208    unsigned16 *ptr;                            // ptr to user data
1209 
1210//printk("%s major=%d minor=%d\r\n", __FUNCTION__,major,minor);
1211
1212    // do some sanity checking
1213
1214    if (minor != SCI_MINOR)
1215    {
1216        return RTEMS_INVALID_NAME;              // check the minor number
1217    }
1218
1219    if (SciOpened == DRIVER_CLOSED)
1220    {
1221        return RTEMS_INCORRECT_STATE;           // must be open first
1222    }
1223
1224    if (args == 0)
1225    {
1226        return RTEMS_INVALID_ADDRESS;           // must have args
1227    }
1228
1229    args->ioctl_return = -1;                    // assume an error
1230
1231    command = args->command;                    // get the command
1232    ptr     = args->buffer;                     // this is an address
1233    unused  = *ptr;                             // brightness
1234
1235    if (command == SCI_SEND_BREAK)              // process the command
1236    {
1237        SciSendBreak();                         // send break char
1238    }
1239
1240    args->ioctl_return = 0;                     // return status
1241
1242    return RTEMS_SUCCESSFUL;
1243}
1244
1245
1246/////////////////////////////////////////////////////////////////////////////
1247//
1248//                              SECTION 5
1249//                       HARDWARE LEVEL ROUTINES
1250//
1251/////////////////////////////////////////////////////////////////////////////
1252
1253
1254/****************************************************************************
1255* Func:     SciSetBaud
1256* Desc:     setup the uart based on the termios modules requests
1257* Inputs:   baud rate
1258* Outputs:  none
1259* Errors:   none
1260* Scope:    private
1261****************************************************************************/
1262
1263static void SciSetBaud(unsigned32 rate)
1264{
1265    unsigned16 value;
1266    unsigned16 save_sccr1;
1267
1268// when you open the console you need to set the termio struct baud rate
1269// it has a default value of 9600, when someone calls tcsetattr it reverts!
1270
1271
1272    SciBaud = rate;                             // save the rate
1273
1274    // calculate the register value as a float and convert to an int
1275    // set baud rate - you must define the system clock constant
1276    // see efi332.h for an example
1277
1278    value = ( (unsigned16) ( SYS_CLOCK / rate / 32.0 + 0.5 ) & 0x1fff );
1279
1280    save_sccr1 = *SCCR1;                        // save register
1281
1282    // also turns off the xmtr and rcvr
1283
1284    *SCCR1 &= SCI_DISABLE_INT_ALL;              // disable interrupts
1285
1286    *SCCR0 = value;                             // write the register
1287
1288    *SCCR1 = save_sccr1;                        // restore register
1289
1290    return;
1291}
1292
1293
1294/****************************************************************************
1295* Func:     SciSetParity
1296* Desc:     setup the uart based on the termios modules requests
1297* Inputs:   parity
1298* Outputs:  none
1299* Errors:   none
1300* Scope:    private
1301****************************************************************************/
1302
1303static void SciSetParity(unsigned16 parity)
1304{
1305    unsigned16 value;
1306
1307    value = *SCCR1;                             // get the register
1308
1309    if (parity == SCI_PARITY_ODD)
1310    {
1311        value |= SCI_PARITY_ENABLE;             // parity enabled
1312        value |= SCI_PARITY_ODD;                // parity odd
1313    }
1314
1315    else if (parity == SCI_PARITY_EVEN)
1316    {
1317        value |= SCI_PARITY_ENABLE;             // parity enabled
1318        value &= ~SCI_PARITY_ODD;               // parity even
1319    }
1320
1321    else if (parity == SCI_PARITY_NONE)
1322    {
1323        value &= ~SCI_PARITY_ENABLE;            // disabled, most common
1324    }
1325
1326    /* else no changes */
1327
1328    *SCCR1 = value;                             // write the register
1329
1330    return;
1331}
1332
1333
1334/****************************************************************************
1335* Func:     SciSetDataBits
1336* Desc:     setup the uart based on the termios modules requests
1337* Inputs:   data bits
1338* Outputs:  none
1339* Errors:   none
1340* Scope:    private
1341****************************************************************************/
1342
1343static void SciSetDataBits(unsigned16 bits)
1344{
1345    unsigned16 value;
1346
1347    value = *SCCR1;                             // get the register
1348
1349    /* note - the parity setting affects the number of data bits */
1350
1351    if (bits == SCI_9_DATA_BITS)
1352    {
1353        value |= SCI_9_DATA_BITS;               // 9 data bits
1354    }
1355
1356    else if (bits == SCI_8_DATA_BITS)
1357    {
1358        value &= SCI_8_DATA_BITS;               // 8 data bits
1359    }
1360
1361    /* else no changes */
1362
1363    *SCCR1 = value;                             // write the register
1364
1365    return;
1366}
1367
1368
1369/****************************************************************************
1370* Func:     SciDisableAllInterrupts
1371* Func:     SciEnableTransmitInterrupts
1372* Func:     SciEnableReceiveInterrupts
1373* Desc:     handles generation of interrupts by the sci module
1374* Inputs:   none
1375* Outputs:  none
1376* Errors:   none
1377* Scope:    private
1378****************************************************************************/
1379
1380static void inline SciDisableAllInterrupts( void )
1381{
1382    // this also turns off the xmtr and rcvr
1383
1384    *SCCR1 &= SCI_DISABLE_INT_ALL;
1385}
1386
1387static void inline SciEnableReceiveInterrupts( void )
1388{
1389    *SCCR1 |= SCI_ENABLE_INT_RX;
1390}
1391
1392static void inline SciDisableReceiveInterrupts( void )
1393{
1394    *SCCR1 &= SCI_DISABLE_INT_RX;
1395}
1396
1397static void inline SciEnableTransmitInterrupts( void )
1398{
1399    *SCCR1 |= SCI_ENABLE_INT_TX;
1400}
1401
1402static void inline SciDisableTransmitInterrupts( void )
1403{
1404    *SCCR1 &= SCI_DISABLE_INT_TX;
1405}
1406
1407
1408/****************************************************************************
1409* Func:     SciEnableTransmitter, SciDisableTransmitter
1410* Func:     SciEnableReceiver,    SciDisableReceiver
1411* Desc:     turns the transmitter and receiver on and off
1412* Inputs:   none
1413* Outputs:  none
1414* Errors:   none
1415* Scope:    private
1416****************************************************************************/
1417
1418static void inline SciEnableTransmitter( void )
1419{
1420    *SCCR1 |= SCI_ENABLE_XMTR;
1421}
1422
1423static void inline SciDisableTransmitter( void )
1424{
1425    *SCCR1 &= SCI_DISABLE_XMTR;
1426}
1427
1428static void inline SciEnableReceiver( void )
1429{
1430    *SCCR1 |= SCI_ENABLE_RCVR;
1431}
1432
1433static void inline SciDisableReceiver( void )
1434{
1435    *SCCR1 &= SCI_DISABLE_RCVR;
1436}
1437
1438
1439/****************************************************************************
1440* Func:     SciWriteCharWait
1441* Desc:     wait for room in the fifo and then put a char in
1442* Inputs:   a byte to send
1443* Outputs:  none
1444* Errors:   none
1445* Scope:    public
1446****************************************************************************/
1447
1448void SciWriteCharWait(unsigned8 c)
1449{
1450    // poll the fifo, waiting for room for another character
1451
1452    while ( ( *SCSR & SCI_XMTR_AVAILABLE ) == 0 )
1453    {
1454        /* Either we are writing to the fifo faster than
1455         * the uart can clock bytes out onto the cable,
1456         * or we are in flow control (actually no, we
1457         * are ignoring flow control from the other end).
1458         * In the first case, higher baud rates will help.
1459         */
1460    }
1461
1462    *SCDR = c;                                  // send the charcter
1463
1464    SciBytesOut++;                              // increment the counter
1465
1466    return;
1467}
1468
1469
1470/****************************************************************************
1471* Func:     SciWriteCharNoWait
1472* Desc:     if no room in the fifo throw the char on the floor
1473* Inputs:   a byte to send
1474* Outputs:  none
1475* Errors:   none
1476* Scope:    public
1477****************************************************************************/
1478
1479void SciWriteCharNoWait(unsigned8 c)
1480{
1481    if ( ( *SCSR & SCI_XMTR_AVAILABLE ) == 0 )
1482    {
1483        return;                                 // no room, throw it away
1484    }
1485
1486    *SCDR = c;                                  // put the char in the fifo
1487
1488    SciBytesOut++;                              // increment the counter
1489
1490    return;
1491}
1492
1493
1494/****************************************************************************
1495* Func:     SciReadCharWait
1496* Desc:     read a character, waiting for one to show up, if need be
1497* Inputs:   none
1498* Outputs:  a character
1499* Errors:   none
1500* Scope:    public
1501****************************************************************************/
1502
1503unsigned8 inline SciReadCharWait( void )
1504{
1505    unsigned8 ch;
1506
1507    while ( SciCharAvailable() == 0 )           // anything there?
1508    {
1509        // do nothing
1510    }
1511
1512    // if you have rcv ints enabled, then the isr will probably
1513    // get the character before you will unless you turn off ints
1514    // ie polling and ints don't mix that well
1515
1516    ch = *SCDR;                                 // get the charcter
1517
1518    SciBytesIn++;                               // increment the counter
1519
1520    return ch;                                  // return the char
1521}
1522
1523
1524/****************************************************************************
1525* Func:     SciReadCharNoWait
1526* Desc:     try to get a char but dont wait for one
1527* Inputs:   none
1528* Outputs:  a character or -1 if none
1529* Errors:   none
1530* Scope:    public
1531****************************************************************************/
1532
1533unsigned8 inline SciReadCharNoWait( void )
1534{
1535    unsigned8 ch;
1536
1537    if ( SciCharAvailable() == 0 )              // anything there?
1538        return -1;
1539
1540    ch = *SCDR;                                 // get the character
1541
1542    SciBytesIn++;                               // increment the count
1543
1544    return ch;                                  // return the char
1545}
1546
1547
1548
1549/****************************************************************************
1550* Func:     SciCharAvailable
1551* Desc:     is there a receive character in the data register
1552* Inputs:   none
1553* Outputs:  false if no char available, else true
1554* Errors:   none
1555* Scope:    public
1556****************************************************************************/
1557
1558unsigned8 inline SciCharAvailable( void )
1559{
1560    return ( *SCSR & SCI_RCVR_READY );          // char in data register?
1561}
1562
1563
1564/****************************************************************************
1565* Func:     SciSendBreak
1566* Desc:     send 1 or tow breaks (all zero bits)
1567* Inputs:   none
1568* Outputs:  none
1569* Errors:   none
1570* Scope:    public
1571****************************************************************************/
1572
1573void SciSendBreak( void )
1574{
1575    // From the Motorola QSM reference manual -
1576
1577    // "if SBK is toggled by writing it first to a one and then immediately
1578    // to a zero (in less than one serial frame interval), the transmitter
1579    // sends only one or two break frames before reverting to mark (idle)
1580    // or before commencing to send more data"
1581
1582    *SCCR1 |=  SCI_SEND_BREAK;                  // set the bit
1583
1584    *SCCR1 &= ~SCI_SEND_BREAK;                  // clear the bit
1585
1586    return;
1587}
1588
1589
1590/////////////////////////////////////////////////////////////////////////////
1591//
1592//                             SECTION 6
1593//                             TEST CODE
1594//
1595/////////////////////////////////////////////////////////////////////////////
1596
1597
1598/****************************************************************************
1599* Func:     SciUnitTest
1600* Desc:     test the device driver
1601* Inputs:   nothing
1602* Outputs:  nothing
1603* Scope:    public
1604****************************************************************************/
1605
1606#if 0
1607#define O_RDWR LIBIO_FLAGS_READ_WRITE           // dont like this but...
1608
1609void SciUnitTest()
1610{
1611    unsigned8 byte;                             // a character
1612    unsigned16 fd;                              // file descriptor for device
1613    unsigned16 result;                          // result of ioctl
1614
1615
1616    fd = open("/dev/sci",O_RDWR);               // open the device
1617
1618printk("SCI open fd=%d\r\n",fd);
1619
1620
1621    result = write(fd, "abcd\r\n", 6);          // send a string
1622
1623printk("SCI write result=%d\r\n",result);
1624
1625
1626    result = read(fd, &byte, 1);                // read a byte
1627
1628printk("SCI read result=%d,byte=%x\r\n",result,byte);
1629
1630    return;
1631}
1632#endif
1633
1634
1635/****************************************************************************
1636* Func:     SciPrintStats
1637* Desc:     print out some driver information
1638* Inputs:   nothing
1639* Outputs:  nothing
1640* Scope:    public
1641****************************************************************************/
1642
1643void SciPrintStats ( void )
1644{
1645    printk("\r\n");
1646
1647    printk( "SYS_CLOCK is %2.6f Mhz\r\n\n", SYS_CLOCK / 1000000.0 );
1648
1649    printk( "Current baud rate is %d bps or %d cps\r\n\n", SciBaud, SciBaud / 10 );
1650
1651    printk( "SCI Uart chars in       %8d\r\n", SciBytesIn       );
1652    printk( "SCI Uart chars out      %8d\r\n", SciBytesOut      );
1653    printk( "SCI Uart framing errors %8d\r\n", SciErrorsFraming );
1654    printk( "SCI Uart parity  errors %8d\r\n", SciErrorsParity  );
1655    printk( "SCI Uart overrun errors %8d\r\n", SciErrorsOverrun );
1656    printk( "SCI Uart noise   errors %8d\r\n", SciErrorsNoise   );
1657
1658    return;
1659}
1660
1661
1662
Note: See TracBrowser for help on using the repository browser.