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

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

	/*
	 * Check if the flash is write protected
	 */
	OnfiStatus = Onfi_CmdReadStatus(InstancePtr);
	if (!(OnfiStatus & ONFI_STATUS_WP)) {
		return XST_NAND_WRITE_PROTECTED;
	}

	/*
	 * Copy the user spare data buffer
	 */
	if (UserSparePtr == NULL) {
		memset(InstancePtr->SpareBufPtr, 0xff,
				InstancePtr->Geometry.SpareBytesPerPage);
	} else {
		memcpy(InstancePtr->SpareBufPtr, UserSparePtr,
				InstancePtr->Geometry.SpareBytesPerPage);
	}

	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;

	while (Length)
	{
		/*
		 * Partial write, fill the remaining buffer with 0xff
		 */
		if (NumOfBytes < InstancePtr->Geometry.BytesPerPage) {
			BufPtr = &InstancePtr->DataBuf[0];
			memset(BufPtr, 0xff,
					InstancePtr->Geometry.BytesPerPage);
			memcpy(BufPtr + CopyOffset, Ptr, NumOfBytes);
		} else {
			BufPtr = (u8 *)Ptr;
		}

		/*
		 * Send ONFI Program command
		 */
		XNandPs_SendCommand(InstancePtr, &OnfiCommands[PAGE_PROGRAM],
					Page, 0);

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

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

	return XST_SUCCESS;
}
/*****************************************************************************/
/**
*
* This function programs the flash device(s) with data specified in the user
* buffer. The source and destination address must be aligned to the width of the
* flash's data bus. It doesn't check for the bad blocks while writing to
* 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 write to.
* @param	Length is number of bytes to write.
* @param	SrcPtr is the source address to write the data from.
* @param	UserSparePtr is the user buffer which contains buffer to write
*		into spare data area.
*
* @return
*		- XST_SUCCESS if successful.
*		- XST_FAILURE if fail.
*		- XST_NAND_WRITE_PROTECTED if the flash is write protected.
*
* @note		This function writes number of sequential pages into the
*		Flash device.
*
******************************************************************************/
This function programs the flash device(s) with data specified in the user
buffer. The source and destination address must be aligned to the width of the
flash's data bus. It doesn't check for the bad blocks while writing to
the flash pages that cross block boundary. User must take care of handling
bad blocks.
This function programs the flash device ( s ) with data specified in the user buffer . The source and destination address must be aligned to the width of the flash ' s data bus . It doesn ' t check for the bad blocks while writing to the flash pages that cross block boundary . User must take care of handling bad blocks .
int XNandPs_Write(XNandPs *InstancePtr, u64 Offset, u32 Length, void *SrcPtr,
			u8 *UserSparePtr)
{
	u32 Page;
	u32 Col;
	u32 PartialBytes;
	u32 NumOfBytes;
	u32 CopyOffset;
	u32 Status;
	u8 *BufPtr;
	u8 OnfiStatus;
	u8 *Ptr = (u8 *)SrcPtr;
	Xil_AssertNonvoid(InstancePtr != NULL);
	Xil_AssertNonvoid(SrcPtr != NULL);
	Xil_AssertNonvoid((Offset + Length) < InstancePtr->Geometry.DeviceSize);
	Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
	Xil_AssertNonvoid(Length != 0);
	OnfiStatus = Onfi_CmdReadStatus(InstancePtr);
	if (!(OnfiStatus & ONFI_STATUS_WP)) {
		return XST_NAND_WRITE_PROTECTED;
	}
	if (UserSparePtr == NULL) {
		memset(InstancePtr->SpareBufPtr, 0xff,
				InstancePtr->Geometry.SpareBytesPerPage);
	} else {
		memcpy(InstancePtr->SpareBufPtr, UserSparePtr,
				InstancePtr->Geometry.SpareBytesPerPage);
	}
	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;
	while (Length)
	{
		if (NumOfBytes < InstancePtr->Geometry.BytesPerPage) {
			BufPtr = &InstancePtr->DataBuf[0];
			memset(BufPtr, 0xff,
					InstancePtr->Geometry.BytesPerPage);
			memcpy(BufPtr + CopyOffset, Ptr, NumOfBytes);
		} else {
			BufPtr = (u8 *)Ptr;
		}
		XNandPs_SendCommand(InstancePtr, &OnfiCommands[PAGE_PROGRAM],
					Page, 0);
		Status = InstancePtr->WritePage(InstancePtr, BufPtr);
		if (Status != XST_SUCCESS) {
			return Status;
		}
		Ptr += NumOfBytes;
		Length -= NumOfBytes;
		Page++;
		NumOfBytes = (Length > InstancePtr->Geometry.BytesPerPage) ?
				InstancePtr->Geometry.BytesPerPage:Length;
		CopyOffset = 0;
	}
	return XST_SUCCESS;
}
int XNandPs_Write ( XNandPs * InstancePtr , u64 Offset , u32 Length , void * SrcPtr , u8 * UserSparePtr ) { u32 Page ; u32 Col ; u32 PartialBytes ; u32 NumOfBytes ; u32 CopyOffset ; u32 Status ; u8 * BufPtr ; u8 OnfiStatus ; u8 * Ptr = ( u8 * ) SrcPtr ; Xil_AssertNonvoid ( InstancePtr != NULL ) ; Xil_AssertNonvoid ( SrcPtr != NULL ) ; Xil_AssertNonvoid ( ( Offset + Length ) < InstancePtr -> Geometry . DeviceSize ) ; Xil_AssertNonvoid ( InstancePtr -> IsReady == XIL_COMPONENT_IS_READY ) ; Xil_AssertNonvoid ( Length != 0 ) ; OnfiStatus = Onfi_CmdReadStatus ( InstancePtr ) ; if ( ! ( OnfiStatus & ONFI_STATUS_WP ) ) { return XST_NAND_WRITE_PROTECTED ; } if ( UserSparePtr == NULL ) { memset ( InstancePtr -> SpareBufPtr , 0xff , InstancePtr -> Geometry . SpareBytesPerPage ) ; } else { memcpy ( InstancePtr -> SpareBufPtr , UserSparePtr , InstancePtr -> Geometry . SpareBytesPerPage ) ; } 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 ; while ( Length ) { if ( NumOfBytes < InstancePtr -> Geometry . BytesPerPage ) { BufPtr = & InstancePtr -> DataBuf [ 0 ] ; memset ( BufPtr , 0xff , InstancePtr -> Geometry . BytesPerPage ) ; memcpy ( BufPtr + CopyOffset , Ptr , NumOfBytes ) ; } else { BufPtr = ( u8 * ) Ptr ; } XNandPs_SendCommand ( InstancePtr , & OnfiCommands [ PAGE_PROGRAM ] , Page , 0 ) ; Status = InstancePtr -> WritePage ( InstancePtr , BufPtr ) ; if ( Status != XST_SUCCESS ) { return Status ; } Ptr += NumOfBytes ; Length -= NumOfBytes ; Page ++ ; NumOfBytes = ( Length > InstancePtr -> Geometry . BytesPerPage ) ? InstancePtr -> Geometry . BytesPerPage : Length ; CopyOffset = 0 ; } return XST_SUCCESS ; }
This function programs the flash device(s) with data specified in the user
buffer.
This function programs the flash device ( s ) with data specified in the user buffer .
/*
	 * Check if the flash is write protected
	 */ /*
	 * Copy the user spare data buffer
	 */ /*
		 * Partial write, fill the remaining buffer with 0xff
		 */ /*
		 * Send ONFI Program command
		 */ /*
		 * Write the page data
		 */