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

📄 serial_ti16550.c

📁 MIPS YAMON, a famous monitor inc. source, make file and PDF manuals.
💻 C
📖 第 1 页 / 共 3 页
字号:
    }    /* TTY1 */    tty = PORT_TTY1;    SYSCON_read( SYSCON_COM_TTY1_MAJOR, (void *)(&major), sizeof(UINT32) );    if (major == SYS_MAJOR_SERIAL_TI16550)    {	SYSCON_read(SYSCON_COM_TTY1_MINOR, (void *)(&minor), sizeof(UINT32));	IO_init( SYS_MAJOR_SERIAL_TI16550, minor, &tty );    }    return OK;}/************************************************************************ *      Implementation : Device driver services ************************************************************************//************************************************************************ * *                          SERIAL_TI16550_init *  Description : *  ------------- *  This service initializes the serial driver and configures *  the applicable channels according to the configuration data, read *  from SYSCON * *  Parameters : *  ------------ * *  'major',     IN,    major device number *  'minor',     IN,    not used *  'port',      IN,	port mapping (PORT_TTY0/PORT_TTY1) * *  Return values : *  --------------- * *  'OK'(=0) * ************************************************************************/staticINT32 SERIAL_TI16550_init(    UINT32 major,          /* IN: major device number			*/    UINT32 minor,          /* IN: minor device number			*/    UINT32 *port )         /* IN: port mapping				*/{    INT32		      rcode;    UINT32		      brkresval;    UINT8		      baudrate, databits, parity, stopbits, flowctrl;    UINT8		      dll, dlm;    t_SERIAL_ctrl_descriptor  ctrl;    void		      *minor_data;    bool		      ic_in_use;    UINT32		      int_line;    bool		      adjust_break;    /* Get settings */    SYSCON_read( (*port == PORT_TTY0) ? 		     SYSCON_COM_TTY0_BAUDRATE_ID :		     SYSCON_COM_TTY1_BAUDRATE_ID,		 (void *)&baudrate,		 sizeof(UINT8) );    SYSCON_read( (*port == PORT_TTY0) ? 		     SYSCON_COM_TTY0_DATABITS_ID :		     SYSCON_COM_TTY1_DATABITS_ID,		 (void *)&databits,		 sizeof(UINT8) );    SYSCON_read( (*port == PORT_TTY0) ? 		     SYSCON_COM_TTY0_PARITY_ID :		     SYSCON_COM_TTY1_PARITY_ID,		 (void *)&parity,		 sizeof(UINT8) );    SYSCON_read( (*port == PORT_TTY0) ? 		     SYSCON_COM_TTY0_STOPBITS_ID :		     SYSCON_COM_TTY1_STOPBITS_ID,		 (void *)&stopbits,		 sizeof(UINT8) );    SYSCON_read( (*port == PORT_TTY0) ? 		     SYSCON_COM_TTY0_FLOWCTRL_ID :		     SYSCON_COM_TTY1_FLOWCTRL_ID,		 (void *)&flowctrl,		 sizeof(UINT8) );    SYSCON_read( (*port == PORT_TTY0) ? 		     SYSCON_COM_TTY0_REG_SIZE_ID :		     SYSCON_COM_TTY1_REG_SIZE_ID,		 (void *)&size[minor],		 sizeof(UINT8) );    SYSCON_read( (*port == PORT_TTY0) ? 		     SYSCON_COM_TTY0_REG_SPACING_ID :		     SYSCON_COM_TTY1_REG_SPACING_ID,		 (void *)&spacing,		 sizeof(UINT8) );    SYSCON_read( (*port == PORT_TTY0) ? 		     SYSCON_COM_TTY0_IC_IN_USE_ID :		     SYSCON_COM_TTY1_IC_IN_USE_ID,		 (void *)&ic_in_use,		 sizeof(bool) );    SYSCON_read( (*port == PORT_TTY0) ? 		     SYSCON_COM_TTY0_INTLINE_ID :		     SYSCON_COM_TTY1_INTLINE_ID,		 (void *)&int_line,		 sizeof(UINT32) );    SYSCON_read( (*port == PORT_TTY0) ? 		     SYSCON_COM_TTY0_ADJUST_BREAK_ID :		     SYSCON_COM_TTY1_ADJUST_BREAK_ID,		 (void *)&adjust_break,		 sizeof(bool) );    SYSCON_read( (*port == PORT_TTY0) ? 		     SYSCON_COM_TTY0_BIGEND_ID :		     SYSCON_COM_TTY1_BIGEND_ID,		 (void *)&bigend,		 sizeof(bool) );    SYSCON_read( (minor == SERIAL_MINOR_TI16550_UART0) ?		     SYSCON_BOARD_TI16C550C_BASE0_ID :		     SYSCON_BOARD_TI16C550C_BASE1_ID,		 (void *)&ti16550base,		 sizeof(void *) );    SYSCON_read( (minor == SERIAL_MINOR_TI16550_UART0) ?		     SYSCON_COM_TTY0_BAUDRATE_DIV_ID :		     SYSCON_COM_TTY1_BAUDRATE_DIV_ID,		 (void *)&serial_baudrate,		 sizeof(t_SERIAL_baudrate_div *) );    ti16550base  = (void *)KSEG1(ti16550base);    /* Verify settings */    if (baudrate >= SERIAL_BAUDRATE_MAX ||        (*serial_baudrate)[baudrate] == SERIAL_ILLEGAL )    {	return( ERROR_SERIAL_INVALID_BAUDRATE ) ;    }    if (databits >= SERIAL_DATABITS_MAX ||	serial_databits[databits] == SERIAL_ILLEGAL )    {	return( ERROR_SERIAL_INVALID_DATABITS ) ;    }    if (parity >= SERIAL_PARITY_MAX ||	serial_parity[parity] == SERIAL_ILLEGAL )    {	return( ERROR_SERIAL_INVALID_PARITY ) ;    }    if (stopbits >= SERIAL_STOPBITS_MAX ||	serial_stopbits[stopbits] == SERIAL_ILLEGAL )    {	return( ERROR_SERIAL_INVALID_STOPBITS ) ;    }    if (flowctrl >= SERIAL_FLOWCTRL_MAX ||        flowctrl == SERIAL_FLOWCTRL_NOT_DEFINED )    {	return( ERROR_SERIAL_INVALID_FLOWCTRL ) ;    }    /* convert */    dll      = (*serial_baudrate)[baudrate] & 0xff;    dlm      = ((*serial_baudrate)[baudrate]>>8) & 0xff;    databits = serial_databits[databits];    parity   = serial_parity[parity];    stopbits = serial_stopbits[stopbits];    /* initialize physical register addresses based on size and spacing */    phy_rbr[minor] = SET_ADDR( SERIAL_TI16550_RBR_OFS );    phy_thr[minor] = SET_ADDR( SERIAL_TI16550_THR_OFS );    phy_ier[minor] = SET_ADDR( SERIAL_TI16550_IER_OFS );    phy_iir[minor] = SET_ADDR( SERIAL_TI16550_IIR_OFS );    phy_fcr[minor] = SET_ADDR( SERIAL_TI16550_FCR_OFS );    phy_lcr[minor] = SET_ADDR( SERIAL_TI16550_LCR_OFS );    phy_mcr[minor] = SET_ADDR( SERIAL_TI16550_MCR_OFS );    phy_lsr[minor] = SET_ADDR( SERIAL_TI16550_LSR_OFS );    phy_msr[minor] = SET_ADDR( SERIAL_TI16550_MSR_OFS );    phy_scr[minor] = SET_ADDR( SERIAL_TI16550_SCR_OFS );    phy_dll[minor] = SET_ADDR( SERIAL_TI16550_DLL_OFS );    phy_dlm[minor] = SET_ADDR( SERIAL_TI16550_DLM_OFS );    /* init IER: clear all interrupts */    PHY_IER_W(minor, 0);    shadow_ier[minor] = 0;    /* initalize poll buffer pointers */    recv_getptr[minor] = recv_putptr[minor] = &recv_buffer[minor][0];    /* clear statistical info */    uart_statistics[minor].ua_tx_bytes   = 0;    uart_statistics[minor].ua_rx_bytes   = 0;    uart_statistics[minor].ua_rx_overrun = 0;    uart_statistics[minor].ua_rx_parity  = 0;    uart_statistics[minor].ua_rx_framing = 0;    uart_statistics[minor].ua_rx_break   = 0;    uart_statistics[minor].ua_rx_irqs    = 0;    uart_statistics[minor].ua_no_of_init++;    /*  Init baudrate :      *	    1) enable DL-registers     *	    2) set DLL + DLM divisor registers     *	    3) disable DL-registers                                     */    PHY_LCR_W(minor, SERIAL_LCR_DLAB);    PHY_DLL_W(minor, dll);    PHY_DLM_W(minor, dlm);    PHY_LCR_W(minor, 0);    /*  Init LCR:      *      1) 8-bit data     *	    2) 1 stop bit     *	    3) no parity                                                */    PHY_LCR_W(minor, databits | stopbits | parity);    /*  Init FCR:      *      1) enable FIFO     *	    2) reset receiver FIFO     *	    3) reset transmitter FIFO     *	    4) set receive FIFO threshold to 4                          */    PHY_FCR_W(minor, SERIAL_FCR_ENABLE     | 		     SERIAL_FCR_RCVR_RESET | 		     SERIAL_FCR_TXMT_RESET |		     SERIAL_FCR_RCVFIFO_4);    /*  Init MCR:      *      1) set DTR     *	    2) set RTS     *	    3) enable auto-flow control (both RX and TX)     *           (Texas only;                SuperIO and Philips: No OPeration)     *	    4) enable interrupt mask (OUT2)     *           (SuperIO and Philips only;  Texas: NC on Atlas,SEAD,Malta)     */    shadow_flow[minor] = flowctrl == SERIAL_FLOWCTRL_HARDWARE ? SERIAL_MCR_AFE : 0;    shadow_mcr[minor] = shadow_flow[minor] |                        SERIAL_MCR_DTR |                        SERIAL_MCR_RTS |                        SERIAL_MCR_OUT2;    PHY_MCR_W(minor, shadow_mcr[minor]);    if( adjust_break )    {        /* limit BRKRES register to prevent low baudrates from forcing reset */	rcode = SYSCON_read( SYSCON_BOARD_BRKRES_ID, &brkresval, sizeof(brkresval));        if(rcode == OK && brkresval && brkresval < (*serial_baudrate)[baudrate]>>4)        {            brkresval = (*serial_baudrate)[baudrate] >> 4;	  	    rcode     = SYSCON_write( SYSCON_BOARD_BRKRES_ID,				      &brkresval,				      sizeof(brkresval));        }    }    /* If this is the first call of init, we need to install interrupt handler */    if( !registered[minor] )    {            /* Determine parameter for interrupt service routine */        minor_data = (void *)&minor_numbers[minor];        /* Register interrupt handler */        if( ic_in_use )        {            EXCEP_register_ic_isr(  int_line,			            serial_int_handler,			            minor_data,				    NULL );        }        else        {	    EXCEP_register_cpu_isr( int_line,			            serial_int_handler,			            minor_data,				    NULL );        }        registered[minor] = TRUE;    }    /* Configure driver to be interrupt driven */    ctrl.sc_command = SERIAL_CTRL_RCV_IRQ_ON;    SERIAL_TI16550_ctrl( major, minor, &ctrl );    return( OK );}/************************************************************************ *		serial_int_handler ************************************************************************/static voidserial_int_handler(    void *data )	/* Holds the minor device number		*/{    t_SERIAL_ctrl_descriptor  ctrl;    ctrl.sc_command = SERIAL_CTRL_RCV_IRQ;    SERIAL_TI16550_ctrl( 0, *(UINT32 *)data, &ctrl );}/************************************************************************ * *                          SERIAL_TI16550_read *  Description : *  ------------- *  This service polls the specified channel for any present character. *  If any character is present, it will be read into the user allocated *  variable; if none present, completion = 'ERROR_SERIAL_NO_CHARACTER' *  will be returned. * *  Parameters : *  ------------ * *  'major',     IN,    major device number *  'minor',     IN,    minor device number for multi device drivers *  'p_param',   OUT,   character read * *  Return values : *  --------------- *  'OK' = 0x00:                 character read into user variable *  'ERROR_SERIAL_NO_CHARACTER': no character present on channel *  'ERROR_SERIAL_COMM_ERROR':   communication error detected *  'ERROR_SERIAL_COMM_BREAK':   'BREAK' detected * ************************************************************************/static INT32 SERIAL_TI16550_read(    UINT32 major,          /* IN: major device number             */    UINT32 minor,          /* IN: minor device number             */    UINT8  *p_param )      /* OUT: character been read            */{    UINT32 rc;    UINT32 lstat;

⌨️ 快捷键说明

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