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

📄 xiic_l.c

📁 FPGA 并行NOR FLash的操作相关
💻 C
📖 第 1 页 / 共 3 页
字号:
	 * addressed device.	 */	XIic_mDynSendStop(BaseAddress, ByteCount);	/*	 * Receive the data from the IIC bus.	 */	RemainingByteCount = DynRecvData(BaseAddress, BufferPtr, ByteCount);	/*	 * The receive is complete. Return the number of bytes that were	 * received.	 */	return ByteCount - RemainingByteCount;}/*****************************************************************************//*** Receive the specified data from the device that has been previously addressed* on the IIC bus. This function assumes the following:*   - The Rx Fifo occupancy depth has been set to its max.*   - Upon entry, the Rx Fifo is empty.*   - The 7 bit address has been sent.*   - The dynamic stop and number of bytes to receive has been written to Tx*     Fifo.** @param    BaseAddress contains the base address of the IIC Device.* @param    BufferPtr points to the buffer to hold the data that is received.* @param    ByteCount is the number of bytes to be received. The range of this*           value is greater than 0 and not higher than 255.** @return   The number of bytes remaining to be received.** @note     This function contains loops that could cause the function not*           to return if the hardware is not working.*******************************************************************************/static unsigned DynRecvData(u32 BaseAddress, u8 *BufferPtr, u8 ByteCount){ 	u8 StatusReg; 	u32 IntrStatus; 	u32 IntrStatusMask; 	while (ByteCount > 0) { 		/* Setup the mask to use for checking errors because when 		 * receiving one byte OR the last byte of a multibyte message 		 * an error naturally occurs when the no ack is done to tell 		 * the slave the last byte. 		 */ 		if (ByteCount == 1) { 			IntrStatusMask = 				XIIC_INTR_ARB_LOST_MASK | XIIC_INTR_BNB_MASK; 		} 		else { 			IntrStatusMask = 				XIIC_INTR_ARB_LOST_MASK | 				XIIC_INTR_TX_ERROR_MASK | XIIC_INTR_BNB_MASK; 		} 		/* 		 * Wait for a byte to show up in the Rx Fifo. 		 */ 		do { 			StatusReg = XIo_In8(BaseAddress + XIIC_SR_REG_OFFSET); 			IntrStatus = XIIC_READ_IISR(BaseAddress); 			/* Check the transmit error after the receive full 			 * because when sending only one byte transmit error 			 * will occur because of the no ack to indicate the end 			 *  of the data. 			 */ 			if (IntrStatus & IntrStatusMask) { 				return ByteCount; 			} 		} while ((StatusReg & XIIC_SR_RX_FIFO_EMPTY_MASK) == 			 		XIIC_SR_RX_FIFO_EMPTY_MASK); 		/* 		 * Read in byte from the Rx Fifo. If the Fifo reached the 		 * programmed occupancy depth as programmed in the Rx occupancy 		 * reg, this read access will un throttle the bus such that 		 * the next byte is read from the IIC bus. 		 */ 		*BufferPtr++ = XIo_In8(BaseAddress + XIIC_DRR_REG_OFFSET); 		ByteCount--; 	}	return ByteCount;}/*****************************************************************************//*** Send data as a master on the IIC bus. This function sends the data using* polled I/O and blocks until the data has been sent. It only supports 7 bit* addressing. The user is responsible for ensuring the bus is not busy if* multiple masters are present on the bus.** @param    BaseAddress contains the base address of the IIC Device.* @param    Address contains the 7 bit IIC address of the device to send the*           specified data to.* @param    BufferPtr points to the data to be sent.* @param    ByteCount is the number of bytes to be sent.* @param    Option: XIIC_STOP = end with STOP condition, XIIC_REPEATED_START*           = don't end with STOP condition.** @return   The number of bytes sent.** @note     None.*******************************************************************************/unsigned XIic_DynSend(u32 BaseAddress, u16 Address, u8 *BufferPtr,		      u8 ByteCount, u8 Option){	unsigned RemainingByteCount;	u32 StatusRegister;	/*	 * Clear the latched interrupt status so that it will be updated with	 * the new state when it changes, this must be done after the address	 * is put in the FIFO	 */	XIic_mClearIisr(BaseAddress, XIIC_INTR_TX_EMPTY_MASK |			XIIC_INTR_TX_ERROR_MASK | XIIC_INTR_ARB_LOST_MASK);	/*	 * Put the address into the Fifo to be sent and indicate that the	 * operation to be performed on the bus is a write operation. Upon	 * writing the address, a start condition is initiated. MSMS is	 * automatically set to master when the address is written to the Fifo.	 * If MSMS was already set, then a re-start is sent prior to the	 *  address.	 */	if(!(Address & XIIC_TX_DYN_STOP_MASK))	{		XIic_mDynSend7BitAddress(BaseAddress, Address,		XIIC_WRITE_OPERATION);	}	else	{		XIic_mDynSendStartStopAddress(BaseAddress, Address,					XIIC_WRITE_OPERATION);    }	/*	 * Wait for the bus to go busy.	 */	StatusRegister = XIo_In8(BaseAddress + XIIC_SR_REG_OFFSET);	while (( StatusRegister & XIIC_SR_BUS_BUSY_MASK) != XIIC_SR_BUS_BUSY_MASK)	{		StatusRegister = XIo_In8(BaseAddress + XIIC_SR_REG_OFFSET);	}	/*	 * Clear the latched interrupt status for the bus not busy bit which	 * must be done while the bus is busy.	 */	XIic_mClearIisr(BaseAddress, XIIC_INTR_BNB_MASK);	/*	 * Send the specified data to the device on the IIC bus specified by the	 * the address.	 */	RemainingByteCount = DynSendData(BaseAddress, BufferPtr, ByteCount,					 Option);	/*	 * The send is complete return the number of bytes that was sent.	 */	return ByteCount - RemainingByteCount;}/******************************************************************************** Send the specified buffer to the device that has been previously addressed* on the IIC bus. This function assumes that the 7 bit address has been sent.** @param    BaseAddress contains the base address of the IIC Device.* @param    BufferPtr points to the data to be sent.* @param    ByteCount is the number of bytes to be sent.* @param    Option: XIIC_STOP = end with STOP condition, XIIC_REPEATED_START*           = don't end with STOP condition.** @return   The number of bytes remaining to be sent.** @note     This function does not take advantage of the transmit Fifo because*           it is designed for minimal code space and complexity.*******************************************************************************/static unsigned DynSendData(u32 BaseAddress, u8 *BufferPtr,			    u8 ByteCount, u8 Option){	u32 IntrStatus;	while (ByteCount > 0) {		/*		 * Wait for the transmit to be empty before sending any more		 * data by polling the interrupt status register.		 */		while (1) {			IntrStatus = XIIC_READ_IISR(BaseAddress);			if (IntrStatus & (XIIC_INTR_TX_ERROR_MASK |					  XIIC_INTR_ARB_LOST_MASK |					  XIIC_INTR_BNB_MASK)) {				/*				 * Error condition (NACK or ARB Lost or BNB				 * Error Has occurred. Clear the Control				 * register to send a STOP condition on the Bus				 * and return the number of bytes still to				 * transmit.				 */				XIo_Out8(BaseAddress + XIIC_CR_REG_OFFSET,					 0x03);				XIo_Out8(BaseAddress + XIIC_CR_REG_OFFSET,					 0x01);				return ByteCount;			}			/*			 * Check for the transmit Fifo to become Empty.			 */			if (IntrStatus & XIIC_INTR_TX_EMPTY_MASK) {				break;			}		}		/*		 * Send data to Tx Fifo. If a stop condition is specified and		 * the last byte is being sent, then set the dynamic stop bit.		 */		if ((ByteCount == 1) && (Option == XIIC_STOP)) {			/*			 * The MSMS will be cleared automatically upon setting			 *  dynamic stop.			 */			XIo_Out16(BaseAddress + XIIC_DTR_REG_OFFSET - 1,				  	XIIC_TX_DYN_STOP_MASK | *BufferPtr++);		}		else {			XIo_Out8(BaseAddress + XIIC_DTR_REG_OFFSET,				 				*BufferPtr++);		}		/*		 * Update the byte count to reflect the byte sent.		 */		ByteCount--;	}	if (Option == XIIC_STOP) {		/*		 * If the Option is to release the bus after transmission of		 * data, Wait for the bus to transition to not busy before		 * returning, the IIC device cannot be disabled until this		 * occurs.		 */		while (1) {			if (XIIC_READ_IISR(BaseAddress) & XIIC_INTR_BNB_MASK) {				break;			}		}	}	return ByteCount;}/******************************************************************************** Initialize the IIC core for Dynamic Functionality.** @param    BaseAddress contains the base address of the IIC Device.** @return   XST_SUCCESS if Successful else XST_FAILURE.** @note     None.*******************************************************************************/int XIic_DynInit(u32 BaseAddress){    u8 Status;	/*	 * Reset IIC Core.	 */	XIIC_RESET(BaseAddress);    /*     * Set receive Fifo depth to maximum (zero based).     */    XIo_Out8(BaseAddress + XIIC_RFD_REG_OFFSET, IIC_RX_FIFO_DEPTH - 1);    /*     * Reset Tx Fifo.     */    XIo_Out8(BaseAddress + XIIC_CR_REG_OFFSET, XIIC_CR_TX_FIFO_RESET_MASK);    /*     * Enable IIC Device, remove Tx Fifo reset & disable general call.     */    XIo_Out8(BaseAddress + XIIC_CR_REG_OFFSET, XIIC_CR_ENABLE_DEVICE_MASK);    /*     * Read status register and verify IIC Device is in initial state. Only the     * Tx Fifo and Rx Fifo empty bits should be set.     */    Status = XIo_In8(BaseAddress + XIIC_SR_REG_OFFSET);    if(Status == (XIIC_SR_RX_FIFO_EMPTY_MASK | XIIC_SR_TX_FIFO_EMPTY_MASK))    {        return XST_SUCCESS;    }    return XST_FAILURE;}

⌨️ 快捷键说明

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