XilinxProcessorIPLib/drivers/nandps/src/xnandps.c
int XNandPs_ReadSpareBytes(XNandPs *InstancePtr, u32 Page, u8 *Buf)
{
	u32 Col;
	u32 Length;
	u32 DataPhaseAddr;
	u32 ZeroCommand;
	u32 Status;

	Xil_AssertNonvoid(Buf != NULL);

	/*
	 * Bypass the ECC block in the SMC controller since
	 * we don't calculate ECC for spare bytes.
	 */
	if (InstancePtr->EccMode == XNANDPS_ECC_HW) {
		XNandPs_EccDisable(InstancePtr);
	}

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

	XNandPs_SendCommand(InstancePtr, &OnfiCommands[READ], Page, Col);
	/*
	 * Poll the Memory controller status register for BUSY input signal
	 */
	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 ONFI Status Register
	 */
	Status = Onfi_CmdReadStatus(InstancePtr);
	if (Status & ONFI_STATUS_FAIL) {
		return XST_FAILURE;
	}

	/*
	 * ONFI : Reissue the 0x00 on the command line to start
	 * reading data
	 */
	ZeroCommand = InstancePtr->Config.FlashBase |
			(0 << XNANDPS_ADDR_CYCLES_SHIFT)|
			(0 << XNANDPS_END_CMD_VALID_SHIFT)|
			(XNANDPS_COMMAND_PHASE_MASK)|
			(0 << XNANDPS_END_CMD_SHIFT)|
			(0 << XNANDPS_START_CMD_SHIFT);

	/*
	 * AXI transaction for sending command 0x00 to the flash
	 */
	Xil_Out32(ZeroCommand, 0x00);

	/*
	 * Read the spare data
	 */
	XNandPs_ReadBuf(InstancePtr, Buf, (Length - XNANDPS_AXI_DATA_WIDTH));

	/*
	 * Clear chip select for last AXI transaction
	 */
	DataPhaseAddr = InstancePtr->DataPhaseAddr;
	DataPhaseAddr |= XNANDPS_CLR_CS;
	InstancePtr->DataPhaseAddr = DataPhaseAddr;
	Buf += (Length - XNANDPS_AXI_DATA_WIDTH);
	XNandPs_ReadBuf(InstancePtr, Buf, XNANDPS_AXI_DATA_WIDTH);

	/*
	 * Re-enable ECC block in the SMC controller
	 */
	if (InstancePtr->EccMode == XNANDPS_ECC_HW) {
		Status = XNandPs_EccHwInit(InstancePtr);
		if (Status != XST_SUCCESS)
			return XST_FAILURE;
	}

	return XST_SUCCESS;
}
/*****************************************************************************/
/**
*
* This function reads the spare area of a page.
*
* @param	InstancePtr is the pointer to the XNandPs instance.
* @param	Page is the page number from where spare data is read.
* @param	Buf is pointer to the buffer where the spare data is filled.
*
* @return
*		- XST_SUCCESS if successful.
*		- XST_FAILURE if fail.
*
* @note		None.
*
******************************************************************************/
This function reads the spare area of a page.
This function reads the spare area of a page .
int XNandPs_ReadSpareBytes(XNandPs *InstancePtr, u32 Page, u8 *Buf)
{
	u32 Col;
	u32 Length;
	u32 DataPhaseAddr;
	u32 ZeroCommand;
	u32 Status;
	Xil_AssertNonvoid(Buf != NULL);
	if (InstancePtr->EccMode == XNANDPS_ECC_HW) {
		XNandPs_EccDisable(InstancePtr);
	}
	Col = InstancePtr->Geometry.BytesPerPage;
	Length = InstancePtr->Geometry.SpareBytesPerPage;
	XNandPs_SendCommand(InstancePtr, &OnfiCommands[READ], Page, Col);
	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;
	}
	ZeroCommand = InstancePtr->Config.FlashBase |
			(0 << XNANDPS_ADDR_CYCLES_SHIFT)|
			(0 << XNANDPS_END_CMD_VALID_SHIFT)|
			(XNANDPS_COMMAND_PHASE_MASK)|
			(0 << XNANDPS_END_CMD_SHIFT)|
			(0 << XNANDPS_START_CMD_SHIFT);
	Xil_Out32(ZeroCommand, 0x00);
	XNandPs_ReadBuf(InstancePtr, Buf, (Length - XNANDPS_AXI_DATA_WIDTH));
	DataPhaseAddr = InstancePtr->DataPhaseAddr;
	DataPhaseAddr |= XNANDPS_CLR_CS;
	InstancePtr->DataPhaseAddr = DataPhaseAddr;
	Buf += (Length - XNANDPS_AXI_DATA_WIDTH);
	XNandPs_ReadBuf(InstancePtr, Buf, XNANDPS_AXI_DATA_WIDTH);
	if (InstancePtr->EccMode == XNANDPS_ECC_HW) {
		Status = XNandPs_EccHwInit(InstancePtr);
		if (Status != XST_SUCCESS)
			return XST_FAILURE;
	}
	return XST_SUCCESS;
}
int XNandPs_ReadSpareBytes ( XNandPs * InstancePtr , u32 Page , u8 * Buf ) { u32 Col ; u32 Length ; u32 DataPhaseAddr ; u32 ZeroCommand ; u32 Status ; Xil_AssertNonvoid ( Buf != NULL ) ; if ( InstancePtr -> EccMode == XNANDPS_ECC_HW ) { XNandPs_EccDisable ( InstancePtr ) ; } Col = InstancePtr -> Geometry . BytesPerPage ; Length = InstancePtr -> Geometry . SpareBytesPerPage ; XNandPs_SendCommand ( InstancePtr , & OnfiCommands [ READ ] , Page , Col ) ; 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 ; } ZeroCommand = InstancePtr -> Config . FlashBase | ( 0 << XNANDPS_ADDR_CYCLES_SHIFT ) | ( 0 << XNANDPS_END_CMD_VALID_SHIFT ) | ( XNANDPS_COMMAND_PHASE_MASK ) | ( 0 << XNANDPS_END_CMD_SHIFT ) | ( 0 << XNANDPS_START_CMD_SHIFT ) ; Xil_Out32 ( ZeroCommand , 0x00 ) ; XNandPs_ReadBuf ( InstancePtr , Buf , ( Length - XNANDPS_AXI_DATA_WIDTH ) ) ; DataPhaseAddr = InstancePtr -> DataPhaseAddr ; DataPhaseAddr |= XNANDPS_CLR_CS ; InstancePtr -> DataPhaseAddr = DataPhaseAddr ; Buf += ( Length - XNANDPS_AXI_DATA_WIDTH ) ; XNandPs_ReadBuf ( InstancePtr , Buf , XNANDPS_AXI_DATA_WIDTH ) ; if ( InstancePtr -> EccMode == XNANDPS_ECC_HW ) { Status = XNandPs_EccHwInit ( InstancePtr ) ; if ( Status != XST_SUCCESS ) return XST_FAILURE ; } return XST_SUCCESS ; }
This function reads the spare area of a page.
This function reads the spare area of a page .
/*
	 * Bypass the ECC block in the SMC controller since
	 * we don't calculate ECC for spare bytes.
	 */ /*
	 * Poll the Memory controller status register for BUSY input signal
	 */ /*
	 * Clear the interrupt condition
	 */ /*
	 * Check ONFI Status Register
	 */ /*
	 * ONFI : Reissue the 0x00 on the command line to start
	 * reading data
	 */ /*
	 * AXI transaction for sending command 0x00 to the flash
	 */ /*
	 * Read the spare data
	 */ /*
	 * Clear chip select for last AXI transaction
	 */ /*
	 * Re-enable ECC block in the SMC controller
	 */