📄 sh4uart.c
字号:
{ 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 + -