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

📄 at91sio.c

📁 ARM7开发板 AT91EB01 BSP源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
	     * in sioLib.h). Return OK or ENOSYS if this command is not
	     * implemented.  Note: if this command is unimplemented, it
	     * will be assumed that the driver options are CREAD | CS8
	     * (e.g., eight data bits, one stop bit, no parity, ints enabled).
	     */

	default:
	    status = ENOSYS;
	}

    return status;

    }

/*******************************************************************************
*
* at91SioInt - handle an interrupt
*
* This routine handles interrupts from the USART.
*
* RETURNS: N/A
*/

void at91SioInt
    (
    AT91_SIO_CHAN *	pChan   /* ptr to AT91_SIO_CHAN describing this chan */
    )
    {
#ifndef AT91_USE_PDC
    UINT32	ch;		/* Possible char to be in/output */
#endif
    UINT32	status;		/* Status from USART */
    int		gotOne;
#ifdef AT91_USE_PDC
    UINT8 *	ptr;
    int		count;
#endif


    /* read status register */

    AT91_USART_REG_READ (pChan, AT91_US_CSR, status);

    if (status & (AT91_US_RXBRK | AT91_US_OVRE | AT91_US_FRAME | AT91_US_PARE))
	{
    	at91SioIntErrs++;

	/* reset error status */

	AT91_USART_REG_WRITE (pChan, AT91_US_CR, AT91_US_RSTSTA);
	}

#ifndef AT91_USE_PDC
    if (status & AT91_US_RXRDY)		   /* data? */
	{
	AT91_USART_REG_READ (pChan, AT91_US_RHR, ch);	   /* read character */
	(*pChan->putRcvChar) (pChan->putRcvArg, (char)ch); /* pass it on */
	}
#else /* AT91_USE_PDC */
    if (status & AT91_US_TIMEOUT)
	{
	/* restart timeout */

	AT91_USART_REG_WRITE (pChan, AT91_US_CR, AT91_US_STTTO);
	}

    /*
     * Read the Receiver Peripheral Data Controller count. It was originally
     * set to the size of the receive buffer.
     */

    AT91_USART_REG_READ (pChan, AT91_US_RCR, count);

    while (count < AT91_RXBUFF_SIZE)
    	{
	/*
	 * then characters have been received into the buffer - setup
	 * PDC to use the other swing-buffer whilst we deal with this
	 * one.
	 */

	AT91_USART_REG_WRITE (pChan, AT91_US_RCR, 0);	/* stop Rx PDC */
	if (pChan->buffInUse == 0)
	    {
	    ptr = &pChan->rxBuffA[0];	/* ptr to beginning of Rx buffer */

	    /* reset ptr to beginning of new buffer  */

	    AT91_USART_REG_WRITE (pChan, AT91_US_RPR,
	    					(UINT32)(&pChan->rxBuffB[0]));
	    pChan->buffInUse = 1;
	    }
	else
	    {
	    ptr = &pChan->rxBuffB[0];	/* ptr to beginning of Rx buffer */
	    AT91_USART_REG_WRITE (pChan, AT91_US_RPR,
	    					(UINT32)(&pChan->rxBuffA[0]));
	    pChan->buffInUse = 0;
	    }

	/* reset count to size of buffer and restart timeout  */

	AT91_USART_REG_WRITE (pChan, AT91_US_RCR, AT91_RXBUFF_SIZE);
	AT91_USART_REG_WRITE (pChan, AT91_US_CR, AT91_US_STTTO);

	/* read chars from buffer and pass on to installed callback rtn */

	while (count < AT91_RXBUFF_SIZE)
	    {
	    /* while there are chars in buffer we have not yet passed on */

	    (*pChan->putRcvChar) (pChan->putRcvArg, *ptr++); /* pass it on */
	    count++;
	    }


	/* reread PDC Rx count */

	AT91_USART_REG_READ (pChan, AT91_US_RCR, count);

	} /* endwhile */

#endif /* AT91_USE_PDC */


#ifndef AT91_USE_PDC
    /*
     * There is a THR and the Tx Shift Register, so we may be able to push
     * two characters into the USART.
     */

    if (status & AT91_US_TXRDY)		/* if THR is empty */
	{
	do
	    {
	    gotOne = (*pChan->getTxChar) (pChan->getTxArg, &ch) != ERROR;
	    if (gotOne)
		AT91_USART_REG_WRITE(pChan, AT91_US_THR, ch);  /* tx char */

	    AT91_USART_REG_READ (pChan, AT91_US_CSR, status);	/* get status */
	    }
	while (gotOne && (status & AT91_US_TXRDY));	/* while not full */

	if (!gotOne)
	    {
	    /* no more chars to send - disable transmitter interrupts */

	    AT91_USART_REG_WRITE (pChan, AT91_US_IDR, AT91_US_TXEMPTY);
	    }
	}
#else /* AT91_USE_PDC */
    AT91_USART_REG_READ (pChan, AT91_US_IMR, status);	   /* read int mask */

    if (status & AT91_US_ENDTX)		/* ENDTX is enabled => Tx is required */
	{
	AT91_USART_REG_READ (pChan, AT91_US_TCR, count);   /* read PDC count */

	if (count == 0)
	    {
	    /* then transmission is finished */

	    ptr = &pChan->txBuff[0];	/* ptr to beginning of Tx buffer */

	    do
		{
		gotOne = (*pChan->getTxChar) (pChan->getTxArg, ptr++) != ERROR;
		if (gotOne)
		    count++;
		}
	    while (gotOne && (count < AT91_TXBUFF_SIZE));

	    /* reset ptr to beginning of buffer and count to size of buffer */

	    AT91_USART_REG_WRITE (pChan, AT91_US_TPR,
	    					(UINT32)(&pChan->txBuff[0]));
	    AT91_USART_REG_WRITE (pChan, AT91_US_TCR, count);

	    if (count == 0)
		{
	    	/* then nothing more to transmit, so disable ENDTX interrupt */

		AT91_USART_REG_WRITE (pChan, AT91_US_IDR, AT91_US_ENDTX);
		}

	    } /* endif count was zero */

	} /* endif ENDTX was enabled */
#endif /* AT91_USE_PDC */
    }

/*******************************************************************************
*
* at91SioTxStartup - transmitter startup routine
*
* Call interrupt level char output routine and enable interrupt
*
* RETURNS: OK on success, ENOSYS if the device is polled-only, or
* EIO on hardware error.
*/

LOCAL int at91SioTxStartup
    (
    SIO_CHAN *	pSioChan	/* ptr to SIO_CHAN describing this channel */
    )
    {
    AT91_SIO_CHAN * pChan = (AT91_SIO_CHAN *)pSioChan;

    if (pChan->channelMode == SIO_MODE_INT)
	{
	/* Enable Transmitter interrupts */

#ifndef AT91_USE_PDC
	AT91_USART_REG_WRITE (pChan, AT91_US_IER, AT91_US_TXEMPTY);
#else
	AT91_USART_REG_WRITE (pChan, AT91_US_IER, AT91_US_ENDTX);
#endif
	return OK;
	}
    else
	return ENOSYS;
    }

/******************************************************************************
*
* at91SioPollOutput - output a character in polled mode.
*
* RETURNS: OK if a character arrived, EIO on device error, EAGAIN
* if the output buffer is full, ENOSYS if the device is interrupt-only.
*/

LOCAL int at91SioPollOutput
    (
    SIO_CHAN *	pSioChan,	/* ptr to SIO_CHAN describing this channel */
    char	outChar 	/* char to output */
    )
    {
    AT91_SIO_CHAN * pChan = (AT91_SIO_CHAN *)pSioChan;
    UINT32 pollStatus;

    AT91_USART_REG_READ (pChan, AT91_US_CSR, pollStatus);

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

    if ((pollStatus & AT91_US_TXRDY) == 0)
	return EAGAIN;


    /* write out the character */

    AT91_USART_REG_WRITE (pChan, AT91_US_THR, outChar);	/* transmit character */

    return OK;
    }

/******************************************************************************
*
* at91SioPollInput - poll the device for input.
*
* RETURNS: OK if a character arrived, EIO on device error, EAGAIN
* if the input buffer is empty, ENOSYS if the device is interrupt-only.
*/

LOCAL int at91SioPollInput
    (
    SIO_CHAN *	pSioChan,	/* ptr to SIO_CHAN describing this channel */
    char *	thisChar	/* pointer to where to return character */
    )
    {
    AT91_SIO_CHAN * pChan = (AT91_SIO_CHAN *)pSioChan;
    UINT32 pollStatus;

    AT91_USART_REG_READ (pChan, AT91_US_CSR, pollStatus);

    if ((pollStatus & AT91_US_RXRDY) == 0)
	return EAGAIN;


    /* got a character */

    AT91_USART_REG_READ (pChan, AT91_US_RHR, *thisChar);

    return OK;
    }

/******************************************************************************
*
* at91SioCallbackInstall - install ISR callbacks to get/put chars.
*
* This routine installs interrupt callbacks for transmitting characters
* and receiving characters.
*
* RETURNS: OK on success, or ENOSYS for an unsupported callback type.
*
*/

LOCAL int at91SioCallbackInstall
    (
    SIO_CHAN *	pSioChan,	/* ptr to SIO_CHAN describing this channel */
    int		callbackType,	/* type of callback */
    STATUS	(*callback)(),	/* callback */
    void *	callbackArg	/* parameter to callback */

    )
    {
    AT91_SIO_CHAN * pChan = (AT91_SIO_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;
	}
    }

#endif /* INCLUDE_SERIAL */

⌨️ 快捷键说明

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