📄 console.c
字号:
*/ pccchip2->SCC_error = 0x01; pccchip2->SCC_modem_int_ctl = 0x10 | CD2401_INT_LEVEL; pccchip2->SCC_tx_int_ctl = 0x10 | CD2401_INT_LEVEL; pccchip2->SCC_rx_int_ctl = 0x50 | CD2401_INT_LEVEL; pccchip2->gen_control |= 0x02; /* Enable pccchip2 interrupts */ } else { /* Disable interrupts */ pccchip2->SCC_modem_int_ctl &= 0xEF; pccchip2->SCC_tx_int_ctl &= 0xEF; pccchip2->SCC_rx_int_ctl &= 0xEF; }}/* ISRs *//* * cd2401_modem_isr * * Modem/timer interrupt (group 1) from CD2401. These are not used, and not * expected. Record as spurious and clear. * * Input parameters: * vector - vector number * * Output parameters: NONE * * Return values: NONE */rtems_isr cd2401_modem_isr( rtems_vector_number vector){ rtems_unsigned8 ch; /* Get interrupting channel ID */ ch = cd2401->licr >> 2; /* Record interrupt info for debugging */ CD2401_Channel_Info[ch].spur_dev = (vector << 24) | (cd2401->stk << 16) | (cd2401->mir << 8) | cd2401->misr; CD2401_Channel_Info[ch].spur_cnt++; cd2401->meoir = 0; /* EOI */ CD2401_RECORD_MODEM_ISR_SPURIOUS_INFO(( ch, CD2401_Channel_Info[ch].spur_dev, CD2401_Channel_Info[ch].spur_cnt ));}/* * cd2401_re_isr * * RX exception interrupt (group 3, receiver exception) from CD2401. These are * not used, and not expected. Record as spurious and clear. * * FIX THIS ISR TO DETECT BREAK CONDITIONS AND RAISE SIGINT * * Input parameters: * vector - vector number * * Output parameters: NONE * * Return values: NONE */rtems_isr cd2401_re_isr( rtems_vector_number vector){ rtems_unsigned8 ch; /* Get interrupting channel ID */ ch = cd2401->licr >> 2; /* Record interrupt info for debugging */ CD2401_Channel_Info[ch].spur_dev = (vector << 24) | (cd2401->stk << 16) | (cd2401->rir << 8) | cd2401->u5.b.risrl; CD2401_Channel_Info[ch].spur_cnt++; if ( cd2401->u5.b.risrl & 0x80 ) /* Timeout interrupt? */ cd2401->ier &= 0xDF; /* Disable rx timeout interrupt */ cd2401->reoir = 0x08; /* EOI; exception char not read */ CD2401_RECORD_RE_ISR_SPURIOUS_INFO(( ch, CD2401_Channel_Info[ch].spur_dev, CD2401_Channel_Info[ch].spur_cnt ));}/* * cd2401_rx_isr * * RX interrupt (group 3, receiver data) from CD2401. * * Input parameters: * vector - vector number * * Output parameters: NONE * * Return values: NONE */rtems_isr cd2401_rx_isr( rtems_vector_number vector){ char c; rtems_unsigned8 ch, status, nchars, i, total; char buffer[256]; status = cd2401->u5.b.risrl; ch = cd2401->licr >> 2; /* Has this channel been initialized or is it a condition we ignore? */ if ( CD2401_Channel_Info[ch].tty && !status ) { /* Normal Rx Int, read chars, enqueue them, and issue EOI */ total = nchars = cd2401->rfoc; /* Nb of chars to retrieve from rx FIFO */ i = 0; while ( nchars-- > 0 ) { c = (char)cd2401->dr; /* Next char in rx FIFO */ rtems_termios_enqueue_raw_characters( CD2401_Channel_Info[ch].tty ,&c, 1 ); buffer[i++] = c; } cd2401->reoir = 0; /* EOI */ CD2401_RECORD_RX_ISR_INFO(( ch, total, buffer )); } else { /* No, record as spurious interrupt */ CD2401_Channel_Info[ch].spur_dev = (vector << 24) | (cd2401->stk << 16) | (cd2401->rir << 8) | cd2401->u5.b.risrl; CD2401_Channel_Info[ch].spur_cnt++; cd2401->reoir = 0x04; /* EOI - character not read */ CD2401_RECORD_RX_ISR_SPURIOUS_INFO(( ch, status, CD2401_Channel_Info[ch].spur_dev, CD2401_Channel_Info[ch].spur_cnt )); }}/* * cd2401_tx_isr * * TX interrupt (group 2) from CD2401. * * Input parameters: * vector - vector number * * Output parameters: NONE * * Return values: NONE */rtems_isr cd2401_tx_isr( rtems_vector_number vector){ rtems_unsigned8 ch, status, buserr, initial_ier, final_ier; status = cd2401->tisr; ch = cd2401->licr >> 2; initial_ier = cd2401->ier; /* Has this channel been initialized? */ if ( !CD2401_Channel_Info[ch].tty ) { /* No, record as spurious interrupt */ CD2401_Channel_Info[ch].spur_dev = (vector << 24) | (cd2401->stk << 16) | (cd2401->tir << 8) | cd2401->tisr; CD2401_Channel_Info[ch].spur_cnt++; final_ier = cd2401->ier &= 0xFC;/* Shut up, whoever you are */ cd2401->teoir = 0x88; /* EOI - Terminate buffer and no transfer */ CD2401_RECORD_TX_ISR_SPURIOUS_INFO(( ch, status, initial_ier, final_ier, CD2401_Channel_Info[ch].spur_dev, CD2401_Channel_Info[ch].spur_cnt )); return; } if ( status & 0x80 ) { /* * Bus error occurred during DMA transfer. For now, just record. * Get reason for DMA bus error and clear the report for the next * occurrence */ buserr = pccchip2->SCC_error; pccchip2->SCC_error = 0x01; CD2401_Channel_Info[ch].buserr_type = (vector << 24) | (buserr << 16) | (cd2401->tir << 8) | cd2401->tisr; CD2401_Channel_Info[ch].buserr_addr = (((rtems_unsigned32)cd2401->tcbadru) << 16) | cd2401->tcbadrl; cd2401->teoir = 0x80; /* EOI - terminate bad buffer */ CD2401_RECORD_TX_ISR_BUSERR_INFO(( ch, status, initial_ier, buserr, CD2401_Channel_Info[ch].buserr_type, CD2401_Channel_Info[ch].buserr_addr )); return; } if ( status & 0x20 ) { /* DMA done -- Turn off TxD int, turn on TxMpty */ final_ier = cd2401->ier = (cd2401->ier & 0xFE) | 0x02; if( status & 0x08 ) { /* Transmit buffer B was released */ CD2401_Channel_Info[ch].own_buf_B = TRUE; } else { /* Transmit buffer A was released */ CD2401_Channel_Info[ch].own_buf_A = TRUE; } CD2401_RECORD_TX_ISR_INFO(( ch, status, initial_ier, final_ier, CD2401_Channel_Info[ch].txEmpty )); /* This call can result in a call to cd2401_write() */ rtems_termios_dequeue_characters ( CD2401_Channel_Info[ch].tty, CD2401_Channel_Info[ch].len ); cd2401->teoir = 0x08; /* EOI - no data transfered */ } else if ( status & 0x02 ) { /* TxEmpty */ CD2401_Channel_Info[ch].txEmpty = TRUE; final_ier = cd2401->ier &= 0xFD;/* Shut up the interrupts */ cd2401->teoir = 0x08; /* EOI - no data transfered */ CD2401_RECORD_TX_ISR_INFO(( ch, status, initial_ier, final_ier, CD2401_Channel_Info[ch].txEmpty )); } else { /* Why did we get a Tx interrupt? */ CD2401_Channel_Info[ch].spur_dev = (vector << 24) | (cd2401->stk << 16) | (cd2401->tir << 8) | cd2401->tisr; CD2401_Channel_Info[ch].spur_cnt++; cd2401->teoir = 0x08; /* EOI - no data transfered */ CD2401_RECORD_TX_ISR_SPURIOUS_INFO(( ch, status, initial_ier, 0xFF, CD2401_Channel_Info[ch].spur_dev, CD2401_Channel_Info[ch].spur_cnt )); }}/* * termios callbacks *//* * cd2401_firstOpen * * This is the first time that this minor device (channel) is opened. * Complete the asynchronous initialization. * * Input parameters: * major - device major number * minor - channel number * arg - pointer to a struct rtems_libio_open_close_args_t * * Output parameters: NONE * * Return value: IGNORED */int cd2401_firstOpen( int major, int minor, void *arg){ rtems_libio_open_close_args_t *args = arg; rtems_libio_ioctl_args_t newarg; struct termios termios; rtems_status_code sc; rtems_interrupt_level level; rtems_interrupt_disable (level); /* * Set up the line with the specified parameters. The difficulty is that * the line parameters are stored in the struct termios field of a * struct rtems_termios_tty that is not defined in a public header file. * Therefore, we do not have direct access to the termios passed in with * arg. So we make a rtems_termios_ioctl() call to get a pointer to the * termios structure. * * THIS KLUDGE MAY BREAK IN THE FUTURE! * * We could have made a tcgetattr() call if we had our fd. */ newarg.iop = args->iop; newarg.command = RTEMS_IO_GET_ATTRIBUTES; newarg.buffer = &termios; sc = rtems_termios_ioctl (&newarg); if (sc != RTEMS_SUCCESSFUL) rtems_fatal_error_occurred (sc); /* * Turn off hardware flow control. It is a pain with 3-wire cables. * The rtems_termios_ioctl() call below results in a call to * cd2401_setAttributes to initialize the line. The caller will "wait" * on the ttyMutex that it already owns; this is safe in RTEMS. */ termios.c_cflag |= CLOCAL; /* Ignore modem status lines */ newarg.command = RTEMS_IO_SET_ATTRIBUTES; sc = rtems_termios_ioctl (&newarg); if (sc != RTEMS_SUCCESSFUL) rtems_fatal_error_occurred (sc); /* Mark that the channel as initialized */ CD2401_Channel_Info[minor].tty = args->iop->data1; /* If the first of the four channels to open, set up the interrupts */ if ( !Init_count++ ) { /* Install the interrupt handlers */ Prev_re_isr = (rtems_isr_entry) set_vector( cd2401_re_isr, 0x5C, 1 ); Prev_modem_isr = (rtems_isr_entry) set_vector( cd2401_modem_isr, 0x5D, 1 ); Prev_tx_isr = (rtems_isr_entry) set_vector( cd2401_tx_isr, 0x5E, 1 ); Prev_rx_isr = (rtems_isr_entry) set_vector( cd2401_rx_isr, 0x5F, 1 ); cd2401_interrupts_initialize( TRUE ); } CD2401_RECORD_FIRST_OPEN_INFO(( minor, Init_count )); rtems_interrupt_enable (level); /* Return something */ return RTEMS_SUCCESSFUL;}/* * cd2401_lastClose * * There are no more opened file descriptors to this device. Close it down. * * Input parameters: * major - device major number * minor - channel number * arg - pointer to a struct rtems_libio_open_close_args_t */int cd2401_lastClose( int major, int minor, void *arg){ rtems_interrupt_level level; rtems_interrupt_disable (level); /* Mark that the channel is no longer is use */ CD2401_Channel_Info[minor].tty = NULL; /* If the last of the four channels to close, disable the interrupts */ if ( !--Init_count ) { cd2401_interrupts_initialize( FALSE ); /* De-install the interrupt handlers */ set_vector( Prev_re_isr, 0x5C, 1 ); set_vector( Prev_modem_isr, 0x5D, 1 ); set_vector( Prev_tx_isr, 0x5E, 1 ); set_vector( Prev_rx_isr, 0x5F, 1 ); } CD2401_RECORD_LAST_CLOSE_INFO(( minor, Init_count )); rtems_interrupt_enable (level); /* return something */ return RTEMS_SUCCESSFUL;}/* * cd2401_setAttributes * * Set up the selected channel of the CD2401 chip for doing asynchronous * I/O with DMA. * * The chip must already have been initialized by cd2401_initialize(). * * This code was written for clarity. The code space it occupies could be * reduced. The code could also be compiled with aggressive optimization * turned on. * * Input parameters: * minor - the selected channel * t - the termios parameters * * Output parameters: NONE * * Return value: IGNORED */int cd2401_setAttributes( int minor, const struct termios *t){ rtems_unsigned8 csize, cstopb, parodd, parenb, ignpar, inpck; rtems_unsigned8 hw_flow_ctl, sw_flow_ctl, extra_flow_ctl; rtems_unsigned8 icrnl, igncr, inlcr, brkint, ignbrk, parmrk, istrip; rtems_unsigned8 need_reinitialization = FALSE; rtems_unsigned8 read_enabled; rtems_unsigned16 tx_period, rx_period; rtems_unsigned32 out_baud, in_baud; rtems_interrupt_level level; /* Determine what the line parameters should be */ /* Output baud rate */ switch ( cfgetospeed (t) ) { default: out_baud = 9600; break; case B50: out_baud = 50; break; case B75: out_baud = 75; break; case B110: out_baud = 110; break; case B134: out_baud = 134; break; case B150: out_baud = 150; break; case B200: out_baud = 200; break; case B300: out_baud = 300; break; case B600: out_baud = 600; break; case B1200: out_baud = 1200; break; case B1800: out_baud = 1800; break; case B2400: out_baud = 2400; break; case B4800: out_baud = 4800; break; case B9600: out_baud = 9600; break; case B19200: out_baud = 19200; break; case B38400: out_baud = 38400; break; case B57600: out_baud = 57600; break; case B115200: out_baud = 115200; break; case B230400: out_baud = 230400; break; case B460800: out_baud = 460800; break; } /* Input baud rate */ switch ( cfgetispeed (t) ) { default: in_baud = out_baud; break; case B50: in_baud = 50; break; case B75: in_baud = 75; break;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -