sci.c

来自「RTEMS (Real-Time Executive for Multiproc」· C语言 代码 · 共 1,681 行 · 第 1/4 页

C
1,681
字号
//                       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(unsigned32 rate){    unsigned16 value;    unsigned16 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 efi332.h for an example    value = ( (unsigned16) ( 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(unsigned16 parity){    unsigned16 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(unsigned16 bits){    unsigned16 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(unsigned8 c){    // poll the fifo, waiting for room for another character    while ( ( *SCSR & SCI_XMTR_AVAILABLE ) == 0 )    {        /* 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(unsigned8 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****************************************************************************/unsigned8 inline SciReadCharWait( void ){    unsigned8 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****************************************************************************/unsigned8 inline SciReadCharNoWait( void ){    unsigned8 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****************************************************************************/unsigned8 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#define O_RDWR LIBIO_FLAGS_READ_WRITE           // dont like this but...void SciUnitTest(){    unsigned8 byte;                             // a character    unsigned16 fd;                              // file descriptor for device    unsigned16 result;                          // result of ioctl    fd = open("/dev/sci",O_RDWR);               // open the deviceprintk("SCI open fd=%d\r\n",fd);    result = write(fd, "abcd\r\n", 6);          // send a stringprintk("SCI write result=%d\r\n",result);    result = read(fd, &byte, 1);                // read a byteprintk("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       %8d\r\n", SciBytesIn       );    printk( "SCI Uart chars out      %8d\r\n", SciBytesOut      );    printk( "SCI Uart framing errors %8d\r\n", SciErrorsFraming );    printk( "SCI Uart parity  errors %8d\r\n", SciErrorsParity  );    printk( "SCI Uart overrun errors %8d\r\n", SciErrorsOverrun );    printk( "SCI Uart noise   errors %8d\r\n", SciErrorsNoise   );    return;}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?