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

4.11
Last change on this file since 36ad3c7 was 36ad3c7, checked in by Joel Sherrill <joel.sherrill@…>, on Mar 21, 2015 at 7:42:55 PM

mrm332/console/sci.c: Make routines static

  • 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_cflag & CBAUD;        /* 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.