summaryrefslogtreecommitdiffstats
path: root/c/src/lib/libbsp/m68k/mrm332/console/sci.c
diff options
context:
space:
mode:
Diffstat (limited to 'c/src/lib/libbsp/m68k/mrm332/console/sci.c')
-rw-r--r--c/src/lib/libbsp/m68k/mrm332/console/sci.c1586
1 files changed, 0 insertions, 1586 deletions
diff --git a/c/src/lib/libbsp/m68k/mrm332/console/sci.c b/c/src/lib/libbsp/m68k/mrm332/console/sci.c
deleted file mode 100644
index c6b4933f13..0000000000
--- a/c/src/lib/libbsp/m68k/mrm332/console/sci.c
+++ /dev/null
@@ -1,1586 +0,0 @@
-/*****************************************************************************
-* File: sci.c
-*
-* Desc: This file contains the console IO routines for the SCI port.
-* There are two interfaces in this module. One is for the rtems
-* termios/console code and the other is a device driver interface.
-* This module works together with the termio module which is
-* sometimes referred to as the "line disciplines" which implements
-* terminal i/o processing like tabs, backspaces, and newlines.
-* The rtems printf uses interrupt io and the rtems printk routine
-* uses polled io which is better for debugging.
-*
-* Index: Documentation
-* Section A - Include Files
-* Section B - Manifest Constants
-* Section C - External Data
-* Section D - External Functions
-* Section E - Local Functions
-* Section F - Local Variables
-* Section G - A circular data buffer for rcv chars
-* Section H - RTEMS termios callbacks for the interrupt api
-* Section I - RTEMS termios callbacks for the polled api
-
-* Section 0 - Miscellaneous routines
-* Section 1 - Routines to manipulate the circular buffer
-* Section 2 - Interrupt based entry points for the termios module
-* Section 3 - Polling based entry points for the termios module
-* Section 4 - Device driver public api entry points
-* Section 5 - Hardware level routines
-* Section 6 - Testing and debugging code
-*
-* Refer: Motorola QSM Reference Manual - Chapter 5 - SCI sub-module
-*
-* Note: See bsp.h,confdefs.h,system.h for installing drivers into RTEMS.
-*
-*****************************************************************************/
-
-/*****************************************************************************
- Overview of serial port console terminal input/output
-*****************************************************************************/
-
-/*
- +-----------+ +---------+
- | app | | app |
- +-----------+ +---------+
- | |
- | (printf,scanf,etc.) |
- v |
- +-----------+ |
- | libc | |
- +-----------+ |
- | |
- | |
- | (open,close,read,write,ioctl) |
- ======|==========================================|========================
- | /dev/console | /dev/sci
- | (stdin,stdout,stderr) |
- ======|==========================================|========================
- | |
- | |
- v v
- +-----------+ +-----------+ +---------+
- | console | <---> | termios | <---> | sci |
- | driver | | module | | driver |
- +-----------+ +-----------+ +---------+
- |
- |
- v
- +---------+
- | |
- | uart |
- | |
- +---------+
-*/
-
-
-/*****************************************************************************
- Section A - Include Files
-*****************************************************************************/
-
-#include <rtems.h>
-#include <bsp.h>
-#include <rtems/bspIo.h>
-#include <stdio.h>
-#include <rtems/libio.h>
-#include <libchip/serial.h>
-#include <libchip/sersupp.h>
-#include "sci.h"
-#include <rtems/m68k/qsm.h>
-#include <inttypes.h>
-/*#include "../misc/include/cpu332.h" */
-
-/*****************************************************************************
- Section B - Manifest Constants
-*****************************************************************************/
-
-#define SCI_MINOR 0 /* minor device number */
-
-/* IMPORTANT - if the device driver api is opened, it means the sci is being
- * used for direct hardware access, so other users (like termios) get ignored
- */
-#define DRIVER_CLOSED 0 /* the device driver api is closed */
-#define DRIVER_OPENED 1 /* the device driver api is opened */
-
-/* system clock definitions, i dont have documentation on this... */
-
-#if 0 /* Not needed, this is provided in mrm332.h */
-#define XTAL 32768.0 /* crystal frequency in Hz */
-#define NUMB_W 0 /* system clock parameters */
-#define NUMB_X 1
-#define NUMB_Y 0x38 /* for 14.942 Mhz */
-#define NUMB_Y 0x3F /* for 16.777 Mhz */
-
-#define SYS_CLOCK (XTAL * 4.0 * (NUMB_Y+1) * (1 << (2 * NUMB_W + NUMB_X)))
-
-#endif
-
-
-/*****************************************************************************
- Section C - External Data
-*****************************************************************************/
-
-
-
-/*****************************************************************************
- Section D - External Functions
-*****************************************************************************/
-
-
-
-/*****************************************************************************
- Section E - Local Functions
-*****************************************************************************/
-
-void SCI_output_char(char c);
-
-/*rtems_isr SciIsr( rtems_vector_number vector ); interrupt handler */
-
-const rtems_termios_callbacks * SciGetTermiosHandlers( int32_t polled );
-
-rtems_device_driver SciInitialize( /* device driver api */
- rtems_device_major_number, rtems_device_minor_number, void *);
-rtems_device_driver SciOpen( /* device driver api */
- rtems_device_major_number, rtems_device_minor_number, void *);
-rtems_device_driver SciClose( /* device driver api */
- rtems_device_major_number, rtems_device_minor_number, void *);
-rtems_device_driver SciRead( /* device driver api */
- rtems_device_major_number, rtems_device_minor_number, void *);
-rtems_device_driver SciWrite( /* device driver api */
- rtems_device_major_number, rtems_device_minor_number, void *);
-rtems_device_driver SciControl( /* device driver api */
- rtems_device_major_number, rtems_device_minor_number, void *);
-rtems_device_driver SciRead (
- rtems_device_major_number, rtems_device_minor_number, void *);
-
-rtems_isr SciIsr( rtems_vector_number vector );
-
-int SciInterruptOpen(int, int, void *); /* termios api */
-int SciInterruptClose(int, int, void *); /* termios api */
-ssize_t SciInterruptWrite(int, const char *, size_t); /* termios api */
-
-int SciSetAttributes(int, const struct termios*); /* termios api */
-int SciPolledOpen(int, int, void *); /* termios api */
-int SciPolledClose(int, int, void *); /* termios api */
-int SciPolledRead(int); /* termios api */
-ssize_t SciPolledWrite(int, const char *, size_t); /* termios api */
-
-static void SciSetBaud(uint32_t rate); /* hardware routine */
-static void SciSetDataBits(uint16_t bits); /* hardware routine */
-static void SciSetParity(uint16_t parity); /* hardware routine */
-
-static void inline SciDisableAllInterrupts( void ); /* hardware routine */
-static void inline SciDisableTransmitInterrupts( void );/* hardware routine */
-static void inline SciDisableReceiveInterrupts( void ); /* hardware routine */
-
-static void inline SciEnableTransmitInterrupts( void ); /* hardware routine */
-static void inline SciEnableReceiveInterrupts( void ); /* hardware routine */
-
-static void inline SciDisableReceiver( void ); /* hardware routine */
-static void inline SciDisableTransmitter( void ); /* hardware routine */
-
-static void inline SciEnableReceiver( void ); /* hardware routine */
-static void inline SciEnableTransmitter( void ); /* hardware routine */
-
-void SciWriteCharWait ( uint8_t ); /* hardware routine */
-void SciWriteCharNoWait( uint8_t ); /* hardware routine */
-
-uint8_t inline SciCharAvailable( void ); /* hardware routine */
-
-static uint8_t inline SciReadCharWait( void ); /* hardware routine */
-static uint8_t inline SciReadCharNoWait( void ); /* hardware routine */
-
-void SciSendBreak( void ); /* test routine */
-
-static int8_t SciRcvBufGetChar(void); /* circular rcv buf */
-static void SciRcvBufPutChar( uint8_t); /* circular rcv buf */
-#if 0
-static void SciRcvBufFlush( void ); /* unused routine */
-#endif
-
-void SciUnitTest(void); /* test routine */
-void SciPrintStats(void); /* test routine */
-
-
-/*****************************************************************************
- Section F - Local Variables
-*****************************************************************************/
-
-static struct rtems_termios_tty *SciTermioTty;
-
-static uint8_t SciInited = 0; /* has the driver been inited */
-
-static uint8_t SciOpened; /* has the driver been opened */
-
-static uint8_t SciMajor; /* major device number */
-
-static uint16_t SciBaud; /* current value in baud register */
-
-static uint32_t SciBytesIn = 0; /* bytes received */
-static uint32_t SciBytesOut = 0; /* bytes transmitted */
-
-static uint32_t SciErrorsParity = 0; /* error counter */
-static uint32_t SciErrorsNoise = 0; /* error counter */
-static uint32_t SciErrorsFraming = 0; /* error counter */
-static uint32_t SciErrorsOverrun = 0; /* error counter */
-
-#if defined(CONSOLE_SCI)
-
-/* this is what rtems printk uses to do polling based output */
-
-BSP_output_char_function_type BSP_output_char = SCI_output_char;
-BSP_polling_getchar_function_type BSP_poll_char = NULL;
-
-#endif
-
-/*****************************************************************************
- Section G - A circular buffer for rcv chars when the driver interface is used.
-*****************************************************************************/
-
-/* it is trivial to wrap your buffer pointers when size is a power of two */
-
-#define SCI_RCV_BUF_SIZE 256 /* must be a power of 2 !!! */
-
-/* if someone opens the sci device using the device driver interface,
- * then the receive data interrupt handler will put characters in this buffer
- * instead of sending them up to the termios module for the console
- */
-static uint8_t SciRcvBuffer[SCI_RCV_BUF_SIZE];
-
-static uint8_t SciRcvBufPutIndex = 0; /* array index to put in next char */
-
-static uint8_t SciRcvBufGetIndex = 0; /* array index to take out next char */
-
-static uint16_t SciRcvBufCount = 0; /* how many bytes are in the buffer */
-
-
-
-/*****************************************************************************
- Section H - RTEMS termios callbacks for the interrupt version of the driver
-*****************************************************************************/
-
-static const rtems_termios_callbacks SciInterruptCallbacks =
-{
- SciInterruptOpen, /* first open */
- SciInterruptClose, /* last close */
- NULL, /* polled read (not required) */
- SciInterruptWrite, /* write */
- SciSetAttributes, /* set attributes */
- NULL, /* stop remote xmit */
- NULL, /* start remote xmit */
- TRUE /* output uses interrupts */
-};
-
-/*****************************************************************************
- Section I - RTEMS termios callbacks for the polled version of the driver
-*****************************************************************************/
-
-static const rtems_termios_callbacks SciPolledCallbacks =
-{
- SciPolledOpen, /* first open */
- SciPolledClose, /* last close */
- SciPolledRead, /* polled read */
- SciPolledWrite, /* write */
- SciSetAttributes, /* set attributes */
- NULL, /* stop remote xmit */
- NULL, /* start remote xmit */
- FALSE /* output uses interrupts */
-};
-
-
-/*
- * SECTION 0
- * MISCELLANEOUS ROUTINES
- */
-
-/****************************************************************************
- * Func: SCI_output_char
- * Desc: used by rtems printk function to send a char to the uart
- * Inputs: the character to transmit
- * Outputs: none
- * Errors: none
- * Scope: public
- ****************************************************************************/
-
-void SCI_output_char(char c)
-{
-/* ( minor device number, pointer to the character, length ) */
-
- SciPolledWrite( SCI_MINOR, &c, 1);
-
- return;
-}
-
-
-/****************************************************************************
-* Func: SciGetTermiosHandlers
-* Desc: returns a pointer to the table of serial io functions
-* this is called from console_open with polled set to false
-* Inputs: flag indicating whether we want polled or interrupt driven io
-* Outputs: pointer to function table
-* Errors: none
-* Scope: public
-****************************************************************************/
-
-const rtems_termios_callbacks * SciGetTermiosHandlers( int32_t polled )
-{
- if ( polled )
- {
- return &SciPolledCallbacks; /* polling based */
- }
- else
- {
- return &SciInterruptCallbacks; /* interrupt driven */
- }
-}
-
-
-/****************************************************************************
-* Func: SciIsr
-* Desc: interrupt handler for serial communications interface
-* Inputs: vector number - unused
-* Outputs: none
-* Errors: none
-* Scope: public API
-****************************************************************************/
-
-rtems_isr SciIsr( rtems_vector_number vector )
-{
- uint8_t ch;
-
- if ( (*SCSR) & SCI_ERROR_PARITY ) SciErrorsParity ++;
- if ( (*SCSR) & SCI_ERROR_FRAMING ) SciErrorsFraming ++;
- if ( (*SCSR) & SCI_ERROR_NOISE ) SciErrorsNoise ++;
- if ( (*SCSR) & SCI_ERROR_OVERRUN ) SciErrorsOverrun ++;
-
- /* see if it was a transmit interrupt */
- /* data reg empty, xmt complete */
- if ( ( *SCCR1 & SCI_ENABLE_INT_TX ) && ( (*SCSR) & SCI_XMTR_AVAILABLE ) )
- {
- SciDisableTransmitInterrupts();
-
- /* tell termios module that the charcter was sent */
- /* he will call us later to transmit more if there are any */
-
- if (rtems_termios_dequeue_characters( SciTermioTty, 1 ))
- {
- /* there are more bytes to transmit so enable TX interrupt */
-
- SciEnableTransmitInterrupts();
- }
- }
-
- /* see if it was a receive interrupt */
- /* on the sci uart we just get one character per interrupt */
-
- while ( SciCharAvailable() ) /* char in data register? */
- {
- ch = SciReadCharNoWait(); /* get the char from the uart */
-
- /* IMPORTANT!!! */
- /* either send it to the termios module or keep it locally */
-
- if ( SciOpened == DRIVER_OPENED ) /* the driver is open */
- {
- SciRcvBufPutChar(ch); /* keep it locally */
- }
- else /* put in termios buffer */
- {
- char c = (char) ch;
- rtems_termios_enqueue_raw_characters( SciTermioTty, &c, 1 );
- }
-
- *SCSR &= SCI_CLEAR_RX_INT; /* clear the interrupt */
- }
-}
-
-
-/*
- * SECTION 1
- * ROUTINES TO MANIPULATE THE CIRCULAR BUFFER
- */
-
-/****************************************************************************
-* Func: SciRcvBufGetChar
-* Desc: read a character from the circular buffer
-* make sure there is data before you call this!
-* Inputs: none
-* Outputs: the character or -1
-* Errors: none
-* Scope: private
-****************************************************************************/
-
-static int8_t SciRcvBufGetChar(void)
-{
- rtems_interrupt_level level;
- uint8_t ch;
-
- if ( SciRcvBufCount == 0 )
- {
- rtems_fatal_error_occurred(0xDEAD); /* check the count first! */
- }
-
- rtems_interrupt_disable( level ); /* disable interrupts */
-
- ch = SciRcvBuffer[SciRcvBufGetIndex]; /* get next byte */
-
- SciRcvBufGetIndex++; /* bump the index */
-
- SciRcvBufGetIndex &= SCI_RCV_BUF_SIZE - 1; /* and wrap it */
-
- SciRcvBufCount--; /* decrement counter */
-
- rtems_interrupt_enable( level ); /* restore interrupts */
-
- return ch; /* return the char */
-}
-
-
-/****************************************************************************
-* Func: SciRcvBufPutChar
-* Desc: put a character into the rcv data circular buffer
-* Inputs: the character
-* Outputs: none
-* Errors: none
-* Scope: private
-****************************************************************************/
-
-static void SciRcvBufPutChar( uint8_t ch )
-{
- rtems_interrupt_level level;
-
- if ( SciRcvBufCount == SCI_RCV_BUF_SIZE ) /* is there room? */
- {
- return; /* no, throw it away */
- }
-
- rtems_interrupt_disable( level ); /* disable interrupts */
-
- SciRcvBuffer[SciRcvBufPutIndex] = ch; /* put it in the buf */
-
- SciRcvBufPutIndex++; /* bump the index */
-
- SciRcvBufPutIndex &= SCI_RCV_BUF_SIZE - 1; /* and wrap it */
-
- SciRcvBufCount++; /* increment counter */
-
- rtems_interrupt_enable( level ); /* restore interrupts */
-
- return; /* return */
-}
-
-
-/****************************************************************************
-* Func: SciRcvBufFlush
-* Desc: completely reset and clear the rcv buffer
-* Inputs: none
-* Outputs: none
-* Errors: none
-* Scope: private
-****************************************************************************/
-
-#if 0 /* prevents compiler warning */
-static void SciRcvBufFlush( void )
-{
- rtems_interrupt_level level;
-
- rtems_interrupt_disable( level ); /* disable interrupts */
-
- memset( SciRcvBuffer, 0, sizeof(SciRcvBuffer) );
-
- SciRcvBufPutIndex = 0; /* clear */
-
- SciRcvBufGetIndex = 0; /* clear */
-
- SciRcvBufCount = 0; /* clear */
-
- rtems_interrupt_enable( level ); /* restore interrupts */
-
- return; /* return */
-}
-#endif
-
-
-/*
- *
- * SECTION 2
- * INTERRUPT BASED ENTRY POINTS FOR THE TERMIOS MODULE
- */
-
-/****************************************************************************
-* Func: SciInterruptOpen
-* Desc: open routine for the interrupt based device driver
-* Default state is 9600 baud, 8 bits, No parity, and 1 stop bit. ??
-**CHANGED** Default baud rate is now 19200, 8N1
-* called from rtems_termios_open which is called from console_open
-* Inputs: major - device number
-* minor - device number
-* args - points to terminal info
-* Outputs: success/fail
-* Errors: none
-* Scope: public API
-****************************************************************************/
-
-int SciInterruptOpen(
- int major,
- int minor,
- void *arg
-)
-{
- rtems_libio_open_close_args_t * args = arg;
- rtems_isr_entry old_vector;
-
- if ( minor != SCI_MINOR ) /* check minor device num */
- {
- return -1;
- }
-
- if ( !args ) /* must have args */
- {
- return -1;
- }
-
- SciTermioTty = args->iop->data1; /* save address of struct */
-
- SciDisableAllInterrupts(); /* turn off sci interrupts */
-
- /* THIS IS ACTUALLY A BAD THING - SETTING LINE PARAMETERS HERE */
- /* IT SHOULD BE DONE THROUGH TCSETATTR() WHEN THE CONSOLE IS OPENED!!! */
-
-/* SciSetBaud(115200); set the baud rate */
-/* SciSetBaud( 57600); set the baud rate */
-/* SciSetBaud( 38400); set the baud rate */
-/* SciSetBaud( 19200); set the baud rate */
- SciSetBaud( 9600); /* set the baud rate */
-
- SciSetParity(SCI_PARITY_NONE); /* set parity to none */
-
- SciSetDataBits(SCI_8_DATA_BITS); /* set data bits to 8 */
-
- /* Install our interrupt handler into RTEMS. */
- /* 68 is an unused user-defined vector. Note that the vector must be */
- /* even - it sets the low bit for SPI interrupts, and clears it for */
- /* SCI interrupts. Also note that vector 66 is used by CPU32bug on */
- /* the mrm332. */
-
- rtems_interrupt_catch( SciIsr, 68, &old_vector );
-
- *QSMCR = (*QSMCR & ~IARB) | 1; // Is 1 a good value for qsm iarb?
- *QIVR = 68;
- *QILR &= 0xf8;
- *QILR |= 0x06 & 0x07;
-
- SciEnableTransmitter(); /* enable the transmitter */
-
- SciEnableReceiver(); /* enable the receiver */
-
- SciEnableReceiveInterrupts(); /* enable rcv interrupts */
-
- return RTEMS_SUCCESSFUL;
-}
-
-
-/****************************************************************************
-* Func: SciInterruptClose
-* Desc: close routine called by the termios module
-* Inputs: major - device number
-* minor - device number
-* args - unused
-* Outputs: success/fail
-* Errors: none
-* Scope: public - termio entry point
-****************************************************************************/
-
-int SciInterruptClose(
- int major,
- int minor,
- void *arg
-)
-{
- SciDisableAllInterrupts();
-
- return RTEMS_SUCCESSFUL;
-}
-
-
-/****************************************************************************
-* Func: SciInterruptWrite
-* Desc: writes data to the uart using transmit interrupts
-* Inputs: minor - device number
-* buf - points to the data
-* len - number of bytes to send
-* Outputs: success/fail
-* Errors: none
-* Scope: public API
-****************************************************************************/
-
-ssize_t SciInterruptWrite(
- int minor,
- const char *buf,
- size_t len
-)
-{
- /* We are using interrupt driven output so termios only sends us */
- /* one character at a time. The sci does not have a fifo. */
-
- if ( !len ) /* no data? */
- {
- return -1; /* return error */
- }
-
- if ( minor != SCI_MINOR ) /* check the minor dev num */
- {
- return -1; /* return error */
- }
-
- if ( SciOpened == DRIVER_OPENED ) /* is the driver api open? */
- {
- return -1; /* yep, throw this away */
- }
-
- SciWriteCharNoWait(*buf); /* try to send a char */
-
- *SCSR &= SCI_CLEAR_TDRE; /* clear tx data reg empty flag */
-
- SciEnableTransmitInterrupts(); /* enable the tx interrupt */
-
- return 0; /* return success */
-}
-
-
-/****************************************************************************
-* Func: SciSetAttributes
-* Desc: setup the uart based on the termios modules requests
-* Inputs: minor - device number
-* t - pointer to the termios info struct
-* Outputs: none
-* Errors: none
-* Scope: public API
-****************************************************************************/
-
-int SciSetAttributes(
- int minor,
- const struct termios *t
-)
-{
- uint32_t baud_requested;
- uint32_t sci_rate = 0;
- uint16_t sci_parity = 0;
- uint16_t sci_databits = 0;
-
- if ( minor != SCI_MINOR ) /* check the minor dev num */
- {
- return -1; /* return error */
- }
-
- /* if you look closely you will see this is the only thing we use */
- /* set the baud rate */
-
- baud_requested = t->c_ospeed; /* baud rate */
-
- if (!baud_requested)
- {
- baud_requested = B9600; /* default to 9600 baud */
- /* baud_requested = B19200; default to 19200 baud */
- }
-
- sci_rate = rtems_termios_baud_to_number( baud_requested );
-
- /* parity error detection */
-
- if (t->c_cflag & PARENB) /* enable parity detection? */
- {
- if (t->c_cflag & PARODD)
- {
- sci_parity = SCI_PARITY_ODD; /* select odd parity */
- }
- else
- {
- sci_parity = SCI_PARITY_EVEN; /* select even parity */
- }
- }
- else
- {
- sci_parity = SCI_PARITY_NONE; /* no parity, most common */
- }
-
- /* set the number of data bits, 8 is most common */
-
- if (t->c_cflag & CSIZE) /* was it specified? */
- {
- switch (t->c_cflag & CSIZE)
- {
- case CS8: sci_databits = SCI_8_DATA_BITS; break;
- default : sci_databits = SCI_9_DATA_BITS; break;
- }
- }
- else
- {
- sci_databits = SCI_8_DATA_BITS; /* default to 8 data bits */
- }
-
- /* the number of stop bits; always 1 for SCI */
-
- if (t->c_cflag & CSTOPB)
- {
- /* do nothing */
- }
-
- /* setup the hardware with these serial port parameters */
-
- SciSetBaud(sci_rate); /* set the baud rate */
- SciSetParity(sci_parity); /* set the parity type */
- SciSetDataBits(sci_databits); /* set the data bits */
-
- return RTEMS_SUCCESSFUL;
-}
-
-
-/*
- *
- * SECTION 3
- * POLLING BASED ENTRY POINTS FOR THE TERMIOS MODULE
- */
-
-/****************************************************************************
-* Func: SciPolledOpen
-* Desc: open routine for the polled i/o version of the driver
-* called from rtems_termios_open which is called from console_open
-* Inputs: major - device number
-* minor - device number
-* args - points to terminal info struct
-* Outputs: success/fail
-* Errors: none
-* Scope: public - termios entry point
-****************************************************************************/
-
-int SciPolledOpen(
- int major,
- int minor,
- void *arg
-)
-{
- rtems_libio_open_close_args_t * args = arg;
-
- if ( minor != SCI_MINOR ) /* check minor device num */
- {
- return -1;
- }
-
- if ( !args ) /* must have args */
- {
- return -1;
- }
-
- SciTermioTty = args->iop->data1; /* Store tty pointer */
-
- SciDisableAllInterrupts(); /* don't generate interrupts */
-
- /* THIS IS ACTUALLY A BAD THING - SETTING LINE PARAMETERS HERE */
- /* IT SHOULD BE DONE THROUGH TCSETATTR() WHEN THE CONSOLE IS OPENED!!! */
-
-/* SciSetBaud(115200); set the baud rate */
-/* SciSetBaud( 57600); set the baud rate */
-/* SciSetBaud( 38400); set the baud rate */
-/* SciSetBaud( 19200); * set the baud rate */
- SciSetBaud( 9600); /* set the baud rate */
-
- SciSetParity(SCI_PARITY_NONE); /* set no parity */
-
- SciSetDataBits(SCI_8_DATA_BITS); /* set 8 data bits */
-
- SciEnableTransmitter(); /* enable the xmitter */
-
- SciEnableReceiver(); /* enable the rcvr */
-
- return RTEMS_SUCCESSFUL;
-}
-
-
-/****************************************************************************
-* Func: SciPolledClose
-* Desc: close routine for the device driver, same for both
-* Inputs: major - device number
-* minor - device number
-* args - unused
-* Outputs: success/fail
-* Errors: none
-* Scope: public termios API
-****************************************************************************/
-
-int SciPolledClose(
- int major,
- int minor,
- void *arg
-)
-{
- SciDisableAllInterrupts();
-
- return RTEMS_SUCCESSFUL;
-}
-
-
-/****************************************************************************
-* Func: SciPolledRead
-* Desc: polling based read routine for the uart
-* Inputs: minor - device number
-* Outputs: error or the character read
-* Errors: none
-* Scope: public API
-****************************************************************************/
-
-int SciPolledRead(
- int minor
-)
-{
- if ( minor != SCI_MINOR ) /* check the type-punned dev num */
- {
- return -1; /* return error */
- }
-
- if ( SciCharAvailable() ) /* if a char is available */
- {
- return SciReadCharNoWait(); /* read the rx data register */
- }
-
- return -1; /* return error */
-}
-
-
-/****************************************************************************
-* Func: SciPolledWrite
-* Desc: writes out characters in polled mode, waiting for the uart
-* check in console_open, but we only seem to use interrupt mode
-* Inputs: minor - device number
-* buf - points to the data
-* len - how many bytes
-* Outputs: error or number of bytes written
-* Errors: none
-* Scope: public termios API
-****************************************************************************/
-
-ssize_t SciPolledWrite(
- int minor,
- const char *buf,
- size_t len
-)
-{
- ssize_t written = 0;
-
- if ( minor != SCI_MINOR ) /* check minor device num */
- {
- return -1;
- }
-
- if ( SciOpened == DRIVER_OPENED ) /* is the driver api open? */
- {
- return -1; /* toss the data */
- }
-
- /* send each byte in the string out the port */
-
- while ( written < len )
- {
- SciWriteCharWait(*buf++); /* send a byte */
-
- written++; /* increment counter */
- }
-
- return written; /* return count */
-}
-
-
-/*
- *
- * SECTION 4
- * DEVICE DRIVER PUBLIC API ENTRY POINTS
- */
-
-/****************************************************************************
-* Func: SciInit
-* Desc: Initialize the lasers device driver and hardware
-* Inputs: major - the major device number which is assigned by rtems
-* minor - the minor device number which is undefined at this point
-* arg - ?????
-* Outputs: RTEMS_SUCCESSFUL
-* Errors: None.
-* Scope: public API
-****************************************************************************/
-
-rtems_device_driver SciInitialize (
- rtems_device_major_number major,
- rtems_device_minor_number minor,
- void * arg
-)
-{
-/* rtems_status_code status; */
-
-/*printk("%s\r\n", __FUNCTION__); */
-
- /* register the SCI device name for termios console i/o
- * this is done over in console.c which doesn't seem exactly right
- * but there were problems doing it here...
- */
-
-/* status = rtems_io_register_name( "/dev/sci", major, 0 ); */
-
-/* if (status != RTEMS_SUCCESSFUL) */
-/* rtems_fatal_error_occurred(status); */
-
- SciMajor = major; /* save the rtems major number */
-
- SciOpened = DRIVER_CLOSED; /* initial state is closed */
-
- /* if you have an interrupt handler, install it here */
-
- SciInited = 1; /* set the inited flag */
-
- return RTEMS_SUCCESSFUL;
-}
-
-
-/****************************************************************************
-* Func: SciOpen
-* Desc: device driver open routine
-* you must open a device before you can anything else
-* only one process can have the device opened at a time
-* you could look at the task id to restrict access if you want
-* Inputs: major - the major device number assigned by rtems
-* minor - the minor device number assigned by us
-* arg - ?????
-* Outputs: see below
-* Errors: none
-* Scope: public API
-****************************************************************************/
-
-rtems_device_driver SciOpen (
- rtems_device_major_number major,
- rtems_device_minor_number minor,
- void * arg
-)
-{
-/*printk("%s major=%d minor=%d\r\n", __FUNCTION__,major,minor); */
-
- if (SciInited == 0) /* must be initialized first! */
- {
- return RTEMS_NOT_CONFIGURED;
- }
-
- if (minor != SCI_MINOR)
- {
- return RTEMS_INVALID_NAME; /* verify minor number */
- }
-
- if (SciOpened == DRIVER_OPENED)
- {
- return RTEMS_RESOURCE_IN_USE; /* already opened! */
- }
-
- SciOpened = DRIVER_OPENED; /* set the opened flag */
-
- return RTEMS_SUCCESSFUL;
-}
-
-
-/****************************************************************************
-* Func: SciClose
-* Desc: device driver close routine
-* the device must be opened before you can close it
-* the device must be closed before someone (else) can open it
-* Inputs: major - the major device number
-* minor - the minor device number
-* arg - ?????
-* Outputs: see below
-* Errors: none
-* Scope: public API
-****************************************************************************/
-
-rtems_device_driver SciClose (
- rtems_device_major_number major,
- rtems_device_minor_number minor,
- void * arg
-)
-{
-/*printk("%s major=%d minor=%d\r\n", __FUNCTION__,major,minor); */
-
- if (minor != SCI_MINOR)
- {
- return RTEMS_INVALID_NAME; /* check the minor number */
- }
-
- if (SciOpened != DRIVER_OPENED)
- {
- return RTEMS_INCORRECT_STATE; /* must be opened first */
- }
-
- SciOpened = DRIVER_CLOSED; /* set the flag */
-
- return RTEMS_SUCCESSFUL;
-}
-
-
-/****************************************************************************
-* Func: SciRead
-* Desc: device driver read routine
-* this function is not meaningful for the laser devices
-* Inputs: major - the major device number
-* minor - the minor device number
-* arg - read/write arguments
-* Outputs: see below
-* Errors: none
-* Scope: public API
-****************************************************************************/
-
-rtems_device_driver SciRead (
- rtems_device_major_number major,
- rtems_device_minor_number minor,
- void *arg
-)
-{
- rtems_libio_rw_args_t *rw_args; /* ptr to argument struct */
- char *buffer;
-
- rw_args = (rtems_libio_rw_args_t *) arg; /* arguments to read() */
-
- if (minor != SCI_MINOR)
- {
- return RTEMS_INVALID_NAME; /* check the minor number */
- }
-
- if (SciOpened == DRIVER_CLOSED)
- {
- return RTEMS_INCORRECT_STATE; /* must be opened first */
- }
-
- buffer = rw_args->buffer; /* points to user's buffer */
-
-/* *buffer = SciReadCharWait(); wait for a character */
-
- /* if there isn't a character available, wait until one shows up */
- /* or the timeout period expires, which ever happens first */
-
- if ( SciRcvBufCount == 0 ) /* no chars */
- {
- /* wait for someone to wake me up... */
- /*rtems_task_wake_after(SciReadTimeout); */
- }
-
- if ( SciRcvBufCount ) /* any characters locally? */
- {
- *buffer = SciRcvBufGetChar(); /* get the character */
-
- rw_args->bytes_moved = 1; /* how many we actually read */
- }
-
- return RTEMS_SUCCESSFUL;
-}
-
-
-/****************************************************************************
-* Func: SciWrite
-* Desc: device driver write routine
-* this function is not meaningful for the laser devices
-* Inputs: major - the major device number
-* minor - the minor device number
-* arg - read/write arguments
-* Outputs: see below
-* Errors: non3
-* Scope: public API
-****************************************************************************/
-
-rtems_device_driver SciWrite (
- rtems_device_major_number major,
- rtems_device_minor_number minor,
- void * arg
-)
-{
- rtems_libio_rw_args_t *rw_args; /* ptr to argument struct */
- uint8_t *buffer;
- size_t length;
-
- rw_args = (rtems_libio_rw_args_t *) arg;
-
- if (minor != SCI_MINOR)
- {
- return RTEMS_INVALID_NAME; /* check the minor number */
- }
-
- if (SciOpened == DRIVER_CLOSED)
- {
- return RTEMS_INCORRECT_STATE; /* must be opened first */
- }
-
- buffer = (uint8_t*)rw_args->buffer; /* points to data */
-
- length = rw_args->count; /* how many bytes */
-
- while (length--)
- {
- SciWriteCharWait(*buffer++); /* send the bytes out */
- }
-
- rw_args->bytes_moved = rw_args->count; /* how many we wrote */
-
- return RTEMS_SUCCESSFUL;
-}
-
-
-/****************************************************************************
-* Func: SciControl
-* Desc: device driver control routine
-* see below for an example of how to use the ioctl interface
-* Inputs: major - the major device number
-* minor - the minor device number
-* arg - io control args
-* Outputs: see below
-* Errors: none
-* Scope: public API
-****************************************************************************/
-
-rtems_device_driver SciControl (
- rtems_device_major_number major,
- rtems_device_minor_number minor,
- void * arg
-)
-{
- rtems_libio_ioctl_args_t *args = arg; /* rtems arg struct */
- uint16_t command; /* the cmd to execute */
-
-/*printk("%s major=%d minor=%d\r\n", __FUNCTION__,major,minor); */
-
- /* do some sanity checking */
-
- if (minor != SCI_MINOR)
- {
- return RTEMS_INVALID_NAME; /* check the minor number */
- }
-
- if (SciOpened == DRIVER_CLOSED)
- {
- return RTEMS_INCORRECT_STATE; /* must be open first */
- }
-
- if (args == 0)
- {
- return RTEMS_INVALID_ADDRESS; /* must have args */
- }
-
- args->ioctl_return = -1; /* assume an error */
-
- command = args->command; /* get the command */
-
- if (command == SCI_SEND_BREAK) /* process the command */
- {
- SciSendBreak(); /* send break char */
- }
-
- args->ioctl_return = 0; /* return status */
-
- return RTEMS_SUCCESSFUL;
-}
-
-
-/*
- *
- * SECTION 5
- * HARDWARE LEVEL ROUTINES
- */
-
-/****************************************************************************
-* Func: SciSetBaud
-* Desc: setup the uart based on the termios modules requests
-* Inputs: baud rate
-* Outputs: none
-* Errors: none
-* Scope: private
-****************************************************************************/
-
-static void SciSetBaud(uint32_t rate)
-{
- uint16_t value;
- uint16_t save_sccr1;
-
-/* when you open the console you need to set the termio struct baud rate */
-/* it has a default value of 9600, when someone calls tcsetattr it reverts! */
-
- SciBaud = rate; /* save the rate */
-
- /* calculate the register value as a float and convert to an int */
- /* set baud rate - you must define the system clock constant */
- /* see mrm332.h for an example */
-
- value = ( (uint16_t) ( SYS_CLOCK / rate / 32.0 + 0.5 ) & 0x1fff );
-
- save_sccr1 = *SCCR1; /* save register */
-
- /* also turns off the xmtr and rcvr */
-
- *SCCR1 &= SCI_DISABLE_INT_ALL; /* disable interrupts */
-
- *SCCR0 = value; /* write the register */
-
- *SCCR1 = save_sccr1; /* restore register */
-
- return;
-}
-
-
-/****************************************************************************
-* Func: SciSetParity
-* Desc: setup the uart based on the termios modules requests
-* Inputs: parity
-* Outputs: none
-* Errors: none
-* Scope: private
-****************************************************************************/
-
-static void SciSetParity(uint16_t parity)
-{
- uint16_t value;
-
- value = *SCCR1; /* get the register */
-
- if (parity == SCI_PARITY_ODD)
- {
- value |= SCI_PARITY_ENABLE; /* parity enabled */
- value |= SCI_PARITY_ODD; /* parity odd */
- }
-
- else if (parity == SCI_PARITY_EVEN)
- {
- value |= SCI_PARITY_ENABLE; /* parity enabled */
- value &= ~SCI_PARITY_ODD; /* parity even */
- }
-
- else if (parity == SCI_PARITY_NONE)
- {
- value &= ~SCI_PARITY_ENABLE; /* disabled, most common */
- }
-
- /* else no changes */
-
- *SCCR1 = value; /* write the register */
-
- return;
-}
-
-
-/****************************************************************************
-* Func: SciSetDataBits
-* Desc: setup the uart based on the termios modules requests
-* Inputs: data bits
-* Outputs: none
-* Errors: none
-* Scope: private
-****************************************************************************/
-
-static void SciSetDataBits(uint16_t bits)
-{
- uint16_t value;
-
- value = *SCCR1; /* get the register */
-
- /* note - the parity setting affects the number of data bits */
-
- if (bits == SCI_9_DATA_BITS)
- {
- value |= SCI_9_DATA_BITS; /* 9 data bits */
- }
-
- else if (bits == SCI_8_DATA_BITS)
- {
- value &= SCI_8_DATA_BITS; /* 8 data bits */
- }
-
- /* else no changes */
-
- *SCCR1 = value; /* write the register */
-
- return;
-}
-
-
-/****************************************************************************
-* Func: SciDisableAllInterrupts
-* Func: SciEnableTransmitInterrupts
-* Func: SciEnableReceiveInterrupts
-* Desc: handles generation of interrupts by the sci module
-* Inputs: none
-* Outputs: none
-* Errors: none
-* Scope: private
-****************************************************************************/
-
-static void inline SciDisableAllInterrupts( void )
-{
- /* this also turns off the xmtr and rcvr */
-
- *SCCR1 &= SCI_DISABLE_INT_ALL;
-}
-
-static void inline SciEnableReceiveInterrupts( void )
-{
- *SCCR1 |= SCI_ENABLE_INT_RX;
-}
-
-static void inline SciDisableReceiveInterrupts( void )
-{
- *SCCR1 &= SCI_DISABLE_INT_RX;
-}
-
-static void inline SciEnableTransmitInterrupts( void )
-{
- *SCCR1 |= SCI_ENABLE_INT_TX;
-}
-
-static void inline SciDisableTransmitInterrupts( void )
-{
- *SCCR1 &= SCI_DISABLE_INT_TX;
-}
-
-
-/****************************************************************************
-* Func: SciEnableTransmitter, SciDisableTransmitter
-* Func: SciEnableReceiver, SciDisableReceiver
-* Desc: turns the transmitter and receiver on and off
-* Inputs: none
-* Outputs: none
-* Errors: none
-* Scope: private
-****************************************************************************/
-
-static void inline SciEnableTransmitter( void )
-{
- *SCCR1 |= SCI_ENABLE_XMTR;
-}
-
-static void inline SciDisableTransmitter( void )
-{
- *SCCR1 &= SCI_DISABLE_XMTR;
-}
-
-static void inline SciEnableReceiver( void )
-{
- *SCCR1 |= SCI_ENABLE_RCVR;
-}
-
-static void inline SciDisableReceiver( void )
-{
- *SCCR1 &= SCI_DISABLE_RCVR;
-}
-
-
-/****************************************************************************
-* Func: SciWriteCharWait
-* Desc: wait for room in the fifo and then put a char in
-* Inputs: a byte to send
-* Outputs: none
-* Errors: none
-* Scope: public
-****************************************************************************/
-
-void SciWriteCharWait(uint8_t c)
-{
- /* poll the fifo, waiting for room for another character */
-
- while ( ( *SCSR & SCI_XMTR_AVAILABLE ) != SCI_XMTR_AVAILABLE )
- {
- /* Either we are writing to the fifo faster than
- * the uart can clock bytes out onto the cable,
- * or we are in flow control (actually no, we
- * are ignoring flow control from the other end).
- * In the first case, higher baud rates will help.
- */
- /* relinquish processor while waiting */
- rtems_task_wake_after(RTEMS_YIELD_PROCESSOR);
- }
-
- *SCDR = c; /* send the charcter */
-
- SciBytesOut++; /* increment the counter */
-
- return;
-}
-
-/****************************************************************************
-* Func: SciWriteCharNoWait
-* Desc: if no room in the fifo throw the char on the floor
-* Inputs: a byte to send
-* Outputs: none
-* Errors: none
-* Scope: public
-****************************************************************************/
-
-void SciWriteCharNoWait(uint8_t c)
-{
- if ( ( *SCSR & SCI_XMTR_AVAILABLE ) == 0 )
- {
- return; /* no room, throw it away */
- }
-
- *SCDR = c; /* put the char in the fifo */
-
- SciBytesOut++; /* increment the counter */
-
- return;
-}
-
-
-/****************************************************************************
-* Func: SciReadCharWait
-* Desc: read a character, waiting for one to show up, if need be
-* Inputs: none
-* Outputs: a character
-* Errors: none
-* Scope: public
-****************************************************************************/
-
-static uint8_t inline SciReadCharWait( void )
-{
- uint8_t ch;
-
- while ( SciCharAvailable() == 0 ) /* anything there? */
- {
- /* relinquish processor while waiting */
- rtems_task_wake_after(RTEMS_YIELD_PROCESSOR);
- }
-
- /* if you have rcv ints enabled, then the isr will probably */
- /* get the character before you will unless you turn off ints */
- /* ie polling and ints don't mix that well */
-
- ch = *SCDR; /* get the charcter */
-
- SciBytesIn++; /* increment the counter */
-
- return ch; /* return the char */
-}
-
-/****************************************************************************
-* Func: SciReadCharNoWait
-* Desc: try to get a char but dont wait for one
-* Inputs: none
-* Outputs: a character or -1 if none
-* Errors: none
-* Scope: public
-****************************************************************************/
-
-static uint8_t inline SciReadCharNoWait( void )
-{
- uint8_t ch;
-
- if ( SciCharAvailable() == 0 ) /* anything there? */
- return -1;
-
- ch = *SCDR; /* get the character */
-
- SciBytesIn++; /* increment the count */
-
- return ch; /* return the char */
-}
-
-
-/****************************************************************************
-* Func: SciCharAvailable
-* Desc: is there a receive character in the data register
-* Inputs: none
-* Outputs: false if no char available, else true
-* Errors: none
-* Scope: public
-****************************************************************************/
-
-uint8_t inline SciCharAvailable( void )
-{
- return ( *SCSR & SCI_RCVR_READY ); /* char in data register? */
-}
-
-
-/****************************************************************************
-* Func: SciSendBreak
-* Desc: send 1 or tow breaks (all zero bits)
-* Inputs: none
-* Outputs: none
-* Errors: none
-* Scope: public
-****************************************************************************/
-
-void SciSendBreak( void )
-{
- /* From the Motorola QSM reference manual - */
-
- /* "if SBK is toggled by writing it first to a one and then immediately */
- /* to a zero (in less than one serial frame interval), the transmitter */
- /* sends only one or two break frames before reverting to mark (idle) */
- /* or before commencing to send more data" */
-
- *SCCR1 |= SCI_SEND_BREAK; /* set the bit */
-
- *SCCR1 &= ~SCI_SEND_BREAK; /* clear the bit */
-
- return;
-}
-
-
-/*
- *
- * SECTION 6
- * TEST CODE
- */
-
-/****************************************************************************
-* Func: SciUnitTest
-* Desc: test the device driver
-* Inputs: nothing
-* Outputs: nothing
-* Scope: public
-****************************************************************************/
-
-#if 0
-void SciUnitTest()
-{
- uint8_t byte; /* a character */
- uint16_t fd; /* file descriptor for device */
- uint16_t result; /* result of ioctl */
-
- fd = open("/dev/sci",O_RDWR); /* open the device */
-
-printk("SCI open fd=%d\r\n",fd);
-
- result = write(fd, "abcd\r\n", 6); /* send a string */
-
-printk("SCI write result=%d\r\n",result);
-
- result = read(fd, &byte, 1); /* read a byte */
-
-printk("SCI read result=%d,byte=%x\r\n",result,byte);
-
- return;
-}
-#endif
-
-
-/****************************************************************************
-* Func: SciPrintStats
-* Desc: print out some driver information
-* Inputs: nothing
-* Outputs: nothing
-* Scope: public
-****************************************************************************/
-
-void SciPrintStats ( void )
-{
- printk("\r\n");
-
- printk( "SYS_CLOCK is %2.6f Mhz\r\n\n", SYS_CLOCK / 1000000.0 );
-
- printk( "Current baud rate is %d bps or %d cps\r\n\n", SciBaud, SciBaud / 10 );
-
- printk( "SCI Uart chars in %8" PRIu32 "\r\n", SciBytesIn );
- printk( "SCI Uart chars out %8" PRIu32 "\r\n", SciBytesOut );
- printk( "SCI Uart framing errors %8" PRIu32 "\r\n", SciErrorsFraming );
- printk( "SCI Uart parity errors %8" PRIu32 "\r\n", SciErrorsParity );
- printk( "SCI Uart overrun errors %8" PRIu32 "\r\n", SciErrorsOverrun );
- printk( "SCI Uart noise errors %8" PRIu32 "\r\n", SciErrorsNoise );
-
- return;
-}