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;
        }
    }
}