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

📄 ns16550sio.c

📁 Vxworks的bsp软件开发包(基于wrPpmc74xx)
💻 C
📖 第 1 页 / 共 2 页
字号:
            }           }    else        {         /* disable all ns16550 interrupts */        pChan->regs->IER = 0;        }    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    )    {    char           outChar;    if ((*pChan->getTxChar) (pChan->getTxArg, &outChar) != ERROR)        {        pChan->regs->THR = outChar;        }    else        {        pChan->ier &= (~TxFIFO_BIT);    /* indicates to disable Tx Int */        pChan->regs->IER = pChan->ier;         }    }/********************************************************************************* ns16550IntRd - handle a receiver interrupt ** This routine handles read interrupts from the UART.** RETURNS: N/A**/void ns16550IntRd    (    NS16550_CHAN *pChan    )    {    char   inchar;    /* read character from Receive Holding Reg. */    inchar = pChan->regs->RBR;    (*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    )    {    FAST volatile char        intStatus;    vxMsrSet(vxMsrGet() | 0x2000);    /* read the Interrrupt Status Register (Int. Ident.) */    intStatus = pChan->regs->IIR & 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.     */    pChan->regs->IER = 0;  /* disable interrupt */    switch (intStatus)        {        case IIR_RLS:            /* overrun,parity error and break interrupt */            intStatus = pChan->regs->LSR; /* read LSR to reset interrupt */            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)                    {                    pChan->regs->THR = outChar; /* char to Transmit Holding Reg */                    }                else                    {                    pChan->ier &= (~TxFIFO_BIT); /* indicates to disable Tx Int */                    }            }            break;        case IIR_MSTAT: /* modem status register */            {                char msr;                msr = pChan->regs->MSR;                /* 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;        }    pChan->regs->IER = pChan->ier; /* enable interrupts accordingly */    }/********************************************************************************* 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    )    {    char mask;    if (pChan->channelMode == SIO_MODE_INT)        {        if (pChan->options & CLOCAL)            {        /* No modem control */            pChan->ier |= TxFIFO_BIT;            pChan->regs->IER = pChan->ier;            }        else            {            mask = pChan->regs->MSR & MSR_CTS;             /* 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 */            pChan->regs->IER = pChan->ier;             }        }    }/******************************************************************************** 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,    char outChar    )    {    char    pollStatus,msr;    pollStatus = pChan->regs->LSR;    msr = pChan->regs->MSR;    /* 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)            {            pChan->regs->THR = outChar;            }        else            {            return EAGAIN;            }        }    else        {        pChan->regs->THR = outChar;        }    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,    char *pChar    )    {    char pollStatus;    pollStatus = pChan->regs->LSR;    if ((pollStatus & LSR_DR) == 0x00)        return(EAGAIN);    /* got a character */    *pChar = pChan->regs->RBR;    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 + -