1 /******************************************************************************
3 * Copyright (C) 2010 - 2015 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 /****************************************************************************/
35 * @file xuartps_options.c
36 * @addtogroup uartps_v3_5
39 * The implementation of the options functions for the XUartPs driver.
42 * MODIFICATION HISTORY:
44 * Ver Who Date Changes
45 * ----- ------ -------- -----------------------------------------------
46 * 1.00 drg/jz 01/13/10 First Release
47 * 1.00 sdm 09/27/11 Fixed a bug in XUartPs_SetFlowDelay where the input
48 * value was not being written to the register.
49 * 3.00 kvn 02/13/15 Modified code for MISRA-C:2012 compliance.
50 * 3.2 rk 07/20/16 Modified the logic for transmission break bit set
54 *****************************************************************************/
56 /***************************** Include Files ********************************/
60 /************************** Constant Definitions ****************************/
62 /**************************** Type Definitions ******************************/
64 /***************** Macros (Inline Functions) Definitions ********************/
66 /************************** Variable Definitions ****************************/
68 * The following data type is a map from an option to the offset in the
69 * register to which it belongs as well as its bit mask in that register.
78 * Create the table which contains options which are to be processed to get/set
79 * the options. These options are table driven to allow easy maintenance and
80 * expansion of the options.
83 static Mapping OptionsTable[] = {
84 {XUARTPS_OPTION_SET_BREAK, XUARTPS_CR_OFFSET, XUARTPS_CR_STARTBRK},
85 {XUARTPS_OPTION_STOP_BREAK, XUARTPS_CR_OFFSET, XUARTPS_CR_STOPBRK},
86 {XUARTPS_OPTION_RESET_TMOUT, XUARTPS_CR_OFFSET, XUARTPS_CR_TORST},
87 {XUARTPS_OPTION_RESET_TX, XUARTPS_CR_OFFSET, XUARTPS_CR_TXRST},
88 {XUARTPS_OPTION_RESET_RX, XUARTPS_CR_OFFSET, XUARTPS_CR_RXRST},
89 {XUARTPS_OPTION_ASSERT_RTS, XUARTPS_MODEMCR_OFFSET,
91 {XUARTPS_OPTION_ASSERT_DTR, XUARTPS_MODEMCR_OFFSET,
93 {XUARTPS_OPTION_SET_FCM, XUARTPS_MODEMCR_OFFSET, XUARTPS_MODEMCR_FCM}
96 /* Create a constant for the number of entries in the table */
98 #define XUARTPS_NUM_OPTIONS (sizeof(OptionsTable) / sizeof(Mapping))
100 /************************** Function Prototypes *****************************/
102 /****************************************************************************/
105 * Gets the options for the specified driver instance. The options are
106 * implemented as bit masks such that multiple options may be enabled or
107 * disabled simulataneously.
109 * @param InstancePtr is a pointer to the XUartPs instance.
113 * The current options for the UART. The optionss are bit masks that are
114 * contained in the file xuartps.h and named XUARTPS_OPTION_*.
118 *****************************************************************************/
119 u16 XUartPs_GetOptions(XUartPs *InstancePtr)
125 /* Assert validates the input arguments */
126 Xil_AssertNonvoid(InstancePtr != NULL);
127 Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
130 * Loop thru the options table to map the physical options in the
131 * registers of the UART to the logical options to be returned
133 for (Index = 0U; Index < XUARTPS_NUM_OPTIONS; Index++) {
134 Register = XUartPs_ReadReg(InstancePtr->Config.BaseAddress,
139 * If the bit in the register which correlates to the option
140 * is set, then set the corresponding bit in the options,
141 * ignoring any bits which are zero since the options variable
142 * is initialized to zero
144 if ((Register & OptionsTable[Index].Mask) != (u32)0) {
145 Options |= OptionsTable[Index].Option;
152 /****************************************************************************/
155 * Sets the options for the specified driver instance. The options are
156 * implemented as bit masks such that multiple options may be enabled or
157 * disabled simultaneously.
159 * The GetOptions function may be called to retrieve the currently enabled
160 * options. The result is ORed in the desired new settings to be enabled and
161 * ANDed with the inverse to clear the settings to be disabled. The resulting
162 * value is then used as the options for the SetOption function call.
164 * @param InstancePtr is a pointer to the XUartPs instance.
165 * @param Options contains the options to be set which are bit masks
166 * contained in the file xuartps.h and named XUARTPS_OPTION_*.
172 *****************************************************************************/
173 void XUartPs_SetOptions(XUartPs *InstancePtr, u16 Options)
178 /* Assert validates the input arguments */
179 Xil_AssertVoid(InstancePtr != NULL);
180 Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
183 * Loop thru the options table to map the logical options to the
184 * physical options in the registers of the UART.
186 for (Index = 0U; Index < XUARTPS_NUM_OPTIONS; Index++) {
189 * Read the register which contains option so that the register
190 * can be changed without destoying any other bits of the
193 Register = XUartPs_ReadReg(InstancePtr->Config.BaseAddress,
198 * If the option is set in the input, then set the corresponding
199 * bit in the specified register, otherwise clear the bit in
202 if ((Options & OptionsTable[Index].Option) != (u16)0) {
203 if(OptionsTable[Index].Option == XUARTPS_OPTION_SET_BREAK)
204 Register &= ~XUARTPS_CR_STOPBRK;
205 Register |= OptionsTable[Index].Mask;
208 Register &= ~OptionsTable[Index].Mask;
211 /* Write the new value to the register to set the option */
212 XUartPs_WriteReg(InstancePtr->Config.BaseAddress,
213 OptionsTable[Index].RegisterOffset,
219 /****************************************************************************/
222 * This function gets the receive FIFO trigger level. The receive trigger
223 * level indicates the number of bytes in the receive FIFO that cause a receive
224 * data event (interrupt) to be generated.
226 * @param InstancePtr is a pointer to the XUartPs instance.
228 * @return The current receive FIFO trigger level. This is a value
233 *****************************************************************************/
234 u8 XUartPs_GetFifoThreshold(XUartPs *InstancePtr)
238 /* Assert validates the input arguments */
239 Xil_AssertNonvoid(InstancePtr != NULL);
240 Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
243 * Read the value of the FIFO control register so that the threshold
244 * can be retrieved, this read takes special register processing
246 RtrigRegister = (u8) XUartPs_ReadReg(InstancePtr->Config.BaseAddress,
247 XUARTPS_RXWM_OFFSET);
249 /* Return only the trigger level from the register value */
251 RtrigRegister &= (u8)XUARTPS_RXWM_MASK;
252 return RtrigRegister;
255 /****************************************************************************/
258 * This functions sets the receive FIFO trigger level. The receive trigger
259 * level specifies the number of bytes in the receive FIFO that cause a receive
260 * data event (interrupt) to be generated.
262 * @param InstancePtr is a pointer to the XUartPs instance.
263 * @param TriggerLevel contains the trigger level to set.
269 *****************************************************************************/
270 void XUartPs_SetFifoThreshold(XUartPs *InstancePtr, u8 TriggerLevel)
274 /* Assert validates the input arguments */
275 Xil_AssertVoid(InstancePtr != NULL);
276 Xil_AssertVoid(TriggerLevel <= (u8)XUARTPS_RXWM_MASK);
277 Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
279 RtrigRegister = ((u32)TriggerLevel) & (u32)XUARTPS_RXWM_MASK;
282 * Write the new value for the FIFO control register to it such that the
283 * threshold is changed
285 XUartPs_WriteReg(InstancePtr->Config.BaseAddress,
286 XUARTPS_RXWM_OFFSET, RtrigRegister);
290 /****************************************************************************/
293 * This function gets the modem status from the specified UART. The modem
294 * status indicates any changes of the modem signals. This function allows
295 * the modem status to be read in a polled mode. The modem status is updated
296 * whenever it is read such that reading it twice may not yield the same
299 * @param InstancePtr is a pointer to the XUartPs instance.
303 * The modem status which are bit masks that are contained in the file
304 * xuartps.h and named XUARTPS_MODEM_*.
308 * The bit masks used for the modem status are the exact bits of the modem
309 * status register with no abstraction.
311 *****************************************************************************/
312 u16 XUartPs_GetModemStatus(XUartPs *InstancePtr)
314 u32 ModemStatusRegister;
316 /* Assert validates the input arguments */
317 Xil_AssertNonvoid(InstancePtr != NULL);
318 Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
320 /* Read the modem status register to return
322 ModemStatusRegister = XUartPs_ReadReg(InstancePtr->Config.BaseAddress,
323 XUARTPS_MODEMSR_OFFSET);
324 TmpRegister = (u16)ModemStatusRegister;
328 /****************************************************************************/
331 * This function determines if the specified UART is sending data.
333 * @param InstancePtr is a pointer to the XUartPs instance.
336 * - TRUE if the UART is sending data
337 * - FALSE if UART is not sending data
341 *****************************************************************************/
342 u32 XUartPs_IsSending(XUartPs *InstancePtr)
344 u32 ChanStatRegister;
345 u32 ChanTmpSRegister;
349 /* Assert validates the input arguments */
350 Xil_AssertNonvoid(InstancePtr != NULL);
351 Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
354 * Read the channel status register to determine if the transmitter is
357 ChanStatRegister = XUartPs_ReadReg(InstancePtr->Config.BaseAddress,
361 * If the transmitter is active, or the TX FIFO is not empty, then indicate
362 * that the UART is still sending some data
364 ActiveResult = ChanStatRegister & ((u32)XUARTPS_SR_TACTIVE);
365 EmptyResult = ChanStatRegister & ((u32)XUARTPS_SR_TXEMPTY);
366 ChanTmpSRegister = (((u32)XUARTPS_SR_TACTIVE) == ActiveResult) ||
367 (((u32)XUARTPS_SR_TXEMPTY) != EmptyResult);
369 return ChanTmpSRegister;
372 /****************************************************************************/
375 * This function gets the operational mode of the UART. The UART can operate
376 * in one of four modes: Normal, Local Loopback, Remote Loopback, or automatic
379 * @param InstancePtr is a pointer to the XUartPs instance.
383 * The operational mode is specified by constants defined in xuartps.h. The
384 * constants are named XUARTPS_OPER_MODE_*
388 *****************************************************************************/
389 u8 XUartPs_GetOperMode(XUartPs *InstancePtr)
394 /* Assert validates the input arguments */
395 Xil_AssertNonvoid(InstancePtr != NULL);
396 Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
398 /* Read the Mode register. */
400 XUartPs_ReadReg(InstancePtr->Config.BaseAddress,
403 ModeRegister &= (u32)XUARTPS_MR_CHMODE_MASK;
404 /* Return the constant */
405 switch (ModeRegister) {
406 case XUARTPS_MR_CHMODE_NORM:
407 OperMode = XUARTPS_OPER_MODE_NORMAL;
409 case XUARTPS_MR_CHMODE_ECHO:
410 OperMode = XUARTPS_OPER_MODE_AUTO_ECHO;
412 case XUARTPS_MR_CHMODE_L_LOOP:
413 OperMode = XUARTPS_OPER_MODE_LOCAL_LOOP;
415 case XUARTPS_MR_CHMODE_R_LOOP:
416 OperMode = XUARTPS_OPER_MODE_REMOTE_LOOP;
419 OperMode = (u8) ((ModeRegister & (u32)XUARTPS_MR_CHMODE_MASK) >>
420 XUARTPS_MR_CHMODE_SHIFT);
427 /****************************************************************************/
430 * This function sets the operational mode of the UART. The UART can operate
431 * in one of four modes: Normal, Local Loopback, Remote Loopback, or automatic
434 * @param InstancePtr is a pointer to the XUartPs instance.
435 * @param OperationMode is the mode of the UART.
441 *****************************************************************************/
442 void XUartPs_SetOperMode(XUartPs *InstancePtr, u8 OperationMode)
446 /* Assert validates the input arguments. */
447 Xil_AssertVoid(InstancePtr != NULL);
448 Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
449 Xil_AssertVoid(OperationMode <= XUARTPS_OPER_MODE_REMOTE_LOOP);
451 /* Read the Mode register. */
453 XUartPs_ReadReg(InstancePtr->Config.BaseAddress,
456 /* Set the correct value by masking the bits, then ORing the const. */
457 ModeRegister &= (u32)(~XUARTPS_MR_CHMODE_MASK);
459 switch (OperationMode) {
460 case XUARTPS_OPER_MODE_NORMAL:
461 ModeRegister |= (u32)XUARTPS_MR_CHMODE_NORM;
463 case XUARTPS_OPER_MODE_AUTO_ECHO:
464 ModeRegister |= (u32)XUARTPS_MR_CHMODE_ECHO;
466 case XUARTPS_OPER_MODE_LOCAL_LOOP:
467 ModeRegister |= (u32)XUARTPS_MR_CHMODE_L_LOOP;
469 case XUARTPS_OPER_MODE_REMOTE_LOOP:
470 ModeRegister |= (u32)XUARTPS_MR_CHMODE_R_LOOP;
473 /* Default case made for MISRA-C Compliance. */
477 XUartPs_WriteReg(InstancePtr->Config.BaseAddress, XUARTPS_MR_OFFSET,
482 /****************************************************************************/
485 * This function sets the Flow Delay.
486 * 0 - 3: Flow delay inactive
487 * 4 - 32: If Flow Control mode is enabled, UART_rtsN is deactivated when the
488 * receive FIFO fills to this level.
490 * @param InstancePtr is a pointer to the XUartPs instance.
494 * The Flow Delay is specified by constants defined in xuartps_hw.h. The
495 * constants are named XUARTPS_FLOWDEL*
499 *****************************************************************************/
500 u8 XUartPs_GetFlowDelay(XUartPs *InstancePtr)
504 /* Assert validates the input arguments */
505 Xil_AssertNonvoid(InstancePtr != NULL);
506 Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
508 /* Read the Mode register. */
509 FdelTmpRegister = XUartPs_ReadReg(InstancePtr->Config.BaseAddress,
510 XUARTPS_FLOWDEL_OFFSET);
512 /* Return the contents of the flow delay register */
513 FdelTmpRegister = (u8)(FdelTmpRegister & (u32)XUARTPS_FLOWDEL_MASK);
514 return FdelTmpRegister;
517 /****************************************************************************/
520 * This function sets the Flow Delay.
521 * 0 - 3: Flow delay inactive
522 * 4 - 63: If Flow Control mode is enabled, UART_rtsN is deactivated when the
523 * receive FIFO fills to this level.
525 * @param InstancePtr is a pointer to the XUartPs instance.
526 * @param FlowDelayValue is the Setting for the flow delay.
532 *****************************************************************************/
533 void XUartPs_SetFlowDelay(XUartPs *InstancePtr, u8 FlowDelayValue)
537 /* Assert validates the input arguments */
538 Xil_AssertVoid(InstancePtr != NULL);
539 Xil_AssertVoid(FlowDelayValue > (u8)XUARTPS_FLOWDEL_MASK);
540 Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
543 * Set the correct value by shifting the input constant, then masking
546 FdelRegister = ((u32)FlowDelayValue) & (u32)XUARTPS_FLOWDEL_MASK;
548 XUartPs_WriteReg(InstancePtr->Config.BaseAddress,
549 XUARTPS_FLOWDEL_OFFSET, FdelRegister);
553 /****************************************************************************/
556 * This function gets the Receive Timeout of the UART.
558 * @param InstancePtr is a pointer to the XUartPs instance.
560 * @return The current setting for receive time out.
564 *****************************************************************************/
565 u8 XUartPs_GetRecvTimeout(XUartPs *InstancePtr)
570 /* Assert validates the input arguments */
571 Xil_AssertNonvoid(InstancePtr != NULL);
572 Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
574 /* Read the Receive Timeout register. */
575 RtoRegister = XUartPs_ReadReg(InstancePtr->Config.BaseAddress,
576 XUARTPS_RXTOUT_OFFSET);
578 /* Return the contents of the mode register shifted appropriately */
579 RtoRTmpRegister = (u8)(RtoRegister & (u32)XUARTPS_RXTOUT_MASK);
580 return RtoRTmpRegister;
583 /****************************************************************************/
586 * This function sets the Receive Timeout of the UART.
588 * @param InstancePtr is a pointer to the XUartPs instance.
589 * @param RecvTimeout setting allows the UART to detect an idle connection
590 * on the reciever data line.
591 * Timeout duration = RecvTimeout x 4 x Bit Period. 0 disables the
598 *****************************************************************************/
599 void XUartPs_SetRecvTimeout(XUartPs *InstancePtr, u8 RecvTimeout)
603 /* Assert validates the input arguments */
604 Xil_AssertVoid(InstancePtr != NULL);
605 Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
607 /* Set the correct value by masking the bits */
608 RtoRegister = ((u32)RecvTimeout & (u32)XUARTPS_RXTOUT_MASK);
610 XUartPs_WriteReg(InstancePtr->Config.BaseAddress,
611 XUARTPS_RXTOUT_OFFSET, RtoRegister);
613 /* Configure CR to restart the receiver timeout counter */
615 XUartPs_ReadReg(InstancePtr->Config.BaseAddress,
617 XUartPs_WriteReg(InstancePtr->Config.BaseAddress, XUARTPS_CR_OFFSET,
618 (RtoRegister | XUARTPS_CR_TORST));
621 /****************************************************************************/
624 * Sets the data format for the device. The data format includes the
625 * baud rate, number of data bits, number of stop bits, and parity. It is the
626 * caller's responsibility to ensure that the UART is not sending or receiving
627 * data when this function is called.
629 * @param InstancePtr is a pointer to the XUartPs instance.
630 * @param FormatPtr is a pointer to a format structure containing the data
634 * - XST_SUCCESS if the data format was successfully set.
635 * - XST_UART_BAUD_ERROR indicates the baud rate could not be
636 * set because of the amount of error with the baud rate and
637 * the input clock frequency.
638 * - XST_INVALID_PARAM if one of the parameters was not valid.
642 * The data types in the format type, data bits and parity, are 32 bit fields
643 * to prevent a compiler warning.
644 * The asserts in this function will cause a warning if these fields are
648 *****************************************************************************/
649 s32 XUartPs_SetDataFormat(XUartPs *InstancePtr,
650 XUartPsFormat * FormatPtr)
655 Xil_AssertNonvoid(InstancePtr != NULL);
656 Xil_AssertNonvoid(FormatPtr != NULL);
657 Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
659 /* Verify the inputs specified are valid */
660 if ((FormatPtr->DataBits > ((u32)XUARTPS_FORMAT_6_BITS)) ||
661 (FormatPtr->StopBits > ((u8)XUARTPS_FORMAT_2_STOP_BIT)) ||
662 (FormatPtr->Parity > ((u32)XUARTPS_FORMAT_NO_PARITY))) {
663 Status = XST_INVALID_PARAM;
667 * Try to set the baud rate and if it's not successful then don't
668 * continue altering the data format, this is done first to avoid the
669 * format from being altered when an error occurs
671 Status = XUartPs_SetBaudRate(InstancePtr, FormatPtr->BaudRate);
672 if (Status != (s32)XST_SUCCESS) {
677 XUartPs_ReadReg(InstancePtr->Config.BaseAddress,
681 * Set the length of data (8,7,6) by first clearing out the bits
682 * that control it in the register, then set the length in the register
684 ModeRegister &= (u32)(~XUARTPS_MR_CHARLEN_MASK);
685 ModeRegister |= (FormatPtr->DataBits << XUARTPS_MR_CHARLEN_SHIFT);
688 * Set the number of stop bits in the mode register by first clearing
689 * out the bits that control it in the register, then set the number
690 * of stop bits in the register.
692 ModeRegister &= (u32)(~XUARTPS_MR_STOPMODE_MASK);
693 ModeRegister |= (((u32)FormatPtr->StopBits) << XUARTPS_MR_STOPMODE_SHIFT);
696 * Set the parity by first clearing out the bits that control it in the
697 * register, then set the bits in the register, the default is no parity
698 * after clearing the register bits
700 ModeRegister &= (u32)(~XUARTPS_MR_PARITY_MASK);
701 ModeRegister |= (FormatPtr->Parity << XUARTPS_MR_PARITY_SHIFT);
703 /* Update the mode register */
704 XUartPs_WriteReg(InstancePtr->Config.BaseAddress, XUARTPS_MR_OFFSET,
707 Status = XST_SUCCESS;
713 /****************************************************************************/
716 * Gets the data format for the specified UART. The data format includes the
717 * baud rate, number of data bits, number of stop bits, and parity.
719 * @param InstancePtr is a pointer to the XUartPs instance.
720 * @param FormatPtr is a pointer to a format structure that will contain
721 * the data format after this call completes.
728 *****************************************************************************/
729 void XUartPs_GetDataFormat(XUartPs *InstancePtr, XUartPsFormat * FormatPtr)
734 /* Assert validates the input arguments */
735 Xil_AssertVoid(InstancePtr != NULL);
736 Xil_AssertVoid(FormatPtr != NULL);
737 Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
740 * Get the baud rate from the instance, this is not retrieved from the
741 * hardware because it is only kept as a divisor such that it is more
742 * difficult to get back to the baud rate
744 FormatPtr->BaudRate = InstancePtr->BaudRate;
746 ModeRegister = XUartPs_ReadReg(InstancePtr->Config.BaseAddress,
749 /* Get the length of data (8,7,6,5) */
750 FormatPtr->DataBits =
751 ((ModeRegister & (u32)XUARTPS_MR_CHARLEN_MASK) >>
752 XUARTPS_MR_CHARLEN_SHIFT);
754 /* Get the number of stop bits */
755 FormatPtr->StopBits =
756 (u8)((ModeRegister & (u32)XUARTPS_MR_STOPMODE_MASK) >>
757 XUARTPS_MR_STOPMODE_SHIFT);
759 /* Determine what parity is */
761 (u32)((ModeRegister & (u32)XUARTPS_MR_PARITY_MASK) >>
762 XUARTPS_MR_PARITY_SHIFT);