1 /*
2 * Copyright (c) 2020 - 2024 Renesas Electronics Corporation and/or its affiliates
3 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 */
6
7 /***********************************************************************************************************************
8 * Includes
9 **********************************************************************************************************************/
10 #include <string.h>
11 #include "r_sdhi.h"
12 #include "r_sdhi_private.h"
13 #include "r_sdhi_cfg.h"
14
15 /***********************************************************************************************************************
16 * Macro definitions
17 **********************************************************************************************************************/
18
19 /** "SDHI" in ASCII, used to determine if channel is open. */
20 #define SDHI_PRV_OPEN (0x53444849U)
21
22 /* Create a bitmask of access errors. */
23 #define SDHI_PRV_CARD_CMD_ERR (1U << 16) // Command error
24 #define SDHI_PRV_CARD_CRC_ERR (1U << 17) // CRC error
25 #define SDHI_PRV_CARD_END_ERR (1U << 18) // End bit error
26 #define SDHI_PRV_CARD_DTO (1U << 19) // Data Timeout
27 #define SDHI_PRV_CARD_ILW (1U << 20) // Illegal write address
28 #define SDHI_PRV_CARD_ILR (1U << 21) // Illegal read address
29 #define SDHI_PRV_CARD_RSPT (1U << 22) // Response timeout
30 #define SDHI_PRV_CARD_ILA_ERR (1U << 31) // Illegal access
31
32 #define SDHI_PRV_ACCESS_ERROR_MASK \
33 (SDHI_PRV_CARD_CMD_ERR | SDHI_PRV_CARD_CRC_ERR | SDHI_PRV_CARD_END_ERR | SDHI_PRV_CARD_DTO | \
34 SDHI_PRV_CARD_ILW | SDHI_PRV_CARD_ILR | SDHI_PRV_CARD_RSPT | SDHI_PRV_CARD_ILA_ERR)
35
36 /* The clock register can be accessed 8 SD clock cycles after the last command completes. */
37
38 /* SD_INFO1 */
39 #define SDHI_PRV_SDHI_INFO1_RESPONSE_END (1U << 0) // Response End
40 #define SDHI_PRV_SDHI_INFO1_ACCESS_END (1U << 2) // Access End
41 #define SDHI_PRV_SDHI_INFO1_CARD_REMOVED (1U << 3) // Card Removed
42 #define SDHI_PRV_SDHI_INFO1_CARD_INSERTED (1U << 4) // Card Inserted
43 #define SDHI_PRV_SDHI_INFO1_CARD_DAT3_REMOVED (1U << 8) // Card Removed
44 #define SDHI_PRV_SDHI_INFO1_CARD_DAT3_INSERTED (1U << 9) // Card Inserted
45 #define SDHI_PRV_SDHI_INFO2_CARD_CMD_ERR (1U << 0) // Command error
46 #define SDHI_PRV_SDHI_INFO2_CARD_CRC_ERR (1U << 1) // CRC error
47 #define SDHI_PRV_SDHI_INFO2_CARD_END_ERR (1U << 2) // End bit error
48 #define SDHI_PRV_SDHI_INFO2_CARD_DTO (1U << 3) // Data Timeout
49 #define SDHI_PRV_SDHI_INFO2_CARD_ILW (1U << 4) // Illegal write address
50 #define SDHI_PRV_SDHI_INFO2_CARD_ILR (1U << 5) // Illegal read address
51 #define SDHI_PRV_SDHI_INFO2_CARD_RSPT (1U << 6) // Response timeout
52 #define SDHI_PRV_SDHI_INFO2_CARD_BRE (1U << 8) // Buffer read enable
53 #define SDHI_PRV_SDHI_INFO2_CARD_BWE (1U << 9) // Buffer write enable
54 #define SDHI_PRV_SDHI_INFO2_CARD_ILA_ERR (1U << 15) // Illegal access
55
56 #define SDHI_PRV_SDHI_INFO2_MASK \
57 ((SDHI_PRV_SDHI_INFO2_CARD_CMD_ERR | SDHI_PRV_SDHI_INFO2_CARD_CRC_ERR | SDHI_PRV_SDHI_INFO2_CARD_END_ERR | \
58 SDHI_PRV_SDHI_INFO2_CARD_DTO | SDHI_PRV_SDHI_INFO2_CARD_ILW | SDHI_PRV_SDHI_INFO2_CARD_ILR | \
59 SDHI_PRV_SDHI_INFO2_CARD_BRE | \
60 SDHI_PRV_SDHI_INFO2_CARD_BWE | \
61 SDHI_PRV_SDHI_INFO2_CARD_RSPT | SDHI_PRV_SDHI_INFO2_CARD_ILA_ERR))
62
63 #define SDHI_PRV_SDHI_INFO1_ACCESS_MASK ((SDHI_PRV_SDHI_INFO1_RESPONSE_END | \
64 SDHI_PRV_SDHI_INFO1_ACCESS_END))
65 #define SDHI_PRV_SDHI_INFO1_CARD_MASK ((SDHI_PRV_SDHI_INFO1_CARD_REMOVED | \
66 SDHI_PRV_SDHI_INFO1_CARD_INSERTED | \
67 SDHI_PRV_SDHI_INFO1_CARD_DAT3_REMOVED | \
68 SDHI_PRV_SDHI_INFO1_CARD_DAT3_INSERTED))
69 #define SDHI_PRV_SDHI_INFO1_CARD_REMOVED_MASK ((SDHI_PRV_SDHI_INFO1_CARD_REMOVED | \
70 SDHI_PRV_SDHI_INFO1_CARD_DAT3_REMOVED))
71 #define SDHI_PRV_SDHI_INFO1_CARD_INSERTED_MASK ((SDHI_PRV_SDHI_INFO1_CARD_INSERTED | \
72 SDHI_PRV_SDHI_INFO1_CARD_DAT3_INSERTED))
73
74 /* Clear all masks to enable interrupts by all sources.
75 * Do not set BREM or BWEM when using DMA/DTC. This driver always uses DMA or DTC. */
76 #define SDHI_PRV_SDHI_INFO2_MASK_CMD_SEND (0x00007C80U)
77
78 /* The relationship of the SD Clock Control Register SD_CLK_CTRL CLKSEL to the division of the source PCLK
79 * b7 b0
80 * 1 1 1 1 1 1 1 1: PCLK
81 * 0 0 0 0 0 0 0 0: PCLK/2
82 * 0 0 0 0 0 0 0 1: PCLK/4
83 * 0 0 0 0 0 0 1 0: PCLK/8
84 * 0 0 0 0 0 1 0 0: PCLK/16
85 * 0 0 0 0 1 0 0 0: PCLK/32
86 * 0 0 0 1 0 0 0 0: PCLK/64
87 * 0 0 1 0 0 0 0 0: PCLK/128
88 * 0 1 0 0 0 0 0 0: PCLK/256
89 * 1 0 0 0 0 0 0 0: PCLK/512.
90 * Other settings are prohibited.
91 */
92 #define SDHI_PRV_MAX_CLOCK_DIVISION_SHIFT (9U) /* 512 (2^9) is max clock division supported */
93
94 #define SDHI_PRV_CLK_CTRL_DIV_INVALID (0xFFU)
95
96 /* Delay up to 250 ms per sector before timing out waiting for response or response timeout flag. */
97
98 /* Delay up to 10 ms before timing out waiting for response or response timeout flag. */
99 #define SDHI_PRV_RESPONSE_TIMEOUT_US (10000U)
100
101 /* Delay up to 5 seconds before timing out waiting for busy after updating bus width or high speed status for eMMC. */
102 #define SDHI_PRV_BUSY_TIMEOUT_US (5000000U)
103
104 /* Delay up to 500 ms before timing out waiting for data or data timeout flag. */
105 #define SDHI_PRV_DATA_TIMEOUT_US (500000U)
106
107 /* Delay up to 100 ms before timing out waiting for access end flag after receiving data during initialization. */
108 #define SDHI_PRV_ACCESS_TIMEOUT_US (100000U)
109
110 /* 400 kHz maximum clock required for initialization. */
111 #define SDHI_PRV_INIT_MAX_CLOCK_RATE_HZ (400000U)
112 #define SDHI_PRV_BITS_PER_COMMAD (48U)
113 #define SDHI_PRV_BITS_PER_RESPONSE (48U)
114 #define SDHI_PRV_CLOCKS_BETWEEN_COMMANDS (8U)
115 #define SDHI_PRV_MIN_CYCLES_PER_COMMAND_RESPONSE ((SDHI_PRV_BITS_PER_COMMAD + \
116 SDHI_PRV_BITS_PER_RESPONSE) + \
117 SDHI_PRV_CLOCKS_BETWEEN_COMMANDS)
118 #define SDHI_PRV_INIT_ONE_SECOND_TIMEOUT_ITERATIONS (SDHI_PRV_INIT_MAX_CLOCK_RATE_HZ / \
119 SDHI_PRV_MIN_CYCLES_PER_COMMAND_RESPONSE)
120
121 #define SDHI_PRV_SDIO_REG_HIGH_SPEED (0x13U) // SDIO High Speed register address
122 #define SDHI_PRV_SDIO_REG_HIGH_SPEED_BIT_EHS (1U << 1) // Enable high speed bit of SDIO high speed register
123 #define SDHI_PRV_SDIO_REG_HIGH_SPEED_BIT_SHS (1U << 0) // Support high speed bit of SDIO high speed register
124 #define SDHI_PRV_CSD_REG_CCC_CLASS_10_BIT ((1U << 10)) // CCC_CLASS bit is set if the card supports high speed
125
126 /* SDIO maximum bytes allows in writeIoExt() and readIoExt(). */
127 #define SDHI_PRV_SDIO_EXT_MAX_BYTES (512U)
128
129 /* SDIO maximum blocks allows in writeIoExt() and readIoExt(). */
130 #define SDHI_PRV_SDIO_EXT_MAX_BLOCKS (511U)
131
132 /* Masks for CMD53 argument. */
133 #define SDHI_PRV_SDIO_CMD52_CMD53_COUNT_MASK (0x1FFU)
134 #define SDHI_PRV_SDIO_CMD52_CMD53_FUNCTION_MASK (0x7U)
135 #define SDHI_PRV_SDIO_CMD52_CMD53_ADDRESS_MASK (0x1FFFFU)
136
137 /* Startup delay in milliseconds. */
138
139 #define SDHI_PRV_SD_OPTION_DEFAULT (0x40E0U)
140 #define SDHI_PRV_SD_OPTION_WIDTH8_BIT (13)
141
142 #define SDHI_PRV_BUS_WIDTH_1_BIT (4U)
143
144 #define SDHI_PRV_SDIO_INFO1_MASK_IRQ_DISABLE (0xC006U)
145 #define SDHI_PRV_SDIO_INFO1_IRQ_CLEAR (0xFFFF3FFEU)
146 #define SDHI_PRV_SDIO_INFO1_TRANSFER_COMPLETE_MASK (0xC000)
147 #define SDHI_PRV_SD_INFO2_MASK_BREM_BWEM_MASK (0x300U)
148 #define SDHI_PRV_EMMC_BUS_WIDTH_INDEX (183U)
149 #define SDHI_PRV_BYTES_PER_KILOBYTE (1024)
150 #define SDHI_PRV_SECTOR_COUNT_IN_EXT_CSD (0xFFFU)
151 #define SDHI_PRV_SD_CLK_CTRL_DEFAULT (0x20U)
152
153 #define SDHI_PRV_SD_INFO2_CBSY_SDD0MON_IDLE_MASK (0x4080)
154 #define SDHI_PRV_SD_INFO2_CBSY_SDD0MON_IDLE_VAL (0x80)
155 #define SDHI_PRV_SD_CLK_CTRLEN_TIMEOUT (8U * 512U)
156 #define SDHI_PRV_SD_INFO1_MASK_MASK_ALL (0x31DU)
157 #define SDHI_PRV_SD_INFO1_MASK_CD_ENABLE (0x305U)
158 #define SDHI_PRV_SD_STOP_SD_SECCNT_ENABLE (0x100U)
159 #define SDHI_PRV_SD_DMAEN_DMAEN_SET (0x2U)
160
161 #define SDHI_PRV_SDHI_PRV_SD_CLK_CTRL_CLKCTRLEN_MASK (1U << 9)
162 #define SDHI_PRV_SDHI_PRV_SD_CLK_CTRL_CLKEN_MASK (1U << 8)
163 #define SDHI_PRV_SDHI_PRV_SD_CLK_AUTO_CLOCK_ENABLE_MASK (0x300U)
164
165 #define SDHI_PRV_ACCESS_BIT (2U)
166 #define SDHI_PRV_RESPONSE_BIT (0U)
167
168 /***********************************************************************************************************************
169 * Typedef definitions
170 **********************************************************************************************************************/
171 #if defined(__ARMCC_VERSION) || defined(__ICCARM__)
172 typedef void (BSP_CMSE_NONSECURE_CALL * sdhi_prv_ns_callback)(sdmmc_callback_args_t * p_args);
173 #elif defined(__GNUC__)
174 typedef BSP_CMSE_NONSECURE_CALL void (*volatile sdhi_prv_ns_callback)(sdmmc_callback_args_t * p_args);
175 #endif
176
177 /***********************************************************************************************************************
178 * Private function prototypes
179 **********************************************************************************************************************/
180 #if SDHI_CFG_PARAM_CHECKING_ENABLE
181 static fsp_err_t r_sdhi_open_param_check(sdhi_instance_ctrl_t * p_ctrl, sdmmc_cfg_t const * const p_cfg);
182
183 #endif
184
185 #if SDHI_CFG_EMMC_SUPPORT_ENABLE
186 static fsp_err_t r_sdhi_emmc_check(sdhi_instance_ctrl_t * const p_ctrl);
187
188 static fsp_err_t r_sdhi_csd_extended_get(sdhi_instance_ctrl_t * const p_ctrl, uint32_t rca, uint8_t * p_device_type);
189
190 #endif
191
192 #if SDHI_CFG_SDIO_SUPPORT_ENABLE
193 static fsp_err_t r_sdhi_sdio_check(sdhi_instance_ctrl_t * const p_ctrl);
194
195 static fsp_err_t r_sdhi_sdio_clock_optimize(sdhi_instance_ctrl_t * const p_ctrl);
196
197 static fsp_err_t r_sdhi_cmd52(sdhi_instance_ctrl_t * const p_ctrl,
198 uint8_t * const p_data,
199 uint32_t const function,
200 uint32_t const address,
201 sdmmc_io_write_mode_t const read_after_write,
202 uint32_t const command);
203
204 #endif
205
206 #if SDHI_CFG_SD_SUPPORT_ENABLE
207 static fsp_err_t r_sdhi_sd_card_check(sdhi_instance_ctrl_t * const p_ctrl);
208
209 static fsp_err_t r_sdhi_sd_high_speed(sdhi_instance_ctrl_t * const p_ctrl);
210
211 static void r_sdhi_write_protect_get(sdhi_instance_ctrl_t * const p_ctrl);
212
213 #endif
214
215 #if SDHI_CFG_SD_SUPPORT_ENABLE || SDHI_CFG_EMMC_SUPPORT_ENABLE
216 static fsp_err_t r_sdhi_clock_optimize(sdhi_instance_ctrl_t * const p_ctrl,
217 uint32_t rca,
218 sdmmc_priv_csd_reg_t * const p_csd_reg);
219
220 static fsp_err_t r_sdhi_csd_save(sdhi_instance_ctrl_t * const p_ctrl,
221 uint32_t rca,
222 sdmmc_priv_csd_reg_t * const p_csd_reg);
223
224 fsp_err_t r_sdhi_read_and_block(sdhi_instance_ctrl_t * const p_ctrl,
225 uint32_t command,
226 uint32_t argument,
227 uint32_t byte_count);
228
229 static fsp_err_t r_sdhi_bus_width_set(sdhi_instance_ctrl_t * const p_ctrl, uint32_t rca);
230
231 #endif
232
233 static fsp_err_t r_sdhi_erase_error_check(sdhi_instance_ctrl_t * const p_ctrl,
234 uint32_t const start_sector,
235 uint32_t const sector_count);
236
237 static fsp_err_t r_sdhi_common_error_check(sdhi_instance_ctrl_t * const p_ctrl);
238
239 static void r_sdhi_irq_enable(IRQn_Type irq, uint8_t priority, void * p_context);
240 static void r_sdhi_irq_disable(IRQn_Type irq);
241
242 static void r_sdhi_access_irq_process(sdhi_instance_ctrl_t * p_ctrl, sdmmc_callback_args_t * p_args);
243
244 void r_sdhi_command_send_no_wait(sdhi_instance_ctrl_t * p_ctrl, uint32_t command, uint32_t argument);
245
246 fsp_err_t r_sdhi_command_send(sdhi_instance_ctrl_t * p_ctrl, uint32_t command, uint32_t argument);
247
248 fsp_err_t r_sdhi_max_clock_rate_set(sdhi_instance_ctrl_t * p_ctrl, uint32_t max_rate);
249
250 fsp_err_t r_sdhi_wait_for_event(sdhi_instance_ctrl_t * const p_ctrl, uint32_t bit, uint32_t timeout);
251
252 static fsp_err_t r_sdhi_rca_get(sdhi_instance_ctrl_t * const p_ctrl, uint32_t * p_rca);
253
254 fsp_err_t r_sdhi_hw_cfg(sdhi_instance_ctrl_t * const p_ctrl);
255
256 static fsp_err_t r_sdhi_card_identify(sdhi_instance_ctrl_t * const p_ctrl);
257
258 static fsp_err_t r_sdhi_bus_cfg(sdhi_instance_ctrl_t * const p_ctrl);
259
260 fsp_err_t r_sdhi_wait_for_device(sdhi_instance_ctrl_t * const p_ctrl);
261
262 void r_sdhi_read_write_common(sdhi_instance_ctrl_t * const p_ctrl,
263 uint32_t sector_count,
264 uint32_t sector_size,
265 uint32_t command,
266 uint32_t argument);
267
268 fsp_err_t r_sdhi_transfer_read(sdhi_instance_ctrl_t * const p_ctrl,
269 uint32_t block_count,
270 uint32_t bytes,
271 void * p_data);
272
273 fsp_err_t r_sdhi_transfer_write(sdhi_instance_ctrl_t * const p_ctrl,
274 uint32_t block_count,
275 uint32_t bytes,
276 const uint8_t * p_data);
277
278 static void r_sdhi_transfer_end(sdhi_instance_ctrl_t * const p_ctrl);
279
280 static void r_sdhi_call_callback(sdhi_instance_ctrl_t * p_ctrl, sdmmc_callback_args_t * p_args);
281
282 void r_sdhi_transfer_callback(sdhi_instance_ctrl_t * p_ctrl);
283
284 void sdhimmc_accs_isr(void);
285
286 void sdhimmc_card_isr(void);
287
288 void sdhimmc_dma_req_isr(void);
289
290 void sdhimmc_sdio_isr(void);
291
292 /***********************************************************************************************************************
293 * Private global variables
294 **********************************************************************************************************************/
295
296 /***********************************************************************************************************************
297 * Global Variables
298 **********************************************************************************************************************/
299
300 /** SDMMC function pointers */
301 const sdmmc_api_t g_sdmmc_on_sdhi =
302 {
303 .open = R_SDHI_Open,
304 .mediaInit = R_SDHI_MediaInit,
305 .read = R_SDHI_Read,
306 .write = R_SDHI_Write,
307 .readIo = R_SDHI_ReadIo,
308 .writeIo = R_SDHI_WriteIo,
309 .readIoExt = R_SDHI_ReadIoExt,
310 .writeIoExt = R_SDHI_WriteIoExt,
311 .ioIntEnable = R_SDHI_IoIntEnable,
312 .statusGet = R_SDHI_StatusGet,
313 .erase = R_SDHI_Erase,
314 .callbackSet = R_SDHI_CallbackSet,
315 .close = R_SDHI_Close,
316 };
317
318 /*******************************************************************************************************************//**
319 * @addtogroup SDHI
320 * @{
321 **********************************************************************************************************************/
322
323 /***********************************************************************************************************************
324 * Functions
325 **********************************************************************************************************************/
326
327 /*******************************************************************************************************************//**
328 * Opens the driver. Resets SDHI, and enables card detection interrupts if card detection is enabled.
329 * @ref R_SDHI_MediaInit must be called after this function before any other functions can be used.
330 *
331 * Implements @ref sdmmc_api_t::open().
332 *
333 * Example:
334 * @snippet r_sdhi_example.c R_SDHI_Open
335 *
336 * @retval FSP_SUCCESS Module is now open.
337 * @retval FSP_ERR_ASSERTION Null Pointer or block size is not in the valid range of 1-512. Block size
338 * must be 512 bytes for SD cards and eMMC devices. It is configurable for
339 * SDIO only.
340 * @retval FSP_ERR_ALREADY_OPEN Driver has already been opened with this instance of the control
341 * structure.
342 * @retval FSP_ERR_IRQ_BSP_DISABLED Access interrupt is not enabled.
343 * @retval FSP_ERR_IP_CHANNEL_NOT_PRESENT Requested channel does not exist on this MCU.
344 **********************************************************************************************************************/
R_SDHI_Open(sdmmc_ctrl_t * const p_api_ctrl,sdmmc_cfg_t const * const p_cfg)345 fsp_err_t R_SDHI_Open (sdmmc_ctrl_t * const p_api_ctrl, sdmmc_cfg_t const * const p_cfg)
346 {
347 sdhi_instance_ctrl_t * p_ctrl = (sdhi_instance_ctrl_t *) p_api_ctrl;
348
349 fsp_err_t err = FSP_SUCCESS;
350
351 #if SDHI_CFG_PARAM_CHECKING_ENABLE
352 err = r_sdhi_open_param_check(p_ctrl, p_cfg);
353 FSP_ERROR_RETURN(FSP_SUCCESS == err, err);
354 #endif
355
356 /* Open the transfer driver. Clear the transfer length in case the transfer_info_t structure is reused and the
357 * length was copied to the upper 8 bits for block mode. Configurations are updated before it is used. */
358 p_cfg->p_lower_lvl_transfer->p_cfg->p_info->transfer_settings_word = 0U;
359 err = p_cfg->p_lower_lvl_transfer->p_api->open(p_cfg->p_lower_lvl_transfer->p_ctrl,
360 p_cfg->p_lower_lvl_transfer->p_cfg);
361 FSP_ERROR_RETURN(FSP_SUCCESS == err, err);
362
363 /* Initialize control block. */
364 memset(p_ctrl, 0, sizeof(*p_ctrl));
365 #if BSP_FEATURE_SDHI_VALID_CHANNEL_MASK > 1U
366 p_ctrl->p_reg = p_cfg->channel ? R_SDHI1 : R_SDHI0;
367 #else
368 p_ctrl->p_reg = R_SDHI0;
369 #endif
370 p_ctrl->p_cfg = p_cfg;
371
372 /* Clear module stop bit (turn module on). */
373 R_BSP_MODULE_START(FSP_IP_SDHIMMC, p_cfg->channel);
374
375 /* Reset stale interrupt flags */
376 p_ctrl->p_reg->SD_INFO1 = 0U;
377
378 /* Reset SDHI. */
379 p_ctrl->p_reg->SOFT_RST = 0x0U;
380 p_ctrl->p_reg->SOFT_RST = 0x1U;
381
382 /* Configure card detection. */
383 if (SDMMC_CARD_DETECT_CD == p_ctrl->p_cfg->card_detect)
384 {
385 p_ctrl->p_reg->SD_INFO1_MASK = SDHI_PRV_SD_INFO1_MASK_CD_ENABLE;
386 }
387 else
388 {
389 p_ctrl->p_reg->SD_INFO1_MASK = SDHI_PRV_SD_INFO1_MASK_MASK_ALL;
390 }
391
392 /* Set callback and context pointers, if configured */
393 p_ctrl->p_callback = p_cfg->p_callback;
394 p_ctrl->p_context = p_cfg->p_context;
395 p_ctrl->p_callback_memory = NULL;
396
397 /* Configure and enable interrupts. */
398 R_BSP_IrqCfgEnable(p_cfg->access_irq, p_cfg->access_ipl, p_ctrl);
399 r_sdhi_irq_enable(p_cfg->card_irq, p_cfg->card_ipl, p_ctrl);
400 r_sdhi_irq_enable(p_cfg->sdio_irq, p_cfg->sdio_ipl, p_ctrl);
401 r_sdhi_irq_enable(p_cfg->dma_req_irq, p_cfg->dma_req_ipl, p_ctrl);
402
403 p_ctrl->initialized = false;
404 p_ctrl->open = SDHI_PRV_OPEN;
405
406 return FSP_SUCCESS;
407 }
408
409 /*******************************************************************************************************************//**
410 * Initializes the SDHI hardware and completes identification and configuration for the SD or eMMC device. This
411 * procedure requires several sequential commands. This function blocks until all identification and configuration
412 * commands are complete.
413 *
414 * Implements @ref sdmmc_api_t::mediaInit().
415 *
416 * Example:
417 * @snippet r_sdhi_example.c R_SDHI_MediaInit
418 *
419 * @retval FSP_SUCCESS Module is now ready for read/write access.
420 * @retval FSP_ERR_ASSERTION Null Pointer or block size is not in the valid range of 1-512. Block size must
421 * be 512 bytes for SD cards and eMMC devices. It is configurable for SDIO only.
422 * @retval FSP_ERR_NOT_OPEN Driver has not been initialized.
423 * @retval FSP_ERR_CARD_INIT_FAILED Device was not identified as an SD card, eMMC device, or SDIO card.
424 * @retval FSP_ERR_RESPONSE Device responded with an error.
425 * @retval FSP_ERR_TIMEOUT Device did not respond.
426 * @retval FSP_ERR_DEVICE_BUSY Device is holding DAT0 low (device is busy) or another operation is ongoing.
427 **********************************************************************************************************************/
R_SDHI_MediaInit(sdmmc_ctrl_t * const p_api_ctrl,sdmmc_device_t * const p_device)428 fsp_err_t R_SDHI_MediaInit (sdmmc_ctrl_t * const p_api_ctrl, sdmmc_device_t * const p_device)
429 {
430 sdhi_instance_ctrl_t * p_ctrl = (sdhi_instance_ctrl_t *) p_api_ctrl;
431
432 fsp_err_t err = FSP_SUCCESS;
433
434 #if SDHI_CFG_PARAM_CHECKING_ENABLE
435 FSP_ASSERT(NULL != p_ctrl);
436 FSP_ERROR_RETURN(SDHI_PRV_OPEN == p_ctrl->open, FSP_ERR_NOT_OPEN);
437 #endif
438
439 /* Device is not initialized until this function completes. */
440 p_ctrl->initialized = false;
441
442 /* Configure SDHI peripheral. */
443 err = r_sdhi_hw_cfg(p_ctrl);
444 FSP_ERROR_RETURN(FSP_SUCCESS == err, err);
445
446 /* Perform the identification procedure for SD card or eMMC device. */
447 err = r_sdhi_card_identify(p_ctrl);
448 FSP_ERROR_RETURN(FSP_SUCCESS == err, err);
449
450 /* Configure bus clock, block size, and bus width. */
451 err = r_sdhi_bus_cfg(p_ctrl);
452 FSP_ERROR_RETURN(FSP_SUCCESS == err, err);
453
454 /* Check to see if the card is write protected (SD cards only). */
455 #if SDHI_CFG_SD_SUPPORT_ENABLE
456 r_sdhi_write_protect_get(p_ctrl);
457 #endif
458
459 /* Return device information to user. */
460 p_ctrl->device.sector_size_bytes = p_ctrl->p_cfg->block_size;
461 if (NULL != p_device)
462 {
463 *p_device = p_ctrl->device;
464 }
465
466 p_ctrl->initialized = true;
467
468 return FSP_SUCCESS;
469 }
470
471 /*******************************************************************************************************************//**
472 * Reads data from an SD or eMMC device. Up to 0x10000 sectors can be read at a time. Implements @ref sdmmc_api_t::read().
473 *
474 * A callback with the event SDMMC_EVENT_TRANSFER_COMPLETE is called when the read data is available.
475 *
476 * Example:
477 * @snippet r_sdhi_example.c R_SDHI_Read
478 *
479 * @retval FSP_SUCCESS Data read successfully.
480 * @retval FSP_ERR_ASSERTION NULL pointer.
481 * @retval FSP_ERR_NOT_OPEN Driver has not been initialized.
482 * @retval FSP_ERR_CARD_NOT_INITIALIZED Card was unplugged.
483 * @retval FSP_ERR_DEVICE_BUSY Driver is busy with a previous operation.
484 **********************************************************************************************************************/
R_SDHI_Read(sdmmc_ctrl_t * const p_api_ctrl,uint8_t * const p_dest,uint32_t const start_sector,uint32_t const sector_count)485 fsp_err_t R_SDHI_Read (sdmmc_ctrl_t * const p_api_ctrl,
486 uint8_t * const p_dest,
487 uint32_t const start_sector,
488 uint32_t const sector_count)
489 {
490 sdhi_instance_ctrl_t * p_ctrl = (sdhi_instance_ctrl_t *) p_api_ctrl;
491
492 fsp_err_t err = FSP_SUCCESS;
493
494 #if SDHI_CFG_PARAM_CHECKING_ENABLE
495 FSP_ASSERT(NULL != p_dest);
496 FSP_ASSERT(sector_count <= (UINT16_MAX + 1));
497 #endif
498 err = r_sdhi_common_error_check(p_ctrl);
499 FSP_ERROR_RETURN(FSP_SUCCESS == err, err);
500
501 /* Configure the transfer interface for reading. */
502 err = r_sdhi_transfer_read(p_ctrl, sector_count, p_ctrl->p_cfg->block_size, p_dest);
503 FSP_ERROR_RETURN(FSP_SUCCESS == err, err);
504
505 uint32_t command = 0U;
506 uint32_t argument = start_sector;
507 if (!p_ctrl->sector_addressing)
508 {
509 /* Standard capacity SD cards and some eMMC devices use byte addressing. */
510 argument *= p_ctrl->p_cfg->block_size;
511 }
512
513 if (sector_count > 1U)
514 {
515 command = SDHI_PRV_CMD_READ_MULTIPLE_BLOCK;
516 }
517 else
518 {
519 command = SDHI_PRV_CMD_READ_SINGLE_BLOCK;
520 }
521
522 r_sdhi_read_write_common(p_ctrl, sector_count, p_ctrl->p_cfg->block_size, command, argument);
523
524 return FSP_SUCCESS;
525 }
526
527 /*******************************************************************************************************************//**
528 * Writes data to an SD or eMMC device. Up to 0x10000 sectors can be written at a time. Implements @ref sdmmc_api_t::write().
529 *
530 * A callback with the event SDMMC_EVENT_TRANSFER_COMPLETE is called when the all data has been written and the device
531 * is no longer holding DAT0 low to indicate it is busy.
532 *
533 * Example:
534 * @snippet r_sdhi_example.c R_SDHI_Write
535 *
536 * @retval FSP_SUCCESS Card write finished successfully.
537 * @retval FSP_ERR_ASSERTION Handle or Source address is NULL.
538 * @retval FSP_ERR_NOT_OPEN Driver has not been initialized.
539 * @retval FSP_ERR_CARD_NOT_INITIALIZED Card was unplugged.
540 * @retval FSP_ERR_DEVICE_BUSY Driver is busy with a previous operation.
541 * @retval FSP_ERR_CARD_WRITE_PROTECTED SD card is Write Protected.
542 * @retval FSP_ERR_WRITE_FAILED Write operation failed.
543 **********************************************************************************************************************/
R_SDHI_Write(sdmmc_ctrl_t * const p_api_ctrl,uint8_t const * const p_source,uint32_t const start_sector,uint32_t const sector_count)544 fsp_err_t R_SDHI_Write (sdmmc_ctrl_t * const p_api_ctrl,
545 uint8_t const * const p_source,
546 uint32_t const start_sector,
547 uint32_t const sector_count)
548 {
549 sdhi_instance_ctrl_t * p_ctrl = (sdhi_instance_ctrl_t *) p_api_ctrl;
550
551 fsp_err_t err = FSP_SUCCESS;
552
553 #if SDHI_CFG_PARAM_CHECKING_ENABLE
554 FSP_ASSERT(NULL != p_source);
555 FSP_ASSERT(sector_count <= (UINT16_MAX + 1));
556 #endif
557 err = r_sdhi_common_error_check(p_ctrl);
558 FSP_ERROR_RETURN(FSP_SUCCESS == err, err);
559
560 /* Check for write protection */
561 FSP_ERROR_RETURN(!p_ctrl->device.write_protected, FSP_ERR_CARD_WRITE_PROTECTED);
562
563 /* Configure the transfer interface for writing. */
564 err = r_sdhi_transfer_write(p_ctrl, sector_count, p_ctrl->p_cfg->block_size, p_source);
565 FSP_ERROR_RETURN(FSP_SUCCESS == err, FSP_ERR_WRITE_FAILED);
566
567 /* Call SDMMC protocol write function */
568 uint32_t command = 0U;
569 uint32_t argument = start_sector;
570 if (!p_ctrl->sector_addressing)
571 {
572 /* Standard capacity SD cards and some eMMC devices use byte addressing. */
573 argument *= p_ctrl->p_cfg->block_size;
574 }
575
576 if (sector_count > 1U)
577 {
578 command = SDHI_PRV_CMD_WRITE_MULTIPLE_BLOCK;
579 }
580 else
581 {
582 command = SDHI_PRV_CMD_WRITE_SINGLE_BLOCK;
583 }
584
585 /* Casting to uint16_t safe because block size verified in R_SDHI_Open */
586 r_sdhi_read_write_common(p_ctrl, sector_count, p_ctrl->p_cfg->block_size, command, argument);
587
588 return FSP_SUCCESS;
589 }
590
591 /*******************************************************************************************************************//**
592 * The Read function reads a one byte register from an SDIO card. Implements @ref sdmmc_api_t::readIo().
593 *
594 * This function blocks until the command is sent and the response is received. p_data contains the register value read
595 * when this function returns.
596 *
597 * @retval FSP_SUCCESS Data read successfully.
598 * @retval FSP_ERR_ASSERTION NULL pointer.
599 * @retval FSP_ERR_NOT_OPEN Driver has not been initialized.
600 * @retval FSP_ERR_CARD_NOT_INITIALIZED Card was unplugged.
601 * @retval FSP_ERR_UNSUPPORTED SDIO support disabled in SDHI_CFG_SDIO_SUPPORT_ENABLE.
602 * @retval FSP_ERR_RESPONSE Device responded with an error.
603 * @retval FSP_ERR_TIMEOUT Device did not respond.
604 * @retval FSP_ERR_DEVICE_BUSY Device is holding DAT0 low (device is busy) or another operation is
605 * ongoing.
606 **********************************************************************************************************************/
R_SDHI_ReadIo(sdmmc_ctrl_t * const p_api_ctrl,uint8_t * const p_data,uint32_t const function,uint32_t const address)607 fsp_err_t R_SDHI_ReadIo (sdmmc_ctrl_t * const p_api_ctrl,
608 uint8_t * const p_data,
609 uint32_t const function,
610 uint32_t const address)
611 {
612 #if SDHI_CFG_SDIO_SUPPORT_ENABLE
613 sdhi_instance_ctrl_t * p_ctrl = (sdhi_instance_ctrl_t *) p_api_ctrl;
614
615 fsp_err_t err = FSP_SUCCESS;
616
617 #if SDHI_CFG_PARAM_CHECKING_ENABLE
618 FSP_ASSERT(NULL != p_data);
619 #endif
620 err = r_sdhi_common_error_check(p_ctrl);
621 FSP_ERROR_RETURN(FSP_SUCCESS == err, err);
622
623 /* Call SDMMC protocol read function */
624 *p_data = 0U;
625 err = r_sdhi_cmd52(p_ctrl, p_data, function, address, SDMMC_IO_WRITE_MODE_NO_READ, SDHI_PRV_SDIO_CMD52_READ);
626
627 FSP_ERROR_RETURN(FSP_SUCCESS == err, err);
628
629 return err;
630 #else
631 FSP_PARAMETER_NOT_USED(p_api_ctrl);
632 FSP_PARAMETER_NOT_USED(p_data);
633 FSP_PARAMETER_NOT_USED(function);
634 FSP_PARAMETER_NOT_USED(address);
635
636 FSP_RETURN(FSP_ERR_UNSUPPORTED);
637 #endif
638 }
639
640 /*******************************************************************************************************************//**
641 * Writes a one byte register to an SDIO card. Implements @ref sdmmc_api_t::writeIo().
642 *
643 * This function blocks until the command is sent and the response is received. The register has been written when this
644 * function returns. If read_after_write is true, p_data contains the register value read when this function returns.
645 *
646 * @retval FSP_SUCCESS Card write finished successfully.
647 * @retval FSP_ERR_ASSERTION Handle or Source address is NULL.
648 * @retval FSP_ERR_NOT_OPEN Driver has not been initialized.
649 * @retval FSP_ERR_CARD_NOT_INITIALIZED Card was unplugged.
650 * @retval FSP_ERR_WRITE_FAILED Write operation failed.
651 * @retval FSP_ERR_UNSUPPORTED SDIO support disabled in SDHI_CFG_SDIO_SUPPORT_ENABLE.
652 * @retval FSP_ERR_RESPONSE Device responded with an error.
653 * @retval FSP_ERR_TIMEOUT Device did not respond.
654 * @retval FSP_ERR_DEVICE_BUSY Device is holding DAT0 low (device is busy) or another operation is
655 * ongoing.
656 **********************************************************************************************************************/
R_SDHI_WriteIo(sdmmc_ctrl_t * const p_api_ctrl,uint8_t * const p_data,uint32_t const function,uint32_t const address,sdmmc_io_write_mode_t const read_after_write)657 fsp_err_t R_SDHI_WriteIo (sdmmc_ctrl_t * const p_api_ctrl,
658 uint8_t * const p_data,
659 uint32_t const function,
660 uint32_t const address,
661 sdmmc_io_write_mode_t const read_after_write)
662 {
663 #if SDHI_CFG_SDIO_SUPPORT_ENABLE
664 sdhi_instance_ctrl_t * p_ctrl = (sdhi_instance_ctrl_t *) p_api_ctrl;
665
666 fsp_err_t err = FSP_SUCCESS;
667 #if SDHI_CFG_PARAM_CHECKING_ENABLE
668 FSP_ASSERT(NULL != p_data);
669 #endif
670
671 err = r_sdhi_common_error_check(p_ctrl);
672 FSP_ERROR_RETURN(FSP_SUCCESS == err, err);
673
674 err = r_sdhi_cmd52(p_ctrl, p_data, function, address, read_after_write, SDHI_PRV_SDIO_CMD52_WRITE);
675
676 FSP_ERROR_RETURN(FSP_SUCCESS == err, FSP_ERR_WRITE_FAILED);
677
678 return err;
679 #else
680 FSP_PARAMETER_NOT_USED(p_api_ctrl);
681 FSP_PARAMETER_NOT_USED(p_data);
682 FSP_PARAMETER_NOT_USED(function);
683 FSP_PARAMETER_NOT_USED(address);
684 FSP_PARAMETER_NOT_USED(read_after_write);
685
686 FSP_RETURN(FSP_ERR_UNSUPPORTED);
687 #endif
688 }
689
690 /*******************************************************************************************************************//**
691 * Reads data from an SDIO card function. Implements @ref sdmmc_api_t::readIoExt().
692 *
693 * This function blocks until the command is sent and the response is received. A callback with the event
694 * SDMMC_EVENT_TRANSFER_COMPLETE is called when the read data is available.
695 *
696 * @retval FSP_SUCCESS Data read successfully.
697 * @retval FSP_ERR_ASSERTION NULL pointer, or count is not in the valid range of 1-512 for byte mode or
698 * 1-511 for block mode.
699 * @retval FSP_ERR_NOT_OPEN Driver has not been initialized.
700 * @retval FSP_ERR_CARD_NOT_INITIALIZED Card was unplugged.
701 * @retval FSP_ERR_DEVICE_BUSY Driver is busy with a previous operation.
702 * @retval FSP_ERR_UNSUPPORTED SDIO support disabled in SDHI_CFG_SDIO_SUPPORT_ENABLE.
703 **********************************************************************************************************************/
R_SDHI_ReadIoExt(sdmmc_ctrl_t * const p_api_ctrl,uint8_t * const p_dest,uint32_t const function,uint32_t const address,uint32_t * const count,sdmmc_io_transfer_mode_t transfer_mode,sdmmc_io_address_mode_t address_mode)704 fsp_err_t R_SDHI_ReadIoExt (sdmmc_ctrl_t * const p_api_ctrl,
705 uint8_t * const p_dest,
706 uint32_t const function,
707 uint32_t const address,
708 uint32_t * const count,
709 sdmmc_io_transfer_mode_t transfer_mode,
710 sdmmc_io_address_mode_t address_mode)
711 {
712 #if SDHI_CFG_SDIO_SUPPORT_ENABLE
713 sdhi_instance_ctrl_t * p_ctrl = (sdhi_instance_ctrl_t *) p_api_ctrl;
714
715 fsp_err_t err = FSP_SUCCESS;
716
717 #if SDHI_CFG_PARAM_CHECKING_ENABLE
718 FSP_ASSERT(NULL != p_dest);
719 FSP_ASSERT(0U != (*count));
720 #endif
721 err = r_sdhi_common_error_check(p_ctrl);
722 FSP_ERROR_RETURN(FSP_SUCCESS == err, err);
723
724 uint32_t command = SDHI_PRV_CMD_IO_READ_EXT_SINGLE_BLOCK;
725 uint32_t byte_count = 0U;
726 uint32_t block_count = 0U;
727 if (SDMMC_IO_MODE_TRANSFER_BLOCK == transfer_mode)
728 {
729 #if SDHI_CFG_PARAM_CHECKING_ENABLE
730 FSP_ASSERT((*count) <= SDHI_PRV_SDIO_EXT_MAX_BLOCKS);
731 #endif
732 block_count = *count;
733 byte_count = p_ctrl->p_cfg->block_size;
734 if (block_count > 1U)
735 {
736 command |= SDHI_PRV_CMD_IO_EXT_MULTI_BLOCK;
737 }
738 }
739 else
740 {
741 #if SDHI_CFG_PARAM_CHECKING_ENABLE
742 FSP_ASSERT((*count) <= SDHI_PRV_SDIO_EXT_MAX_BYTES);
743 #endif
744 block_count = 1U;
745 byte_count = *count;
746 }
747
748 /* Configure the transfer interface for reading. */
749 err = r_sdhi_transfer_read(p_ctrl, block_count, byte_count, p_dest);
750 FSP_ERROR_RETURN(FSP_SUCCESS == err, err);
751
752 sdmmc_priv_sdio_arg_t argument = {0U};
753
754 /* According to SDIO spec, 512 = 0. */
755 argument.cmd_53_arg.count = (*count & SDHI_PRV_SDIO_CMD52_CMD53_COUNT_MASK);
756 argument.cmd_53_arg.function_number = (function & SDHI_PRV_SDIO_CMD52_CMD53_FUNCTION_MASK);
757 argument.cmd_53_arg.block_mode = transfer_mode;
758 argument.cmd_53_arg.op_code = address_mode;
759 argument.cmd_53_arg.register_address = (address & SDHI_PRV_SDIO_CMD52_CMD53_ADDRESS_MASK);
760 argument.cmd_53_arg.rw_flag = 0U;
761 r_sdhi_read_write_common(p_ctrl, block_count, byte_count, command, argument.arg);
762
763 return FSP_SUCCESS;
764 #else
765 FSP_PARAMETER_NOT_USED(p_api_ctrl);
766 FSP_PARAMETER_NOT_USED(p_dest);
767 FSP_PARAMETER_NOT_USED(function);
768 FSP_PARAMETER_NOT_USED(address);
769 FSP_PARAMETER_NOT_USED(count);
770 FSP_PARAMETER_NOT_USED(transfer_mode);
771 FSP_PARAMETER_NOT_USED(address_mode);
772
773 FSP_RETURN(FSP_ERR_UNSUPPORTED);
774 #endif
775 }
776
777 /*******************************************************************************************************************//**
778 * Writes data to an SDIO card function. Implements @ref sdmmc_api_t::writeIoExt().
779 *
780 * This function blocks until the command is sent and the response is received. A callback with the event
781 * SDMMC_EVENT_TRANSFER_COMPLETE is called when the all data has been written.
782 *
783 * @retval FSP_SUCCESS Card write finished successfully.
784 * @retval FSP_ERR_ASSERTION NULL pointer, or count is not in the valid range of 1-512 for byte mode or
785 * 1-511 for block mode.
786 * @retval FSP_ERR_NOT_OPEN Driver has not been initialized.
787 * @retval FSP_ERR_CARD_NOT_INITIALIZED Card was unplugged.
788 * @retval FSP_ERR_DEVICE_BUSY Driver is busy with a previous operation.
789 * @retval FSP_ERR_WRITE_FAILED Write operation failed.
790 * @retval FSP_ERR_UNSUPPORTED SDIO support disabled in SDHI_CFG_SDIO_SUPPORT_ENABLE.
791 **********************************************************************************************************************/
R_SDHI_WriteIoExt(sdmmc_ctrl_t * const p_api_ctrl,uint8_t const * const p_source,uint32_t const function,uint32_t const address,uint32_t const count,sdmmc_io_transfer_mode_t transfer_mode,sdmmc_io_address_mode_t address_mode)792 fsp_err_t R_SDHI_WriteIoExt (sdmmc_ctrl_t * const p_api_ctrl,
793 uint8_t const * const p_source,
794 uint32_t const function,
795 uint32_t const address,
796 uint32_t const count,
797 sdmmc_io_transfer_mode_t transfer_mode,
798 sdmmc_io_address_mode_t address_mode)
799 {
800 #if SDHI_CFG_SDIO_SUPPORT_ENABLE
801 sdhi_instance_ctrl_t * p_ctrl = (sdhi_instance_ctrl_t *) p_api_ctrl;
802
803 fsp_err_t err = FSP_SUCCESS;
804
805 #if SDHI_CFG_PARAM_CHECKING_ENABLE
806 FSP_ASSERT(NULL != p_source);
807 FSP_ASSERT(0U != count);
808 #endif
809
810 err = r_sdhi_common_error_check(p_ctrl);
811 FSP_ERROR_RETURN(FSP_SUCCESS == err, err);
812
813 uint32_t command = SDHI_PRV_CMD_IO_WRITE_EXT_SINGLE_BLOCK;
814 uint32_t byte_count = 0U;
815 uint32_t block_count = 0U;
816 if (SDMMC_IO_MODE_TRANSFER_BLOCK == transfer_mode)
817 {
818 #if SDHI_CFG_PARAM_CHECKING_ENABLE
819 FSP_ASSERT(count <= SDHI_PRV_SDIO_EXT_MAX_BLOCKS);
820 #endif
821 block_count = count;
822 byte_count = p_ctrl->p_cfg->block_size;
823 if (block_count > 1U)
824 {
825 command |= SDHI_PRV_CMD_IO_EXT_MULTI_BLOCK;
826 }
827 }
828 else
829 {
830 #if SDHI_CFG_PARAM_CHECKING_ENABLE
831 FSP_ASSERT(count <= SDHI_PRV_SDIO_EXT_MAX_BYTES);
832 #endif
833 block_count = 1U;
834 byte_count = count;
835 }
836
837 /* Configure the transfer interface for writing. */
838 err = r_sdhi_transfer_write(p_ctrl, block_count, byte_count, p_source);
839 FSP_ERROR_RETURN(FSP_SUCCESS == err, FSP_ERR_WRITE_FAILED);
840
841 sdmmc_priv_sdio_arg_t argument = {0U};
842
843 /* According to SDIO spec, 512 = 0. */
844 argument.cmd_53_arg.count = (count & SDHI_PRV_SDIO_CMD52_CMD53_COUNT_MASK);
845 argument.cmd_53_arg.function_number = (function & SDHI_PRV_SDIO_CMD52_CMD53_FUNCTION_MASK);
846 argument.cmd_53_arg.block_mode = transfer_mode;
847 argument.cmd_53_arg.op_code = address_mode;
848 argument.cmd_53_arg.register_address = (address & SDHI_PRV_SDIO_CMD52_CMD53_ADDRESS_MASK);
849 argument.cmd_53_arg.rw_flag = 1U;
850 r_sdhi_read_write_common(p_ctrl, block_count, byte_count, command, argument.arg);
851
852 return FSP_SUCCESS;
853 #else
854 FSP_PARAMETER_NOT_USED(p_api_ctrl);
855 FSP_PARAMETER_NOT_USED(p_source);
856 FSP_PARAMETER_NOT_USED(function);
857 FSP_PARAMETER_NOT_USED(address);
858 FSP_PARAMETER_NOT_USED(count);
859 FSP_PARAMETER_NOT_USED(transfer_mode);
860 FSP_PARAMETER_NOT_USED(address_mode);
861
862 FSP_RETURN(FSP_ERR_UNSUPPORTED);
863 #endif
864 }
865
866 /*******************************************************************************************************************//**
867 * Enables or disables the SDIO Interrupt. Implements @ref sdmmc_api_t::ioIntEnable().
868 *
869 * @retval FSP_SUCCESS Card enabled or disabled SDIO interrupts successfully.
870 * @retval FSP_ERR_NOT_OPEN Driver has not been initialized.
871 * @retval FSP_ERR_ASSERTION NULL pointer.
872 * @retval FSP_ERR_DEVICE_BUSY Driver is busy with a previous operation.
873 * @retval FSP_ERR_UNSUPPORTED SDIO support disabled in SDHI_CFG_SDIO_SUPPORT_ENABLE.
874 **********************************************************************************************************************/
R_SDHI_IoIntEnable(sdmmc_ctrl_t * const p_api_ctrl,bool enable)875 fsp_err_t R_SDHI_IoIntEnable (sdmmc_ctrl_t * const p_api_ctrl, bool enable)
876 {
877 #if SDHI_CFG_SDIO_SUPPORT_ENABLE
878 sdhi_instance_ctrl_t * p_ctrl = (sdhi_instance_ctrl_t *) p_api_ctrl;
879
880 #if SDHI_CFG_PARAM_CHECKING_ENABLE
881 FSP_ASSERT(NULL != p_ctrl);
882
883 FSP_ERROR_RETURN(SDHI_PRV_OPEN == p_ctrl->open, FSP_ERR_NOT_OPEN);
884 #endif
885
886 /* Make sure the card is not busy. */
887 FSP_ERROR_RETURN(SDHI_PRV_SD_INFO2_CBSY_SDD0MON_IDLE_VAL ==
888 (p_ctrl->p_reg->SD_INFO2 & SDHI_PRV_SD_INFO2_CBSY_SDD0MON_IDLE_MASK),
889 FSP_ERR_DEVICE_BUSY);
890
891 /* Enable or disable interrupt. */
892 if (enable)
893 {
894 p_ctrl->p_reg->SDIO_MODE = 1U;
895 p_ctrl->p_reg->SDIO_INFO1_MASK = 0x6U;
896 }
897 else
898 {
899 p_ctrl->p_reg->SDIO_MODE = 0U;
900 p_ctrl->p_reg->SDIO_INFO1_MASK = SDHI_PRV_SDIO_INFO1_MASK_IRQ_DISABLE;
901 }
902
903 return FSP_SUCCESS;
904 #else
905 FSP_PARAMETER_NOT_USED(p_api_ctrl);
906 FSP_PARAMETER_NOT_USED(enable);
907
908 FSP_RETURN(FSP_ERR_UNSUPPORTED);
909 #endif
910 }
911
912 /*******************************************************************************************************************//**
913 * Provides driver status. Implements @ref sdmmc_api_t::statusGet().
914 *
915 * @retval FSP_SUCCESS Status stored in p_status.
916 * @retval FSP_ERR_ASSERTION NULL pointer.
917 * @retval FSP_ERR_NOT_OPEN Driver has not been initialized.
918 **********************************************************************************************************************/
R_SDHI_StatusGet(sdmmc_ctrl_t * const p_api_ctrl,sdmmc_status_t * const p_status)919 fsp_err_t R_SDHI_StatusGet (sdmmc_ctrl_t * const p_api_ctrl, sdmmc_status_t * const p_status)
920 {
921 sdhi_instance_ctrl_t * p_ctrl = (sdhi_instance_ctrl_t *) p_api_ctrl;
922
923 #if SDHI_CFG_PARAM_CHECKING_ENABLE
924
925 /* Check pointers for NULL values */
926 FSP_ASSERT(NULL != p_ctrl);
927 FSP_ASSERT(NULL != p_status);
928
929 FSP_ERROR_RETURN(SDHI_PRV_OPEN == p_ctrl->open, FSP_ERR_NOT_OPEN);
930 #endif
931
932 /* Check CD pin. */
933 if (SDMMC_CARD_DETECT_CD == p_ctrl->p_cfg->card_detect)
934 {
935 p_status->card_inserted = p_ctrl->p_reg->SD_INFO1_b.SDCDMON;
936 }
937 else
938 {
939 p_status->card_inserted = true;
940 }
941
942 /* Whether or not the media is initialized. */
943 p_status->initialized = p_ctrl->initialized;
944
945 /* Check if the card is busy. */
946 p_status->transfer_in_progress =
947 (SDHI_PRV_SD_INFO2_CBSY_SDD0MON_IDLE_VAL !=
948 (p_ctrl->p_reg->SD_INFO2 & SDHI_PRV_SD_INFO2_CBSY_SDD0MON_IDLE_MASK));
949
950 return FSP_SUCCESS;
951 }
952
953 /*******************************************************************************************************************//**
954 * Erases sectors of an SD card or eMMC device. Implements @ref sdmmc_api_t::erase().
955 *
956 * This function blocks until the erase command is sent. Poll the status to determine when erase is complete.
957 *
958 * @retval FSP_SUCCESS Erase operation requested.
959 * @retval FSP_ERR_ASSERTION A required pointer is NULL or an argument is invalid.
960 * @retval FSP_ERR_NOT_OPEN Driver has not been initialized.
961 * @retval FSP_ERR_CARD_NOT_INITIALIZED Card was unplugged.
962 * @retval FSP_ERR_CARD_WRITE_PROTECTED SD card is Write Protected.
963 * @retval FSP_ERR_RESPONSE Device responded with an error.
964 * @retval FSP_ERR_TIMEOUT Device did not respond.
965 * @retval FSP_ERR_DEVICE_BUSY Device is holding DAT0 low (device is busy) or another operation is
966 * ongoing.
967 **********************************************************************************************************************/
R_SDHI_Erase(sdmmc_ctrl_t * const p_api_ctrl,uint32_t const start_sector,uint32_t const sector_count)968 fsp_err_t R_SDHI_Erase (sdmmc_ctrl_t * const p_api_ctrl, uint32_t const start_sector, uint32_t const sector_count)
969 {
970 sdhi_instance_ctrl_t * p_ctrl = (sdhi_instance_ctrl_t *) p_api_ctrl;
971
972 fsp_err_t err = FSP_SUCCESS;
973 uint32_t start_address;
974 uint32_t end_address;
975 uint32_t start_command;
976 uint32_t end_command;
977 uint32_t argument;
978
979 err = r_sdhi_erase_error_check(p_ctrl, start_sector, sector_count);
980 FSP_ERROR_RETURN(FSP_SUCCESS == err, err);
981
982 /* SDHC, SDXC and eMMC high capacity media use block addressing. */
983 if (true == p_ctrl->sector_addressing)
984 {
985 start_address = start_sector;
986 end_address = ((start_sector + sector_count) - 1);
987 }
988 else
989 {
990 start_address = (start_sector * p_ctrl->p_cfg->block_size);
991 end_address = ((start_sector + sector_count) * p_ctrl->p_cfg->block_size) - 1U;
992 }
993
994 #if SDHI_CFG_EMMC_SUPPORT_ENABLE
995 if (SDMMC_CARD_TYPE_MMC == p_ctrl->device.card_type)
996 {
997 start_command = SDHI_PRV_CMD_TAG_ERASE_GROUP_START;
998 end_command = SDHI_PRV_CMD_TAG_ERASE_GROUP_END;
999 argument = SDHI_PRV_EMMC_ERASE_ARGUMENT_TRIM;
1000 }
1001 else
1002 #endif
1003 {
1004 start_command = SDHI_PRV_CMD_ERASE_WR_BLK_START;
1005 end_command = SDHI_PRV_CMD_ERASE_WR_BLK_END;
1006 argument = 0U; // Argument unused for SD
1007 }
1008
1009 /* Send command to set start erase address (CMD35 for eMMC, CMD32 for SD). */
1010 err = r_sdhi_command_send(p_ctrl, start_command, start_address);
1011 FSP_ERROR_RETURN(FSP_SUCCESS == err, err);
1012
1013 /* Send command to set end erase address (CMD36 for eMMC, CMD33 for SD). */
1014 err = r_sdhi_command_send(p_ctrl, end_command, end_address);
1015 FSP_ERROR_RETURN(FSP_SUCCESS == err, err);
1016
1017 /* Send erase command (CMD38). */
1018 r_sdhi_command_send_no_wait(p_ctrl, SDHI_PRV_CMD_ERASE, argument);
1019
1020 return FSP_SUCCESS;
1021 }
1022
1023 /*******************************************************************************************************************//**
1024 * Updates the user callback with the option to provide memory for the callback argument structure.
1025 * Implements @ref sdmmc_api_t::callbackSet.
1026 *
1027 * @retval FSP_SUCCESS Callback updated successfully.
1028 * @retval FSP_ERR_ASSERTION A required pointer is NULL.
1029 * @retval FSP_ERR_NOT_OPEN The control block has not been opened.
1030 * @retval FSP_ERR_NO_CALLBACK_MEMORY p_callback is non-secure and p_callback_memory is either secure or NULL.
1031 **********************************************************************************************************************/
R_SDHI_CallbackSet(sdmmc_ctrl_t * const p_api_ctrl,void (* p_callback)(sdmmc_callback_args_t *),void const * const p_context,sdmmc_callback_args_t * const p_callback_memory)1032 fsp_err_t R_SDHI_CallbackSet (sdmmc_ctrl_t * const p_api_ctrl,
1033 void ( * p_callback)(sdmmc_callback_args_t *),
1034 void const * const p_context,
1035 sdmmc_callback_args_t * const p_callback_memory)
1036 {
1037 sdhi_instance_ctrl_t * p_ctrl = (sdhi_instance_ctrl_t *) p_api_ctrl;
1038
1039 #if SDHI_CFG_PARAM_CHECKING_ENABLE
1040 FSP_ASSERT(p_ctrl);
1041 FSP_ASSERT(p_callback);
1042 FSP_ERROR_RETURN(SDHI_PRV_OPEN == p_ctrl->open, FSP_ERR_NOT_OPEN);
1043 #endif
1044
1045 #if BSP_TZ_SECURE_BUILD
1046
1047 /* Get security state of p_callback */
1048 bool callback_is_secure =
1049 (NULL == cmse_check_address_range((void *) p_callback, sizeof(void *), CMSE_AU_NONSECURE));
1050
1051 #if SDHI_CFG_PARAM_CHECKING_ENABLE
1052
1053 /* In secure projects, p_callback_memory must be provided in non-secure space if p_callback is non-secure */
1054 sdmmc_callback_args_t * const p_callback_memory_checked = cmse_check_pointed_object(p_callback_memory,
1055 CMSE_AU_NONSECURE);
1056 FSP_ERROR_RETURN(callback_is_secure || (NULL != p_callback_memory_checked), FSP_ERR_NO_CALLBACK_MEMORY);
1057 #endif
1058 #endif
1059
1060 /* Store callback and context */
1061 #if BSP_TZ_SECURE_BUILD
1062 p_ctrl->p_callback = callback_is_secure ? p_callback :
1063 (void (*)(sdmmc_callback_args_t *))cmse_nsfptr_create(p_callback);
1064 #else
1065 p_ctrl->p_callback = p_callback;
1066 #endif
1067 p_ctrl->p_context = p_context;
1068 p_ctrl->p_callback_memory = p_callback_memory;
1069
1070 return FSP_SUCCESS;
1071 }
1072
1073 /*******************************************************************************************************************//**
1074 * Closes an open SD/MMC device. Implements @ref sdmmc_api_t::close().
1075 *
1076 * @retval FSP_SUCCESS Successful close.
1077 * @retval FSP_ERR_ASSERTION The parameter p_ctrl is NULL.
1078 * @retval FSP_ERR_NOT_OPEN Driver has not been initialized.
1079 **********************************************************************************************************************/
R_SDHI_Close(sdmmc_ctrl_t * const p_api_ctrl)1080 fsp_err_t R_SDHI_Close (sdmmc_ctrl_t * const p_api_ctrl)
1081 {
1082 sdhi_instance_ctrl_t * p_ctrl = (sdhi_instance_ctrl_t *) p_api_ctrl;
1083
1084 #if SDHI_CFG_PARAM_CHECKING_ENABLE
1085 FSP_ASSERT(NULL != p_ctrl);
1086
1087 FSP_ERROR_RETURN(SDHI_PRV_OPEN == p_ctrl->open, FSP_ERR_NOT_OPEN);
1088 #endif
1089
1090 p_ctrl->open = 0U;
1091
1092 /* Disable SDHI interrupts. */
1093 r_sdhi_irq_disable(p_ctrl->p_cfg->access_irq);
1094 r_sdhi_irq_disable(p_ctrl->p_cfg->card_irq);
1095 r_sdhi_irq_disable(p_ctrl->p_cfg->sdio_irq);
1096
1097 /* Put the card in idle state (CMD0). */
1098 r_sdhi_command_send_no_wait(p_ctrl, SDHI_PRV_CMD_GO_IDLE_STATE, 0);
1099
1100 /* Close the transfer driver. */
1101 p_ctrl->p_cfg->p_lower_lvl_transfer->p_api->close(p_ctrl->p_cfg->p_lower_lvl_transfer->p_ctrl);
1102
1103 /* Do not set the module stop bit since the CMD0 may not be complete yet. Do not wait for CMD0 to complete because
1104 * the card could be unplugged and waiting for the response timeout in this function is not desireable. */
1105
1106 return FSP_SUCCESS;
1107 }
1108
1109 /*******************************************************************************************************************//**
1110 * @} (end addtogroup SDMMC)
1111 **********************************************************************************************************************/
1112
1113 /***********************************************************************************************************************
1114 * Private Functions
1115 **********************************************************************************************************************/
1116
1117 #if SDHI_CFG_PARAM_CHECKING_ENABLE
1118
1119 /*******************************************************************************************************************//**
1120 * Parameter checking for the open function.
1121 *
1122 * @param[in] p_ctrl Pointer to the instance control block.
1123 * @param[in] p_cfg Pointer to the instance configuration structure.
1124 *
1125 * @retval FSP_SUCCESS Parameters to open() are in the valid range.
1126 * @retval FSP_ERR_ASSERTION A required input pointer is NULL, or the block size is 0 or > 512 bytes.
1127 * @retval FSP_ERR_ALREADY_OPEN Driver has already been opened with this instance of the control
1128 * structure.
1129 * @retval FSP_ERR_IP_CHANNEL_NOT_PRESENT Requested channel does not exist on this MCU.
1130 * @retval FSP_ERR_IRQ_BSP_DISABLED Access interrupt is not enabled.
1131 **********************************************************************************************************************/
r_sdhi_open_param_check(sdhi_instance_ctrl_t * p_ctrl,sdmmc_cfg_t const * const p_cfg)1132 static fsp_err_t r_sdhi_open_param_check (sdhi_instance_ctrl_t * p_ctrl, sdmmc_cfg_t const * const p_cfg)
1133 {
1134 FSP_ASSERT(NULL != p_ctrl);
1135 FSP_ASSERT(NULL != p_cfg);
1136 FSP_ASSERT(NULL != p_cfg->p_lower_lvl_transfer);
1137 FSP_ERROR_RETURN(SDHI_PRV_OPEN != p_ctrl->open, FSP_ERR_ALREADY_OPEN);
1138
1139 /* Verify the requested channel exists on the MCU. */
1140 FSP_ERROR_RETURN(0U != ((1U << p_cfg->channel) & BSP_FEATURE_SDHI_VALID_CHANNEL_MASK),
1141 FSP_ERR_IP_CHANNEL_NOT_PRESENT);
1142
1143 /* Some MCUs don't support card detection. */
1144 #if !BSP_FEATURE_SDHI_HAS_CARD_DETECTION
1145 FSP_ASSERT(SDMMC_CARD_DETECT_NONE == p_cfg->card_detect);
1146 #endif
1147
1148 /* Some MCUs don't support 8-bit MMC. */
1149 #if !BSP_FEATURE_SDHI_SUPPORTS_8_BIT_MMC
1150 FSP_ASSERT(SDMMC_BUS_WIDTH_8_BITS != p_cfg->bus_width);
1151 #endif
1152
1153 #if SDHI_CFG_SDIO_SUPPORT_ENABLE
1154
1155 /* Check block size, 512 bytes is the maximum block size the peripheral supports */
1156 FSP_ASSERT(0U != p_cfg->block_size);
1157 FSP_ASSERT(p_cfg->block_size <= SDHI_MAX_BLOCK_SIZE);
1158 #else
1159
1160 /* SD and eMMC cards only support block size of 512 bytes on the SDHI hardware. */
1161 /* This can't be checked until we know it's not an SDIO card if SDIO is enabled. */
1162 FSP_ASSERT(SDHI_MAX_BLOCK_SIZE == p_cfg->block_size);
1163 #endif
1164
1165 /* Access interrupt is required. */
1166 FSP_ERROR_RETURN(p_cfg->access_irq >= 0, FSP_ERR_IRQ_BSP_DISABLED);
1167
1168 return FSP_SUCCESS;
1169 }
1170
1171 #endif
1172
1173 /*******************************************************************************************************************//**
1174 * Parameter checking for erase.
1175 *
1176 * @param[in] p_ctrl Pointer to the instance control block.
1177 * @param[in] start_sector First sector to write
1178 * @param[in] sector_count Number of sectors to write
1179 *
1180 * @retval FSP_SUCCESS Erase operation requested.
1181 * @retval FSP_ERR_ASSERTION A required pointer is NULL or an argument is invalid.
1182 * @retval FSP_ERR_NOT_OPEN Driver has not been initialized.
1183 * @retval FSP_ERR_CARD_NOT_INITIALIZED Card was unplugged.
1184 * @retval FSP_ERR_DEVICE_BUSY Driver is busy with a previous operation.
1185 * @retval FSP_ERR_CARD_WRITE_PROTECTED SD card is Write Protected.
1186 **********************************************************************************************************************/
r_sdhi_erase_error_check(sdhi_instance_ctrl_t * const p_ctrl,uint32_t const start_sector,uint32_t const sector_count)1187 static fsp_err_t r_sdhi_erase_error_check (sdhi_instance_ctrl_t * const p_ctrl,
1188 uint32_t const start_sector,
1189 uint32_t const sector_count)
1190 {
1191 fsp_err_t err = r_sdhi_common_error_check(p_ctrl);
1192 FSP_ERROR_RETURN(FSP_SUCCESS == err, err);
1193
1194 #if SDHI_CFG_PARAM_CHECKING_ENABLE
1195
1196 /* Check for valid sector count. Must be a non-zero multiple of erase_sector_count. */
1197
1198 FSP_ASSERT(0U != sector_count);
1199 FSP_ASSERT(0U == (sector_count % p_ctrl->device.erase_sector_count));
1200
1201 /* Check for valid start sector. Must be a multiple of erase_sector_count. */
1202 FSP_ASSERT(0U == (start_sector % p_ctrl->device.erase_sector_count));
1203 #else
1204 FSP_PARAMETER_NOT_USED(start_sector);
1205 FSP_PARAMETER_NOT_USED(sector_count);
1206 #endif
1207
1208 /* Check for write protection */
1209 FSP_ERROR_RETURN(!p_ctrl->device.write_protected, FSP_ERR_CARD_WRITE_PROTECTED);
1210
1211 return FSP_SUCCESS;
1212 }
1213
1214 /*******************************************************************************************************************//**
1215 * Parameter checking for runtime APIs.
1216 *
1217 * @param[in] p_ctrl Pointer to the instance control block.
1218 *
1219 * @retval FSP_SUCCESS Device is ready to be accessed.
1220 * @retval FSP_ERR_ASSERTION A required pointer is NULL.
1221 * @retval FSP_ERR_NOT_OPEN Driver has not been initialized.
1222 * @retval FSP_ERR_CARD_NOT_INITIALIZED Card was unplugged.
1223 * @retval FSP_ERR_DEVICE_BUSY Driver is busy with a previous operation.
1224 **********************************************************************************************************************/
r_sdhi_common_error_check(sdhi_instance_ctrl_t * const p_ctrl)1225 static fsp_err_t r_sdhi_common_error_check (sdhi_instance_ctrl_t * const p_ctrl)
1226 {
1227 #if SDHI_CFG_PARAM_CHECKING_ENABLE
1228 FSP_ASSERT(NULL != p_ctrl);
1229 FSP_ERROR_RETURN(SDHI_PRV_OPEN == p_ctrl->open, FSP_ERR_NOT_OPEN);
1230 #endif
1231
1232 /* To verify no command sequence is in progress in SDHI, verify SD_INFO2.CBSY is not set. To verify the card has
1233 * completed the requested operation, verify SD_INFO2.SDD0MON is set. */
1234 FSP_ERROR_RETURN(SDHI_PRV_SD_INFO2_CBSY_SDD0MON_IDLE_VAL ==
1235 (p_ctrl->p_reg->SD_INFO2 & SDHI_PRV_SD_INFO2_CBSY_SDD0MON_IDLE_MASK),
1236 FSP_ERR_DEVICE_BUSY);
1237
1238 #if SDHI_CFG_SD_SUPPORT_ENABLE || SDHI_CFG_SDIO_SUPPORT_ENABLE
1239
1240 /* Verify the card has not been removed since the last card initialization. */
1241 FSP_ERROR_RETURN(p_ctrl->initialized, FSP_ERR_CARD_NOT_INITIALIZED);
1242 #endif
1243
1244 return FSP_SUCCESS;
1245 }
1246
1247 /*******************************************************************************************************************//**
1248 * Configures and enables an interrupt.
1249 *
1250 * @param[in] irq Interrupt number.
1251 * @param[in] priority NVIC priority of the interrupt
1252 * @param[in] p_context Pointer to data required in the ISR.
1253 **********************************************************************************************************************/
r_sdhi_irq_enable(IRQn_Type irq,uint8_t priority,void * p_context)1254 static void r_sdhi_irq_enable (IRQn_Type irq, uint8_t priority, void * p_context)
1255 {
1256 if (irq >= 0)
1257 {
1258 R_BSP_IrqCfgEnable(irq, priority, p_context);
1259 }
1260 }
1261
1262 /*******************************************************************************************************************//**
1263 * Disables an interrupt.
1264 *
1265 * @param[in] irq Interrupt to disable.
1266 **********************************************************************************************************************/
r_sdhi_irq_disable(IRQn_Type irq)1267 static void r_sdhi_irq_disable (IRQn_Type irq)
1268 {
1269 if (irq >= 0)
1270 {
1271 /* Disables interrupts in the NVIC. */
1272 R_BSP_IrqDisable(irq);
1273
1274 /* Clears the control block from the vector information array. */
1275 R_FSP_IsrContextSet(irq, NULL);
1276 }
1277 }
1278
1279 /*******************************************************************************************************************//**
1280 * Stores access interrupt flags in the control block and calls the callback.
1281 *
1282 * @param[in] p_ctrl Pointer to the instance control block.
1283 * @param[in] p_args Pointer to SDMMC callback arguments.
1284 **********************************************************************************************************************/
r_sdhi_access_irq_process(sdhi_instance_ctrl_t * p_ctrl,sdmmc_callback_args_t * p_args)1285 static void r_sdhi_access_irq_process (sdhi_instance_ctrl_t * p_ctrl, sdmmc_callback_args_t * p_args)
1286 {
1287 uint32_t info1;
1288 uint32_t info2;
1289 sdhi_event_t flags;
1290
1291 /* Clear stop register after access end. */
1292 p_ctrl->p_reg->SD_STOP_b.STP = 0U;
1293
1294 /* Read interrupt flag registers. */
1295 info1 = p_ctrl->p_reg->SD_INFO1;
1296 info2 = p_ctrl->p_reg->SD_INFO2;
1297
1298 /* Clear interrupt flags processed in this ISR. */
1299 info1 &= SDHI_PRV_SDHI_INFO1_ACCESS_MASK;
1300 info2 &= SDHI_PRV_SDHI_INFO2_MASK;
1301 p_ctrl->p_reg->SD_INFO1 = (~info1);
1302 p_ctrl->p_reg->SD_INFO2 = (~info2);
1303
1304 /* Combine all flags in one 32 bit word. */
1305 flags.word = (info1 | (info2 << 16));
1306
1307 if (flags.bit.response_end)
1308 {
1309 p_args->event |= SDMMC_EVENT_RESPONSE;
1310
1311 /* Check the R1 response. */
1312 if (1U == p_ctrl->p_reg->SD_STOP_b.SEC)
1313 {
1314 /* Get the R1 response for multiple block read and write from SD_RSP54 since the response in SD_RSP10 may
1315 * have been overwritten by the response to CMD12. */
1316 p_args->response.status = p_ctrl->p_reg->SD_RSP54;
1317 }
1318 else
1319 {
1320 p_args->response.status = p_ctrl->p_reg->SD_RSP10;
1321 }
1322
1323 if (SDHI_PRV_CMD_ERASE == p_ctrl->p_reg->SD_CMD)
1324 {
1325 /* Determine if erase is complete or not based on DAT0. Access interrupt is not required for erase. */
1326 if (SDHI_PRV_SD_INFO2_CBSY_SDD0MON_IDLE_VAL ==
1327 (p_ctrl->p_reg->SD_INFO2 & SDHI_PRV_SD_INFO2_CBSY_SDD0MON_IDLE_MASK))
1328 {
1329 p_args->event |= SDMMC_EVENT_ERASE_COMPLETE;
1330 }
1331 else
1332 {
1333 p_args->event |= SDMMC_EVENT_ERASE_BUSY;
1334 }
1335 }
1336 else
1337 {
1338 /* Enable the access interrupt. */
1339 /* Disable response end interrupt (set the bit) and enable access end interrupt (clear the bit). */
1340 uint32_t mask = p_ctrl->p_reg->SD_INFO1_MASK;
1341 mask &= (~SDHI_PRV_SDHI_INFO1_ACCESS_END);
1342 mask |= SDHI_PRV_SDHI_INFO1_RESPONSE_END;
1343 p_ctrl->p_reg->SD_INFO1_MASK = mask;
1344 }
1345 }
1346
1347 /* Check for errors */
1348 if (flags.word & SDHI_PRV_ACCESS_ERROR_MASK)
1349 {
1350 flags.bit.event_error = 1U;
1351 p_args->event |= SDMMC_EVENT_TRANSFER_ERROR;
1352 p_ctrl->p_reg->SD_STOP = 1U;
1353
1354 /* Disable the transfer and clear related variables since an error occurred. */
1355 r_sdhi_transfer_end(p_ctrl);
1356 }
1357 else
1358 {
1359 /* Check for access end */
1360 if (flags.bit.access_end)
1361 {
1362 /* All aligned transfers end here. Unaligned write transfers also end here. Unaligned read transfers end
1363 * in the transfer callback. */
1364 if (SDHI_TRANSFER_DIR_READ != p_ctrl->transfer_dir)
1365 {
1366 /* Disable the transfer and clear related variables since the transfer is complete. */
1367 r_sdhi_transfer_end(p_ctrl);
1368 p_args->event |= SDMMC_EVENT_TRANSFER_COMPLETE;
1369 }
1370 }
1371 }
1372
1373 /* Combine all events for each command because this flag is polled in some functions. */
1374 p_ctrl->sdhi_event.word |= flags.word;
1375 }
1376
1377 /*******************************************************************************************************************//**
1378 * Send a command to the SD, eMMC, or SDIO device.
1379 *
1380 * @param[in] p_ctrl Pointer to the instance control block.
1381 * @param[in] command Command to send.
1382 * @param[in] argument Argument to send with the command.
1383 **********************************************************************************************************************/
r_sdhi_command_send_no_wait(sdhi_instance_ctrl_t * p_ctrl,uint32_t command,uint32_t argument)1384 void r_sdhi_command_send_no_wait (sdhi_instance_ctrl_t * p_ctrl, uint32_t command, uint32_t argument)
1385 {
1386 /* Clear Status */
1387 p_ctrl->p_reg->SD_INFO1 = 0U;
1388 p_ctrl->p_reg->SD_INFO2 = 0U;
1389 p_ctrl->sdhi_event.word = 0U;
1390
1391 /* Enable response end interrupt. */
1392 /* Disable access end interrupt and enable response end interrupt. */
1393 uint32_t mask = p_ctrl->p_reg->SD_INFO1_MASK;
1394 mask &= (~SDHI_PRV_SDHI_INFO1_RESPONSE_END);
1395 mask |= SDHI_PRV_SDHI_INFO1_ACCESS_END;
1396 p_ctrl->p_reg->SD_INFO1_MASK = mask;
1397 p_ctrl->p_reg->SD_INFO2_MASK = SDHI_PRV_SDHI_INFO2_MASK_CMD_SEND;
1398
1399 /* Enable Clock */
1400 p_ctrl->p_reg->SD_CLK_CTRL |= SDHI_PRV_SDHI_PRV_SD_CLK_AUTO_CLOCK_ENABLE_MASK;
1401
1402 /* Write argument, then command to the SDHI peripheral. */
1403 p_ctrl->p_reg->SD_ARG = argument & UINT16_MAX;
1404 p_ctrl->p_reg->SD_ARG1 = argument >> 16;
1405 p_ctrl->p_reg->SD_CMD = command;
1406 }
1407
1408 /*******************************************************************************************************************//**
1409 * Send a command to the SD, eMMC, or SDIO device and wait for response
1410 *
1411 * @param[in] p_ctrl Pointer to the instance control block.
1412 * @param[in] command Command to send.
1413 * @param[in] argument Argument to send with the command.
1414 *
1415 * @retval FSP_SUCCESS Command sent and response received, no errors in response.
1416 * @retval FSP_ERR_RESPONSE Device responded with an error.
1417 * @retval FSP_ERR_TIMEOUT Device did not respond.
1418 * @retval FSP_ERR_DEVICE_BUSY Device is holding DAT0 low (device is busy) or another operation is ongoing.
1419 **********************************************************************************************************************/
r_sdhi_command_send(sdhi_instance_ctrl_t * p_ctrl,uint32_t command,uint32_t argument)1420 fsp_err_t r_sdhi_command_send (sdhi_instance_ctrl_t * p_ctrl, uint32_t command, uint32_t argument)
1421 {
1422 /* Verify the device is not busy. */
1423 r_sdhi_wait_for_device(p_ctrl);
1424
1425 /* Send the command. */
1426 r_sdhi_command_send_no_wait(p_ctrl, command, argument);
1427
1428 /* Wait for end of response, error or timeout */
1429 return r_sdhi_wait_for_event(p_ctrl, SDHI_PRV_RESPONSE_BIT, SDHI_PRV_RESPONSE_TIMEOUT_US);
1430 }
1431
1432 /*******************************************************************************************************************//**
1433 * Set the SD clock to a rate less than or equal to the requested maximum rate.
1434 *
1435 * @param[in] p_ctrl Pointer to the instance control block.
1436 * @param[in] max_rate Maximum SD clock rate to set
1437 *
1438 * @retval FSP_SUCCESS SD clock rate is less than or equal to the requested maximum rate.
1439 * @retval FSP_ERR_CARD_INIT_FAILED Timeout setting divider or operation is still too fast at maximum divider
1440 * (unlikely).
1441 **********************************************************************************************************************/
r_sdhi_max_clock_rate_set(sdhi_instance_ctrl_t * p_ctrl,uint32_t max_rate)1442 fsp_err_t r_sdhi_max_clock_rate_set (sdhi_instance_ctrl_t * p_ctrl, uint32_t max_rate)
1443 {
1444 uint32_t setting = SDHI_PRV_CLK_CTRL_DIV_INVALID;
1445
1446 /* Get the runtime frequency of the source of the SD clock */
1447 uint32_t frequency = R_FSP_SystemClockHzGet(BSP_FEATURE_SDHI_CLOCK);
1448
1449 /* Iterate over all possible divisors, starting with the smallest, until the resulting clock rate is less than
1450 * or equal to the requested maximum rate. */
1451 for (uint32_t divisor_shift = BSP_FEATURE_SDHI_MIN_CLOCK_DIVISION_SHIFT;
1452 divisor_shift <= SDHI_PRV_MAX_CLOCK_DIVISION_SHIFT;
1453 divisor_shift++)
1454 {
1455 if ((frequency >> divisor_shift) <= max_rate)
1456 {
1457 /* If the calculated frequency is less than or equal to the maximum supported by the device,
1458 * select this frequency. The register setting is the divisor value divided by 4, or 0xFF for no divider. */
1459 setting = divisor_shift ? ((1U << divisor_shift) >> 2U) : UINT8_MAX;
1460
1461 /* Set the clock setting. */
1462
1463 /* The clock register is accessible 8 SD clock counts after the last command completes. Each register access
1464 * requires at least one PCLK count, so check the register up to 8 times the maximum PCLK divisor value (512). */
1465 uint32_t timeout = SDHI_PRV_SD_CLK_CTRLEN_TIMEOUT;
1466
1467 while (timeout > 0U)
1468 {
1469 /* Do not write to clock control register until this bit is set. */
1470 if (p_ctrl->p_reg->SD_INFO2_b.SD_CLK_CTRLEN)
1471 {
1472 /* Set the calculated divider and enable clock output to start the 74 clocks required before
1473 * initialization. Do not change the automatic clock control setting. */
1474 uint32_t clkctrlen = p_ctrl->p_reg->SD_CLK_CTRL & SDHI_PRV_SDHI_PRV_SD_CLK_CTRL_CLKCTRLEN_MASK;
1475 p_ctrl->p_reg->SD_CLK_CTRL = setting | clkctrlen | SDHI_PRV_SDHI_PRV_SD_CLK_CTRL_CLKEN_MASK;
1476 p_ctrl->device.clock_rate = frequency >> divisor_shift;
1477
1478 return FSP_SUCCESS;
1479 }
1480
1481 timeout--;
1482 }
1483
1484 /* Valid setting already found, stop looking. */
1485 break;
1486 }
1487 }
1488
1489 return FSP_ERR_CARD_INIT_FAILED;
1490 }
1491
1492 /*******************************************************************************************************************//**
1493 * Initializes SD host interface hardware.
1494 *
1495 * @param[in] p_ctrl Pointer to the instance control block.
1496 *
1497 * @retval FSP_SUCCESS Operation completed successfully.
1498 * @retval FSP_ERR_CARD_INIT_FAILED Timeout setting divider or operation is still too fast at maximum divider
1499 * (unlikely).
1500 **********************************************************************************************************************/
r_sdhi_hw_cfg(sdhi_instance_ctrl_t * const p_ctrl)1501 fsp_err_t r_sdhi_hw_cfg (sdhi_instance_ctrl_t * const p_ctrl)
1502 {
1503 /* Reset SDHI. */
1504 p_ctrl->p_reg->SOFT_RST = 0x0U;
1505 p_ctrl->p_reg->SOFT_RST = 0x1U;
1506
1507 /* Execute software reset or check SD_INFO2.SD_CLK_CTRLEN prior to calling this function. */
1508 p_ctrl->p_reg->SD_CLK_CTRL = SDHI_PRV_SD_CLK_CTRL_DEFAULT; // Automatic clock control disabled.
1509 p_ctrl->p_reg->SDIO_MODE = 0x00U; // Not in SDIO mode initially.
1510 p_ctrl->p_reg->SD_DMAEN = 0x00U; // Not in DMA mode initially.
1511 p_ctrl->p_reg->SDIF_MODE = 0x00U; // CRC check is valid.
1512 p_ctrl->p_reg->EXT_SWAP = 0x00U; // Don't swap endianness
1513
1514 /* Set the clock frequency to 400 kHz or less for identification. */
1515 fsp_err_t err = r_sdhi_max_clock_rate_set(p_ctrl, SDHI_PRV_INIT_MAX_CLOCK_RATE_HZ);
1516 FSP_ERROR_RETURN(FSP_SUCCESS == err, err);
1517
1518 /* Set initial bus width to one bit wide. */
1519 p_ctrl->p_reg->SD_OPTION = SDHI_PRV_SD_OPTION_DEFAULT |
1520 (SDHI_PRV_BUS_WIDTH_1_BIT << SDHI_PRV_SD_OPTION_WIDTH8_BIT);
1521
1522 /* The host shall supply at least 74 SD clocks to the SD card while keeping CMD line high. Reference section
1523 * 6.4.1.1 "Power Up Time of Card" in the SD Physical Layer Specification Version 6.00. */
1524 R_BSP_SoftwareDelay(1U, BSP_DELAY_UNITS_MILLISECONDS);
1525
1526 /* Automatic clock control can be enabled only after 74 SD/MMC clock cycles are output. Reference section 43.4.3
1527 * Automatic Control of SD/MMC Clock Output (SD/MMC) of the RA6M3 manual R01UH0886EJ0100. */
1528
1529 return FSP_SUCCESS;
1530 }
1531
1532 /*******************************************************************************************************************//**
1533 * Initializes driver and device.
1534 *
1535 * @param[in] p_ctrl Pointer to the instance control block.
1536 *
1537 * @retval FSP_SUCCESS Operation completed successfully.
1538 * @retval FSP_ERR_CARD_INIT_FAILED Device could not be identified.
1539 * @retval FSP_ERR_ASSERTION Card detection configured but not supported.
1540 * @retval FSP_ERR_RESPONSE Device responded with an error.
1541 * @retval FSP_ERR_TIMEOUT Device did not respond.
1542 * @retval FSP_ERR_DEVICE_BUSY Device is holding DAT0 low (device is busy) or another operation is ongoing.
1543 **********************************************************************************************************************/
r_sdhi_card_identify(sdhi_instance_ctrl_t * const p_ctrl)1544 static fsp_err_t r_sdhi_card_identify (sdhi_instance_ctrl_t * const p_ctrl)
1545 {
1546 #if SDHI_CFG_SDIO_SUPPORT_ENABLE
1547
1548 /* For SDIO, follow the procedure in Figure 3-2 "Card Initialization Flow in SD mode (SDIO Aware Host)" in SDIO
1549 * Simplified Specification Version 3.00. */
1550
1551 /* Reset I/O: In order to reset an I/O only card or the I/O portion of a combo card, use CMD52 to set the RES bit
1552 * in the CCCR (bit 3 of register 6). Reference Table 6-2 "CCCR bit definitions" in SDIO Simplified Specification
1553 * Version 3.00. */
1554 uint8_t data = 1U << 3;
1555 r_sdhi_cmd52(p_ctrl, &data, 0U, 6U, SDMMC_IO_WRITE_MODE_NO_READ, SDHI_PRV_SDIO_CMD52_WRITE);
1556 #endif
1557
1558 /* For SD cards, follow the procedure in Figure 4-1 "SD Memory Card State Diagram (card identification mode" in
1559 * Physical Layer Simplified Specification Version 6.00. */
1560
1561 /* For eMMC devices, follow the procedure in A.6.1 "Bus Initialization" in JEDEC Standard No. 84-B51A. */
1562
1563 /* Put the card in idle state. */
1564 fsp_err_t err = r_sdhi_command_send(p_ctrl, SDHI_PRV_CMD_GO_IDLE_STATE, 0);
1565 FSP_ERROR_RETURN(FSP_SUCCESS == err, err);
1566
1567 #if SDHI_CFG_SDIO_SUPPORT_ENABLE
1568
1569 /* See if the device is SDIO, SD, or eMMC.*/
1570 /* Order matters - Check if the card has SDIO capabilities first (CMD5). */
1571 p_ctrl->device.card_type = (sdmmc_card_type_t) UINT8_MAX;
1572 err = r_sdhi_sdio_check(p_ctrl);
1573 FSP_ERROR_RETURN(FSP_SUCCESS == err, err);
1574 if (SDMMC_CARD_TYPE_SDIO != p_ctrl->device.card_type)
1575 #endif
1576 {
1577 #if SDHI_CFG_SD_SUPPORT_ENABLE || SDHI_CFG_EMMC_SUPPORT_ENABLE
1578 #if SDHI_CFG_SDIO_SUPPORT_ENABLE && SDHI_CFG_PARAM_CHECKING_ENABLE
1579
1580 /* SD and eMMC cards only support block size of 512 bytes on the SDHI hardware. */
1581 /* This can't be checked until we know it's not an SDIO card if SDIO is enabled. */
1582 FSP_ASSERT(SDHI_MAX_BLOCK_SIZE == p_ctrl->p_cfg->block_size);
1583 #endif
1584
1585 #if SDHI_CFG_SD_SUPPORT_ENABLE
1586
1587 /* If the device is not SDIO, check to see if it is an SD memory card (CMD8 + ACMD41).
1588 * NOTE: Not supporting memory on SDIO combo cards. */
1589 err = r_sdhi_sd_card_check(p_ctrl);
1590 FSP_ERROR_RETURN(FSP_SUCCESS == err, err);
1591 if (SDMMC_CARD_TYPE_SD != p_ctrl->device.card_type)
1592 #endif
1593 {
1594 #if SDHI_CFG_EMMC_SUPPORT_ENABLE
1595
1596 /* If the device is not SDIO or SD memory, check to see if it is an eMMC device (CMD1). */
1597 err = r_sdhi_emmc_check(p_ctrl);
1598 FSP_ERROR_RETURN(FSP_SUCCESS == err, err);
1599 #endif
1600 if ((sdmmc_card_type_t) UINT8_MAX == p_ctrl->device.card_type)
1601 {
1602
1603 /* If the device is not identified as SDIO, SD memory card, or eMMC, return an error. */
1604 return FSP_ERR_CARD_INIT_FAILED;
1605 }
1606 }
1607
1608 /* Enter identification state (CMD2). */
1609 err = r_sdhi_command_send(p_ctrl, SDHI_PRV_CMD_ALL_SEND_CID, 0); /* send SD CMD2 */
1610 FSP_ERROR_RETURN(FSP_SUCCESS == err, err);
1611 #endif
1612 }
1613
1614 return FSP_SUCCESS;
1615 }
1616
1617 /*******************************************************************************************************************//**
1618 * Initializes bus clock, block length, and bus width.
1619 *
1620 * @param[in] p_ctrl Pointer to the instance control block.
1621 *
1622 * @retval FSP_SUCCESS Operation completed successfully.
1623 * @retval FSP_ERR_CARD_INIT_FAILED Operation failed.
1624 * @retval FSP_ERR_RESPONSE Device responded with an error.
1625 * @retval FSP_ERR_TIMEOUT Device did not respond.
1626 * @retval FSP_ERR_DEVICE_BUSY Device is holding DAT0 low (device is busy) or another operation is ongoing.
1627 **********************************************************************************************************************/
r_sdhi_bus_cfg(sdhi_instance_ctrl_t * const p_ctrl)1628 static fsp_err_t r_sdhi_bus_cfg (sdhi_instance_ctrl_t * const p_ctrl)
1629 {
1630 /* Get relative card address (CMD3). */
1631 uint32_t rca;
1632 fsp_err_t err = r_sdhi_rca_get(p_ctrl, &rca);
1633 FSP_ERROR_RETURN(FSP_SUCCESS == err, err);
1634
1635 #if SDHI_CFG_SDIO_SUPPORT_ENABLE
1636
1637 /* Set clock rate to highest supported by both host and device. Move card to transfer state during this
1638 * process. */
1639 if (p_ctrl->device.card_type == SDMMC_CARD_TYPE_SDIO)
1640 {
1641 /* Switch to data transfer mode (CMD7). */
1642 err = r_sdhi_command_send(p_ctrl, SDHI_PRV_CMD_SEL_DES_CARD, rca << 16);
1643 FSP_ERROR_RETURN(FSP_SUCCESS == err, err);
1644
1645 /* Set the clock speed to the highest . */
1646 err = r_sdhi_sdio_clock_optimize(p_ctrl);
1647 FSP_ERROR_RETURN(FSP_SUCCESS == err, err);
1648
1649 /* Set bus width.
1650 * Note: Low speed SDIO not supported, so no need to check if 4-bit mode is supported. */
1651 uint8_t bus_width_setting = (uint8_t) p_ctrl->p_cfg->bus_width;
1652 bus_width_setting = ((bus_width_setting >> 1) & 0x03U);
1653 err = r_sdhi_cmd52(p_ctrl,
1654 &bus_width_setting,
1655 0U,
1656 0x07U,
1657 SDMMC_IO_WRITE_READ_AFTER_WRITE,
1658 SDHI_PRV_SDIO_CMD52_WRITE);
1659 FSP_ERROR_RETURN(FSP_SUCCESS == err, err);
1660
1661 uint32_t bus_width_reg = 0U;
1662 if (SDMMC_BUS_WIDTH_1_BIT == p_ctrl->p_cfg->bus_width)
1663 {
1664 bus_width_reg = SDHI_PRV_BUS_WIDTH_1_BIT;
1665 }
1666
1667 p_ctrl->p_reg->SD_OPTION = SDHI_PRV_SD_OPTION_DEFAULT | (bus_width_reg << SDHI_PRV_SD_OPTION_WIDTH8_BIT);
1668
1669 /* Enable SDIO interrupts. Busy flag must be cleared before enabling interrupts. */
1670 p_ctrl->p_reg->SDIO_MODE_b.INTEN = 1U;
1671 p_ctrl->p_reg->SDIO_INFO1_MASK = 0x6U;
1672 }
1673 else
1674 #endif
1675 {
1676 #if SDHI_CFG_SD_SUPPORT_ENABLE || SDHI_CFG_EMMC_SUPPORT_ENABLE
1677
1678 /* Decode CSD register depending on version of card */
1679 sdmmc_priv_csd_reg_t csd_reg;
1680 err = r_sdhi_csd_save(p_ctrl, rca, &csd_reg);
1681 FSP_ERROR_RETURN(FSP_SUCCESS == err, err);
1682
1683 /* Switch to transfer state (CMD7). */
1684 err = r_sdhi_command_send(p_ctrl, SDHI_PRV_CMD_SEL_DES_CARD, rca << 16);
1685 FSP_ERROR_RETURN(FSP_SUCCESS == err, err);
1686
1687 /* Set clock to highest supported frequency. */
1688 err = r_sdhi_clock_optimize(p_ctrl, rca, &csd_reg);
1689 FSP_ERROR_RETURN(FSP_SUCCESS == err, err);
1690
1691 /* Set the block length (CMD16) to 512 bytes. */
1692 err = r_sdhi_command_send(p_ctrl, SDHI_PRV_CMD_SET_BLOCKLEN, p_ctrl->p_cfg->block_size);
1693 FSP_ERROR_RETURN(FSP_SUCCESS == err, err);
1694
1695 /* Set bus width. */
1696 err = r_sdhi_bus_width_set(p_ctrl, rca);
1697 FSP_ERROR_RETURN(FSP_SUCCESS == err, err);
1698 #endif
1699 }
1700
1701 return FSP_SUCCESS;
1702 }
1703
1704 /*******************************************************************************************************************//**
1705 * Read or write data.
1706 *
1707 * @param[in] p_ctrl Pointer to the instance control block.
1708 * @param[in] sector_count Number of sectors to read or write.
1709 * @param[in] sector_size Size of one sector in bytes.
1710 * @param[in] command Command number
1711 * @param[in] argument Argument
1712 **********************************************************************************************************************/
r_sdhi_read_write_common(sdhi_instance_ctrl_t * const p_ctrl,uint32_t sector_count,uint32_t sector_size,uint32_t command,uint32_t argument)1713 void r_sdhi_read_write_common (sdhi_instance_ctrl_t * const p_ctrl,
1714 uint32_t sector_count,
1715 uint32_t sector_size,
1716 uint32_t command,
1717 uint32_t argument)
1718 {
1719 /* Set the sector count. */
1720 if (sector_count > 1U)
1721 {
1722 p_ctrl->p_reg->SD_STOP = SDHI_PRV_SD_STOP_SD_SECCNT_ENABLE;
1723 p_ctrl->p_reg->SD_SECCNT = sector_count;
1724 }
1725 else
1726 {
1727 p_ctrl->p_reg->SD_STOP = 0U;
1728 }
1729
1730 /* Set sector size */
1731 p_ctrl->p_reg->SD_SIZE = sector_size;
1732
1733 /* Send command. */
1734 r_sdhi_command_send_no_wait(p_ctrl, command, argument);
1735 }
1736
1737 #if SDHI_CFG_SDIO_SUPPORT_ENABLE
1738
1739 /*******************************************************************************************************************//**
1740 * Command 52 Write.
1741 *
1742 * @param[in] p_ctrl Pointer to the instance control block.
1743 * @param p_data Pointer to the data
1744 * @param[in] function Function
1745 * @param[in] address Address on device
1746 * @param[in] read_after_write Whether to read after write
1747 * @param[in] command Command (read or write)
1748 *
1749 * @retval FSP_SUCCESS CMD52 sent and response received with no error.
1750 * @retval FSP_ERR_RESPONSE Device responded with an error.
1751 * @retval FSP_ERR_TIMEOUT Device did not respond.
1752 * @retval FSP_ERR_DEVICE_BUSY Device is holding DAT0 low (device is busy) or another operation is ongoing.
1753 **********************************************************************************************************************/
r_sdhi_cmd52(sdhi_instance_ctrl_t * const p_ctrl,uint8_t * const p_data,uint32_t const function,uint32_t const address,sdmmc_io_write_mode_t const read_after_write,uint32_t const command)1754 static fsp_err_t r_sdhi_cmd52 (sdhi_instance_ctrl_t * const p_ctrl,
1755 uint8_t * const p_data,
1756 uint32_t const function,
1757 uint32_t const address,
1758 sdmmc_io_write_mode_t const read_after_write,
1759 uint32_t const command)
1760 {
1761 /* Send Write I/O command. */
1762 sdmmc_priv_sdio_arg_t argument = {0U};
1763 argument.cmd_52_arg.function_number = (function & SDHI_PRV_SDIO_CMD52_CMD53_FUNCTION_MASK);
1764 argument.cmd_52_arg.rw_flag = (command & 1U);
1765 argument.cmd_52_arg.raw = read_after_write;
1766 argument.cmd_52_arg.register_address = (address & SDHI_PRV_SDIO_CMD52_CMD53_ADDRESS_MASK);
1767 argument.cmd_52_arg.data = *p_data;
1768
1769 /* Send CMD52. */
1770 fsp_err_t err = r_sdhi_command_send(p_ctrl, SDHI_PRV_CMD_IO_RW_DIRECT, argument.arg);
1771 FSP_ERROR_RETURN(FSP_SUCCESS == err, err);
1772
1773 /* Store data read from the response. */
1774 sdmmc_response_t response = {0U};
1775 response.status = p_ctrl->p_reg->SD_RSP10;
1776 *p_data = response.r5.read_write_data;
1777
1778 return FSP_SUCCESS;
1779 }
1780
1781 #endif
1782
1783 #if SDHI_CFG_SDIO_SUPPORT_ENABLE
1784
1785 /*******************************************************************************************************************//**
1786 * Check to see if the device is an SDIO card.
1787 *
1788 * @param[in] p_ctrl Pointer to the instance control block.
1789 *
1790 * @retval FSP_SUCCESS Card type is set if the device is an SDIO card.
1791 * @retval FSP_ERR_RESPONSE Device responded with an error.
1792 * @retval FSP_ERR_TIMEOUT Device did not respond.
1793 * @retval FSP_ERR_DEVICE_BUSY Device is holding DAT0 low (device is busy) or another operation is ongoing.
1794 **********************************************************************************************************************/
r_sdhi_sdio_check(sdhi_instance_ctrl_t * const p_ctrl)1795 static fsp_err_t r_sdhi_sdio_check (sdhi_instance_ctrl_t * const p_ctrl)
1796 {
1797 sdmmc_response_t response = {0U};
1798 uint32_t ocr = SDHI_PRV_OCR_VDD_SUPPORTED;
1799
1800 /* Check for SDIO capabilities (CMD5). */
1801 fsp_err_t err = r_sdhi_command_send(p_ctrl, SDHI_PRV_CMD_SDIO, 0x00);
1802 if (FSP_ERR_RESPONSE == err)
1803 {
1804
1805 /* This is not an SDIO card. */
1806 return FSP_SUCCESS;
1807 }
1808
1809 /* Check response of CMD5 (R4). */
1810 response.status = p_ctrl->p_reg->SD_RSP10;
1811 if (response.r4.io_functions)
1812 {
1813 /* If the card supports SDIO, check for the card to be ready for at least one second. */
1814
1815 /* To ensure the 1 second timeout, consider that there are 48 bits in a command, 48 bits
1816 * in a response, and 8 clock cycles minimum between commands, so there are 104 clocks minimum,
1817 * and the maximum clock rate at this point is 400 kHz, so issue the command 400000 / 104
1818 * times to ensure a timeout of at least 1 second. */
1819 for (uint32_t i = 0U; i < SDHI_PRV_INIT_ONE_SECOND_TIMEOUT_ITERATIONS; i++)
1820 {
1821 err = r_sdhi_command_send(p_ctrl, SDHI_PRV_CMD_SDIO, ocr);
1822 FSP_ERROR_RETURN(FSP_SUCCESS == err, err);
1823
1824 /* Get response of CMD5 (R4) */
1825 response.status = p_ctrl->p_reg->SD_RSP10;
1826 if (response.r4.ready)
1827 {
1828 /* SDIO card is ready. */
1829 p_ctrl->device.card_type = SDMMC_CARD_TYPE_SDIO;
1830
1831 return FSP_SUCCESS;
1832 }
1833 }
1834 }
1835
1836 return FSP_SUCCESS;
1837 }
1838
1839 #endif
1840
1841 #if SDHI_CFG_SD_SUPPORT_ENABLE
1842
1843 /*******************************************************************************************************************//**
1844 * Checks to see if the device is an SD card.
1845 *
1846 * @param[in] p_ctrl Pointer to the instance control block.
1847 *
1848 * @retval FSP_SUCCESS Card type is set if the device is an SD card.
1849 * @retval FSP_ERR_RESPONSE Device responded with an error.
1850 * @retval FSP_ERR_TIMEOUT Device did not respond.
1851 * @retval FSP_ERR_DEVICE_BUSY Device is holding DAT0 low (device is busy) or another operation is ongoing.
1852 **********************************************************************************************************************/
r_sdhi_sd_card_check(sdhi_instance_ctrl_t * const p_ctrl)1853 static fsp_err_t r_sdhi_sd_card_check (sdhi_instance_ctrl_t * const p_ctrl)
1854 {
1855 /* CMD8 must be sent before ACMD41. Reference Figure 4-1 "SD Memory Card State Diagram (card identification mode)"
1856 * in the SD Physical Layer Specification Version 6.00. */
1857 uint32_t argument = ((SDHI_PRV_IF_COND_VOLTAGE << 8) | SDHI_PRV_IF_COND_CHECK_PATTERN);
1858 fsp_err_t err = r_sdhi_command_send(p_ctrl, SDHI_PRV_CMD_IF_COND, argument);
1859 if (FSP_ERR_TIMEOUT == err)
1860 {
1861 FSP_RETURN(err);
1862 }
1863
1864 /* An SD card responds to CMD8 by echoing the argument in the R7 response. An eMMC device responds to CMD8 with the
1865 * extended CSD. If the response does not match the argument, return to check if this is an eMMC device. */
1866 sdmmc_response_t response;
1867 response.status = p_ctrl->p_reg->SD_RSP10;
1868
1869 /* CMD8 is not supported by spec V1.X so we have to try CMD41. */
1870 if ((FSP_ERR_RESPONSE == err) || (response.status == argument))
1871 {
1872 /* Try to send ACMD41 for up to 1 second as long as the card is responding and initialization is not complete.
1873 * Returns immediately if the card fails to respond to ACMD41. */
1874
1875 /* To ensure the 1 second timeout, consider that there are 48 bits in a command, 48 bits
1876 * in a response, and 8 clock cycles minimum between commands, so there are 104 clocks minimum,
1877 * and the maximum clock rate at this point is 400 kHz, so issue the command 400000 / 104
1878 * times to ensure a timeout of at least 1 second. */
1879 for (uint32_t i = 0U; i < SDHI_PRV_INIT_ONE_SECOND_TIMEOUT_ITERATIONS; i++)
1880 {
1881 /* Send App Command - CMD55 */
1882 err = r_sdhi_command_send(p_ctrl, SDHI_PRV_CMD_APP_CMD, 0U);
1883 FSP_ERROR_RETURN(FSP_SUCCESS == err, err);
1884
1885 uint32_t ocr = SDHI_PRV_OCR_VDD_SUPPORTED | SDHI_PRV_OCR_CAPACITY_HC;
1886
1887 /* ACMD41 */
1888 err = r_sdhi_command_send(p_ctrl, SDHI_PRV_CMD_C_ACMD | SDHI_PRV_CMD_SD_SEND_OP_COND, ocr);
1889 FSP_ERROR_RETURN(FSP_SUCCESS == err, err);
1890
1891 /* get response of ACMD41 (R3) */
1892 response.status = p_ctrl->p_reg->SD_RSP10;
1893
1894 /* Initialization complete? */
1895 if (response.r3.power_up_status)
1896 {
1897 /* High capacity card ? */
1898 /* 0 = SDSC, 1 = SDHC or SDXC */
1899 p_ctrl->sector_addressing = (response.r3.card_capacity_status > 0U);
1900 p_ctrl->device.card_type = SDMMC_CARD_TYPE_SD;
1901
1902 break;
1903 }
1904 }
1905 }
1906
1907 return FSP_SUCCESS;
1908 }
1909
1910 #endif
1911
1912 #if SDHI_CFG_EMMC_SUPPORT_ENABLE
1913
1914 /*******************************************************************************************************************//**
1915 * Checks to see if the device is an eMMC.
1916 *
1917 * @param[in] p_ctrl Pointer to the instance control block.
1918 *
1919 * @retval FSP_SUCCESS Card type is set if the device is an eMMC card.
1920 * @retval FSP_ERR_RESPONSE Device responded with an error.
1921 * @retval FSP_ERR_TIMEOUT Device did not respond.
1922 * @retval FSP_ERR_DEVICE_BUSY Device is holding DAT0 low (device is busy) or another operation is ongoing.
1923 **********************************************************************************************************************/
r_sdhi_emmc_check(sdhi_instance_ctrl_t * const p_ctrl)1924 static fsp_err_t r_sdhi_emmc_check (sdhi_instance_ctrl_t * const p_ctrl)
1925 {
1926 uint32_t ocr;
1927 sdmmc_response_t response = {0U};
1928 uint32_t capacity;
1929 capacity = SDHI_PRV_OCR_CAPACITY_HC; /* SDHC cards supported */
1930
1931 /* Tries to send CMD1 for up to 1 second as long as the device is responding and initialization is not complete.
1932 * Returns immediately if the device fails to respond to CMD1. */
1933
1934 /* To ensure the 1 second timeout, consider that there are 48 bits in a command, 48 bits in a response, and 8 clock
1935 * cycles minimum between commands, so there are 104 clocks minimum, and the maximum clock rate at this point is 400
1936 * kHz, so issue the command 400000 / 104 times to ensure a timeout of at least 1 second. */
1937 for (uint32_t i = 0U; i < SDHI_PRV_INIT_ONE_SECOND_TIMEOUT_ITERATIONS; i++)
1938 {
1939 /* Format and send cmd: Volt. window is usually 0x00300000 (3.4-3.2v) */
1940 /* SD cards will not respond to CMD1 */
1941 ocr = SDHI_PRV_OCR_VDD_SUPPORTED;
1942 ocr |= capacity;
1943
1944 fsp_err_t err = r_sdhi_command_send(p_ctrl, SDHI_PRV_EMMC_SEND_OP_COND, ocr);
1945 FSP_ERROR_RETURN(FSP_SUCCESS == err, err);
1946
1947 /* get response of CMD1 */
1948 response.status = p_ctrl->p_reg->SD_RSP10;
1949
1950 /* Initialization complete? */
1951 if (response.r3.power_up_status)
1952 {
1953 p_ctrl->sector_addressing = (response.r3.card_capacity_status > 0U);
1954 p_ctrl->device.card_type = SDMMC_CARD_TYPE_MMC;
1955
1956 return FSP_SUCCESS;
1957 }
1958 }
1959
1960 return FSP_SUCCESS;
1961 }
1962
1963 #endif
1964
1965 #if SDHI_CFG_SD_SUPPORT_ENABLE
1966
1967 /*******************************************************************************************************************//**
1968 * Update write protection status in control block.
1969 *
1970 * @param[in] p_ctrl Pointer to the instance control block.
1971 **********************************************************************************************************************/
r_sdhi_write_protect_get(sdhi_instance_ctrl_t * const p_ctrl)1972 static void r_sdhi_write_protect_get (sdhi_instance_ctrl_t * const p_ctrl)
1973 {
1974 /* Update write protection status in the control block if the device is a card. */
1975 if (p_ctrl->p_cfg->write_protect)
1976 {
1977 p_ctrl->device.write_protected = (p_ctrl->p_reg->SD_INFO1_b.SDWPMON == 0U);
1978 }
1979 }
1980
1981 #endif
1982
1983 /*******************************************************************************************************************//**
1984 * Wait for the device.
1985 *
1986 * @param[in] p_ctrl Pointer to the instance control block.
1987 *
1988 * @retval FSP_SUCCESS Previous operation is complete, and SDHI is ready for the next operation.
1989 * @retval FSP_ERR_DEVICE_BUSY Device is holding DAT0 low (device is busy) or another operation is ongoing.
1990 **********************************************************************************************************************/
r_sdhi_wait_for_device(sdhi_instance_ctrl_t * const p_ctrl)1991 fsp_err_t r_sdhi_wait_for_device (sdhi_instance_ctrl_t * const p_ctrl)
1992 {
1993 /* Wait for the device to stop holding DAT0 low. */
1994 uint32_t timeout = SDHI_PRV_BUSY_TIMEOUT_US;
1995 while (SDHI_PRV_SD_INFO2_CBSY_SDD0MON_IDLE_VAL !=
1996 (p_ctrl->p_reg->SD_INFO2 & SDHI_PRV_SD_INFO2_CBSY_SDD0MON_IDLE_MASK))
1997 {
1998 FSP_ERROR_RETURN(timeout > 0, FSP_ERR_DEVICE_BUSY);
1999
2000 R_BSP_SoftwareDelay(1U, BSP_DELAY_UNITS_MICROSECONDS);
2001 timeout--;
2002 }
2003
2004 return FSP_SUCCESS;
2005 }
2006
2007 #if SDHI_CFG_SD_SUPPORT_ENABLE || SDHI_CFG_EMMC_SUPPORT_ENABLE
2008
2009 /*******************************************************************************************************************//**
2010 * Set SDHI clock to fastest allowable speed for card.
2011 *
2012 * @param[in] p_ctrl Pointer to the instance control block.
2013 * @param[in] rca Relative card address
2014 * @param[in] p_csd_reg Pointer to card specific data.
2015 *
2016 * @retval FSP_SUCCESS Clock rate adjusted to the maximum speed allowed by both device and MCU.
2017 * @retval FSP_ERR_RESPONSE Device responded with an error.
2018 * @retval FSP_ERR_TIMEOUT Device did not respond.
2019 * @retval FSP_ERR_CARD_INIT_FAILED Timeout setting divider or operation is still too fast at maximum divider
2020 * (unlikely).
2021 * @retval FSP_ERR_DEVICE_BUSY Device is holding DAT0 low (device is busy) or another operation is ongoing.
2022 **********************************************************************************************************************/
r_sdhi_clock_optimize(sdhi_instance_ctrl_t * const p_ctrl,uint32_t rca,sdmmc_priv_csd_reg_t * const p_csd_reg)2023 static fsp_err_t r_sdhi_clock_optimize (sdhi_instance_ctrl_t * const p_ctrl,
2024 uint32_t rca,
2025 sdmmc_priv_csd_reg_t * const p_csd_reg)
2026 {
2027 fsp_err_t err = FSP_SUCCESS;
2028
2029 uint32_t max_clock_rate = SDHI_PRV_SD_DEFAULT_CLOCK_RATE;
2030 #if SDHI_CFG_EMMC_SUPPORT_ENABLE
2031 if (SDMMC_CARD_TYPE_MMC == p_ctrl->device.card_type)
2032 {
2033 uint8_t device_type;
2034 err = r_sdhi_csd_extended_get(p_ctrl, rca, &device_type);
2035 FSP_ERROR_RETURN(FSP_SUCCESS == err, err);
2036
2037 max_clock_rate = SDHI_PRV_EMMC_DEFAULT_CLOCK_RATE;
2038 if ((SDHI_PRV_EMMC_HIGH_SPEED_52_MHZ_BIT & device_type) > 0U)
2039 {
2040 /* 52 MHz high speed supported, switch to this mode (CMD6). */
2041 err = r_sdhi_command_send(p_ctrl, SDHI_PRV_EMMC_CMD_SWITCH_WBUSY, SDHI_PRV_EMMC_HIGH_SPEED_MODE);
2042 FSP_ERROR_RETURN(FSP_SUCCESS == err, err);
2043
2044 max_clock_rate = SDHI_PRV_EMMC_HIGH_SPEED_CLOCK_RATE; // Set clock rate to 52 MHz maximum
2045
2046 /* Device may signal busy after CMD6. Wait for busy to clear. */
2047 r_sdhi_wait_for_device(p_ctrl);
2048 }
2049 }
2050 else
2051 #else
2052 FSP_PARAMETER_NOT_USED(rca);
2053 #endif
2054 {
2055 #if SDHI_CFG_SD_SUPPORT_ENABLE
2056
2057 /* Ask SD card to switch to high speed if CMD6 is supported. CMD6 is supported if bit 10 of the CCC field
2058 * in the CSD is set.*/
2059 if (SDHI_PRV_CSD_REG_CCC_CLASS_10_BIT == (SDHI_PRV_CSD_REG_CCC_CLASS_10_BIT & p_csd_reg->csd_v1_b.ccc))
2060 {
2061 if (FSP_SUCCESS == r_sdhi_sd_high_speed(p_ctrl))
2062 {
2063 max_clock_rate = SDHI_PRV_SD_HIGH_SPEED_CLOCK_RATE; // Set clock rate to 50 MHz maximum
2064 }
2065 }
2066
2067 #else
2068 FSP_PARAMETER_NOT_USED(p_csd_reg);
2069 #endif
2070 }
2071
2072 err = r_sdhi_max_clock_rate_set(p_ctrl, max_clock_rate);
2073 FSP_ERROR_RETURN(FSP_SUCCESS == err, err);
2074
2075 return FSP_SUCCESS;
2076 }
2077
2078 #endif
2079
2080 #if SDHI_CFG_SDIO_SUPPORT_ENABLE
2081
2082 /*******************************************************************************************************************//**
2083 * Checks to see if the SDIO card supports high speed.
2084 *
2085 * @param[in] p_ctrl Pointer to the instance control block.
2086 *
2087 * @retval FSP_SUCCESS Clock settings applied for SDIO.
2088 * @retval FSP_ERR_RESPONSE Device responded with an error.
2089 * @retval FSP_ERR_TIMEOUT Device did not respond.
2090 * @retval FSP_ERR_DEVICE_BUSY Device is holding DAT0 low (device is busy) or another operation is ongoing.
2091 * @retval FSP_ERR_CARD_INIT_FAILED Timeout setting divider or operation is still too fast at maximum divider
2092 * (unlikely).
2093 **********************************************************************************************************************/
r_sdhi_sdio_clock_optimize(sdhi_instance_ctrl_t * const p_ctrl)2094 static fsp_err_t r_sdhi_sdio_clock_optimize (sdhi_instance_ctrl_t * const p_ctrl)
2095 {
2096 fsp_err_t err;
2097 uint8_t data = 0U;
2098
2099 /* Issue CMD52 to set the high speed register. */
2100 data = SDHI_PRV_SDIO_REG_HIGH_SPEED_BIT_EHS;
2101 err = r_sdhi_cmd52(p_ctrl,
2102 &data,
2103 0U,
2104 SDHI_PRV_SDIO_REG_HIGH_SPEED,
2105 SDMMC_IO_WRITE_READ_AFTER_WRITE,
2106 SDHI_PRV_SDIO_CMD52_WRITE);
2107 FSP_ERROR_RETURN(FSP_SUCCESS == err, err);
2108
2109 /* Check to see if high speed mode was successfully enabled. Both EHS and SHS bits must be set. */
2110 uint8_t high_speed_enabled_mask = SDHI_PRV_SDIO_REG_HIGH_SPEED_BIT_EHS | SDHI_PRV_SDIO_REG_HIGH_SPEED_BIT_SHS;
2111 uint32_t max_clock_rate = SDHI_PRV_SD_DEFAULT_CLOCK_RATE;
2112 if (high_speed_enabled_mask == (data & high_speed_enabled_mask))
2113 {
2114 max_clock_rate = SDHI_PRV_SDIO_HIGH_SPEED_CLOCK_RATE;
2115 }
2116
2117 /* Set the clock rate to the maximum supported by both host and device. */
2118 err = r_sdhi_max_clock_rate_set(p_ctrl, max_clock_rate);
2119 FSP_ERROR_RETURN(FSP_SUCCESS == err, err);
2120
2121 return FSP_SUCCESS;
2122 }
2123
2124 #endif
2125
2126 /*******************************************************************************************************************//**
2127 * Waits for the access end interrupt.
2128 *
2129 * @param[in] p_ctrl Pointer to the instance control block.
2130 * @param[in] bit Bit to check in p_ctrl->sdhi_event
2131 * @param[in] timeout_us Number of loops to check bit (at least 1 us per loop).
2132 *
2133 * @retval FSP_SUCCESS Requested bit (access end or response end) is set.
2134 * @retval FSP_ERR_RESPONSE Device responded with an error.
2135 * @retval FSP_ERR_TIMEOUT Device did not respond.
2136 **********************************************************************************************************************/
r_sdhi_wait_for_event(sdhi_instance_ctrl_t * const p_ctrl,uint32_t bit,uint32_t timeout_us)2137 fsp_err_t r_sdhi_wait_for_event (sdhi_instance_ctrl_t * const p_ctrl, uint32_t bit, uint32_t timeout_us)
2138 {
2139 /* The event status is updated in the access interrupt. Use a local copy of the event status to make sure
2140 * it isn't updated during the loop. */
2141 volatile sdhi_event_t event;
2142 while (true)
2143 {
2144 /* Check for updates to the event status. */
2145 event.word = p_ctrl->sdhi_event.word;
2146
2147 /* Return an error if a hardware error occurred. */
2148 if (event.bit.event_error)
2149 {
2150 FSP_RETURN(FSP_ERR_RESPONSE);
2151 }
2152
2153 /* If the requested bit is set, return success. */
2154 if (event.word & (1U << bit))
2155 {
2156 return FSP_SUCCESS;
2157 }
2158
2159 /* Check for timeout. */
2160 timeout_us--;
2161 if (0U == timeout_us)
2162 {
2163 FSP_RETURN(FSP_ERR_TIMEOUT);
2164 }
2165
2166 /* Wait 1 us for consistent loop timing. */
2167 R_BSP_SoftwareDelay(1U, BSP_DELAY_UNITS_MICROSECONDS);
2168 }
2169 }
2170
2171 #if SDHI_CFG_SD_SUPPORT_ENABLE
2172
2173 /*******************************************************************************************************************//**
2174 * Checks to see if the SD card supports high speed.
2175 *
2176 * @param[in] p_ctrl Pointer to the instance control block.
2177 *
2178 * @retval FSP_SUCCESS SD clock set to the maximum supported by both host and device.
2179 * @retval FSP_ERR_RESPONSE Device responded with an error.
2180 * @retval FSP_ERR_TIMEOUT Device did not respond.
2181 * @retval FSP_ERR_INTERNAL Error in response from card during switch to high speed mode.
2182 **********************************************************************************************************************/
r_sdhi_sd_high_speed(sdhi_instance_ctrl_t * const p_ctrl)2183 static fsp_err_t r_sdhi_sd_high_speed (sdhi_instance_ctrl_t * const p_ctrl)
2184 {
2185 /* Issue CMD6 to switch to high speed. */
2186 fsp_err_t err = r_sdhi_read_and_block(p_ctrl,
2187 SDHI_PRV_CMD_SWITCH,
2188 SDHI_PRV_SD_HIGH_SPEED_MODE_SWITCH,
2189 SDHI_PRV_SD_SWITCH_STATUS_SIZE);
2190 FSP_ERROR_RETURN(FSP_SUCCESS == err, err);
2191
2192 /* Read the switch response to see if the high speed switch is supported and completed successfully. */
2193 uint8_t * p_read_data_8 = (uint8_t *) &p_ctrl->aligned_buff[0];
2194
2195 /* Check for successful switch. */
2196 if (SDHI_PRV_SD_SWITCH_HIGH_SPEED_OK ==
2197 (p_read_data_8[SDHI_PRV_SD_SWITCH_HIGH_SPEED_RESPONSE] & SDHI_PRV_SD_SWITCH_HIGH_SPEED_OK))
2198 {
2199 err = FSP_SUCCESS;
2200 }
2201
2202 /* Check for error response to High speed Function. */
2203 if (SDHI_PRV_SD_SWITCH_HIGH_SPEED_ERROR ==
2204 (p_read_data_8[SDHI_PRV_SD_SWITCH_HIGH_SPEED_ERROR_RESPONSE] &
2205 SDHI_PRV_SD_SWITCH_HIGH_SPEED_ERROR))
2206 {
2207 err = FSP_ERR_INTERNAL;
2208 }
2209
2210 FSP_ERROR_RETURN(FSP_SUCCESS == err, err);
2211
2212 return FSP_SUCCESS;
2213 }
2214
2215 #endif
2216
2217 #if SDHI_CFG_SD_SUPPORT_ENABLE || SDHI_CFG_EMMC_SUPPORT_ENABLE
2218
2219 /*******************************************************************************************************************//**
2220 * Save Card Specific Data.
2221 *
2222 * @param[in] p_ctrl Pointer to the instance control block.
2223 * @param[in] rca Relative card address
2224 * @param[out] p_csd_reg Pointer to card specific data.
2225 *
2226 * @retval FSP_SUCCESS Card specific data stored in provided pointer.
2227 * @retval FSP_ERR_RESPONSE Device responded with an error.
2228 * @retval FSP_ERR_TIMEOUT Device did not respond.
2229 * @retval FSP_ERR_DEVICE_BUSY Device is holding DAT0 low (device is busy) or another operation is ongoing.
2230 **********************************************************************************************************************/
r_sdhi_csd_save(sdhi_instance_ctrl_t * const p_ctrl,uint32_t rca,sdmmc_priv_csd_reg_t * const p_csd_reg)2231 static fsp_err_t r_sdhi_csd_save (sdhi_instance_ctrl_t * const p_ctrl,
2232 uint32_t rca,
2233 sdmmc_priv_csd_reg_t * const p_csd_reg)
2234 {
2235 /* Send CMD9 to get CSD */
2236 fsp_err_t err = r_sdhi_command_send(p_ctrl, SDHI_PRV_CMD_SEND_CSD, rca << 16);
2237 FSP_ERROR_RETURN(FSP_SUCCESS == err, err);
2238
2239 /* SDResponseR2 are bits from 8-127, first 8 MSBs are reserved */
2240 p_csd_reg->reg.sdrsp10 = p_ctrl->p_reg->SD_RSP10;
2241 p_csd_reg->reg.sdrsp32 = p_ctrl->p_reg->SD_RSP32;
2242 p_csd_reg->reg.sdrsp54 = p_ctrl->p_reg->SD_RSP54;
2243 p_csd_reg->reg.sdrsp76 = p_ctrl->p_reg->SD_RSP76;
2244
2245 /* Get the CSD version. */
2246 uint32_t csd_version = p_csd_reg->csd_v1_b.csd_structure;
2247
2248 /* Save sector count (total number of sectors on device) and erase sector count (minimum erasable unit in
2249 * sectors). */
2250 uint32_t mult;
2251 if ((SDHI_PRV_CSD_VERSION_1_0 == csd_version) || (SDMMC_CARD_TYPE_MMC == p_ctrl->device.card_type))
2252 {
2253 mult = (1U << (p_csd_reg->csd_v1_b.c_size_mult + 2));
2254 p_ctrl->device.sector_count = ((p_csd_reg->csd_v1_b.c_size + 1U) * mult);
2255
2256 /* Scale the sector count by the actual block size. */
2257 uint32_t read_sector_size = 1U << p_csd_reg->csd_v1_b.read_bl_len;
2258 p_ctrl->device.sector_count = p_ctrl->device.sector_count * (read_sector_size / SDHI_MAX_BLOCK_SIZE);
2259
2260 if (SDMMC_CARD_TYPE_MMC == p_ctrl->device.card_type)
2261 {
2262 /* If c_size is 0xFFF, then sector_count should be obtained from the extended CSD. Set it to 0 to indicate it
2263 * should come from the extended CSD later. */
2264 if (SDHI_PRV_SECTOR_COUNT_IN_EXT_CSD == p_csd_reg->csd_v1_b.c_size)
2265 {
2266 p_ctrl->device.sector_count = 0U;
2267 }
2268 }
2269 }
2270
2271 #if SDHI_CFG_SD_SUPPORT_ENABLE
2272 else if (SDHI_PRV_CSD_VERSION_2_0 == csd_version)
2273 {
2274 p_ctrl->device.sector_count = (p_csd_reg->csd_v2_b.c_size + 1U) * SDHI_PRV_BYTES_PER_KILOBYTE;
2275 }
2276 else
2277 {
2278 /* Do Nothing */
2279 }
2280
2281 if (SDHI_PRV_CSD_VERSION_1_0 == csd_version)
2282 {
2283 /* Get the minimum erasable unit (in 512 byte sectors). */
2284 p_ctrl->device.erase_sector_count = p_csd_reg->csd_v1_b.sector_size + 1U;
2285 }
2286 else
2287 #endif
2288 {
2289 /* For SDHC and SDXC cards, there are no erase group restrictions.
2290 *
2291 * Using the eMMC TRIM operation, there are no erase group restrictions. */
2292 p_ctrl->device.erase_sector_count = 1U;
2293 }
2294
2295 return FSP_SUCCESS;
2296 }
2297
2298 #endif
2299
2300 #if SDHI_CFG_EMMC_SUPPORT_ENABLE
2301
2302 /*******************************************************************************************************************//**
2303 * Get and store relevant extended card specific data.
2304 *
2305 * @param[in] p_ctrl Pointer to the instance control block.
2306 * @param[in] rca Relative card address
2307 * @param[out] p_device_type Pointer to store device type, which is used to determine if high speed is supported.
2308 *
2309 * @retval FSP_SUCCESS Device type obtained from eMMC extended CSD. Sector count is also calculated here
2310 * if it was not determined previously.
2311 * @retval FSP_ERR_RESPONSE Device responded with an error.
2312 * @retval FSP_ERR_TIMEOUT Device did not respond.
2313 **********************************************************************************************************************/
r_sdhi_csd_extended_get(sdhi_instance_ctrl_t * const p_ctrl,uint32_t rca,uint8_t * p_device_type)2314 static fsp_err_t r_sdhi_csd_extended_get (sdhi_instance_ctrl_t * const p_ctrl, uint32_t rca, uint8_t * p_device_type)
2315 {
2316 /* Ask card to send extended CSD (CMD8). */
2317 fsp_err_t err =
2318 r_sdhi_read_and_block(p_ctrl, SDHI_PRV_EMMC_CMD_SEND_EXT_CSD, rca << 16, SDHI_PRV_EMMC_EXT_CSD_SIZE);
2319 FSP_ERROR_RETURN(FSP_SUCCESS == err, err);
2320
2321 /* Store device type. Also store sector count if it is not already determined. */
2322 uint8_t * p_read_data_8 = (uint8_t *) &p_ctrl->aligned_buff[0];
2323 *p_device_type = p_read_data_8[SDHI_PRV_EMMC_EXT_CSD_DEVICE_TYPE_OFFSET];
2324
2325 if (0U == p_ctrl->device.sector_count)
2326 {
2327 p_ctrl->device.sector_count = p_ctrl->aligned_buff[SDHI_PRV_EMMC_EXT_CSD_SEC_COUNT_OFFSET / sizeof(uint32_t)];
2328 }
2329
2330 return FSP_SUCCESS;
2331 }
2332
2333 #endif
2334
2335 #if SDHI_CFG_SD_SUPPORT_ENABLE || SDHI_CFG_EMMC_SUPPORT_ENABLE
2336
2337 /*******************************************************************************************************************//**
2338 * Issue command expecting data to be returned, and block until read data is returned.
2339 *
2340 * @param[in] p_ctrl Pointer to the instance control block.
2341 * @param[in] command Command to issue.
2342 * @param[in] argument Argument to send with command.
2343 * @param[in] byte_count Expected number of bytes to read.
2344 *
2345 * @retval FSP_SUCCESS Requested data read into internal buffer.
2346 * @retval FSP_ERR_RESPONSE Device responded with an error.
2347 * @retval FSP_ERR_TIMEOUT Device did not respond.
2348 **********************************************************************************************************************/
r_sdhi_read_and_block(sdhi_instance_ctrl_t * const p_ctrl,uint32_t command,uint32_t argument,uint32_t byte_count)2349 fsp_err_t r_sdhi_read_and_block (sdhi_instance_ctrl_t * const p_ctrl,
2350 uint32_t command,
2351 uint32_t argument,
2352 uint32_t byte_count)
2353 {
2354 /* Prepare transfer interface to read. */
2355 fsp_err_t err = r_sdhi_transfer_read(p_ctrl, 1U, byte_count, &p_ctrl->aligned_buff[0]);
2356 FSP_ERROR_RETURN(FSP_SUCCESS == err, err);
2357
2358 /* Issue command. */
2359 r_sdhi_read_write_common(p_ctrl, 1U, byte_count, command, argument);
2360
2361 /* Wait for access end, error, or timeout. */
2362 return r_sdhi_wait_for_event(p_ctrl, SDHI_PRV_ACCESS_BIT, SDHI_PRV_ACCESS_TIMEOUT_US);
2363 }
2364
2365 #endif
2366
2367 /*******************************************************************************************************************//**
2368 * Gets or assigns the relative card address.
2369 *
2370 * @param[in] p_ctrl Pointer to the instance control block.
2371 * @param[out] p_rca Pointer to store relative card address.
2372 *
2373 * @retval FSP_SUCCESS Relative card address is assigned and device is in standby state.
2374 * @retval FSP_ERR_RESPONSE Device responded with an error.
2375 * @retval FSP_ERR_TIMEOUT Device did not respond.
2376 * @retval FSP_ERR_DEVICE_BUSY Device is holding DAT0 low (device is busy) or another operation is ongoing.
2377 **********************************************************************************************************************/
r_sdhi_rca_get(sdhi_instance_ctrl_t * const p_ctrl,uint32_t * p_rca)2378 static fsp_err_t r_sdhi_rca_get (sdhi_instance_ctrl_t * const p_ctrl, uint32_t * p_rca)
2379 {
2380 /* Send CMD3. For eMMC, assign an RCA of SDHI channel number + 2. These bits of the argument are ignored for SD
2381 * cards. */
2382 uint32_t rca = (p_ctrl->p_cfg->channel + 2U);
2383 fsp_err_t err = r_sdhi_command_send(p_ctrl, SDHI_PRV_CMD_SEND_RELATIVE_ADDR, rca << 16);
2384 FSP_ERROR_RETURN(FSP_SUCCESS == err, err);
2385
2386 #if SDHI_CFG_SD_SUPPORT_ENABLE || SDHI_CFG_SDIO_SUPPORT_ENABLE
2387 sdmmc_response_t response = {0U};
2388 response.status = p_ctrl->p_reg->SD_RSP10;
2389 if (SDMMC_CARD_TYPE_MMC != p_ctrl->device.card_type)
2390 {
2391 /* Get relative card address from the response if the device is an SD card. */
2392 rca = (response.r6.rca);
2393 }
2394 #endif
2395
2396 *p_rca = rca;
2397
2398 return FSP_SUCCESS;
2399 }
2400
2401 #if SDHI_CFG_SD_SUPPORT_ENABLE || SDHI_CFG_EMMC_SUPPORT_ENABLE
2402
2403 /*******************************************************************************************************************//**
2404 * Set bus width.
2405 *
2406 * @param[in] p_ctrl Pointer to the instance control block.
2407 * @param[in] rca Relative card address
2408 *
2409 * @retval FSP_SUCCESS Bus width updated on device.
2410 * @retval FSP_ERR_RESPONSE Device responded with an error.
2411 * @retval FSP_ERR_TIMEOUT Device did not respond.
2412 * @retval FSP_ERR_DEVICE_BUSY Device is holding DAT0 low (device is busy) or another operation is ongoing.
2413 **********************************************************************************************************************/
r_sdhi_bus_width_set(sdhi_instance_ctrl_t * const p_ctrl,uint32_t rca)2414 static fsp_err_t r_sdhi_bus_width_set (sdhi_instance_ctrl_t * const p_ctrl, uint32_t rca)
2415 {
2416 uint32_t bus_width;
2417 uint32_t bus_width_setting;
2418
2419 bus_width = p_ctrl->p_cfg->bus_width;
2420
2421 #if SDHI_CFG_EMMC_SUPPORT_ENABLE
2422 if (SDMMC_CARD_TYPE_MMC == p_ctrl->device.card_type)
2423 {
2424 /* For eMMC, set bus width using CMD6. */
2425 bus_width_setting = ((bus_width >> 2U) & 0x03U);
2426 fsp_err_t err = r_sdhi_command_send(p_ctrl,
2427 SDHI_PRV_EMMC_CMD_SWITCH_WBUSY,
2428 ((0x1U << SDHI_PRV_SWITCH_ACCESS_SHIFT) |
2429 (SDHI_PRV_EMMC_BUS_WIDTH_INDEX <<
2430 SDHI_PRV_SWITCH_INDEX_SHIFT) |
2431 (bus_width_setting << SDHI_PRV_SWITCH_VALUE_SHIFT)));
2432 FSP_ERROR_RETURN(FSP_SUCCESS == err, err);
2433
2434 /* Device may signal busy after CMD6. Wait for busy to clear. */
2435 r_sdhi_wait_for_device(p_ctrl);
2436 }
2437 else
2438 #endif
2439 {
2440 #if SDHI_CFG_SD_SUPPORT_ENABLE
2441
2442 /* Send CMD55, app command. */
2443 bus_width_setting = ((bus_width >> 1U) & 0x03U);
2444 fsp_err_t err = r_sdhi_command_send(p_ctrl, SDHI_PRV_CMD_APP_CMD, rca << 16);
2445 FSP_ERROR_RETURN(FSP_SUCCESS == err, err);
2446
2447 /* For SD cards, set bus width using ACMD6. */
2448 err = r_sdhi_command_send(p_ctrl, SDHI_PRV_CMD_C_ACMD | SDHI_PRV_CMD_SET_BUS_WIDTH, bus_width_setting);
2449 FSP_ERROR_RETURN(FSP_SUCCESS == err, err);
2450 #else
2451 FSP_PARAMETER_NOT_USED(rca);
2452 #endif
2453 }
2454
2455 /* Set the bus width in the SDHI peripheral. */
2456 uint32_t bus_width_reg = 0U;
2457 if (SDMMC_BUS_WIDTH_8_BITS == bus_width)
2458 {
2459 bus_width_reg = 1U;
2460 }
2461
2462 if (SDMMC_BUS_WIDTH_1_BIT == bus_width)
2463 {
2464 bus_width_reg = SDHI_PRV_BUS_WIDTH_1_BIT;
2465 }
2466
2467 p_ctrl->p_reg->SD_OPTION = SDHI_PRV_SD_OPTION_DEFAULT | (bus_width_reg << SDHI_PRV_SD_OPTION_WIDTH8_BIT);
2468
2469 return FSP_SUCCESS;
2470 }
2471
2472 #endif
2473
2474 /*******************************************************************************************************************//**
2475 * Performs workaround in the transfer interrupt for unaligned reads and writes.
2476 *
2477 * @param[in] p_ctrl Pointer to the instance control block.
2478 **********************************************************************************************************************/
r_sdhi_transfer_callback(sdhi_instance_ctrl_t * p_ctrl)2479 void r_sdhi_transfer_callback (sdhi_instance_ctrl_t * p_ctrl)
2480 {
2481 #if SDMMC_CFG_UNALIGNED_ACCESS_ENABLE
2482 if (p_ctrl->transfer_blocks_total != p_ctrl->transfer_block_current)
2483 {
2484 if (SDHI_TRANSFER_DIR_READ == p_ctrl->transfer_dir)
2485 {
2486 /* If the transfer is a read operation into an unaligned buffer, copy the block read from the aligned
2487 * buffer in the control block to the application data buffer. */
2488 memcpy(p_ctrl->p_transfer_data, (void *) &p_ctrl->aligned_buff[0], p_ctrl->transfer_block_size);
2489 }
2490
2491 if (SDHI_TRANSFER_DIR_WRITE == p_ctrl->transfer_dir)
2492 {
2493 /* If the transfer is a write operation from an unaligned buffer, copy the next block to write from the
2494 * application data buffer to the aligned buffer in the control block. */
2495 memcpy((void *) &p_ctrl->aligned_buff[0], p_ctrl->p_transfer_data, p_ctrl->transfer_block_size);
2496 }
2497
2498 p_ctrl->transfer_block_current++;
2499 p_ctrl->p_transfer_data += p_ctrl->transfer_block_size;
2500 }
2501
2502 if (p_ctrl->transfer_blocks_total == p_ctrl->transfer_block_current)
2503 {
2504 if (SDHI_TRANSFER_DIR_READ == p_ctrl->transfer_dir)
2505 {
2506 /* After the entire read transfer to an unaligned buffer is complete, read transfer end and callback are
2507 * performed in transfer interrupt to ensure the last block is in the application buffer before the
2508 * callback is called. */
2509 r_sdhi_transfer_end(p_ctrl);
2510
2511 sdmmc_callback_args_t args;
2512 memset(&args, 0U, sizeof(args));
2513 args.p_context = p_ctrl->p_context;
2514 args.event |= SDMMC_EVENT_TRANSFER_COMPLETE;
2515 r_sdhi_call_callback(p_ctrl, &args);
2516 }
2517 }
2518
2519 #else
2520 FSP_PARAMETER_NOT_USED(p_ctrl);
2521 #endif
2522 }
2523
2524 /*******************************************************************************************************************//**
2525 * Set up transfer to read from device.
2526 *
2527 * @param[in] p_ctrl Pointer to the instance control block.
2528 * @param[in] block_count Number of blocks to transfer.
2529 * @param[in] bytes Bytes per block.
2530 * @param[in] p_data Pointer to data to read data from device into.
2531 *
2532 * @retval FSP_SUCCESS Transfer successfully configured to write data.
2533 * @return See @ref RENESAS_ERROR_CODES or functions called by this function for other possible return codes. This
2534 * function calls:
2535 * * @ref transfer_api_t::reconfigure
2536 **********************************************************************************************************************/
r_sdhi_transfer_read(sdhi_instance_ctrl_t * const p_ctrl,uint32_t block_count,uint32_t bytes,void * p_data)2537 fsp_err_t r_sdhi_transfer_read (sdhi_instance_ctrl_t * const p_ctrl,
2538 uint32_t block_count,
2539 uint32_t bytes,
2540 void * p_data)
2541 {
2542 transfer_info_t * p_info = p_ctrl->p_cfg->p_lower_lvl_transfer->p_cfg->p_info;
2543
2544 /* When the SD_DMAEN.DMAEN bit is 1, set the SD_INFO2_MASK.BWEM bit to 1 and the SD_INFO2_MASK.BREM bit to 1. */
2545 p_ctrl->p_reg->SD_INFO2_MASK |= SDHI_PRV_SD_INFO2_MASK_BREM_BWEM_MASK;
2546 p_ctrl->p_reg->SD_DMAEN = SDHI_PRV_SD_DMAEN_DMAEN_SET;
2547
2548 uint32_t transfer_settings = (uint32_t) TRANSFER_MODE_BLOCK << TRANSFER_SETTINGS_MODE_BITS;
2549 transfer_settings |= TRANSFER_ADDR_MODE_INCREMENTED << TRANSFER_SETTINGS_DEST_ADDR_BITS;
2550 transfer_settings |= TRANSFER_SIZE_4_BYTE << TRANSFER_SETTINGS_SIZE_BITS;
2551
2552 #if SDMMC_CFG_UNALIGNED_ACCESS_ENABLE
2553
2554 /* If the pointer is not 4-byte aligned or the number of bytes is not a multiple of 4, use a temporary buffer.
2555 * Data will be transferred from the temporary buffer into the user buffer in an interrupt after each block transfer. */
2556 if ((0U != ((uint32_t) p_data & 0x3U)) || (0U != (bytes & 3U)))
2557 {
2558 transfer_settings |= TRANSFER_IRQ_EACH << TRANSFER_SETTINGS_IRQ_BITS;
2559 p_info->p_dest = &p_ctrl->aligned_buff[0];
2560
2561 p_ctrl->transfer_block_current = 0U;
2562 p_ctrl->transfer_blocks_total = block_count;
2563 p_ctrl->p_transfer_data = (uint8_t *) p_data;
2564 p_ctrl->transfer_dir = SDHI_TRANSFER_DIR_READ;
2565 p_ctrl->transfer_block_size = bytes;
2566 }
2567 else
2568 #endif
2569 {
2570 transfer_settings |= TRANSFER_REPEAT_AREA_SOURCE << TRANSFER_SETTINGS_REPEAT_AREA_BITS;
2571 p_info->p_dest = p_data;
2572 }
2573
2574 p_info->transfer_settings_word = transfer_settings;
2575 p_info->p_src = (uint32_t *) (&p_ctrl->p_reg->SD_BUF0);
2576 p_info->num_blocks = (uint16_t) block_count;
2577
2578 /* Round up to the nearest multiple of 4 bytes for the transfer. */
2579 uint32_t words = (bytes + (sizeof(uint32_t) - 1U)) / sizeof(uint32_t);
2580 p_info->length = (uint16_t) words;
2581
2582 /* Configure the transfer driver to read from the SD buffer. */
2583 fsp_err_t err = p_ctrl->p_cfg->p_lower_lvl_transfer->p_api->reconfigure(p_ctrl->p_cfg->p_lower_lvl_transfer->p_ctrl,
2584 p_ctrl->p_cfg->p_lower_lvl_transfer->p_cfg->p_info);
2585 FSP_ERROR_RETURN(FSP_SUCCESS == err, err);
2586
2587 return FSP_SUCCESS;
2588 }
2589
2590 /*******************************************************************************************************************//**
2591 * Set up transfer to write to device.
2592 *
2593 * @param[in] p_ctrl Pointer to the instance control block.
2594 * @param[in] block_count Number of blocks to transfer.
2595 * @param[in] bytes Bytes per block.
2596 * @param[in] p_data Pointer to data to write to device.
2597 *
2598 * @retval FSP_SUCCESS Transfer successfully configured to write data.
2599 * @return See @ref RENESAS_ERROR_CODES or functions called by this function for other possible return codes. This
2600 * function calls:
2601 * * @ref transfer_api_t::reconfigure
2602 **********************************************************************************************************************/
r_sdhi_transfer_write(sdhi_instance_ctrl_t * const p_ctrl,uint32_t block_count,uint32_t bytes,const uint8_t * p_data)2603 fsp_err_t r_sdhi_transfer_write (sdhi_instance_ctrl_t * const p_ctrl,
2604 uint32_t block_count,
2605 uint32_t bytes,
2606 const uint8_t * p_data)
2607 {
2608 transfer_info_t * p_info = p_ctrl->p_cfg->p_lower_lvl_transfer->p_cfg->p_info;
2609
2610 /* When the SD_DMAEN.DMAEN bit is 1, set the SD_INFO2_MASK.BWEM bit to 1 and the SD_INFO2_MASK.BREM bit to 1. */
2611 p_ctrl->p_reg->SD_INFO2_MASK |= SDHI_PRV_SD_INFO2_MASK_BREM_BWEM_MASK;
2612 p_ctrl->p_reg->SD_DMAEN = SDHI_PRV_SD_DMAEN_DMAEN_SET;
2613
2614 uint32_t transfer_settings = (uint32_t) TRANSFER_MODE_BLOCK << TRANSFER_SETTINGS_MODE_BITS;
2615 transfer_settings |= TRANSFER_ADDR_MODE_INCREMENTED << TRANSFER_SETTINGS_SRC_ADDR_BITS;
2616 transfer_settings |= TRANSFER_SIZE_4_BYTE << TRANSFER_SETTINGS_SIZE_BITS;
2617
2618 #if SDMMC_CFG_UNALIGNED_ACCESS_ENABLE
2619 if ((0U != ((uint32_t) p_data & 0x3U)) || (0U != (bytes & 3U)))
2620 {
2621 transfer_settings |= TRANSFER_IRQ_EACH << TRANSFER_SETTINGS_IRQ_BITS;
2622 transfer_settings |= TRANSFER_REPEAT_AREA_SOURCE << TRANSFER_SETTINGS_REPEAT_AREA_BITS;
2623
2624 /* If the pointer is not 4-byte aligned or the number of bytes is not a multiple of 4, use a temporary buffer.
2625 * Transfer the first block to the temporary buffer before enabling the transfer. Subsequent blocks will be
2626 * transferred from the user buffer to the temporary buffer in an interrupt after each block transfer. */
2627 memcpy((void *) &p_ctrl->aligned_buff[0], p_data, bytes);
2628 p_info->p_src = &p_ctrl->aligned_buff[0];
2629
2630 p_ctrl->transfer_block_current = 1U;
2631 p_ctrl->transfer_blocks_total = block_count;
2632 p_ctrl->p_transfer_data = (uint8_t *) &p_data[bytes];
2633 p_ctrl->transfer_dir = SDHI_TRANSFER_DIR_WRITE;
2634 p_ctrl->transfer_block_size = bytes;
2635 }
2636 else
2637 #endif
2638 {
2639 p_info->p_src = p_data;
2640 }
2641
2642 p_info->transfer_settings_word = transfer_settings;
2643 p_info->p_dest = (uint32_t *) (&p_ctrl->p_reg->SD_BUF0);
2644 p_info->num_blocks = (uint16_t) block_count;
2645
2646 /* Round up to the nearest multiple of 4 bytes for the transfer. */
2647 uint32_t words = (bytes + (sizeof(uint32_t) - 1U)) / sizeof(uint32_t);
2648 p_info->length = (uint16_t) words;
2649
2650 /* Configure the transfer driver to write to the SD buffer. */
2651 fsp_err_t err = p_ctrl->p_cfg->p_lower_lvl_transfer->p_api->reconfigure(p_ctrl->p_cfg->p_lower_lvl_transfer->p_ctrl,
2652 p_ctrl->p_cfg->p_lower_lvl_transfer->p_cfg->p_info);
2653 FSP_ERROR_RETURN(FSP_SUCCESS == err, err);
2654
2655 return FSP_SUCCESS;
2656 }
2657
2658 /*******************************************************************************************************************//**
2659 * Close transfer driver, clear transfer data, and disable transfer in the SDHI peripheral.
2660 *
2661 * @param[in] p_ctrl Pointer to the instance control block.
2662 **********************************************************************************************************************/
r_sdhi_transfer_end(sdhi_instance_ctrl_t * const p_ctrl)2663 static void r_sdhi_transfer_end (sdhi_instance_ctrl_t * const p_ctrl)
2664 {
2665 p_ctrl->transfer_block_current = 0U;
2666 p_ctrl->transfer_blocks_total = 0U;
2667 p_ctrl->p_transfer_data = NULL;
2668 p_ctrl->transfer_dir = SDHI_TRANSFER_DIR_NONE;
2669 p_ctrl->transfer_block_size = 0U;
2670
2671 p_ctrl->p_cfg->p_lower_lvl_transfer->p_api->disable(p_ctrl->p_cfg->p_lower_lvl_transfer->p_ctrl);
2672 p_ctrl->p_reg->SD_DMAEN = 0U;
2673 }
2674
2675 /*******************************************************************************************************************//**
2676 * Calls user callback
2677 *
2678 * @param[in] p_ctrl Pointer to the instance control block.
2679 * @param[in] p_args Pointer to callback arguments with event and response set.
2680 **********************************************************************************************************************/
r_sdhi_call_callback(sdhi_instance_ctrl_t * p_ctrl,sdmmc_callback_args_t * p_args)2681 static void r_sdhi_call_callback (sdhi_instance_ctrl_t * p_ctrl, sdmmc_callback_args_t * p_args)
2682 {
2683 /* Call user callback if provided, if an event was determined, and if the driver is initialized. */
2684 if (NULL != p_ctrl->p_callback)
2685 {
2686 sdmmc_callback_args_t args;
2687
2688 /* Store callback arguments in memory provided by user if available. This allows callback arguments to be
2689 * stored in non-secure memory so they can be accessed by a non-secure callback function. */
2690 sdmmc_callback_args_t * p_args_memory = p_ctrl->p_callback_memory;
2691 if (NULL == p_args_memory)
2692 {
2693 /* Use provided args struct on stack */
2694 p_args_memory = p_args;
2695 }
2696 else
2697 {
2698 /* Save current arguments on the stack in case this is a nested interrupt. */
2699 args = *p_args_memory;
2700
2701 /* Copy the stacked args to callback memory */
2702 *p_args_memory = *p_args;
2703 }
2704
2705 p_args_memory->p_context = p_ctrl->p_context;
2706
2707 #if BSP_TZ_SECURE_BUILD
2708
2709 /* p_callback can point to a secure function or a non-secure function. */
2710 if (!cmse_is_nsfptr(p_ctrl->p_callback))
2711 {
2712 /* If p_callback is secure, then the project does not need to change security state. */
2713 p_ctrl->p_callback(p_args_memory);
2714 }
2715 else
2716 {
2717 /* If p_callback is Non-secure, then the project must change to Non-secure state in order to call the callback. */
2718 sdhi_prv_ns_callback p_callback = (sdhi_prv_ns_callback) (p_ctrl->p_callback);
2719 p_callback(p_args_memory);
2720 }
2721
2722 #else
2723
2724 /* If the project is not Trustzone Secure, then it will never need to change security state in order to call the callback. */
2725 p_ctrl->p_callback(p_args_memory);
2726 #endif
2727
2728 if (NULL != p_ctrl->p_callback_memory)
2729 {
2730 /* Restore callback memory in case this is a nested interrupt. */
2731 *p_ctrl->p_callback_memory = args;
2732 }
2733 }
2734 }
2735
2736 /*******************************************************************************************************************//**
2737 * Calls user callback after response or data transfer complete.
2738 **********************************************************************************************************************/
sdhimmc_accs_isr(void)2739 void sdhimmc_accs_isr (void)
2740 {
2741 /* Save context if RTOS is used */
2742 FSP_CONTEXT_SAVE
2743
2744 IRQn_Type irq = R_FSP_CurrentIrqGet();
2745 sdhi_instance_ctrl_t * p_ctrl = (sdhi_instance_ctrl_t *) R_FSP_IsrContextGet(irq);
2746
2747 sdmmc_callback_args_t args;
2748 memset(&args, 0U, sizeof(args));
2749 r_sdhi_access_irq_process(p_ctrl, &args);
2750
2751 /* Call user callback */
2752 if ((p_ctrl->initialized) && (0U != args.event))
2753 {
2754 r_sdhi_call_callback(p_ctrl, &args);
2755 }
2756
2757 /* Clear the IR flag in the ICU */
2758 /* Clearing the IR bit must be done after clearing the interrupt source in the the peripheral */
2759 R_BSP_IrqStatusClear(irq);
2760
2761 /* Restore context if RTOS is used */
2762 FSP_CONTEXT_RESTORE
2763 }
2764
2765 /*******************************************************************************************************************//**
2766 * Calls user callback when card insertion or removal interrupt fires.
2767 **********************************************************************************************************************/
sdhimmc_card_isr(void)2768 void sdhimmc_card_isr (void)
2769 {
2770 /* Save context if RTOS is used */
2771 FSP_CONTEXT_SAVE
2772 sdmmc_callback_args_t args;
2773 memset(&args, 0U, sizeof(args));
2774
2775 IRQn_Type irq = R_FSP_CurrentIrqGet();
2776 sdhi_instance_ctrl_t * p_ctrl = (sdhi_instance_ctrl_t *) R_FSP_IsrContextGet(irq);
2777
2778 sdhi_event_t info1 = {0U};
2779 info1.word = p_ctrl->p_reg->SD_INFO1;
2780
2781 if (0U != (info1.word & SDHI_PRV_SDHI_INFO1_CARD_REMOVED_MASK))
2782 {
2783 p_ctrl->initialized = false;
2784 args.event |= SDMMC_EVENT_CARD_REMOVED;
2785 }
2786
2787 if (0U != (info1.word & SDHI_PRV_SDHI_INFO1_CARD_INSERTED_MASK))
2788 {
2789 args.event |= SDMMC_EVENT_CARD_INSERTED;
2790 }
2791
2792 /* Clear interrupt flags processed in this ISR. */
2793 info1.word &= SDHI_PRV_SDHI_INFO1_CARD_MASK;
2794 p_ctrl->p_reg->SD_INFO1 = (~info1.word);
2795
2796 /* Call user callback if provided */
2797 args.p_context = p_ctrl->p_context;
2798 r_sdhi_call_callback(p_ctrl, &args);
2799
2800 /* Clear the IR flag in the ICU */
2801 /* Clearing the IR bit must be done after clearing the interrupt source in the the peripheral */
2802 R_BSP_IrqStatusClear(irq);
2803
2804 /* Restore context if RTOS is used */
2805 FSP_CONTEXT_RESTORE
2806 }
2807
2808 /*******************************************************************************************************************//**
2809 * DMA ISR. Called when a DTC transfer completes. Not used for DMAC.
2810 *
2811 * Handles data copy for unaligned buffers and transfer complete processing.
2812 **********************************************************************************************************************/
sdhimmc_dma_req_isr(void)2813 void sdhimmc_dma_req_isr (void)
2814 {
2815 /* Save context if RTOS is used */
2816 FSP_CONTEXT_SAVE
2817
2818 IRQn_Type irq = R_FSP_CurrentIrqGet();
2819
2820 sdhi_instance_ctrl_t * p_ctrl = (sdhi_instance_ctrl_t *) R_FSP_IsrContextGet(irq);
2821
2822 r_sdhi_transfer_callback(p_ctrl);
2823
2824 /* Clear the IR flag in the ICU.
2825 * This must be after the callback because the next DTC transfer will begin when this bit is cleared. */
2826 R_BSP_IrqStatusClear(irq);
2827
2828 /* Restore context if RTOS is used */
2829 FSP_CONTEXT_RESTORE
2830 }
2831
2832 /*******************************************************************************************************************//**
2833 * Calls callback and clears interrupt flags.
2834 **********************************************************************************************************************/
sdhimmc_sdio_isr(void)2835 void sdhimmc_sdio_isr (void)
2836 {
2837 /* Save context if RTOS is used */
2838 FSP_CONTEXT_SAVE
2839
2840 IRQn_Type irq = R_FSP_CurrentIrqGet();
2841 sdhi_instance_ctrl_t * p_ctrl = (sdhi_instance_ctrl_t *) R_FSP_IsrContextGet(irq);
2842
2843 /* Determine the source of the interrupt. */
2844 sdmmc_callback_args_t args;
2845 memset(&args, 0U, sizeof(args));
2846 uint32_t info1 = p_ctrl->p_reg->SDIO_INFO1;
2847 if (info1 & SDHI_PRV_SDIO_INFO1_TRANSFER_COMPLETE_MASK)
2848 {
2849 /* A multi-block CMD53 transfer is complete. */
2850 args.event |= SDMMC_EVENT_TRANSFER_COMPLETE;
2851 }
2852 else
2853 {
2854 /* I/O interrupt requested by device. */
2855 args.event |= SDMMC_EVENT_SDIO;
2856 }
2857
2858 /* Call user callback */
2859 if (p_ctrl->initialized)
2860 {
2861 r_sdhi_call_callback(p_ctrl, &args);
2862 }
2863
2864 /* Clear interrupt flags */
2865 p_ctrl->p_reg->SDIO_INFO1 = SDHI_PRV_SDIO_INFO1_IRQ_CLEAR;
2866
2867 /* Clear the IR flag in the ICU */
2868 /* Clearing the IR bit must be done after clearing the interrupt source in the the peripheral */
2869 R_BSP_IrqStatusClear(irq);
2870
2871 /* Restore context if RTOS is used */
2872 FSP_CONTEXT_RESTORE
2873 }
2874