257 lines
8.6 KiB
C
257 lines
8.6 KiB
C
![]() |
/******************************************************************************
|
||
|
*
|
||
|
* 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.
|
||
|
*
|
||
|
* <pre>
|
||
|
* 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
|
||
|
* </pre>
|
||
|
*
|
||
|
*****************************************************************************/
|
||
|
|
||
|
/***************************** 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();
|
||
|
}
|