/* $Id: xuartns550.c,v 1.1 2006/02/17 22:43:40 moleres Exp $ */
/*****************************************************************************
*
* XILINX IS PROVIDING THIS DESIGN, CODE, OR INFORMATION "AS IS"
* AS A COURTESY TO YOU, SOLELY FOR USE IN DEVELOPING PROGRAMS AND
* SOLUTIONS FOR XILINX DEVICES. BY PROVIDING THIS DESIGN, CODE,
* OR INFORMATION AS ONE POSSIBLE IMPLEMENTATION OF THIS FEATURE,
* APPLICATION OR STANDARD, XILINX IS MAKING NO REPRESENTATION
* THAT THIS IMPLEMENTATION IS FREE FROM ANY CLAIMS OF INFRINGEMENT,
* AND YOU ARE RESPONSIBLE FOR OBTAINING ANY RIGHTS YOU MAY REQUIRE
* FOR YOUR IMPLEMENTATION. XILINX EXPRESSLY DISCLAIMS ANY
* WARRANTY WHATSOEVER WITH RESPECT TO THE ADEQUACY OF THE
* IMPLEMENTATION, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OR
* REPRESENTATIONS THAT THIS IMPLEMENTATION IS FREE FROM CLAIMS OF
* INFRINGEMENT, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE.
*
* (c) Copyright 2002-2005 Xilinx Inc.
* All rights reserved.
*
*****************************************************************************/
/****************************************************************************/
/**
*
* @file xuartns550.c
*
* This file contains the required functions for the 16450/16550 UART driver.
* Refer to the header file xuartns550.h for more detailed information.
*
* <pre>
* MODIFICATION HISTORY:
*
* Ver Who Date Changes
* ----- ---- -------- -----------------------------------------------
* 1.00a ecm 08/16/01 First release
* 1.00b jhl 03/11/02 Repartitioned driver for smaller files.
* 1.00b rmm 05/14/03 Fixed diab compiler warnings relating to asserts.
* 1.01a jvb 12/13/05 I changed Initialize() into CfgInitialize(), and made
* CfgInitialize() take a pointer to a config structure
* instead of a device id. I moved Initialize() into
* xgpio_sinit.c, and had Initialize() call CfgInitialize()
* after it retrieved the config structure using the device
* id. I removed include of xparameters.h along with any
* dependencies on xparameters.h and the _g.c config table.
* </pre>
*
*****************************************************************************/
/***************************** Include Files ********************************/
#include "xstatus.h"
#include "xuartns550.h"
#include "xuartns550_i.h"
#include "xio.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 ********************/
/************************** Variable Definitions ****************************/
/************************** Function Prototypes *****************************/
static void XUartNs550_StubHandler(void *CallBackRef, Xuint32 Event,
unsigned int ByteCount);
/****************************************************************************/
/**
*
* Initializes a specific XUartNs550 instance such that it is ready to be used.
* The data format of the device is setup for 8 data bits, 1 stop bit, and no
* parity by default. The baud rate is set to a default value specified by
* Config->DefaultBaudRate if set, otherwise it is set to 19.2K baud. If the
* device has FIFOs (16550), they are enabled and the a receive FIFO threshold
* is set for 8 bytes. The default operating mode of the driver is polled mode.
*
* @param InstancePtr is a pointer to the XUartNs550 instance to be worked on.
* @param Config is a reference to a structure containing information about
* a specific UART 16450/16550 device. XUartNs550_Init initializes an
* InstancePtr object for a specific device specified by the contents
* of Config. XUartNs550_Init can initialize multiple instance objects
* with the use of multiple calls giving different Config information
* on each call.
* @param EffectiveAddr is the device base address in the virtual memory address
* space. The caller is responsible for keeping the address mapping
* from EffectiveAddr to the device physical base address unchanged
* once this function is invoked. Unexpected errors may occur if the
* address mapping changes after this function is called. If address
* translation is not used, use Config->BaseAddress for this parameters,
* passing the physical address instead.
*
* @return
*
* - XST_SUCCESS if initialization was successful
* - XST_UART_BAUD_ERROR if the baud rate is not possible because the input
* clock frequency is not divisible with an acceptable amount of error
*
* @note
*
* None.
*
*****************************************************************************/
XStatus XUartNs550_CfgInitialize(XUartNs550 *InstancePtr,
XUartNs550_Config *Config,
Xuint32 EffectiveAddr)
{
XStatus Status;
Xuint8 LcrRegister;
Xuint32 BaudRate;
/*
* Assert validates the input arguments
*/
XASSERT_NONVOID(InstancePtr != XNULL);
/*
* Setup the data that is from the configuration information
*/
InstancePtr->BaseAddress = EffectiveAddr;
InstancePtr->InputClockHz = Config->InputClockHz;
/*
* Initialize the instance data to some default values and setup a default
* handler
*/
InstancePtr->Handler = XUartNs550_StubHandler;
InstancePtr->SendBuffer.NextBytePtr = XNULL;
InstancePtr->SendBuffer.RemainingBytes = 0;
InstancePtr->SendBuffer.RequestedBytes = 0;
InstancePtr->ReceiveBuffer.NextBytePtr = XNULL;
InstancePtr->ReceiveBuffer.RemainingBytes = 0;
InstancePtr->ReceiveBuffer.RequestedBytes = 0;
/*
* Indicate the instance is now ready to use, initialized without error
*/
InstancePtr->IsReady = XCOMPONENT_IS_READY;
/*
* set the default Baud rate here, can be changed prior to
* starting the device
*/
BaudRate = Config->DefaultBaudRate;
if (! BaudRate)
{
BaudRate = 19200;
}
Status = XUartNs550_SetBaudRate(InstancePtr, BaudRate);
if (Status != XST_SUCCESS)
{
InstancePtr->IsReady = 0;
return Status;
}
/*
* Set up the default format for the data, 8 bit data, 1 stop bit, no
* parity
*/
LcrRegister = XIo_In8(InstancePtr->BaseAddress + XUN_LCR_OFFSET);
XIo_Out8(InstancePtr->BaseAddress + XUN_LCR_OFFSET,
XUN_FORMAT_8_BITS);
/* Enable the FIFOs assuming they are present and set the receive FIFO
* trigger level for 8 bytes assuming that this will work best with most
* baud rates, enabling the FIFOs also clears them, note that this must
* be done with 2 writes, 1st enabling the FIFOs then set the trigger level
*/
XIo_Out8(InstancePtr->BaseAddress + XUN_FCR_OFFSET,
XUN_FIFO_ENABLE);
XIo_Out8(InstancePtr->BaseAddress + XUN_FCR_OFFSET,
XUN_FIFO_ENABLE | XUN_FIFO_RX_TRIG_MSB);
/*
* Clear the statistics for this driver
*/
XUartNs550_mClearStats(InstancePtr);
return XST_SUCCESS;
}
/****************************************************************************/
/**
*
* This functions sends the specified buffer of data using the UART in either
* polled or interrupt driven modes. This function is non-blocking such that it
* will return before the data has been sent by the UART. If the UART is busy
* sending data, it will return and indicate