1.1.13.3.2 Using The Library
The W25 driver provides non-blocking API's to read, write and erase W25 Flash memory.
The W25 driver can be used in following ways:
To perform page write to W25 Flash. Here, the memory start address must be aligned to the page boundary
To perform Sector/Block/Chip Erase operations
To unlock flash before performing Erase/Write operations. Done as part of DRV_W25_Open().
To read flash JEDEC-ID
To interface with the Memory driver to perform block operations on the W25 Flash
Note: The client should poll for the status of the data transfer
Example application to Erase, Write and Read W25 Flash Memory
/* Erase-Write-Read 2 Sector of Data (4096 *2)*/ #define BUFFER_SIZE 8192 #define MEM_ADDRESS 0x0 APP_DATA CACHE_ALIGN appData; static uint32_t erase_index = 0; static uint32_t write_index = 0; void APP_Initialize ( void ) { uint32_t i = 0; /* Place the App state machine in its initial state. */ appData.state = APP_STATE_INIT; for (i = 0; i < BUFFER_SIZE; i++) appData.writeBuffer[i] = i; } void APP_Tasks ( void ) { DRV_W25_TRANSFER_STATUS transferStatus = DRV_W25_TRANSFER_ERROR_UNKNOWN; /* Check the application's current state. */ switch ( appData.state ) { /* Application's initial state. */ case APP_STATE_INIT: { if (DRV_W25_Status(DRV_W25_INDEX) == SYS_STATUS_READY) { appData.state = APP_STATE_OPEN_DRIVER; } break; } case APP_STATE_OPEN_DRIVER: { appData.handle = DRV_W25_Open(DRV_W25_INDEX, DRV_IO_INTENT_READWRITE); if (appData.handle != DRV_HANDLE_INVALID) { appData.state = APP_STATE_GEOMETRY_GET; } break; } case APP_STATE_GEOMETRY_GET: { if (DRV_W25_GeometryGet(appData.handle, &appData.geometry) != true) { appData.state = APP_STATE_ERROR; break; } erase_index = 0; write_index = 0; appData.state = APP_STATE_ERASE_FLASH; break; } case APP_STATE_ERASE_FLASH: { if (DRV_W25_SectorErase(appData.handle, (MEM_ADDRESS + erase_index)) != true) { appData.state = APP_STATE_ERROR; } appData.state = APP_STATE_ERASE_WAIT; break; } case APP_STATE_ERASE_WAIT: { transferStatus = DRV_W25_TransferStatusGet(appData.handle); if(transferStatus == DRV_W25_TRANSFER_COMPLETED) { erase_index += appData.geometry.erase_blockSize; if (erase_index < BUFFER_SIZE) { appData.state = APP_STATE_ERASE_FLASH; } else { appData.state = APP_STATE_WRITE_MEMORY; } } else if (transferStatus == DRV_W25_TRANSFER_ERROR_UNKNOWN) { appData.state = APP_STATE_ERROR; } break; } case APP_STATE_WRITE_MEMORY: { if (DRV_W25_PageWrite(appData.handle, (uint32_t *)&appData.writeBuffer[write_index], (MEM_ADDRESS + write_index)) != true) { appData.state = APP_STATE_ERROR; break; } appData.state = APP_STATE_WRITE_WAIT; break; } case APP_STATE_WRITE_WAIT: { transferStatus = DRV_W25_TransferStatusGet(appData.handle); if(transferStatus == DRV_W25_TRANSFER_COMPLETED) { write_index += appData.geometry.write_blockSize; if (write_index < BUFFER_SIZE) { appData.state = APP_STATE_WRITE_MEMORY; } else { appData.state = APP_STATE_READ_MEMORY; } } else if (transferStatus == DRV_W25_TRANSFER_ERROR_UNKNOWN) { appData.state = APP_STATE_ERROR; } break; } case APP_STATE_READ_MEMORY: { if (DRV_W25_Read(appData.handle, (uint32_t *)&appData.readBuffer, BUFFER_SIZE, MEM_ADDRESS) != true) { appData.state = APP_STATE_ERROR; } else { appData.state = APP_STATE_READ_WAIT; } break; } case APP_STATE_READ_WAIT: { transferStatus = DRV_W25_TransferStatusGet(appData.handle); if(transferStatus == DRV_W25_TRANSFER_COMPLETED) { appData.state = APP_STATE_VERIFY_DATA; } else if (transferStatus == DRV_W25_TRANSFER_ERROR_UNKNOWN) { appData.state = APP_STATE_ERROR; } break; } case APP_STATE_VERIFY_DATA: { if (!memcmp(appData.writeBuffer, appData.readBuffer, BUFFER_SIZE)) { appData.state = APP_STATE_SUCCESS; } else { appData.state = APP_STATE_ERROR; } break; } case APP_STATE_SUCCESS: { DRV_W25_Close(appData.handle); LED_ON(); break; } case APP_STATE_ERROR: default: { DRV_W25_Close(appData.handle); break; } } }