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

4.104.114.84.95
Last change on this file since 6128a4a was 6128a4a, checked in by Ralf Corsepius <ralf.corsepius@…>, on 04/21/04 at 10:43:04

Remove stray white spaces.

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