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

📄 xqspips.c

📁 自学ZedBoard:使用IP通过ARM PS访问FPGA(源代码)
💻 C
📖 第 1 页 / 共 3 页
字号:
		/* Get the complete command (flash inst + address/data) */		Data = 0;		XQspiPs_GetWriteData(InstancePtr, &Data,				      CurrInst->InstSize);		/* Write the command to the FIFO */		XQspiPs_WriteReg(InstancePtr->Config.BaseAddress,				  CurrInst->TxOffset, Data);	}	/*	 * Fill the Tx FIFO with as many bytes as it takes (or as many as	 * we have to send).	 */	while ((InstancePtr->RemainingBytes > 0) &&	       ((XQspiPs_ReadReg(InstancePtr->Config.BaseAddress,				  XQSPIPS_SR_OFFSET) &				  XQSPIPS_IXR_TXFULL_MASK) == 0)) {		if (InstancePtr->RemainingBytes < 4) {			XQspiPs_GetWriteData(InstancePtr, &Data,					      InstancePtr->RemainingBytes);		} else {			XQspiPs_GetWriteData(InstancePtr, &Data, 4);		}		XQspiPs_WriteReg(InstancePtr->Config.BaseAddress,				  XQSPIPS_TXD_00_OFFSET, Data);	}	/*	 * Enable QSPI interrupts (connecting to the interrupt controller and	 * enabling interrupts should have been done by the caller).	 */	XQspiPs_WriteReg(InstancePtr->Config.BaseAddress,			  XQSPIPS_IER_OFFSET, XQSPIPS_IXR_DFLT_MASK);	/*	 * If, in Manual Start mode, Start the transfer.	 */	if ((ControlReg & (XQSPIPS_CR_MSTREN_MASK |			   XQSPIPS_CR_MANSTRTEN_MASK)) ==	    (XQSPIPS_CR_MSTREN_MASK | XQSPIPS_CR_MANSTRTEN_MASK)) {		ControlReg |= XQSPIPS_CR_MANSTRT_MASK;		XQspiPs_WriteReg(InstancePtr->Config.BaseAddress,				  XQSPIPS_CR_OFFSET, ControlReg);	}	return XST_SUCCESS;}/*****************************************************************************//*** Transfers specified data on the QSPI bus in polled mode.** 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_PolledTransfer(InstancePtr, SendBuf, RecvBuf, ByteCount)*	The caller wishes to send and receive, and provides two different*	buffers for send and receive.**   XQspiPs_PolledTransfer(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_PolledTransfer(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_PolledTransfer(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>** @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_PolledTransfer(XQspiPs *InstancePtr, u8 *SendBufPtr,			    u8 *RecvBufPtr, unsigned ByteCount, int IsInst){	u32 StatusReg;	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 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 not supported */			return XST_FAILURE;		}		CurrInst = &FlashInst[Index];		/* Get the complete command (flash inst + address/data) */		Data = 0;		XQspiPs_GetWriteData(InstancePtr, &Data,				      CurrInst->InstSize);		/* Write the command to the FIFO */		XQspiPs_WriteReg(InstancePtr->Config.BaseAddress,				  CurrInst->TxOffset, Data);	}	while((InstancePtr->RemainingBytes > 0) ||	      (InstancePtr->RequestedBytes > 0)) {		/*		 * Fill the DTR/FIFO with as many bytes as it will take (or as		 * many as we have to send).		 */		while ((InstancePtr->RemainingBytes > 0) &&		       ((XQspiPs_ReadReg(InstancePtr->Config.BaseAddress,					  XQSPIPS_SR_OFFSET) &					  XQSPIPS_IXR_TXFULL_MASK) == 0)) {			if (InstancePtr->RemainingBytes < 4) {				XQspiPs_GetWriteData(InstancePtr, &Data,						InstancePtr->RemainingBytes);			} else {				XQspiPs_GetWriteData(InstancePtr, &Data, 4);			}			XQspiPs_WriteReg(InstancePtr->Config.BaseAddress,					  XQSPIPS_TXD_00_OFFSET, Data);		}		/*		 * If, in Manual Start mode, start the transfer.		 */		if ((ControlReg & (XQSPIPS_CR_MSTREN_MASK |				   XQSPIPS_CR_MANSTRTEN_MASK)) ==		    (XQSPIPS_CR_MSTREN_MASK | XQSPIPS_CR_MANSTRTEN_MASK)) {			ControlReg |= XQSPIPS_CR_MANSTRT_MASK;			XQspiPs_WriteReg(InstancePtr->Config.BaseAddress,					  XQSPIPS_CR_OFFSET, ControlReg);		}		/*		 * Wait for the transfer to finish by polling Tx fifo status.		 */		do {			StatusReg = XQspiPs_ReadReg(					InstancePtr->Config.BaseAddress,					XQSPIPS_SR_OFFSET);		} while ((StatusReg & 0x04) == 0);		/*		 * A transmit has just completed. Process received data		 * and check for more data to transmit.		 * First get the data received as a result of the		 * transmit that just completed. We get all the data		 * available by reading the status register to determine		 * when the Receive register/FIFO is empty. Always get		 * the received data, but only fill the receive		 * buffer if it points to something (the upper layer		 * software may not care to receive data).		 */		while ((StatusReg & XQSPIPS_IXR_RXNEMPTY_MASK) != 0) {			u32 Data;			Data = XQspiPs_ReadReg(InstancePtr->Config.BaseAddress,						XQSPIPS_RXD_OFFSET);			if (InstancePtr->RequestedBytes < 4) {				XQspiPs_GetReadData(InstancePtr, Data,						InstancePtr->RequestedBytes);			} else {				XQspiPs_GetReadData(InstancePtr, Data, 4);			}			StatusReg = XQspiPs_ReadReg(						InstancePtr->Config.BaseAddress,						XQSPIPS_SR_OFFSET);		}	}	/*	 * If the Slave select lines are being manually controlled, disable	 * them because the transfer is complete.	 */	if (0 != (ControlReg & XQSPIPS_CR_SSFORCE_MASK)) {		ControlReg |= XQSPIPS_CR_SSCTRL_MASK;		XQspiPs_WriteReg(InstancePtr->Config.BaseAddress,				  XQSPIPS_CR_OFFSET, ControlReg);	}	InstancePtr->IsBusy = FALSE;	/*	 * Disable the device.	 */	XQspiPs_Disable(InstancePtr->Config.BaseAddress);	return XST_SUCCESS;}/*****************************************************************************//**** Read the flash in Linear QSPI mode.** @param	InstancePtr is a pointer to the XQspiPs instance.* @param	RecvBufPtr is a pointer to a buffer for received data.* @param	Address is the starting address within the flash from*		from where data needs to be read.* @param	ByteCount contains the number of bytes to receive.** @return	None.** @note** This function assumes that QSPI device in Linear mode. If the device is in* normal mode unexpected errors will occur.*******************************************************************************/void XQspiPs_LqspiRead(XQspiPs *InstancePtr, u8 *RecvBufPtr,			u32 Address, unsigned ByteCount){	memcpy((void*)RecvBufPtr, (const void*)(XPAR_XQSPIPS_0_LINEAR_BASEADDR +		Address), (size_t)ByteCount);}/*****************************************************************************//**** Selects the slave with which the master communicates.** The user is not allowed to select the slave while a transfer is in progress.* If no transfer is in progress, the user can select a new slave, which* implicitly deselects the current slave.** @param	InstancePtr is a pointer to the XQspiPs instance.* @param	SlaveSel is the chip select line which needs to be asserted.*		A value of 0 asserts the first chip select line. Only one slave*		can be selected at a time.** @return*		- XST_SUCCESS if the slave is selected or deselected*		  successfully.*		- XST_DEVICE_BUSY if a transfer is in progress, slave cannot be*		  changed.** @note** This function only sets the slave which will be selected when a transfer* occurs. The slave is not selected when the QSPI is idle. The slave select* has no affect when the device is configured as a slave.*******************************************************************************/int XQspiPs_SetSlaveSelect(XQspiPs *InstancePtr, u8 SlaveSel){	u32 ControlReg;	Xil_AssertNonvoid(InstancePtr != NULL);	Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);	Xil_AssertNonvoid(SlaveSel <= XQSPIPS_CR_SSCTRL_MAXIMUM);	/*	 * Do not allow the slave select to change while a transfer is in	 * progress. Not thread-safe.	 */	if (InstancePtr->IsBusy) {		return XST_DEVICE_BUSY;	}	InstancePtr->SlaveSelect = (((~(0x0001 << SlaveSel)) <<				     XQSPIPS_CR_SSCTRL_SHIFT) &				    XQSPIPS_CR_SSCTRL_MASK);	ControlReg = XQspiPs_ReadReg(InstancePtr->Config.BaseAddress,				      XQSPIPS_CR_OFFSET);	/*	 * Select the slaves	 */	ControlReg &= ~XQSPIPS_CR_SSCTRL_MASK;	ControlReg |= InstancePtr->SlaveSelect;	XQspiPs_WriteReg(InstancePtr->Config.BaseAddress,			  XQSPIPS_CR_OFFSET, ControlReg);	return XST_SUCCESS;}/*****************************************************************************//**** Gets the current slave select setting for the QSPI device.** @param	InstancePtr is a pointer to the XQspiPs instance.** @return	The value of the SPI_ss_outN bits in the control register, if*		the slave selects are in manual control, or,*		The value of SlaveSelect, in XQspiPs instance.** @note		None.*******************************************************************************/u8 XQspiPs_GetSlaveSelect(XQspiPs *InstancePtr){	u32 ControlReg;	Xil_AssertNonvoid(InstancePtr != NULL);	Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);	ControlReg = XQspiPs_ReadReg(InstancePtr->Config.BaseAddress,				      XQSPIPS_CR_OFFSET);	if (0 != (ControlReg & XQSPIPS_CR_SSFORCE_MASK)) {		ControlReg &= XQSPIPS_CR_SSCTRL_MASK;		ControlReg >>= XQSPIPS_CR_SSCTRL_SHIFT;	} else {		ControlReg = InstancePtr->SlaveSelect;	}	return ((u8) ControlReg);}/*****************************************************************************//**** Sets the status callback function, the status handler, which the driver

⌨️ 快捷键说明

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