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

📄 au1500sio.c

📁 au1500开发的应用程序
💻 C
📖 第 1 页 / 共 2 页
字号:
    oldlevel = intLock ();

    if (newMode == SIO_MODE_INT)
	{
        /* Enable appropriate interrupts */
		
        if (pChan->options & CLOCAL) 
            {
            regs->uart_inten = pChan->ier | UART_INTEN_TIE | UART_INTEN_RIE;
            }
        else  
            {
            mask = regs->uart_mdmctrl & UART_MDMSTAT_CT;

            /* if the CTS is asserted enable Tx interrupt */

            if (mask & UART_MDMSTAT_CT)
                pChan->ier |= UART_INTEN_TIE; /* enable Tx interrupt */
            else
                pChan->ier &= ~UART_INTEN_TIE; /* disable Tx interrupt */

            regs->uart_inten = pChan->ier;
            }	
	}
    else
        {
        /* disable all interrupts */ 

        regs->uart_inten = 0;
	}

    pChan->channelMode = newMode;

    intUnlock (oldlevel);

    return (OK);
    }

/*******************************************************************************
*
* auSioIoctl - 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 auSioIoctl
    (
    AUSIO_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 < AU_UART_MIN_RATE || arg > AU_UART_MAX_RATE)
                status = EIO;		/* baud rate out of range */
            else
                status = auSioBaudSet (pChan, arg);
            break;

        case SIO_BAUD_GET:
            *(int *)arg = pChan->baudRate;
            break; 

        case SIO_MODE_SET:
            status = (auSioModeSet (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 = (auSioOptsSet (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 = auSioHup (pChan);
            break;
	
        case SIO_OPEN:
            /* check if hupcl option is enabled */
    	    if (pChan->options & HUPCL) 
	    	status = auSioOpen (pChan);
            break;

        default:
            status = ENOSYS;
	}
    return (status);
    }

/*******************************************************************************
*
* auSioIntWr - 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 auSioIntWr 
    (
    AUSIO_CHAN * pChan		/* pointer to channel */	
    )
    {
    char           outChar;
    AU1000_UART *regs = (AU1000_UART *)pChan->regs;

    /* send as many characters as possible */

    while (regs->uart_linestat & (UART_LINESTAT_TE | UART_LINESTAT_TT))
        {
        if ((*pChan->getTxChar) (pChan->getTxArg, &outChar) != ERROR)
            {
            /* Write Buffer errata */
            __asm("sync");
            regs->uart_txdata = outChar;
            }
        else
            {
            /* FIX!!! could disable int even if some chars sent! */
            pChan->ier &= ~UART_INTEN_TIE; /* disable Tx Int */
            regs->uart_inten = pChan->ier;
            break;
            }
        }
    }

/*******************************************************************************
*
* auSioIntRd - handle a receiver interrupt 
*
* This routine handles read interrupts from the UART.
*
* RETURNS: N/A
*
*/

LOCAL void auSioIntRd 
    (
    AUSIO_CHAN * pChan	/* pointer to channel */
    )
    {
    char   inchar;
    AU1000_UART *regs = (AU1000_UART *)pChan->regs;

    /* read all characters from fifo */

    while (regs->uart_linestat & UART_LINESTAT_DR)
        {
        inchar = regs->uart_rxdata;

        (*pChan->putRcvChar) (pChan->putRcvArg, inchar);
        }
    }

/********************************************************************************
*
* auSioInt - 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 auSioInt 
    (
    AUSIO_CHAN * pChan	/* pointer to channel */
    )
    {
    volatile char intStatus;
    AU1000_UART *regs = (AU1000_UART *)pChan->regs;

    /* read the Interrrupt Status Register (Int. Ident.) */

    intStatus = regs->uart_intcause & UART_INTCAUSE_IID;

    switch (intStatus)
        {
        case UART_INTCAUSE_IID_RLS:
            /* overrun,parity error and break interrupt */
            /* must read to clear condition else rx stops */
            intStatus = regs->uart_linestat;
            break;

        case UART_INTCAUSE_IID_RDA:          /* received data available */
        case UART_INTCAUSE_IID_CTO: 
            auSioIntRd (pChan);
            break;

        case UART_INTCAUSE_IID_TBA:     /* transmitter holding register ready */
            auSioIntWr (pChan);
            break;

        case UART_INTCAUSE_IID_MS:           /* modem status register */
        {
        char	msr;

        msr = regs->uart_mdmstat;

        /* if CTS is asserted by modem, enable tx interrupt */

        if ((msr & UART_MDMSTAT_CT) && (msr & UART_MDMSTAT_DC)) 
            pChan->ier |= UART_INTEN_TIE;
        else
            pChan->ier &= ~UART_INTEN_TIE; 
        }
        break;

        default:
            break;
        }

    regs->uart_inten = pChan->ier;
    }

/*******************************************************************************
*
* auSioTxStartup - 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 auSioTxStartup
    (
    AUSIO_CHAN * pChan 	/* pointer to channel */
    )
    {
    char mask;
    AU1000_UART *regs = (AU1000_UART *)pChan->regs;

    if (pChan->channelMode == SIO_MODE_INT)
	{
	if (pChan->options & CLOCAL)
            {
            /* No modem control */

            pChan->ier |= UART_INTEN_TIE;
            regs->uart_inten = pChan->ier;
            }
	else
            {
            mask = regs->uart_mdmstat & UART_MDMSTAT_CT;

            /* if the CTS is asserted enable Tx interrupt */

            if (mask & UART_MDMSTAT_CT)
                pChan->ier |= UART_INTEN_TIE;    /* enable Tx interrupt */
            else
       		pChan->ier &= ~UART_INTEN_TIE; /* disable Tx interrupt */

            regs->uart_inten = pChan->ier;
            }
	}
    }

/******************************************************************************
*
* auSioPollOutput - 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 auSioPollOutput
    (
    AUSIO_CHAN *  pChan,	/* pointer to channel */
    char            outChar	/* char to send */
    )
    {
    char pollStatus;
    char msr;
    AU1000_UART *regs = (AU1000_UART *)pChan->regs;

    pollStatus = regs->uart_linestat;
    msr = regs->uart_mdmstat;

    /* is the transmitter ready to accept a character? */

    if ((pollStatus & UART_LINESTAT_TE) == 0x00)
        return (EAGAIN);

    if (!(pChan->options & CLOCAL))	 /* modem flow control ? */
    	{
    	if (msr & UART_MDMSTAT_CT)
            {
            /* Write Buffer errata */
            __asm("sync");
            regs->uart_txdata = outChar;
            }
        else
            return (EAGAIN);
        }
    else
        regs->uart_txdata = outChar;

    return (OK);
    }

/******************************************************************************
*
* auSioPollInput - poll the device for input.
*
* RETURNS: OK if a character arrived, EIO on device error, EAGAIN
* if the input buffer if empty.
*/

LOCAL int auSioPollInput
    (
    AUSIO_CHAN *  pChan,	/* pointer to channel */
    char *          pChar 	/* pointer to char */
    )
    {

    char pollStatus;
    AU1000_UART *regs = (AU1000_UART *)pChan->regs;

    pollStatus = regs->uart_linestat;

    if ((pollStatus & UART_LINESTAT_DR) == 0x00)
        return (EAGAIN);

    /* got a character */

    *pChar = regs->uart_rxdata;

    return (OK);
    }

/******************************************************************************
*
* auSioCallbackInstall - 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 auSioCallbackInstall
    (
    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 */
    )
    {
    AUSIO_CHAN * pChan = (AUSIO_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 + -