sci.c

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

C
1,681
字号
        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        {            rtems_termios_enqueue_raw_characters( SciTermioTty, &ch, 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 signed8 SciRcvBufGetChar(){    rtems_interrupt_level level;    unsigned8 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( unsigned8 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 warningstatic 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****************************************************************************/signed32 SciInterruptOpen(    signed32  major,    signed32  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 rateSciSetBaud( 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, where does 66 come from?    rtems_interrupt_catch( SciIsr, 66, &old_vector );    *QIVR  = 66;    *QIVR &= 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****************************************************************************/signed32 SciInterruptClose(    signed32  major,    signed32  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****************************************************************************/signed32 SciInterruptWrite(    signed32    minor,    const char *buf,    signed32    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 0;                               // return error    }    if ( minor != SCI_MINOR )                   // check the minor dev num    {        return 0;                               // 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 1;                                   // 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****************************************************************************/signed32 SciSetAttributes(    signed32 minor,    const struct termios *t){    unsigned32  baud_requested;    unsigned32  sci_rate = 0;    unsigned16  sci_parity = 0;    unsigned16  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_cflag & CBAUD;        // baud rate    if (!baud_requested)    {//        baud_requested = B9600;                 // default to 9600 baud        baud_requested = B19200;                 // default to 19200 baud    }        sci_rate = 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****************************************************************************/signed32 SciPolledOpen(    signed32 major,    signed32 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

⌨️ 快捷键说明

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