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