AM243x MCU+ SDK  11.00.00
MMCSD Low Level Driver

Multi-Media Card Secure Digital (MMCSD) peripheral is a driver which provides an interface with storage devices which follows MMC/SD/SDIO protocol. The driver supports single bit, four bit and eight bit data lines to communicate with the connected media. The MMCSD controller provides accessibility to external MMC/SD/SDIO devices using a programmed IO method or DMA data transfer method. There are two MMCSD modules inside the SOC - MMCSD0 and MMCSD1.

Features Supported

  • Integrated DMA Controller supporting SD Advanced DMA - SDMA, ADMA2 and ADMA3
  • 64-bit data, address width System Bus Interface
  • MMCSD0 supports eMMC 5.1, and also backward compatible withe earlier eMMC standards
  • MMCSD1 supports SD card HC 4.10 and SD Physical Layer v3.01, SDIO v3.00

SysConfig Features

Note
It is strongly recommend to use SysConfig where it is available instead of using direct SW API calls. This will help simplify the SW application and also catch common mistakes early in the development cycle.

Features not Supported

  • MMCSD0 does not support SD card, SDIO and voltages 3.3V, 3.0V, 1.2V and HS400 DDR
  • MMCSD1 does not support MMC card, UHS-II SD card and SDR104

Usage Overview

API Sequence

To use the MMCSD LLD driver to write/read data to or from a MMC/SD Device, the application calls the following APIs:

Initializing the MMCSD LLD Driver

MMCSD_lld_init() must be called before any other MMCSD APIs. This function uses mmcsd lld handle to initialize each instance.

Calling MMCSD_lld_init() a second time with the same handle previously passed to MMCSD_lld_init() will result in an error. You can, though, re-use the handle if the instance is closed via MMCSD_lld_deInit().

Please note that initializing MMCSD LLD driver is taken care by the SysConfig generated code.

MMCSD Transfer Mode

The MMCSD driver supports two transfer modes of operation: Polling and Interrupt Mode.

In Polling mode transfer can be initiated with all the polling mode APIs

In Interrupt mode Users have to register the appropriate ISR and assign a callback function before calling the interrupt mode APIs

DMA can enabled in any mode of operation if enabled.

Example Usage

Include the below file to access the APIs

#include <string.h>
#include <kernel/dpl/MutexArmP.h>
#include <kernel/nortos/dpl/r5/HwiP_armv7r_vim.h>

Instance Open Example

int32_t status = MMCSD_STS_SUCCESS;
gMmcsdLldHandle = (MMCSDLLD_Handle)(&gMmcsdLldObject);
gMmcsdLldHandle->initHandle = (MMCSDLLD_InitHandle)(&gMmcsdLldInitObject);
status = MMCSD_lld_init(gMmcsdLldHandle);

Instance Close Example

int32_t status = MMCSD_STS_SUCCESS;
status = MMCSD_lld_deInit(gMmcsdLldHandle);

Non-Blocking Transfer Example

gMmcsdLldHandle = (MMCSDLLD_Handle)(gMmcsdLldHandle);
intrNum = gMmcsdLldHandle->initHandle->intrNum;
intcBaseAddr = gHwiConfig.intcBaseAddr;
gMmcsdVimStsAddr = intcBaseAddr + (0x404u + (((intrNum)>> 5) & 0xFu)*0x20u);
gMmcsdVimStsClrMask = 0x1u << ((intrNum) & 0x1Fu);
/* Assign Transfer Complete Callback Function */
gMmcsdLldHandle->transferCompleteCallback = MMCSD_lld_transferCompleteCallback_implementation;
/* Register Interrupt */
HwiP_setVecAddr(intrNum, (uintptr_t)&App_MMCSD_ISR);
HwiP_setPri(intrNum, MMCSD_INTERRUPT_PRIORITY);
HwiP_enableInt(intrNum);
int32_t status = MMCSD_STS_SUCCESS;
uint32_t blockSize = MMCSD_lld_getBlockSize(gMmcsdLldHandle);
uint32_t numBlocks = APP_MMCSD_DATA_SIZE / blockSize;
if((APP_MMCSD_DATA_SIZE % blockSize) != 0)
{
numBlocks += 1;
}
/* Fill Write and Read Buffer */
mmcsd_io_fill_buffers();
/* Lock Mutex */
gMMCSDTransferMutex = MUTEX_ARM_LOCKED;
/* Initiate Transfer */
status = MMCSD_lld_write_SD_Intr(gMmcsdLldHandle, gMmcsdTxBuf,
APP_MMCSD_START_BLK, numBlocks);
/* Wait for Mutex to unlock */
while(try_lock_mutex(&gMMCSDTransferMutex) == MUTEX_ARM_LOCKED);

Non-Blocking Example transfer callback

void MMCSD_lld_transferCompleteCallback_implementation (void * args,
int32_t transferStatus)
{
unlock_mutex(&gMMCSDTransferMutex);
}

Non-Blocking Example ISR CALL callback

static __attribute__((__section__(".text.hwi"), noinline, naked, target("arm"), aligned(4))) void App_MMCSD_ISR(void)
{
ISR_CALL_LEVEL_NONFLOAT_REENTRANT(MMCSD_lld_Isr, \
gMmcsdLldHandle, \
intrNum, \
gMmcsdVimStsAddr, \
gMmcsdVimStsClrMask,
intcBaseAddr);
}

API

APIs for MMCSD LLD

__attribute__
struct tisci_boardcfg_sa2ul_cfg __attribute__
MMCSD_lld_Isr
void MMCSD_lld_Isr(void *args)
This is the MMCSD Controller ISR and can be used as IRQ handler.
MMCSD_lld_deInit
int32_t MMCSD_lld_deInit(MMCSDLLD_Handle handle)
This API De-Initializes the MMCSD instance.
MMCSD_lld_write_SD_Intr
int32_t MMCSD_lld_write_SD_Intr(MMCSDLLD_Handle handle, uint8_t *buf, uint32_t startBlk, uint32_t numBlks)
Function to perform block writes to the SD media in Interrupt Mode.
HwiP_enableInt
void HwiP_enableInt(uint32_t intNum)
Enable a specific interrupt.
MMCSDLLD_InitHandle
struct MMCSDLLD_InitObject * MMCSDLLD_InitHandle
MMCSD_lld_init
int32_t MMCSD_lld_init(MMCSDLLD_Handle handle)
This API Initializes the MMCSD instance.
DebugP.h
MMCSDLLD_Handle
struct MMCSDLLD_Object * MMCSDLLD_Handle
MMCSD_lld_getBlockSize
uint32_t MMCSD_lld_getBlockSize(MMCSDLLD_Handle handle)
This function returns the block size of the MMC/SD media connected to the MMCSD controller.
mmcsd.h
MMCSD Driver API/interface file.
MMCSD_STS_SUCCESS
#define MMCSD_STS_SUCCESS
Return status when the API execution was successful.
Definition: mmcsd_lld.h:87
DebugP_assert
#define DebugP_assert(expression)
Function to call for assert check.
Definition: DebugP.h:177