1 /***************************************************************************//** 2 * \file cyhal_sdhc.h 3 * 4 * \brief 5 * Provides a high level interface for interacting with the Infineon SDHC. 6 * This interface abstracts out the chip specific details. If any chip specific 7 * functionality is necessary, or performance is critical the low level functions 8 * can be used directly. 9 * 10 ******************************************************************************** 11 * \copyright 12 * Copyright 2018-2022 Cypress Semiconductor Corporation (an Infineon company) or 13 * an affiliate of Cypress Semiconductor Corporation 14 * 15 * SPDX-License-Identifier: Apache-2.0 16 * 17 * Licensed under the Apache License, Version 2.0 (the "License"); 18 * you may not use this file except in compliance with the License. 19 * You may obtain a copy of the License at 20 * 21 * http://www.apache.org/licenses/LICENSE-2.0 22 * 23 * Unless required by applicable law or agreed to in writing, software 24 * distributed under the License is distributed on an "AS IS" BASIS, 25 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 26 * See the License for the specific language governing permissions and 27 * limitations under the License. 28 *******************************************************************************/ 29 30 /** 31 * \addtogroup group_hal_sdhc SDHC (SD Host Controller) 32 * \ingroup group_hal 33 * \{ 34 * High level interface to the Secure Digital Host Controller (SDHC). 35 * 36 * The SDHC driver allows data to be read from and written to an SD Card using the SDHC block. 37 * The data is transferred in blocks with a block size of 512 bytes. 38 * 39 * \section subsection_sdhc_features Features 40 * * Supports the 4-bit interface 41 * * Supports Ultra High Speed (UHS-I) mode 42 * * Supports Default Speed (DS), High Speed (HS), SDR12, SDR25 and SDR50 speed modes 43 * 44 * \section subsection_sdhc_quickstart Quick Start 45 * Initialize SDHC by using \ref cyhal_sdhc_init by selecting the pins according to the target device used. 46 * Specify the SDHC configuration using the configuration structure (const \ref cyhal_sdhc_config_t * config). <br> 47 * See \ref subsection_sdhc_snippet_1 48 * 49 * \section subsection_sdhc_code_snippets Code Snippets 50 * 51 * \subsection subsection_sdhc_snippet_1 Snippet 1: SDHC Initialization and configuration 52 * The following snippet is used to initialize the SDHC block. SDHC object - \ref cyhal_sdhc_t, 53 * SDHC card configuration structure (const \ref cyhal_sdhc_config_t * config). The pins connected to the SDHC block 54 * needs to be provided to the \ref cyhal_sdhc_init function. 55 * \snippet hal_sdhc.c snippet_cyhal_sdhc_init 56 * 57 * \subsection subsection_sdhc_snippet_2 Snippet 2: Reading a block of data from an SD Card 58 * The following snippet reads a block of data from the SD Card. 59 * \snippet hal_sdhc.c snippet_cyhal_sdhc_read 60 61 * \subsection subsection_sdhc_snippet_3 Snippet 3: Writing a block of data to an SD Card 62 * The following snippet writes a block of data to the SD Card. 63 * \snippet hal_sdhc.c snippet_cyhal_sdhc_write 64 65 */ 66 67 #pragma once 68 69 #include <stdint.h> 70 #include <stdbool.h> 71 #include "cy_result.h" 72 #include "cyhal_hw_types.h" 73 74 #if defined(__cplusplus) 75 extern "C" { 76 #endif 77 78 /******************************************************************************* 79 * Defines 80 *******************************************************************************/ 81 82 /** \addtogroup group_hal_results_sdhc SDHC HAL Results 83 * SDHC specific return codes 84 * \ingroup group_hal_results 85 * \{ *//** 86 */ 87 88 /** Pin related Error. */ 89 #define CYHAL_SDHC_RSLT_ERR_PIN \ 90 (CY_RSLT_CREATE_EX(CY_RSLT_TYPE_ERROR, CY_RSLT_MODULE_ABSTRACTION_HAL, CYHAL_RSLT_MODULE_SDHC, 0)) 91 /** Requested feature is not supported on this hardware. */ 92 #define CYHAL_SDHC_RSLT_ERR_UNSUPPORTED \ 93 (CY_RSLT_CREATE_EX(CY_RSLT_TYPE_ERROR, CY_RSLT_MODULE_ABSTRACTION_HAL, CYHAL_RSLT_MODULE_SDHC, 1)) 94 /** Timeout during waiting for erase complete. */ 95 #define CYHAL_SDHC_RSLT_ERR_ERASE_CMPLT_TIMEOUT \ 96 (CY_RSLT_CREATE_EX(CY_RSLT_TYPE_ERROR, CY_RSLT_MODULE_ABSTRACTION_HAL, CYHAL_RSLT_MODULE_SDHC, 2)) 97 /** Block count cannot be retrieved. */ 98 #define CYHAL_SDHC_RSLT_ERR_BLOCK_COUNT_GET_FAILURE \ 99 (CY_RSLT_CREATE_EX(CY_RSLT_TYPE_ERROR, CY_RSLT_MODULE_ABSTRACTION_HAL, CYHAL_RSLT_MODULE_SDHC, 3)) 100 /** Cannot set desired SD bus frequency. */ 101 #define CYHAL_SDHC_RSLT_ERR_SET_FREQ \ 102 (CY_RSLT_CREATE_EX(CY_RSLT_TYPE_ERROR, CY_RSLT_MODULE_ABSTRACTION_HAL, CYHAL_RSLT_MODULE_SDHC, 4)) 103 /** Incorrect function parameter. */ 104 #define CYHAL_SDHC_RSLT_ERR_WRONG_PARAM \ 105 (CY_RSLT_CREATE_EX(CY_RSLT_TYPE_ERROR, CY_RSLT_MODULE_ABSTRACTION_HAL, CYHAL_RSLT_MODULE_SDHC, 5)) 106 /** Error occured during I/O voltage switch sequence. */ 107 #define CYHAL_SDHC_RSLT_ERR_IO_VOLT_SWITCH_SEQ \ 108 (CY_RSLT_CREATE_EX(CY_RSLT_TYPE_ERROR, CY_RSLT_MODULE_ABSTRACTION_HAL, CYHAL_RSLT_MODULE_SDHC, 6)) 109 /** Cannot configure data timeout. */ 110 #define CYHAL_SDHC_RSLT_ERR_TOUT_CFG \ 111 (CY_RSLT_CREATE_EX(CY_RSLT_TYPE_ERROR, CY_RSLT_MODULE_ABSTRACTION_HAL, CYHAL_RSLT_MODULE_SDHC, 7)) 112 /** Cannot make changes in user provided clock configuration or provided clock is incorrect. */ 113 #define CYHAL_SDHC_RSLT_ERR_CLOCK \ 114 (CY_RSLT_CREATE_EX(CY_RSLT_TYPE_ERROR, CY_RSLT_MODULE_ABSTRACTION_HAL, CYHAL_RSLT_MODULE_SDHC, 8)) 115 116 /** 117 * \} 118 */ 119 120 /******************************************************************************* 121 * Enumerations 122 *******************************************************************************/ 123 124 /** Card types */ 125 typedef enum 126 { 127 CYHAL_SDHC_SD, //!< Secure Digital card 128 CYHAL_SDHC_SDIO, //!< SD Input Output card 129 CYHAL_SDHC_EMMC, //!< Embedded Multimedia card 130 CYHAL_SDHC_COMBO, //!< Combo Card (SD + SDIO) 131 CYHAL_SDHC_UNUSABLE, //!< Unusable card or unsupported type 132 CYHAL_SDHC_NOT_EMMC, //!< Not an eMMC card 133 } cyhal_sdhc_card_type_t; 134 135 /** SDHC interrupt triggers */ 136 typedef enum { 137 CYHAL_SDHC_CMD_COMPLETE = 0x00001, //!< Command Complete 138 CYHAL_SDHC_XFER_COMPLETE = 0x00002, //!< Host read/write transfer is complete 139 CYHAL_SDHC_BGAP_EVENT = 0x00004, //!< This bit is set when both read/write transaction is stopped at the block gap 140 CYHAL_SDHC_DMA_INTERRUPT = 0x00008, //!< Host controller detects an SDMA Buffer Boundary during transfer 141 CYHAL_SDHC_BUF_WR_READY = 0x00010, //!< This bit is set if the Buffer Write Enable changes from 0 to 1 142 CYHAL_SDHC_BUF_RD_READY = 0x00020, //!< This bit is set if the Buffer Read Enable changes from 0 to 1 143 CYHAL_SDHC_CARD_INSERTION = 0x00040, //!< This bit is set if the Card Inserted in the Present State register changes from 0 to 1. 144 CYHAL_SDHC_CARD_REMOVAL = 0x00080, //!< This bit is set if the Card Inserted in the Present State register changes from 1 to 0. 145 CYHAL_SDHC_INT_A = 0x00200, 146 CYHAL_SDHC_INT_B = 0x00400, 147 CYHAL_SDHC_INT_C = 0x00800, 148 CYHAL_SDHC_RE_TUNE_EVENT = 0x01000, //!< This bit is set if the Re-Tuning Request changes from 0 to 1 149 CYHAL_SDHC_FX_EVENT = 0x02000, //!< This status is set when R[14] of response register is set to 1 150 CYHAL_SDHC_CQE_EVENT = 0x04000, //!< This status is set if Command Queuing/Crypto event has occurred 151 CYHAL_SDHC_ERR_INTERRUPT = 0x08000, //!< If any of the bits in the Error Interrupt Status register are set 152 CYHAL_SDHC_ALL_INTERRUPTS = 0x0FEFF, //!< Is used to enable/disable all interrupts 153 } cyhal_sdhc_event_t; 154 155 /** I/O voltage levels */ 156 typedef enum 157 { 158 CYHAL_SDHC_IO_VOLTAGE_3_3V = 0U, //!< I/O voltage is 3.3V. 159 CYHAL_SDHC_IO_VOLTAGE_1_8V = 1U //!< I/O voltage is 1.8V. 160 } cyhal_sdhc_io_voltage_t; 161 162 /** SDHC I/O voltage select principle */ 163 typedef enum 164 { 165 CYHAL_SDHC_IO_VOLT_ACTION_NEGOTIATE = 0U, //!< (Recommended) HAL driver performs all steps, needed for switching I/O bus voltage to certain level: sends needed commands to prepare card, changes level of io_volt_sel pin and performs switching sequence according to SD specification. 166 CYHAL_SDHC_IO_VOLT_ACTION_SWITCH_SEQ_ONLY = 1U, //!< HAL driver performs switching sequence (if voltage is being switched to 1.8V) and changes io_volt_sel pin level accordingly. No commands are being send to the card in this mode. 167 CYHAL_SDHC_IO_VOLT_ACTION_NONE = 2U, //!< I/O voltage is changed by changing io_volt_sel pin's level. No commands are being send to the card in this mode. 168 } cyhal_sdhc_io_volt_action_type_t; 169 170 /** SDHC response types */ 171 typedef enum 172 { 173 CYHAL_SDHC_RESPONSE_NONE = 0U, //!< No Response. 174 CYHAL_SDHC_RESPONSE_LEN_136 = 1U, //!< Response Length 136. 175 CYHAL_SDHC_RESPONSE_LEN_48 = 2U, //!< Response Length 48. 176 CYHAL_SDHC_RESPONSE_LEN_48B = 3U //!< Response Length 48. Check Busy after response. 177 } cyhal_sdhc_cmd_response_type_t; 178 179 /** SDHC auto command enable selection. */ 180 typedef enum 181 { 182 CYHAL_SDHC_AUTO_CMD_NONE = 0U, //!< Auto command disable. 183 CYHAL_SDHC_AUTO_CMD_12 = 1U, //!< Auto command 12 enable. 184 CYHAL_SDHC_AUTO_CMD_23 = 2U, //!< Auto command 23 enable. 185 CYHAL_SDHC_AUTO_CMD_AUTO = 3U //!< Auto command Auto enable. 186 } cyhal_sdhc_auto_cmd_t; 187 188 /** SDHC command types */ 189 typedef enum 190 { 191 CYHAL_SDHC_CMD_NORMAL = 0U, //!< Other commands. 192 CYHAL_SDHC_CMD_SUSPEND = 1U, //!< CMD52 for writing "Bus Suspend" in CCCR. 193 CYHAL_SDHC_CMD_RESUME = 2U, //!< CMD52 for writing "Function Select" in CCCR. 194 CYHAL_SDHC_CMD_ABORT = 3U //!< CMD12, CMD52 for writing "I/O Abort" in CCCR. 195 } cyhal_sdhc_cmd_type_t; 196 197 /** SDHC command error states */ 198 typedef enum 199 { 200 /** Last operation did not cause any error status. */ 201 CYHAL_SDHC_NO_ERR = 0x0000U, 202 /** Command timeout error. In SD/eMMC Mode, this event is set only if no response is returned 203 * within 64 SD clock cycles from the end bit of the command. If the Host Controller detects a CMD line conflict, 204 * along with Command CRC Error bit, this event is set to 1, without waiting for 64 SD/eMMC card clock cycles. */ 205 CYHAL_SDHC_CMD_TOUT_ERR = 0x0001U, 206 /** Command CRC error. A Command CRC Error is generated in SD/eMMC mode when: 207 * 1. A response is returned and the Command Timeout Error is set to 0 (indicating no timeout), 208 * this bit is set to 1 when detecting a CRC error in the command response. 209 * 2. The Host Controller detects a CMD line conflict by monitoring the CMD line when a command is issued. If 210 * the Host Controller drives the CMD line to level 1, but detects level 0 on the CMD line at the next SD clock 211 * edge, then the Host Controller aborts the command (stop driving CMD line) and sets this bit to 1. The Command 212 * Timeout Error is also set to 1 to distinguish a CMD line conflict. */ 213 CYHAL_SDHC_CMD_CRC_ERR = 0x0002U, 214 /** Command End Bit error. This bit is set after detecting that the end bit of a command response is 0 in SD/eMMC mode. */ 215 CYHAL_SDHC_CMD_END_BIT_ERR = 0x0004U, 216 /** Command Index error. This bit is set if a Command Index error occurs in the command response in SD/eMMC mode. */ 217 CYHAL_SDHC_CMD_IDX_ERR = 0x0008U, 218 /** Data Timeout error. This bit is set in SD/eMMC mode when detecting one of the following timeout conditions: 219 * * Busy timeout for R1b, R5b type 220 * * Busy timeout after Write CRC status 221 * * Write CRC Status timeout 222 * * Read Data timeout. */ 223 CYHAL_SDHC_DATA_TOUT_ERR = 0x0010U, 224 /** Data CRC error. This error occurs in SD/eMMC mode after detecting a CRC error while transferring read data 225 * that uses the DAT line, detecting the Write CRC status having a value other than 010 or when writing a CRC status timeout. */ 226 CYHAL_SDHC_DATA_CRC_ERR = 0x0020U, 227 /** Data End Bit error. This error occurs in SD/eMMC mode either when detecting 0 at the end bit position of read 228 * data that uses the DAT line or at the end bit position of the CRC status. */ 229 CYHAL_SDHC_DATA_END_BIT_ERR = 0x0040U, 230 /** Current Limit error. */ 231 CYHAL_SDHC_CUR_LMT_ERR = 0x0080U, 232 /** Auto CMD error. This error status is used by Auto CMD12 and Auto CMD23 in SD/eMMC mode. This bit is set after 233 * detecting that any of the bits D00 to D05 in the Auto CMD Error Status register has changed from 0 to 1. D07 is 234 * effective in case for Auto CMD12. The Auto CMD Error Status register is valid while this bit is set to 1 and may 235 * be cleared by clearing this bit. */ 236 CYHAL_SDHC_AUTO_CMD_ERR = 0x0100U, 237 /** ADMA error. This bit is set when the Host Controller detects an error during an ADMA-based data transfer. 238 * The possible reasons for an error: 239 * * An error response is received from the System bus; 240 * * ADMA3, ADMA2 Descriptors are invalid; 241 * * CQE Task or Transfer descriptors are invalid. 242 * When an error occurs, the state of the ADMA is saved in the ADMA Error Status register. */ 243 CYHAL_SDHC_ADMA_ERR = 0x0200U, 244 /** Tuning error. */ 245 CYHAL_SDHC_TUNNING_ERR = 0x0400U, 246 /** Response error. Host Controller Version 4.00 supports the response error check function to avoid overhead of 247 * the response error check by Host Driver during DMA execution. If the Response Error Check Enable is set to 1 in 248 * the Transfer Mode register, the Host Controller checks R1 or R5 response. If an error is detected in a response, 249 * this bit is set to 1. This is applicable in SD/eMMC mode. */ 250 CYHAL_SDHC_RESP_ERR = 0x0800U, 251 /** Boot Acknowledgement error. This bit is set when there is a timeout for boot acknowledgement or after detecting 252 * the boot ACK status having a value other than 010. This is applicable only when boot acknowledgement is expected in eMMC mode. */ 253 CYHAL_SDHC_BOOT_ACK_ERR = 0x1000U 254 } cyhal_sdhc_error_type_t; 255 256 /******************************************************************************* 257 * Typedefs 258 *******************************************************************************/ 259 260 /** Handler for SDHC interrupts */ 261 typedef void (*cyhal_sdhc_event_callback_t)(void *callback_arg, cyhal_sdhc_event_t event); 262 263 /******************************************************************************* 264 * Data Structures 265 *******************************************************************************/ 266 267 /** Defines configuration options for the SDHC block */ 268 typedef struct 269 { 270 bool enableLedControl; //!< Drive one IO to indicate when the card is being accessed 271 bool lowVoltageSignaling; //!< Whether 1.8V signaling is supported 272 bool isEmmc; //!< true if eMMC card, otherwise false 273 uint8_t busWidth; //!< The desired bus width, 1-bit, 4-bit, 8-bit 274 } cyhal_sdhc_config_t; 275 276 /** Defines data configuration */ 277 typedef struct 278 { 279 uint32_t* data_ptr; //!< The pointer to data for send/receive. Data will be transfered using DMA, which will be configured automaticaly by SDHC HAL driver. 280 uint32_t block_size; //!< The size of the data block. 281 uint32_t number_of_blocks; //!< The number of blocks with size block_size to send. 282 cyhal_sdhc_auto_cmd_t auto_command; //!< Selects which auto commands are used if any. 283 bool is_read; //!< true = Read from the card, false = Write to the card. 284 } cyhal_sdhc_data_config_t; 285 286 /** Defines command configuration for \ref cyhal_sdhc_send_cmd function */ 287 typedef struct 288 { 289 uint32_t command_index; //!< The index of the command. 290 uint32_t command_argument; //!< The argument for the command. 291 bool enable_crc_check; //!< Enables the CRC check on the response. 292 cyhal_sdhc_cmd_response_type_t response_type; //!< The response type. 293 bool enable_idx_check; //!< Checks the index of the response. 294 cyhal_sdhc_cmd_type_t command_type; //!< The command type. 295 cyhal_sdhc_data_config_t *data_config; //!< Data transfer configuration, defined in \ref cyhal_sdhc_data_config_t. Should be NULL if data transfer is not expected for provided command. 296 } cyhal_sdhc_cmd_config_t; 297 298 /******************************************************************************* 299 * Functions 300 *******************************************************************************/ 301 302 /** Initialize SDHC driver and corresponding hardware. 303 * 304 * @param[out] obj Pointer to an SDHC object. The caller must allocate the memory for this object but 305 * the init function will initialize its contents. 306 * @param[in] config The card configuration object 307 * @param[out] clk The pin connected to the clk signal 308 * @param[in] cmd The pin connected to the command signal 309 * @param[in] data0 The pin connected to the data0 signal 310 * @param[in] data1 The pin connected to the data1 signal. This pin can be NC if bus width is 1-bit. 311 * @param[in] data2 The pin connected to the data2 signal. This pin can be NC if bus width is 1-bit. 312 * @param[in] data3 The pin connected to the data3 signal. This pin can be NC if bus width is 1-bit. 313 * @param[in] data4 The pin connected to the data4 signal. This pin can be NC if bus width is less than 8-bit. 314 * @param[in] data5 The pin connected to the data5 signal. This pin can be NC if bus width is less than 8-bit. 315 * @param[in] data6 The pin connected to the data6 signal. This pin can be NC if bus width is less than 8-bit. 316 * @param[in] data7 The pin connected to the data7 signal. This pin can be NC if bus width is less than 8-bit. 317 * @param[in] card_detect The pin connected to the card_detect signal 318 * Card is considered as inserted if card_detect pin in low state. 319 * This pin can be NC. 320 * @param[out] io_volt_sel The pin connected to the io_volt_sel signal. This pin changes the logic level on the 321 * sd_io_volt_sel line. It assumes that this line is used to control a regulator connected to the VDDIO of the MCU. 322 * This regulator allows for switching between the 3.3V and 1.8V signaling. High level on the pin stands for 323 * 1.8V signaling, while low - for 3.3V. 324 * This pin can be NC. 325 * @param[out] card_pwr_en The pin connected to the card_pwr_en signal This pin can be used to enable a voltage 326 * regulator used to power the card. High level on the pin - card is powered. Low - card is not powered. 327 * This pin can be NC. 328 * @param[in] card_mech_write_prot The pin connected to the card_mech_write_prot signal This pin is used for card 329 * mechanical write protect checking. 330 * If pin in high state - card is mechanically write protected, if in low state - card is not mechanically write 331 * protected. 332 * \ref cyhal_sdhc_is_card_mech_write_protected function can be used to check card write protection state. 333 * This pin can be NC. 334 * @param[in] led_ctrl The pin connected to the led_ctrl signal. This pin can be NC. 335 * @param[in] emmc_reset The pin connected to the emmc_reset signal. This pin can be NC. 336 * @param[in] block_clk The clock to use can be shared, if not provided a new clock will be allocated 337 * @return The status of the init request 338 * 339 */ 340 cy_rslt_t cyhal_sdhc_init_hw(cyhal_sdhc_t *obj, 341 const cyhal_sdhc_config_t *config, 342 cyhal_gpio_t cmd, 343 cyhal_gpio_t clk, 344 cyhal_gpio_t data0, 345 cyhal_gpio_t data1, 346 cyhal_gpio_t data2, 347 cyhal_gpio_t data3, 348 cyhal_gpio_t data4, 349 cyhal_gpio_t data5, 350 cyhal_gpio_t data6, 351 cyhal_gpio_t data7, 352 cyhal_gpio_t card_detect, 353 cyhal_gpio_t io_volt_sel, 354 cyhal_gpio_t card_pwr_en, 355 cyhal_gpio_t card_mech_write_prot, 356 cyhal_gpio_t led_ctrl, 357 cyhal_gpio_t emmc_reset, 358 cyhal_clock_t *block_clk); 359 360 /** Initialize the connected card. 361 * \note This function should be called after \ref cyhal_sdhc_init_hw 362 * 363 * @param[in,out] obj The SDHC object 364 * @return The status of the card init request 365 */ 366 cy_rslt_t cyhal_sdhc_init_card(cyhal_sdhc_t *obj); 367 368 /** Initialize the SDHC block and connected card. 369 * This function is a combination of \ref cyhal_sdhc_init_hw and \ref cyhal_sdhc_init_card calls. 370 * \note refer to \ref cyhal_sdhc_init_hw function description for detailed parameter guidance. 371 * 372 * @param[out] obj Pointer to an SDHC object. The caller must allocate the memory for this object but 373 * the init function will initialize its contents. 374 * @param[in] config The card configuration object 375 * @param[out] clk The pin connected to the clk signal 376 * @param[in] cmd The pin connected to the command signal 377 * @param[in] data0 The pin connected to the data0 signal 378 * @param[in] data1 The pin connected to the data1 signal. This pin can be NC if bus width is 1-bit. 379 * @param[in] data2 The pin connected to the data2 signal. This pin can be NC if bus width is 1-bit. 380 * @param[in] data3 The pin connected to the data3 signal. This pin can be NC if bus width is 1-bit. 381 * @param[in] data4 The pin connected to the data4 signal. This pin can be NC if bus width is less than 8-bit. 382 * @param[in] data5 The pin connected to the data5 signal. This pin can be NC if bus width is less than 8-bit. 383 * @param[in] data6 The pin connected to the data6 signal. This pin can be NC if bus width is less than 8-bit. 384 * @param[in] data7 The pin connected to the data7 signal. This pin can be NC if bus width is less than 8-bit. 385 * @param[in] card_detect The pin connected to the card_detect signal 386 * @param[out] io_volt_sel The pin connected to the io_volt_sel signal 387 * @param[out] card_pwr_en The pin connected to the card_pwr_en signal 388 * @param[in] card_mech_write_prot The pin connected to the card_mech_write_prot signal 389 * @param[in] led_ctrl The pin connected to the led_ctrl signal 390 * @param[in] emmc_reset The pin connected to the emmc_reset signal 391 * @param[in] block_clk The clock to use can be shared, if not provided a new clock will be allocated 392 * @return The status of the init request 393 * 394 */ 395 cy_rslt_t cyhal_sdhc_init(cyhal_sdhc_t *obj, 396 const cyhal_sdhc_config_t *config, 397 cyhal_gpio_t cmd, 398 cyhal_gpio_t clk, 399 cyhal_gpio_t data0, 400 cyhal_gpio_t data1, 401 cyhal_gpio_t data2, 402 cyhal_gpio_t data3, 403 cyhal_gpio_t data4, 404 cyhal_gpio_t data5, 405 cyhal_gpio_t data6, 406 cyhal_gpio_t data7, 407 cyhal_gpio_t card_detect, 408 cyhal_gpio_t io_volt_sel, 409 cyhal_gpio_t card_pwr_en, 410 cyhal_gpio_t card_mech_write_prot, 411 cyhal_gpio_t led_ctrl, 412 cyhal_gpio_t emmc_reset, 413 cyhal_clock_t *block_clk); 414 415 /** Release the SDHC peripheral, not currently invoked. It requires further 416 * resource management. 417 * 418 * @param[in,out] obj The SDHC object 419 */ 420 void cyhal_sdhc_free(cyhal_sdhc_t *obj); 421 422 /** Attempts to read data synchronously over the SDHC peripheral. 423 * 424 * This will read as many blocks as possible, up to `length` blocks, into the buffer 425 * pointed to by `data`, then return. The value pointed to by `length` will be 426 * updated to reflect the number of words that were actually read. 427 * 428 * See \ref subsection_sdhc_snippet_2 429 * 430 * @param[in] obj The SDHC object 431 * @param[in] address The address to read data from 432 * @param[out] data Pointer to the byte-array where data read from the device should be stored 433 * @param[in,out] length Number of 512 byte blocks to read, updated with the number actually read 434 * @return The status of the read request 435 */ 436 cy_rslt_t cyhal_sdhc_read(cyhal_sdhc_t *obj, uint32_t address, uint8_t *data, size_t *length); 437 438 /** Attempts to write data synchronously over SDHC peripheral 439 * 440 * This will write as many blocks as possible, up to `length` blocks, then return. 441 * The value pointed to by `length` will be updated to reflect the number of words 442 * that were actually read. 443 * 444 * See \ref subsection_sdhc_snippet_3 445 * 446 * @param[in] obj The SDHC object 447 * @param[in] address The address to write data to 448 * @param[in] data Pointer to the byte-array of data to write to the device 449 * @param[in,out] length Number of 512 byte blocks to write, updated with the number actually written 450 * @return The status of the write request 451 * 452 */ 453 cy_rslt_t cyhal_sdhc_write(cyhal_sdhc_t *obj, uint32_t address, const uint8_t *data, size_t *length); 454 455 /** Erases a block of data over the SDHC peripheral 456 * 457 * @param[in] obj The SDHC object 458 * @param[in] start_addr Is the address of the first byte to erase 459 * @param[in] length Number of 512 byte blocks (starting at start_addr) to erase 460 * @param[in] timeout_ms Timeout value in ms for waiting/polling operations. If zero is provided 461 * for this parameter the default value will be used. See implementation specific 462 * documentation for timeout details. 463 * @return The status of the erase request 464 * 465 */ 466 cy_rslt_t cyhal_sdhc_erase(cyhal_sdhc_t *obj, uint32_t start_addr, size_t length, uint32_t timeout_ms); 467 468 /** Start SDHC asynchronous read 469 * 470 * This will transfer `length` 512 byte blocks into the buffer pointed to by `data` in the background. 471 * When the requested quantity of data has been read, the \ref CYHAL_SDHC_XFER_COMPLETE event will 472 * be raised. See \ref cyhal_sdhc_register_callback and \ref cyhal_sdhc_enable_event. 473 * 474 * @param[in] obj The SDHC object that holds the transfer information 475 * @param[in] address The address to read data from 476 * @param[out] data The receive buffer 477 * @param[in,out] length Number of 512 byte blocks to read, updated with the number actually read 478 * @return The status of the read_async request 479 */ 480 cy_rslt_t cyhal_sdhc_read_async(cyhal_sdhc_t *obj, uint32_t address, uint8_t *data, size_t *length); 481 482 /** Start asynchronous SDHC write 483 * 484 * This will transfer `length` 512 byte blocks from the buffer pointed to by `data` in the background. 485 * When the requested quantity of data has been written, the \ref CYHAL_SDHC_XFER_COMPLETE event 486 * will be raised. See \ref cyhal_sdhc_register_callback and \ref cyhal_sdhc_enable_event. 487 * 488 * @param[in] obj The SDHC object that holds the transfer information 489 * @param[in] address The address to write data to 490 * @param[in] data The transmit buffer 491 * @param[in,out] length The number of 512 byte blocks to write, updated with the number actually written 492 * @return The status of the write_async request 493 */ 494 cy_rslt_t cyhal_sdhc_write_async(cyhal_sdhc_t *obj, uint32_t address, const uint8_t *data, size_t *length); 495 496 /** Checks if the specified SDHC peripheral is in use 497 * 498 * @param[in] obj The SDHC peripheral to check 499 * @return Indication of whether the SDHC is still transmitting 500 */ 501 bool cyhal_sdhc_is_busy(const cyhal_sdhc_t *obj); 502 503 /** Abort an SDHC transfer 504 * 505 * @param[in] obj The SDHC peripheral to stop 506 * @return The status of the abort_async request 507 */ 508 cy_rslt_t cyhal_sdhc_abort_async(cyhal_sdhc_t *obj); 509 510 /** Register an SDHC callback handler 511 * 512 * This function will be called when one of the events enabled by \ref cyhal_sdhc_enable_event occurs. 513 * 514 * @param[in] obj The SDHC object 515 * @param[in] callback The callback handler which will be invoked when the event fires 516 * @param[in] callback_arg Generic argument that will be provided to the callback when called 517 */ 518 void cyhal_sdhc_register_callback(cyhal_sdhc_t *obj, cyhal_sdhc_event_callback_t callback, void *callback_arg); 519 520 /** Configure SDHC event enablement. 521 * 522 * When an enabled event occurs, the function specified by \ref cyhal_sdhc_register_callback will be called. 523 * 524 * @param[in] obj The SDHC object 525 * @param[in] event The SDHC event type 526 * @param[in] intr_priority The priority for NVIC interrupt events 527 * @param[in] enable True to turn on interrupts, False to turn off 528 */ 529 void cyhal_sdhc_enable_event(cyhal_sdhc_t *obj, cyhal_sdhc_event_t event, uint8_t intr_priority, bool enable); 530 531 /** Checks if SD card is inserted 532 * 533 * @param[in] obj The SDHC peripheral to check 534 * @return Indication of whether the card is inserted. 535 */ 536 bool cyhal_sdhc_is_card_inserted(const cyhal_sdhc_t *obj); 537 538 /** Checks if the inserted SD card is mechanically write protected 539 * 540 * @param[in] obj The SDHC peripheral to check 541 * @return Indication of whether the inserted SD card is mechanically write protected 542 */ 543 bool cyhal_sdhc_is_card_mech_write_protected(const cyhal_sdhc_t *obj); 544 545 /** Get block count of inserted SD card / eMMC 546 * \note SDHC driver should be initialized with \ref cyhal_sdhc_init prior to using this function. 547 * 548 * @param[in] obj The SDHC object 549 * @param[in] block_count Pointer to variable where block count will be stored 550 * @return The status of the operation 551 */ 552 cy_rslt_t cyhal_sdhc_get_block_count(cyhal_sdhc_t *obj, uint32_t *block_count); 553 554 /** Sets the SD bus frequency (frequency on which SD card / eMMC is accessed) 555 * \note Actual frequency may differ from the desired frequency due to available dividers and the frequency of source clock. 556 * Function will set the closest possible (but not greater than) frequency to what was requested. 557 * Use \ref cyhal_sdhc_get_frequency function to get actual frequency value that was achieved and set. 558 * \note If data timeout was configured by \ref cyhal_sdhc_set_data_read_timeout, it can be automaticaly recalculated 559 * according to new SD bus frequency. For details, please refer to \ref cyhal_sdhc_set_data_read_timeout function description. 560 * 561 * @param[in] obj The SDHC object 562 * @param[in] hz Desired SD bus frequency in Hz 563 * @param[in] negotiate Whether new frequency value needs to be negotiated with card or not. true is 564 * recommended and it means that new frequency will be negotiated. 565 * @return The status of the operation 566 */ 567 cy_rslt_t cyhal_sdhc_set_frequency(cyhal_sdhc_t *obj, uint32_t hz, bool negotiate); 568 569 /** Get the actual frequency that SD bus is configured for 570 * 571 * @param[in] obj The SDHC object 572 * @return Frequency in Hz 573 */ 574 uint32_t cyhal_sdhc_get_frequency(cyhal_sdhc_t *obj); 575 576 /** Sets the maximum time to wait for data from the card. The time is specified in number of card clock cycles. 577 * With SD bus frequency changed by \ref cyhal_sdhc_set_frequency, timeout can automaticaly be recalculated according 578 * to new clock frequency. This can be activated by 'auto_reconfigure' parameter. 579 * 580 * @param[in] obj The SDHC object 581 * @param[in] timeout Time to wait for data from the card. 582 * @param[in] auto_reconfigure Timeout value will be automaticaly reconfigured upon clock change 583 * 584 * @return The status of the operation 585 */ 586 cy_rslt_t cyhal_sdhc_set_data_read_timeout(cyhal_sdhc_t *obj, uint32_t timeout, bool auto_reconfigure); 587 588 /** Initializes the SD block and DMA for a data transfer. It does not start a transfer. 589 * \ref cyhal_sdhc_send_cmd needs to be called after this function in order to start data transfer. 590 * 591 * @param[in] obj The SDHC object 592 * @param[in] data_config Data transfer configuration 593 * @return The status of the operation 594 */ 595 cy_rslt_t cyhal_sdhc_config_data_transfer(cyhal_sdhc_t *obj, cyhal_sdhc_data_config_t *data_config); 596 597 /** Sends a command to the card and wait until it is sent. If the command assumes data transfer via data lines, 598 * \ref cyhal_sdhc_config_data_transfer function needs to be called prior to this one. The response of issued command 599 * can be retrieved by using \ref cyhal_sdhc_get_response function. 600 * \note Function does not wait until data (configured with \ref cyhal_sdhc_config_data_transfer) transfer complete. 601 * In order to do so, user can: 602 * - register \ref CYHAL_SDHC_XFER_COMPLETE and wait for it 603 * - wait until \ref cyhal_sdhc_is_busy return false 604 * - use \ref cyhal_sdhc_wait_transfer_complete function 605 * 606 * @param[in] obj The SDHC object 607 * @param[in] cmd_config Command configuration 608 * @return The status of the operation 609 */ 610 cy_rslt_t cyhal_sdhc_send_cmd(cyhal_sdhc_t *obj, cyhal_sdhc_cmd_config_t *cmd_config); 611 612 /** Returns a response of last issued by \ref cyhal_sdhc_send_cmd function command. 613 * 614 * @param[in] obj The SDHC object 615 * @param[in] response Pointer to array where response will be stored 616 * @param[in] large_response If true, the expected response is 136 bits, false - 48 bits, which corresponds to 617 * 120 and 32 bits of useful for application data respectively. So for large_response 4 uint32_t element array can be used 618 * while for not large_response 1 uint32_t value will be enough. 619 * @return The status of the operation 620 */ 621 cy_rslt_t cyhal_sdhc_get_response(cyhal_sdhc_t *obj, uint32_t *response, bool large_response); 622 623 /** Wait for asynchronous data transfer to complete. Such data transfer can be triggered by \ref cyhal_sdhc_write_async, 624 * \ref cyhal_sdhc_read_async or by \ref cyhal_sdhc_config_data_transfer + \ref cyhal_sdhc_send_cmd functions. 625 * 626 * @param[in] obj The SDHC object 627 * @return The status of the operation 628 */ 629 cy_rslt_t cyhal_sdhc_wait_transfer_complete(cyhal_sdhc_t *obj); 630 631 /** Sets the voltage level of the I/O lines. 632 * \note This function requires io_volt_sel and (for some cases) card_pwr_en pins to be assigned. Please refer to 633 * \ref cyhal_sdhc_init_hw for pin details. 634 * \note Switching from 1.8V to 3.3V can be done only via power cycle sequence (power down card, wait, power up card), 635 * which is supported by HAL driver and performed only if CYHAL_SDHC_IO_VOLT_ACTION_NEGOTIATE selected. card_pwr_en pin 636 * has to be assigned. Please refer to \ref cyhal_sdhc_init_hw for pin details. 637 * 638 * @param[in] obj The SDHC object 639 * @param[in] io_voltage I/O voltage to be set on lines 640 * @param[in] io_switch_type Defines how I/O voltage will be switched 641 * @return The status of the operation 642 */ 643 cy_rslt_t cyhal_sdhc_set_io_voltage(cyhal_sdhc_t *obj, cyhal_sdhc_io_voltage_t io_voltage, cyhal_sdhc_io_volt_action_type_t io_switch_type); 644 645 /** Returns the current voltage level of the I/O lines 646 * 647 * @param[in] obj The SDHC object 648 * @return Current I/O voltage setting value 649 */ 650 cyhal_sdhc_io_voltage_t cyhal_sdhc_get_io_voltage(cyhal_sdhc_t *obj); 651 652 /** Configures data bus width on host side and (optionally) informs the card about new width configuration. 653 * 654 * @param[in] obj The SDHC object 655 * @param[in] bus_width The desired bus width, 1-bit, 4-bit, 8-bit 656 * @param[in] configure_card Whether card needs to be configured with new bus width. true is recommended. 657 * @return The status of the operation 658 */ 659 cy_rslt_t cyhal_sdhc_set_bus_width(cyhal_sdhc_t *obj, uint8_t bus_width, bool configure_card); 660 661 /** Returns currently configured data bus width 662 * 663 * @param[in] obj The SDHC object 664 * @return Currently configured bus width, 1-bit, 4-bit, 8-bit 665 */ 666 uint8_t cyhal_sdhc_get_bus_width(cyhal_sdhc_t *obj); 667 668 /** Returns last issued SD operation error states. This function can be used for error checking after any of cmd / data 669 * transfer-related operations. For list of possible errors, that are being tracked, please refer to \ref cyhal_sdhc_error_type_t. 670 * 671 * @param[in] obj The SDHC object 672 * @return Errors occurred during last command 673 */ 674 cyhal_sdhc_error_type_t cyhal_sdhc_get_last_command_errors(cyhal_sdhc_t *obj); 675 676 /** Clears SDHC hardware error states. Error statuses are indicated by \ref cyhal_sdhc_get_last_command_errors function. 677 * 678 * @param[in] obj The SDHC object 679 */ 680 void cyhal_sdhc_clear_errors(cyhal_sdhc_t *obj); 681 682 /** Resets CMD and Data lines and corresponding circuits of SD Host. 683 * 684 * @param[in] obj The SDHC object 685 */ 686 void cyhal_sdhc_software_reset(cyhal_sdhc_t *obj); 687 688 /** Powers up / down the card based on provided parameter. This function uses card_pwr_en pin to change card power 689 * state. Please refer to \ref cyhal_sdhc_init_hw for pin description. 690 * 691 * @param[in] obj The SDHC peripheral to configure 692 * @param[in] enable Card is powered if true, not powered if false. 693 * @return The status of the operation 694 */ 695 cy_rslt_t cyhal_sdhc_enable_card_power(cyhal_sdhc_t *obj, bool enable); 696 697 /** Initialize the SDHC peripheral using a configurator generated configuration struct. 698 * 699 * @param[in] obj The SDHC peripheral to configure 700 * @param[in] cfg Configuration structure generated by a configurator. 701 * @return The status of the operation 702 */ 703 cy_rslt_t cyhal_sdhc_init_cfg(cyhal_sdhc_t *obj, const cyhal_sdhc_configurator_t *cfg); 704 705 #if defined(__cplusplus) 706 } 707 #endif 708 709 #ifdef CYHAL_SDHC_IMPL_HEADER 710 #include CYHAL_SDHC_IMPL_HEADER 711 #endif /* CYHAL_SDHC_IMPL_HEADER */ 712 713 /** \} group_hal_sdhc */ 714