1 /******************************************************************************
3 * Copyright (C) 2010 - 2014 Xilinx, Inc. All rights reserved.
5 * Permission is hereby granted, free of charge, to any person obtaining a copy
6 * of this software and associated documentation files (the "Software"), to deal
7 * in the Software without restriction, including without limitation the rights
8 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 * copies of the Software, and to permit persons to whom the Software is
10 * furnished to do so, subject to the following conditions:
12 * The above copyright notice and this permission notice shall be included in
13 * all copies or substantial portions of the Software.
15 * Use of the Software is limited solely to applications:
16 * (a) running on a Xilinx device, or
17 * (b) that interact with a Xilinx device through a bus or interconnect.
19 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
22 * XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
23 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
24 * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
27 * Except as contained in this notice, the name of the Xilinx shall not be used
28 * in advertising or otherwise to promote the sale, use or other dealings in
29 * this Software without prior written authorization from Xilinx.
31 ******************************************************************************/
32 /****************************************************************************/
36 * @addtogroup uartps_v2_1
39 * This file contains the implementation of the interface functions for XUartPs
40 * driver. Refer to the header file xuartps.h for more detailed information.
43 * MODIFICATION HISTORY:
45 * Ver Who Date Changes
46 * ----- ------ -------- ----------------------------------------------
47 * 1.00 drg/jz 01/13/10 First Release
50 *****************************************************************************/
52 /***************************** Include Files ********************************/
58 /************************** Constant Definitions ****************************/
60 /* The following constant defines the amount of error that is allowed for
61 * a specified baud rate. This error is the difference between the actual
62 * baud rate that will be generated using the specified clock and the
65 #define XUARTPS_MAX_BAUD_ERROR_RATE 3 /* max % error allowed */
67 /**************************** Type Definitions ******************************/
70 /***************** Macros (Inline Functions) Definitions ********************/
73 /************************** Function Prototypes *****************************/
75 static void XUartPs_StubHandler(void *CallBackRef, u32 Event,
76 unsigned int ByteCount);
78 unsigned int XUartPs_SendBuffer(XUartPs *InstancePtr);
80 unsigned int XUartPs_ReceiveBuffer(XUartPs *InstancePtr);
82 /************************** Variable Definitions ****************************/
84 /****************************************************************************/
87 * Initializes a specific XUartPs instance such that it is ready to be used.
88 * The data format of the device is setup for 8 data bits, 1 stop bit, and no
89 * parity by default. The baud rate is set to a default value specified by
90 * Config->DefaultBaudRate if set, otherwise it is set to 19.2K baud. The
91 * receive FIFO threshold is set for 8 bytes. The default operating mode of the
92 * driver is polled mode.
94 * @param InstancePtr is a pointer to the XUartPs instance.
95 * @param Config is a reference to a structure containing information
96 * about a specific XUartPs driver.
97 * @param EffectiveAddr is the device base address in the virtual memory
98 * address space. The caller is responsible for keeping the address
99 * mapping from EffectiveAddr to the device physical base address
100 * unchanged once this function is invoked. Unexpected errors may
101 * occur if the address mapping changes after this function is
102 * called. If address translation is not used, pass in the physical
107 * - XST_SUCCESS if initialization was successful
108 * - XST_UART_BAUD_ERROR if the baud rate is not possible because
109 * the inputclock frequency is not divisible with an acceptable
114 * The default configuration for the UART after initialization is:
116 * - 19,200 bps or XPAR_DFT_BAUDRATE if defined
120 * - FIFO's are enabled with a receive threshold of 8 bytes
121 * - The RX timeout is enabled with a timeout of 1 (4 char times)
123 * All interrupts are disabled.
125 *****************************************************************************/
126 int XUartPs_CfgInitialize(XUartPs *InstancePtr,
127 XUartPs_Config * Config, u32 EffectiveAddr)
134 * Assert validates the input arguments
136 Xil_AssertNonvoid(InstancePtr != NULL);
137 Xil_AssertNonvoid(Config != NULL);
140 * Setup the driver instance using passed in parameters
142 InstancePtr->Config.BaseAddress = EffectiveAddr;
143 InstancePtr->Config.InputClockHz = Config->InputClockHz;
144 InstancePtr->Config.ModemPinsConnected = Config->ModemPinsConnected;
147 * Initialize other instance data to default values
149 InstancePtr->Handler = XUartPs_StubHandler;
151 InstancePtr->SendBuffer.NextBytePtr = NULL;
152 InstancePtr->SendBuffer.RemainingBytes = 0;
153 InstancePtr->SendBuffer.RequestedBytes = 0;
155 InstancePtr->ReceiveBuffer.NextBytePtr = NULL;
156 InstancePtr->ReceiveBuffer.RemainingBytes = 0;
157 InstancePtr->ReceiveBuffer.RequestedBytes = 0;
160 * Flag that the driver instance is ready to use
162 InstancePtr->IsReady = XIL_COMPONENT_IS_READY;
165 * Set the default baud rate here, can be changed prior to
166 * starting the device
168 BaudRate = XUARTPS_DFT_BAUDRATE;
169 Status = XUartPs_SetBaudRate(InstancePtr, BaudRate);
170 if (Status != XST_SUCCESS) {
171 InstancePtr->IsReady = 0;
176 * Set up the default data format: 8 bit data, 1 stop bit, no
179 ModeRegister = XUartPs_ReadReg(InstancePtr->Config.BaseAddress,
183 * Mask off what's already there
185 ModeRegister &= ~(XUARTPS_MR_CHARLEN_MASK |
186 XUARTPS_MR_STOPMODE_MASK |
187 XUARTPS_MR_PARITY_MASK);
190 * Set the register value to the desired data format
192 ModeRegister |= (XUARTPS_MR_CHARLEN_8_BIT |
193 XUARTPS_MR_STOPMODE_1_BIT |
194 XUARTPS_MR_PARITY_NONE);
197 * Write the mode register out
199 XUartPs_WriteReg(InstancePtr->Config.BaseAddress, XUARTPS_MR_OFFSET,
203 * Set the RX FIFO trigger at 8 data bytes.
205 XUartPs_WriteReg(InstancePtr->Config.BaseAddress,
206 XUARTPS_RXWM_OFFSET, 0x08);
209 * Set the RX timeout to 1, which will be 4 character time
211 XUartPs_WriteReg(InstancePtr->Config.BaseAddress,
212 XUARTPS_RXTOUT_OFFSET, 0x01);
215 * Disable all interrupts, polled mode is the default
217 XUartPs_WriteReg(InstancePtr->Config.BaseAddress, XUARTPS_IDR_OFFSET,
223 /****************************************************************************/
226 * This functions sends the specified buffer using the device in either
227 * polled or interrupt driven mode. This function is non-blocking, if the device
228 * is busy sending data, it will return and indicate zero bytes were sent.
229 * Otherwise, it fills the TX FIFO as much as it can, and return the number of
232 * In a polled mode, this function will only send as much data as TX FIFO can
233 * buffer. The application may need to call it repeatedly to send the entire
236 * In interrupt mode, this function will start sending the specified buffer,
237 * then the interrupt handler will continue sending data until the entire
238 * buffer has been sent. A callback function, as specified by the application,
239 * will be called to indicate the completion of sending.
241 * @param InstancePtr is a pointer to the XUartPs instance.
242 * @param BufferPtr is pointer to a buffer of data to be sent.
243 * @param NumBytes contains the number of bytes to be sent. A value of
244 * zero will stop a previous send operation that is in progress
245 * in interrupt mode. Any data that was already put into the
246 * transmit FIFO will be sent.
248 * @return The number of bytes actually sent.
252 * The number of bytes is not asserted so that this function may be called with
253 * a value of zero to stop an operation that is already in progress.
256 *****************************************************************************/
257 unsigned int XUartPs_Send(XUartPs *InstancePtr, u8 *BufferPtr,
258 unsigned int NumBytes)
260 unsigned int BytesSent;
263 * Asserts validate the input arguments
265 Xil_AssertNonvoid(InstancePtr != NULL);
266 Xil_AssertNonvoid(BufferPtr != NULL);
267 Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
270 * Disable the UART transmit interrupts to allow this call to stop a
271 * previous operation that may be interrupt driven.
273 XUartPs_WriteReg(InstancePtr->Config.BaseAddress, XUARTPS_IDR_OFFSET,
274 (XUARTPS_IXR_TXEMPTY | XUARTPS_IXR_TXFULL));
277 * Setup the buffer parameters
279 InstancePtr->SendBuffer.RequestedBytes = NumBytes;
280 InstancePtr->SendBuffer.RemainingBytes = NumBytes;
281 InstancePtr->SendBuffer.NextBytePtr = BufferPtr;
284 * Transmit interrupts will be enabled in XUartPs_SendBuffer(), after
285 * filling the TX FIFO.
287 BytesSent = XUartPs_SendBuffer(InstancePtr);
292 /****************************************************************************/
295 * This function attempts to receive a specified number of bytes of data
296 * from the device and store it into the specified buffer. This function works
297 * for both polled or interrupt driven modes. It is non-blocking.
299 * In a polled mode, this function will only receive the data already in the
300 * RX FIFO. The application may need to call it repeatedly to receive the
301 * entire buffer. Polled mode is the default mode of operation for the device.
303 * In interrupt mode, this function will start the receiving, if not the entire
304 * buffer has been received, the interrupt handler will continue receiving data
305 * until the entire buffer has been received. A callback function, as specified
306 * by the application, will be called to indicate the completion of the
307 * receiving or error conditions.
309 * @param InstancePtr is a pointer to the XUartPs instance
310 * @param BufferPtr is pointer to buffer for data to be received into
311 * @param NumBytes is the number of bytes to be received. A value of zero
312 * will stop a previous receive operation that is in progress in
315 * @return The number of bytes received.
319 * The number of bytes is not asserted so that this function may be called
320 * with a value of zero to stop an operation that is already in progress.
322 *****************************************************************************/
323 unsigned int XUartPs_Recv(XUartPs *InstancePtr,
324 u8 *BufferPtr, unsigned int NumBytes)
326 unsigned int ReceivedCount;
330 * Assert validates the input arguments
332 Xil_AssertNonvoid(InstancePtr != NULL);
333 Xil_AssertNonvoid(BufferPtr != NULL);
334 Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
337 * Disable all the interrupts.
338 * This stops a previous operation that may be interrupt driven
340 ImrRegister = XUartPs_ReadReg(InstancePtr->Config.BaseAddress,
342 XUartPs_WriteReg(InstancePtr->Config.BaseAddress, XUARTPS_IDR_OFFSET,
346 * Setup the buffer parameters
348 InstancePtr->ReceiveBuffer.RequestedBytes = NumBytes;
349 InstancePtr->ReceiveBuffer.RemainingBytes = NumBytes;
350 InstancePtr->ReceiveBuffer.NextBytePtr = BufferPtr;
353 * Receive the data from the device
355 ReceivedCount = XUartPs_ReceiveBuffer(InstancePtr);
358 * Restore the interrupt state
360 XUartPs_WriteReg(InstancePtr->Config.BaseAddress, XUARTPS_IER_OFFSET,
363 return ReceivedCount;
366 /****************************************************************************/
369 * This function sends a buffer that has been previously specified by setting
370 * up the instance variables of the instance. This function is an internal
371 * function for the XUartPs driver such that it may be called from a shell
372 * function that sets up the buffer or from an interrupt handler.
374 * This function sends the specified buffer in either polled or interrupt
375 * driven modes. This function is non-blocking.
377 * In a polled mode, this function only sends as much data as the TX FIFO
378 * can buffer. The application may need to call it repeatedly to send the
381 * In interrupt mode, this function starts the sending of the buffer, if not
382 * the entire buffer has been sent, then the interrupt handler continues the
383 * sending until the entire buffer has been sent. A callback function, as
384 * specified by the application, will be called to indicate the completion of
387 * @param InstancePtr is a pointer to the XUartPs instance
389 * @return The number of bytes actually sent
393 *****************************************************************************/
394 unsigned int XUartPs_SendBuffer(XUartPs *InstancePtr)
396 unsigned int SentCount = 0;
400 * If the TX FIFO is full, send nothing.
401 * Otherwise put bytes into the TX FIFO unil it is full, or all of the
402 * data has been put into the FIFO.
404 while ((!XUartPs_IsTransmitFull(InstancePtr->Config.BaseAddress)) &&
405 (InstancePtr->SendBuffer.RemainingBytes > SentCount)) {
408 * Fill the FIFO from the buffer
410 XUartPs_WriteReg(InstancePtr->Config.BaseAddress,
412 InstancePtr->SendBuffer.
413 NextBytePtr[SentCount]);
416 * Incriment the send count.
422 * Update the buffer to reflect the bytes that were sent from it
424 InstancePtr->SendBuffer.NextBytePtr += SentCount;
425 InstancePtr->SendBuffer.RemainingBytes -= SentCount;
428 * If interrupts are enabled as indicated by the receive interrupt, then
429 * enable the TX FIFO empty interrupt, so further action can be taken
433 XUartPs_ReadReg(InstancePtr->Config.BaseAddress,
435 if ((ImrRegister & XUARTPS_IXR_RXFULL) ||
436 (ImrRegister & XUARTPS_IXR_RXEMPTY) ||
437 (ImrRegister & XUARTPS_IXR_RXOVR)) {
439 XUartPs_WriteReg(InstancePtr->Config.BaseAddress,
441 ImrRegister | XUARTPS_IXR_TXEMPTY);
447 /****************************************************************************/
450 * This function receives a buffer that has been previously specified by setting
451 * up the instance variables of the instance. This function is an internal
452 * function, and it may be called from a shell function that sets up the buffer
453 * or from an interrupt handler.
455 * This function attempts to receive a specified number of bytes from the
456 * device and store it into the specified buffer. This function works for
457 * either polled or interrupt driven modes. It is non-blocking.
459 * In polled mode, this function only receives as much data as in the RX FIFO.
460 * The application may need to call it repeatedly to receive the entire buffer.
461 * Polled mode is the default mode for the driver.
463 * In interrupt mode, this function starts the receiving, if not the entire
464 * buffer has been received, the interrupt handler will continue until the
465 * entire buffer has been received. A callback function, as specified by the
466 * application, will be called to indicate the completion of the receiving or
469 * @param InstancePtr is a pointer to the XUartPs instance
471 * @return The number of bytes received.
475 *****************************************************************************/
476 unsigned int XUartPs_ReceiveBuffer(XUartPs *InstancePtr)
479 unsigned int ReceivedCount = 0;
482 * Read the Channel Status Register to determine if there is any data in
485 CsrRegister = XUartPs_ReadReg(InstancePtr->Config.BaseAddress,
489 * Loop until there is no more data in RX FIFO or the specified
490 * number of bytes has been received
492 while((ReceivedCount < InstancePtr->ReceiveBuffer.RemainingBytes)&&
493 (0 == (CsrRegister & XUARTPS_SR_RXEMPTY))){
495 InstancePtr->ReceiveBuffer.NextBytePtr[ReceivedCount] =
496 XUartPs_ReadReg(InstancePtr->Config.
498 XUARTPS_FIFO_OFFSET);
502 CsrRegister = XUartPs_ReadReg(InstancePtr->Config.BaseAddress,
507 * Update the receive buffer to reflect the number of bytes just
510 InstancePtr->ReceiveBuffer.NextBytePtr += ReceivedCount;
511 InstancePtr->ReceiveBuffer.RemainingBytes -= ReceivedCount;
513 return ReceivedCount;
516 /*****************************************************************************/
519 * Sets the baud rate for the device. Checks the input value for
520 * validity and also verifies that the requested rate can be configured to
521 * within the maximum error range specified by XUARTPS_MAX_BAUD_ERROR_RATE.
522 * If the provided rate is not possible, the current setting is unchanged.
524 * @param InstancePtr is a pointer to the XUartPs instance
525 * @param BaudRate to be set
528 * - XST_SUCCESS if everything configured as expected
529 * - XST_UART_BAUD_ERROR if the requested rate is not available
530 * because there was too much error
534 *****************************************************************************/
535 int XUartPs_SetBaudRate(XUartPs *InstancePtr, u32 BaudRate)
537 u8 IterBAUDDIV; /* Iterator for available baud divisor values */
538 u32 BRGR_Value; /* Calculated value for baud rate generator */
539 u32 CalcBaudRate; /* Calculated baud rate */
540 u32 BaudError; /* Diff between calculated and requested baud rate */
541 u32 Best_BRGR = 0; /* Best value for baud rate generator */
542 u8 Best_BAUDDIV = 0; /* Best value for baud divisor */
543 u32 Best_Error = 0xFFFFFFFF;
549 * Asserts validate the input arguments
551 Xil_AssertNonvoid(InstancePtr != NULL);
552 Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
553 Xil_AssertNonvoid(BaudRate <= XUARTPS_MAX_RATE);
554 Xil_AssertNonvoid(BaudRate >= XUARTPS_MIN_RATE);
557 * Make sure the baud rate is not impossilby large.
558 * Fastest possible baud rate is Input Clock / 2.
560 if ((BaudRate * 2) > InstancePtr->Config.InputClockHz) {
561 return XST_UART_BAUD_ERROR;
564 * Check whether the input clock is divided by 8
566 ModeReg = XUartPs_ReadReg( InstancePtr->Config.BaseAddress,
569 InputClk = InstancePtr->Config.InputClockHz;
570 if(ModeReg & XUARTPS_MR_CLKSEL) {
571 InputClk = InstancePtr->Config.InputClockHz / 8;
575 * Determine the Baud divider. It can be 4to 254.
576 * Loop through all possible combinations
578 for (IterBAUDDIV = 4; IterBAUDDIV < 255; IterBAUDDIV++) {
581 * Calculate the value for BRGR register
583 BRGR_Value = InputClk / (BaudRate * (IterBAUDDIV + 1));
586 * Calculate the baud rate from the BRGR value
588 CalcBaudRate = InputClk/ (BRGR_Value * (IterBAUDDIV + 1));
591 * Avoid unsigned integer underflow
593 if (BaudRate > CalcBaudRate) {
594 BaudError = BaudRate - CalcBaudRate;
597 BaudError = CalcBaudRate - BaudRate;
601 * Find the calculated baud rate closest to requested baud rate.
603 if (Best_Error > BaudError) {
605 Best_BRGR = BRGR_Value;
606 Best_BAUDDIV = IterBAUDDIV;
607 Best_Error = BaudError;
612 * Make sure the best error is not too large.
614 PercentError = (Best_Error * 100) / BaudRate;
615 if (XUARTPS_MAX_BAUD_ERROR_RATE < PercentError) {
616 return XST_UART_BAUD_ERROR;
620 * Disable TX and RX to avoid glitches when setting the baud rate.
622 XUartPs_DisableUart(InstancePtr);
624 XUartPs_WriteReg(InstancePtr->Config.BaseAddress,
625 XUARTPS_BAUDGEN_OFFSET, Best_BRGR);
626 XUartPs_WriteReg(InstancePtr->Config.BaseAddress,
627 XUARTPS_BAUDDIV_OFFSET, Best_BAUDDIV);
632 XUartPs_EnableUart(InstancePtr);
634 InstancePtr->BaudRate = BaudRate;
640 /****************************************************************************/
643 * This function is a stub handler that is the default handler such that if the
644 * application has not set the handler when interrupts are enabled, this
645 * function will be called.
647 * @param CallBackRef is unused by this function.
648 * @param Event is unused by this function.
649 * @param ByteCount is unused by this function.
655 *****************************************************************************/
656 static void XUartPs_StubHandler(void *CallBackRef, u32 Event,
657 unsigned int ByteCount)
663 * Assert occurs always since this is a stub and should never be called
665 Xil_AssertVoidAlways();