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