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

4.115
Last change on this file since 89aa1ec8 was 89aa1ec8, checked in by James Fitzsimons <james.fitzsimons@…>, on Mar 24, 2014 at 9:32:10 AM

m68k/mrm332: changes required to get the mrm332 bsp working again.

Changed console driver to use interrupts instead of polling.
Change to avoid overwriting CPU32Bug interrupt vector when setting up the Sci interrupt handler.
Fixed type for boolean flag in bsp.h.
Changed mrm332.h to use 25Mhz clock.
Fixes to mrm332.cfg to use correct mcpu32 value for RTEMS_CPU_MODEL instead of m68332 which is no longer supported.
Added -mcpu=cpu32 to compiler options.
Removed broken ROM linker script and replaced broken RAM linker script with working ROM linker script.
Removed no longer required file except_vect_332_ROM.S.
Enabled 0xbeefbeef magic string in start.S to allow MRM version of CPU32Bug to auto run RTEMS.
Removed old code from start.S
Changed compiler optimization flag to optimize for size.

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