예제 #1
0
/*
*
* This function sends a buffer that has been previously specified by setting
* up the instance variables of the instance. This function is an internal
* function for the XUartPs driver such that it may be called from a shell
* function that sets up the buffer or from an interrupt handler.
*
* This function sends the specified buffer in either polled or interrupt
* driven modes. This function is non-blocking.
*
* In a polled mode, this function only sends as much data as the TX FIFO
* can buffer. The application may need to call it repeatedly to send the
* entire buffer.
*
* In interrupt mode, this function starts the sending of the buffer, if not
* the entire buffer has been sent, then the interrupt handler continues the
* sending 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
*
* @return	The number of bytes actually sent
*
* @note		None.
*
*****************************************************************************/
u32 XUartPs_SendBuffer(XUartPs *InstancePtr)
{
	u32 SentCount = 0U;
	u32 ImrRegister;

	/*
	 * If the TX FIFO is full, send nothing.
	 * Otherwise put bytes into the TX FIFO unil it is full, or all of the
	 * data has been put into the FIFO.
	 */
	while ((!XUartPs_IsTransmitFull(InstancePtr->Config.BaseAddress)) &&
		   (InstancePtr->SendBuffer.RemainingBytes > SentCount)) {

		/*
		 * Fill the FIFO from the buffer
		 */
		XUartPs_WriteReg(InstancePtr->Config.BaseAddress,
				   XUARTPS_FIFO_OFFSET,
				   ((u32)InstancePtr->SendBuffer.
				   NextBytePtr[SentCount]));

		/*
		 * Increment the send count.
		 */
		SentCount++;
	}

	/*
	 * Update the buffer to reflect the bytes that were sent from it
	 */
	InstancePtr->SendBuffer.NextBytePtr += SentCount;
	InstancePtr->SendBuffer.RemainingBytes -= SentCount;

	/*
	 * If interrupts are enabled as indicated by the receive interrupt, then
	 * enable the TX FIFO empty interrupt, so further action can be taken
	 * for this sending.
	 */
	ImrRegister =
		XUartPs_ReadReg(InstancePtr->Config.BaseAddress,
				  XUARTPS_IMR_OFFSET);
	if (((ImrRegister & XUARTPS_IXR_RXFULL) != (u32)0) ||
		((ImrRegister & XUARTPS_IXR_RXEMPTY) != (u32)0)||
		((ImrRegister & XUARTPS_IXR_RXOVR) != (u32)0)) {

		XUartPs_WriteReg(InstancePtr->Config.BaseAddress,
					   XUARTPS_IER_OFFSET,
					   ImrRegister | (u32)XUARTPS_IXR_TXEMPTY);
	}

	return SentCount;
}
예제 #2
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.*/
		;
	}
}
예제 #3
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;
}
예제 #4
0
/**
*
* This function sets the interrupt mask.
*
* @param	InstancePtr is a pointer to the XUartPs instance
* @param	Mask contains the interrupts to be enabled or disabled.
*		A '1' enables an interupt, and a '0' disables.
*
* @return	None.
*
* @note		None.
*
*****************************************************************************/
void XUartPs_SetInterruptMask(XUartPs *InstancePtr, u32 Mask)
{
	u32 TempMask = Mask;
	/* Assert validates the input arguments */
	Xil_AssertVoid(InstancePtr != NULL);

	TempMask &= (u32)XUARTPS_IXR_MASK;

	/* Write the mask to the IER Register */
	XUartPs_WriteReg(InstancePtr->Config.BaseAddress,
		 XUARTPS_IER_OFFSET, TempMask);

	/* Write the inverse of the Mask to the IDR register */
	XUartPs_WriteReg(InstancePtr->Config.BaseAddress,
		 XUARTPS_IDR_OFFSET, (~TempMask));

}
예제 #5
0
/**
*
* This function is the interrupt handler for the driver.
* It must be connected to an interrupt system by the application such that it
* can be called when an interrupt occurs.
*
* @param	InstancePtr contains a pointer to the driver instance
*
* @return	None.
*
* @note		None.
*
******************************************************************************/
void XUartPs_InterruptHandler(XUartPs *InstancePtr)
{
	u32 IsrStatus;

	Xil_AssertVoid(InstancePtr != NULL);
	Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);

	/*
	 * Read the interrupt ID register to determine which
	 * interrupt is active
	 */
	IsrStatus = XUartPs_ReadReg(InstancePtr->Config.BaseAddress,
				   XUARTPS_IMR_OFFSET);

	IsrStatus &= XUartPs_ReadReg(InstancePtr->Config.BaseAddress,
				   XUARTPS_ISR_OFFSET);

	/*
	 * Dispatch an appropriate handler.
	 */
	if((IsrStatus & ((u32)XUARTPS_IXR_RXOVR | (u32)XUARTPS_IXR_RXEMPTY |
			(u32)XUARTPS_IXR_RXFULL)) != (u32)0) {
		/* Received data interrupt */
		ReceiveDataHandler(InstancePtr);
	}

	if((IsrStatus & ((u32)XUARTPS_IXR_TXEMPTY | (u32)XUARTPS_IXR_TXFULL))
									 != (u32)0) {
		/* Transmit data interrupt */
		SendDataHandler(InstancePtr, IsrStatus);
	}

	if((IsrStatus & ((u32)XUARTPS_IXR_OVER | (u32)XUARTPS_IXR_FRAMING |
			(u32)XUARTPS_IXR_PARITY)) != (u32)0) {
		/* Received Error Status interrupt */
		ReceiveErrorHandler(InstancePtr);
	}

	if((IsrStatus & ((u32)XUARTPS_IXR_TOUT)) != (u32)0) {
		/* Received Timeout interrupt */
		ReceiveTimeoutHandler(InstancePtr);
	}

	if((IsrStatus & ((u32)XUARTPS_IXR_DMS)) != (u32)0) {
		/* Modem status interrupt */
		ModemHandler(InstancePtr);
	}

	/*
	 * Clear the interrupt status.
	 */
	XUartPs_WriteReg(InstancePtr->Config.BaseAddress, XUARTPS_ISR_OFFSET,
		IsrStatus);

}
예제 #6
0
/**
*
* This function attempts to receive a specified number of bytes of data
* from the device and store it into the specified buffer. This function works
* for both polled or interrupt driven modes. It is non-blocking.
*
* In a polled mode, this function will only receive the data already in the
* RX FIFO. The application may need to call it repeatedly to receive the
* entire buffer. Polled mode is the default mode of operation for the device.
*
* In interrupt mode, this function will start the receiving, if not the entire
* buffer has been received, the interrupt handler will continue receiving data
* until the entire buffer has been received. A callback function, as specified
* by the application, will be called to indicate the completion of the
* receiving or error conditions.
*
* @param	InstancePtr is a pointer to the XUartPs instance
* @param	BufferPtr is pointer to buffer for data to be received into
* @param	NumBytes is the number of bytes to be received. A value of zero
*		will stop a previous receive operation that is in progress in
*		interrupt mode.
*
* @return	The number of bytes received.
*
* @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.
*
*****************************************************************************/
u32 XUartPs_Recv(XUartPs *InstancePtr,
			  u8 *BufferPtr, u32 NumBytes)
{
	u32 ReceivedCount;
	u32 ImrRegister;

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

	/*
	 * Disable all the interrupts.
	 * This stops a previous operation that may be interrupt driven
	 */
	ImrRegister = XUartPs_ReadReg(InstancePtr->Config.BaseAddress,
				  XUARTPS_IMR_OFFSET);
	XUartPs_WriteReg(InstancePtr->Config.BaseAddress, XUARTPS_IDR_OFFSET,
		XUARTPS_IXR_MASK);

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

	/*
	 * Receive the data from the device
	 */
	ReceivedCount = XUartPs_ReceiveBuffer(InstancePtr);

	/*
	 * Restore the interrupt state
	 */
	XUartPs_WriteReg(InstancePtr->Config.BaseAddress, XUARTPS_IER_OFFSET,
		ImrRegister);

	return ReceivedCount;
}
/**
*
* This function sends one byte using the device. This function operates in
* polled mode and blocks until the data has been put into the TX FIFO register.
*
* @param	BaseAddress contains the base address of the device.
* @param	Data contains the byte to be sent.
*
* @return	None.
*
* @note		None.
*
*****************************************************************************/
void XUartPs_SendByte(u32 BaseAddress, u8 Data)
{
    /*
     * Wait until there is space in TX FIFO
     */
    while (XUartPs_IsTransmitFull(BaseAddress));

    /*
     * Write the byte into the TX FIFO
     */
    XUartPs_WriteReg(BaseAddress, XUARTPS_FIFO_OFFSET, Data);
}
예제 #8
0
파일: serial.c 프로젝트: wugsh/wgs
/*
 * See the serial2.h header file.
 */
xComPortHandle xSerialPortInitMinimal( uint32_t ulWantedBaud, UBaseType_t uxQueueLength )
{
BaseType_t xStatus;
XUartPs_Config *pxConfig;

	/* Create the queue used to hold received characters.  NOTE THE COMMENTS AT
	THE TOP OF THIS FILE REGARDING THE USE OF QUEUES FOR THIS PURPSOE. */
	xRxQueue = xQueueCreate( uxQueueLength, sizeof( char ) );
	configASSERT( xRxQueue );

	/* Create the semaphore used to signal the end of a transmission, then take
	the semaphore so it is in the correct state the first time
	xSerialSendString() is called.  A block time of zero is used when taking
	the semaphore as it is guaranteed to be available (it was just created). */
	xTxCompleteSemaphore = xSemaphoreCreateBinary();
	configASSERT( xTxCompleteSemaphore );
	xSemaphoreTake( xTxCompleteSemaphore, 0 );

	/* Look up the UART configuration then initialise the dirver. */
	pxConfig = XUartPs_LookupConfig( XPAR_XUARTPS_0_DEVICE_ID );

	/* Initialise the driver. */
	xStatus = XUartPs_CfgInitialize( &xUARTInstance, pxConfig, XPAR_PS7_UART_1_BASEADDR );
	configASSERT( xStatus == XST_SUCCESS );
	( void ) xStatus; /* Remove compiler warning if configASSERT() is not defined. */

	/* Misc. parameter configuration. */
	XUartPs_SetBaudRate( &xUARTInstance, ulWantedBaud );
	XUartPs_SetOperMode( &xUARTInstance, XUARTPS_OPER_MODE_NORMAL );

	/* Install the interrupt service routine that is defined within this
	file. */
	xStatus = XScuGic_Connect( &xInterruptController, XPAR_XUARTPS_1_INTR,  (Xil_ExceptionHandler) prvUART_Handler, (void *) &xUARTInstance );
	configASSERT( xStatus == XST_SUCCESS );
	( void ) xStatus; /* Remove compiler warning if configASSERT() is not defined. */

	/* Ensure interrupts start clear. */
	XUartPs_WriteReg( XPAR_PS7_UART_1_BASEADDR, XUARTPS_ISR_OFFSET, XUARTPS_IXR_MASK );

	/* Enable the UART interrupt within the GIC. */
	XScuGic_Enable( &xInterruptController, XPAR_XUARTPS_1_INTR );

	/* Enable the interrupts of interest in the UART. */
	XUartPs_SetInterruptMask( &xUARTInstance, XUARTPS_IXR_RXFULL | XUARTPS_IXR_RXOVR | XUARTPS_IXR_TOUT | XUARTPS_IXR_TXEMPTY );

	/* Set the receive timeout. */
	XUartPs_SetRecvTimeout( &xUARTInstance, 8 );

	return ( xComPortHandle ) 0;
}
/* ---------------------------------------------------------------------------- *
 * 									menu()										*
 * ---------------------------------------------------------------------------- *
 * Presented at system startup. Allows the user to select between three
 * options by pressing certain keys on the keyboard:
 * 		's' - 	Audio loopback streaming
 * 		'n' - 	Tonal noise is generated by an NCO and added to the audio
 * 				being captured from the audio codec.
 * 		'f' - 	The audio + tonal noise is passed to an adaptive LMS noise
 * 				cancellation filter which will use the tonal noise estimate
 * 				to remove the noise from the audio.
 *
 * 	This menu is shown upon exiting from any of the above options.
 * ---------------------------------------------------------------------------- */
void menu(){
	u8 inp = 0x00;
	u32 CntrlRegister;

	/* Turn off all LEDs */
	Xil_Out32(LED_BASE, 0);

	CntrlRegister = XUartPs_ReadReg(UART_BASEADDR, XUARTPS_CR_OFFSET);

	XUartPs_WriteReg(UART_BASEADDR, XUARTPS_CR_OFFSET,
				  ((CntrlRegister & ~XUARTPS_CR_EN_DIS_MASK) |
				   XUARTPS_CR_TX_EN | XUARTPS_CR_RX_EN));

	xil_printf("\r\n\r\n");
	xil_printf("Embedded LMS Filtering Demo\r\n");
	xil_printf("Enter 's' to stream pure audio, 'n' to add tonal noise and 'f' to adaptively filter\r\n");
	xil_printf("----------------------------------------\r\n");

	// Wait for input from UART via the terminal
	while (!XUartPs_IsReceiveData(UART_BASEADDR));
				inp = XUartPs_ReadReg(UART_BASEADDR, XUARTPS_FIFO_OFFSET);
	// Select function based on UART input
	switch(inp){
	case 's':
		xil_printf("STREAMING AUDIO\r\n");
		xil_printf("Press 'q' to return to the main menu\r\n");
		audio_stream();
		break;
	case 'n':
		xil_printf("ENTERING NOISE GENERATION OPERATION\r\n");
		xil_printf("Select step size via the DIP switches...\r\n\n");
		xil_printf("Press 'q' to return to the main menu\r\n");
		tonal_noise();
		break;
	case 'f':
		xil_printf("ENTERING LMS FILTERING OPERATION\r\n");
		xil_printf("Press 'q' to return to the main menu\r\n");
		lms_filter();
		break;
	default:
		menu();
		break;
	} // switch
} // menu()
예제 #10
0
/**
*
* This function does a minimal test on the UART device using the hardware
* interface.
*
* @param	UartBaseAddress is the base address of the device
*
* @return	XST_SUCCESS if successful, XST_FAILURE if unsuccessful
*
* @note		None.
*
**************************************************************************/
int UartPsEchoExample(u32 UartBaseAddress)
{
	int Index;
	u32 Running;
	u8 RecvChar;
	u32 CntrlRegister;

	CntrlRegister = XUartPs_ReadReg(UartBaseAddress, XUARTPS_CR_OFFSET);

	/*
	 * Enable TX and RX for the device
	 */
	XUartPs_WriteReg(UartBaseAddress, XUARTPS_CR_OFFSET,
			  ((CntrlRegister & ~XUARTPS_CR_EN_DIS_MASK) |
			   XUARTPS_CR_TX_EN | XUARTPS_CR_RX_EN));
	/*
	 * Initialize the send buffer bytes with a pattern to send and the
	 * the receive buffer bytes to zero
	 */
	for (Index = 0; Index < TEST_BUFFER_SIZE; Index++) {
		SendBuffer[Index] = Index + '0';
	}

	/*
	 * Send the entire transmit buffer.
	 */
	for (Index = 0; Index < TEST_BUFFER_SIZE; Index++) {
		/*
		 * Wait until there is space in TX FIFO
		 */
		 while (XUartPs_IsTransmitFull(UartBaseAddress));

		/*
		 * Write the byte into the TX FIFO
		 */
		XUartPs_WriteReg(UartBaseAddress, XUARTPS_FIFO_OFFSET,
				  SendBuffer[Index]);
	}

	Running = TRUE;
	while (Running) {
		 /*
		  * Wait until there is data
		  */
		while (!XUartPs_IsReceiveData(UartBaseAddress));

		RecvChar = XUartPs_ReadReg(UartBaseAddress,
					    XUARTPS_FIFO_OFFSET);

		/* Change the capitalization */
		if (('a' <= RecvChar) && ('z' >= RecvChar)) {
//			 Convert the Capital letter to a small.
			RecvChar = RecvChar - 'a' + 'A';
		}
		else if (('A' <= RecvChar) && ('Z' >= RecvChar)) {
	//		 Convert the small letter to a Capital.
			RecvChar = RecvChar - 'A' + 'a';
		}
		else if (CHAR_ESC == RecvChar) {
			Running = FALSE;
		}

		/* Echo the character back */
		XUartPs_WriteReg(UartBaseAddress,  XUARTPS_FIFO_OFFSET,
				  RecvChar);
	}

	return XST_SUCCESS;
}
예제 #11
0
/**
*
* This function resets UART
*
* @param	BaseAddress contains the base address of the device.
*
* @return	None
*
* @note		None.
*
*****************************************************************************/
void XUartPs_ResetHw(u32 BaseAddress)
{

    /*
     * Disable interrupts
     */
    XUartPs_WriteReg(BaseAddress, XUARTPS_IDR_OFFSET, XUARTPS_IXR_MASK);

    /*
     * Disable receive and transmit
     */
    XUartPs_WriteReg(BaseAddress, XUARTPS_CR_OFFSET,
                     XUARTPS_CR_RX_DIS | XUARTPS_CR_TX_DIS);

    /*
     * Software reset of receive and transmit
     * This clears the FIFO.
     */
    XUartPs_WriteReg(BaseAddress, XUARTPS_CR_OFFSET,
                     XUARTPS_CR_TXRST | XUARTPS_CR_RXRST);

    /*
     * Clear status flags - SW reset wont clear sticky flags.
     */
    XUartPs_WriteReg(BaseAddress, XUARTPS_ISR_OFFSET, XUARTPS_IXR_MASK);

    /*
     * Mode register reset value : All zeroes
     * Normal mode, even parity, 1 stop bit
     */
    XUartPs_WriteReg(BaseAddress, XUARTPS_MR_OFFSET,
                     XUARTPS_MR_CHMODE_NORM);

    /*
     * Rx and TX trigger register reset values
     */
    XUartPs_WriteReg(BaseAddress, XUARTPS_RXWM_OFFSET,
                     XUARTPS_RXWM_RESET_VAL);
    XUartPs_WriteReg(BaseAddress, XUARTPS_TXWM_OFFSET,
                     XUARTPS_TXWM_RESET_VAL);

    /*
     * Rx timeout disabled by default
     */
    XUartPs_WriteReg(BaseAddress, XUARTPS_RXTOUT_OFFSET,
                     XUARTPS_RXTOUT_DISABLE);

    /*
     * Baud rate generator and dividor reset values
     */
    XUartPs_WriteReg(BaseAddress, XUARTPS_BAUDGEN_OFFSET,
                     XUARTPS_BAUDGEN_RESET_VAL);
    XUartPs_WriteReg(BaseAddress, XUARTPS_BAUDDIV_OFFSET,
                     XUARTPS_BAUDDIV_RESET_VAL);

    /*
     * Control register reset value -
     * RX and TX are disable by default
     */
    XUartPs_WriteReg(BaseAddress, XUARTPS_CR_OFFSET,
                     XUARTPS_CR_RX_DIS | XUARTPS_CR_TX_DIS |
                     XUARTPS_CR_STOPBRK);

}
예제 #12
0
파일: serial.c 프로젝트: wugsh/wgs
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 );
}
예제 #13
0
/**
*
* Sets the baud rate for the device. Checks the input value for
* validity and also verifies that the requested rate can be configured to
* within the maximum error range specified by XUARTPS_MAX_BAUD_ERROR_RATE.
* If the provided rate is not possible, the current setting is unchanged.
*
* @param	InstancePtr is a pointer to the XUartPs instance
* @param	BaudRate to be set
*
* @return
*		- XST_SUCCESS if everything configured as expected
*		- XST_UART_BAUD_ERROR if the requested rate is not available
*		  because there was too much error
*
* @note		None.
*
*****************************************************************************/
s32 XUartPs_SetBaudRate(XUartPs *InstancePtr, u32 BaudRate)
{
	u32 IterBAUDDIV;	/* Iterator for available baud divisor values */
	u32 BRGR_Value;		/* Calculated value for baud rate generator */
	u32 CalcBaudRate;	/* Calculated baud rate */
	u32 BaudError;		/* Diff between calculated and requested baud rate */
	u32 Best_BRGR = 0U;	/* Best value for baud rate generator */
	u8 Best_BAUDDIV = 0U;	/* Best value for baud divisor */
	u32 Best_Error = 0xFFFFFFFFU;
	u32 PercentError;
	u32 ModeReg;
	u32 InputClk;

	/*
	 * Asserts validate the input arguments
	 */
	Xil_AssertNonvoid(InstancePtr != NULL);
	Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
	Xil_AssertNonvoid(BaudRate <= (u32)XUARTPS_MAX_RATE);
	Xil_AssertNonvoid(BaudRate >= (u32)XUARTPS_MIN_RATE);

	/*
	 * Make sure the baud rate is not impossilby large.
	 * Fastest possible baud rate is Input Clock / 2.
	 */
	if ((BaudRate * 2) > InstancePtr->Config.InputClockHz) {
		return XST_UART_BAUD_ERROR;
	}
	/*
	 * Check whether the input clock is divided by 8
	 */
	ModeReg = XUartPs_ReadReg( InstancePtr->Config.BaseAddress,
				 XUARTPS_MR_OFFSET);

	InputClk = InstancePtr->Config.InputClockHz;
	if(ModeReg & XUARTPS_MR_CLKSEL) {
		InputClk = InstancePtr->Config.InputClockHz / 8;
	}

	/*
	 * Determine the Baud divider. It can be 4to 254.
	 * Loop through all possible combinations
	 */
	for (IterBAUDDIV = 4; IterBAUDDIV < 255; IterBAUDDIV++) {

		/*
		 * Calculate the value for BRGR register
		 */
		BRGR_Value = InputClk / (BaudRate * (IterBAUDDIV + 1));

		/*
		 * Calculate the baud rate from the BRGR value
		 */
		CalcBaudRate = InputClk/ (BRGR_Value * (IterBAUDDIV + 1));

		/*
		 * Avoid unsigned integer underflow
		 */
		if (BaudRate > CalcBaudRate) {
			BaudError = BaudRate - CalcBaudRate;
		}
		else {
			BaudError = CalcBaudRate - BaudRate;
		}

		/*
		 * Find the calculated baud rate closest to requested baud rate.
		 */
		if (Best_Error > BaudError) {

			Best_BRGR = BRGR_Value;
			Best_BAUDDIV = IterBAUDDIV;
			Best_Error = BaudError;
		}
	}

	/*
	 * Make sure the best error is not too large.
	 */
	PercentError = (Best_Error * 100) / BaudRate;
	if (XUARTPS_MAX_BAUD_ERROR_RATE < PercentError) {
		return XST_UART_BAUD_ERROR;
	}

	/*
	 * Disable TX and RX to avoid glitches when setting the baud rate.
	 */
	XUartPs_DisableUart(InstancePtr);

	XUartPs_WriteReg(InstancePtr->Config.BaseAddress,
			   XUARTPS_BAUDGEN_OFFSET, Best_BRGR);
	XUartPs_WriteReg(InstancePtr->Config.BaseAddress,
			   XUARTPS_BAUDDIV_OFFSET, Best_BAUDDIV);

	/*
	 * RX and TX SW reset
	 */
	XUartPs_WriteReg(InstancePtr->Config.BaseAddress, XUARTPS_CR_OFFSET,
				XUARTPS_CR_TXRST | XUARTPS_CR_RXRST);

	/*
	 * Enable device
	 */
	XUartPs_EnableUart(InstancePtr);

	InstancePtr->BaudRate = BaudRate;

	return XST_SUCCESS;

}
예제 #14
0
/**
*
* Initializes a specific XUartPs instance such that it is ready to be used.
* The data format of the device is setup for 8 data bits, 1 stop bit, and no
* parity by default. The baud rate is set to a default value specified by
* Config->DefaultBaudRate if set, otherwise it is set to 19.2K baud. The
* receive FIFO threshold is set for 8 bytes. The default operating mode of the
* driver is polled mode.
*
* @param	InstancePtr is a pointer to the XUartPs instance.
* @param	Config is a reference to a structure containing information
*		about a specific XUartPs driver.
* @param	EffectiveAddr is the device base address in the virtual memory
*		address space. The caller is responsible for keeping the address
*		mapping from EffectiveAddr to the device physical base address
*		unchanged once this function is invoked. Unexpected errors may
*		occur if the address mapping changes after this function is
*		called. If address translation is not used, pass in the physical
*		address instead.
*
* @return
*
*		- XST_SUCCESS if initialization was successful
*		- XST_UART_BAUD_ERROR if the baud rate is not possible because
*		  the inputclock frequency is not divisible with an acceptable
*		  amount of error
*
* @note
*
* The default configuration for the UART after initialization is:
*
* - 19,200 bps or XPAR_DFT_BAUDRATE if defined
* - 8 data bits
* - 1 stop bit
* - no parity
* - FIFO's are enabled with a receive threshold of 8 bytes
* - The RX timeout is enabled with a timeout of 1 (4 char times)
*
*   All interrupts are disabled.
*
*****************************************************************************/
s32 XUartPs_CfgInitialize(XUartPs *InstancePtr,
				   XUartPs_Config * Config, u32 EffectiveAddr)
{
	s32 Status;
	u32 ModeRegister;
	u32 BaudRate;

	/*
	 * Assert validates the input arguments
	 */
	Xil_AssertNonvoid(InstancePtr != NULL);
	Xil_AssertNonvoid(Config != NULL);

	/*
	 * Setup the driver instance using passed in parameters
	 */
	InstancePtr->Config.BaseAddress = EffectiveAddr;
	InstancePtr->Config.InputClockHz = Config->InputClockHz;
	InstancePtr->Config.ModemPinsConnected = Config->ModemPinsConnected;

	/*
	 * Initialize other instance data to default values
	 */
	InstancePtr->Handler = XUartPs_StubHandler;

	InstancePtr->SendBuffer.NextBytePtr = NULL;
	InstancePtr->SendBuffer.RemainingBytes = 0U;
	InstancePtr->SendBuffer.RequestedBytes = 0U;

	InstancePtr->ReceiveBuffer.NextBytePtr = NULL;
	InstancePtr->ReceiveBuffer.RemainingBytes = 0U;
	InstancePtr->ReceiveBuffer.RequestedBytes = 0U;

	/*
	 * Flag that the driver instance is ready to use
	 */
	InstancePtr->IsReady = XIL_COMPONENT_IS_READY;

	/*
	 * Set the default baud rate here, can be changed prior to
	 * starting the device
	 */
	BaudRate = (u32)XUARTPS_DFT_BAUDRATE;
	Status = XUartPs_SetBaudRate(InstancePtr, BaudRate);
	if (Status != (s32)XST_SUCCESS) {
		InstancePtr->IsReady = 0U;
	} else {

		/*
		 * Set up the default data format: 8 bit data, 1 stop bit, no
		 * parity
		 */
		ModeRegister = XUartPs_ReadReg(InstancePtr->Config.BaseAddress,
					  XUARTPS_MR_OFFSET);

		/*
		 * Mask off what's already there
		 */
		ModeRegister &= (~((u32)XUARTPS_MR_CHARLEN_MASK |
						 (u32)XUARTPS_MR_STOPMODE_MASK |
						 (u32)XUARTPS_MR_PARITY_MASK));

		/*
		 * Set the register value to the desired data format
		 */
		ModeRegister |=	((u32)XUARTPS_MR_CHARLEN_8_BIT |
						 (u32)XUARTPS_MR_STOPMODE_1_BIT |
						 (u32)XUARTPS_MR_PARITY_NONE);

		/*
		 * Write the mode register out
		 */
		XUartPs_WriteReg(InstancePtr->Config.BaseAddress, XUARTPS_MR_OFFSET,
				   ModeRegister);

		/*
		 * Set the RX FIFO trigger at 8 data bytes.
		 */
		XUartPs_WriteReg(InstancePtr->Config.BaseAddress,
				   XUARTPS_RXWM_OFFSET, 0x08U);

		/*
		 * Set the RX timeout to 1, which will be 4 character time
		 */
		XUartPs_WriteReg(InstancePtr->Config.BaseAddress,
				   XUARTPS_RXTOUT_OFFSET, 0x01U);

		/*
		 * Disable all interrupts, polled mode is the default
		 */
		XUartPs_WriteReg(InstancePtr->Config.BaseAddress, XUARTPS_IDR_OFFSET,
				   XUARTPS_IXR_MASK);

		Status = XST_SUCCESS;
	}
	return Status;
}
예제 #15
0
/**
*
* This function runs a self-test on the driver and hardware device. This self
* test performs a local loopback and verifies data can be sent and received.
*
* The time for this test is proportional to the baud rate that has been set
* prior to calling this function.
*
* The mode and control registers are restored before return.
*
* @param	InstancePtr is a pointer to the XUartPs instance
*
* @return
*		 - XST_SUCCESS if the test was successful
*		- XST_UART_TEST_FAIL if the test failed looping back the data
*
* @note
*
* This function can hang if the hardware is not functioning properly.
*
******************************************************************************/
s32 XUartPs_SelfTest(XUartPs *InstancePtr)
{
	s32 Status = XST_SUCCESS;
	u32 IntrRegister;
	u32 ModeRegister;
	u8 Index;
	u32 ReceiveDataResult;

	/*
	 * Assert validates the input arguments
	 */
	Xil_AssertNonvoid(InstancePtr != NULL);
	Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);

	/*
	 * Disable all interrupts in the interrupt disable register
	 */
	IntrRegister = XUartPs_ReadReg(InstancePtr->Config.BaseAddress,
				   XUARTPS_IMR_OFFSET);
	XUartPs_WriteReg(InstancePtr->Config.BaseAddress, XUARTPS_IDR_OFFSET,
		XUARTPS_IXR_MASK);

	/*
	 * Setup for local loopback
	 */
	ModeRegister = XUartPs_ReadReg(InstancePtr->Config.BaseAddress,
				   XUARTPS_MR_OFFSET);
	XUartPs_WriteReg(InstancePtr->Config.BaseAddress, XUARTPS_MR_OFFSET,
			   ((ModeRegister & (u32)(~XUARTPS_MR_CHMODE_MASK)) |
				(u32)XUARTPS_MR_CHMODE_L_LOOP));

	/*
	 * Send a number of bytes and receive them, one at a time.
	 */
	for (Index = 0U; Index < XUARTPS_TOTAL_BYTES; Index++) {
		/*
		 * Send out the byte and if it was not sent then the failure
		 * will be caught in the comparison at the end
		 */
		(void)XUartPs_Send(InstancePtr, &TestString[Index], 1U);

		/*
		 * Wait until the byte is received. This can hang if the HW
		 * is broken. Watch for the FIFO empty flag to be false.
		 */
		ReceiveDataResult = Xil_In32((InstancePtr->Config.BaseAddress) + XUARTPS_SR_OFFSET) &
				XUARTPS_SR_RXEMPTY;
		while (ReceiveDataResult == XUARTPS_SR_RXEMPTY ) {
			ReceiveDataResult = Xil_In32((InstancePtr->Config.BaseAddress) + XUARTPS_SR_OFFSET) &
					XUARTPS_SR_RXEMPTY;
		}

		/*
		 * Receive the byte
		 */
		(void)XUartPs_Recv(InstancePtr, &ReturnString[Index], 1U);
	}

	/*
	 * Compare the bytes received to the bytes sent to verify the exact data
	 * was received
	 */
	for (Index = 0U; Index < XUARTPS_TOTAL_BYTES; Index++) {
		if (TestString[Index] != ReturnString[Index]) {
			Status = XST_UART_TEST_FAIL;
		}
	}

	/*
	 * Restore the registers which were altered to put into polling and
	 * loopback modes so that this test is not destructive
	 */
	XUartPs_WriteReg(InstancePtr->Config.BaseAddress, XUARTPS_IER_OFFSET,
			   IntrRegister);
	XUartPs_WriteReg(InstancePtr->Config.BaseAddress, XUARTPS_MR_OFFSET,
			   ModeRegister);

	return Status;
}