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

4.9
Last change on this file since c3f92ef was c3f92ef, checked in by Joel Sherrill <joel.sherrill@…>, on Mar 22, 2011 at 2:14:34 PM

2011-03-22 Joel Sherrill <joel.sherrilL@…>

PR 1772/bsps

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