/** * * This function initializes the controller for the NAND FLASH interface. * * @param none * * @return * - XST_SUCCESS if the controller initializes correctly * - XST_FAILURE if the controller fails to initializes correctly * * @note none. * ****************************************************************************/ u32 InitNand(void) { u32 Status; XNandPs_Config *ConfigPtr; /* * Set up pointers to instance and the config structure */ NandInstPtr = &NandInstance; /* * Initialize the flash driver. */ ConfigPtr = XNandPs_LookupConfig(NAND_DEVICE_ID); if (ConfigPtr == NULL) { fsbl_printf(DEBUG_GENERAL,"Nand Driver failed \n \r"); return XST_FAILURE; } Status = XNandPs_CfgInitialize(NandInstPtr, ConfigPtr, ConfigPtr->SmcBase,ConfigPtr->FlashBase); if (Status != XST_SUCCESS) { fsbl_printf(DEBUG_GENERAL,"NAND intialization failed \n \r"); return XST_FAILURE; } /* * Set up base address for access */ FlashReadBaseAddress = XPS_NAND_BASEADDR; fsbl_printf(DEBUG_INFO,"InitNand: Geometry = 0x%x\r\n", NandInstPtr->Geometry.FlashWidth); if (Status != XST_SUCCESS) { fsbl_printf(DEBUG_GENERAL,"InitNand: Status = 0x%.8x\r\n", Status); return XST_FAILURE; } /* * set up the FLASH access pointers */ fsbl_printf(DEBUG_INFO,"Nand driver initialized \n\r"); return XST_SUCCESS; }
/** * * This function runs a test on the NAND flash device using the basic driver * functions. * The function does the following tasks: * - Initialize the driver. * - Erase the blocks. * - Write in to all the blocks. * - Read back the data from the blocks. * - Compare the data read against the data Written. * * @param NandDeviceId is is the XPAR_<NAND_instance>_DEVICE_ID value * from xparameters.h. * * @return * - XST_SUCCESS if successful. * - XST_FAILURE if failed. * * @note When bad blocks are encountered, they are not erased and * programmed. * ****************************************************************************/ int NandReadWriteExample(u32 NandDeviceId) { int Status; u32 Index; u32 BlockIndex; XNandPs_Config *ConfigPtr; u64 Offset; u32 Length; u32 StartBlock; u32 EndBlock; /* * Initialize the flash driver. */ ConfigPtr = XNandPs_LookupConfig(NandDeviceId); if (ConfigPtr == NULL) { return XST_FAILURE; } Status = XNandPs_CfgInitialize(NandInstPtr, ConfigPtr, ConfigPtr->SmcBase,ConfigPtr->FlashBase); if (Status != XST_SUCCESS) { return XST_FAILURE; } StartBlock = NAND_TEST_START_BLOCK; EndBlock = NAND_TEST_START_BLOCK + NAND_TEST_NUM_BLOCKS; Length = NAND_TEST_BLOCK_SIZE; /* * Prepare the write buffer. Fill in the data need to be written into * Flash Device. */ for (Index = 0; Index < Length; Index++) { WriteBuffer[Index] = Index % 256; } /* * Erase the blocks in the flash */ for (BlockIndex = StartBlock; BlockIndex < EndBlock; BlockIndex++) { /* * Don't erase bad blocks. */ if (XNandPs_IsBlockBad(NandInstPtr, BlockIndex) == XST_SUCCESS) { continue; } /* * Perform erase operation. */ Status = XNandPs_EraseBlock(NandInstPtr, BlockIndex); if (Status != XST_SUCCESS) { return Status; } } /* * Perform the read/write operation */ for (BlockIndex = StartBlock; BlockIndex < EndBlock; BlockIndex++) { /* * Don't program bad blocks. */ if (XNandPs_IsBlockBad(NandInstPtr, BlockIndex) == XST_SUCCESS) { continue; } Offset = BlockIndex * NandInstPtr->Geometry.BlockSize; /* * Perform the write operation. */ Status = XNandPs_Write(NandInstPtr, Offset, Length, WriteBuffer, NULL); if (Status != XST_SUCCESS) { return Status; } /* * Perform the read operation. */ Status = XNandPs_Read(NandInstPtr, Offset, Length, ReadBuffer, NULL); if (Status != XST_SUCCESS) { return Status; } /* * Compare the data read against the data Written. */ for (Index = 0; Index < Length; Index++) { if (ReadBuffer[Index] != WriteBuffer[Index]) { return XST_FAILURE; } } /* * Clear the Receive buffer for next iteration */ memset(ReadBuffer, 0, Length); } return XST_SUCCESS; }