1.1.3.2 Using The Library

The Memory driver can be used to communicate with various media devices using common interface functions. The library interface functions can be used in two different modes.

Modes supported:

  • Asynchronous mode : Supported in both Bare-metal and RTOS environment

  • Synchronous mode : Supported in only RTOS environment

Usage Methods

  • Application can directly use the Memory driver API's to perform Media operations.

  • Application can use File System service layer which in-turn uses Memory driver to perform file operations on the media

  • It can be interfaced with Middleware's like USB.

Example application to Erase, Write and Read SST26 Flash Memory in Asynchronous mode

/* Will Erase, Write and Read into 4 Sectors of 4KB each*/
#define SST26_BUFFER_SIZE           (16384U)

#define GEOMETRY_TABLE_READ_ENTRY   (0)
#define GEOMETRY_TABLE_WRITE_ENTRY  (1)
#define GEOMETRY_TABLE_ERASE_ENTRY  (2)

#define BLOCK_START                 0x0

SYS_MEDIA_GEOMETRY *geometry = NULL;

APP_SST26_DATA CACHE_ALIGN appSST26Data;

void appTransferHandler
(
    DRV_MEMORY_EVENT event,
    DRV_MEMORY_COMMAND_HANDLE commandHandle,
    uintptr_t context
)
{
    APP_SST26_DATA *app_data = (APP_SST26_DATA *)context;

    switch(event)
    {
        case DRV_MEMORY_EVENT_COMMAND_COMPLETE:
        {
            /* Wait until the last request that is Read request is done */
            if (commandHandle == app_data->readHandle)
            {
                appSST26Data.xfer_done = true;
            }
            break;
        }

        case DRV_MEMORY_EVENT_COMMAND_ERROR:
        {
            appSST26Data.state = APP_SST26_STATE_ERROR;
            break;
        }

        default:
        {
            break;
        }
    }
}

void APP_SST26_Initialize ( void )
{
    uint32_t i = 0;

    /* Place the App state machine in its initial state. */
    appSST26Data.state = APP_SST26_STATE_OPEN_DRIVER;

    for (i = 0; i < SST26_BUFFER_SIZE; i++)
    {
        appSST26Data.writeBuffer[i] = i;
    }
}

void APP_SST26_Tasks ( void )
{
    /* Check the application's current state. */
    switch ( appSST26Data.state )
    {
        case APP_SST26_STATE_OPEN_DRIVER:
        {
            appSST26Data.memoryHandle = DRV_MEMORY_Open(DRV_MEMORY_INDEX_0, DRV_IO_INTENT_READWRITE);

            if (DRV_HANDLE_INVALID != appSST26Data.memoryHandle)
            {
                DRV_MEMORY_TransferHandlerSet(appSST26Data.memoryHandle, appTransferHandler, (uintptr_t)&appSST26Data);

                appSST26Data.state = APP_SST26_STATE_GEOMETRY_GET;
            }

            break;
        }

        case APP_SST26_STATE_GEOMETRY_GET:
        {
            geometry = DRV_MEMORY_GeometryGet(appSST26Data.memoryHandle);

            if (geometry == NULL)
            {
                appSST26Data.state = APP_SST26_STATE_ERROR;
                break;
            }

            appSST26Data.numReadBlocks  = (SST26_BUFFER_SIZE / geometry->geometryTable[GEOMETRY_TABLE_READ_ENTRY].blockSize);
            appSST26Data.numWriteBlocks = (SST26_BUFFER_SIZE / geometry->geometryTable[GEOMETRY_TABLE_WRITE_ENTRY].blockSize);
            appSST26Data.numEraseBlocks = (SST26_BUFFER_SIZE / geometry->geometryTable[GEOMETRY_TABLE_ERASE_ENTRY].blockSize);

            appSST26Data.state = APP_SST26_STATE_ERASE_FLASH;

            break;
        }

        case APP_SST26_STATE_ERASE_FLASH:
        {
            DRV_MEMORY_AsyncErase(appSST26Data.memoryHandle, &appSST26Data.eraseHandle, BLOCK_START, appSST26Data.numEraseBlocks);

            if (DRV_MEMORY_COMMAND_HANDLE_INVALID == appSST26Data.eraseHandle)
            {
                appSST26Data.state = APP_SST26_STATE_ERROR;
                break;
            }
            else
            {
                appSST26Data.state = APP_SST26_STATE_WRITE_MEMORY;
            }

            // Fall Through to submit Write request in the Memory Driver Queue
        }

        case APP_SST26_STATE_WRITE_MEMORY:
        {
            DRV_MEMORY_AsyncWrite(appSST26Data.memoryHandle, &appSST26Data.writeHandle, (void *)&appSST26Data.writeBuffer, BLOCK_START, appSST26Data.numWriteBlocks);

            if (DRV_MEMORY_COMMAND_HANDLE_INVALID == appSST26Data.writeHandle)
            {
                appSST26Data.state = APP_SST26_STATE_ERROR;
                break;
            }
            else
            {
                appSST26Data.state = APP_SST26_STATE_READ_MEMORY;
            }

            // Fall Through to submit Read request in the Memory Driver Queue
        }

        case APP_SST26_STATE_READ_MEMORY:
        {
            DRV_MEMORY_AsyncRead(appSST26Data.memoryHandle, &appSST26Data.readHandle, (void *)appSST26Data.readBuffer, BLOCK_START, appSST26Data.numReadBlocks);

            if (DRV_MEMORY_COMMAND_HANDLE_INVALID == appSST26Data.readHandle)
            {
                appSST26Data.state = APP_SST26_STATE_ERROR;
                break;
            }
            else
            {
                appSST26Data.state = APP_SST26_STATE_XFER_WAIT;
            }

            // Fall Through to Wait for all above requests to be completed
        }

        case APP_SST26_STATE_XFER_WAIT:
        {
            /* Wait until all the above queued transfer requests are done */
            if(appSST26Data.xfer_done)
            {
                appSST26Data.xfer_done = false;
                appSST26Data.state = APP_SST26_STATE_VERIFY_DATA;
            }

            break;
        }

        case APP_SST26_STATE_VERIFY_DATA:
        {
            if (!memcmp(appSST26Data.writeBuffer, appSST26Data.readBuffer, SST26_BUFFER_SIZE))
            {
                appSST26Data.state = APP_SST26_STATE_SUCCESS;
            }
            else
            {
                appSST26Data.state = APP_SST26_STATE_ERROR;
            }

            DRV_MEMORY_Close(appSST26Data.memoryHandle);

            break;
        }

        case APP_SST26_STATE_SUCCESS:
        case APP_SST26_STATE_ERROR:
        default:
        {
            break;
        }
    }
}