XilinxProcessorIPLib/drivers/nandps/src/xnandps.c
int XNandPs_Read(XNandPs *InstancePtr, u64 Offset, u32 Length, void *DestPtr,
			u8 *UserSparePtr)
{
	u32 Page;
	u32 Col;
	u32 PartialBytes;
	u32 NumOfBytes;
	int Status;
	u32 PartialPageRead = 0;
	u32 CopyOffset;
	u8 *BufPtr;
	u8 *Ptr = (u8 *)DestPtr;

	Xil_AssertNonvoid(InstancePtr != NULL);
	Xil_AssertNonvoid(DestPtr != NULL);
	Xil_AssertNonvoid((Offset + Length) < InstancePtr->Geometry.DeviceSize);
	Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
	Xil_AssertNonvoid(Length != 0);

	Page = (u32) (Offset/InstancePtr->Geometry.BytesPerPage);
	Col = (u32) (Offset & (InstancePtr->Geometry.BytesPerPage - 1));
	PartialBytes = InstancePtr->Geometry.BytesPerPage - Col;
	NumOfBytes = (PartialBytes < Length) ? PartialBytes:Length;
	CopyOffset = InstancePtr->Geometry.BytesPerPage - PartialBytes;

	/*
	 * Restore the ECC mem command1 and ECC mem command2 register
	 * if the previous command is read page cache.
	 */
	XNandPs_EccSetMemCmd1(InstancePtr, XNANDPS_ECC_CMD1);
	XNandPs_EccSetMemCmd2(InstancePtr, XNANDPS_ECC_CMD2);

	while (Length) {
		/*
		 * Check if partial read
		 */
		if (NumOfBytes < InstancePtr->Geometry.BytesPerPage) {
			BufPtr = &InstancePtr->DataBuf[0];
			PartialPageRead = 1;
		} else {
			BufPtr = (u8 *)Ptr;
			PartialPageRead = 0;
		}

		/*
		 * Send the ONFI Read command
		 */
		XNandPs_SendCommand(InstancePtr, &OnfiCommands[READ], Page, 0);

		/*
		 * Poll the Memory controller status register
		 */
		while (XNandPs_IsBusy(InstancePtr) == TRUE) {
		}

		/*
		 * Clear the interrupt condition
		 */
		XNandPs_WriteReg((InstancePtr->Config.SmcBase +
					XNANDPS_MEMC_CLR_CONFIG_OFFSET),
				XNANDPS_MEMC_CLR_CONFIG_INT_CLR1_MASK);

		/*
		 *  Read the page data
		 */
		Status = InstancePtr->ReadPage(InstancePtr, BufPtr);
		if (Status != XST_SUCCESS) {
			return Status;
		}

		/*
		 * Fill the partial data in the buffer
		 */
		if (PartialPageRead) {
			memcpy(Ptr, BufPtr + CopyOffset, NumOfBytes);
		}

		Ptr += NumOfBytes;
		Length -= NumOfBytes;
		Page++;
		NumOfBytes = (Length > InstancePtr->Geometry.BytesPerPage) ?
				InstancePtr->Geometry.BytesPerPage:Length;
		CopyOffset = 0;
	}

	/*
	 * Copy the spare data to user spare buffer
	 */
	if (UserSparePtr) {
		memcpy(UserSparePtr, InstancePtr->SpareBufPtr,
				InstancePtr->Geometry.SpareBytesPerPage);
	}

	return XST_SUCCESS;
}
/*****************************************************************************/
/**
*
* This function reads the data from the Flash device and copies it into the
* specified user buffer. It doesn't check for the bad blocks while reading
* the flash pages that cross block boundary. User must take care of handling
* bad blocks.
*
* @param	InstancePtr is the pointer to the XNandPs instance.
* @param	Offset is the flash data address to read from.
* @param	Length is number of bytes to read.
* @param	DestPtr is the destination address to copy data to.
* @param	UserSparePtr is the user buffer to which spare data must be
*		copied.
*
* @return
*		- XST_SUCCESS if successful.
*		- XST_FAILURE if fail.
*
* @note		This function reads sequential pages from the Flash device.
*
******************************************************************************/
This function reads the data from the Flash device and copies it into the
specified user buffer. It doesn't check for the bad blocks while reading
the flash pages that cross block boundary. User must take care of handling
bad blocks.
This function reads the data from the Flash device and copies it into the specified user buffer . It doesn ' t check for the bad blocks while reading the flash pages that cross block boundary . User must take care of handling bad blocks .
int XNandPs_Read(XNandPs *InstancePtr, u64 Offset, u32 Length, void *DestPtr,
			u8 *UserSparePtr)
{
	u32 Page;
	u32 Col;
	u32 PartialBytes;
	u32 NumOfBytes;
	int Status;
	u32 PartialPageRead = 0;
	u32 CopyOffset;
	u8 *BufPtr;
	u8 *Ptr = (u8 *)DestPtr;
	Xil_AssertNonvoid(InstancePtr != NULL);
	Xil_AssertNonvoid(DestPtr != NULL);
	Xil_AssertNonvoid((Offset + Length) < InstancePtr->Geometry.DeviceSize);
	Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
	Xil_AssertNonvoid(Length != 0);
	Page = (u32) (Offset/InstancePtr->Geometry.BytesPerPage);
	Col = (u32) (Offset & (InstancePtr->Geometry.BytesPerPage - 1));
	PartialBytes = InstancePtr->Geometry.BytesPerPage - Col;
	NumOfBytes = (PartialBytes < Length) ? PartialBytes:Length;
	CopyOffset = InstancePtr->Geometry.BytesPerPage - PartialBytes;
	XNandPs_EccSetMemCmd1(InstancePtr, XNANDPS_ECC_CMD1);
	XNandPs_EccSetMemCmd2(InstancePtr, XNANDPS_ECC_CMD2);
	while (Length) {
		if (NumOfBytes < InstancePtr->Geometry.BytesPerPage) {
			BufPtr = &InstancePtr->DataBuf[0];
			PartialPageRead = 1;
		} else {
			BufPtr = (u8 *)Ptr;
			PartialPageRead = 0;
		}
		XNandPs_SendCommand(InstancePtr, &OnfiCommands[READ], Page, 0);
		while (XNandPs_IsBusy(InstancePtr) == TRUE) {
		}
		XNandPs_WriteReg((InstancePtr->Config.SmcBase +
					XNANDPS_MEMC_CLR_CONFIG_OFFSET),
				XNANDPS_MEMC_CLR_CONFIG_INT_CLR1_MASK);
		Status = InstancePtr->ReadPage(InstancePtr, BufPtr);
		if (Status != XST_SUCCESS) {
			return Status;
		}
		if (PartialPageRead) {
			memcpy(Ptr, BufPtr + CopyOffset, NumOfBytes);
		}
		Ptr += NumOfBytes;
		Length -= NumOfBytes;
		Page++;
		NumOfBytes = (Length > InstancePtr->Geometry.BytesPerPage) ?
				InstancePtr->Geometry.BytesPerPage:Length;
		CopyOffset = 0;
	}
	if (UserSparePtr) {
		memcpy(UserSparePtr, InstancePtr->SpareBufPtr,
				InstancePtr->Geometry.SpareBytesPerPage);
	}
	return XST_SUCCESS;
}
int XNandPs_Read ( XNandPs * InstancePtr , u64 Offset , u32 Length , void * DestPtr , u8 * UserSparePtr ) { u32 Page ; u32 Col ; u32 PartialBytes ; u32 NumOfBytes ; int Status ; u32 PartialPageRead = 0 ; u32 CopyOffset ; u8 * BufPtr ; u8 * Ptr = ( u8 * ) DestPtr ; Xil_AssertNonvoid ( InstancePtr != NULL ) ; Xil_AssertNonvoid ( DestPtr != NULL ) ; Xil_AssertNonvoid ( ( Offset + Length ) < InstancePtr -> Geometry . DeviceSize ) ; Xil_AssertNonvoid ( InstancePtr -> IsReady == XIL_COMPONENT_IS_READY ) ; Xil_AssertNonvoid ( Length != 0 ) ; Page = ( u32 ) ( Offset / InstancePtr -> Geometry . BytesPerPage ) ; Col = ( u32 ) ( Offset & ( InstancePtr -> Geometry . BytesPerPage - 1 ) ) ; PartialBytes = InstancePtr -> Geometry . BytesPerPage - Col ; NumOfBytes = ( PartialBytes < Length ) ? PartialBytes : Length ; CopyOffset = InstancePtr -> Geometry . BytesPerPage - PartialBytes ; XNandPs_EccSetMemCmd1 ( InstancePtr , XNANDPS_ECC_CMD1 ) ; XNandPs_EccSetMemCmd2 ( InstancePtr , XNANDPS_ECC_CMD2 ) ; while ( Length ) { if ( NumOfBytes < InstancePtr -> Geometry . BytesPerPage ) { BufPtr = & InstancePtr -> DataBuf [ 0 ] ; PartialPageRead = 1 ; } else { BufPtr = ( u8 * ) Ptr ; PartialPageRead = 0 ; } XNandPs_SendCommand ( InstancePtr , & OnfiCommands [ READ ] , Page , 0 ) ; while ( XNandPs_IsBusy ( InstancePtr ) == TRUE ) { } XNandPs_WriteReg ( ( InstancePtr -> Config . SmcBase + XNANDPS_MEMC_CLR_CONFIG_OFFSET ) , XNANDPS_MEMC_CLR_CONFIG_INT_CLR1_MASK ) ; Status = InstancePtr -> ReadPage ( InstancePtr , BufPtr ) ; if ( Status != XST_SUCCESS ) { return Status ; } if ( PartialPageRead ) { memcpy ( Ptr , BufPtr + CopyOffset , NumOfBytes ) ; } Ptr += NumOfBytes ; Length -= NumOfBytes ; Page ++ ; NumOfBytes = ( Length > InstancePtr -> Geometry . BytesPerPage ) ? InstancePtr -> Geometry . BytesPerPage : Length ; CopyOffset = 0 ; } if ( UserSparePtr ) { memcpy ( UserSparePtr , InstancePtr -> SpareBufPtr , InstancePtr -> Geometry . SpareBytesPerPage ) ; } return XST_SUCCESS ; }
This function reads the data from the Flash device and copies it into the
specified user buffer.
This function reads the data from the Flash device and copies it into the specified user buffer .
/*
	 * Restore the ECC mem command1 and ECC mem command2 register
	 * if the previous command is read page cache.
	 */ /*
		 * Check if partial read
		 */ /*
		 * Send the ONFI Read command
		 */ /*
		 * Poll the Memory controller status register
		 */ /*
		 * Clear the interrupt condition
		 */ /*
		 *  Read the page data
		 */ /*
		 * Fill the partial data in the buffer
		 */ /*
	 * Copy the spare data to user spare buffer
	 */