Exemple #1
0
/**
*
* This function handles the interrupt when data has been sent, the transmit
* FIFO is empty (transmitter holding register).
*
* @param	InstancePtr is a pointer to the XUartPs instance
* @param	IsrStatus is the register value for channel status register
*
* @return	None.
*
* @note		None.
*
*****************************************************************************/
static void SendDataHandler(XUartPs *InstancePtr, u32 IsrStatus)
{

	/*
	 * If there are not bytes to be sent from the specified buffer then disable
	 * the transmit interrupt so it will stop interrupting as it interrupts
	 * any time the FIFO is empty
	 */
	if (InstancePtr->SendBuffer.RemainingBytes == (u32)0) {
		XUartPs_WriteReg(InstancePtr->Config.BaseAddress,
				XUARTPS_IDR_OFFSET,
				((u32)XUARTPS_IXR_TXEMPTY | (u32)XUARTPS_IXR_TXFULL));

		/* Call the application handler to indicate the sending is done */
		InstancePtr->Handler(InstancePtr->CallBackRef,
					XUARTPS_EVENT_SENT_DATA,
					InstancePtr->SendBuffer.RequestedBytes -
					InstancePtr->SendBuffer.RemainingBytes);
	}

	/*
	 * If TX FIFO is empty, send more.
	 */
	else if((IsrStatus & ((u32)XUARTPS_IXR_TXEMPTY)) != (u32)0) {
		(void)XUartPs_SendBuffer(InstancePtr);
	}
	else {
		/* Else with dummy entry for MISRA-C Compliance.*/
		;
	}
}
Exemple #2
0
/**
*
* This functions sends the specified buffer using the device in either
* polled or interrupt driven mode. This function is non-blocking, if the device
* is busy sending data, it will return and indicate zero bytes were sent.
* Otherwise, it fills the TX FIFO as much as it can, and return the number of
* bytes sent.
*
* In a polled mode, this function will only send as much data as TX FIFO can
* buffer. The application may need to call it repeatedly to send the entire
* buffer.
*
* In interrupt mode, this function will start sending the specified buffer,
* then the interrupt handler will continue sending data until the entire
* buffer has been sent. A callback function, as specified by the application,
* will be called to indicate the completion of sending.
*
* @param	InstancePtr is a pointer to the XUartPs instance.
* @param	BufferPtr is pointer to a buffer of data to be sent.
* @param  	NumBytes contains the number of bytes to be sent. A value of
*		zero will stop a previous send operation that is in progress
*		in interrupt mode. Any data that was already put into the
*		transmit FIFO will be sent.
*
* @return	The number of bytes actually sent.
*
* @note
*
* The number of bytes is not asserted so that this function may be called with
* a value of zero to stop an operation that is already in progress.
* <br><br>
*
*****************************************************************************/
u32 XUartPs_Send(XUartPs *InstancePtr, u8 *BufferPtr,
			   u32 NumBytes)
{
	u32 BytesSent;

	/*
	 * Asserts validate the input arguments
	 */
	Xil_AssertNonvoid(InstancePtr != NULL);
	Xil_AssertNonvoid(BufferPtr != NULL);
	Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);

	/*
	 * Disable the UART transmit interrupts to allow this call to stop a
	 * previous operation that may be interrupt driven.
	 */
	XUartPs_WriteReg(InstancePtr->Config.BaseAddress, XUARTPS_IDR_OFFSET,
					  (XUARTPS_IXR_TXEMPTY | XUARTPS_IXR_TXFULL));

	/*
	 * Setup the buffer parameters
	 */
	InstancePtr->SendBuffer.RequestedBytes = NumBytes;
	InstancePtr->SendBuffer.RemainingBytes = NumBytes;
	InstancePtr->SendBuffer.NextBytePtr = BufferPtr;

	/*
	 * Transmit interrupts will be enabled in XUartPs_SendBuffer(), after
	 * filling the TX FIFO.
	 */
	BytesSent = XUartPs_SendBuffer(InstancePtr);

	return BytesSent;
}
Exemple #3
0
void prvUART_Handler( void *pvNotUsed )
{
extern unsigned int XUartPs_SendBuffer( XUartPs *InstancePtr );
uint32_t ulActiveInterrupts, ulChannelStatusRegister;
BaseType_t xHigherPriorityTaskWoken = pdFALSE;
char cChar;

	configASSERT( pvNotUsed == &xUARTInstance );

	/* Remove compile warnings if configASSERT() is not defined. */
	( void ) pvNotUsed;

	/* Read the interrupt ID register to see which interrupt is active. */
	ulActiveInterrupts = XUartPs_ReadReg(XPAR_PS7_UART_1_BASEADDR,  XUARTPS_IMR_OFFSET);
	ulActiveInterrupts &= XUartPs_ReadReg(XPAR_PS7_UART_1_BASEADDR,  XUARTPS_ISR_OFFSET);

	/* Are any receive events of interest active? */
	if( ( ulActiveInterrupts & serRECEIVE_INTERRUPT_MASK ) != 0 )
	{
		/* Read the Channel Status Register to determine if there is any data in
		the RX FIFO. */
		ulChannelStatusRegister = XUartPs_ReadReg( XPAR_PS7_UART_1_BASEADDR, XUARTPS_SR_OFFSET );

		/* Move data from the Rx FIFO to the Rx queue.  NOTE THE COMMENTS AT THE
		TOP OF THIS FILE ABOUT USING QUEUES FOR THIS PURPSOE. */
		while( ( ulChannelStatusRegister & XUARTPS_SR_RXEMPTY ) == 0 )
		{
			cChar =	XUartPs_ReadReg( XPAR_PS7_UART_1_BASEADDR, XUARTPS_FIFO_OFFSET );

			/* If writing to the queue unblocks a task, and the unblocked task
			has a priority above the currently running task (the task that this
			interrupt interrupted), then xHigherPriorityTaskWoken will be set
			to pdTRUE inside the xQueueSendFromISR() function.
			xHigherPriorityTaskWoken is then passed to portYIELD_FROM_ISR() at
			the end of this interrupt handler to request a context switch so the
			interrupt returns directly to the (higher priority) unblocked
			task. */
			xQueueSendFromISR( xRxQueue, &cChar, &xHigherPriorityTaskWoken );
			ulChannelStatusRegister = XUartPs_ReadReg( XPAR_PS7_UART_1_BASEADDR, XUARTPS_SR_OFFSET );
		}
	}

	/* Are any transmit events of interest active? */
	if( ( ulActiveInterrupts & serTRANSMIT_IINTERRUPT_MASK ) != 0 )
	{
		if( xUARTInstance.SendBuffer.RemainingBytes == 0 )
		{
			/* Give back the semaphore to indicate that the tranmission is
			complete.  If giving the semaphore unblocks a task, and the
			unblocked task has a priority above the currently running task (the
			task that this interrupt interrupted), then xHigherPriorityTaskWoken
			will be set	to pdTRUE inside the xSemaphoreGiveFromISR() function.
			xHigherPriorityTaskWoken is then passed to portYIELD_FROM_ISR() at
			the end of this interrupt handler to request a context switch so the
			interrupt returns directly to the (higher priority) unblocked
			task. */
			xSemaphoreGiveFromISR( xTxCompleteSemaphore, &xHigherPriorityTaskWoken );

			/* No more data to transmit. */
			XUartPs_WriteReg( XPAR_PS7_UART_1_BASEADDR, XUARTPS_IDR_OFFSET, XUARTPS_IXR_TXEMPTY );
		}
		else
		{
			/* More data to send. */
			XUartPs_SendBuffer( &xUARTInstance );
		}
	}

	/* portYIELD_FROM_ISR() will request a context switch if executing this
	interrupt handler caused a task to leave the blocked state, and the task
	that left the blocked state has a higher priority than the currently running
	task (the task this interrupt interrupted).  See the comment above the calls
	to xSemaphoreGiveFromISR() and xQueueSendFromISR() within this function. */
	portYIELD_FROM_ISR( xHigherPriorityTaskWoken );

	/* Clear the interrupt status. */
	XUartPs_WriteReg( XPAR_PS7_UART_1_BASEADDR, XUARTPS_ISR_OFFSET, ulActiveInterrupts );
}