⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 sh4uart.c

📁 RTEMS (Real-Time Executive for Multiprocessor Systems) is a free open source real-time operating sys
💻 C
📖 第 1 页 / 共 2 页
字号:
    {        if ((SCSSR1 & (SH7750_SCSSR1_PER | SH7750_SCSSR1_FER |                      SH7750_SCSSR1_ORER)) != 0)        {            error_occured = 1;            if (SCSSR1 & (SH7750_SCSSR1_PER | SH7750_SCSSR1_FER))                parity_error = 1;            sh4uart_handle_error(uart);        }        if ((SCSSR1 & SH7750_SCSSR1_RDRF) == 0)            return -1;    }    else    {        if ((SCSSR2 & (SH7750_SCSSR2_ER | SH7750_SCSSR2_DR |                     SH7750_SCSSR2_BRK)) != 0 ||                 (SCLSR2 & SH7750_SCLSR2_ORER) != 0)        {            error_occured = 1;            if (SCSSR2 & (SH7750_SCSSR1_PER | SH7750_SCSSR1_FER))                parity_error = 1;            if (SCSSR2 & SH7750_SCSSR2_BRK)                break_occured = 1;            sh4uart_handle_error(uart);        }        if ((SCSSR2 & SH7750_SCSSR2_RDF) == 0)            return -1;    }    if (parity_error && !(uart->c_iflag & IGNPAR))    {        if (uart->c_iflag & PARMRK)        {            uart->parerr_mark_flag = 1;            return 0xff;        }        else            return 0;    }    if (break_occured && !(uart->c_iflag & BRKINT))    {        if (uart->c_iflag & IGNBRK)            return 0;        else            return 0;   /* XXX -- SIGINT */    }    ch = SCRDR(chn);    if (uart->chn == SH4_SCI)        SCSSR1 &= ~SH7750_SCSSR1_RDRF;    else        SCSSR2 &= ~SH7750_SCSSR2_RDF;    return ch;}/* * sh4uart_poll_write -- *     This function transmit buffer byte-by-byte in polling mode. * * PARAMETERS: *     uart - pointer to the UART descriptor structure *     buf - pointer to transmit buffer *     len - transmit buffer length * * RETURNS: *     0 */intsh4uart_poll_write(sh4uart *uart, const char *buf, int len){    while (len)    {        if (uart->chn == SH4_SCI)        {            while ((SCSSR1 & SH7750_SCSSR1_TDRE) != 0)            {                SCTDR1 = *buf++;                len--;                SCSSR1 &= ~SH7750_SCSSR1_TDRE;            }        }        else        {            while ((SCSSR2 & SH7750_SCSSR2_TDFE) != 0)            {                int i;                for (i = 0;                         i < 16 - TRANSMIT_TRIGGER_VALUE(SCFCR2 &                             SH7750_SCFCR2_TTRG);                         i++)                {                    SCTDR2 = *buf++;                    len--;                }                while ((SCSSR2 & SH7750_SCSSR2_TDFE) == 0 ||                         (SCSSR2 & SH7750_SCSSR2_TEND) == 0);                    SCSSR2 &= ~(SH7750_SCSSR1_TDRE | SH7750_SCSSR2_TEND);            }        }    }    return 0;}/********************************** * Functions to handle interrupts * **********************************//* sh4uart1_interrupt_receive -- *     UART interrupt handler routine -- SCI *     Receiving data * * PARAMETERS: *     vec - interrupt vector number * * RETURNS: *     none */static rtems_isrsh4uart1_interrupt_receive(rtems_vector_number vec){    register int bp = 0;    char buf[32];    /* Find UART descriptor from vector number */    sh4uart *uart = &sh4_uarts[0];    while (1)    {        if ((bp < sizeof(buf) - 1) && ((SCSSR1 & SH7750_SCSSR1_RDRF) != 0))        {            /* Receive character and handle frame/parity errors */            if ((SCSSR1 & (SH7750_SCSSR1_PER | SH7750_SCSSR1_FER |                             SH7750_SCSSR1_ORER)) != 0)            {                if (SCSSR1 & (SH7750_SCSSR1_PER | SH7750_SCSSR1_FER))                {                    if(!(uart->c_iflag & IGNPAR))                    {                        if (uart->c_iflag & PARMRK)                        {                            buf[bp++] = 0xff;                            buf[bp++] = 0x00;                        }                        else                            buf[bp++] = 0x00;                    }                    else                        buf[bp++] = SCRDR1;                }                sh4uart_handle_error(uart);            }            else                buf[bp++] = SCRDR1;            SCSSR1 &= ~SH7750_SCSSR1_RDRF;        }        else        {            if (bp != 0)                rtems_termios_enqueue_raw_characters(uart->tty, buf, bp);            break;        }    }}/* sh4uart2_interrupt_receive -- *     UART interrupt handler routine -- SCIF *     Receiving data * * PARAMETERS: *     vec - interrupt vector number * * RETURNS: *     none */static rtems_isrsh4uart2_interrupt_receive(rtems_vector_number vec){    register int bp = 0;    char buf[32];    /* Find UART descriptor from vector number */    sh4uart *uart = &sh4_uarts[1];    while (1)    {        if ((bp < sizeof(buf) - 1) && ((SCSSR2 & SH7750_SCSSR2_RDF) != 0))        {            if ((SCSSR2 & (SH7750_SCSSR2_ER | SH7750_SCSSR2_DR |                            SH7750_SCSSR2_BRK)) != 0 ||                     (SH7750_SCLSR2 & SH7750_SCLSR2_ORER) != 0)            {                if (SCSSR2 & SH7750_SCSSR2_ER)                {                    if(!(uart->c_iflag & IGNPAR))                    {                        if (uart->c_iflag & PARMRK)                        {                            buf[bp++] = 0xff;                            buf[bp++] = 0x00;                        }                        else                            buf[bp++] = 0x00;                    }                    else                        buf[bp++] = SCRDR1;                }                if (SCSSR2 & SH7750_SCSSR2_BRK)                {                    if (uart->c_iflag & IGNBRK)                        buf[bp++] = 0x00;                    else                        buf[bp++] = 0x00;   /* XXX -- SIGINT */                }                                    sh4uart_handle_error(uart);            }            else                buf[bp++] = SCRDR1;            SCSSR2 &= ~SH7750_SCSSR2_RDF;        }        else        {            if (bp != 0)                rtems_termios_enqueue_raw_characters(uart->tty, buf, bp);            break;        }    }}/* sh4uart1_interrupt_transmit -- *     UART interrupt handler routine -- SCI *     It continues transmit data when old part of data is transmitted * * PARAMETERS: *     vec - interrupt vector number * * RETURNS: *     none */static rtems_isrsh4uart1_interrupt_transmit(rtems_vector_number vec){    /* Find UART descriptor from vector number */    sh4uart *uart = &sh4_uarts[0];    if (uart->tx_buf != NULL && uart->tx_ptr < uart->tx_buf_len)    {        while ((SCSSR1 & SH7750_SCSSR1_TDRE) != 0 &&                 uart->tx_ptr < uart->tx_buf_len)        {            SCTDR1 = uart->tx_buf[uart->tx_ptr++];            SCSSR1 &= ~SH7750_SCSSR1_TDRE;        }    }    else    {        register int dequeue = uart->tx_buf_len;        uart->tx_buf = NULL;        uart->tx_ptr = uart->tx_buf_len = 0;        /* Disable interrupts while we do not have any data to transmit */        SCSCR1 &= ~SH7750_SCSCR_TIE;        rtems_termios_dequeue_characters(uart->tty, dequeue);    }}/* sh4uart2_interrupt_transmit -- *     UART interrupt handler routine -- SCI *     It continues transmit data when old part of data is transmitted * * PARAMETERS: *     vec - interrupt vector number * * RETURNS: *     none */static rtems_isrsh4uart2_interrupt_transmit(rtems_vector_number vec){    /* Find UART descriptor from vector number */    sh4uart *uart = &sh4_uarts[1];    if (uart->tx_buf != NULL && uart->tx_ptr < uart->tx_buf_len)    {            while ((SCSSR2 & SH7750_SCSSR2_TDFE) != 0)            {                int i;                for (i = 0;                         i < 16 - TRANSMIT_TRIGGER_VALUE(SCFCR2 &                             SH7750_SCFCR2_TTRG);                         i++)                    SCTDR2 = uart->tx_buf[uart->tx_ptr++];                while ((SCSSR1 & SH7750_SCSSR1_TDRE) == 0 ||                        (SCSSR1 & SH7750_SCSSR1_TEND) == 0);                    SCSSR1 &= ~(SH7750_SCSSR1_TDRE | SH7750_SCSSR2_TEND);            }    }    else    {        register int dequeue = uart->tx_buf_len;        uart->tx_buf = NULL;        uart->tx_ptr = uart->tx_buf_len = 0;        /* Disable interrupts while we do not have any data to transmit */        SCSCR2 &= ~SH7750_SCSCR_TIE;        rtems_termios_dequeue_characters(uart->tty, dequeue);    }}/* sh4uart_interrupt_write -- *     This function initiate transmitting of the buffer in interrupt mode. * * PARAMETERS: *     uart - pointer to the UART descriptor structure *     buf - pointer to transmit buffer *     len - transmit buffer length * * RETURNS: *     0 */rtems_status_codesh4uart_interrupt_write(sh4uart *uart, const char *buf, int len){    int level;    while ((SCSSR1 & SH7750_SCSSR1_TEND) == 0);    rtems_interrupt_disable(level);        uart->tx_buf = buf;    uart->tx_buf_len = len;    uart->tx_ptr = 0;    if (uart->chn == SH4_SCI)    {        SCSCR1 |= SH7750_SCSCR_TIE;    }    else        SCSCR2 |= SH7750_SCSCR_TIE;    rtems_interrupt_enable(level);    return RTEMS_SUCCESSFUL;}/* sh4uart_stop_remote_tx -- *     This function stop data flow from remote device. * * PARAMETERS: *     uart - pointer to the UART descriptor structure * * RETURNS: *     RTEMS_SUCCESSFUL */rtems_status_codesh4uart_stop_remote_tx(sh4uart *uart){    SCSCR(uart->chn) &= ~(SH7750_SCSCR_RIE | SH7750_SCSCR_RE);    return RTEMS_SUCCESSFUL;}/* sh4uart_start_remote_tx -- *     This function resume data flow from remote device. * * PARAMETERS: *     uart - pointer to the UART descriptor structure * * RETURNS: *     RTEMS_SUCCESSFUL */rtems_status_codesh4uart_start_remote_tx(sh4uart *uart){    SCSCR(uart->chn) |= SH7750_SCSCR_RIE | SH7750_SCSCR_RE;    return RTEMS_SUCCESSFUL;}#ifdef SH4_WITH_IPL/********************************* * Functions for SH-IPL gdb stub * *********************************//* * ipl_finish -- *     Says gdb that program finished to get out from it. */extern void ipl_finish(void);asm("   .global _ipl_finish\n""_ipl_finish:\n""   mov.l   __ipl_finish_value, r0\n""   trapa   #0x3f\n""   nop\n""   rts\n""   nop\n""   .align 4\n""__ipl_finish_value:\n""   .long   255");extern int ipl_serial_input(int poll_count);asm("    .global _ipl_serial_input\n""_ipl_serial_input:\n""    mov  #1,r0\n""    trapa #0x3f\n""    nop\n""    rts\n""    nop\n");extern void ipl_serial_output(const char *buf, int len);asm ("    .global _ipl_serial_output\n""_ipl_serial_output:\n""    mov  #0,r0\n""    trapa #0x3f\n""    nop\n""    rts\n""    nop\n");/* ipl_console_poll_read -- *     poll read operation for simulator console through ipl mechanism. * * PARAMETERS: *     minor - minor device number * * RETURNS: *     character code red from UART, or -1 if there is no characters *     available */intipl_console_poll_read(int minor){    unsigned char buf;    buf = ipl_serial_input(0x100000);    return buf;}/* ipl_console_poll_write -- *     wrapper for polling mode write function * * PARAMETERS: *     minor - minor device number *     buf - output buffer *     len - output buffer length * * RETURNS: *     result code (0) */intipl_console_poll_write(int minor, const char *buf, int len){    int c;    while (len > 0)     {        c = (len < 64 ? len : 64);        ipl_serial_output(buf, c);        len -= c;        buf += c;    }    return 0;}#endif

⌨️ 快捷键说明

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