📄 xuartps.c
字号:
*/ 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 + -