1.1.7.2 Using The Library

The SDSPI driver builds on top of the SPI PLIB or SPI Driver and provides direct access to the SD Card. It also confirms to the media block layer interface which allows it to register its services with the file system's media block driver interface.

Modes supported:

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

  • Synchronous mode : Supported in RTOS environment

Usage Methods

  • Application can directly use the SDSPI 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 Synchronous mode

/* Write and Read 60KB of Data */
#define SDSPI_DATA_SIZE              (10240U)
#define SDSPI_BUFFER_SIZE            (SDSPI_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 */
static CACHE_ALIGN uint32_t readBuffer[SDSPI_BUFFER_SIZE];

/* Write Buffer*/
static CACHE_ALIGN uint32_t writeBuffer[SDSPI_BUFFER_SIZE];

void APP_Initialize ( void )
{
    uint32_t i = 0;

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

    for (i = 0; i < SDSPI_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.sdspiHandle = DRV_SDSPI_Open(DRV_SDSPI_INDEX_0, DRV_IO_INTENT_READWRITE);

            if (appData.sdspiHandle != DRV_HANDLE_INVALID)
            {
                appData.state = APP_STATE_WAIT_FOR_SDCARD_ATTACH;
            }
            break;
        }

        case APP_STATE_WAIT_FOR_SDCARD_ATTACH:
        {
            if (DRV_SDSPI_IsAttached(appData.sdspiHandle) == true)
            {
                appData.state = APP_STATE_GEOMETRY_GET;
            }
            break;
        }

        case APP_STATE_GEOMETRY_GET:
        {
            geometry = DRV_SDSPI_GeometryGet(appData.sdspiHandle);

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

        case APP_STATE_WRITE_MEMORY:
        {
            if (DRV_SDSPI_SyncWrite(appData.sdspiHandle, (void *)writeBuffer, BLOCK_START, appData.numWriteBlocks) == true)
            {
                appData.state = APP_STATE_READ_MEMORY;
            }
            else
            {
                appData.state = APP_STATE_ERROR;
            }

            break;
        }

        case APP_STATE_READ_MEMORY:
        {
            memset((void *)readBuffer, 0, SDSPI_DATA_SIZE);

            if (DRV_SDSPI_SyncRead(appData.sdspiHandle, (void *)readBuffer, BLOCK_START, appData.numReadBlocks) == true)
            {
                appData.state = APP_STATE_VERIFY_DATA;
            }
            else
            {
                appData.state = APP_STATE_ERROR;
            }

            break;
        }

        case APP_STATE_VERIFY_DATA:
        {
            if (!memcmp(writeBuffer, readBuffer, SDSPI_DATA_SIZE))
            {
                appData.state = APP_STATE_SUCCESS;
            }
            else
            {
                appData.state = APP_STATE_ERROR;
            }
            DRV_SDSPI_Close(appData.sdspiHandle);

            break;
        }

        case APP_STATE_SUCCESS:
        {
            LED_ON();
            break;
        }

        case APP_STATE_ERROR:
        default:
        {
            LED_OFF();
            break;
        }
    }
}