/****************************************************************************** * * Copyright (C) 2011 - 2014 Xilinx, Inc. All rights reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * Use of the Software is limited solely to applications: * (a) running on a Xilinx device, or * (b) that interact with a Xilinx device through a bus or interconnect. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * XILINX CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. * * Except as contained in this notice, the name of the Xilinx shall not be used * in advertising or otherwise to promote the sale, use or other dealings in * this Software without prior written authorization from Xilinx. * ******************************************************************************/ /****************************************************************************/ /** * * @file xiomodule_uart.c * * Contains required functions for the XIOModule UART driver. See the * xiomodule.h header file for more details on this driver. * *
* MODIFICATION HISTORY:
*
* Ver   Who  Date     Changes
* ----- ---- -------- -----------------------------------------------
* 1.02a sa   07/25/12 First release
* 1.03a sa   10/16/12 Moved interrupt mode functions to separate file
* 
* *****************************************************************************/ /***************************** Include Files ********************************/ #include "xil_assert.h" #include "xiomodule.h" #include "xiomodule_i.h" #include "xiomodule_l.h" /************************** Constant Definitions ****************************/ /* The following constant defines the amount of error that is allowed for * a specified baud rate. This error is the difference between the actual * baud rate that will be generated using the specified clock and the * desired baud rate. */ #define XUN_MAX_BAUD_ERROR_RATE 3 /* max % error allowed */ /**************************** Type Definitions ******************************/ /***************** Macros (Inline Functions) Definitions ********************/ /************************** Function Prototypes *****************************/ static void StubHandler(void *CallBackRef, unsigned int ByteCount); /************************** Variable Definitions ****************************/ /****************************************************************************/ /** * * Initialize a XIOModule instance. This function disables the UART * interrupts. The baud rate and format of the data are fixed in the hardware * at hardware build time, except if programmable baud rate is selected. * * @param InstancePtr is a pointer to the XIOModule instance. * @param Config is a reference to a structure containing information * about a specific IO Module device. This function initializes an * InstancePtr object for a specific device specified by the * contents of Config. This function can initialize multiple * instance objects with the use of multiple calls giving different * Config information on each call. * @param EffectiveAddr is the device register base address. Use * Config->BaseAddress for this parameters, passing the physical * address. * * @return * - XST_SUCCESS if everything starts up as expected. * * @note The Config and EffectiveAddress arguments are not used by this * function, but are provided to keep the function signature * consistent with other drivers. * *****************************************************************************/ int XIOModule_CfgInitialize(XIOModule *InstancePtr, XIOModule_Config *Config, u32 EffectiveAddr) { u32 NewIER; /* * Assert validates the input arguments */ Xil_AssertNonvoid(InstancePtr != NULL); /* * Set some default values, including setting the callback * handlers to stubs. */ InstancePtr->SendBuffer.NextBytePtr = NULL; InstancePtr->SendBuffer.RemainingBytes = 0; InstancePtr->SendBuffer.RequestedBytes = 0; InstancePtr->ReceiveBuffer.NextBytePtr = NULL; InstancePtr->ReceiveBuffer.RemainingBytes = 0; InstancePtr->ReceiveBuffer.RequestedBytes = 0; InstancePtr->IsReady = XIL_COMPONENT_IS_READY; InstancePtr->RecvHandler = StubHandler; InstancePtr->SendHandler = StubHandler; /* * Modify the IER to disable the UART interrupts */ NewIER = InstancePtr->CurrentIER & 0xFFFFFFF8; XIomodule_Out32(InstancePtr->BaseAddress + XIN_IER_OFFSET, NewIER); InstancePtr->CurrentIER = NewIER; /* * Clear the statistics for this driver */ XIOModule_ClearStats(InstancePtr); return XST_SUCCESS; } /**************************************************************************** * * Sets the baud rate for the specified UART. Checks the input value for * validity and also verifies that the requested rate can be configured to * within the 3 percent error range for RS-232 communications. If the provided * rate is not valid, the current setting is unchanged. * * This function is designed to be an internal function only used within the * XIOModule component. It is necessary for initialization and for the user * available function that sets the data format. * * @param InstancePtr is a pointer to the XIOModule instance. * @param BaudRate to be set in the hardware. * * @return * - XST_SUCCESS if everything configures as expected * - XST_UART_BAUD_ERROR if the requested rate is not available * because there was too much error due to the input clock * * @note None. * *****************************************************************************/ int XIOModule_SetBaudRate(XIOModule *InstancePtr, u32 BaudRate) { u32 Baud8; u32 Baud16; u32 InputClockHz; u32 Divisor; u32 TargetRate; u32 Error; u32 PercentError; /* * Assert validates the input arguments */ Xil_AssertNonvoid(InstancePtr != NULL); Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY); /* * Determine what the divisor should be to get the specified baud * rate based upon the input clock frequency and a baud clock prescaler * of 16, rounded to nearest divisor */ Baud8 = BaudRate << 3; Baud16 = Baud8 << 1; InputClockHz = InstancePtr->CfgPtr->InputClockHz; Divisor = (InputClockHz + Baud8) / Baud16; /* * Check for too much error between the baud rate that will be generated * using the divisor and the expected baud rate, ensuring that the error * is positive due to rounding above */ TargetRate = Divisor * Baud16; if (InputClockHz < TargetRate) Error = TargetRate - InputClockHz; else Error = InputClockHz - TargetRate; /* * Error has total error now compute the percentage multiplied by 100 to * avoid floating point calculations, should be less than 3% as per * RS-232 spec */ PercentError = (Error * 100UL) / InputClockHz; if (PercentError > XUN_MAX_BAUD_ERROR_RATE) { return XST_UART_BAUD_ERROR; } /* * Write the baud rate divisor to the UART Baud Rate Register */ XIOModule_WriteReg(InstancePtr->BaseAddress, XUL_BAUDRATE_OFFSET, Divisor - 1); InstancePtr->CurrentUBRR = Divisor - 1; /* * Save the baud rate in the instance so that the get baud rate function * won't have to calculate it from the divisor */ InstancePtr->CfgPtr->BaudRate = BaudRate; return XST_SUCCESS; } /**************************************************************************** * * This function provides a stub handler such that if the application does not * define a handler but enables interrupts, this function will be called. * * @param CallBackRef has no purpose but is necessary to match the * interface for a handler. * @param ByteCount has no purpose but is necessary to match the * interface for a handler. * * @return None. * * @note None. * *****************************************************************************/ static void StubHandler(void *CallBackRef, unsigned int ByteCount) { /* * Assert occurs always since this is a stub and should never be called */ Xil_AssertVoidAlways(); }