Jump to main content

##

# 1.1.6.2 Using The Library

The SDMMC driver can be used to communicate with SD/eMMC Cards.

Modes supported:

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

Usage Methods

- Application can directly use the SDMMC driver API's to perform Read/Write operations.

- Application can use File System service layer and perform file operations on the SD/eMMC Card.

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

Example application to Write and Read SD Card in Asynchronous mode

    /* Write and Read 60KB of Data */
    #define SDMMC_DATA_SIZE              (61440U)
    #define SDMMC_BUFFER_SIZE            (SDMMC_DATA_SIZE / sizeof(uint32_t))

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

    #define BLOCK_START                 0x2000

    SYS_MEDIA_GEOMETRY *geometry = NULL;

    APP_DATA appData;

    /* Read Buffer */
    uint32_t CACHE_ALIGN readBuffer[SDMMC_BUFFER_SIZE];

    /* Write Buffer*/
    uint32_t CACHE_ALIGN writeBuffer[SDMMC_BUFFER_SIZE];

    void appTransferHandler
    (
        DRV_SDMMC_EVENT event,
        DRV_SDMMC_COMMAND_HANDLE commandHandle,
        uintptr_t context
    )
    {
        APP_DATA* app_data = (APP_DATA *)context;

        switch(event)
        {
            case DRV_SDMMC_EVENT_COMMAND_COMPLETE:
            {
                app_data->xfer_done = true;
                break;
            }

            case DRV_SDMMC_EVENT_COMMAND_ERROR:
            {
                app_data->state = APP_STATE_ERROR;
                break;
            }

            default:
            {
                break;
            }
        }
    }

    void APP_Initialize ( void )
    {
        uint32_t i = 0;

        /* Place the App state machine in its initial state. */
        appData.state = APP_STATE_OPEN_DRIVER;
        appData.xfer_done = false;

        for (i = 0; i < SDMMC_BUFFER_SIZE; i++)
        {
            writeBuffer[i] = i;
        }
    }

    void APP_Tasks ( void )
    {

        /* Check the application's current state. */
        switch ( appData.state )
        {
            case APP_STATE_OPEN_DRIVER:
            {
                appData.sdmmcHandle = DRV_SDMMC_Open(DRV_SDMMC_INDEX_0, DRV_IO_INTENT_READWRITE);

                if (appData.sdmmcHandle != DRV_HANDLE_INVALID)
                {
                    DRV_SDMMC_EventHandlerSet(appData.sdmmcHandle, (const void*)appTransferHandler, (uintptr_t)&appData);
                    appData.state = APP_STATE_SDCARD_ATTACHED;
                }
                else
                {
                    appData.state = APP_STATE_ERROR;
                }
                break;
            }

            case APP_STATE_SDCARD_ATTACHED:
            {
                if (DRV_SDMMC_IsAttached(appData.sdmmcHandle) == true)
                {
                    appData.state = APP_STATE_GEOMETRY_GET;
                }
                break;
            }

            case APP_STATE_GEOMETRY_GET:
            {
                geometry = DRV_SDMMC_GeometryGet(appData.sdmmcHandle);

                if (geometry == NULL)
                {
                    appData.state = APP_STATE_ERROR;
                }
                else
                {
                    appData.numReadBlocks  = (SDMMC_DATA_SIZE / geometry->geometryTable[GEOMETRY_TABLE_READ_ENTRY].blockSize);
                    appData.numWriteBlocks = (SDMMC_DATA_SIZE / geometry->geometryTable[GEOMETRY_TABLE_WRITE_ENTRY].blockSize);
                    appData.numEraseBlocks = (SDMMC_DATA_SIZE / geometry->geometryTable[GEOMETRY_TABLE_ERASE_ENTRY].blockSize);
                    appData.state = APP_STATE_WRITE_MEMORY;
                }
                break;
            }

            case APP_STATE_WRITE_MEMORY:
            {
                DRV_SDMMC_AsyncWrite(appData.sdmmcHandle, &appData.writeHandle, (void *)writeBuffer, BLOCK_START, appData.numWriteBlocks);

                if (appData.writeHandle == DRV_SDMMC_COMMAND_HANDLE_INVALID)
                {
                    appData.state = APP_STATE_ERROR;
                }
                else
                {
                    appData.state = APP_STATE_READ_MEMORY;
                }
                break;
            }

            case APP_STATE_READ_MEMORY:
            {
                if (appData.xfer_done == true)
                {
                    /* Write to the SD Card is complete */
                    appData.xfer_done = false;

                    memset((void *)readBuffer, 0, SDMMC_DATA_SIZE);

                    DRV_SDMMC_AsyncRead(appData.sdmmcHandle, &appData.readHandle, (void *)readBuffer, BLOCK_START, appData.numReadBlocks);

                    if (appData.readHandle == DRV_SDMMC_COMMAND_HANDLE_INVALID)
                    {
                        appData.state = APP_STATE_ERROR;
                    }
                    else
                    {
                        appData.state = APP_STATE_VERIFY_DATA;
                    }
                }
                break;
            }

            case APP_STATE_VERIFY_DATA:
            {
                /* Wait until all the above queued transfer requests are done */
                if(appData.xfer_done == true)
                {
                    appData.xfer_done = false;
                    if (!memcmp(writeBuffer, readBuffer, SDMMC_DATA_SIZE))
                    {
                        appData.state = APP_STATE_SUCCESS;
                    }
                    else
                    {
                        appData.state = APP_STATE_ERROR;
                    }
                }
                break;
            }

            case APP_STATE_SUCCESS:
            {
                DRV_SDMMC_Close(appData.sdmmcHandle);
                LED_ON();

                break;
            }

            case APP_STATE_ERROR:
            default:
            {
                DRV_SDMMC_Close(appData.sdmmcHandle);
                break;
            }
        }
    }