XilinxProcessorIPLib/drivers/nandps/src/xnandps.c
static int XNandPs_WritePage_HwEcc(XNandPs *InstancePtr, u8 *SrcPtr)
{
	u32 Status;
	u32 BytesPerPage;
	u32 SpareBytesPerPage;
	u32 DataPhaseAddr;
	u32 Index;
	u32 *EccPos;
	u8 *EccCalc;
	u8 *Ptr = SrcPtr;
	u8 *SparePtr = InstancePtr->SpareBufPtr;

	BytesPerPage = InstancePtr->Geometry.BytesPerPage;
	SpareBytesPerPage = InstancePtr->Geometry.SpareBytesPerPage;

	EccCalc = &InstancePtr->EccCalc[0];

	/*
	 * Transfer page sized bytes in one less AXI data width
	 */
	XNandPs_WriteBuf(InstancePtr, Ptr,
				(BytesPerPage - XNANDPS_AXI_DATA_WIDTH));

	Ptr += (BytesPerPage - XNANDPS_AXI_DATA_WIDTH);

	/*
	 * Last page transaction with ECC set
	 */
	DataPhaseAddr = InstancePtr->DataPhaseAddr;
	DataPhaseAddr |= XNANDPS_ECC_LAST;
	InstancePtr->DataPhaseAddr = DataPhaseAddr;
	XNandPs_WriteBuf(InstancePtr, Ptr, XNANDPS_AXI_DATA_WIDTH);

	/*
	 * Calculate the ECC
	 */
	Ptr = SrcPtr;
	Status = XNandPs_EccCalculate(InstancePtr, EccCalc);
	if (Status != XST_SUCCESS) {
		return Status;
	}

	/*
	 * Fill the Spare buffer with calculated ECC
	 */
	EccPos = &InstancePtr->EccConfig.EccPos[0];
	for(Index = 0; Index < InstancePtr->EccConfig.TotalBytes; Index++) {
		InstancePtr->SpareBufPtr[EccPos[Index]] = ~(EccCalc[Index]);
	}

	/*
	 * Write the spare area with the ECC
	 */
	DataPhaseAddr = InstancePtr->DataPhaseAddr;
	DataPhaseAddr &= ~XNANDPS_ECC_LAST;
	InstancePtr->DataPhaseAddr = DataPhaseAddr;
	XNandPs_WriteBuf(InstancePtr, SparePtr,
				(SpareBytesPerPage - XNANDPS_AXI_DATA_WIDTH));

	/*
	 * Clear chip select for last AXI transaction
	 */
	DataPhaseAddr = InstancePtr->DataPhaseAddr;
	DataPhaseAddr |= XNANDPS_CLR_CS;
	InstancePtr->DataPhaseAddr = DataPhaseAddr;
	SparePtr += (SpareBytesPerPage - XNANDPS_AXI_DATA_WIDTH);
	XNandPs_WriteBuf(InstancePtr, SparePtr, XNANDPS_AXI_DATA_WIDTH);

	/*
	 * 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);

	/*
	 * Check SR[0] bit
	 */
	Status = Onfi_CmdReadStatus(InstancePtr);
	if (Status & ONFI_STATUS_FAIL) {
		return XST_FAILURE;
	}

	return XST_SUCCESS;
}
/*****************************************************************************/
/**
*
* This function writes a specific page in the NAND device using HW ECC block.
* The ECC code is written into the spare bytes of the page.
*
* @param	InstancePtr is a pointer to the XNandPs instance.
* @param	SrcPtr is a pointer to the source buffer.
* @return
*		- XST_SUCCESS if successful.
*		- XST_FAILURE if fail.
*
* @note		None
*
******************************************************************************/
This function writes a specific page in the NAND device using HW ECC block.
The ECC code is written into the spare bytes of the page.
This function writes a specific page in the NAND device using HW ECC block . The ECC code is written into the spare bytes of the page .
static int XNandPs_WritePage_HwEcc(XNandPs *InstancePtr, u8 *SrcPtr)
{
	u32 Status;
	u32 BytesPerPage;
	u32 SpareBytesPerPage;
	u32 DataPhaseAddr;
	u32 Index;
	u32 *EccPos;
	u8 *EccCalc;
	u8 *Ptr = SrcPtr;
	u8 *SparePtr = InstancePtr->SpareBufPtr;
	BytesPerPage = InstancePtr->Geometry.BytesPerPage;
	SpareBytesPerPage = InstancePtr->Geometry.SpareBytesPerPage;
	EccCalc = &InstancePtr->EccCalc[0];
	XNandPs_WriteBuf(InstancePtr, Ptr,
				(BytesPerPage - XNANDPS_AXI_DATA_WIDTH));
	Ptr += (BytesPerPage - XNANDPS_AXI_DATA_WIDTH);
	DataPhaseAddr = InstancePtr->DataPhaseAddr;
	DataPhaseAddr |= XNANDPS_ECC_LAST;
	InstancePtr->DataPhaseAddr = DataPhaseAddr;
	XNandPs_WriteBuf(InstancePtr, Ptr, XNANDPS_AXI_DATA_WIDTH);
	Ptr = SrcPtr;
	Status = XNandPs_EccCalculate(InstancePtr, EccCalc);
	if (Status != XST_SUCCESS) {
		return Status;
	}
	EccPos = &InstancePtr->EccConfig.EccPos[0];
	for(Index = 0; Index < InstancePtr->EccConfig.TotalBytes; Index++) {
		InstancePtr->SpareBufPtr[EccPos[Index]] = ~(EccCalc[Index]);
	}
	DataPhaseAddr = InstancePtr->DataPhaseAddr;
	DataPhaseAddr &= ~XNANDPS_ECC_LAST;
	InstancePtr->DataPhaseAddr = DataPhaseAddr;
	XNandPs_WriteBuf(InstancePtr, SparePtr,
				(SpareBytesPerPage - XNANDPS_AXI_DATA_WIDTH));
	DataPhaseAddr = InstancePtr->DataPhaseAddr;
	DataPhaseAddr |= XNANDPS_CLR_CS;
	InstancePtr->DataPhaseAddr = DataPhaseAddr;
	SparePtr += (SpareBytesPerPage - XNANDPS_AXI_DATA_WIDTH);
	XNandPs_WriteBuf(InstancePtr, SparePtr, XNANDPS_AXI_DATA_WIDTH);
	while (XNandPs_IsBusy(InstancePtr) == TRUE) {
	}
	XNandPs_WriteReg((InstancePtr->Config.SmcBase +
				XNANDPS_MEMC_CLR_CONFIG_OFFSET),
				XNANDPS_MEMC_CLR_CONFIG_INT_CLR1_MASK);
	Status = Onfi_CmdReadStatus(InstancePtr);
	if (Status & ONFI_STATUS_FAIL) {
		return XST_FAILURE;
	}
	return XST_SUCCESS;
}
static int XNandPs_WritePage_HwEcc ( XNandPs * InstancePtr , u8 * SrcPtr ) { u32 Status ; u32 BytesPerPage ; u32 SpareBytesPerPage ; u32 DataPhaseAddr ; u32 Index ; u32 * EccPos ; u8 * EccCalc ; u8 * Ptr = SrcPtr ; u8 * SparePtr = InstancePtr -> SpareBufPtr ; BytesPerPage = InstancePtr -> Geometry . BytesPerPage ; SpareBytesPerPage = InstancePtr -> Geometry . SpareBytesPerPage ; EccCalc = & InstancePtr -> EccCalc [ 0 ] ; XNandPs_WriteBuf ( InstancePtr , Ptr , ( BytesPerPage - XNANDPS_AXI_DATA_WIDTH ) ) ; Ptr += ( BytesPerPage - XNANDPS_AXI_DATA_WIDTH ) ; DataPhaseAddr = InstancePtr -> DataPhaseAddr ; DataPhaseAddr |= XNANDPS_ECC_LAST ; InstancePtr -> DataPhaseAddr = DataPhaseAddr ; XNandPs_WriteBuf ( InstancePtr , Ptr , XNANDPS_AXI_DATA_WIDTH ) ; Ptr = SrcPtr ; Status = XNandPs_EccCalculate ( InstancePtr , EccCalc ) ; if ( Status != XST_SUCCESS ) { return Status ; } EccPos = & InstancePtr -> EccConfig . EccPos [ 0 ] ; for ( Index = 0 ; Index < InstancePtr -> EccConfig . TotalBytes ; Index ++ ) { InstancePtr -> SpareBufPtr [ EccPos [ Index ] ] = ~ ( EccCalc [ Index ] ) ; } DataPhaseAddr = InstancePtr -> DataPhaseAddr ; DataPhaseAddr &= ~ XNANDPS_ECC_LAST ; InstancePtr -> DataPhaseAddr = DataPhaseAddr ; XNandPs_WriteBuf ( InstancePtr , SparePtr , ( SpareBytesPerPage - XNANDPS_AXI_DATA_WIDTH ) ) ; DataPhaseAddr = InstancePtr -> DataPhaseAddr ; DataPhaseAddr |= XNANDPS_CLR_CS ; InstancePtr -> DataPhaseAddr = DataPhaseAddr ; SparePtr += ( SpareBytesPerPage - XNANDPS_AXI_DATA_WIDTH ) ; XNandPs_WriteBuf ( InstancePtr , SparePtr , XNANDPS_AXI_DATA_WIDTH ) ; while ( XNandPs_IsBusy ( InstancePtr ) == TRUE ) { } XNandPs_WriteReg ( ( InstancePtr -> Config . SmcBase + XNANDPS_MEMC_CLR_CONFIG_OFFSET ) , XNANDPS_MEMC_CLR_CONFIG_INT_CLR1_MASK ) ; Status = Onfi_CmdReadStatus ( InstancePtr ) ; if ( Status & ONFI_STATUS_FAIL ) { return XST_FAILURE ; } return XST_SUCCESS ; }
This function writes a specific page in the NAND device using HW ECC block.
This function writes a specific page in the NAND device using HW ECC block .
/*
	 * Transfer page sized bytes in one less AXI data width
	 */ /*
	 * Last page transaction with ECC set
	 */ /*
	 * Calculate the ECC
	 */ /*
	 * Fill the Spare buffer with calculated ECC
	 */ /*
	 * Write the spare area with the ECC
	 */ /*
	 * Clear chip select for last AXI transaction
	 */ /*
	 * Poll the Memory controller status register
	 */ /*
	 * Clear the interrupt condition
	 */ /*
	 * Check SR[0] bit
	 */