1 /*****************************************************************************
3 * (c) Copyright 2010-13 Xilinx, Inc. All rights reserved.
5 * This file contains confidential and proprietary information of Xilinx, Inc.
6 * and is protected under U.S. and international copyright and other
7 * intellectual property laws.
10 * This disclaimer is not a license and does not grant any rights to the
11 * materials distributed herewith. Except as otherwise provided in a valid
12 * license issued to you by Xilinx, and to the maximum extent permitted by
13 * applicable law: (1) THESE MATERIALS ARE MADE AVAILABLE "AS IS" AND WITH ALL
14 * FAULTS, AND XILINX HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS, EXPRESS,
15 * IMPLIED, OR STATUTORY, INCLUDING BUT NOT LIMITED TO WARRANTIES OF
16 * MERCHANTABILITY, NON-INFRINGEMENT, OR FITNESS FOR ANY PARTICULAR PURPOSE;
17 * and (2) Xilinx shall not be liable (whether in contract or tort, including
18 * negligence, or under any other theory of liability) for any loss or damage
19 * of any kind or nature related to, arising under or in connection with these
20 * materials, including for any direct, or any indirect, special, incidental,
21 * or consequential loss or damage (including loss of data, profits, goodwill,
22 * or any type of loss or damage suffered as a result of any action brought by
23 * a third party) even if such damage or loss was reasonably foreseeable or
24 * Xilinx had been advised of the possibility of the same.
26 * CRITICAL APPLICATIONS
27 * Xilinx products are not designed or intended to be fail-safe, or for use in
28 * any application requiring fail-safe performance, such as life-support or
29 * safety devices or systems, Class III medical devices, nuclear facilities,
30 * applications related to the deployment of airbags, or any other applications
31 * that could lead to death, personal injury, or severe property or
32 * environmental damage (individually and collectively, "Critical
33 * Applications"). Customer assumes the sole risk and liability of any use of
34 * Xilinx products in Critical Applications, subject only to applicable laws
35 * and regulations governing limitations on product liability.
37 * THIS COPYRIGHT NOTICE AND DISCLAIMER MUST BE RETAINED AS PART OF THIS FILE
40 *****************************************************************************/
41 /****************************************************************************/
44 * @file xuartps_options.c
46 * The implementation of the options functions for the XUartPs driver.
49 * MODIFICATION HISTORY:
51 * Ver Who Date Changes
52 * ----- ------ -------- -----------------------------------------------
53 * 1.00 drg/jz 01/13/10 First Release
54 * 1.00 sdm 09/27/11 Fixed a bug in XUartPs_SetFlowDelay where the input
55 * value was not being written to the register.
59 *****************************************************************************/
61 /***************************** Include Files ********************************/
65 /************************** Constant Definitions ****************************/
67 /**************************** Type Definitions ******************************/
69 /***************** Macros (Inline Functions) Definitions ********************/
71 /************************** Variable Definitions ****************************/
73 * The following data type is a map from an option to the offset in the
74 * register to which it belongs as well as its bit mask in that register.
83 * Create the table which contains options which are to be processed to get/set
84 * the options. These options are table driven to allow easy maintenance and
85 * expansion of the options.
88 static Mapping OptionsTable[] = {
89 {XUARTPS_OPTION_SET_BREAK, XUARTPS_CR_OFFSET, XUARTPS_CR_STARTBRK},
90 {XUARTPS_OPTION_STOP_BREAK, XUARTPS_CR_OFFSET, XUARTPS_CR_STOPBRK},
91 {XUARTPS_OPTION_RESET_TMOUT, XUARTPS_CR_OFFSET, XUARTPS_CR_TORST},
92 {XUARTPS_OPTION_RESET_TX, XUARTPS_CR_OFFSET, XUARTPS_CR_TXRST},
93 {XUARTPS_OPTION_RESET_RX, XUARTPS_CR_OFFSET, XUARTPS_CR_RXRST},
94 {XUARTPS_OPTION_ASSERT_RTS, XUARTPS_MODEMCR_OFFSET,
96 {XUARTPS_OPTION_ASSERT_DTR, XUARTPS_MODEMCR_OFFSET,
98 {XUARTPS_OPTION_SET_FCM, XUARTPS_MODEMCR_OFFSET, XUARTPS_MODEMCR_FCM}
101 /* Create a constant for the number of entries in the table */
103 #define XUARTPS_NUM_OPTIONS (sizeof(OptionsTable) / sizeof(Mapping))
105 /************************** Function Prototypes *****************************/
107 /****************************************************************************/
110 * Gets the options for the specified driver instance. The options are
111 * implemented as bit masks such that multiple options may be enabled or
112 * disabled simulataneously.
114 * @param InstancePtr is a pointer to the XUartPs instance.
118 * The current options for the UART. The optionss are bit masks that are
119 * contained in the file xuartps.h and named XUARTPS_OPTION_*.
123 *****************************************************************************/
124 u16 XUartPs_GetOptions(XUartPs *InstancePtr)
131 * Assert validates the input arguments
133 Xil_AssertNonvoid(InstancePtr != NULL);
134 Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
137 * Loop thru the options table to map the physical options in the
138 * registers of the UART to the logical options to be returned
140 for (Index = 0; Index < XUARTPS_NUM_OPTIONS; Index++) {
141 Register = XUartPs_ReadReg(InstancePtr->Config.BaseAddress,
146 * If the bit in the register which correlates to the option
147 * is set, then set the corresponding bit in the options,
148 * ignoring any bits which are zero since the options variable
149 * is initialized to zero
151 if (Register & OptionsTable[Index].Mask) {
152 Options |= OptionsTable[Index].Option;
159 /****************************************************************************/
162 * Sets the options for the specified driver instance. The options are
163 * implemented as bit masks such that multiple options may be enabled or
164 * disabled simultaneously.
166 * The GetOptions function may be called to retrieve the currently enabled
167 * options. The result is ORed in the desired new settings to be enabled and
168 * ANDed with the inverse to clear the settings to be disabled. The resulting
169 * value is then used as the options for the SetOption function call.
171 * @param InstancePtr is a pointer to the XUartPs instance.
172 * @param Options contains the options to be set which are bit masks
173 * contained in the file xuartps.h and named XUARTPS_OPTION_*.
179 *****************************************************************************/
180 void XUartPs_SetOptions(XUartPs *InstancePtr, u16 Options)
186 * Assert validates the input arguments
188 Xil_AssertVoid(InstancePtr != NULL);
189 Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
192 * Loop thru the options table to map the logical options to the
193 * physical options in the registers of the UART.
195 for (Index = 0; Index < XUARTPS_NUM_OPTIONS; Index++) {
198 * Read the register which contains option so that the register
199 * can be changed without destoying any other bits of the
202 Register = XUartPs_ReadReg(InstancePtr->Config.BaseAddress,
207 * If the option is set in the input, then set the corresponding
208 * bit in the specified register, otherwise clear the bit in
211 if (Options & OptionsTable[Index].Option) {
212 Register |= OptionsTable[Index].Mask;
215 Register &= ~OptionsTable[Index].Mask;
218 /* Write the new value to the register to set the option */
219 XUartPs_WriteReg(InstancePtr->Config.BaseAddress,
220 OptionsTable[Index].RegisterOffset,
226 /****************************************************************************/
229 * This function gets the receive FIFO trigger level. The receive trigger
230 * level indicates the number of bytes in the receive FIFO that cause a receive
231 * data event (interrupt) to be generated.
233 * @param InstancePtr is a pointer to the XUartPs instance.
235 * @return The current receive FIFO trigger level. This is a value
240 *****************************************************************************/
241 u8 XUartPs_GetFifoThreshold(XUartPs *InstancePtr)
246 * Assert validates the input arguments
248 Xil_AssertNonvoid(InstancePtr != NULL);
249 Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
252 * Read the value of the FIFO control register so that the threshold
253 * can be retrieved, this read takes special register processing
255 RtrigRegister = (u8) XUartPs_ReadReg(InstancePtr->Config.BaseAddress,
256 XUARTPS_RXWM_OFFSET);
258 /* Return only the trigger level from the register value */
260 return (RtrigRegister & XUARTPS_RXWM_MASK);
263 /****************************************************************************/
266 * This functions sets the receive FIFO trigger level. The receive trigger
267 * level specifies the number of bytes in the receive FIFO that cause a receive
268 * data event (interrupt) to be generated.
270 * @param InstancePtr is a pointer to the XUartPs instance.
271 * @param TriggerLevel contains the trigger level to set.
277 *****************************************************************************/
278 void XUartPs_SetFifoThreshold(XUartPs *InstancePtr, u8 TriggerLevel)
283 * Assert validates the input arguments
285 Xil_AssertVoid(InstancePtr != NULL);
286 Xil_AssertVoid(TriggerLevel <= XUARTPS_RXWM_MASK);
287 Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
289 RtrigRegister = TriggerLevel & XUARTPS_RXWM_MASK;
292 * Write the new value for the FIFO control register to it such that the
293 * threshold is changed
295 XUartPs_WriteReg(InstancePtr->Config.BaseAddress,
296 XUARTPS_RXWM_OFFSET, RtrigRegister);
300 /****************************************************************************/
303 * This function gets the modem status from the specified UART. The modem
304 * status indicates any changes of the modem signals. This function allows
305 * the modem status to be read in a polled mode. The modem status is updated
306 * whenever it is read such that reading it twice may not yield the same
309 * @param InstancePtr is a pointer to the XUartPs instance.
313 * The modem status which are bit masks that are contained in the file
314 * xuartps.h and named XUARTPS_MODEM_*.
318 * The bit masks used for the modem status are the exact bits of the modem
319 * status register with no abstraction.
321 *****************************************************************************/
322 u16 XUartPs_GetModemStatus(XUartPs *InstancePtr)
324 u32 ModemStatusRegister;
327 * Assert validates the input arguments
329 Xil_AssertNonvoid(InstancePtr != NULL);
330 Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
332 /* Read the modem status register to return
334 ModemStatusRegister = XUartPs_ReadReg(InstancePtr->Config.BaseAddress,
335 XUARTPS_MODEMSR_OFFSET);
336 return ModemStatusRegister;
339 /****************************************************************************/
342 * This function determines if the specified UART is sending data.
344 * @param InstancePtr is a pointer to the XUartPs instance.
347 * - TRUE if the UART is sending data
348 * - FALSE if UART is not sending data
352 *****************************************************************************/
353 u32 XUartPs_IsSending(XUartPs *InstancePtr)
355 u32 ChanStatRegister;
358 * Assert validates the input arguments
360 Xil_AssertNonvoid(InstancePtr != NULL);
361 Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
364 * Read the channel status register to determine if the transmitter is
367 ChanStatRegister = XUartPs_ReadReg(InstancePtr->Config.BaseAddress,
371 * If the transmitter is active, or the TX FIFO is not empty, then indicate
372 * that the UART is still sending some data
374 return ((XUARTPS_SR_TACTIVE == (ChanStatRegister &
375 XUARTPS_SR_TACTIVE)) ||
376 (XUARTPS_SR_TXEMPTY != (ChanStatRegister &
377 XUARTPS_SR_TXEMPTY)));
380 /****************************************************************************/
383 * This function gets the operational mode of the UART. The UART can operate
384 * in one of four modes: Normal, Local Loopback, Remote Loopback, or automatic
387 * @param InstancePtr is a pointer to the XUartPs instance.
391 * The operational mode is specified by constants defined in xuartps.h. The
392 * constants are named XUARTPS_OPER_MODE_*
396 *****************************************************************************/
397 u8 XUartPs_GetOperMode(XUartPs *InstancePtr)
403 * Assert validates the input arguments
405 Xil_AssertNonvoid(InstancePtr != NULL);
406 Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
409 * Read the Mode register.
412 XUartPs_ReadReg(InstancePtr->Config.BaseAddress,
415 ModeRegister &= XUARTPS_MR_CHMODE_MASK;
417 * Return the constant
419 switch (ModeRegister) {
420 case XUARTPS_MR_CHMODE_NORM:
421 OperMode = XUARTPS_OPER_MODE_NORMAL;
423 case XUARTPS_MR_CHMODE_ECHO:
424 OperMode = XUARTPS_OPER_MODE_AUTO_ECHO;
426 case XUARTPS_MR_CHMODE_L_LOOP:
427 OperMode = XUARTPS_OPER_MODE_LOCAL_LOOP;
429 case XUARTPS_MR_CHMODE_R_LOOP:
430 OperMode = XUARTPS_OPER_MODE_REMOTE_LOOP;
433 OperMode = (u8) ((ModeRegister & XUARTPS_MR_CHMODE_MASK) >>
434 XUARTPS_MR_CHMODE_SHIFT);
440 /****************************************************************************/
443 * This function sets the operational mode of the UART. The UART can operate
444 * in one of four modes: Normal, Local Loopback, Remote Loopback, or automatic
447 * @param InstancePtr is a pointer to the XUartPs instance.
448 * @param OperationMode is the mode of the UART.
454 *****************************************************************************/
455 void XUartPs_SetOperMode(XUartPs *InstancePtr, u8 OperationMode)
460 * Assert validates the input arguments.
462 Xil_AssertVoid(InstancePtr != NULL);
463 Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
464 Xil_AssertVoid(OperationMode <= XUARTPS_OPER_MODE_REMOTE_LOOP);
467 * Read the Mode register.
470 XUartPs_ReadReg(InstancePtr->Config.BaseAddress,
474 * Set the correct value by masking the bits, then ORing the const.
476 ModeRegister &= ~XUARTPS_MR_CHMODE_MASK;
478 switch (OperationMode) {
479 case XUARTPS_OPER_MODE_NORMAL:
480 ModeRegister |= XUARTPS_MR_CHMODE_NORM;
482 case XUARTPS_OPER_MODE_AUTO_ECHO:
483 ModeRegister |= XUARTPS_MR_CHMODE_ECHO;
485 case XUARTPS_OPER_MODE_LOCAL_LOOP:
486 ModeRegister |= XUARTPS_MR_CHMODE_L_LOOP;
488 case XUARTPS_OPER_MODE_REMOTE_LOOP:
489 ModeRegister |= XUARTPS_MR_CHMODE_R_LOOP;
493 XUartPs_WriteReg(InstancePtr->Config.BaseAddress, XUARTPS_MR_OFFSET,
498 /****************************************************************************/
501 * This function sets the Flow Delay.
502 * 0 - 3: Flow delay inactive
503 * 4 - 32: If Flow Control mode is enabled, UART_rtsN is deactivated when the
504 * receive FIFO fills to this level.
506 * @param InstancePtr is a pointer to the XUartPs instance.
510 * The Flow Delay is specified by constants defined in xuartps_hw.h. The
511 * constants are named XUARTPS_FLOWDEL*
515 *****************************************************************************/
516 u8 XUartPs_GetFlowDelay(XUartPs *InstancePtr)
521 * Assert validates the input arguments
523 Xil_AssertNonvoid(InstancePtr != NULL);
524 Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
527 * Read the Mode register.
529 FdelRegister = XUartPs_ReadReg(InstancePtr->Config.BaseAddress,
530 XUARTPS_FLOWDEL_OFFSET);
533 * Return the contents of the flow delay register
535 return (u8) (FdelRegister & XUARTPS_FLOWDEL_MASK);
538 /****************************************************************************/
541 * This function sets the Flow Delay.
542 * 0 - 3: Flow delay inactive
543 * 4 - 63: If Flow Control mode is enabled, UART_rtsN is deactivated when the
544 * receive FIFO fills to this level.
546 * @param InstancePtr is a pointer to the XUartPs instance.
547 * @param FlowDelayValue is the Setting for the flow delay.
553 *****************************************************************************/
554 void XUartPs_SetFlowDelay(XUartPs *InstancePtr, u8 FlowDelayValue)
559 * Assert validates the input arguments
561 Xil_AssertVoid(InstancePtr != NULL);
562 Xil_AssertVoid(FlowDelayValue > XUARTPS_FLOWDEL_MASK);
563 Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
566 * Set the correct value by shifting the input constant, then masking
569 FdelRegister = (FlowDelayValue & XUARTPS_FLOWDEL_MASK);
571 XUartPs_WriteReg(InstancePtr->Config.BaseAddress,
572 XUARTPS_FLOWDEL_OFFSET, FdelRegister);
576 /****************************************************************************/
579 * This function gets the Receive Timeout of the UART.
581 * @param InstancePtr is a pointer to the XUartPs instance.
583 * @return The current setting for receive time out.
587 *****************************************************************************/
588 u8 XUartPs_GetRecvTimeout(XUartPs *InstancePtr)
593 * Assert validates the input arguments
595 Xil_AssertNonvoid(InstancePtr != NULL);
596 Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
599 * Read the Recieve Timeout register.
601 RtoRegister = XUartPs_ReadReg(InstancePtr->Config.BaseAddress,
602 XUARTPS_RXTOUT_OFFSET);
605 * Return the contents of the mode register shifted appropriately
607 return (RtoRegister & XUARTPS_RXTOUT_MASK);
610 /****************************************************************************/
613 * This function sets the Receive Timeout of the UART.
615 * @param InstancePtr is a pointer to the XUartPs instance.
616 * @param RecvTimeout setting allows the UART to detect an idle connection
617 * on the reciever data line.
618 * Timeout duration = RecvTimeout x 4 x Bit Period. 0 disables the
625 *****************************************************************************/
626 void XUartPs_SetRecvTimeout(XUartPs *InstancePtr, u8 RecvTimeout)
631 * Assert validates the input arguments
633 Xil_AssertVoid(InstancePtr != NULL);
634 Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
637 * Set the correct value by masking the bits
639 RtoRegister = (RecvTimeout & XUARTPS_RXTOUT_MASK);
641 XUartPs_WriteReg(InstancePtr->Config.BaseAddress,
642 XUARTPS_RXTOUT_OFFSET, RtoRegister);
645 * Configure CR to restart the receiver timeout counter
648 XUartPs_ReadReg(InstancePtr->Config.BaseAddress,
650 XUartPs_WriteReg(InstancePtr->Config.BaseAddress, XUARTPS_CR_OFFSET,
651 (RtoRegister | XUARTPS_CR_TORST));
654 /****************************************************************************/
657 * Sets the data format for the device. The data format includes the
658 * baud rate, number of data bits, number of stop bits, and parity. It is the
659 * caller's responsibility to ensure that the UART is not sending or receiving
660 * data when this function is called.
662 * @param InstancePtr is a pointer to the XUartPs instance.
663 * @param FormatPtr is a pointer to a format structure containing the data
667 * - XST_SUCCESS if the data format was successfully set.
668 * - XST_UART_BAUD_ERROR indicates the baud rate could not be
669 * set because of the amount of error with the baud rate and
670 * the input clock frequency.
671 * - XST_INVALID_PARAM if one of the parameters was not valid.
675 * The data types in the format type, data bits and parity, are 32 bit fields
676 * to prevent a compiler warning.
677 * The asserts in this function will cause a warning if these fields are
681 *****************************************************************************/
682 int XUartPs_SetDataFormat(XUartPs *InstancePtr,
683 XUartPsFormat * FormatPtr)
688 Xil_AssertNonvoid(InstancePtr != NULL);
689 Xil_AssertNonvoid(FormatPtr != NULL);
690 Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
693 * Verify the inputs specified are valid
695 if ((FormatPtr->DataBits > XUARTPS_FORMAT_6_BITS) ||
696 (FormatPtr->StopBits > XUARTPS_FORMAT_2_STOP_BIT) ||
697 (FormatPtr->Parity > XUARTPS_FORMAT_NO_PARITY)) {
698 return XST_INVALID_PARAM;
702 * Try to set the baud rate and if it's not successful then don't
703 * continue altering the data format, this is done first to avoid the
704 * format from being altered when an error occurs
706 Status = XUartPs_SetBaudRate(InstancePtr, FormatPtr->BaudRate);
707 if (Status != XST_SUCCESS) {
712 XUartPs_ReadReg(InstancePtr->Config.BaseAddress,
716 * Set the length of data (8,7,6) by first clearing out the bits
717 * that control it in the register, then set the length in the register
719 ModeRegister &= ~XUARTPS_MR_CHARLEN_MASK;
720 ModeRegister |= (FormatPtr->DataBits << XUARTPS_MR_CHARLEN_SHIFT);
723 * Set the number of stop bits in the mode register by first clearing
724 * out the bits that control it in the register, then set the number
725 * of stop bits in the register.
727 ModeRegister &= ~XUARTPS_MR_STOPMODE_MASK;
728 ModeRegister |= (FormatPtr->StopBits << XUARTPS_MR_STOPMODE_SHIFT);
731 * Set the parity by first clearing out the bits that control it in the
732 * register, then set the bits in the register, the default is no parity
733 * after clearing the register bits
735 ModeRegister &= ~XUARTPS_MR_PARITY_MASK;
736 ModeRegister |= (FormatPtr->Parity << XUARTPS_MR_PARITY_SHIFT);
739 * Update the mode register
741 XUartPs_WriteReg(InstancePtr->Config.BaseAddress, XUARTPS_MR_OFFSET,
747 /****************************************************************************/
750 * Gets the data format for the specified UART. The data format includes the
751 * baud rate, number of data bits, number of stop bits, and parity.
753 * @param InstancePtr is a pointer to the XUartPs instance.
754 * @param FormatPtr is a pointer to a format structure that will contain
755 * the data format after this call completes.
762 *****************************************************************************/
763 void XUartPs_GetDataFormat(XUartPs *InstancePtr, XUartPsFormat * FormatPtr)
769 * Assert validates the input arguments
771 Xil_AssertVoid(InstancePtr != NULL);
772 Xil_AssertVoid(FormatPtr != NULL);
773 Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
776 * Get the baud rate from the instance, this is not retrieved from the
777 * hardware because it is only kept as a divisor such that it is more
778 * difficult to get back to the baud rate
780 FormatPtr->BaudRate = InstancePtr->BaudRate;
782 ModeRegister = XUartPs_ReadReg(InstancePtr->Config.BaseAddress,
786 * Get the length of data (8,7,6,5)
788 FormatPtr->DataBits =
789 (ModeRegister & XUARTPS_MR_CHARLEN_MASK) >>
790 XUARTPS_MR_CHARLEN_SHIFT;
793 * Get the number of stop bits
795 FormatPtr->StopBits =
796 (ModeRegister & XUARTPS_MR_STOPMODE_MASK) >>
797 XUARTPS_MR_STOPMODE_SHIFT;
800 * Determine what parity is
803 (ModeRegister & XUARTPS_MR_PARITY_MASK) >>
804 XUARTPS_MR_PARITY_SHIFT;