SDIO (Secure Digital Input Output)¶
-
group
group_hal_sdio
High level interface to the Secure Digital Input Output (SDIO).
This driver allows commands to be sent over the SDIO bus; the supported commands can be found in cyhal_sdio_command_t. Bulk data transfer is also supported via cyhal_sdio_bulk_transfer().
The SDIO protocol is an extension of the SD interface for general I/O functions. Refer to the SD Specifications Part 1 SDIO Specifications Version 4.10 for more information on the SDIO protocol and specifications.
Features
Supports 4-bit interface
Supports Ultra High Speed (UHS-I) mode
Supports Default Speed (DS), High Speed (HS), SDR12, SDR25 and SDR50 speed modes
Supports SDIO card interrupts in both 1-bit and 4-bit modes
Supports Standard capacity (SDSC), High capacity (SDHC) and Extended capacity (SDXC) memory
Quick Start
cyhal_sdio_init initializes the SDIO peripheral and passes a pointer to the SDIO block through the obj object of type cyhal_sdio_t.
Code Snippets
Snippet1: Simple SDIO Initialization example
The following snippet shows how to initialize the SDIO interface with a pre-defined configuration
cy_rslt_t rslt; cyhal_sdio_t sdio_object; #define BLOCK_SIZE (512) #define SDIO_FREQ_HF (100000000UL) cyhal_sdio_cfg_t my_sdio_cfg = { .block_size = BLOCK_SIZE, .frequencyhal_hz = SDIO_FREQ_HF }; rslt = cyhal_sdio_init(&sdio_object, SDIO_CMD_PIN, SDIO_CLK_PIN, SDIO_DATA0_PIN, SDIO_DATA1_PIN, SDIO_DATA2_PIN, SDIO_DATA3_PIN); rslt = cyhal_sdio_configure(&sdio_object, &my_sdio_cfg);
Snippet2: Configure Interrupt
The following snippet shows how to configure an interrupt and handle specific events. Refer cyhal_sdio_event_t for different types of events.
// Event handler callback function void sdio_event_handler(void* handler_arg, cyhal_sdio_event_t event) { CY_UNUSED_PARAMETER(handler_arg); CY_UNUSED_PARAMETER(event); switch (event) { case CYHAL_SDIO_CARD_INSERTION: { // Triggered when card insertion is detected in present state // Insert application code to handle events break; } case CYHAL_SDIO_CMD_COMPLETE: { // Triggered when command transfer is complete // Insert application code to handle events break; } case CYHAL_SDIO_XFER_COMPLETE: { // Triggered when host read/write transfer is complete // Insert application code to handle events break; } default: { // Anything for other commands break; } } } void snippet_cyhal_sdio_interrupt_init() { #define INTERRUPT_PRIORITY (3u) // Register the event callback cyhal_sdio_register_callback(&sdio_obj, &sdio_event_handler, NULL); // Enable events that should trigger the callback cyhal_sdio_enable_event(&sdio_obj, CYHAL_SDIO_ALL_INTERRUPTS, INTERRUPT_PRIORITY, true); }
Snippet3: Sending Commands
The following snippet shows how to send a particular command. Some steps of the card initialization have been provided for reference. Refer cyhal_sdio_command_t for different commands.
cy_rslt_t rslt; uint32_t response; bool f8Flag = false; // The CMD8 valid flag. #define MY_SDIO_CMD_NO_ARG (0u) #define MY_SDIO_CMD8 ((cyhal_sdio_command_t)8u) #define MY_SDIO_CMD8_VHS_27_36 (0x100UL) // CMD8 voltage supplied 2.7-3.6 V. #define MY_SDIO_CMD8_PATTERN_MASK (0xFFUL) #define MY_SDIO_CMD8_CHECK_PATTERN (0xAAUL) // Start the card initialization process // Reset Card (CMD0). rslt = cyhal_sdio_send_cmd(&sdio_obj, CYHAL_WRITE, CYHAL_SDIO_CMD_GO_IDLE_STATE, MY_SDIO_CMD_NO_ARG, &response); // Voltage check (CMD8). rslt = cyhal_sdio_send_cmd(&sdio_obj, CYHAL_WRITE, MY_SDIO_CMD8, MY_SDIO_CMD8_VHS_27_36 | MY_SDIO_CMD8_CHECK_PATTERN, &response); // Check the pattern. if (MY_SDIO_CMD8_CHECK_PATTERN == (response & MY_SDIO_CMD8_PATTERN_MASK)) { // The pattern is valid. f8Flag = true; } else { // SDIO Card is unusable } if (f8Flag) { // Add further initialization commands based on SDIO card }
Snippet4: Bulk Data Transfer
The following snippet shows how to start a bulk data transfer.
#define DATA_LENGTH (5u) #define MY_SDIO_CMD_NO_ARG (0u) cy_rslt_t rslt; uint32_t data[DATA_LENGTH] = { '1', '2', '3', '4', '5' }; uint32_t response; // Begin bulk data transfer rslt = cyhal_sdio_bulk_transfer(&sdio_obj, CYHAL_WRITE, MY_SDIO_CMD_NO_ARG, data, DATA_LENGTH, &response);
Snippet5: Async Data Transfer
The following snippet shows how to start an async data transfer.
void sdio_async_interrupt_handler(void* handler_arg, cyhal_sdio_event_t event) { if ((handler_arg != NULL) && (event == CYHAL_SDIO_XFER_COMPLETE)) { // Triggered when host read/write async transfer is complete // Insert application code to handle events } } void snippet_cyhal_sdio_async_transfer() { #define DATA_LENGTH (5u) #define MY_SDIO_CMD_NO_ARG (0u) #define INTERRUPT_PRIORITY (3u) uint32_t data[DATA_LENGTH] = { '1', '2', '3', '4', '5' }; uint32_t handler_args = 0; // Register the event callback cyhal_sdio_register_callback(&sdio_obj, &sdio_async_interrupt_handler, (void*)&handler_args); // Enable events CYHAL_SDIO_CMD_COMPLETE and CYHAL_SDIO_XFER_COMPLETE events. // Event CYHAL_SDIO_XFER_COMPLETE is triggered once // async transfer is complete. Handle event in the event handler. cyhal_sdio_enable_event(&sdio_obj, (cyhal_sdio_event_t)(CYHAL_SDIO_CMD_COMPLETE | CYHAL_SDIO_XFER_COMPLETE), INTERRUPT_PRIORITY, true); // Begin async data transfer cyhal_sdio_transfer_async(&sdio_obj, CYHAL_WRITE, MY_SDIO_CMD_NO_ARG, data, DATA_LENGTH); // Wait for transfer to finish while (cyhal_sdio_is_busy(&sdio_obj)) { // Halt here until condition is false } }
Typedefs
-
typedef void (*
cyhal_sdio_event_callback_t
)(void *callback_arg, cyhal_sdio_event_t event)¶ Callback for SDIO events.
Enums
-
enum
cyhal_sdio_command_t
¶ cyhal_sdio_command_t: Commands that can be issued.
Values:
-
enumerator
CYHAL_SDIO_CMD_GO_IDLE_STATE
¶ Go to idle state.
-
enumerator
CYHAL_SDIO_CMD_SEND_RELATIVE_ADDR
¶ Send a relative address.
-
enumerator
CYHAL_SDIO_CMD_IO_SEND_OP_COND
¶ Send an OP IO.
-
enumerator
CYHAL_SDIO_CMD_SELECT_CARD
¶ Send a card select.
-
enumerator
CYHAL_SDIO_CMD_GO_INACTIVE_STATE
¶ Go to inactive state.
-
enumerator
CYHAL_SDIO_CMD_IO_RW_DIRECT
¶ Perform a direct read/write.
-
enumerator
CYHAL_SDIO_CMD_IO_RW_EXTENDED
¶ Perform an extended read/write.
-
enumerator
-
enum
cyhal_transfer_t
¶ cyhal_transfer_t: Types of transfer that can be performed.
Values:
-
enumerator
CYHAL_READ
¶ Read from the card.
-
enumerator
CYHAL_WRITE
¶ Write to the card.
-
enumerator
-
enum
cyhal_sdio_event_t
¶ cyhal_sdio_event_t: Types of events that could be asserted by SDIO.
Values:
-
enumerator
CYHAL_SDIO_CMD_COMPLETE
¶ Command Complete.
-
enumerator
CYHAL_SDIO_XFER_COMPLETE
¶ Host read/write transfer is complete.
-
enumerator
CYHAL_SDIO_BGAP_EVENT
¶ This bit is set when both read/write transaction is stopped.
-
enumerator
CYHAL_SDIO_DMA_INTERRUPT
¶ Host controller detects an SDMA Buffer Boundary during transfer.
-
enumerator
CYHAL_SDIO_BUF_WR_READY
¶ This bit is set if the Buffer Write Enable changes from 0 to 1.
-
enumerator
CYHAL_SDIO_BUF_RD_READY
¶ This bit is set if the Buffer Read Enable changes from 0 to 1.
-
enumerator
CYHAL_SDIO_CARD_INSERTION
¶ This bit is set if the Card Inserted in the Present State.
-
enumerator
CYHAL_SDIO_CARD_REMOVAL
¶ This bit is set if the Card Inserted in the Present State.
-
enumerator
CYHAL_SDIO_CARD_INTERRUPT
¶ The synchronized value of the DAT[1] interrupt input for SD mode.
-
enumerator
CYHAL_SDIO_INT_A
¶ Reserved: set to 0.
-
enumerator
CYHAL_SDIO_INT_B
¶ Reserved: set to 0.
-
enumerator
CYHAL_SDIO_INT_C
¶ Reserved: set to 0.
-
enumerator
CYHAL_SDIO_RE_TUNE_EVENT
¶ Reserved: set to 0.
-
enumerator
CYHAL_SDIO_FX_EVENT
¶ This status is set when R[14] of response register is set to 1.
-
enumerator
CYHAL_SDIO_CQE_EVENT
¶ This status is set if Command Queuing/Crypto event has occurred.
-
enumerator
CYHAL_SDIO_ERR_INTERRUPT
¶ If any of the bits in the Error Interrupt Status register are set.
-
enumerator
CYHAL_SDIO_GOING_DOWN
¶ The interface is going away (eg: powering down for some period of time)
-
enumerator
CYHAL_SDIO_COMING_UP
¶ The interface is back up (eg: came back from a low power state)
-
enumerator
CYHAL_SDIO_ALL_INTERRUPTS
¶ Is used to enable/disable all interrupts events.
-
enumerator
Functions
-
cy_rslt_t
cyhal_sdio_init
(cyhal_sdio_t *obj, cyhal_gpio_t cmd, cyhal_gpio_t clk, cyhal_gpio_t data0, cyhal_gpio_t data1, cyhal_gpio_t data2, cyhal_gpio_t data3)¶ Initialize the SDIO peripheral.
Returns
CY_RSLT_SUCCESS on successful operation. Refer Snippet1: Simple SDIO Initialization example for more information.- Return
The status of the init request
- Parameters
[out] obj
: Pointer to an SDIO object. The caller must allocate the memory for this object but the init function will initialize its contents.[out] clk
: The pin connected to the clk signal[in] cmd
: The pin connected to the command signal[in] data0
: The pin connected to the data0 signal[in] data1
: The pin connected to the data1 signal[in] data2
: The pin connected to the data2 signal[in] data3
: The pin connected to the data3 signal
-
void
cyhal_sdio_free
(cyhal_sdio_t *obj)¶ Release the SDIO block.
- Parameters
[inout] obj
: The SDIO object
-
cy_rslt_t
cyhal_sdio_configure
(cyhal_sdio_t *obj, const cyhal_sdio_cfg_t *config)¶ Configure the SDIO block with required parameters.
Refer cyhal_sdio_cfg_t for more information.
Returns
CY_RSLT_SUCCESS on successful operation.- Return
The status of the configure request.
- Parameters
[inout] obj
: The SDIO object[in] config
: The SDIO configuration to apply
-
cy_rslt_t
cyhal_sdio_send_cmd
(const cyhal_sdio_t *obj, cyhal_transfer_t direction, cyhal_sdio_command_t command, uint32_t argument, uint32_t *response)¶ Sends command to the SDIO device.
See cyhal_sdio_command_t for list of available commands.
This will block until the command is completed.
Returns
CY_RSLT_SUCCESS on successful operation. Refer Snippet3: Sending Commands for more information.- Return
The status of the command transfer.
- Parameters
[inout] obj
: The SDIO object[in] direction
: The direction of transfer (read/write)[in] command
: The command to send to the SDIO device[in] argument
: The argument to the command[out] response
: The response from the SDIO device
-
cy_rslt_t
cyhal_sdio_bulk_transfer
(cyhal_sdio_t *obj, cyhal_transfer_t direction, uint32_t argument, const uint32_t *data, uint16_t length, uint32_t *response)¶ Performs a bulk data transfer.
Sends CYHAL_SDIO_CMD_IO_RW_EXTENDED command (CMD=53) which allows writing and reading of a large number of I/O registers with a single command.
This will block until the transfer is completed.
Returns
CY_RSLT_SUCCESS on successful operation. Refer Snippet4: Bulk Data Transfer for more information.- Return
The status of the bulk transfer operation.
- Parameters
[inout] obj
: The SDIO object[in] direction
: The direction of transfer (read/write)[in] argument
: The argument to the command[in] data
: The data to send to the SDIO device. A bulk transfer is done in block size (default: 64 bytes) chunks for better performance. Therefore, the size of the data buffer passed into this function must be at least length bytes and a multiple of the block size. For example, when requesting to read 100 bytes of data with a block size 64 bytes, the data buffer needs to be at least 128 bytes. The first 100 bytes of data in the buffer will be the requested data.[in] length
: The number of bytes to send[out] response
: The response from the SDIO device
-
cy_rslt_t
cyhal_sdio_transfer_async
(cyhal_sdio_t *obj, cyhal_transfer_t direction, uint32_t argument, const uint32_t *data, uint16_t length)¶ Performs a bulk asynchronous data transfer by issuing the CYHAL_SDIO_CMD_IO_RW_EXTENDED command(CMD=53) to the SDIO block.
After exiting this function the CYHAL_SDIO_CMD_COMPLETE and CYHAL_SDIO_XFER_COMPLETE events are not asserted.
The CYHAL_SDIO_CMD_COMPLETE and CYHAL_SDIO_XFER_COMPLETE events are enabled after the asynchronous transfer is complete and in the condition they were enabled in before the transfer operation started. Handle these events in the interrupt callback.
When the transfer is complete, the CYHAL_SDIO_XFER_COMPLETE event will be raised. See cyhal_sdio_register_callback and cyhal_sdio_enable_event.
Returns
CY_RSLT_SUCCESS on successful operation. Refer Snippet5: Async Data Transfer for more information.- Return
The status of the async tranfer operation.
- Parameters
[inout] obj
: The SDIO object[in] direction
: The direction of transfer (read/write)[in] argument
: The argument to the command[in] data
: The data to send to the SDIO device[in] length
: The number of bytes to send
-
bool
cyhal_sdio_is_busy
(const cyhal_sdio_t *obj)¶ Checks if the specified SDIO is in use.
- Return
true if SDIO is in use. false, otherwise.
- Parameters
[in] obj
: The SDIO peripheral to check
-
cy_rslt_t
cyhal_sdio_abort_async
(const cyhal_sdio_t *obj)¶ Abort an SDIO transfer.
Returns
CY_RSLT_SUCCESS on successful operation.- Return
The status of the abort_async request.
- Parameters
[in] obj
: The SDIO peripheral to stop
-
void
cyhal_sdio_register_callback
(cyhal_sdio_t *obj, cyhal_sdio_event_callback_t callback, void *callback_arg)¶ Register an SDIO event callback to be invoked when the event is triggered.
This function will be called when one of the events enabled by cyhal_sdio_enable_event occurs.
Refer
Snippet2: Configure Interrupt for more implementation.- Parameters
[in] obj
: The SDIO object[in] callback
: The callback function which will be invoked when the event triggers[in] callback_arg
: Generic argument that will be provided to the callback when executed
-
void
cyhal_sdio_enable_event
(cyhal_sdio_t *obj, cyhal_sdio_event_t event, uint8_t intr_priority, bool enable)¶ Enables callbacks to be triggered for specified SDIO events.
Refer cyhal_sdio_event_t for all events.
Refer
Snippet2: Configure Interrupt for more information.- Parameters
[in] obj
: The SDIO object[in] event
: The SDIO event type[in] intr_priority
: The priority for NVIC interrupt events[in] enable
: Set to true to enable events, or false to disable them
-
struct
cyhal_sdio_cfg_t
¶ - #include <cyhal_sdio.h>
SDIO controller initial configuration.