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

📄 ns16550sio_x86.c

📁 vxworks下16550SIO Drv
💻 C
📖 第 1 页 / 共 2 页
字号:
#endif    		/* if the CTS is asserted enable Tx interrupt */   		if (mask & MSR_CTS)			pChan->ier |= TxFIFO_BIT;    /* enable Tx interrupt */		else           		pChan->ier &= (~TxFIFO_BIT); /* disable Tx interrupt */#if X86_16550		X86_REG_OUT(IER,pChan,pChan->ier);#else 		REG(IER, pChan) = pChan->ier; #endif		}		}    else/*==SIO_MODE_POLL*/        {        /* disable all ns16550 interrupts */ #if X86_16550		X86_REG_OUT(IER,pChan,0);#else        REG(IER, pChan) = 0;   #endif	}    pChan->channelMode = newMode;    intUnlock (oldlevel);    return (OK);   }/********************************************************************************* ns16550Ioctl - special device control** Includes commands to get/set baud rate, mode(INT,POLL), hardware options(* parity, number of data bits), and modem control(RTS/CTS and DTR/DSR).* The ioctl command SIO_HUP is sent by ttyDrv when the last close() function * call is made. Likewise SIO_OPEN is sent when the first open() function call* is made.** RETURNS: OK on success, EIO on device error, ENOSYS on unsupported*          request.*/LOCAL STATUS ns16550Ioctl    (    NS16550_CHAN * 	pChan,		/* pointer to channel */    int			request,	/* request code */    int        		arg		/* some argument */    )    {    FAST STATUS  status;    status = OK;    switch (request)	{	case SIO_BAUD_SET:	    if (arg < NS16550_MIN_RATE || arg > NS16550_MAX_RATE)		status = EIO;		/* baud rate out of range */	    else	        status = ns16550BaudSet (pChan, arg);	    break;        case SIO_BAUD_GET:            *(int *)arg = pChan->baudRate;            break;         case SIO_MODE_SET:	    status = (ns16550ModeSet (pChan, arg) == OK) ? OK : EIO;            break;                  case SIO_MODE_GET:            *(int *)arg = pChan->channelMode;            break;        case SIO_AVAIL_MODES_GET:            *(int *)arg = SIO_MODE_INT | SIO_MODE_POLL;            break;        case SIO_HW_OPTS_SET:    	    status = (ns16550OptsSet (pChan, arg) == OK) ? OK : EIO;    	    break;        case SIO_HW_OPTS_GET:            *(int *)arg = pChan->options;            break;        case SIO_HUP:            /* check if hupcl option is enabled */    	    if (pChan->options & HUPCL) 	    	status = ns16550Hup (pChan);            break;		case SIO_OPEN:            /* check if hupcl option is enabled */    	    if (pChan->options & HUPCL) 	    	status = ns16550Open (pChan);	    break;        default:            status = ENOSYS;	}    return (status);    }/********************************************************************************* ns16550IntWr - handle a transmitter interrupt ** This routine handles write interrupts from the UART. It reads a character* and puts it in the transmit holding register of the device for transfer.** If there are no more characters to transmit, transmission is disabled by * clearing the transmit interrupt enable bit in the IER(int enable register).** RETURNS: N/A**/void ns16550IntWr     (    NS16550_CHAN * pChan		/* pointer to channel */	    )    {    char           outChar;    if ((*pChan->getTxChar) (pChan->getTxArg, &outChar) != ERROR)#if X86_16550		X86_REG_OUT(THR,pChan,outChar);#else        REG(THR,pChan) = outChar;	/* write char to Transmit Holding Reg */#endif    else        {        pChan->ier &= (~TxFIFO_BIT);	/* indicates to disable Tx Int */#if X86_16550		X86_REG_OUT(IER,pChan,pChan->ier);#else        REG(IER, pChan) = pChan->ier;#endif        }    }/********************************************************************************* ns16550IntRd - handle a receiver interrupt ** This routine handles read interrupts from the UART.** RETURNS: N/A**/void ns16550IntRd     (    NS16550_CHAN * pChan	/* pointer to channel */    )    {    char   inchar;    /* read character from Receive Holding Reg. */#if X86_16550	inchar = X86_REG_IN(RBR,pChan);#else    inchar = REG(RBR, pChan);#endif    (*pChan->putRcvChar) (pChan->putRcvArg, inchar);    }/********************************************************************************* ns16550IntEx - miscellaneous interrupt processing** This routine handles miscellaneous interrupts on the UART.* Not implemented yet.** RETURNS: N/A**/void ns16550IntEx     (    NS16550_CHAN *pChan		/* pointer to channel */    )    {    /* Nothing for now... */    }/********************************************************************************** ns16550Int - interrupt level processing** This routine handles four sources of interrupts from the UART. They are* prioritized in the following order by the Interrupt Identification Register:* Receiver Line Status, Received Data Ready, Transmit Holding Register Empty* and Modem Status.** When a modem status interrupt occurs, the transmit interrupt is enabled if* the CTS signal is TRUE.** RETURNS: N/A**/void ns16550Int     (    NS16550_CHAN * pChan	/* pointer to channel */    )    {    FAST volatile char        intStatus;    /* read the Interrrupt Status Register (Int. Ident.) */#if X86_16550	intStatus = (X86_REG_IN(IIR,pChan)) & 0x0f;	X86_REG_OUT(IER,pChan,0);#else    intStatus = (REG(IIR, pChan)) & 0x0f;    /*     * This UART chip always produces level active interrupts, and the IIR      * only indicates the highest priority interrupt.       * In the case that receive and transmit interrupts happened at     * the same time, we must clear both interrupt pending to prevent     * edge-triggered interrupt(output from interrupt controller) from locking     * up. One way doing it is to disable all the interrupts at the beginning     * of the ISR and enable at the end.     */    REG(IER,pChan) = 0;    /* disable interrupt */#endif    switch (intStatus)	{	case IIR_RLS:            /* overrun,parity error and break interrupt */#if X86_16550			intStatus = X86_REG_IN(LSR,pChan);#else             intStatus = REG(LSR, pChan); /* read LSR to reset interrupt */#endif	    break;        case IIR_RDA:     		/* received data available */	case IIR_TIMEOUT: 	   /*	    * receiver FIFO interrupt. In some case, IIR_RDA will            * not be indicated in IIR register when there is more	    * than one character in FIFO.	    */            ns16550IntRd (pChan);  	/* RxChar Avail */            break;       	case IIR_THRE:  /* transmitter holding register ready */	    {            char outChar;            if ((*pChan->getTxChar) (pChan->getTxArg, &outChar) != ERROR)#if X86_16550				X86_REG_OUT(THR,pChan,outChar);#else                REG(THR, pChan) = outChar;   /* char to Transmit Holding Reg */#endif            else                pChan->ier &= (~TxFIFO_BIT); /* indicates to disable Tx Int */            }            break;	case IIR_MSTAT: /* modem status register */	   {	   char	msr;#if X86_16550 	   msr = X86_REG_IN(MSR,pChan);#else	   msr = REG(MSR, pChan);#endif	   /* if CTS is asserted by modem, enable tx interrupt */	   if ((msr & MSR_CTS) && (msr & MSR_DCTS)) 	   	pChan->ier |= TxFIFO_BIT;           else           	pChan->ier &= (~TxFIFO_BIT); 	   }	   break;        default:	    break;        }#if X86_16550	X86_REG_OUT(IER,pChan,pChan->ier);#else    REG(IER, pChan) = pChan->ier; /* enable interrupts accordingly */#endif    }/********************************************************************************* ns16550TxStartup - transmitter startup routine** Call interrupt level character output routine and enable interrupt if it is* in interrupt mode with no hardware flow control.* If the option for hardware flow control is enabled and CTS is set TRUE,* then the Tx interrupt is enabled.* * RETURNS: N/A*/LOCAL void ns16550TxStartup    (    NS16550_CHAN * pChan 	/* pointer to channel */    )    {    char mask;    if (pChan->channelMode == SIO_MODE_INT)	{	if (pChan->options & CLOCAL)		{		/* No modem control */		pChan->ier |= TxFIFO_BIT;#if X86_16550		X86_REG_OUT(IER,pChan,pChan->ier);#else 		REG(IER,pChan) = pChan->ier; #endif		}	else		{#if X86_16550		mask = X86_REG_IN(MSR, pChan) & MSR_CTS;#else		mask = REG(MSR, pChan) & MSR_CTS;#endif   		/* if the CTS is asserted enable Tx interrupt */   		if (mask & MSR_CTS)			pChan->ier |= TxFIFO_BIT;    /* enable Tx interrupt */		else           		pChan->ier &= (~TxFIFO_BIT); /* disable Tx interrupt */#if X86_16550		X86_REG_OUT(IER,pChan,pChan->ier);#else		REG(IER, pChan) = pChan->ier; #endif		}	}    }/******************************************************************************** ns16550PollOutput - output a character in polled mode.** RETURNS: OK if a character arrived, EIO on device error, EAGAIN* if the output buffer if full.*/LOCAL int ns16550PollOutput    (    NS16550_CHAN *  pChan,	/* pointer to channel */    char            outChar	/* char to send */    )    {#if X86_16550	char pollStatus = X86_REG_IN(LSR,pChan);	char msr = X86_REG_IN(MSR,pChan);#else    char pollStatus = REG(LSR, pChan);    char msr = REG(MSR, pChan);#endif    /* is the transmitter ready to accept a character? */    if ((pollStatus & LSR_THRE) == 0x00)        return (EAGAIN);    if (!(pChan->options & CLOCAL))	 /* modem flow control ? */    	{    	if (msr & MSR_CTS)#if X86_16550			X86_REG_OUT(THR,pChan,outChar);#else    		REG(THR, pChan) = outChar;#endif	else		return (EAGAIN);	}    else#if X86_16550		X86_REG_OUT(THR,pChan,outChar);#else    	REG(THR, pChan) = outChar;       /* transmit character */#endif    return (OK);    }/******************************************************************************** ns16550PollInput - poll the device for input.** RETURNS: OK if a character arrived, EIO on device error, EAGAIN* if the input buffer if empty.*/LOCAL int ns16550PollInput    (    NS16550_CHAN *  pChan,	/* pointer to channel */    char *          pChar 	/* pointer to char */    )    {#if X86_16550	char pollStatus = X86_REG_IN(LSR,pChan);#else    char pollStatus = REG(LSR, pChan);#endif    if ((pollStatus & LSR_DR) == 0x00)        return (EAGAIN);    /* got a character */#if X86_16550	*pChar = X86_REG_IN(RBR,pChan);#else    *pChar = REG(RBR, pChan);#endif    return (OK);    }/******************************************************************************** ns16550CallbackInstall - install ISR callbacks to get/put chars.** This routine installs the callback functions for the driver** RETURNS: OK on success or ENOSYS on unsupported callback type.*/LOCAL int ns16550CallbackInstall    (    SIO_CHAN *  pSioChan,	/* pointer to device to control */    int         callbackType,	/* callback type(tx or receive) */    STATUS      (*callback)(),	/* pointer to callback function */    void *      callbackArg	/* callback function argument */    )    {    NS16550_CHAN * pChan = (NS16550_CHAN *)pSioChan;    switch (callbackType)        {        case SIO_CALLBACK_GET_TX_CHAR:            pChan->getTxChar    = callback;            pChan->getTxArg     = callbackArg;            return (OK);        case SIO_CALLBACK_PUT_RCV_CHAR:            pChan->putRcvChar   = callback;            pChan->putRcvArg    = callbackArg;            return (OK);        default:            return (ENOSYS);        }    }

⌨️ 快捷键说明

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