1 /* 2 * SPDX-FileCopyrightText: 2015-2021 Espressif Systems (Shanghai) CO LTD 3 * 4 * SPDX-License-Identifier: Apache-2.0 5 */ 6 7 #pragma once 8 9 #include <stdint.h> 10 #include <stddef.h> 11 #include "esp_err.h" 12 #include "sdmmc_types.h" 13 #include "driver/gpio.h" 14 #include "driver/spi_master.h" 15 16 #ifdef __cplusplus 17 extern "C" { 18 #endif 19 20 /// Handle representing an SD SPI device 21 typedef int sdspi_dev_handle_t; 22 23 #if CONFIG_IDF_TARGET_ESP32 || CONFIG_IDF_TARGET_ESP32S2 24 #define SDSPI_DEFAULT_HOST HSPI_HOST 25 #else 26 #define SDSPI_DEFAULT_HOST SPI2_HOST 27 #endif 28 29 /** 30 * @brief Default sdmmc_host_t structure initializer for SD over SPI driver 31 * 32 * Uses SPI mode and max frequency set to 20MHz 33 * 34 * 'slot' should be set to an sdspi device initialized by `sdspi_host_init_device()`. 35 */ 36 #define SDSPI_HOST_DEFAULT() {\ 37 .flags = SDMMC_HOST_FLAG_SPI | SDMMC_HOST_FLAG_DEINIT_ARG, \ 38 .slot = SDSPI_DEFAULT_HOST, \ 39 .max_freq_khz = SDMMC_FREQ_DEFAULT, \ 40 .io_voltage = 3.3f, \ 41 .init = &sdspi_host_init, \ 42 .set_bus_width = NULL, \ 43 .get_bus_width = NULL, \ 44 .set_bus_ddr_mode = NULL, \ 45 .set_card_clk = &sdspi_host_set_card_clk, \ 46 .do_transaction = &sdspi_host_do_transaction, \ 47 .deinit_p = &sdspi_host_remove_device, \ 48 .io_int_enable = &sdspi_host_io_int_enable, \ 49 .io_int_wait = &sdspi_host_io_int_wait, \ 50 .command_timeout_ms = 0, \ 51 } 52 53 /** 54 * Extra configuration for SD SPI device. 55 */ 56 typedef struct { 57 spi_host_device_t host_id; ///< SPI host to use, SPIx_HOST (see spi_types.h). 58 gpio_num_t gpio_cs; ///< GPIO number of CS signal 59 gpio_num_t gpio_cd; ///< GPIO number of card detect signal 60 gpio_num_t gpio_wp; ///< GPIO number of write protect signal 61 gpio_num_t gpio_int; ///< GPIO number of interrupt line (input) for SDIO card. 62 } sdspi_device_config_t; 63 64 #define SDSPI_SLOT_NO_CD GPIO_NUM_NC ///< indicates that card detect line is not used 65 #define SDSPI_SLOT_NO_WP GPIO_NUM_NC ///< indicates that write protect line is not used 66 #define SDSPI_SLOT_NO_INT GPIO_NUM_NC ///< indicates that interrupt line is not used 67 68 /** 69 * Macro defining default configuration of SD SPI device. 70 */ 71 #define SDSPI_DEVICE_CONFIG_DEFAULT() {\ 72 .host_id = SDSPI_DEFAULT_HOST, \ 73 .gpio_cs = GPIO_NUM_13, \ 74 .gpio_cd = SDSPI_SLOT_NO_CD, \ 75 .gpio_wp = SDSPI_SLOT_NO_WP, \ 76 .gpio_int = GPIO_NUM_NC, \ 77 } 78 79 /** 80 * @brief Initialize SD SPI driver 81 * 82 * @note This function is not thread safe 83 * 84 * @return 85 * - ESP_OK on success 86 * - other error codes may be returned in future versions 87 */ 88 esp_err_t sdspi_host_init(void); 89 90 /** 91 * @brief Attach and initialize an SD SPI device on the specific SPI bus 92 * 93 * @note This function is not thread safe 94 * 95 * @note Initialize the SPI bus by `spi_bus_initialize()` before calling this function. 96 * 97 * @note The SDIO over sdspi needs an extra interrupt line. Call ``gpio_install_isr_service()`` before this function. 98 * 99 * @param dev_config pointer to device configuration structure 100 * @param out_handle Output of the handle to the sdspi device. 101 102 * @return 103 * - ESP_OK on success 104 * - ESP_ERR_INVALID_ARG if sdspi_host_init_device has invalid arguments 105 * - ESP_ERR_NO_MEM if memory can not be allocated 106 * - other errors from the underlying spi_master and gpio drivers 107 */ 108 esp_err_t sdspi_host_init_device(const sdspi_device_config_t* dev_config, sdspi_dev_handle_t* out_handle); 109 110 /** 111 * @brief Remove an SD SPI device 112 * 113 * @param handle Handle of the SD SPI device 114 * @return Always ESP_OK 115 */ 116 esp_err_t sdspi_host_remove_device(sdspi_dev_handle_t handle); 117 118 /** 119 * @brief Send command to the card and get response 120 * 121 * This function returns when command is sent and response is received, 122 * or data is transferred, or timeout occurs. 123 * 124 * @note This function is not thread safe w.r.t. init/deinit functions, 125 * and bus width/clock speed configuration functions. Multiple tasks 126 * can call sdspi_host_do_transaction as long as other sdspi_host_* 127 * functions are not called. 128 * 129 * @param handle Handle of the sdspi device 130 * @param cmdinfo pointer to structure describing command and data to transfer 131 * @return 132 * - ESP_OK on success 133 * - ESP_ERR_TIMEOUT if response or data transfer has timed out 134 * - ESP_ERR_INVALID_CRC if response or data transfer CRC check has failed 135 * - ESP_ERR_INVALID_RESPONSE if the card has sent an invalid response 136 */ 137 esp_err_t sdspi_host_do_transaction(sdspi_dev_handle_t handle, sdmmc_command_t *cmdinfo); 138 139 /** 140 * @brief Set card clock frequency 141 * 142 * Currently only integer fractions of 40MHz clock can be used. 143 * For High Speed cards, 40MHz can be used. 144 * For Default Speed cards, 20MHz can be used. 145 * 146 * @note This function is not thread safe 147 * 148 * @param host Handle of the sdspi device 149 * @param freq_khz card clock frequency, in kHz 150 * @return 151 * - ESP_OK on success 152 * - other error codes may be returned in the future 153 */ 154 esp_err_t sdspi_host_set_card_clk(sdspi_dev_handle_t host, uint32_t freq_khz); 155 156 /** 157 * @brief Release resources allocated using sdspi_host_init 158 * 159 * @note This function is not thread safe 160 * 161 * @return 162 * - ESP_OK on success 163 * - ESP_ERR_INVALID_STATE if sdspi_host_init function has not been called 164 */ 165 esp_err_t sdspi_host_deinit(void); 166 167 /** 168 * @brief Enable SDIO interrupt. 169 * 170 * @param handle Handle of the sdspi device 171 * 172 * @return 173 * - ESP_OK on success 174 */ 175 esp_err_t sdspi_host_io_int_enable(sdspi_dev_handle_t handle); 176 177 /** 178 * @brief Wait for SDIO interrupt until timeout. 179 * 180 * @param handle Handle of the sdspi device 181 * @param timeout_ticks Ticks to wait before timeout. 182 * 183 * @return 184 * - ESP_OK on success 185 */ 186 esp_err_t sdspi_host_io_int_wait(sdspi_dev_handle_t handle, TickType_t timeout_ticks); 187 188 /******************************************************************************* 189 * Deprecated APIs 190 ******************************************************************************/ 191 192 /** 193 * Extra configuration for SPI host. 194 * 195 * @deprecated Use `sdspi_device_config_t` and corresponding `sdspi_host_init_device()` instead. 196 */ 197 typedef struct { 198 gpio_num_t gpio_cs; ///< GPIO number of CS signal 199 gpio_num_t gpio_cd; ///< GPIO number of card detect signal 200 gpio_num_t gpio_wp; ///< GPIO number of write protect signal 201 gpio_num_t gpio_int; ///< GPIO number of interrupt line (input) for SDIO card. 202 gpio_num_t gpio_miso; ///< GPIO number of MISO signal. 203 gpio_num_t gpio_mosi; ///< GPIO number of MOSI signal. 204 gpio_num_t gpio_sck; ///< GPIO number of SCK signal. 205 int dma_channel; ///< DMA channel to be used by SPI driver (1 or 2). 206 } sdspi_slot_config_t; 207 208 /** 209 * Macro defining default configuration of SPI host 210 */ 211 #define SDSPI_SLOT_CONFIG_DEFAULT() {\ 212 .gpio_cs = GPIO_NUM_13, \ 213 .gpio_cd = SDSPI_SLOT_NO_CD, \ 214 .gpio_wp = SDSPI_SLOT_NO_WP, \ 215 .gpio_int = GPIO_NUM_NC, \ 216 .gpio_miso = GPIO_NUM_2, \ 217 .gpio_mosi = GPIO_NUM_15, \ 218 .gpio_sck = GPIO_NUM_14, \ 219 .dma_channel = 1, \ 220 } 221 222 /** 223 * @brief Initialize SD SPI driver for the specific SPI controller 224 * 225 * @note This function is not thread safe 226 * 227 * @note The SDIO over sdspi needs an extra interrupt line. Call ``gpio_install_isr_service()`` before this function. 228 * 229 * @param slot SPI controller to use (SPI2_HOST or SPI3_HOST) 230 * @param slot_config pointer to slot configuration structure 231 232 * @deprecated Use `sdspi_host_init_device` instead. 233 * 234 * @return 235 * - ESP_OK on success 236 * - ESP_ERR_INVALID_ARG if sdspi_init_slot has invalid arguments 237 * - ESP_ERR_NO_MEM if memory can not be allocated 238 * - other errors from the underlying spi_master and gpio drivers 239 */ 240 esp_err_t sdspi_host_init_slot(int slot, const sdspi_slot_config_t* slot_config); 241 242 #ifdef __cplusplus 243 } 244 #endif 245