source: rtems/c/src/lib/libbsp/m68k/mrm332/console/sci.c @ 1c6926c1

5
Last change on this file since 1c6926c1 was 1c6926c1, checked in by Kevin Kirspel <kevin-kirspel@…>, on 03/21/17 at 19:39:48

termios: Synchronize with latest FreeBSD headers

Adding modified FreeBSD headers to synchronize RTEMS termios with
FreeBSD. Modify termios to support dedicated input and output baud for
termios structure. Updated BSPs to use dedicated input and output baud
in termios structure. Updated tools to use dedicated input and output
baud in termios structure. Updated termios testsuites to use dedicated
input and output baud in termios structure.

Close #2897.

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