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

📄 xuartps.c

📁 自学ZedBoard:使用IP通过ARM PS访问FPGA(源代码)
💻 C
📖 第 1 页 / 共 2 页
字号:
	 */	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 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.******************************************************************************/unsigned int XUartPs_SendBuffer(XUartPs *InstancePtr){	unsigned int SentCount = 0;	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,				   InstancePtr->SendBuffer.				   NextBytePtr[SentCount]);		/*		 * Incriment 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) ||		(ImrRegister & XUARTPS_IXR_RXEMPTY) ||		(ImrRegister & XUARTPS_IXR_RXOVR)) {	XUartPs_WriteReg(InstancePtr->Config.BaseAddress,				   XUARTPS_IER_OFFSET,				   ImrRegister | XUARTPS_IXR_TXEMPTY);	}	return SentCount;}/****************************************************************************//*** This function receives a buffer that has been previously specified by setting* up the instance variables of the instance. This function is an internal* function, and it may be called from a shell function that sets up the buffer* or from an interrupt handler.** This function attempts to receive a specified number of bytes from the* device and store it into the specified buffer. This function works for* either polled or interrupt driven modes. It is non-blocking.** In polled mode, this function only receives as much data as in the RX FIFO.* The application may need to call it repeatedly to receive the entire buffer.* Polled mode is the default mode for the driver.** In interrupt mode, this function starts the receiving, if not the entire* buffer has been received, the interrupt handler will continue 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** @return	The number of bytes received.** @note		None.******************************************************************************/unsigned int XUartPs_ReceiveBuffer(XUartPs *InstancePtr){	u32 CsrRegister;	unsigned int ReceivedCount = 0;	/* 	 * Read the Channel Status Register to determine if there is any data in	 * the RX FIFO	 */	CsrRegister = XUartPs_ReadReg(InstancePtr->Config.BaseAddress,				XUARTPS_SR_OFFSET);	/*	 * Loop until there is no more data in RX FIFO or the specified	 * number of bytes has been received	 */	while((ReceivedCount < InstancePtr->ReceiveBuffer.RemainingBytes)&&		(0 == (CsrRegister & XUARTPS_SR_RXEMPTY))){		InstancePtr->ReceiveBuffer.NextBytePtr[ReceivedCount] =			XUartPs_ReadReg(InstancePtr->Config.				  BaseAddress,				  XUARTPS_FIFO_OFFSET);		ReceivedCount++;		CsrRegister = XUartPs_ReadReg(InstancePtr->Config.BaseAddress,								XUARTPS_SR_OFFSET);	}	/*	 * Update the receive buffer to reflect the number of bytes just	 * received	 */	InstancePtr->ReceiveBuffer.NextBytePtr += ReceivedCount;	InstancePtr->ReceiveBuffer.RemainingBytes -= ReceivedCount;	return ReceivedCount;}/*****************************************************************************//**** 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.******************************************************************************/int XUartPs_SetBaudRate(XUartPs *InstancePtr, u32 BaudRate){	u8 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 = 0;	/* Best value for baud rate generator */	u8 Best_BAUDDIV = 0;	/* Best value for baud divisor */	u32 Best_Error = 0xFFFFFFFF;	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 <= XUARTPS_MAX_RATE);	Xil_AssertNonvoid(BaudRate >= 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);	/*	 * Enable device	 */	XUartPs_EnableUart(InstancePtr);	InstancePtr->BaudRate = BaudRate;	return XST_SUCCESS;}/****************************************************************************//**** This function is a stub handler that is the default handler such that if the* application has not set the handler when interrupts are enabled, this* function will be called.** @param	CallBackRef is unused by this function.* @param	Event is unused by this function.* @param	ByteCount is unused by this function.** @return	None.** @note		None.******************************************************************************/static void XUartPs_StubHandler(void *CallBackRef, u32 Event,				 unsigned int ByteCount){	(void) CallBackRef;	(void) Event;	(void) ByteCount;	/*	 * Assert occurs always since this is a stub and should never be called	 */	Xil_AssertVoidAlways();}

⌨️ 快捷键说明

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