?? xuartns550.c
字號:
/* $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 zero bytes were sent.** In a polled mode, this function will only send as much data as the UART can* buffer, either in the transmitter or in the FIFO if present and enabled. The* application may need to call it repeatedly to send a buffer.** In interrupt mode, this function will start sending the specified buffer and* then the interrupt handler of the driver will continue sending data until the* buffer has been sent. A callback function, as specified by the application,* will be called to indicate the completion of sending the buffer.** @param InstancePtr is a pointer to the XUartNs550 instance to be worked on.* @param BufferPtr is pointer to a buffer of data to be sent.* @param NumBytes contains the number of bytes to be sent. A value of zero* will stop a previous send operation that is in progress in interrupt* mode. Any data that was already put into the transmit FIFO will be* sent.** @return** The number of bytes actually sent.** @note** The number of bytes is not asserted so that this function may be called with* a value of zero to stop an operation that is already in progress.* <br><br>* This function and the XUartNs550_SetOptions() function modify shared data* such that there may be a need for mutual exclusion in a multithreaded* environment and if XUartNs550_SetOptions() if called from a handler.******************************************************************************/unsigned int XUartNs550_Send(XUartNs550 *InstancePtr, Xuint8 *BufferPtr, unsigned int NumBytes){ unsigned int BytesSent; Xuint8 IerRegister; /* * Assert validates the input arguments */ XASSERT_NONVOID(InstancePtr != XNULL); XASSERT_NONVOID(BufferPtr != XNULL); XASSERT_NONVOID(InstancePtr->IsReady == XCOMPONENT_IS_READY); XASSERT_NONVOID(((signed)NumBytes) >= 0); /* Enter a critical region by disabling the UART transmit interrupts to * allow this call to stop a previous operation that may be interrupt * driven, only stop the transmit interrupt since this critical region is * not really exited in the normal manner */ IerRegister = XIo_In8(InstancePtr->BaseAddress + XUN_IER_OFFSET); XIo_Out8(InstancePtr->BaseAddress + XUN_IER_OFFSET, IerRegister & ~XUN_IER_TX_EMPTY); /* Setup the specified buffer to be sent by setting the instance * variables so it can be sent with polled or interrupt mode */ InstancePtr->SendBuffer.RequestedBytes = NumBytes; InstancePtr->SendBuffer.RemainingBytes = NumBytes; InstancePtr->SendBuffer.NextBytePtr = BufferPtr; /* Send the buffer using the UART and return the number of bytes sent */ BytesSent = XUartNs550_SendBuffer(InstancePtr); /* The critical region is not exited in this function because of the way * the transmit interrupts work. The other function called enables the * tranmit interrupt such that this function can't restore a value to the * interrupt enable register and does not need to exit the critical region. */ return BytesSent;}/****************************************************************************//**** This function will attempt to receive a specified number of bytes of data* from the UART and store it into the specified buffer. This function is* designed for either polled or interrupt driven modes. It is non-blocking* such that it will return if no data has already received by the UART.** In a polled mode, this function will only receive as much data as the UART* can buffer, either in the receiver or in the FIFO if present and enabled.* The application may need to call it repeatedly to receive a buffer. Polled* mode is the default mode of operation for the driver.** In interrupt mode, this function will start receiving and then the interrupt* handler of the driver will continue receiving data until the buffer has been* received. A callback function, as specified by the application, will be called* to indicate the completion of receiving the buffer or when any receive errors* or timeouts occur. Interrupt mode must be enabled using the SetOptions function.** @param InstancePtr is a pointer to the XUartNs550 instance to be worked on.* @param BufferPtr is pointer to buffer for data to be received into* @param NumBytes is the number of bytes to be received. A value of zero will* stop a previous receive operation that is in progress in interrupt mode.** @return** The number of bytes received.** @note** The number of bytes is not asserted so that this function may be called with* a value of zero to stop an operation that is already in progress.******************************************************************************/unsigned int XUartNs550_Recv(XUartNs550 *InstancePtr, Xuint8 *BufferPtr, unsigned int NumBytes){ unsigned int ReceivedCount; Xuint8 IerRegister; /* * Assert validates the input arguments */ XASSERT_NONVOID(InstancePtr != XNULL); XASSERT_NONVOID(BufferPtr != XNULL); XASSERT_NONVOID(InstancePtr->IsReady == XCOMPONENT_IS_READY); XASSERT_NONVOID(((signed)NumBytes) >= 0); /* Enter a critical region by disabling all the UART interrupts to allow * this call to stop a previous operation that may be interrupt driven */ IerRegister = XIo_In8(InstancePtr->BaseAddress + XUN_IER_OFFSET); XIo_Out8(InstancePtr->BaseAddress + XUN_IER_OFFSET, 0); /* Setup the specified buffer to be received by setting the instance * variables so it can be received with polled or interrupt mode */ InstancePtr->ReceiveBuffer.RequestedBytes = NumBytes; InstancePtr->ReceiveBuffer.RemainingBytes = NumBytes; InstancePtr->ReceiveBuffer.NextBytePtr = BufferPtr; /* Receive the data from the UART and return the number of bytes * received */ ReceivedCount = XUartNs550_ReceiveBuffer(InstancePtr); /* Restore the interrupt enable register to it's previous value such * that the critical region is exited */ XIo_Out8(InstancePtr->BaseAddress + XUN_IER_OFFSET, IerRegister); return ReceivedCount;}/****************************************************************************//**** This function sends a buffer that has been previously specified by setting* up the instance variables of the instance. This function is designed to be* an internal function for the XUartNs550 component such that it may be called* from a shell function that sets up the buffer or from an interrupt handler.** This function sends the specified buffer of data to the UART in either
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -