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

📄 st16c2550sio.c

📁 sbc7410的vxworksbsp
💻 C
📖 第 1 页 / 共 2 页
字号:
    oldlevel = intLock ();    if (newMode == SIO_MODE_INT)    {        /* Enable appropriate interrupts */        if (pChan->options & CLOCAL)            REG(IER, pChan) = pChan->ier | RxFIFO_BIT | TxFIFO_BIT;        else        {            mask = REG(MSR, pChan) & 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 */            REG(IER, pChan) = pChan->ier;        }    }    else    {        /* disable all st16c2550 interrupts */        REG(IER, pChan) = 0;    }    pChan->channelMode = newMode;    intUnlock (oldlevel);    return (OK);}/********************************************************************************* st16c2550Ioctl - 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 st16c2550Ioctl    (    ST16C2550_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 < ST16C2550_MIN_RATE || arg > ST16C2550_MAX_RATE)                status = EIO;       /* baud rate out of range */            else                status = st16c2550BaudSet (pChan, arg);            break;        case SIO_BAUD_GET:            *(int *)arg = pChan->baudRate;            break;        case SIO_MODE_SET:            status = (st16c2550ModeSet (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 = (st16c2550OptsSet (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 = st16c2550Hup (pChan);            break;        case SIO_OPEN:            /* check if hupcl option is enabled */            if (pChan->options & HUPCL)                status = st16c2550Open (pChan);            break;        default:            status = ENOSYS;    }    return (status);}/********************************************************************************* st16c2550IntWr - 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 st16c2550IntWr    (    ST16C2550_CHAN * pChan      /* pointer to channel */    ){    char           outChar;    if ((*pChan->getTxChar) (pChan->getTxArg, &outChar) != ERROR)        REG(THR,pChan) = outChar;   /* write char to Transmit Holding Reg */    else    {        pChan->ier &= (~TxFIFO_BIT);    /* indicates to disable Tx Int */        REG(IER, pChan) = pChan->ier;    }}/********************************************************************************* st16c2550IntRd - handle a receiver interrupt** This routine handles read interrupts from the UART.** RETURNS: N/A**/void st16c2550IntRd    (    ST16C2550_CHAN * pChan  /* pointer to channel */    ){    char   inchar;    /* read character from Receive Holding Reg. */    inchar = REG(RBR, pChan);    (*pChan->putRcvChar) (pChan->putRcvArg, inchar);}/********************************************************************************* st16c2550IntEx - miscellaneous interrupt processing** This routine handles miscellaneous interrupts on the UART.* Not implemented yet.** RETURNS: N/A**/void st16c2550IntEx    (    ST16C2550_CHAN *pChan       /* pointer to channel */    ){    /* Nothing for now... */}/********************************************************************************** st16c2550Int - 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 st16c2550Int    (    ST16C2550_CHAN * pChan  /* pointer to channel */    ){    FAST volatile char        intStatus;    /* read the Interrrupt Status Register (Int. Ident.) */    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 */    switch (intStatus)    {        case IIR_RLS:            /* overrun,parity error and break interrupt */            intStatus = REG(LSR, pChan); /* 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.        */            st16c2550IntRd (pChan);     /* RxChar Avail */            break;        case IIR_THRE:  /* transmitter holding register ready */            {            char outChar;            if ((*pChan->getTxChar) (pChan->getTxArg, &outChar) != ERROR)                REG(THR, pChan) = 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 = REG(MSR, pChan);           /* 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;        }    REG(IER, pChan) = pChan->ier; /* enable interrupts accordingly */}/********************************************************************************* st16c2550TxStartup - 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 st16c2550TxStartup    (    ST16C2550_CHAN * pChan  /* pointer to channel */    ){    char mask;    if (pChan->channelMode == SIO_MODE_INT)    {        if (pChan->options & CLOCAL)        {        /* No modem control */            pChan->ier |= TxFIFO_BIT;            REG(IER,pChan) = pChan->ier;        }        else        {            mask = REG(MSR, pChan) & 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 */            REG(IER, pChan) = pChan->ier;        }    }}/******************************************************************************** st16c2550PollOutput - 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 st16c2550PollOutput    (    ST16C2550_CHAN *  pChan,    /* pointer to channel */    char            outChar /* char to send */    ){    char pollStatus = REG(LSR, pChan);    char msr = REG(MSR, pChan);    /* 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)            REG(THR, pChan) = outChar;        else            return (EAGAIN);    }    else        REG(THR, pChan) = outChar;       /* transmit character */    return (OK);}/******************************************************************************** st16c2550PollInput - poll the device for input.** RETURNS: OK if a character arrived, EIO on device error, EAGAIN* if the input buffer if empty.*/LOCAL int st16c2550PollInput    (    ST16C2550_CHAN *  pChan,    /* pointer to channel */    char *          pChar   /* pointer to char */    ){    char pollStatus = REG(LSR, pChan);    if ((pollStatus & LSR_DR) == 0x00)        return (EAGAIN);    /* got a character */    *pChar = REG(RBR, pChan);    return (OK);}/******************************************************************************** st16c2550CallbackInstall - 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 st16c2550CallbackInstall    (    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 */    ){    ST16C2550_CHAN * pChan = (ST16C2550_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 + -