/*
* fmsh_pl_user_flash.c
*
* Created on: 2024年3月4日
* Author: zhaolb
*/
#include "fmsh_pl_user_flash.h"
int fmsh_pl_user_flash_test()
{
int Status;
u32 Index;
u32 Address;
init_platform();
FMSH_WriteReg(FPS_SLCR_BASEADDR, 0x008, 0xDF0D767BU); //unlock
FMSH_WriteReg(FPS_SLCR_BASEADDR, 0x838, 0xf); //Open USER_LVL_SHFTR_EN_A and USER_LVL_SHFTR_EN_5
FMSH_WriteReg(FPS_SLCR_BASEADDR, 0x004, 0xDF0D767BU); //lock
XSpi_Config *ConfigPtr; /* Pointer to Configuration data */
/*
* Initialize the SPI driver so that it's ready to use,
* specify the device ID that is generated in xparameters.h.
*/
ConfigPtr = XSpi_LookupConfig(SPI_DEVICE_ID);
if (ConfigPtr == NULL) {
return XST_DEVICE_NOT_FOUND;
}
Status = XSpi_CfgInitialize(&Spi, ConfigPtr,
ConfigPtr->BaseAddress);
if (Status != XST_SUCCESS) {
return XST_FAILURE;
}
/*
* Connect the SPI driver to the interrupt subsystem such that
* interrupts can occur. This function is application specific.
*/
Status = axi_irq_request(&IntcInstance); //PS中断控制器初始化;
if(Status != XST_SUCCESS) {
return XST_FAILURE;
}
/*
* Setup the handler for the SPI that will be called from the interrupt
* context when an SPI status occurs, specify a pointer to the SPI
* driver instance as the callback reference so the handler is able to
* access the instance data.
*/
XSpi_SetStatusHandler(&Spi, &Spi, (XSpi_StatusHandler)SpiHandler);
/*
* Set the SPI device as a master and in manual slave select mode such
* that the slave select signal does not toggle for every byte of a
* transfer, this must be done before the slave select is set.
*/
Status = XSpi_SetOptions(&Spi, XSP_MASTER_OPTION |
XSP_MANUAL_SSELECT_OPTION);
if(Status != XST_SUCCESS) {
return XST_FAILURE;
}
/*
* Select the quad flash device on the SPI bus, so that it can be
* read and written using the SPI bus.
*/
Status = XSpi_SetSlaveSelect(&Spi, SPI_SELECT);
if(Status != XST_SUCCESS) {
return XST_FAILURE;
}
/*
* Start the SPI driver so that interrupts and the device are enabled.
*/
XSpi_Start(&Spi);
/*
* Specify address in the Quad Serial Flash for the Erase/Write/Read
* operations.
*/
Address = FLASH_TEST_ADDRESS;
/*
* Perform the Write Enable operation.
*/
Status = SpiFlashWriteEnable(&Spi);
if(Status != XST_SUCCESS) {
return XST_FAILURE;
}
/*
* Perform the Sector Erase operation.
*/
Status = SpiFlashSectorErase(&Spi, Address);
if(Status != XST_SUCCESS) {
return XST_FAILURE;
}
/*
* Perform the Write Enable operation.
*/
Status = SpiFlashWriteEnable(&Spi);
if(Status != XST_SUCCESS) {
return XST_FAILURE;
}
/*
* Write the data to the Page using Page Program command.
*/
Status = SpiFlashWrite(&Spi, Address, PAGE_SIZE, COMMAND_PAGE_PROGRAM);
if(Status != XST_SUCCESS) {
return XST_FAILURE;
}
/*
* Clear the read Buffer.
*/
for(Index = 0; Index < PAGE_SIZE + READ_WRITE_EXTRA_BYTES; Index++) {
ReadBuffer[Index] = 0x0;
}
/*
* Read the data from the Page using Random Read command.
*/
Status = SpiFlashRead(&Spi, Address, PAGE_SIZE, COMMAND_RANDOM_READ);
if(Status != XST_SUCCESS) {
return XST_FAILURE;
}
/*
* Compare the data read against the data written.
*/
for(Index = 0; Index < PAGE_SIZE; Index++) {
if(ReadBuffer[Index + READ_WRITE_EXTRA_BYTES] !=
(u8)(Index + TestByte)) {
return XST_FAILURE;
}
}
/*
* Clear the Read Buffer.
*/
for(Index = 0; Index < PAGE_SIZE + READ_WRITE_EXTRA_BYTES +
DUAL_READ_DUMMY_BYTES; Index++) {
ReadBuffer[Index] = 0x0;
}
/*
* Read the data from the Page using Dual Output Fast Read command.
*/
Status = SpiFlashRead(&Spi, Address, PAGE_SIZE, COMMAND_DUAL_READ);
if(Status != XST_SUCCESS) {
return XST_FAILURE;
}
/*
* Compare the data read against the data written.
*/
for(Index = 0; Index < PAGE_SIZE; Index++) {
if(ReadBuffer[Index + READ_WRITE_EXTRA_BYTES +
DUAL_READ_DUMMY_BYTES] !=
(u8)(Index + TestByte)) {
return XST_FAILURE;
}
}
/*
* Clear the read Buffer.
*/
for(Index = 0; Index < PAGE_SIZE + READ_WRITE_EXTRA_BYTES +
QUAD_READ_DUMMY_BYTES; Index++) {
ReadBuffer[Index] = 0x0;
}
/*
* Read the data from the Page using Quad Output Fast Read command.
*/
Status = SpiFlashRead(&Spi, Address, PAGE_SIZE, COMMAND_QUAD_READ);
if(Status != XST_SUCCESS) {
return XST_FAILURE;
}
/*
* Compare the data read against the data written.
*/
for(Index = 0; Index < PAGE_SIZE; Index++) {
if(ReadBuffer[Index + READ_WRITE_EXTRA_BYTES +
QUAD_READ_DUMMY_BYTES] != (u8)(Index + TestByte)) {
return XST_FAILURE;
}
}
/*
* Perform the Write Enable operation.
*/
Status = SpiFlashWriteEnable(&Spi);
if(Status != XST_SUCCESS) {
return XST_FAILURE;
}
/*
* Write the data to the next Page using Quad Fast Write command. Erase
* is not required since we are writing to next page with in the same
* erased sector
*/
TestByte = 0x09;
Address += PAGE_SIZE;
Status = SpiFlashWrite(&Spi, Address, PAGE_SIZE, COMMAND_QUAD_WRITE);
if(Status != XST_SUCCESS) {
return XST_FAILURE;
}
/*
* Wait while the Flash is busy.
*/
Status = SpiFlashWaitForFlashReady();
if(Status != XST_SUCCESS) {
return XST_FAILURE;
}
/*
* Clear the read Buffer.
*/
for(Index = 0; Index < PAGE_SIZE + READ_WRITE_EXTRA_BYTES;
Index++) {
ReadBuffer[Index] = 0x0;
}
/*
* Read the data from the Page using Normal Read command.
*/
Status = SpiFlashRead(&Spi, Address, PAGE_SIZE, COMMAND_RANDOM_READ);
if(Status != XST_SUCCESS) {
return XST_FAILURE;
}
/*
* Compare the data read against the data written.
*/
for(Index = 0; Index < PAGE_SIZE; Index++) {
if(ReadBuffer[Index + READ_WRITE_EXTRA_BYTES] !=
(u8)(Index + TestByte)) {
return XST_FAILURE;
}
}
/*
* Clear the read Buffer.
*/
for(Index = 0; Index < PAGE_SIZE + READ_WRITE_EXTRA_BYTES +
DUAL_IO_READ_DUMMY_BYTES; Index++) {
ReadBuffer[Index] = 0x0;
}
/*
* Read the data from the Page using Dual IO Fast Read command.
*/
Status = SpiFlashRead(&Spi, Address, PAGE_SIZE, COMMAND_DUAL_IO_READ);
if(Status != XST_SUCCESS) {
return XST_FAILURE;
}
/*
* Compare the data read against the data written.
*/
for(Index = 0; Index < PAGE_SIZE; Index++) {
if(ReadBuffer[Index + READ_WRITE_EXTRA_BYTES +
DUAL_IO_READ_DUMMY_BYTES] !=
(u8)(Index + TestByte)) {
return XST_FAILURE;
}
}
/*
* Clear the read Buffer.
*/
for(Index = 0; Index < PAGE_SIZE + READ_WRITE_EXTRA_BYTES +
QUAD_IO_READ_DUMMY_BYTES; Index++) {
ReadBuffer[Index] = 0x0;
}
/*
* Read the data from the Page using Quad IO Fast Read command.
*/
Status = SpiFlashRead(&Spi, Address, PAGE_SIZE, COMMAND_QUAD_IO_READ);
if(Status != XST_SUCCESS) {
return XST_FAILURE;
}
/*
* Compare the data read against the data written.
*/
for(Index = 0; Index < PAGE_SIZE; Index++) {
if(ReadBuffer[Index + READ_WRITE_EXTRA_BYTES +
QUAD_IO_READ_DUMMY_BYTES] !=
(u8)(Index + TestByte)) {
return XST_FAILURE;
}
}
fmsh_print("Successfully ran Spi numonyx flash quad Example\r\n");
cleanup_platform();
return XST_SUCCESS;
}
/*****************************************************************************/
/**
*
* This function enables writes to the Numonyx Serial Flash memory.
*
* @param SpiPtr is a pointer to the instance of the Spi device.
*
* @return XST_SUCCESS if successful else XST_FAILURE.
*
* @note None
*
******************************************************************************/
int SpiFlashWriteEnable(XSpi *SpiPtr)
{
int Status;
/*