Hardware Abstraction Layer (HAL)
SDHC (SD Host Controller)

General Description

High level interface to the Secure Digital Host Controller (SDHC).

The SDHC driver allows data to be read from and written to an SD Card using the SDHC block. The data is transferred in blocks with a block size of 512 bytes.

Features

Quick Start

Initialize SDHC by using cyhal_sdhc_init by selecting the pins according to the target device used. Specify the SDHC configuration using the configuration structure (const cyhal_sdhc_config_t * config).
See Snippet 1: SDHC Initialization and configuration

Code Snippets

Snippet 1: SDHC Initialization and configuration

The following snippet is used to initialize the SDHC block. SDHC object - cyhal_sdhc_t, SDHC card configuration structure (const cyhal_sdhc_config_t * config). The pins connected to the SDHC block needs to be provided to the cyhal_sdhc_init function.

/* Pins connected to the SDHC block */
#define CMD P12_4
#define CLK P12_5
#define DAT0 P13_0
#define DAT1 P13_1
#define DAT2 P13_2
#define DAT3 P13_3
/* dat4 to dat7 are reserved for future use and should be NC */
#define DAT4 NC
#define DAT5 NC
#define DAT6 NC
#define DAT7 NC
#define CARD_DETECT P12_1
#define EMMC_RESET NC
#define IO_VOLT_SEL NC
#define CARD_IF_PWREN NC
#define CARD_MECH_WRITEPROT NC
#define LED_CTL NC
#define ENABLE_LED_CONTROL false
#define LOW_VOLTAGE_SIGNALLING false
#define IS_EMMC false
#define BUS_WIDTH 4
cy_rslt_t rslt;
cyhal_sdhc_t sdhc_obj;
const cyhal_sdhc_config_t sdhc_config = {ENABLE_LED_CONTROL,
LOW_VOLTAGE_SIGNALLING,
IS_EMMC, BUS_WIDTH};
rslt = cyhal_sdhc_init(&sdhc_obj, &sdhc_config, CMD, CLK,
DAT0, DAT1, DAT2, DAT3, DAT4, DAT5, DAT6, DAT7,
CARD_DETECT, IO_VOLT_SEL, CARD_IF_PWREN,
CARD_MECH_WRITEPROT, LED_CTL, EMMC_RESET);

Snippet 2: SDHC Initialization and configuration with custom card detect pin

The following snippet is used to initialize the SDHC block with a custom card detect pin. Cy_SD_Host_IsCardConnected() function needs to be over-ridden depending on the card detect pin selected.

#define CUSTOM_CARD_DETECT P13_5
__USED bool Cy_SD_Host_IsCardConnected(SDHC_Type const *base __attribute__((unused)))
{
/* Card detect pin reads 0 (false) when card detected, 1 (true) when card not detected */
return cyhal_gpio_read(CUSTOM_CARD_DETECT) ? false : true;
}
void snippet_cyhal_sdhc_init_custom_card_detect()
{
/* Pins connected to the SDHC block */
#define CMD P12_4
#define CLK P12_5
#define DAT0 P13_0
#define DAT1 P13_1
#define DAT2 P13_2
#define DAT3 P13_3
/* dat4 to dat7 are reserved for future use and should be NC */
#define DAT4 NC
#define DAT5 NC
#define DAT6 NC
#define DAT7 NC
#define CARD_DETECT P12_1
#define EMMC_RESET NC
#define IO_VOLT_SEL NC
#define CARD_IF_PWREN NC
#define CARD_MECH_WRITEPROT NC
#define LED_CTL NC
#define ENABLE_LED_CONTROL false
#define LOW_VOLTAGE_SIGNALLING false
#define IS_EMMC false
#define BUS_WIDTH 4
#define INITIAL_VALUE true
cy_rslt_t rslt;
cyhal_sdhc_t sdhc_obj;
const cyhal_sdhc_config_t sdhc_config = {ENABLE_LED_CONTROL,
LOW_VOLTAGE_SIGNALLING,
IS_EMMC, BUS_WIDTH};
rslt = cyhal_gpio_init(CUSTOM_CARD_DETECT, CYHAL_GPIO_DIR_INPUT, CYHAL_GPIO_DRIVE_NONE, INITIAL_VALUE);
CY_ASSERT(CY_RSLT_SUCCESS == rslt);
rslt = cyhal_sdhc_init(&sdhc_obj, &sdhc_config, CMD, CLK,
DAT0, DAT1, DAT2, DAT3, DAT4, DAT5, DAT6, DAT7,
CARD_DETECT, IO_VOLT_SEL, CARD_IF_PWREN,
CARD_MECH_WRITEPROT, LED_CTL, EMMC_RESET);
}

Snippet 3: Reading a block of data from an SD Card

The following snippet reads a block of data from the SD Card.

#define DEFAULT_BLOCKSIZE 512
/* Data buffer to store the data read from the SD Card */
uint8_t read_buff[DEFAULT_BLOCKSIZE] = {0};
/* Starting block address from which the data needs to be read */
uint32_t block_address = 0;
/* Number of blocks that needs to be read */
size_t block_count = 1;
rslt = cyhal_sdhc_read(&sdhc_obj, block_address, read_buff, &block_count);

Snippet 4: Writing a block of data to an SD Card

The following snippet writes a block of data to the SD Card.

#define DEFAULT_BLOCKSIZE 512
/* Number of bytes of data to be written into the SD Card */
#define DATA_BYTE_COUNT (2 * DEFAULT_BLOCKSIZE)
/* Data buffer that stores the data to be written into the SD Card */
uint8_t write_buff[DATA_BYTE_COUNT];
/* Starting block address into which the data is to be written */
uint32_t block_address = 0;
/* Number of blocks that needs to be written */
size_t block_count = 2;
/* Generate sample data */
for (int i = 0; i < DATA_BYTE_COUNT; i++)
{
write_buff[i] = i;
}
rslt = cyhal_sdhc_write(&sdhc_obj, block_address, write_buff, &block_count);

API Reference

 SDHC HAL Results
 SDHC specific return codes.
 

Data Structures

struct  cyhal_sdhc_config_t
 Defines configuration options for the SDHC block. More...
 

Typedefs

typedef void(* cyhal_sdhc_event_callback_t) (void *callback_arg, cyhal_sdhc_event_t event)
 Handler for SDHC interrupts.
 

Enumerations

enum  cyhal_sdhc_card_type_t {
  CYHAL_SDHC_SD,
  CYHAL_SDHC_SDIO,
  CYHAL_SDHC_EMMC,
  CYHAL_SDHC_COMBO,
  CYHAL_SDHC_UNUSABLE,
  CYHAL_SDHC_NOT_EMMC
}
 Card types. More...
 
enum  cyhal_sdhc_event_t {
  CYHAL_SDHC_CMD_COMPLETE = 0x00001,
  CYHAL_SDHC_XFER_COMPLETE = 0x00002,
  CYHAL_SDHC_BGAP_EVENT = 0x00004,
  CYHAL_SDHC_DMA_INTERRUPT = 0x00008,
  CYHAL_SDHC_BUF_WR_READY = 0x00010,
  CYHAL_SDHC_BUF_RD_READY = 0x00020,
  CYHAL_SDHC_CARD_INSERTION = 0x00040,
  CYHAL_SDHC_CARD_REMOVAL = 0x00080,
  CYHAL_SDHC_CARD_INTERRUPT = 0x00100,
  CYHAL_SDHC_INT_A = 0x00200,
  CYHAL_SDHC_INT_B = 0x00400,
  CYHAL_SDHC_INT_C = 0x00800,
  CYHAL_SDHC_RE_TUNE_EVENT = 0x01000,
  CYHAL_SDHC_FX_EVENT = 0x02000,
  CYHAL_SDHC_CQE_EVENT = 0x04000,
  CYHAL_SDHC_ASYNC_READ_COMPLETE = 0x10000,
  CYHAL_SDHC_ASYNC_WRITE_COMPLETE = 0x20000,
  CYHAL_SDHC_ERR_INTERRUPT = 0x08000,
  CYHAL_SDHC_ALL_INTERRUPTS = 0x3FFFF
}
 SDHC interrupt triggers. More...
 

Functions

cy_rslt_t cyhal_sdhc_init (cyhal_sdhc_t *obj, const cyhal_sdhc_config_t *config, cyhal_gpio_t cmd, cyhal_gpio_t clk, cyhal_gpio_t data0, cyhal_gpio_t data1, cyhal_gpio_t data2, cyhal_gpio_t data3, cyhal_gpio_t data4, cyhal_gpio_t data5, cyhal_gpio_t data6, cyhal_gpio_t data7, cyhal_gpio_t cardDetect, cyhal_gpio_t ioVoltSel, cyhal_gpio_t cardIfPwrEn, cyhal_gpio_t cardMechWriteProt, cyhal_gpio_t ledCtrl, cyhal_gpio_t cardEmmcReset)
 Initialize the SDHC peripheral. More...
 
void cyhal_sdhc_free (cyhal_sdhc_t *obj)
 Release the SDHC peripheral, not currently invoked. More...
 
cy_rslt_t cyhal_sdhc_read (const cyhal_sdhc_t *obj, uint32_t address, uint8_t *data, size_t *length)
 Attempts to read data synchronously over the SDHC peripheral. More...
 
cy_rslt_t cyhal_sdhc_write (const cyhal_sdhc_t *obj, uint32_t address, const uint8_t *data, size_t *length)
 Attempts to write data synchronously over SDHC peripheral. More...
 
cy_rslt_t cyhal_sdhc_erase (const cyhal_sdhc_t *obj, uint32_t start_addr, size_t length)
 Erases a block of data over the SDHC peripheral. More...
 
cy_rslt_t cyhal_sdhc_read_async (const cyhal_sdhc_t *obj, uint32_t address, uint8_t *data, size_t *length)
 Start SDHC asynchronous read. More...
 
cy_rslt_t cyhal_sdhc_write_async (const cyhal_sdhc_t *obj, uint32_t address, const uint8_t *data, size_t *length)
 Start asynchronous SDHC write. More...
 
bool cyhal_sdhc_is_busy (const cyhal_sdhc_t *obj)
 Checks if the specified SDHC peripheral is in use. More...
 
cy_rslt_t cyhal_sdhc_abort_async (const cyhal_sdhc_t *obj)
 Abort an SDHC transfer. More...
 
void cyhal_sdhc_register_callback (cyhal_sdhc_t *obj, cyhal_sdhc_event_callback_t callback, void *callback_arg)
 Register an SDHC callback handler. More...
 
void cyhal_sdhc_enable_event (cyhal_sdhc_t *obj, cyhal_sdhc_event_t event, uint8_t intr_priority, bool enable)
 Configure SDHC event enablement. More...
 

Data Structure Documentation

◆ cyhal_sdhc_config_t

struct cyhal_sdhc_config_t
Data Fields
bool enableLedControl Drive one IO to indicate when the card is being accessed.
bool lowVoltageSignaling Whether 1.8V signaling is supported.
bool isEmmc true if eMMC card, otherwise false
uint8_t busWidth The desired bus width.

Enumeration Type Documentation

◆ cyhal_sdhc_card_type_t

Card types.

Enumerator
CYHAL_SDHC_SD 

Secure Digital card.

CYHAL_SDHC_SDIO 

SD Input Output card.

CYHAL_SDHC_EMMC 

Embedded Multimedia card.

CYHAL_SDHC_COMBO 

Combo Card (SD + SDIO)

CYHAL_SDHC_UNUSABLE 

Unusable card or unsupported type.

CYHAL_SDHC_NOT_EMMC 

Not an eMMC card.

◆ cyhal_sdhc_event_t

SDHC interrupt triggers.

Enumerator
CYHAL_SDHC_XFER_COMPLETE 

Command Complete

CYHAL_SDHC_BGAP_EVENT 

Host read/write transfer is complete

CYHAL_SDHC_DMA_INTERRUPT 

This bit is set when both read/write transaction is stopped at the block gap

CYHAL_SDHC_BUF_WR_READY 

Host controller detects an SDMA Buffer Boundary during transfer

CYHAL_SDHC_BUF_RD_READY 

This bit is set if the Buffer Write Enable changes from 0 to 1

CYHAL_SDHC_CARD_INSERTION 

This bit is set if the Buffer Read Enable changes from 0 to 1

CYHAL_SDHC_CARD_REMOVAL 

This bit is set if the Card Inserted in the Present State register changes from 0 to 1.

CYHAL_SDHC_CARD_INTERRUPT 

This bit is set if the Card Inserted in the Present State register changes from 1 to 0.

CYHAL_SDHC_INT_A 

The synchronized value of the DAT[1] interrupt input for SD mode

CYHAL_SDHC_FX_EVENT 

This bit is set if the Re-Tuning Request changes from 0 to 1

CYHAL_SDHC_CQE_EVENT 

This status is set when R[14] of response register is set to 1

CYHAL_SDHC_ASYNC_READ_COMPLETE 

This status is set if Command Queuing/Crypto event has occurred

CYHAL_SDHC_ASYNC_WRITE_COMPLETE 

Asynchronous read operation is complete

CYHAL_SDHC_ERR_INTERRUPT 

Asynchronous write operation is complete

CYHAL_SDHC_ALL_INTERRUPTS 

If any of the bits in the Error Interrupt Status register are set

Function Documentation

◆ cyhal_sdhc_init()

cy_rslt_t cyhal_sdhc_init ( cyhal_sdhc_t obj,
const cyhal_sdhc_config_t config,
cyhal_gpio_t  cmd,
cyhal_gpio_t  clk,
cyhal_gpio_t  data0,
cyhal_gpio_t  data1,
cyhal_gpio_t  data2,
cyhal_gpio_t  data3,
cyhal_gpio_t  data4,
cyhal_gpio_t  data5,
cyhal_gpio_t  data6,
cyhal_gpio_t  data7,
cyhal_gpio_t  cardDetect,
cyhal_gpio_t  ioVoltSel,
cyhal_gpio_t  cardIfPwrEn,
cyhal_gpio_t  cardMechWriteProt,
cyhal_gpio_t  ledCtrl,
cyhal_gpio_t  cardEmmcReset 
)

Initialize the SDHC peripheral.

Parameters
[out]objPointer to an SDHC object. The caller must allocate the memory for this object but the init function will initialize its contents.
[in]configThe card configuration object
[out]clkThe pin connected to the clk signal
[in]cmdThe pin connected to the command signal
[in]data0The pin connected to the data0 signal
[in]data1The pin connected to the data1 signal
[in]data2The pin connected to the data2 signal
[in]data3The pin connected to the data3 signal
[in]data4The pin connected to the data4 signal
[in]data5The pin connected to the data5 signal
[in]data6The pin connected to the data6 signal
[in]data7The pin connected to the data7 signal
[in]cardDetectThe pin connected to the cardDetect signal
[out]ioVoltSelThe pin connected to the ioVoltSel signal
[out]cardIfPwrEnThe pin connected to the cardIfPwrEn signal
[in]cardMechWriteProtThe pin connected to the cardMechWriteProt signal
[in]ledCtrlThe pin connected to the ledCtrl signal
[in]cardEmmcResetThe pin connected to the cardEmmcReset signal
Returns
The status of the init request

◆ cyhal_sdhc_free()

void cyhal_sdhc_free ( cyhal_sdhc_t obj)

Release the SDHC peripheral, not currently invoked.

It requires further resource management.

Parameters
[in,out]objThe SDHC object

◆ cyhal_sdhc_read()

cy_rslt_t cyhal_sdhc_read ( const cyhal_sdhc_t obj,
uint32_t  address,
uint8_t *  data,
size_t *  length 
)

Attempts to read data synchronously over the SDHC peripheral.

This will read as many blocks as possible, up to length blocks, into the buffer pointed to by data, then return. The value pointed to by length will be updated to reflect the number of words that were actually read.

See Snippet 3: Reading a block of data from an SD Card

Parameters
[in]objThe SDHC object
[in]addressThe address to read data from
[out]dataPointer to the byte-array where data read from the device should be stored
[in,out]lengthNumber of 512 byte blocks to read, updated with the number actually read
Returns
The status of the read request

◆ cyhal_sdhc_write()

cy_rslt_t cyhal_sdhc_write ( const cyhal_sdhc_t obj,
uint32_t  address,
const uint8_t *  data,
size_t *  length 
)

Attempts to write data synchronously over SDHC peripheral.

This will write as many blocks as possible, up to length blocks, then return. The value pointed to by length will be updated to reflect the number of words that were actually read.

See Snippet 4: Writing a block of data to an SD Card

Parameters
[in]objThe SDHC object
[in]addressThe address to write data to
[in]dataPointer to the byte-array of data to write to the device
[in,out]lengthNumber of 512 byte blocks to write, updated with the number actually written
Returns
The status of the write request

◆ cyhal_sdhc_erase()

cy_rslt_t cyhal_sdhc_erase ( const cyhal_sdhc_t obj,
uint32_t  start_addr,
size_t  length 
)

Erases a block of data over the SDHC peripheral.

Parameters
[in]objThe SDHC object
[in]start_addrIs the address of the first byte to erase
[in]lengthNumber of 512 byte blocks (starting at start_addr) to erase
Returns
The status of the erase request

◆ cyhal_sdhc_read_async()

cy_rslt_t cyhal_sdhc_read_async ( const cyhal_sdhc_t obj,
uint32_t  address,
uint8_t *  data,
size_t *  length 
)

Start SDHC asynchronous read.

This will transfer length 512 byte blocks into the buffer pointed to by data in the background. When the requested quantity of data has been read, the CYHAL_SDHC_ASYNC_READ_COMPLETE event will be raised. See cyhal_sdhc_register_callback and cyhal_sdhc_enable_event.

Parameters
[in]objThe SDHC object that holds the transfer information
[in]addressThe address to read data from
[out]dataThe receive buffer
[in,out]lengthNumber of 512 byte blocks to read, updated with the number actually read
Returns
The status of the read_async request

◆ cyhal_sdhc_write_async()

cy_rslt_t cyhal_sdhc_write_async ( const cyhal_sdhc_t obj,
uint32_t  address,
const uint8_t *  data,
size_t *  length 
)

Start asynchronous SDHC write.

This will transfer length 512 byte blocks from the buffer pointed to by data in the background. When the requested quantity of data has been written, the CYHAL_SDHC_ASYNC_WRITE_COMPLETE event will be raised. See cyhal_sdhc_register_callback and cyhal_sdhc_enable_event.

Parameters
[in]objThe SDHC object that holds the transfer information
[in]addressThe address to write data to
[in]dataThe transmit buffer
[in,out]lengthThe number of 512 byte blocks to write, updated with the number actually written
Returns
The status of the write_async request

◆ cyhal_sdhc_is_busy()

bool cyhal_sdhc_is_busy ( const cyhal_sdhc_t obj)

Checks if the specified SDHC peripheral is in use.

Parameters
[in]objThe SDHC peripheral to check
Returns
Indication of whether the SDHC is still transmitting

◆ cyhal_sdhc_abort_async()

cy_rslt_t cyhal_sdhc_abort_async ( const cyhal_sdhc_t obj)

Abort an SDHC transfer.

Parameters
[in]objThe SDHC peripheral to stop
Returns
The status of the abort_async request

◆ cyhal_sdhc_register_callback()

void cyhal_sdhc_register_callback ( cyhal_sdhc_t obj,
cyhal_sdhc_event_callback_t  callback,
void *  callback_arg 
)

Register an SDHC callback handler.

This function will be called when one of the events enabled by cyhal_sdhc_enable_event occurs.

Parameters
[in]objThe SDHC object
[in]callbackThe callback handler which will be invoked when the event fires
[in]callback_argGeneric argument that will be provided to the callback when called

◆ cyhal_sdhc_enable_event()

void cyhal_sdhc_enable_event ( cyhal_sdhc_t obj,
cyhal_sdhc_event_t  event,
uint8_t  intr_priority,
bool  enable 
)

Configure SDHC event enablement.

When an enabled event occurs, the function specified by cyhal_sdhc_register_callback will be called.

Parameters
[in]objThe SDHC object
[in]eventThe SDHC event type
[in]intr_priorityThe priority for NVIC interrupt events
[in]enableTrue to turn on interrupts, False to turn off