⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 xqspips.c

📁 自学ZedBoard:使用IP通过ARM PS访问FPGA(源代码)
💻 C
📖 第 1 页 / 共 3 页
字号:
/******************************************************************************** (c) Copyright 2010-12 Xilinx, Inc. All rights reserved.** This file contains confidential and proprietary information of Xilinx, Inc.* and is protected under U.S. and international copyright and other* intellectual property laws.** DISCLAIMER* This disclaimer is not a license and does not grant any rights to the* materials distributed herewith. Except as otherwise provided in a valid* license issued to you by Xilinx, and to the maximum extent permitted by* applicable law: (1) THESE MATERIALS ARE MADE AVAILABLE "AS IS" AND WITH ALL* FAULTS, AND XILINX HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS, EXPRESS,* IMPLIED, OR STATUTORY, INCLUDING BUT NOT LIMITED TO WARRANTIES OF* MERCHANTABILITY, NON-INFRINGEMENT, OR FITNESS FOR ANY PARTICULAR PURPOSE;* and (2) Xilinx shall not be liable (whether in contract or tort, including* negligence, or under any other theory of liability) for any loss or damage* of any kind or nature related to, arising under or in connection with these* materials, including for any direct, or any indirect, special, incidental,* or consequential loss or damage (including loss of data, profits, goodwill,* or any type of loss or damage suffered as a result of any action brought by* a third party) even if such damage or loss was reasonably foreseeable or* Xilinx had been advised of the possibility of the same.** CRITICAL APPLICATIONS* Xilinx products are not designed or intended to be fail-safe, or for use in* any application requiring fail-safe performance, such as life-support or* safety devices or systems, Class III medical devices, nuclear facilities,* applications related to the deployment of airbags, or any other applications* that could lead to death, personal injury, or severe property or* environmental damage (individually and collectively, "Critical* Applications"). Customer assumes the sole risk and liability of any use of* Xilinx products in Critical Applications, subject only to applicable laws* and regulations governing limitations on product liability.** THIS COPYRIGHT NOTICE AND DISCLAIMER MUST BE RETAINED AS PART OF THIS FILE* AT ALL TIMES.*******************************************************************************//*****************************************************************************//**** @file xqspips.c** Contains implements the interface functions of the XQspiPs driver.* See xqspips.h for a detailed description of the device and driver.** <pre>* MODIFICATION HISTORY:** Ver   Who Date     Changes* ----- --- -------- -----------------------------------------------* 1.00  sdm 11/25/10 First release** </pre>*******************************************************************************//***************************** Include Files *********************************/#include "xqspips.h"/************************** Constant Definitions *****************************//**************************** Type Definitions *******************************//** * This typedef defines qspi flash instruction format */typedef struct {	u8 OpCode;	/**< Operational code of the instruction */	u8 InstSize;	/**< Size of the instruction including address bytes */	u8 TxOffset;	/**< Register address where instruction has to be			     written */} XQspiPsInstFormat;/***************** Macros (Inline Functions) Definitions *********************/#define ARRAY_SIZE(Array)		(sizeof(Array) / sizeof((Array)[0]))/************************** Function Prototypes ******************************/static void XQspiPs_GetWriteData(XQspiPs *InstancePtr, u32 *Data, u8 Size);static void XQspiPs_GetReadData(XQspiPs *InstancePtr, u32 Data, u8 Size);static void StubStatusHandler(void *CallBackRef, u32 StatusEvent,				unsigned ByteCount);/************************** Variable Definitions *****************************//* * List of all the QSPI instructions and its format */static XQspiPsInstFormat FlashInst[] = {	{ XQSPIPS_FLASH_OPCODE_WREN, 1, XQSPIPS_TXD_01_OFFSET },	{ XQSPIPS_FLASH_OPCODE_WRDS, 1, XQSPIPS_TXD_01_OFFSET },	{ XQSPIPS_FLASH_OPCODE_RDSR1, 2, XQSPIPS_TXD_10_OFFSET },	{ XQSPIPS_FLASH_OPCODE_RDSR2, 2, XQSPIPS_TXD_10_OFFSET },	{ XQSPIPS_FLASH_OPCODE_WRSR, 2, XQSPIPS_TXD_10_OFFSET },	{ XQSPIPS_FLASH_OPCODE_PP, 4, XQSPIPS_TXD_00_OFFSET },	{ XQSPIPS_FLASH_OPCODE_SE, 4, XQSPIPS_TXD_00_OFFSET },	{ XQSPIPS_FLASH_OPCODE_BE_32K, 4, XQSPIPS_TXD_00_OFFSET },	{ XQSPIPS_FLASH_OPCODE_BE_4K, 4, XQSPIPS_TXD_00_OFFSET },	{ XQSPIPS_FLASH_OPCODE_BE, 1, XQSPIPS_TXD_01_OFFSET },	{ XQSPIPS_FLASH_OPCODE_ERASE_SUS, 1, XQSPIPS_TXD_01_OFFSET },	{ XQSPIPS_FLASH_OPCODE_ERASE_RES, 1, XQSPIPS_TXD_01_OFFSET },	{ XQSPIPS_FLASH_OPCODE_RDID, 4, XQSPIPS_TXD_00_OFFSET },	{ XQSPIPS_FLASH_OPCODE_NORM_READ, 4, XQSPIPS_TXD_00_OFFSET },	{ XQSPIPS_FLASH_OPCODE_FAST_READ, 4, XQSPIPS_TXD_00_OFFSET },	{ XQSPIPS_FLASH_OPCODE_DUAL_READ, 4, XQSPIPS_TXD_00_OFFSET },	{ XQSPIPS_FLASH_OPCODE_QUAD_READ, 4, XQSPIPS_TXD_00_OFFSET },	/* Add all the instructions supported by the flash device */};/*****************************************************************************//**** Initializes a specific XQspiPs instance such that the driver is ready to use.** The state of the device after initialization is:*   - Master mode*   - Active high clock polarity*   - Clock phase 0*   - Baud rate divisor 2*   - Transfer width 32*   - Master reference clock = pclk*   - No chip select active*   - Manual CS and Manual Start disabled** @param	InstancePtr is a pointer to the XQspiPs instance.* @param	ConfigPtr is a reference to a structure containing information*		about a specific QSPI 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 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*		ConfigPtr->Config.BaseAddress for this device.** @return*		- XST_SUCCESS if successful.*		- XST_DEVICE_IS_STARTED if the device is already started.*		It must be stopped to re-initialize.** @note		None.*******************************************************************************/int XQspiPs_CfgInitialize(XQspiPs *InstancePtr, XQspiPs_Config *ConfigPtr,				u32 EffectiveAddr){	Xil_AssertNonvoid(InstancePtr != NULL);	Xil_AssertNonvoid(ConfigPtr != NULL);	/*	 * If the device is busy, disallow the initialize and return a status	 * indicating it is already started. This allows the user to stop the	 * device and re-initialize, but prevents a user from inadvertently	 * initializing. This assumes the busy flag is cleared at startup.	 */	if (InstancePtr->IsBusy == TRUE) {		return XST_DEVICE_IS_STARTED;	}	/*	 * Set some default values.	 */	InstancePtr->IsBusy = FALSE;	InstancePtr->Config.BaseAddress = EffectiveAddr;	InstancePtr->StatusHandler = StubStatusHandler;	InstancePtr->SendBufferPtr = NULL;	InstancePtr->RecvBufferPtr = NULL;	InstancePtr->RequestedBytes = 0;	InstancePtr->RemainingBytes = 0;	InstancePtr->IsReady = XIL_COMPONENT_IS_READY;	/*	 * Reset the QSPI device to get it into its initial state. It is	 * expected that device configuration will take place after this	 * initialization is done, but before the device is started.	 */	XQspiPs_Reset(InstancePtr);	return XST_SUCCESS;}/*****************************************************************************//**** Resets the QSPI device. Reset must only be called after the driver has been* initialized. Any data transfer that is in progress is aborted.** The upper layer software is responsible for re-configuring (if necessary)* and restarting the QSPI device after the reset.** @param	InstancePtr is a pointer to the XQspiPs instance.** @return	None.** @note		None.*******************************************************************************/void XQspiPs_Reset(XQspiPs *InstancePtr){	Xil_AssertVoid(InstancePtr != NULL);	Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);	/*	 * Abort any transfer that is in progress	 */	XQspiPs_Abort(InstancePtr);	/*	 * Reset any values that are not reset by the hardware reset such that	 * the software state matches the hardware device	 */	XQspiPs_WriteReg(InstancePtr->Config.BaseAddress, XQSPIPS_CR_OFFSET,			  XQSPIPS_CR_RESET_STATE);}/*****************************************************************************//**** Aborts a transfer in progress by disabling the device and resetting the FIFOs* if present. The byte counts are cleared, the busy flag is cleared, and mode* fault is cleared.** @param	InstancePtr is a pointer to the XQspiPs instance.** @return	None.** @note** This function does a read/modify/write of the control register. The user of* this function needs to take care of critical sections.*******************************************************************************/void XQspiPs_Abort(XQspiPs *InstancePtr){	XQspiPs_Disable(InstancePtr->Config.BaseAddress);	/*	 * Clear the RX FIFO and drop any data.	 */	while ((XQspiPs_ReadReg(InstancePtr->Config.BaseAddress,		 XQSPIPS_SR_OFFSET) & XQSPIPS_IXR_RXNEMPTY_MASK) != 0) {		XQspiPs_ReadReg(InstancePtr->Config.BaseAddress,				 XQSPIPS_RXD_OFFSET);	}	/*	 * Clear mode fault condition.	 */	XQspiPs_WriteReg(InstancePtr->Config.BaseAddress,			  XQSPIPS_SR_OFFSET, XQSPIPS_IXR_MODF_MASK);	InstancePtr->RemainingBytes = 0;	InstancePtr->RequestedBytes = 0;	InstancePtr->IsBusy = FALSE;}/*****************************************************************************//**** Transfers specified data on the QSPI bus. If the QSPI device is configured as* a master, this function initiates bus communication and sends/receives the* data to/from the selected QSPI slave. If the QSPI device is configured as a* slave, this function prepares the buffers to be sent/received when selected* by a master. For every byte sent, a byte is received.** The caller has the option of providing two different buffers for send and* receive, or one buffer for both send and receive, or no buffer for receive.* The receive buffer must be at least as big as the send buffer to prevent* unwanted memory writes. This implies that the byte count passed in as an* argument must be the smaller of the two buffers if they differ in size.* Here are some sample usages:* <pre>*   XQspiPs_Transfer(InstancePtr, SendBuf, RecvBuf, ByteCount)*	The caller wishes to send and receive, and provides two different*	buffers for send and receive.**   XQspiPs_Transfer(InstancePtr, SendBuf, NULL, ByteCount)*	The caller wishes only to send and does not care about the received*	data. The driver ignores the received data in this case.**   XQspiPs_Transfer(InstancePtr, SendBuf, SendBuf, ByteCount)*	The caller wishes to send and receive, but provides the same buffer*	for doing both. The driver sends the data and overwrites the send*	buffer with received data as it transfers the data.**   XQspiPs_Transfer(InstancePtr, RecvBuf, RecvBuf, ByteCount)*	The caller wishes to only receive and does not care about sending*	data.  In this case, the caller must still provide a send buffer, but*	it can be the same as the receive buffer if the caller does not care*	what it sends.  The device must send N bytes of data if it wishes to*	receive N bytes of data.* </pre>* Although this function takes entire buffers as arguments, the driver can only* transfer a limited number of bytes at a time, limited by the size of the* FIFO. A call to this function only starts the transfer, then subsequent* transfers of the data is performed by the interrupt service routine until* the entire buffer has been transferred. The status callback function is* called when the entire buffer has been sent/received.** This function is non-blocking. As a master, the SetSlaveSelect function must* be called prior to this function.** @param	InstancePtr is a pointer to the XQspiPs instance.* @param	SendBufPtr is a pointer to a data buffer that needs to be*		transmitted. This buffer must not be NULL.* @param	RecvBufPtr is a pointer to a buffer for received data.*		This argument can be NULL if do not care about receiving.* @param	ByteCount contains the number of bytes to send/receive.*		The number of bytes received always equals the number of bytes*		sent.* @param	IsInst specifies whether the first byte(s) in the transmit*		buffer is a serial flash instruction.** @return*		- XST_SUCCESS if the buffers are successfully handed off to the*		  device for transfer.*		- XST_DEVICE_BUSY indicates that a data transfer is already in*		  progress. This is determined by the driver.** @note** This function is not thread-safe.  The higher layer software must ensure that* no two threads are transferring data on the QSPI bus at the same time.*******************************************************************************/int XQspiPs_Transfer(XQspiPs *InstancePtr, u8 *SendBufPtr, u8 *RecvBufPtr,		      unsigned ByteCount, int IsInst){	u32 ControlReg;	u8 Instruction;	u32 Data;	unsigned int Index;	XQspiPsInstFormat *CurrInst;	/*	 * The RecvBufPtr argument can be null	 */	Xil_AssertNonvoid(InstancePtr != NULL);	Xil_AssertNonvoid(SendBufPtr != NULL);	Xil_AssertNonvoid(ByteCount > 0);	Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);	Xil_AssertNonvoid(IsInst <= XQSPIPS_IS_INST);	/*	 * Check whether there is another transfer in progress. Not thread-safe.	 */	if (InstancePtr->IsBusy) {		return XST_DEVICE_BUSY;	}	/*	 * Set the busy flag, which will be cleared in the ISR when the	 * transfer is entirely done.	 */	InstancePtr->IsBusy = TRUE;	/*	 * Set up buffer pointers.	 */	InstancePtr->SendBufferPtr = SendBufPtr;	InstancePtr->RecvBufferPtr = RecvBufPtr;	InstancePtr->RequestedBytes = ByteCount;	InstancePtr->RemainingBytes = ByteCount;	/*	 * If the slave select lines are "Forced" or under manual control,	 * set the slave selects now, before beginning the transfer.	 */	ControlReg = XQspiPs_ReadReg(InstancePtr->Config.BaseAddress,				      XQSPIPS_CR_OFFSET);	if (0 != (ControlReg & XQSPIPS_CR_SSFORCE_MASK)) {		ControlReg &= ~XQSPIPS_CR_SSCTRL_MASK;		ControlReg |= InstancePtr->SlaveSelect;		XQspiPs_WriteReg(InstancePtr->Config.BaseAddress,				  XQSPIPS_CR_OFFSET, ControlReg);	}	/*	 * Enable the device.	 */	XQspiPs_Enable(InstancePtr->Config.BaseAddress);	if (IsInst == 1) {		Instruction = *InstancePtr->SendBufferPtr;		for (Index = 0 ; Index < ARRAY_SIZE(FlashInst); Index++) {			if (Instruction == FlashInst[Index].OpCode) {				break;			}		}		if (Index == ARRAY_SIZE(FlashInst)) {			/* Instruction is not supported */			return XST_FAILURE;		}		CurrInst = &FlashInst[Index];

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -