Example #1
0
/**
*
* This function receives a buffer that has been previously specified by setting
* up the instance variables of the instance. This function is designed to be
* an internal function for the XUartLite component such that it may be called
* from a shell function that sets up the buffer or from an interrupt handler.
*
* This function will attempt to receive a specified number of bytes of data
* from the UART and store it into the specified buffer. This function is
* designed for either polled or interrupt driven modes. It is non-blocking
* such that it will return if there is no data has already received by the
* UART.
*
* In a polled mode, this function will only receive as much data as the UART
* can buffer, either in the receiver or in the FIFO if present and enabled.
* The application may need to call it repeatedly to receive a buffer. Polled
* mode is the default mode of operation for the driver.
*
* In interrupt mode, this function will start receiving and then the interrupt
* handler of the driver will continue until the buffer has been received. A
* callback function, as specified by the application, will be called to indicate
* the completion of receiving the buffer or when any receive errors or timeouts
* occur. Interrupt mode must be enabled using the SetOptions function.
*
* @param    InstancePtr is a pointer to the XUartLite instance to be worked on.
*
* @return
*
* The number of bytes received.
*
* @note
*
* None.
*
*****************************************************************************/
unsigned int
XUartLite_ReceiveBuffer(XUartLite * InstancePtr)
{
	u8 StatusRegister;
	unsigned int ReceivedCount = 0;

	/* Loop until there is not more data buffered by the UART or the specified
	 * number of bytes is received
	 */

	while (ReceivedCount < InstancePtr->ReceiveBuffer.RemainingBytes) {
		/* Read the Status Register to determine if there is any data in
		 * the receiver/FIFO
		 */
		StatusRegister =
		    XUartLite_mGetStatusReg(InstancePtr->RegBaseAddress);

		/* If there is data ready to be removed, then put the next byte
		 * received into the specified buffer and update the stats to reflect
		 * any receive errors for the byte
		 */
		if (StatusRegister & XUL_SR_RX_FIFO_VALID_DATA) {
			InstancePtr->ReceiveBuffer.
			    NextBytePtr[ReceivedCount++] =
			    XIo_In32(InstancePtr->RegBaseAddress +
				     XUL_RX_FIFO_OFFSET);

			XUartLite_mUpdateStats(InstancePtr, StatusRegister);
		}

		/* There's no more data buffered, so exit such that this function does
		 * not block waiting for data
		 */
		else {
			break;
		}
	}

	/* Update the receive buffer to reflect the number of bytes that was
	 * received
	 */
	InstancePtr->ReceiveBuffer.NextBytePtr += ReceivedCount;
	InstancePtr->ReceiveBuffer.RemainingBytes -= ReceivedCount;

	/*
	 * Increment associated counters in the statistics
	 */
	InstancePtr->Stats.CharactersReceived += ReceivedCount;

	return ReceivedCount;
}
/**
*
* This function receives a buffer that has been previously specified by setting
* up the instance variables of the instance. This function is designed to be
* an internal function for the XUartLite component such that it may be called
* from a shell function that sets up the buffer or from an interrupt handler.
*
* This function will attempt to receive a specified number of bytes of data
* from the UART and store it into the specified buffer. This function is
* designed for either polled or interrupt driven modes. It is non-blocking
* such that it will return if there is no data has already received by the
* UART.
*
* In a polled mode, this function will only receive as much data as the UART
* can buffer, either in the receiver or in the FIFO if present and enabled.
* The application may need to call it repeatedly to receive a buffer. Polled
* mode is the default mode of operation for the driver.
*
* In interrupt mode, this function will start receiving and then the interrupt
* handler of the driver will continue until the buffer has been received. A
* callback function, as specified by the application, will be called to indicate
* the completion of receiving the buffer or when any receive errors or timeouts
* occur. Interrupt mode must be enabled using the SetOptions function.
*
* @param    InstancePtr is a pointer to the XUartLite instance to be worked on.
*
* @return
*
* The number of bytes received.
*
* @note
*
* None.
*
*****************************************************************************/
unsigned int XUartLite_ReceiveBuffer(XUartLite *InstancePtr)
{
    Xuint8 StatusRegister;
    unsigned int ReceivedCount = 0;

    /* Loop until there is not more data buffered by the UART or the specified
     * number of bytes is received
     */

    while (ReceivedCount < InstancePtr->ReceiveBuffer.RemainingBytes)
    {
        /* Read the Status Register to determine if there is any data in
         * the receiver/FIFO
         */
        StatusRegister = XUartLite_mGetStatusReg(InstancePtr->RegBaseAddress);

        /* If there is data ready to be removed, then put the next byte
         * received into the specified buffer and update the stats to reflect
         * any receive errors for the byte
         */
        if (StatusRegister & XUL_SR_RX_FIFO_VALID_DATA)
        {
            InstancePtr->ReceiveBuffer.NextBytePtr[ReceivedCount++] =
                XIo_In32(InstancePtr->RegBaseAddress + XUL_RX_FIFO_OFFSET);

            XUartLite_mUpdateStats(InstancePtr, StatusRegister);
        }

        /* There's no more data buffered, so exit such that this function does
         * not block waiting for data
         */
        else
        {
            break;
        }
    }

    /* Enter a critical region by disabling all the UART interrupts to allow
     * this call to stop a previous operation that may be interrupt driven
     */
    StatusRegister = XUartLite_mGetStatusReg(InstancePtr->RegBaseAddress);
    XIo_Out32(InstancePtr->RegBaseAddress + XUL_CONTROL_REG_OFFSET, 0);

    /* Update the receive buffer to reflect the number of bytes that was
     * received
     */
    InstancePtr->ReceiveBuffer.NextBytePtr += ReceivedCount;
    InstancePtr->ReceiveBuffer.RemainingBytes -= ReceivedCount;

    /*
     * Increment associated counters in the statistics
     */
    InstancePtr->Stats.CharactersReceived += ReceivedCount;

    /* Restore the interrupt enable register to it's previous value such
     * that the critical region is exited
     */
    StatusRegister &= XUL_CR_ENABLE_INTR;
    XIo_Out32(InstancePtr->RegBaseAddress + XUL_CONTROL_REG_OFFSET, StatusRegister);

    return ReceivedCount;
}