1 /*******************************************************************************
2 * \file cy_sd_host.c
3 * \version 2.1
4 *
5 * \brief
6 * This file provides the driver code to the API for the SD Host Controller
7 * driver.
8 *
9 ********************************************************************************
10 * \copyright
11 * Copyright 2018-2021 Cypress Semiconductor Corporation
12 * SPDX-License-Identifier: Apache-2.0
13 *
14 * Licensed under the Apache License, Version 2.0 (the "License");
15 * you may not use this file except in compliance with the License.
16 * You may obtain a copy of the License at
17 *
18 * http://www.apache.org/licenses/LICENSE-2.0
19 *
20 * Unless required by applicable law or agreed to in writing, software
21 * distributed under the License is distributed on an "AS IS" BASIS,
22 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
23 * See the License for the specific language governing permissions and
24 * limitations under the License.
25 *******************************************************************************/
26
27 #include "cy_device.h"
28
29 #if defined (CY_IP_MXSDHC)
30
31 #include "cy_sd_host.h"
32 #include <string.h>
33 #include <stdlib.h>
34
35 #if defined(__cplusplus)
36 extern "C" {
37 #endif
38
39 CY_MISRA_DEVIATE_BLOCK_START('MISRA C-2012 Rule 18.1', 11, \
40 'Checked manually, base pointer will not exceed register range.')
41
42 /** \cond internal */
43
44 /* Timeouts. */
45 #define CY_SD_HOST_INT_CLK_STABLE_TIMEOUT_MS (150U) /* The Internal Clock Stable timeout. */
46 #define CY_SD_HOST_1_8_REG_STABLE_TIME_MS (30UL) /* The 1.8 voltage regulator stable time. */
47 #define CY_SD_HOST_SUPPLY_RAMP_UP_TIME_MS (35UL) /* The host supply ramp up time. */
48 #define CY_SD_HOST_BUS_RAMP_UP_TIME_MS (1000UL) /* The host bus voltage ramp up time. */
49
50 #define CY_SD_HOST_EMMC_CMD6_TIMEOUT_MULT (10UL) /* The 10x multiplier of GENERIC_CMD6_TIME[248]. */
51 #define CY_SD_HOST_RETRY_TIME (1000UL) /* The number loops to make the timeout in msec. */
52 #define CY_SD_HOST_VOLTAGE_CHECK_RETRY (2UL) /* The number loops for voltage check. */
53 #define CY_SD_HOST_SDIO_CMD5_TIMEOUT_MS (1000U) /* The SDIO CMD5 timeout. */
54 #define CY_SD_HOST_ACMD41_TIMEOUT_MS (1000U) /* The ACMD41 timeout. */
55 #define CY_SD_HOST_CMD1_TIMEOUT_MS (1000U) /* The eMMC device timeout to complete its initialization. */
56 #define CY_SD_HOST_CMD_TIMEOUT_MS (3U) /* The Command complete timeout. */
57 #define CY_SD_HOST_BUFFER_RDY_TIMEOUT_MS (150U) /* The Buffer read ready timeout. */
58 #define CY_SD_HOST_RD_WR_ENABLE_TIMEOUT (1U) /* The valid data in the Host buffer timeout. */
59 #define CY_SD_HOST_READ_TIMEOUT_MS (100U) /* The Read timeout for one block. */
60 #define CY_SD_HOST_WRITE_TIMEOUT_MS (250U) /* The Write timeout for one block. */
61 #define CY_SD_HOST_MAX_TIMEOUT (0x0EU) /* The data max timeout for TOUT_CTRL_R. */
62 #define CY_SD_HOST_NCC_MIN_CYCLES (8U) /* The period (clock cycles) between an end bit
63 * of the command and a start bit of the next command.
64 */
65 #define CY_SD_HOST_NCC_MIN_US ((1000U * CY_SD_HOST_NCC_MIN_CYCLES) / CY_SD_HOST_INIT_CLK_FREQUENCY_KHZ)
66
67 /* Commands codes. */
68 #define CY_SD_HOST_SD_CMD0 (0UL)
69 #define CY_SD_HOST_SD_CMD1 (1UL)
70 #define CY_SD_HOST_SD_CMD2 (2UL)
71 #define CY_SD_HOST_SD_CMD3 (3UL)
72 #define CY_SD_HOST_SD_CMD5 (5UL)
73 #define CY_SD_HOST_SD_CMD6 (6UL)
74 #define CY_SD_HOST_SD_CMD7 (7UL)
75 #define CY_SD_HOST_SD_CMD8 (8UL)
76 #define CY_SD_HOST_SD_CMD9 (9UL)
77 #define CY_SD_HOST_SD_CMD10 (10UL)
78 #define CY_SD_HOST_SD_CMD11 (11UL)
79 #define CY_SD_HOST_SD_CMD12 (12UL)
80 #define CY_SD_HOST_SD_CMD13 (13UL)
81
82 #define CY_SD_HOST_SD_CMD16 (16UL)
83 #define CY_SD_HOST_SD_CMD17 (17UL)
84 #define CY_SD_HOST_SD_CMD18 (18UL)
85
86 #define CY_SD_HOST_SD_CMD23 (23UL)
87 #define CY_SD_HOST_SD_CMD24 (24UL)
88 #define CY_SD_HOST_SD_CMD25 (25UL)
89
90 #define CY_SD_HOST_SD_CMD27 (27UL)
91 #define CY_SD_HOST_SD_CMD28 (28UL)
92 #define CY_SD_HOST_SD_CMD29 (29UL)
93 #define CY_SD_HOST_SD_CMD30 (30UL)
94
95 #define CY_SD_HOST_SD_CMD32 (32UL)
96 #define CY_SD_HOST_SD_CMD33 (33UL)
97 #define CY_SD_HOST_SD_CMD35 (35UL)
98 #define CY_SD_HOST_SD_CMD36 (36UL)
99 #define CY_SD_HOST_SD_CMD38 (38UL)
100
101 #define CY_SD_HOST_SD_CMD42 (42UL)
102 #define CY_SD_HOST_SD_CMD52 (52UL)
103
104 #define CY_SD_HOST_SD_CMD55 (55UL)
105
106 #define CY_SD_HOST_MMC_CMD_TAG (0x80UL)
107 #define CY_SD_HOST_MMC_CMD8 (0x8UL | CY_SD_HOST_MMC_CMD_TAG)
108
109 #define CY_SD_HOST_SD_ACMD_OFFSET (0x40UL)
110 #define CY_SD_HOST_SD_ACMD6 (CY_SD_HOST_SD_ACMD_OFFSET + 6UL)
111 #define CY_SD_HOST_SD_ACMD13 (CY_SD_HOST_SD_ACMD_OFFSET + 13UL)
112 #define CY_SD_HOST_SD_ACMD41 (CY_SD_HOST_SD_ACMD_OFFSET + 41UL)
113 #define CY_SD_HOST_SD_ACMD51 (CY_SD_HOST_SD_ACMD_OFFSET + 51UL)
114
115 /* CMD5/CMD8/ACMD41 constants. */
116 #define CY_SD_HOST_CMD5_IO_NUM_MASK (0x70000000UL) /* The Number of IO functions mask. */
117 #define CY_SD_HOST_CMD5_MP_MASK (0x08000000UL) /* The Memory Present mask. */
118 #define CY_SD_HOST_IO_OCR_MASK (0x00FFFFFFUL) /* The IO OCR register mask. */
119 #define CY_SD_HOST_IO_OCR_C (0x80000000UL) /* The IO power up status (IORDY). */
120 #define CY_SD_HOST_MIN_SDXC_SECTORS (67108864UL) /* Minimum sectors for SDXC: 32 Gbytes / 512. */
121 #define CY_SD_HOST_MMC_LEGACY_SIZE_BYTES (0x200000UL)
122 #define CY_SD_HOST_CMD8_VHS_27_36 (0x100UL) /* CMD8 voltage supplied 2.7-3.6 V. */
123 #define CY_SD_HOST_CMD8_PATTERN_MASK (0xFFUL)
124 #define CY_SD_HOST_CMD8_CHECK_PATTERN (0xAAUL)
125 #define CY_SD_HOST_ACMD41_S18R (1UL << 24U) /* The 1.8 V request. */
126 #define CY_SD_HOST_ACMD41_HCS (1UL << 30U) /* SDHC or SDXC supported. */
127 #define CY_SD_HOST_OCR_S18A (1UL << 24U) /* The 1.8 V accepted. */
128 #define CY_SD_HOST_OCR_35_36_V (1UL << 23U) /* The 3.5 - 3.6 voltage window. */
129 #define CY_SD_HOST_OCR_34_35_V (1UL << 22U) /* The 3.4 - 3.5 voltage window. */
130 #define CY_SD_HOST_OCR_33_34_V (1UL << 21U) /* The 3.3 - 3.4 voltage window. */
131 #define CY_SD_HOST_OCR_32_33_V (1UL << 20U) /* The 3.2 - 3.3 voltage window. */
132 #define CY_SD_HOST_OCR_31_32_V (1UL << 19U) /* The 3.1 - 3.2 voltage window. */
133 #define CY_SD_HOST_OCR_30_31_V (1UL << 18U) /* The 3.0 - 3.1 voltage window. */
134 #define CY_SD_HOST_OCR_29_30_V (1UL << 17U) /* The 2.9 - 3.0 voltage window. */
135 #define CY_SD_HOST_OCR_28_29_V (1UL << 16U) /* The 2.8 - 2.9 voltage window. */
136 #define CY_SD_HOST_OCR_27_28_V (1UL << 15U) /* The 2.7 - 2.8 voltage window. */
137 #define CY_SD_HOST_ACMD41_VOLTAGE_MASK (CY_SD_HOST_OCR_35_36_V |\
138 CY_SD_HOST_OCR_34_35_V |\
139 CY_SD_HOST_OCR_33_34_V |\
140 CY_SD_HOST_OCR_32_33_V |\
141 CY_SD_HOST_OCR_31_32_V |\
142 CY_SD_HOST_OCR_30_31_V |\
143 CY_SD_HOST_OCR_29_30_V |\
144 CY_SD_HOST_OCR_28_29_V |\
145 CY_SD_HOST_OCR_27_28_V)
146 #define CY_SD_HOST_ARG_ACMD41_BUSY (0x80000000UL)
147 #define CY_SD_HOST_OCR_BUSY_BIT (0x80000000UL) /* The Card power up status bit (busy). */
148 #define CY_SD_HOST_OCR_CAPACITY_MASK (0x40000000UL) /* The OCR sector access mode bit. */
149 #define CY_SD_HOST_ACMD_OFFSET_MASK (0x3FUL)
150 #define CY_SD_HOST_EMMC_DUAL_VOLTAGE (0x00000080UL)
151 #define CY_SD_HOST_EMMC_VOLTAGE_WINDOW (CY_SD_HOST_OCR_CAPACITY_MASK |\
152 CY_SD_HOST_EMMC_DUAL_VOLTAGE |\
153 CY_SD_HOST_ACMD41_VOLTAGE_MASK)
154
155 /* Other constants. */
156 #define CY_SD_HOST_SWITCH_FUNCTION_BIT (31U)
157 #define CY_SD_HOST_DEFAULT_SPEED (0UL)
158 #define CY_SD_HOST_HIGH_SPEED (1UL)
159 #define CY_SD_HOST_SDR12_SPEED (0UL) /* The SDR12/Legacy speed. */
160 #define CY_SD_HOST_SDR25_SPEED (1UL) /* The SDR25/High Speed SDR speed. */
161 #define CY_SD_HOST_SDR50_SPEED (2UL) /* The SDR50 speed. */
162 #define CY_SD_HOST_DDR50_SPEED (4UL) /* The DDR50 speed. */
163 #define CY_SD_HOST_SDR12_OUT_DELAY (0UL)
164 #define CY_SD_HOST_SDR25_OUT_DELAY (1UL)
165 #define CY_SD_HOST_DDR50_OUT_DELAY (3UL)
166 #define CY_SD_HOST_SDR12_IN_DELAY (0UL)
167 #define CY_SD_HOST_SDR25_IN_DELAY (1UL)
168 #define CY_SD_HOST_HIGH_SPEED_IN_DELAY (2UL)
169 #define CY_SD_HOST_DDR50_IN_DELAY (3UL)
170 #define CY_SD_HOST_EMMC_BUS_WIDTH_ADDR (0xB7UL)
171 #define CY_SD_HOST_EMMC_HS_TIMING_ADDR (0xB9UL)
172 #define CY_SD_HOST_CMD23_BLOCKS_NUM_MASK (0xFFFFUL)
173 #define CY_SD_HOST_CMD23_RELIABLE_WRITE_POS (31U)
174 #define CY_SD_HOST_RCA_SHIFT (16U)
175 #define CY_SD_HOST_RESPONSE_SIZE (4U)
176 #define CY_SD_HOST_CID_SIZE (4U)
177 #define CY_SD_HOST_CSD_SIZE (4U)
178 #define CY_SD_HOST_SCR_BLOCKS (8UL)
179 #define CY_SD_HOST_CSD_BLOCKS (16UL)
180 #define CY_SD_HOST_SD_STATUS_BLOCKS (64UL)
181 #define CY_SD_HOST_SWITCH_STATUS_LEN (16UL)
182 #define CY_SD_HOST_PERI_FREQUENCY (100000000UL)
183 #define CY_SD_HOST_FREQ_SEL_MSK (0xFFUL)
184 #define CY_SD_HOST_UPPER_FREQ_SEL_POS (8U)
185
186 /* CMD6 SWITCH command bitfields. */
187 #define CY_SD_HOST_EMMC_CMD6_ACCESS_OFFSET (24U)
188 #define CY_SD_HOST_EMMC_CMD6_IDX_OFFSET (16U)
189 #define CY_SD_HOST_EMMC_CMD6_VALUE_OFFSET (8U)
190 #define CY_SD_HOST_EMMC_CMD6_CMD_SET_OFFSET (0U)
191
192 /* EMMC EXTCSD register bitfields. */
193 #define CY_SD_HOST_EXTCSD_SEC_COUNT (53U)
194 #define CY_SD_HOST_EXTCSD_GENERIC_CMD6_TIME (62U)
195 #define CY_SD_HOST_EXTCSD_GENERIC_CMD6_TIME_MSK (0xFFUL)
196 #define CY_SD_HOST_EXTCSD_SIZE (128U)
197
198 /* CSD register masks/positions. */
199 #define CY_SD_HOST_CSD_V1_C_SIZE_MSB_MASK (0x00000003UL)
200 #define CY_SD_HOST_CSD_V1_C_SIZE_ISB_MASK (0xFF000000UL)
201 #define CY_SD_HOST_CSD_V1_C_SIZE_LSB_MASK (0x00C00000UL)
202 #define CY_SD_HOST_CSD_V1_C_SIZE_MSB_POS (0U)
203 #define CY_SD_HOST_CSD_V1_C_SIZE_ISB_POS (24U)
204 #define CY_SD_HOST_CSD_V1_C_SIZE_LSB_POS (22U)
205 #define CY_SD_HOST_CSD_V1_C_SIZE_MSB_MULT (10U)
206 #define CY_SD_HOST_CSD_V1_C_SIZE_ISB_MULT (2U)
207 #define CY_SD_HOST_CSD_V1_C_SIZE_MULT_MASK (0x00000380UL)
208 #define CY_SD_HOST_CSD_V1_C_SIZE_MULT_POS (7U)
209 #define CY_SD_HOST_CSD_V1_READ_BL_LEN_MASK (0x00000F00UL)
210 #define CY_SD_HOST_CSD_V1_READ_BL_LEN_POS (8U)
211 #define CY_SD_HOST_CSD_V1_BL_LEN_512 (9UL)
212 #define CY_SD_HOST_CSD_V1_BL_LEN_1024 (10UL)
213 #define CY_SD_HOST_CSD_V1_BL_LEN_2048 (11UL)
214 #define CY_SD_HOST_CSD_V1_1024_SECT_FACTOR (2UL)
215 #define CY_SD_HOST_CSD_V1_2048_SECT_FACTOR (4UL)
216 #define CY_SD_HOST_CSD_V2_C_SIZE_POS (8U)
217 #define CY_SD_HOST_CSD_V2_SECTOR_MULT (10U)
218 #define CY_SD_HOST_CSD_TEMP_WRITE_PROTECT (20U)
219 #define CY_SD_HOST_CSD_PERM_WRITE_PROTECT (21U)
220 #define CY_SD_HOST_CSD_LSB_MASK (0x000000FFUL)
221 #define CY_SD_HOST_CSD_ISBR_MASK (0x0000FF00UL)
222 #define CY_SD_HOST_CSD_ISBL_MASK (0x00FF0000UL)
223 #define CY_SD_HOST_CSD_MSB_MASK (0xFF000000UL)
224 #define CY_SD_HOST_CSD_ISB_SHIFT (16U)
225
226 /* CMD6 EXT_CSD access mode. */
227 #define CY_SD_HOST_EMMC_ACCESS_COMMAND_SET (0x0U)
228 #define CY_SD_HOST_EMMC_ACCESS_SET_BITS (0x1U)
229 #define CY_SD_HOST_EMMC_ACCESS_CLEAR_BITS (0x2U)
230 #define CY_SD_HOST_EMMC_ACCESS_WRITE_BYTE (0x3UL)
231
232 /* CCCR register values. */
233 #define CY_SD_HOST_CCCR_SPEED_CONTROL (0x00013UL)
234 #define CY_SD_HOST_CCCR_IO_ABORT (0x00006UL)
235 #define CY_SD_HOST_CCCR_SPEED_SHS_MASK (0x1UL)
236 #define CY_SD_HOST_CCCR_SPEED_EHS_MASK (0x2UL)
237 #define CY_SD_HOST_CCCR_SPEED_BSS0_MASK (0x2UL)
238 #define CY_SD_HOST_CCCR_SPEED_BSS1_MASK (0x4UL)
239 #define CY_SD_HOST_CCCR_SPEED_BSS2_MASK (0x8UL)
240 #define CY_SD_HOST_CCCR_BUS_INTERFACE_CTR (0x00007UL)
241 #define CY_SD_HOST_CCCR_BUS_WIDTH_0 (0x1UL)
242 #define CY_SD_HOST_CCCR_BUS_WIDTH_1 (0x2UL)
243 #define CY_SD_HOST_CCCR_S8B (0x4UL)
244
245 /* SDMA constants. */
246 #define CY_SD_HOST_SDMA_BUF_BYTES_4K (0x0U) /* 4K bytes SDMA Buffer Boundary. */
247 #define CY_SD_HOST_SDMA_BUF_BYTES_8K (0x1U) /* 8K bytes SDMA Buffer Boundary. */
248 #define CY_SD_HOST_SDMA_BUF_BYTES_16K (0x2U) /* 16K bytes SDMA Buffer Boundary. */
249 #define CY_SD_HOST_SDMA_BUF_BYTES_32K (0x3U) /* 32K bytes SDMA Buffer Boundary. */
250 #define CY_SD_HOST_SDMA_BUF_BYTES_64K (0x4U) /* 64K bytes SDMA Buffer Boundary. */
251 #define CY_SD_HOST_SDMA_BUF_BYTES_128K (0x5U) /* 128K bytes SDMA Buffer Boundary. */
252 #define CY_SD_HOST_SDMA_BUF_BYTES_256K (0x6U) /* 256K bytes SDMA Buffer Boundary. */
253 #define CY_SD_HOST_SDMA_BUF_BYTES_512K (0x7U) /* 512K bytes SDMA Buffer Boundary. */
254
255 /* CMD38 arguments. */
256 #define CY_SD_HOST_ERASE (0x00000000UL) /* The SD/eMMC Erase. */
257 #define CY_SD_HOST_SD_DISCARD (0x00000001UL) /* The SD Discard. */
258 #define CY_SD_HOST_SD_FULE (0x00000002UL) /* The SD FULE. */
259 #define CY_SD_HOST_EMMC_DISCARD (0x00000003UL) /* The eMMC Discard. */
260 #define CY_SD_HOST_EMMC_SECURE_ERASE (0x80000000UL) /* The eMMC Secure Erase. */
261 #define CY_SD_HOST_EMMC_SECURE_TRIM_STEP_2 (0x80008000UL) /* The eMMC Secure Trim Step 2. */
262 #define CY_SD_HOST_EMMC_SECURE_TRIM_STEP_1 (0x80000001UL) /* The eMMC Secure Trim Step 1. */
263 #define CY_SD_HOST_EMMC_TRIM (0x00000001UL) /* The eMMC Trim. */
264
265 /* CMD52 constants. */
266 #define CY_SD_HOST_CMD52_RWFLAG_POS (31U) /* The CMD52 RW Flag position. */
267 #define CY_SD_HOST_CMD52_FUNCT_NUM_POS (28U) /* The CMD52 Function Number position. */
268 #define CY_SD_HOST_CMD52_FUNCT_NUM_MSK (0x07UL) /* The CMD52 Function Number mask. */
269 #define CY_SD_HOST_CMD52_RAWFLAG_POS (27U) /* The CMD52 Raw Flag position. */
270 #define CY_SD_HOST_CMD52_REG_ADDR_POS (9U) /* The CMD52 Register Address position. */
271 #define CY_SD_HOST_CMD52_REG_ADDR_MSK (0x1FFFFUL) /* The CMD52 Register Address mask. */
272 #define CY_SD_HOST_CMD52_DATA_MSK (0xFFUL) /* The CMD52 data mask. */
273
274 /* Interrupt masks. */
275 #define CY_SD_HOST_NORMAL_INT_MSK (0x1FFFU) /* The enabled Normal Interrupts. */
276 #define CY_SD_HOST_ERROR_INT_MSK (0x07FFU) /* The enabled Error Interrupts. */
277
278 /* SD output clock. */
279 #define CY_SD_HOST_CLK_400K (400UL * 1000UL) /* 400 kHz. */
280 #define CY_SD_HOST_CLK_10M (10UL * 1000UL * 1000UL) /* 10 MHz. */
281 #define CY_SD_HOST_CLK_20M (20UL * 1000UL * 1000UL) /* 20 MHz. */
282
283 /** \endcond */
284
285 /** \cond PARAM_CHECK_MACROS */
286
287 #define CY_SD_HOST_FREQ_MAX (50000000UL) /* The maximum clk frequency. */
288 #define CY_SD_HOST_IS_FREQ_VALID(frequency) ((0UL < (frequency)) && (CY_SD_HOST_FREQ_MAX >= (frequency)))
289
290 #define CY_SD_HOST_IS_SD_BUS_WIDTH_VALID(width) ((CY_SD_HOST_BUS_WIDTH_1_BIT == (width)) || \
291 (CY_SD_HOST_BUS_WIDTH_4_BIT == (width)))
292
293 #define CY_SD_HOST_IS_EMMC_BUS_WIDTH_VALID(width) ((CY_SD_HOST_BUS_WIDTH_1_BIT == (width)) || \
294 (CY_SD_HOST_BUS_WIDTH_4_BIT == (width)) || \
295 (CY_SD_HOST_BUS_WIDTH_8_BIT == (width)))
296
297 #define CY_SD_HOST_IS_BUS_WIDTH_VALID(width, cardType) ((CY_SD_HOST_EMMC == (cardType)) ? \
298 CY_SD_HOST_IS_EMMC_BUS_WIDTH_VALID(width) : \
299 CY_SD_HOST_IS_SD_BUS_WIDTH_VALID(width))
300
301 #define CY_SD_HOST_IS_AUTO_CMD_VALID(cmd) ((CY_SD_HOST_AUTO_CMD_NONE == (cmd)) || \
302 (CY_SD_HOST_AUTO_CMD_12 == (cmd)) || \
303 (CY_SD_HOST_AUTO_CMD_23 == (cmd)) || \
304 (CY_SD_HOST_AUTO_CMD_AUTO == (cmd)))
305
306 #define CY_SD_HOST_IS_TIMEOUT_VALID(timeout) (CY_SD_HOST_MAX_TIMEOUT >= (timeout))
307
308 #define CY_SD_HOST_BLK_SIZE_MAX (2048UL) /* The maximum block size. */
309 /* Macro to check that block size is less than 2048 bytes and block size is even if DDR50 mode is selected */
310 #define CY_SD_HOST_IS_BLK_SIZE_VALID(size, speedMode) ((CY_SD_HOST_BLK_SIZE_MAX >= (size)) ? \
311 (((speedMode) == 0x4UL) ? (((size) % 2UL) == 0UL) : true) : false)
312
313 #define CY_SD_HOST_IS_ERASE_VALID(eraseType) ((CY_SD_HOST_ERASE_ERASE == (eraseType)) || \
314 (CY_SD_HOST_ERASE_DISCARD == (eraseType)) || \
315 (CY_SD_HOST_ERASE_FULE == (eraseType)) || \
316 (CY_SD_HOST_ERASE_SECURE == (eraseType)) || \
317 (CY_SD_HOST_ERASE_SECURE_TRIM_STEP_2 == (eraseType)) || \
318 (CY_SD_HOST_ERASE_SECURE_TRIM_STEP_1 == (eraseType)) || \
319 (CY_SD_HOST_ERASE_TRIM == (eraseType)))
320
321 #define CY_SD_HOST_IS_CMD_IDX_VALID(cmd) (0UL == ((cmd) & (uint32_t)~(CY_SD_HOST_ACMD_OFFSET_MASK | \
322 CY_SD_HOST_MMC_CMD_TAG | \
323 CY_SD_HOST_SD_ACMD_OFFSET)))
324
325 #define CY_SD_HOST_IS_DMA_VALID(dmaType) ((CY_SD_HOST_DMA_SDMA == (dmaType)) || \
326 (CY_SD_HOST_DMA_ADMA2 == (dmaType)) || \
327 (CY_SD_HOST_DMA_ADMA2_ADMA3 == (dmaType)))
328
329 #define CY_SD_HOST_IS_SPEED_MODE_VALID(speedMode) ((CY_SD_HOST_BUS_SPEED_DEFAULT == (speedMode)) || \
330 (CY_SD_HOST_BUS_SPEED_HIGHSPEED == (speedMode)) || \
331 (CY_SD_HOST_BUS_SPEED_SDR12_5 == (speedMode)) || \
332 (CY_SD_HOST_BUS_SPEED_SDR25 == (speedMode)) || \
333 (CY_SD_HOST_BUS_SPEED_SDR50 == (speedMode)) || \
334 (CY_SD_HOST_BUS_SPEED_DDR50 == (speedMode)) || \
335 (CY_SD_HOST_BUS_SPEED_EMMC_LEGACY == (speedMode)) || \
336 (CY_SD_HOST_BUS_SPEED_EMMC_HIGHSPEED_SDR == (speedMode)))
337
338 #define CY_SD_HOST_IS_DMA_WR_RD_VALID(dmaType) ((CY_SD_HOST_DMA_SDMA == (dmaType)) || \
339 (CY_SD_HOST_DMA_ADMA2 == (dmaType)))
340
341 #define CY_SD_HOST_IS_CMD_TYPE_VALID(cmdType) ((CY_SD_HOST_CMD_NORMAL == (cmdType)) || \
342 (CY_SD_HOST_CMD_SUSPEND == (cmdType)) || \
343 (CY_SD_HOST_CMD_RESUME == (cmdType)) || \
344 (CY_SD_HOST_CMD_ABORT == (cmdType)))
345
346 #define CY_SD_HOST_IS_RELIABLE_WRITE(cardType, rw) ((CY_SD_HOST_EMMC != (cardType)) && \
347 (false == (rw)))
348
349 /** \endcond */
350
351 __STATIC_INLINE cy_en_sd_host_status_t Cy_SD_Host_eMMC_InitCard(SDHC_Type *base,
352 cy_stc_sd_host_sd_card_config_t const *config,
353 cy_stc_sd_host_context_t *context);
354 static cy_en_sd_host_status_t Cy_SD_Host_CmdRxData(SDHC_Type *base, cy_stc_sd_host_data_config_t *pcmd);
355 __STATIC_INLINE cy_en_sd_host_status_t Cy_SD_Host_CmdTxData(SDHC_Type *base, cy_stc_sd_host_data_config_t *pcmd);
356 static cy_en_sd_host_status_t Cy_SD_Host_OpsGoIdle(SDHC_Type *base);
357 static cy_en_sd_host_status_t Cy_SD_Host_OpsVoltageSwitch(SDHC_Type *base,
358 cy_stc_sd_host_context_t const *context);
359 static cy_en_sd_host_status_t Cy_SD_Host_OpsSwitchFunc(SDHC_Type *base,
360 uint32_t cmdArgument);
361 static cy_en_sd_host_status_t Cy_SD_Host_SdCardSwitchFunc(SDHC_Type *base, uint32_t cmdArgument,
362 cy_en_sd_host_card_type_t cardType);
363 static cy_en_sd_host_bus_speed_mode_t Cy_SD_Host_FindBusSpeedMode(SDHC_Type *base, bool lowVoltageSignaling,
364 cy_en_sd_host_card_type_t cardType);
365 __STATIC_INLINE cy_en_sd_host_status_t Cy_SD_Host_OpsSetBlockCount(SDHC_Type *base,
366 bool reliableWrite,
367 uint32_t blockNum);
368 __STATIC_INLINE cy_en_sd_host_status_t Cy_SD_Host_OpsProgramCsd(SDHC_Type *base,
369 uint32_t csd,
370 cy_stc_sd_host_context_t *context);
371 static cy_en_sd_host_status_t Cy_SD_Host_OpsSelectCard(SDHC_Type *base,
372 cy_stc_sd_host_context_t const *context);
373 static cy_en_sd_host_status_t Cy_SD_Host_OpsSendIoRwDirectCmd(SDHC_Type *base,
374 uint32_t rwFlag,
375 uint32_t functionNumber,
376 uint32_t rawFlag,
377 uint32_t registerAddress,
378 uint32_t data);
379 static cy_en_sd_host_status_t Cy_SD_Host_OpsSendAppCmd(SDHC_Type *base,
380 cy_stc_sd_host_context_t const *context);
381 __STATIC_INLINE cy_en_sd_host_status_t Cy_SD_Host_OpsSendIfCond(SDHC_Type *base,
382 uint32_t cmdArgument,
383 bool noResponse);
384 __STATIC_INLINE cy_en_sd_host_status_t Cy_SD_Host_OpsSetSdBusWidth(SDHC_Type *base,
385 uint32_t cmdArgument,
386 cy_stc_sd_host_context_t const *context);
387 static cy_en_sd_host_status_t Cy_SD_Host_OpsSdioSendOpCond(SDHC_Type *base,
388 uint32_t *ocrReg,
389 uint32_t cmdArgument);
390 static cy_en_sd_host_status_t Cy_SD_Host_OpsSdSendOpCond(SDHC_Type *base,
391 uint32_t *ocrReg,
392 uint32_t cmdArgument,
393 cy_stc_sd_host_context_t const *context);
394 static cy_en_sd_host_status_t Cy_SD_Host_MmcOpsSendOpCond(SDHC_Type *base,
395 uint32_t *ocrReg,
396 uint32_t cmdArgument);
397 static cy_en_sd_host_status_t Cy_SD_Host_SdCardChangeClock(SDHC_Type *base, uint32_t frequency);
398 __STATIC_INLINE cy_en_sd_host_status_t Cy_SD_Host_PollBufferReadReady(SDHC_Type *base);
399 __STATIC_INLINE cy_en_sd_host_status_t Cy_SD_Host_PollBufferWriteReady(SDHC_Type *base);
400 __STATIC_INLINE cy_en_sd_host_status_t Cy_SD_Host_PollCmdComplete(SDHC_Type *base);
401 __STATIC_INLINE cy_en_sd_host_status_t Cy_SD_Host_PollTransferComplete(SDHC_Type *base);
402 static void Cy_SD_Host_ErrorReset(SDHC_Type *base);
403 static void Cy_SD_Host_NormalReset(SDHC_Type *base);
404 __STATIC_INLINE bool Cy_SD_Host_VoltageCheck(SDHC_Type *base);
405 __STATIC_INLINE cy_en_sd_host_status_t Cy_SD_Host_IoOcr(SDHC_Type *base,
406 bool lowVoltageSignaling,
407 uint32_t *s18aFlag,
408 uint32_t *sdioFlag,
409 bool *mpFlag,
410 uint32_t *ocrReg);
411 __STATIC_INLINE cy_en_sd_host_status_t Cy_SD_Host_SdOcr(SDHC_Type *base,
412 bool lowVoltageSignaling,
413 uint32_t *s18aFlag,
414 bool *mpFlag,
415 bool f8Flag,
416 uint32_t *ocrReg,
417 cy_stc_sd_host_context_t *context);
418 __STATIC_INLINE cy_en_sd_host_status_t Cy_SD_Host_PollCmdLineFree(SDHC_Type const *base);
419 __STATIC_INLINE cy_en_sd_host_status_t Cy_SD_Host_PollDataLineNotInhibit(SDHC_Type const *base);
420 __STATIC_INLINE cy_en_sd_host_status_t Cy_SD_Host_PollDataLineFree(SDHC_Type const *base);
421
422 /* High-level section */
423
424 /*******************************************************************************
425 * Function Name: Cy_SD_Host_eMMC_InitCard
426 ****************************************************************************//**
427 *
428 * Initializes the eMMC card.
429 *
430 * \param *base
431 * The SD host registers structure pointer.
432 *
433 * \param *config
434 * The pointer to the SD card configuration structure.
435 *
436 * \param context
437 * The pointer to the context structure \ref cy_stc_sd_host_context_t allocated
438 * by the user. The structure is used during the SD host operation for internal
439 * configuration and data retention. The user must not modify anything
440 * in this structure.
441 * If only the SD host functions which do not require context will be used, pass NULL
442 * as the pointer to the context.
443 *
444 * \return \ref cy_en_sd_host_status_t
445 *
446 *******************************************************************************/
Cy_SD_Host_eMMC_InitCard(SDHC_Type * base,cy_stc_sd_host_sd_card_config_t const * config,cy_stc_sd_host_context_t * context)447 __STATIC_INLINE cy_en_sd_host_status_t Cy_SD_Host_eMMC_InitCard(SDHC_Type *base,
448 cy_stc_sd_host_sd_card_config_t const *config,
449 cy_stc_sd_host_context_t *context)
450 {
451 cy_en_sd_host_status_t ret = CY_SD_HOST_SUCCESS;
452 cy_en_sd_host_bus_speed_mode_t speedMode = CY_SD_HOST_BUS_SPEED_EMMC_LEGACY;
453 uint32_t retry;
454 uint32_t ocrReg; /* The Operation Condition register. */
455 uint32_t cidReg[CY_SD_HOST_CID_SIZE]; /* The Device Identification register. */
456 uint32_t extCsd[CY_SD_HOST_EXTCSD_SIZE] = { 0UL };
457 uint32_t genericCmd6Time;
458 uint32_t csdReg[CY_SD_HOST_CSD_SIZE]; /* The Card-Specific Data register. */
459
460 /* Reset Card (CMD0). */
461 ret = Cy_SD_Host_OpsGoIdle(base); /* The Idle state. */
462
463 /* Software reset for the CMD line */
464 Cy_SD_Host_SoftwareReset(base, CY_SD_HOST_RESET_DATALINE);
465 Cy_SD_Host_SoftwareReset(base, CY_SD_HOST_RESET_CMD_LINE);
466
467 retry = CY_SD_HOST_RETRY_TIME;
468 while (retry > 0UL)
469 {
470 /* Get OCR (CMD1). */
471 ret = Cy_SD_Host_MmcOpsSendOpCond(base, &ocrReg, CY_SD_HOST_EMMC_VOLTAGE_WINDOW);
472
473 context->cardCapacity = CY_SD_HOST_EMMC_LESS_2G;
474
475 /* Check if the eMMC capacity is greater than 2GB */
476 if (CY_SD_HOST_OCR_CAPACITY_MASK == (ocrReg & CY_SD_HOST_OCR_CAPACITY_MASK))
477 {
478 context->cardCapacity = CY_SD_HOST_EMMC_GREATER_2G;
479 }
480
481 if (CY_SD_HOST_SUCCESS == ret)
482 {
483 break;
484 }
485 else
486 {
487 Cy_SD_Host_ErrorReset(base);
488
489 Cy_SysLib_DelayUs(CY_SD_HOST_CMD1_TIMEOUT_MS); /* The CMD1 timeout. */
490 }
491 retry--;
492 }
493
494 /* The low voltage operation check. */
495 if ((true == config->lowVoltageSignaling) &&
496 (CY_SD_HOST_EMMC_DUAL_VOLTAGE == (ocrReg & CY_SD_HOST_EMMC_DUAL_VOLTAGE)))
497 {
498 /* Power down the MMC bus */
499 Cy_SD_Host_DisableCardVoltage(base);
500
501 Cy_SysLib_Delay(CY_SD_HOST_1_8_REG_STABLE_TIME_MS);
502
503 /* Switch the bus to 1.8 V */
504 Cy_SD_Host_ChangeIoVoltage(base, CY_SD_HOST_IO_VOLT_1_8V);
505
506 Cy_SD_Host_EnableCardVoltage(base);
507 (void)Cy_SD_Host_SdCardChangeClock(base, CY_SD_HOST_CLK_400K);
508
509 /* Wait 10 ms */
510 Cy_SysLib_Delay(CY_SD_HOST_1_8_REG_STABLE_TIME_MS);
511
512 retry = CY_SD_HOST_RETRY_TIME;
513 while (retry > 0UL)
514 {
515 /* Get OCR (CMD1). */
516 ret = Cy_SD_Host_MmcOpsSendOpCond(base, &ocrReg, CY_SD_HOST_EMMC_VOLTAGE_WINDOW);
517
518 Cy_SD_Host_ErrorReset(base);
519
520 if (CY_SD_HOST_SUCCESS == ret)
521 {
522 break;
523 }
524
525 Cy_SysLib_DelayUs(CY_SD_HOST_CMD1_TIMEOUT_MS); /* The CMD1 timeout. */
526 retry--;
527 }
528 }
529
530 if (CY_SD_HOST_SUCCESS == ret) /* The ready state. */
531 {
532 /* Get CID (CMD2). */
533 ret = Cy_SD_Host_GetCid(base, cidReg);
534
535 Cy_SysLib_DelayUs(CY_SD_HOST_NCC_MIN_US);
536
537 if (CY_SD_HOST_SUCCESS == ret) /* The Identification state. */
538 {
539 /* Get RCA (CMD3) */
540 context->RCA = Cy_SD_Host_GetRca(base);
541
542 /* The stand-by state. */
543
544 /* Get CSD (CMD9) */
545 ret = Cy_SD_Host_GetCsd(base, csdReg, context);
546
547 if (CY_SD_HOST_SUCCESS == ret)
548 {
549 /* Select the card (CMD7). */
550 ret = Cy_SD_Host_OpsSelectCard(base, context);
551
552 if (CY_SD_HOST_SUCCESS == ret) /* The transfer state. */
553 {
554 /* Get Ext CSD (CMD8).
555 * Capacity Type and Max Sector Num are in the context.
556 */
557 ret = Cy_SD_Host_GetExtCsd(base, extCsd, context);
558
559 /* Get GENERIC_CMD6_TIME [248] of the EXTCSD register */
560 genericCmd6Time = CY_SD_HOST_EMMC_CMD6_TIMEOUT_MULT *
561 (extCsd[CY_SD_HOST_EXTCSD_GENERIC_CMD6_TIME] &
562 CY_SD_HOST_EXTCSD_GENERIC_CMD6_TIME_MSK);
563
564 if ((CY_SD_HOST_SUCCESS == ret) &&
565 (CY_SD_HOST_BUS_WIDTH_1_BIT != config->busWidth))
566 {
567 /* Set Bus Width (CMD6) */
568 ret = Cy_SD_Host_SetBusWidth(base,
569 config->busWidth,
570 context);
571
572 Cy_SysLib_Delay(genericCmd6Time); /* The CMD6 timeout. */
573 }
574
575 if (CY_SD_HOST_SUCCESS == ret)
576 {
577 /* Set Bus Speed Mode (CMD6). */
578 ret = Cy_SD_Host_SetBusSpeedMode(base,
579 speedMode,
580 context);
581 if (CY_SD_HOST_SUCCESS == ret)
582 {
583 (void)Cy_SD_Host_SdCardChangeClock(base, CY_SD_HOST_CLK_25M);
584 }
585 Cy_SysLib_Delay(CY_SD_HOST_CLK_RAMP_UP_TIME_MS);
586 }
587 }
588 }
589 }
590 }
591
592 return ret;
593 }
594
595
596 /*******************************************************************************
597 * Function Name: Cy_SD_Host_InitCard
598 ****************************************************************************//**
599 *
600 * Initializes a card if it is connected.
601 * After this function is called, the card is in the transfer state.
602 *
603 * \param *base
604 * The SD host registers structure pointer.
605 *
606 * \param *config
607 * The pointer to the SD card configuration structure.
608 *
609 * \param context
610 * The pointer to the context structure \ref cy_stc_sd_host_context_t allocated
611 * by the user. The structure is used during the SD host operation for internal
612 * configuration and data retention. The user must not modify anything
613 * in this structure.
614 * If only the SD host functions which do not require context will be used, pass NULL
615 * as the pointer to the context.
616 *
617 * \return \ref cy_en_sd_host_status_t
618 *
619 * \note When lowVoltageSignaling is True, this function negotiates with
620 * the card to change the bus signaling level to 1.8V.
621 * The dedicated io_volt_sel pin is used to change the regulator supplying voltage
622 * to the VDDIO of the SD block in order to operate at 1.8V. To configure
623 * the custom IO pin in order to control (using the GPIO driver) the regulator
624 * supplying voltage, the user must implement weak Cy_SD_Host_ChangeIoVoltage().
625 * Also, this function must set the SIGNALING_EN bit of the SDHC_CORE_HOST_CTRL2_R
626 * register when ioVoltage = CY_SD_HOST_IO_VOLT_1_8V.
627 *
628 * \note lowVoltageSignaling is not supported for CAT1C devices.
629 *
630 * \note After calling this function, the SD Host is configured in
631 * highest supported bus speed mode (for the SD card, irrespective of
632 * the value of lowVoltageSignaling), or eMMC legacy (for the eMMC card)
633 * with SD clock = 25 MHz. The Power Limit and Driver Strength functions of
634 * the CMD6 command are set into the default state (0.72 W and Type B).
635 * It is the user's responsibility to set Power Limit and Driver Strength
636 * depending on the capacitance load of the host system.
637 * To change Speed mode, the user must call the Cy_SD_Host_SetBusSpeedMode()
638 * and Cy_SD_Host_SdCardChangeClock() functions.
639 * Additionally, SD SDR25, SD SDR50, eMMC High Speed SDR modes require
640 * settings CLOCK_OUT_DLY and CLOCK_IN_DLY bit-fields of the GP_OUT_R register.
641 * For more information about Speed modes, refer to Part 1 Physical Layer
642 * SD Specification.
643 *******************************************************************************/
Cy_SD_Host_InitCard(SDHC_Type * base,cy_stc_sd_host_sd_card_config_t * config,cy_stc_sd_host_context_t * context)644 cy_en_sd_host_status_t Cy_SD_Host_InitCard(SDHC_Type *base,
645 cy_stc_sd_host_sd_card_config_t *config,
646 cy_stc_sd_host_context_t *context)
647 {
648 cy_en_sd_host_status_t ret = CY_SD_HOST_ERROR_INVALID_PARAMETER;
649 cy_en_sd_host_bus_speed_mode_t speedMode = CY_SD_HOST_BUS_SPEED_DEFAULT;
650 uint32_t ocrReg; /* The Operation Condition register. */
651 uint32_t cidReg[CY_SD_HOST_CID_SIZE]; /* The Device Identification register. */
652 uint32_t csdReg[CY_SD_HOST_CSD_SIZE]; /* The Card-Specific Data register. */
653 uint32_t sdioFlag = 0UL; /* The IO flag. */
654 uint32_t s18aFlag = 0UL; /* The S18A flag. */
655 bool f8Flag = false; /* The CMD8 flag. */
656 bool mpFlag = false; /* The MEM flag. */
657
658 if ((NULL != base) && (NULL != context) && (NULL != config))
659 {
660 CY_ASSERT_L3(CY_SD_HOST_IS_BUS_WIDTH_VALID(config->busWidth, context->cardType));
661
662 /* Wait until the card is stable and check if it is connected. */
663 if ((true == Cy_SD_Host_IsCardConnected(base)) ||
664 (CY_SD_HOST_EMMC == context->cardType))
665 {
666 Cy_SD_Host_EnableCardVoltage(base);
667
668 Cy_SD_Host_ChangeIoVoltage(base, CY_SD_HOST_IO_VOLT_3_3V);
669
670 /* Set the host bus width to 1 bit. */
671 (void)Cy_SD_Host_SetHostBusWidth(base, CY_SD_HOST_BUS_WIDTH_1_BIT);
672
673 /* Change the host SD clock to 400 kHz. */
674 (void)Cy_SD_Host_SdCardChangeClock(base, CY_SD_HOST_CLK_400K);
675
676 /* Wait until the voltage and clock are stable. */
677 Cy_SysLib_Delay(CY_SD_HOST_BUS_RAMP_UP_TIME_MS);
678
679 context->RCA = 0UL;
680
681 if (CY_SD_HOST_EMMC != context->cardType)
682 {
683 /* Send CMD0 and CMD8 commands. */
684 f8Flag = Cy_SD_Host_VoltageCheck(base);
685
686 /* Set SDHC can be supported. */
687 if (f8Flag)
688 {
689 context->cardCapacity = CY_SD_HOST_SDHC;
690 }
691
692 /* Clear the insert event */
693 Cy_SD_Host_NormalReset(base);
694 Cy_SysLib_Delay(1);
695
696 /* Send CMD5 to get IO OCR */
697 ret = Cy_SD_Host_IoOcr(base,
698 config->lowVoltageSignaling,
699 &s18aFlag,
700 &sdioFlag,
701 &mpFlag,
702 &ocrReg);
703
704 /* Check if CMD5 has no response or MP = 1.
705 * This means we have a SD memory card or Combo card.
706 */
707 if (mpFlag || (0UL == sdioFlag))
708 {
709 /* Send ACMD41 */
710 ret = Cy_SD_Host_SdOcr(base,
711 config->lowVoltageSignaling,
712 &s18aFlag,
713 &mpFlag,
714 f8Flag,
715 &ocrReg,
716 context);
717 }
718
719 /* Set the card type */
720 if (CY_SD_HOST_ERROR_UNUSABLE_CARD != ret) /* The Ready state. */
721 {
722 if (true == mpFlag)
723 {
724 if (0UL != sdioFlag)
725 {
726 context->cardType = CY_SD_HOST_COMBO;
727 }
728 else
729 {
730 context->cardType = CY_SD_HOST_SD;
731 }
732 }
733 else if (0UL != sdioFlag)
734 {
735 context->cardType = CY_SD_HOST_SDIO;
736 }
737 else
738 {
739 /* The unusable card */
740 ret = CY_SD_HOST_ERROR_UNUSABLE_CARD;
741
742 context->cardType = CY_SD_HOST_UNUSABLE;
743 }
744
745 if (CY_SD_HOST_ERROR_UNUSABLE_CARD != ret)
746 {
747 if ((1UL == s18aFlag) && (config->lowVoltageSignaling))
748 {
749 /* Voltage switch (CMD11). */
750 ret = Cy_SD_Host_OpsVoltageSwitch(base, context);
751
752 if (CY_SD_HOST_SUCCESS != ret) /* Initialize again at 3.3 V. */
753 {
754 Cy_SD_Host_ChangeIoVoltage(base, CY_SD_HOST_IO_VOLT_3_3V);
755
756 /* Wait until the voltage and clock are stable. */
757 Cy_SysLib_Delay(CY_SD_HOST_BUS_RAMP_UP_TIME_MS);
758
759 /* Send CMD0 and CMD8 commands. */
760 f8Flag = Cy_SD_Host_VoltageCheck(base);
761
762 if (0UL < sdioFlag)
763 {
764 /* Send CMD5 to get IO OCR. */
765 ret = Cy_SD_Host_IoOcr(base,
766 config->lowVoltageSignaling,
767 &s18aFlag,
768 &sdioFlag,
769 &mpFlag,
770 &ocrReg);
771 }
772
773 if (mpFlag)
774 {
775 /* Send ACMD41 */
776 ret = Cy_SD_Host_SdOcr(base,
777 config->lowVoltageSignaling,
778 &s18aFlag,
779 &mpFlag,
780 f8Flag,
781 &ocrReg,
782 context);
783 }
784
785 s18aFlag = 0UL;
786 }
787 }
788
789 if (CY_SD_HOST_SDIO != context->cardType)
790 {
791 /* Get CID (CMD2). */
792 ret = Cy_SD_Host_GetCid(base, cidReg);
793
794 Cy_SysLib_DelayUs(CY_SD_HOST_NCC_MIN_US);
795 } /* The Identification state. */
796
797 /* Get RCA (CMD3). */
798 context->RCA = Cy_SD_Host_GetRca(base);
799
800 Cy_SysLib_DelayUs(CY_SD_HOST_NCC_MIN_US);
801
802 if (CY_SD_HOST_SDIO != context->cardType) /* The stand-by state. */
803 {
804 /* Get CSD (CMD9) to save
805 * Max Sector Number in the context.
806 */
807 ret = Cy_SD_Host_GetCsd(base, csdReg, context);
808
809 if (CY_SD_HOST_MIN_SDXC_SECTORS <= context->maxSectorNum)
810 {
811 context->cardCapacity = CY_SD_HOST_SDXC;
812 }
813
814 Cy_SysLib_DelayUs(CY_SD_HOST_NCC_MIN_US);
815 }
816
817 if (CY_SD_HOST_SUCCESS == ret) /* The Standby state. */
818 {
819 /* Select the card (CMD7). */
820 ret = Cy_SD_Host_OpsSelectCard(base, context);
821 }
822
823 if ((CY_SD_HOST_SUCCESS == ret) &&
824 (CY_SD_HOST_SDIO != context->cardType)) /* The Transition state. */
825 {
826 /* Set Bus Width (ACMD6). */
827 if (CY_SD_HOST_BUS_WIDTH_1_BIT != config->busWidth)
828 {
829 ret = Cy_SD_Host_SetBusWidth(base,
830 CY_SD_HOST_BUS_WIDTH_4_BIT,
831 context);
832 Cy_SysLib_Delay(CY_SD_HOST_READ_TIMEOUT_MS);
833 }
834
835 if (CY_SD_HOST_SUCCESS == ret)
836 {
837 /* Find Highest Supported Bus Speed Mode (CMD6). */
838 speedMode = Cy_SD_Host_FindBusSpeedMode(base, ((bool)s18aFlag && config->lowVoltageSignaling), context->cardType);
839 Cy_SysLib_Delay(CY_SD_HOST_READ_TIMEOUT_MS);
840
841
842 /* Set Bus Speed Mode (CMD6). */
843 ret = Cy_SD_Host_SetBusSpeedMode(base,
844 speedMode,
845 context);
846 Cy_SysLib_Delay(CY_SD_HOST_READ_TIMEOUT_MS);
847
848 if (CY_SD_HOST_SUCCESS == ret)
849 {
850 (void)Cy_SD_Host_SdCardChangeClock(base,
851 CY_SD_HOST_CLK_25M);
852 }
853 Cy_SysLib_Delay(CY_SD_HOST_CLK_RAMP_UP_TIME_MS);
854 }
855 }
856 }
857 }
858 }
859 else
860 {
861 ret = Cy_SD_Host_eMMC_InitCard(base, config, context);
862 }
863
864 *config->rca = context->RCA;
865 *config->cardType = context->cardType;
866 *config->cardCapacity = context->cardCapacity;
867 }
868 else
869 {
870 /* The SD card is disconnected or an embedded card. */
871 ret = CY_SD_HOST_ERROR_DISCONNECTED;
872 }
873 }
874
875 return ret;
876 }
877
878
879 /*******************************************************************************
880 * Function Name: Cy_SD_Host_Read
881 ****************************************************************************//**
882 *
883 * Reads single- or multiple-block data from the SD card / eMMC. If DMA is not used
884 * this function blocks until all data is read.
885 * If DMA is used all data is read when the Transfer complete event is set.
886 * It is the user responsibility to check and reset the transfer complete event
887 * (using \ref Cy_SD_Host_GetNormalInterruptStatus and
888 * \ref Cy_SD_Host_ClearNormalInterruptStatus functions).
889 *
890 * \param *base
891 * The SD host registers structure pointer.
892 *
893 * \param *config
894 * The pointer to the SD card read-write structure.
895 *
896 * \param context
897 * The pointer to the context structure \ref cy_stc_sd_host_context_t allocated
898 * by the user. The structure is used during the SD host operation for internal
899 * configuration and data retention. The user must not modify anything
900 * in this structure.
901 * If only the SD host functions which do not require context will be used, pass NULL
902 * as the pointer to the context.
903 *
904 * \return \ref cy_en_sd_host_status_t
905 *
906 *******************************************************************************/
Cy_SD_Host_Read(SDHC_Type * base,cy_stc_sd_host_write_read_config_t * config,cy_stc_sd_host_context_t const * context)907 cy_en_sd_host_status_t Cy_SD_Host_Read(SDHC_Type *base,
908 cy_stc_sd_host_write_read_config_t *config,
909 cy_stc_sd_host_context_t const *context)
910 {
911 cy_en_sd_host_status_t ret = CY_SD_HOST_ERROR_INVALID_PARAMETER;
912 cy_stc_sd_host_cmd_config_t cmd;
913 cy_stc_sd_host_data_config_t dataConfig;
914 uint32_t dataAddress;
915 uint32_t aDmaDescriptTbl[CY_SD_HOST_ADMA2_DESCR_SIZE]; /* The ADMA2 descriptor table. */
916 uint32_t length; /* The length of data to transfer for a descriptor. */
917
918 if ((NULL != context) && (NULL != config) && (NULL != config->data))
919 {
920 CY_ASSERT_L3(CY_SD_HOST_IS_AUTO_CMD_VALID(config->autoCommand));
921 CY_ASSERT_L2(CY_SD_HOST_IS_TIMEOUT_VALID(config->dataTimeout));
922 CY_ASSERT_L3(CY_SD_HOST_IS_DMA_WR_RD_VALID(context->dmaType));
923
924 dataAddress = config->address;
925 /* 0 < maxSectorNum check is needed for legacy cards. */
926 if (!((0UL < context->maxSectorNum) &&
927 ((context->maxSectorNum - dataAddress) < config->numberOfBlocks)))
928 {
929 if (CY_SD_HOST_SDSC == context->cardCapacity)
930 {
931 dataAddress = dataAddress << CY_SD_HOST_SDSC_ADDR_SHIFT;
932 }
933
934 if (1UL < config->numberOfBlocks)
935 {
936 cmd.commandIndex = CY_SD_HOST_SD_CMD18;
937 dataConfig.enableIntAtBlockGap = true;
938 }
939 else
940 {
941 cmd.commandIndex = CY_SD_HOST_SD_CMD17;
942 dataConfig.enableIntAtBlockGap = false;
943 }
944
945 dataConfig.blockSize = CY_SD_HOST_BLOCK_SIZE;
946 dataConfig.numberOfBlock = config->numberOfBlocks;
947 dataConfig.enableDma = config->enableDma;
948 dataConfig.autoCommand = config->autoCommand;
949 dataConfig.read = true;
950 dataConfig.dataTimeout = config->dataTimeout;
951 dataConfig.enReliableWrite = config->enReliableWrite;
952
953 if ((true == dataConfig.enableDma) &&
954 (CY_SD_HOST_DMA_ADMA2 == context->dmaType))
955 {
956 length = CY_SD_HOST_BLOCK_SIZE * config->numberOfBlocks;
957
958 aDmaDescriptTbl[0] = (1UL << CY_SD_HOST_ADMA_ATTR_VALID_POS) | /* Attr Valid */
959 (1UL << CY_SD_HOST_ADMA_ATTR_END_POS) | /* Attr End */
960 (0UL << CY_SD_HOST_ADMA_ATTR_INT_POS) | /* Attr Int */
961 (CY_SD_HOST_ADMA_TRAN << CY_SD_HOST_ADMA_ACT_POS) |
962 (length << CY_SD_HOST_ADMA_LEN_POS); /* Len */
963
964 aDmaDescriptTbl[1] = (uint32_t)config->data;
965
966 /* The address of the ADMA2 descriptor table. */
967 dataConfig.data = (uint32_t*)&aDmaDescriptTbl[0];
968 }
969 else
970 {
971 /* SDMA mode. */
972 dataConfig.data = (uint32_t*)config->data;
973 }
974
975 ret = Cy_SD_Host_InitDataTransfer(base, &dataConfig);
976
977 if (CY_SD_HOST_SUCCESS == ret)
978 {
979 cmd.commandArgument = dataAddress;
980 cmd.dataPresent = true;
981 cmd.enableAutoResponseErrorCheck = false;
982 cmd.respType = CY_SD_HOST_RESPONSE_LEN_48;
983 cmd.enableCrcCheck = true;
984 cmd.enableIdxCheck = true;
985 cmd.cmdType = CY_SD_HOST_CMD_NORMAL;
986
987 ret = Cy_SD_Host_SendCommand(base, &cmd);
988
989 if (CY_SD_HOST_SUCCESS == ret)
990 {
991 /* Wait for the Command Complete event. */
992 ret = Cy_SD_Host_PollCmdComplete(base);
993 }
994
995 if ((CY_SD_HOST_SUCCESS == ret) &&
996 (false == dataConfig.enableDma))
997 {
998 /* DMA is not used - wait until all data is read. */
999 ret = Cy_SD_Host_CmdRxData(base, &dataConfig);
1000 }
1001 }
1002 }
1003 }
1004
1005 return ret;
1006 }
1007
1008
1009 /*******************************************************************************
1010 * Function Name: Cy_SD_Host_Write
1011 ****************************************************************************//**
1012 *
1013 * Writes single- or multiple-block data to the SD card / eMMC. If DMA is not
1014 * used this function blocks until all data is written.
1015 * If DMA is used all data is written when the Transfer complete event is set.
1016 * It is the user responsibility to check and reset the transfer complete event
1017 * (using \ref Cy_SD_Host_GetNormalInterruptStatus and
1018 * \ref Cy_SD_Host_ClearNormalInterruptStatus functions).
1019 *
1020 * \param *base
1021 * The SD host registers structure pointer.
1022 *
1023 * \param *config
1024 * The pointer to the SD card read-write structure.
1025 *
1026 * \param context
1027 * The pointer to the context structure \ref cy_stc_sd_host_context_t allocated
1028 * by the user. The structure is used during the SD host operation for internal
1029 * configuration and data retention. The user must not modify anything
1030 * in this structure.
1031 * If only the SD host functions which do not require context will be used, pass NULL
1032 * as the pointer to the context.
1033 *
1034 * \return \ref cy_en_sd_host_status_t
1035 *
1036 *******************************************************************************/
Cy_SD_Host_Write(SDHC_Type * base,cy_stc_sd_host_write_read_config_t * config,cy_stc_sd_host_context_t const * context)1037 cy_en_sd_host_status_t Cy_SD_Host_Write(SDHC_Type *base,
1038 cy_stc_sd_host_write_read_config_t *config,
1039 cy_stc_sd_host_context_t const *context)
1040 {
1041 cy_en_sd_host_status_t ret = CY_SD_HOST_ERROR_INVALID_PARAMETER;
1042 cy_stc_sd_host_cmd_config_t cmd;
1043 cy_stc_sd_host_data_config_t dataConfig;
1044 uint32_t dataAddress;
1045 uint32_t aDmaDescriptTbl[CY_SD_HOST_ADMA2_DESCR_SIZE]; /* The ADMA2 descriptor table. */
1046 uint32_t length; /* The length of data to transfer for a descriptor. */
1047
1048 if ((NULL != context) && (NULL != config) && (NULL != config->data))
1049 {
1050 CY_ASSERT_L3(CY_SD_HOST_IS_AUTO_CMD_VALID(config->autoCommand));
1051 CY_ASSERT_L2(CY_SD_HOST_IS_TIMEOUT_VALID(config->dataTimeout));
1052 CY_ASSERT_L3(CY_SD_HOST_IS_DMA_WR_RD_VALID(context->dmaType));
1053
1054 dataAddress = config->address;
1055
1056 /* 0 < maxSectorNum check is needed for legacy cards */
1057 if (!((0UL < context->maxSectorNum) &&
1058 ((context->maxSectorNum - dataAddress) < config->numberOfBlocks)))
1059 {
1060 if (CY_SD_HOST_SDSC == context->cardCapacity)
1061 {
1062 /* The SDSC card uses a byte-unit address, multiply by 512 */
1063 dataAddress = dataAddress << CY_SD_HOST_SDSC_ADDR_SHIFT;
1064 }
1065
1066 if (1UL < config->numberOfBlocks)
1067 {
1068 cmd.commandIndex = CY_SD_HOST_SD_CMD25;
1069 dataConfig.enableIntAtBlockGap = true;
1070 }
1071 else
1072 {
1073 cmd.commandIndex = CY_SD_HOST_SD_CMD24;
1074 dataConfig.enableIntAtBlockGap = false;
1075 }
1076
1077 dataConfig.blockSize = CY_SD_HOST_BLOCK_SIZE;
1078 dataConfig.numberOfBlock = config->numberOfBlocks;
1079 dataConfig.enableDma = config->enableDma;
1080 dataConfig.autoCommand = config->autoCommand;
1081 dataConfig.read = false;
1082 dataConfig.data = (uint32_t*)config->data;
1083 dataConfig.dataTimeout = config->dataTimeout;
1084 dataConfig.enReliableWrite = config->enReliableWrite;
1085
1086 if ((true == dataConfig.enableDma) &&
1087 (CY_SD_HOST_DMA_ADMA2 == context->dmaType))
1088 {
1089 length = CY_SD_HOST_BLOCK_SIZE * config->numberOfBlocks;
1090
1091 aDmaDescriptTbl[0] = (1UL << CY_SD_HOST_ADMA_ATTR_VALID_POS) | /* Attr Valid */
1092 (1UL << CY_SD_HOST_ADMA_ATTR_END_POS) | /* Attr End */
1093 (0UL << CY_SD_HOST_ADMA_ATTR_INT_POS) | /* Attr Int */
1094 (CY_SD_HOST_ADMA_TRAN << CY_SD_HOST_ADMA_ACT_POS) |
1095 (length << CY_SD_HOST_ADMA_LEN_POS); /* Len */
1096
1097 aDmaDescriptTbl[1] = (uint32_t)config->data;
1098
1099 /* The address of the ADMA descriptor table. */
1100 dataConfig.data = (uint32_t*)&aDmaDescriptTbl[0];
1101 }
1102 else
1103 {
1104 dataConfig.data = (uint32_t*)config->data;
1105 }
1106
1107 ret = Cy_SD_Host_InitDataTransfer(base, &dataConfig);
1108
1109 if (CY_SD_HOST_SUCCESS == ret)
1110 {
1111 cmd.commandArgument = dataAddress;
1112 cmd.dataPresent = true;
1113 cmd.enableAutoResponseErrorCheck = false;
1114 cmd.respType = CY_SD_HOST_RESPONSE_LEN_48;
1115 cmd.enableCrcCheck = true;
1116 cmd.enableIdxCheck = true;
1117 cmd.cmdType = CY_SD_HOST_CMD_NORMAL;
1118
1119 ret = Cy_SD_Host_SendCommand(base, &cmd);
1120
1121 if (CY_SD_HOST_SUCCESS == ret)
1122 {
1123 /* Wait for the Command Complete event. */
1124 ret = Cy_SD_Host_PollCmdComplete(base);
1125 }
1126
1127 if ((CY_SD_HOST_SUCCESS == ret) &&
1128 (false == dataConfig.enableDma))
1129 {
1130 /* DMA is not used - wait until all data is written. */
1131 ret = Cy_SD_Host_CmdTxData(base, &dataConfig);
1132 }
1133 }
1134 }
1135 }
1136
1137 return ret;
1138 }
1139
1140
1141 /*******************************************************************************
1142 * Function Name: Cy_SD_Host_Erase
1143 ****************************************************************************//**
1144 *
1145 * Erases the number block data of the SD card / eMMC.
1146 *
1147 * \note This function starts the erase operation end exits.
1148 * It is the user's responsibility to check when the erase operation completes.
1149 * The erase operation completes when \ref Cy_SD_Host_GetCardStatus returns
1150 * the status value where both ready-for-data (CY_SD_HOST_CMD13_READY_FOR_DATA)
1151 * and card-transition (CY_SD_HOST_CARD_TRAN) bits are set.
1152 * Also it is the user's responsibility to clear the CY_SD_HOST_CMD_COMPLETE flag
1153 * after calling this function.
1154 *
1155 * \param *base
1156 * The SD host registers structure pointer.
1157 *
1158 * \param startAddr
1159 * The address to start erasing from.
1160 *
1161 * \param endAddr
1162 * The address to stop erasing.
1163 *
1164 * \param eraseType
1165 * Specifies the erase type (FULE, DISCARD).
1166 *
1167 * \param context
1168 * The pointer to the context structure \ref cy_stc_sd_host_context_t allocated
1169 * by the user. The structure is used during the SD host operation for internal
1170 * configuration and data retention. The user must not modify anything
1171 * in this structure.
1172 * If only the SD host functions which do not require context will be used, pass NULL
1173 * as the pointer to the context.
1174 *
1175 * \return \ref cy_en_sd_host_status_t
1176 *
1177 *******************************************************************************/
Cy_SD_Host_Erase(SDHC_Type * base,uint32_t startAddr,uint32_t endAddr,cy_en_sd_host_erase_type_t eraseType,cy_stc_sd_host_context_t const * context)1178 cy_en_sd_host_status_t Cy_SD_Host_Erase(SDHC_Type *base,
1179 uint32_t startAddr,
1180 uint32_t endAddr,
1181 cy_en_sd_host_erase_type_t eraseType,
1182 cy_stc_sd_host_context_t const *context)
1183 {
1184 cy_en_sd_host_status_t ret = CY_SD_HOST_ERROR_INVALID_PARAMETER;
1185 cy_stc_sd_host_cmd_config_t cmd;
1186
1187 if ((NULL != context) && (NULL != base))
1188 {
1189 /* 0<maxSectorNum check is needed for legacy EMMC cards */
1190 if (!((0UL < context->maxSectorNum) &&
1191 ((context->maxSectorNum < (startAddr)) ||
1192 (context->maxSectorNum < (endAddr)))))
1193 {
1194 /* Initialize the command parameters */
1195 cmd.dataPresent = false;
1196 cmd.enableAutoResponseErrorCheck = false;
1197 cmd.respType = CY_SD_HOST_RESPONSE_LEN_48;
1198 cmd.enableCrcCheck = true;
1199 cmd.enableIdxCheck = true;
1200 cmd.cmdType = CY_SD_HOST_CMD_NORMAL;
1201
1202 /* EraseStartAddr (CMD32) */
1203 if (CY_SD_HOST_SDSC == context->cardCapacity)
1204 {
1205 /* The SDSC card uses a byte-unit address, multiply by 512 */
1206 startAddr = startAddr << CY_SD_HOST_SDSC_ADDR_SHIFT;
1207 }
1208
1209 if (CY_SD_HOST_EMMC == context->cardType)
1210 {
1211 cmd.commandIndex = CY_SD_HOST_SD_CMD35;
1212 }
1213 else
1214 {
1215 cmd.commandIndex = CY_SD_HOST_SD_CMD32;
1216 }
1217 cmd.commandArgument = startAddr;
1218
1219 ret = Cy_SD_Host_SendCommand(base, &cmd);
1220
1221 if (CY_SD_HOST_SUCCESS == ret)
1222 {
1223 /* Wait for the Command Complete event. */
1224 ret = Cy_SD_Host_PollCmdComplete(base);
1225 }
1226
1227 if (CY_SD_HOST_SUCCESS != ret)
1228 {
1229 return ret;
1230 }
1231
1232 /* EraseEndAddr (CMD33) */
1233 if (CY_SD_HOST_SDSC == context->cardCapacity)
1234 {
1235 /* The SDSC card uses a byte-unit address, multiply by 512 */
1236 endAddr = endAddr << CY_SD_HOST_SDSC_ADDR_SHIFT;
1237 }
1238
1239 if (CY_SD_HOST_EMMC == context->cardType)
1240 {
1241 cmd.commandIndex = CY_SD_HOST_SD_CMD36;
1242 }
1243 else
1244 {
1245 cmd.commandIndex = CY_SD_HOST_SD_CMD33;
1246 }
1247 cmd.commandArgument = endAddr;
1248
1249 ret = Cy_SD_Host_SendCommand(base, &cmd);
1250
1251 if (CY_SD_HOST_SUCCESS == ret)
1252 {
1253 /* Wait for the Command Complete event. */
1254 ret = Cy_SD_Host_PollCmdComplete(base);
1255 }
1256
1257 /* Erase (CMD38) */
1258 cmd.commandIndex = CY_SD_HOST_SD_CMD38;
1259
1260 switch (eraseType)
1261 {
1262 case CY_SD_HOST_ERASE_ERASE:
1263 cmd.commandArgument = CY_SD_HOST_ERASE;
1264 break;
1265 case CY_SD_HOST_ERASE_DISCARD:
1266 if (CY_SD_HOST_EMMC == context->cardType)
1267 {
1268 cmd.commandArgument = CY_SD_HOST_EMMC_DISCARD;
1269 }
1270 else
1271 {
1272 cmd.commandArgument = CY_SD_HOST_SD_DISCARD;
1273 }
1274 break;
1275 case CY_SD_HOST_ERASE_FULE:
1276 cmd.commandArgument = CY_SD_HOST_SD_FULE;
1277 break;
1278 case CY_SD_HOST_ERASE_SECURE:
1279 cmd.commandArgument = CY_SD_HOST_EMMC_SECURE_ERASE;
1280 break;
1281 case CY_SD_HOST_ERASE_SECURE_TRIM_STEP_2:
1282 cmd.commandArgument = CY_SD_HOST_EMMC_SECURE_TRIM_STEP_2;
1283 break;
1284 case CY_SD_HOST_ERASE_SECURE_TRIM_STEP_1:
1285 cmd.commandArgument = CY_SD_HOST_EMMC_SECURE_TRIM_STEP_1;
1286 break;
1287 case CY_SD_HOST_ERASE_TRIM:
1288 cmd.commandArgument = CY_SD_HOST_EMMC_TRIM;
1289 break;
1290 default:
1291 ret = CY_SD_HOST_ERROR_INVALID_PARAMETER;
1292 break;
1293 }
1294
1295 if (CY_SD_HOST_SUCCESS == ret)
1296 {
1297 ret = Cy_SD_Host_SendCommand(base, &cmd);
1298 }
1299 }
1300 }
1301
1302 return ret;
1303 }
1304
1305 /* The commands low level section */
1306
1307 /*******************************************************************************
1308 * Function Name: Cy_SD_Host_PollCmdLineFree
1309 ****************************************************************************//**
1310 *
1311 * Waits for the command line free.
1312 *
1313 * \param *base
1314 * The SD host registers structure pointer.
1315 *
1316 * \return \ref cy_en_sd_host_status_t
1317 *
1318 *******************************************************************************/
Cy_SD_Host_PollCmdLineFree(SDHC_Type const * base)1319 __STATIC_INLINE cy_en_sd_host_status_t Cy_SD_Host_PollCmdLineFree(SDHC_Type const *base)
1320 {
1321 cy_en_sd_host_status_t ret = CY_SD_HOST_ERROR_TIMEOUT;
1322 uint32_t retry = CY_SD_HOST_RETRY_TIME;
1323 bool commandInhibit;
1324
1325 while (retry > 0UL)
1326 {
1327 commandInhibit = _FLD2BOOL(SDHC_CORE_PSTATE_REG_CMD_INHIBIT,
1328 SDHC_CORE_PSTATE_REG(base));
1329
1330 if (false == commandInhibit)
1331 {
1332 ret = CY_SD_HOST_SUCCESS;
1333 break;
1334 }
1335
1336 Cy_SysLib_DelayUs(CY_SD_HOST_CMD_TIMEOUT_MS);
1337 retry--;
1338 }
1339
1340 return ret;
1341 }
1342
1343
1344 /*******************************************************************************
1345 * Function Name: Cy_SD_Host_PollDataLineNotInhibit
1346 ****************************************************************************//**
1347 *
1348 * Waits for the data line is not inhibit.
1349 *
1350 * \param *base
1351 * The SD host registers structure pointer.
1352 *
1353 * \return \ref cy_en_sd_host_status_t
1354 *
1355 *******************************************************************************/
Cy_SD_Host_PollDataLineNotInhibit(SDHC_Type const * base)1356 __STATIC_INLINE cy_en_sd_host_status_t Cy_SD_Host_PollDataLineNotInhibit(SDHC_Type const *base)
1357 {
1358 cy_en_sd_host_status_t ret = CY_SD_HOST_ERROR_TIMEOUT;
1359 uint32_t retry = CY_SD_HOST_RETRY_TIME;
1360 bool dataInhibit;
1361
1362 while (retry > 0UL)
1363 {
1364 dataInhibit = _FLD2BOOL(SDHC_CORE_PSTATE_REG_CMD_INHIBIT_DAT,
1365 SDHC_CORE_PSTATE_REG(base));
1366
1367 if (false == dataInhibit)
1368 {
1369 ret = CY_SD_HOST_SUCCESS;
1370 break;
1371 }
1372
1373 Cy_SysLib_DelayUs(CY_SD_HOST_CMD_TIMEOUT_MS);
1374 retry--;
1375 }
1376
1377 return ret;
1378 }
1379
1380
1381 /*******************************************************************************
1382 * Function Name: Cy_SD_Host_PollDataLineFree
1383 ****************************************************************************//**
1384 *
1385 * Waits for the data line free.
1386 *
1387 * \param *base
1388 * The SD host registers structure pointer.
1389 *
1390 * \return \ref cy_en_sd_host_status_t
1391 *
1392 *******************************************************************************/
Cy_SD_Host_PollDataLineFree(SDHC_Type const * base)1393 __STATIC_INLINE cy_en_sd_host_status_t Cy_SD_Host_PollDataLineFree(SDHC_Type const *base)
1394 {
1395 cy_en_sd_host_status_t ret = CY_SD_HOST_SUCCESS;
1396 uint32_t retry = CY_SD_HOST_RETRY_TIME;
1397
1398 while ((true == _FLD2BOOL(SDHC_CORE_PSTATE_REG_DAT_LINE_ACTIVE, SDHC_CORE_PSTATE_REG(base))) &&
1399 (retry > 0UL))
1400 {
1401 Cy_SysLib_DelayUs(CY_SD_HOST_WRITE_TIMEOUT_MS);
1402 retry--;
1403 }
1404
1405 if (true == _FLD2BOOL(SDHC_CORE_PSTATE_REG_DAT_LINE_ACTIVE, SDHC_CORE_PSTATE_REG(base)))
1406 {
1407 ret = CY_SD_HOST_ERROR_TIMEOUT;
1408 }
1409
1410 return ret;
1411 }
1412
1413
1414 /*******************************************************************************
1415 * Function Name: Cy_SD_Host_PollBufferReadReady
1416 ****************************************************************************//**
1417 *
1418 * Waits for the Buffer Read ready event.
1419 *
1420 * \param *base
1421 * The SD host registers structure pointer.
1422 *
1423 * \return \ref cy_en_sd_host_status_t
1424 *
1425 *******************************************************************************/
Cy_SD_Host_PollBufferReadReady(SDHC_Type * base)1426 __STATIC_INLINE cy_en_sd_host_status_t Cy_SD_Host_PollBufferReadReady(SDHC_Type *base)
1427 {
1428 cy_en_sd_host_status_t ret = CY_SD_HOST_ERROR_TIMEOUT;
1429 uint32_t retry = CY_SD_HOST_RETRY_TIME;
1430
1431 while (retry > 0UL)
1432 {
1433 /* Check the Buffer Read ready */
1434 if (true == _FLD2BOOL(SDHC_CORE_NORMAL_INT_STAT_R_BUF_RD_READY,
1435 SDHC_CORE_NORMAL_INT_STAT_R(base)))
1436 {
1437 /* Clear the interrupt flag */
1438 SDHC_CORE_NORMAL_INT_STAT_R(base) = CY_SD_HOST_BUF_RD_READY;
1439
1440 ret = CY_SD_HOST_SUCCESS;
1441 break;
1442 }
1443
1444 Cy_SysLib_DelayUs(CY_SD_HOST_BUFFER_RDY_TIMEOUT_MS);
1445 retry--;
1446 }
1447
1448 return ret;
1449 }
1450
1451
1452 /*******************************************************************************
1453 * Function Name: Cy_SD_Host_PollBufferWriteReady
1454 ****************************************************************************//**
1455 *
1456 * Waits for the Buffer Write ready event.
1457 *
1458 * \param *base
1459 * The SD host registers structure pointer.
1460 *
1461 * \return \ref cy_en_sd_host_status_t
1462 *
1463 *******************************************************************************/
Cy_SD_Host_PollBufferWriteReady(SDHC_Type * base)1464 __STATIC_INLINE cy_en_sd_host_status_t Cy_SD_Host_PollBufferWriteReady(SDHC_Type *base)
1465 {
1466 cy_en_sd_host_status_t ret = CY_SD_HOST_ERROR_TIMEOUT;
1467 uint32_t retry = CY_SD_HOST_RETRY_TIME;
1468
1469 while (retry > 0UL)
1470 {
1471 /* Check the Buffer Write ready */
1472 if (true == _FLD2BOOL(SDHC_CORE_NORMAL_INT_STAT_R_BUF_WR_READY,
1473 SDHC_CORE_NORMAL_INT_STAT_R(base)))
1474 {
1475 /* Clear the interrupt flag */
1476 SDHC_CORE_NORMAL_INT_STAT_R(base) = CY_SD_HOST_BUF_WR_READY;
1477
1478 ret = CY_SD_HOST_SUCCESS;
1479 break;
1480 }
1481
1482 Cy_SysLib_DelayUs(CY_SD_HOST_BUFFER_RDY_TIMEOUT_MS);
1483 retry--;
1484 }
1485
1486 return ret;
1487 }
1488
1489
1490 /*******************************************************************************
1491 * Function Name: Cy_SD_Host_PollCmdComplete
1492 ****************************************************************************//**
1493 *
1494 * Waits for the Command Complete event.
1495 *
1496 * \param *base
1497 * The SD host registers structure pointer.
1498 *
1499 * \return \ref cy_en_sd_host_status_t
1500 *
1501 *******************************************************************************/
Cy_SD_Host_PollCmdComplete(SDHC_Type * base)1502 __STATIC_INLINE cy_en_sd_host_status_t Cy_SD_Host_PollCmdComplete(SDHC_Type *base)
1503 {
1504 cy_en_sd_host_status_t ret = CY_SD_HOST_ERROR_TIMEOUT;
1505 uint32_t retry = CY_SD_HOST_RETRY_TIME;
1506
1507 while (retry > 0UL)
1508 {
1509 /* Command Complete */
1510 if (true == _FLD2BOOL(SDHC_CORE_NORMAL_INT_STAT_R_CMD_COMPLETE,
1511 SDHC_CORE_NORMAL_INT_STAT_R(base)))
1512 {
1513 /* Clear the interrupt flag */
1514 SDHC_CORE_NORMAL_INT_STAT_R(base) = CY_SD_HOST_CMD_COMPLETE;
1515
1516 ret = CY_SD_HOST_SUCCESS;
1517 break;
1518 }
1519
1520 Cy_SysLib_DelayUs(CY_SD_HOST_CMD_TIMEOUT_MS);
1521 retry--;
1522 }
1523
1524 return ret;
1525 }
1526
1527
1528 /*******************************************************************************
1529 * Function Name: Cy_SD_Host_PollTransferComplete
1530 ****************************************************************************//**
1531 *
1532 * Waits for the Transfer Complete event.
1533 *
1534 * \param *base
1535 * The SD host registers structure pointer.
1536 *
1537 * \return \ref cy_en_sd_host_status_t
1538 *
1539 *******************************************************************************/
Cy_SD_Host_PollTransferComplete(SDHC_Type * base)1540 __STATIC_INLINE cy_en_sd_host_status_t Cy_SD_Host_PollTransferComplete(SDHC_Type *base)
1541 {
1542 cy_en_sd_host_status_t ret = CY_SD_HOST_ERROR_TIMEOUT;
1543 uint32_t retry = CY_SD_HOST_RETRY_TIME;
1544
1545 while (retry > 0UL)
1546 {
1547 /* Transfer Complete */
1548 if (true == _FLD2BOOL(SDHC_CORE_NORMAL_INT_STAT_R_XFER_COMPLETE,
1549 SDHC_CORE_NORMAL_INT_STAT_R(base)))
1550 {
1551 /* Clear the interrupt flag */
1552 SDHC_CORE_NORMAL_INT_STAT_R(base) = CY_SD_HOST_XFER_COMPLETE;
1553
1554 ret = CY_SD_HOST_SUCCESS;
1555 break;
1556 }
1557
1558 Cy_SysLib_DelayUs(CY_SD_HOST_WRITE_TIMEOUT_MS);
1559 retry--;
1560 }
1561
1562 return ret;
1563 }
1564
1565
1566 /*******************************************************************************
1567 * Function Name: Cy_SD_Host_CmdRxData
1568 ****************************************************************************//**
1569 *
1570 * Reads the command data using a non-DMA data transfer.
1571 * This function is blocking (it exits after all data is read).
1572 *
1573 * \param *base
1574 * The SD host registers structure pointer.
1575 *
1576 * \param *pcmd
1577 * The pointer to the current command data structure.
1578 *
1579 * \return \ref cy_en_sd_host_status_t
1580 *
1581 *******************************************************************************/
Cy_SD_Host_CmdRxData(SDHC_Type * base,cy_stc_sd_host_data_config_t * pcmd)1582 static cy_en_sd_host_status_t Cy_SD_Host_CmdRxData(SDHC_Type *base,
1583 cy_stc_sd_host_data_config_t *pcmd)
1584 {
1585 cy_en_sd_host_status_t ret;
1586 uint32_t blkSize;
1587 uint32_t blkCnt;
1588 uint32_t i;
1589 uint32_t retry;
1590
1591 blkCnt = pcmd->numberOfBlock;
1592 blkSize = pcmd->blockSize;
1593
1594 while (blkCnt > 0UL)
1595 {
1596 /* Wait for the Buffer Read ready. */
1597 ret = Cy_SD_Host_PollBufferReadReady(base);
1598
1599 if (CY_SD_HOST_SUCCESS != ret)
1600 {
1601 break;
1602 }
1603
1604 for ( i = blkSize >> 2UL; i != 0UL; i-- )
1605 {
1606 /* Wait if valid data exists in the Host buffer. */
1607 retry = CY_SD_HOST_RETRY_TIME;
1608 while ((false == _FLD2BOOL(SDHC_CORE_PSTATE_REG_BUF_RD_ENABLE,
1609 SDHC_CORE_PSTATE_REG(base))) &&
1610 (retry > 0UL))
1611 {
1612 Cy_SysLib_DelayUs(CY_SD_HOST_RD_WR_ENABLE_TIMEOUT);
1613 retry--;
1614 }
1615
1616 if (false == _FLD2BOOL(SDHC_CORE_PSTATE_REG_BUF_RD_ENABLE,
1617 SDHC_CORE_PSTATE_REG(base)))
1618 {
1619 break;
1620 }
1621
1622 /* Read data from the Host buffer. */
1623 *pcmd->data = Cy_SD_Host_BufferRead(base);
1624 pcmd->data++;
1625 }
1626 blkCnt--;
1627 }
1628
1629 /* Wait for the Transfer Complete. */
1630 ret = Cy_SD_Host_PollTransferComplete(base);
1631
1632 (void)Cy_SD_Host_PollCmdLineFree(base);
1633 (void)Cy_SD_Host_PollDataLineNotInhibit(base);
1634
1635 return ret;
1636 }
1637
1638
1639 /*******************************************************************************
1640 * Function Name: Cy_SD_Host_CmdTxData
1641 ****************************************************************************//**
1642 *
1643 * Writes the command data using a non-DMA data transfer.
1644 * This function is blocking (it exits after all data is written).
1645 *
1646 * \param *base
1647 * The SD host registers structure pointer.
1648 *
1649 * \param *pcmd
1650 * The pointer to the current command data structure.
1651 *
1652 * \return \ref cy_en_sd_host_status_t
1653 *
1654 *******************************************************************************/
Cy_SD_Host_CmdTxData(SDHC_Type * base,cy_stc_sd_host_data_config_t * pcmd)1655 __STATIC_INLINE cy_en_sd_host_status_t Cy_SD_Host_CmdTxData(SDHC_Type *base,
1656 cy_stc_sd_host_data_config_t *pcmd)
1657 {
1658 cy_en_sd_host_status_t ret;
1659 uint32_t blkSize;
1660 uint32_t blkCnt;
1661 uint32_t i;
1662 uint32_t retry;
1663
1664 blkCnt = pcmd->numberOfBlock;
1665 blkSize = pcmd->blockSize;
1666
1667 while (0UL < blkCnt)
1668 {
1669 /* Wait for the Buffer Write ready. */
1670 ret = Cy_SD_Host_PollBufferWriteReady(base);
1671
1672 if (CY_SD_HOST_SUCCESS != ret)
1673 {
1674 break;
1675 }
1676
1677 for ( i = blkSize >> 2UL; i != 0UL; i-- )
1678 {
1679 /* Wait if space is available for writing data. */
1680 retry = CY_SD_HOST_RETRY_TIME;
1681 while ((false == _FLD2BOOL(SDHC_CORE_PSTATE_REG_BUF_WR_ENABLE,
1682 SDHC_CORE_PSTATE_REG(base))) &&
1683 (retry > 0UL))
1684 {
1685 Cy_SysLib_DelayUs(CY_SD_HOST_RD_WR_ENABLE_TIMEOUT);
1686 retry--;
1687 }
1688
1689 if (false == _FLD2BOOL(SDHC_CORE_PSTATE_REG_BUF_WR_ENABLE,
1690 SDHC_CORE_PSTATE_REG(base)))
1691 {
1692 break;
1693 }
1694
1695 /* Write data to the Host buffer. */
1696 (void)Cy_SD_Host_BufferWrite(base, *pcmd->data);
1697 pcmd->data++;
1698 }
1699 blkCnt--;
1700 }
1701
1702 ret = Cy_SD_Host_PollTransferComplete(base);
1703
1704 if (CY_SD_HOST_SUCCESS == ret)
1705 {
1706 /* Check if DAT line is active. */
1707 ret = Cy_SD_Host_PollDataLineFree(base);
1708 }
1709
1710 return ret;
1711 }
1712
1713
1714 /*******************************************************************************
1715 * Function Name: Cy_SD_Host_SendCommand
1716 ****************************************************************************//**
1717 *
1718 * Starts sending a command on the SD bus. If the command uses the data lines
1719 * Cy_SD_Host_InitDataTransfer() must be call first.
1720 * This function returns before the command completes.
1721 * To determine if the command is done, read the Normal Interrupt Status register
1722 * and check the CMD_COMPLETE flag. To determine if the entire transfer is done
1723 * check the XFER_COMPLETE flag. Also the interrupt is used and flags are set
1724 * on these events in an ISR.
1725 * \note It is the user's responsibility to clear the CY_SD_HOST_CMD_COMPLETE flag
1726 * after calling this function.
1727 *
1728 * \param *base
1729 * The SD host registers structure pointer.
1730 *
1731 * \param *config
1732 * The configuration structure for the command.
1733 *
1734 * \return \ref cy_en_sd_host_status_t
1735 *
1736 *******************************************************************************/
Cy_SD_Host_SendCommand(SDHC_Type * base,cy_stc_sd_host_cmd_config_t const * config)1737 cy_en_sd_host_status_t Cy_SD_Host_SendCommand(SDHC_Type *base,
1738 cy_stc_sd_host_cmd_config_t const *config)
1739 {
1740 cy_en_sd_host_status_t ret = CY_SD_HOST_SUCCESS;
1741
1742 if ((NULL != base) && (NULL != config))
1743 {
1744 CY_ASSERT_L2(CY_SD_HOST_IS_CMD_IDX_VALID(config->commandIndex));
1745 CY_ASSERT_L3(CY_SD_HOST_IS_CMD_TYPE_VALID(config->cmdType));
1746
1747 ret = Cy_SD_Host_PollCmdLineFree(base);
1748 if (CY_SD_HOST_SUCCESS == ret)
1749 {
1750 if ((true == config->dataPresent) && (CY_SD_HOST_CMD_ABORT != config->cmdType))
1751 {
1752 /* Check the DAT line inhibits only commands with the DAT line is used
1753 * and when the command is not the ABORT type.
1754 */
1755 ret = Cy_SD_Host_PollDataLineNotInhibit(base);
1756 }
1757
1758 if (CY_SD_HOST_SUCCESS == ret)
1759 {
1760 /* Set the commandArgument directly to the hardware register. */
1761 SDHC_CORE_ARGUMENT_R(base) = config->commandArgument;
1762
1763 /* Update the command hardware register (the command is sent)
1764 * according to the spec, this register should be written only once.
1765 */
1766 SDHC_CORE_CMD_R(base) = (uint16_t)(_VAL2FLD(SDHC_CORE_CMD_R_CMD_TYPE, 0U) |
1767 _VAL2FLD(SDHC_CORE_CMD_R_RESP_TYPE_SELECT, (uint32_t)config->respType) |
1768 _VAL2FLD(SDHC_CORE_CMD_R_CMD_TYPE, (uint32_t)config->cmdType) |
1769 _VAL2FLD(SDHC_CORE_CMD_R_DATA_PRESENT_SEL, ((true == config->dataPresent) ? 1U : 0U)) |
1770 _VAL2FLD(SDHC_CORE_CMD_R_CMD_IDX_CHK_ENABLE, ((true == config->enableIdxCheck) ? 1U : 0U)) |
1771 _VAL2FLD(SDHC_CORE_CMD_R_CMD_CRC_CHK_ENABLE, ((true == config->enableCrcCheck) ? 1U : 0U)) |
1772 _VAL2FLD(SDHC_CORE_CMD_R_CMD_INDEX, config->commandIndex & CY_SD_HOST_ACMD_OFFSET_MASK));
1773 }
1774 }
1775 }
1776 else
1777 {
1778 ret = CY_SD_HOST_ERROR_INVALID_PARAMETER;
1779 }
1780
1781 return ret;
1782 }
1783
1784
1785 /*******************************************************************************
1786 * Function Name: Cy_SD_Host_SetBusWidth
1787 ****************************************************************************//**
1788 *
1789 * Sends out the SD bus width changing command.
1790 *
1791 * \param *base
1792 * The SD host registers structure pointer.
1793 *
1794 * \param width
1795 * The width of the data bus.
1796 *
1797 * \param context
1798 * The pointer to the context structure \ref cy_stc_sd_host_context_t allocated
1799 * by the user. The structure is used during the SD host operation for internal
1800 * configuration and data retention. The user must not modify anything
1801 * in this structure.
1802 * If only the SD host functions which do not require context will be used, pass NULL
1803 * as the pointer to the context.
1804 *
1805 * \return \ref cy_en_sd_host_status_t
1806 *
1807 *******************************************************************************/
Cy_SD_Host_SetBusWidth(SDHC_Type * base,cy_en_sd_host_bus_width_t width,cy_stc_sd_host_context_t const * context)1808 cy_en_sd_host_status_t Cy_SD_Host_SetBusWidth(SDHC_Type *base,
1809 cy_en_sd_host_bus_width_t width,
1810 cy_stc_sd_host_context_t const *context)
1811 {
1812 cy_en_sd_host_status_t ret = CY_SD_HOST_SUCCESS;
1813 uint32_t cmdArgument = 0UL;
1814
1815 if ((NULL != base) && (NULL != context))
1816 {
1817 if (CY_SD_HOST_SD == context->cardType)
1818 {
1819 switch (width)
1820 {
1821 case CY_SD_HOST_BUS_WIDTH_1_BIT:
1822 cmdArgument = 0UL; /* 0 = 1bit */
1823 break;
1824 case CY_SD_HOST_BUS_WIDTH_4_BIT:
1825 cmdArgument = 2UL; /* 2 = 4bit */
1826 break;
1827 default:
1828 ret = CY_SD_HOST_ERROR_INVALID_PARAMETER;
1829 break;
1830 }
1831
1832 if (CY_SD_HOST_SUCCESS == ret)
1833 {
1834 ret = Cy_SD_Host_OpsSetSdBusWidth(base, cmdArgument, context);
1835 }
1836 }
1837 else if (CY_SD_HOST_EMMC == context->cardType)
1838 {
1839 switch (width)
1840 {
1841 /* The CMD6 Argument data structure:
1842 * [ACCESS:2]<<24 | [EXT_CSD IDX:8]<<16
1843 * |[Value:8]<<8 | [CMD set:2]<<0
1844 */
1845 case CY_SD_HOST_BUS_WIDTH_1_BIT:
1846 cmdArgument = (CY_SD_HOST_EMMC_ACCESS_WRITE_BYTE << CY_SD_HOST_EMMC_CMD6_ACCESS_OFFSET) |
1847 (CY_SD_HOST_EMMC_BUS_WIDTH_ADDR << CY_SD_HOST_EMMC_CMD6_IDX_OFFSET) |
1848 (0x0UL << CY_SD_HOST_EMMC_CMD6_VALUE_OFFSET) |
1849 (0x0UL << CY_SD_HOST_EMMC_CMD6_CMD_SET_OFFSET);
1850 break;
1851 case CY_SD_HOST_BUS_WIDTH_4_BIT:
1852 cmdArgument = (CY_SD_HOST_EMMC_ACCESS_WRITE_BYTE << CY_SD_HOST_EMMC_CMD6_ACCESS_OFFSET) |
1853 (CY_SD_HOST_EMMC_BUS_WIDTH_ADDR << CY_SD_HOST_EMMC_CMD6_IDX_OFFSET) |
1854 (0x1UL << CY_SD_HOST_EMMC_CMD6_VALUE_OFFSET) |
1855 (0x0UL << CY_SD_HOST_EMMC_CMD6_CMD_SET_OFFSET);
1856 break;
1857 case CY_SD_HOST_BUS_WIDTH_8_BIT:
1858 cmdArgument = (CY_SD_HOST_EMMC_ACCESS_WRITE_BYTE << CY_SD_HOST_EMMC_CMD6_ACCESS_OFFSET) |
1859 (CY_SD_HOST_EMMC_BUS_WIDTH_ADDR << CY_SD_HOST_EMMC_CMD6_IDX_OFFSET) |
1860 (0x2UL << CY_SD_HOST_EMMC_CMD6_VALUE_OFFSET) |
1861 (0x0UL << CY_SD_HOST_EMMC_CMD6_CMD_SET_OFFSET);
1862 break;
1863 default:
1864 ret = CY_SD_HOST_ERROR_INVALID_PARAMETER;
1865 break;
1866 }
1867
1868 if (CY_SD_HOST_SUCCESS == ret)
1869 {
1870 /* Send CMD6 */
1871 ret = Cy_SD_Host_OpsSwitchFunc(base, cmdArgument);
1872 }
1873 }
1874 else if (CY_SD_HOST_SDIO == context->cardType)
1875 {
1876 switch (width)
1877 {
1878 case CY_SD_HOST_BUS_WIDTH_1_BIT:
1879 cmdArgument = 0UL;
1880 break;
1881 case CY_SD_HOST_BUS_WIDTH_4_BIT:
1882 cmdArgument = CY_SD_HOST_CCCR_BUS_WIDTH_1;
1883 break;
1884 case CY_SD_HOST_BUS_WIDTH_8_BIT:
1885 cmdArgument = CY_SD_HOST_CCCR_BUS_WIDTH_0 |
1886 CY_SD_HOST_CCCR_BUS_WIDTH_1 |
1887 CY_SD_HOST_CCCR_S8B;
1888 break;
1889 default:
1890 ret = CY_SD_HOST_ERROR_INVALID_PARAMETER;
1891 break;
1892 }
1893
1894 if (CY_SD_HOST_SUCCESS == ret)
1895 {
1896 ret = Cy_SD_Host_OpsSendIoRwDirectCmd(base,
1897 1UL,
1898 0UL,
1899 0UL,
1900 CY_SD_HOST_CCCR_BUS_INTERFACE_CTR,
1901 cmdArgument);
1902 }
1903 }
1904 else
1905 {
1906 ret = CY_SD_HOST_ERROR_INVALID_PARAMETER;
1907 }
1908
1909 if (CY_SD_HOST_SUCCESS == ret)
1910 {
1911 /* Update the host side setting. */
1912 ret = Cy_SD_Host_SetHostBusWidth(base, width);
1913 }
1914 }
1915 else
1916 {
1917 ret = CY_SD_HOST_ERROR_INVALID_PARAMETER;
1918 }
1919
1920 return ret;
1921 }
1922
1923
1924 /*******************************************************************************
1925 * Function Name: Cy_SD_Host_OpsGoIdle
1926 ****************************************************************************//**
1927 *
1928 * Send CMD0 (Go idle).
1929 *
1930 * \param *base
1931 * The SD host registers structure pointer.
1932 *
1933 * \return \ref cy_en_sd_host_status_t
1934 *
1935 *******************************************************************************/
Cy_SD_Host_OpsGoIdle(SDHC_Type * base)1936 static cy_en_sd_host_status_t Cy_SD_Host_OpsGoIdle(SDHC_Type *base)
1937 {
1938 cy_stc_sd_host_cmd_config_t cmd;
1939 cy_en_sd_host_status_t ret;
1940
1941 cmd.commandIndex = CY_SD_HOST_SD_CMD0;
1942 cmd.commandArgument = 0UL;
1943 cmd.enableCrcCheck = false;
1944 cmd.enableAutoResponseErrorCheck = false;
1945 cmd.respType = CY_SD_HOST_RESPONSE_NONE;
1946 cmd.enableIdxCheck = false;
1947 cmd.dataPresent = false;
1948 cmd.cmdType = CY_SD_HOST_CMD_ABORT;
1949
1950 ret = Cy_SD_Host_SendCommand(base, &cmd);
1951
1952 if (CY_SD_HOST_SUCCESS == ret)
1953 {
1954 /* Wait for the Command Complete event. */
1955 ret = Cy_SD_Host_PollCmdComplete(base);
1956 }
1957
1958 Cy_SysLib_DelayUs(CY_SD_HOST_NCC_MIN_US);
1959
1960 return ret;
1961 }
1962
1963
1964 /*******************************************************************************
1965 * Function Name: Cy_SD_Host_OpsVoltageSwitch
1966 ****************************************************************************//**
1967 *
1968 * Send CMD11 (Signal Voltage Switch to 1.8 V).
1969 *
1970 * \param *base
1971 * The SD host registers structure pointer.
1972 *
1973 * \param context
1974 * The pointer to the context structure \ref cy_stc_sd_host_context_t allocated
1975 * by the user. The structure is used during the SD host operation for internal
1976 * configuration and data retention. The user must not modify anything
1977 * in this structure.
1978 * If only the SD host functions which do not require context will be used, pass NULL
1979 * as the pointer to the context.
1980 *
1981 * \return \ref cy_en_sd_host_status_t
1982 *
1983 *******************************************************************************/
Cy_SD_Host_OpsVoltageSwitch(SDHC_Type * base,cy_stc_sd_host_context_t const * context)1984 static cy_en_sd_host_status_t Cy_SD_Host_OpsVoltageSwitch(SDHC_Type *base,
1985 cy_stc_sd_host_context_t const *context)
1986 {
1987 (void) context;
1988 cy_en_sd_host_status_t ret;
1989 cy_stc_sd_host_cmd_config_t cmd;
1990 uint32_t pState;
1991
1992 /* Voltage switch (CMD11). */
1993 cmd.commandIndex = CY_SD_HOST_SD_CMD11;
1994 cmd.commandArgument = 0UL;
1995 cmd.enableCrcCheck = true;
1996 cmd.enableAutoResponseErrorCheck = false;
1997 cmd.respType = CY_SD_HOST_RESPONSE_LEN_48;
1998 cmd.enableIdxCheck = true;
1999 cmd.dataPresent = false;
2000 cmd.cmdType = CY_SD_HOST_CMD_NORMAL;
2001
2002 ret = Cy_SD_Host_SendCommand(base, &cmd);
2003
2004 if (CY_SD_HOST_SUCCESS == ret)
2005 {
2006 /* Wait for the Command Complete event. */
2007 ret = Cy_SD_Host_PollCmdComplete(base);
2008 }
2009
2010 Cy_SysLib_DelayUs(CY_SD_HOST_NCC_MIN_US);
2011
2012 if (CY_SD_HOST_SUCCESS == ret)
2013 {
2014 /* Disable providing the SD Clock. */
2015 Cy_SD_Host_DisableSdClk(base);
2016
2017 pState = Cy_SD_Host_GetPresentState(base) & SDHC_CORE_PSTATE_REG_DAT_3_0_Msk;
2018
2019 /* Check DAT[3:0]. */
2020 if (0UL == pState)
2021 {
2022 /* Switch the bus to 1.8 V (Set the IO_VOLT_SEL pin to low)*/
2023 Cy_SD_Host_ChangeIoVoltage(base, CY_SD_HOST_IO_VOLT_1_8V);
2024
2025 /* Wait 10 ms to 1.8 voltage regulator to be stable. */
2026 Cy_SysLib_Delay(CY_SD_HOST_1_8_REG_STABLE_TIME_MS);
2027
2028 /* Check the 1.8V signaling enable. */
2029 if (true == _FLD2BOOL(SDHC_CORE_HOST_CTRL2_R_SIGNALING_EN,
2030 SDHC_CORE_HOST_CTRL2_R(base)))
2031 {
2032 /* Enable providing the SD Clock. */
2033 Cy_SD_Host_EnableSdClk(base);
2034
2035 /* Wait for the stable CLK */
2036 Cy_SysLib_Delay(CY_SD_HOST_CLK_RAMP_UP_TIME_MS);
2037
2038 pState = Cy_SD_Host_GetPresentState(base) & SDHC_CORE_PSTATE_REG_DAT_3_0_Msk;
2039
2040 /* Check DAT[3:0]. */
2041 if (SDHC_CORE_PSTATE_REG_DAT_3_0_Msk != pState)
2042 {
2043 ret = CY_SD_HOST_ERROR_UNUSABLE_CARD;
2044 }
2045 }
2046 else
2047 {
2048 ret = CY_SD_HOST_ERROR_UNUSABLE_CARD;
2049 }
2050 }
2051 else
2052 {
2053 ret = CY_SD_HOST_ERROR_UNUSABLE_CARD;
2054 }
2055 }
2056
2057 return ret;
2058 }
2059
2060
2061 /*******************************************************************************
2062 * Function Name: Cy_SD_Host_OpsSendIoRwDirectCmd
2063 ****************************************************************************//**
2064 *
2065 * Sends CMD52 (Reads/writes 1 byte to the SDIO register).
2066 *
2067 * \param *base
2068 * The SD host registers structure pointer.
2069 * \param rwFlag
2070 * \param functionNumber
2071 * \param rawFlag
2072 * \param registerAddress
2073 * \param data
2074 *
2075 * \return \ref cy_en_sd_host_status_t
2076 *
2077 *******************************************************************************/
Cy_SD_Host_OpsSendIoRwDirectCmd(SDHC_Type * base,uint32_t rwFlag,uint32_t functionNumber,uint32_t rawFlag,uint32_t registerAddress,uint32_t data)2078 static cy_en_sd_host_status_t Cy_SD_Host_OpsSendIoRwDirectCmd(SDHC_Type *base,
2079 uint32_t rwFlag,
2080 uint32_t functionNumber,
2081 uint32_t rawFlag,
2082 uint32_t registerAddress,
2083 uint32_t data)
2084 {
2085 cy_stc_sd_host_cmd_config_t cmd;
2086 cy_en_sd_host_status_t ret;
2087
2088 cmd.commandIndex = CY_SD_HOST_SD_CMD52;
2089 cmd.commandArgument = ((rwFlag & 0x01UL) << CY_SD_HOST_CMD52_RWFLAG_POS) |
2090 ((functionNumber & CY_SD_HOST_CMD52_FUNCT_NUM_MSK) << CY_SD_HOST_CMD52_FUNCT_NUM_POS) |
2091 ((rawFlag & 0x01UL) << CY_SD_HOST_CMD52_RAWFLAG_POS) |
2092 ((registerAddress & CY_SD_HOST_CMD52_REG_ADDR_MSK) << CY_SD_HOST_CMD52_REG_ADDR_POS) |
2093 (data & CY_SD_HOST_CMD52_DATA_MSK);
2094
2095 cmd.dataPresent = false;
2096 cmd.enableAutoResponseErrorCheck = false;
2097 cmd.respType = CY_SD_HOST_RESPONSE_LEN_48B;
2098 cmd.enableCrcCheck = true;
2099 cmd.enableIdxCheck = true;
2100 cmd.cmdType = CY_SD_HOST_CMD_NORMAL;
2101
2102 ret = Cy_SD_Host_SendCommand(base, &cmd);
2103
2104 if (CY_SD_HOST_SUCCESS == ret)
2105 {
2106 /* Wait for the Command Complete event. */
2107 ret = Cy_SD_Host_PollCmdComplete(base);
2108 }
2109
2110 Cy_SysLib_DelayUs(CY_SD_HOST_NCC_MIN_US);
2111
2112 return ret;
2113 }
2114
2115
2116 /*******************************************************************************
2117 * Function Name: Cy_SD_Host_OpsSendAppCmd
2118 ****************************************************************************//**
2119 *
2120 * Sends CMD55 (Sends the application command).
2121 * If no response of CMD55 received, the card is not the SD card.
2122 * The CMD55 response may have an error because some SD card does not support the CMD8
2123 * command.
2124 *
2125 * \param *base
2126 * The SD host registers structure pointer.
2127 *
2128 * \param context
2129 * The pointer to the context structure \ref cy_stc_sd_host_context_t allocated
2130 * by the user. The structure is used during the SD host operation for internal
2131 * configuration and data retention. The user must not modify anything
2132 * in this structure.
2133 * If only the SD host functions which do not require context will be used, pass NULL
2134 * as the pointer to the context.
2135 *
2136 * \return \ref cy_en_sd_host_status_t
2137 *
2138 *******************************************************************************/
Cy_SD_Host_OpsSendAppCmd(SDHC_Type * base,cy_stc_sd_host_context_t const * context)2139 static cy_en_sd_host_status_t Cy_SD_Host_OpsSendAppCmd(SDHC_Type *base,
2140 cy_stc_sd_host_context_t const *context)
2141 {
2142 cy_stc_sd_host_cmd_config_t cmd;
2143 cy_en_sd_host_status_t ret;
2144
2145 cmd.commandIndex = CY_SD_HOST_SD_CMD55;
2146 cmd.commandArgument = context->RCA << CY_SD_HOST_RCA_SHIFT;
2147 cmd.dataPresent = false;
2148 cmd.enableAutoResponseErrorCheck = false;
2149 cmd.respType = CY_SD_HOST_RESPONSE_LEN_48;
2150 cmd.enableCrcCheck = true;
2151 cmd.enableIdxCheck = true;
2152 cmd.cmdType = CY_SD_HOST_CMD_NORMAL;
2153
2154 ret = Cy_SD_Host_SendCommand(base, &cmd);
2155
2156 if (CY_SD_HOST_SUCCESS == ret)
2157 {
2158 /* Wait for the Command Complete event. */
2159 ret = Cy_SD_Host_PollCmdComplete(base);
2160 }
2161
2162 Cy_SysLib_DelayUs(CY_SD_HOST_NCC_MIN_US);
2163
2164 return ret;
2165 }
2166
2167
2168 /*******************************************************************************
2169 * Function Name: Cy_SD_Host_OpsSendIfCond
2170 ****************************************************************************//**
2171 *
2172 * Send CMD8 (Send application command).
2173 *
2174 * \param *base
2175 * The SD host registers structure pointer.
2176 *
2177 * \param cmdArgument
2178 * The command argument.
2179 *
2180 * \param noResponse
2181 * No response if true, false - a 48 bit response with CRC and IDX check.
2182 *
2183 * \return \ref cy_en_sd_host_status_t
2184 *
2185 *******************************************************************************/
Cy_SD_Host_OpsSendIfCond(SDHC_Type * base,uint32_t cmdArgument,bool noResponse)2186 __STATIC_INLINE cy_en_sd_host_status_t Cy_SD_Host_OpsSendIfCond(SDHC_Type *base,
2187 uint32_t cmdArgument,
2188 bool noResponse)
2189 {
2190 cy_stc_sd_host_cmd_config_t cmd;
2191 cy_en_sd_host_status_t ret;
2192
2193 cmd.commandIndex = CY_SD_HOST_SD_CMD8;
2194 cmd.commandArgument = cmdArgument;
2195 cmd.dataPresent = false;
2196 cmd.enableAutoResponseErrorCheck = false;
2197 cmd.cmdType = CY_SD_HOST_CMD_NORMAL;
2198 if (noResponse)
2199 {
2200 cmd.respType = CY_SD_HOST_RESPONSE_NONE;
2201 cmd.enableCrcCheck = false;
2202 cmd.enableIdxCheck = false;
2203 }
2204 else
2205 {
2206 cmd.respType = CY_SD_HOST_RESPONSE_LEN_48;
2207 cmd.enableCrcCheck = true;
2208 cmd.enableIdxCheck = true;
2209 }
2210
2211 ret = Cy_SD_Host_SendCommand(base, &cmd);
2212
2213 if (CY_SD_HOST_SUCCESS == ret)
2214 {
2215 /* Wait for the Command Complete event. */
2216 ret = Cy_SD_Host_PollCmdComplete(base);
2217 }
2218
2219 Cy_SysLib_DelayUs(CY_SD_HOST_NCC_MIN_US);
2220
2221 return ret;
2222 }
2223
2224
2225 /*******************************************************************************
2226 * Function Name: Cy_SD_Host_OpsSelectCard
2227 ****************************************************************************//**
2228 *
2229 * Send CMD7 (Send select card command).
2230 *
2231 * \param *base
2232 * The SD host registers structure pointer.
2233 *
2234 * \param context
2235 * The pointer to the context structure \ref cy_stc_sd_host_context_t allocated
2236 * by the user. The structure is used during the SD host operation for internal
2237 * configuration and data retention. The user must not modify anything
2238 * in this structure.
2239 * If only the SD host functions which do not require context will be used, pass NULL
2240 * as the pointer to the context.
2241 *
2242 * \return \ref cy_en_sd_host_status_t
2243 *
2244 *******************************************************************************/
Cy_SD_Host_OpsSelectCard(SDHC_Type * base,cy_stc_sd_host_context_t const * context)2245 static cy_en_sd_host_status_t Cy_SD_Host_OpsSelectCard(SDHC_Type *base,
2246 cy_stc_sd_host_context_t const *context)
2247 {
2248 cy_stc_sd_host_cmd_config_t cmd;
2249 cy_en_sd_host_status_t ret;
2250
2251 cmd.commandIndex = CY_SD_HOST_SD_CMD7;
2252 cmd.commandArgument = context->RCA << CY_SD_HOST_RCA_SHIFT;
2253 cmd.dataPresent = false;
2254 cmd.enableAutoResponseErrorCheck = false;
2255 cmd.respType = CY_SD_HOST_RESPONSE_LEN_48B;
2256 cmd.enableCrcCheck = false;
2257 cmd.enableIdxCheck = false;
2258 cmd.cmdType = CY_SD_HOST_CMD_NORMAL;
2259
2260 ret = Cy_SD_Host_SendCommand(base, &cmd);
2261
2262 if (CY_SD_HOST_SUCCESS == ret)
2263 {
2264 /* Wait for the Command Complete event. */
2265 ret = Cy_SD_Host_PollCmdComplete(base);
2266 }
2267 if (CY_SD_HOST_SUCCESS == ret)
2268 {
2269 Cy_SysLib_DelayUs(CY_SD_HOST_NCC_MIN_US);
2270
2271 /* The R1b response requires sending an optional busy
2272 * signal to the DAT line. The transfer complete event
2273 * should be checked and reset.
2274 */
2275 ret = Cy_SD_Host_PollTransferComplete(base);
2276 }
2277
2278 return ret;
2279 }
2280
2281
2282 /*******************************************************************************
2283 * Function Name: Cy_SD_Host_OpsSetSdBusWidth
2284 ****************************************************************************//**
2285 *
2286 * Sends ACMD6 (Send set bus width command).
2287 *
2288 * \param *base
2289 * The SD host registers structure pointer.
2290
2291 * \param cmdArgument
2292 * The command argument.
2293 *
2294 * \param context
2295 * The pointer to the context structure \ref cy_stc_sd_host_context_t allocated
2296 * by the user. The structure is used during the SD host operation for internal
2297 * configuration and data retention. The user must not modify anything
2298 * in this structure.
2299 * If only the SD host functions which do not require context will be used, pass NULL
2300 * as the pointer to the context.
2301 *
2302 * \return \ref cy_en_sd_host_status_t
2303 *
2304 *******************************************************************************/
Cy_SD_Host_OpsSetSdBusWidth(SDHC_Type * base,uint32_t cmdArgument,cy_stc_sd_host_context_t const * context)2305 __STATIC_INLINE cy_en_sd_host_status_t Cy_SD_Host_OpsSetSdBusWidth(SDHC_Type *base,
2306 uint32_t cmdArgument,
2307 cy_stc_sd_host_context_t const *context)
2308 {
2309 cy_stc_sd_host_cmd_config_t cmd;
2310 cy_en_sd_host_status_t ret;
2311
2312 cmd.commandIndex = CY_SD_HOST_SD_ACMD6;
2313 cmd.commandArgument = cmdArgument;
2314 cmd.dataPresent = false;
2315 cmd.enableAutoResponseErrorCheck = false;
2316 cmd.respType = CY_SD_HOST_RESPONSE_LEN_48;
2317 cmd.enableCrcCheck = false;
2318 cmd.enableIdxCheck = false;
2319 cmd.cmdType = CY_SD_HOST_CMD_NORMAL;
2320
2321 ret = Cy_SD_Host_OpsSendAppCmd(base, context);
2322
2323 if (CY_SD_HOST_SUCCESS == ret)
2324 {
2325 ret = Cy_SD_Host_SendCommand(base, &cmd);
2326
2327 if (CY_SD_HOST_SUCCESS == ret)
2328 {
2329 /* Wait for the Command Complete event. */
2330 ret = Cy_SD_Host_PollCmdComplete(base);
2331 }
2332
2333 Cy_SysLib_DelayUs(CY_SD_HOST_NCC_MIN_US);
2334 }
2335
2336 return ret;
2337 }
2338
2339
2340 /*******************************************************************************
2341 * Function Name: Cy_SD_Host_OpsSwitchFunc
2342 ****************************************************************************//**
2343 *
2344 * Sends CMD6 (Sends the Switch function command).
2345 *
2346 * \param *base
2347 * The SD host registers structure pointer.
2348 *
2349 * \param cmdArgument
2350 * The command argument.
2351 *
2352 * \return \ref cy_en_sd_host_status_t
2353 *
2354 *******************************************************************************/
Cy_SD_Host_OpsSwitchFunc(SDHC_Type * base,uint32_t cmdArgument)2355 static cy_en_sd_host_status_t Cy_SD_Host_OpsSwitchFunc(SDHC_Type *base, uint32_t cmdArgument)
2356 {
2357 cy_stc_sd_host_cmd_config_t cmd;
2358 cy_en_sd_host_status_t ret;
2359
2360 cmd.commandIndex = CY_SD_HOST_SD_CMD6;
2361 cmd.commandArgument = cmdArgument;
2362 cmd.dataPresent = false;
2363 cmd.enableAutoResponseErrorCheck = false;
2364 cmd.respType = CY_SD_HOST_RESPONSE_LEN_48;
2365 cmd.enableCrcCheck = true;
2366 cmd.enableIdxCheck = true;
2367 cmd.cmdType = CY_SD_HOST_CMD_NORMAL;
2368
2369 ret = Cy_SD_Host_SendCommand(base, &cmd);
2370
2371 if (CY_SD_HOST_SUCCESS == ret)
2372 {
2373 /* Wait for the Command Complete event. */
2374 ret = Cy_SD_Host_PollCmdComplete(base);
2375 }
2376
2377 Cy_SysLib_DelayUs(CY_SD_HOST_NCC_MIN_US);
2378
2379 return ret;
2380 }
2381
2382
2383 /*******************************************************************************
2384 * Function Name: Cy_SD_Host_SdCardSwitchFunc
2385 ****************************************************************************//**
2386 *
2387 * Sends CMD6 (Switch Function Command) and parses the 512 bits wide
2388 * response on the DAT lines.
2389 *
2390 * \param *base
2391 * The SD host registers structure pointer.
2392 *
2393 * \param cmdArgument
2394 * The command argument.
2395 *
2396 * \param cardType
2397 * The type of card.
2398 *
2399 * \note
2400 * This function is applicable only for \ref CY_SD_HOST_SD &
2401 * \ref CY_SD_HOST_COMBO card types
2402 *
2403 * \return \ref cy_en_sd_host_status_t
2404 *
2405 *******************************************************************************/
Cy_SD_Host_SdCardSwitchFunc(SDHC_Type * base,uint32_t cmdArgument,cy_en_sd_host_card_type_t cardType)2406 static cy_en_sd_host_status_t Cy_SD_Host_SdCardSwitchFunc(SDHC_Type *base,
2407 uint32_t cmdArgument,
2408 cy_en_sd_host_card_type_t cardType)
2409 {
2410 cy_stc_sd_host_cmd_config_t cmd;
2411 cy_en_sd_host_status_t ret;
2412 cy_stc_sd_host_data_config_t dataConfig;
2413 uint32_t status[CY_SD_HOST_SWITCH_STATUS_LEN];
2414
2415 cmd.commandIndex = CY_SD_HOST_SD_CMD6;
2416 cmd.commandArgument = cmdArgument;
2417 cmd.dataPresent = true;
2418 cmd.enableAutoResponseErrorCheck = false;
2419 cmd.respType = CY_SD_HOST_RESPONSE_LEN_48;
2420 cmd.enableCrcCheck = true;
2421 cmd.enableIdxCheck = true;
2422 cmd.cmdType = CY_SD_HOST_CMD_NORMAL;
2423
2424 dataConfig.blockSize = CY_SD_HOST_SD_STATUS_BLOCKS;
2425 dataConfig.numberOfBlock = 1UL;
2426 dataConfig.enableDma = false;
2427 dataConfig.autoCommand = CY_SD_HOST_AUTO_CMD_NONE;
2428 dataConfig.read = true;
2429 dataConfig.data = status;
2430 dataConfig.dataTimeout = CY_SD_HOST_MAX_TIMEOUT;
2431 dataConfig.enableIntAtBlockGap = false;
2432 dataConfig.enReliableWrite = false;
2433
2434 if ((cardType == CY_SD_HOST_SD) || (cardType == CY_SD_HOST_COMBO))
2435 {
2436 (void)Cy_SD_Host_InitDataTransfer(base, &dataConfig);
2437
2438 ret = Cy_SD_Host_SendCommand(base, &cmd);
2439
2440 if (CY_SD_HOST_SUCCESS == ret)
2441 {
2442 /* Wait for the Command Complete event. */
2443 ret = Cy_SD_Host_PollCmdComplete(base);
2444 }
2445
2446 if (CY_SD_HOST_SUCCESS == ret)
2447 {
2448 /* Wait for the response on the DAT lines. */
2449 ret = Cy_SD_Host_CmdRxData(base, &dataConfig);
2450 }
2451
2452 if (CY_SD_HOST_SUCCESS == ret)
2453 {
2454 /* Parse the response on DAT lines. */
2455 if ((((status[4] >> 4UL) & 0xFUL) == 0xFUL) || /* Function group 1 (376-379) */
2456 ((status[4] & 0xFUL) == 0xFUL) || /* Function group 2 (380-383) */
2457 (((status[3] >> 28UL) & 0xFUL) == 0xFUL) || /* Function group 3 (384-387) */
2458 (((status[3] >> 24UL) & 0xFUL) == 0xFUL) || /* Function group 4 (388-391) */
2459 (((status[3] >> 20UL) & 0xFUL) == 0xFUL) || /* Function group 5 (392-395) */
2460 (((status[3] >> 16UL) & 0xFUL) == 0xFUL)) /* Function group 6 (396-399) */
2461 {
2462 ret = CY_SD_HOST_ERROR_INVALID_PARAMETER;
2463 }
2464 }
2465
2466 Cy_SysLib_DelayUs(CY_SD_HOST_NCC_MIN_US);
2467 }
2468 else
2469 {
2470 ret = CY_SD_HOST_ERROR_INVALID_PARAMETER;
2471 }
2472
2473 return ret;
2474 }
2475
2476
2477 /*******************************************************************************
2478 * Function Name: Cy_SD_Host_OpsSetBlockCount
2479 ****************************************************************************//**
2480 *
2481 * Sends CMD23 (Sends the Set Block Count command).
2482 *
2483 * \param *base
2484 * The SD host registers structure pointer.
2485 *
2486 * \param reliableWrite
2487 * For EMMC enables the reliable write.
2488 *
2489 * \param blockNum
2490 * The number of blocks to send.
2491 *
2492 * \return \ref cy_en_sd_host_status_t
2493 *
2494 *******************************************************************************/
Cy_SD_Host_OpsSetBlockCount(SDHC_Type * base,bool reliableWrite,uint32_t blockNum)2495 __STATIC_INLINE cy_en_sd_host_status_t Cy_SD_Host_OpsSetBlockCount(SDHC_Type *base,
2496 bool reliableWrite,
2497 uint32_t blockNum)
2498 {
2499 cy_stc_sd_host_cmd_config_t cmd;
2500 cy_en_sd_host_status_t ret;
2501 uint32_t cmdArgument;
2502
2503 cmdArgument = (blockNum & CY_SD_HOST_CMD23_BLOCKS_NUM_MASK) |
2504 (reliableWrite ? (1UL << CY_SD_HOST_CMD23_RELIABLE_WRITE_POS) : 0UL);
2505
2506 cmd.commandIndex = CY_SD_HOST_SD_CMD23;
2507 cmd.commandArgument = cmdArgument;
2508 cmd.dataPresent = false;
2509 cmd.enableAutoResponseErrorCheck = false;
2510 cmd.respType = CY_SD_HOST_RESPONSE_LEN_48;
2511 cmd.enableCrcCheck = true;
2512 cmd.enableIdxCheck = true;
2513 cmd.cmdType = CY_SD_HOST_CMD_NORMAL;
2514
2515 ret = Cy_SD_Host_SendCommand(base, &cmd);
2516
2517 if (CY_SD_HOST_SUCCESS == ret)
2518 {
2519 /* Wait for the Command Complete event. */
2520 ret = Cy_SD_Host_PollCmdComplete(base);
2521 }
2522
2523 Cy_SysLib_DelayUs(CY_SD_HOST_NCC_MIN_US);
2524
2525 return ret;
2526 }
2527
2528
2529 /*******************************************************************************
2530 * Function Name: Cy_SD_Host_OpsProgramCsd
2531 ****************************************************************************//**
2532 *
2533 * Sends CMD27 (Sends the Program CSD command).
2534 *
2535 * \param *base
2536 * The SD host registers structure pointer.
2537 *
2538 * \param csd
2539 * The Card-Specific Data register value.
2540 *
2541 * \param context
2542 * The pointer to the context structure \ref cy_stc_sd_host_context_t allocated
2543 * by the user. The structure is used during the SD host operation for internal
2544 * configuration and data retention. The user must not modify anything
2545 * in this structure.
2546 * If only the SD host functions which do not require context will be used, pass NULL
2547 * as the pointer to the context.
2548 *
2549 * \return \ref cy_en_sd_host_status_t
2550 *
2551 *******************************************************************************/
Cy_SD_Host_OpsProgramCsd(SDHC_Type * base,uint32_t csd,cy_stc_sd_host_context_t * context)2552 __STATIC_INLINE cy_en_sd_host_status_t Cy_SD_Host_OpsProgramCsd(SDHC_Type *base,
2553 uint32_t csd,
2554 cy_stc_sd_host_context_t *context)
2555 {
2556 cy_en_sd_host_status_t ret;
2557 cy_stc_sd_host_cmd_config_t cmd;
2558 cy_stc_sd_host_data_config_t dataConfig;
2559 uint32_t i;
2560 uint32_t blkSize = CY_SD_HOST_CSD_BLOCKS;
2561 uint32_t csdTepm;
2562
2563 cmd.commandIndex = CY_SD_HOST_SD_CMD27;
2564 cmd.commandArgument = context->RCA << CY_SD_HOST_RCA_SHIFT;
2565 cmd.dataPresent = true;
2566 cmd.enableAutoResponseErrorCheck = false;
2567 cmd.respType = CY_SD_HOST_RESPONSE_LEN_48;
2568 cmd.enableCrcCheck = true;
2569 cmd.enableIdxCheck = true;
2570 cmd.cmdType = CY_SD_HOST_CMD_NORMAL;
2571
2572 dataConfig.blockSize = CY_SD_HOST_CSD_BLOCKS;
2573 dataConfig.numberOfBlock = 1UL;
2574 dataConfig.enableDma = false;
2575 dataConfig.autoCommand = CY_SD_HOST_AUTO_CMD_NONE;
2576 dataConfig.read = false;
2577 dataConfig.data = context->csd;
2578 dataConfig.dataTimeout = CY_SD_HOST_MAX_TIMEOUT;
2579 dataConfig.enableIntAtBlockGap = false;
2580 dataConfig.enReliableWrite = false;
2581
2582 /* The CSD register is sent using DAT lines. Initialize a data transfer in Non-DMA mode. */
2583 (void)Cy_SD_Host_InitDataTransfer(base, &dataConfig);
2584
2585 /* Send the program CSD command (CMD27) */
2586 ret = Cy_SD_Host_SendCommand(base, &cmd);
2587
2588 if (CY_SD_HOST_SUCCESS == ret)
2589 {
2590 /* Wait for the Command Complete event. */
2591 ret = Cy_SD_Host_PollCmdComplete(base);
2592 }
2593
2594 if (CY_SD_HOST_SUCCESS == ret)
2595 {
2596 /* Wait when buffer is read ready. */
2597 ret = Cy_SD_Host_PollBufferWriteReady(base);
2598
2599 for (i = (blkSize >> 2UL); i != 0UL; i--)
2600 {
2601 /* The CSD register is sent a using usual data (8-bit width) type of the Data packet format.
2602 * The usual data (8-bit width) is sent in the LSB (Least Significant Byte) first,
2603 * MSB (Most Significant Byte) last. The bytes in each context->csd[] element
2604 * should be reordered and shifted right to one byte.
2605 */
2606 csdTepm = ((context->csd[i-1UL] & CY_SD_HOST_CSD_ISBL_MASK) >> CY_SD_HOST_CSD_ISB_SHIFT) |
2607 (context->csd[i-1UL] & CY_SD_HOST_CSD_ISBR_MASK) |
2608 ((context->csd[i-1UL] & CY_SD_HOST_CSD_LSB_MASK) << CY_SD_HOST_CSD_ISB_SHIFT);
2609
2610 if (i > 1UL)
2611 {
2612 csdTepm |= (context->csd[i-2UL] & CY_SD_HOST_CSD_MSB_MASK);
2613 }
2614 else
2615 {
2616 csdTepm &= ~((1UL << CY_SD_HOST_CSD_TEMP_WRITE_PROTECT) | /* Clear TMP_WRITE_PROTECT bit in the CSD register. */
2617 CY_SD_HOST_CSD_MSB_MASK);
2618 csdTepm |= csd; /* Set writable bits of the CSD register. */
2619 }
2620
2621 (void)Cy_SD_Host_BufferWrite(base, csdTepm);
2622 }
2623
2624 /* Wait for the transfer complete */
2625 ret = Cy_SD_Host_PollTransferComplete(base);
2626
2627 if (CY_SD_HOST_SUCCESS == ret)
2628 {
2629 /* Check if the data line is free. */
2630 ret = Cy_SD_Host_PollDataLineFree(base);
2631 }
2632 }
2633
2634 return ret;
2635 }
2636
2637
2638 /*******************************************************************************
2639 * Function Name: Cy_SD_Host_OpsSdioSendOpCond
2640 ****************************************************************************//**
2641 *
2642 * Send CMD5 (Send SDIO operation condition command).
2643 *
2644 * \param *base
2645 * The SD host registers structure pointer.
2646 *
2647 * \param *ocrReg
2648 * The Operation Condition register (OCR).
2649 *
2650 * \param cmdArgument
2651 * The command argument.
2652 *
2653 * \return \ref cy_en_sd_host_status_t
2654 *
2655 *******************************************************************************/
Cy_SD_Host_OpsSdioSendOpCond(SDHC_Type * base,uint32_t * ocrReg,uint32_t cmdArgument)2656 static cy_en_sd_host_status_t Cy_SD_Host_OpsSdioSendOpCond(SDHC_Type *base,
2657 uint32_t *ocrReg,
2658 uint32_t cmdArgument)
2659 {
2660 cy_en_sd_host_status_t ret;
2661 cy_stc_sd_host_cmd_config_t cmd;
2662 uint32_t response = 0UL;
2663
2664 cmd.commandIndex = CY_SD_HOST_SD_CMD5;
2665 cmd.commandArgument = cmdArgument;
2666 cmd.dataPresent = false;
2667 cmd.enableAutoResponseErrorCheck = false;
2668 cmd.respType = CY_SD_HOST_RESPONSE_LEN_48;
2669 cmd.enableCrcCheck = false;
2670 cmd.enableIdxCheck = false;
2671 cmd.cmdType = CY_SD_HOST_CMD_NORMAL;
2672
2673 /* Send the SDIO operation condition command (CMD5) */
2674 ret = Cy_SD_Host_SendCommand(base, &cmd);
2675
2676 if (CY_SD_HOST_SUCCESS == ret)
2677 {
2678 /* Wait for the Command Complete event. */
2679 ret = Cy_SD_Host_PollCmdComplete(base);
2680 }
2681
2682 Cy_SysLib_DelayUs(CY_SD_HOST_NCC_MIN_US);
2683
2684 (void)Cy_SD_Host_GetResponse(base, (uint32_t *)&response, false);
2685
2686 *ocrReg = response;
2687
2688 return ret;
2689 }
2690
2691
2692 /*******************************************************************************
2693 * Function Name: Cy_SD_Host_OpsSdSendOpCond
2694 ****************************************************************************//**
2695 *
2696 * Send ACMD41 (Send SD operation condition command).
2697 *
2698 * \param *base
2699 * The SD host registers structure pointer.
2700 *
2701 * \param *ocrReg
2702 * The Operation Condition register (OCR).
2703 *
2704 * \param cmdArgument
2705 * The command argument.
2706 *
2707 * \param context
2708 * The pointer to the context structure \ref cy_stc_sd_host_context_t allocated
2709 * by the user. The structure is used during the SD host operation for internal
2710 * configuration and data retention. The user must not modify anything
2711 * in this structure.
2712 * If only the SD host functions which do not require context will be used, pass NULL
2713 * as the pointer to the context.
2714 *
2715 * \return \ref cy_en_sd_host_status_t
2716 *
2717 *******************************************************************************/
Cy_SD_Host_OpsSdSendOpCond(SDHC_Type * base,uint32_t * ocrReg,uint32_t cmdArgument,cy_stc_sd_host_context_t const * context)2718 static cy_en_sd_host_status_t Cy_SD_Host_OpsSdSendOpCond(SDHC_Type *base,
2719 uint32_t *ocrReg,
2720 uint32_t cmdArgument,
2721 cy_stc_sd_host_context_t const *context)
2722 {
2723 cy_en_sd_host_status_t ret;
2724 cy_stc_sd_host_cmd_config_t cmd;
2725 uint32_t response = 0UL;
2726
2727 cmd.commandIndex = CY_SD_HOST_SD_ACMD41;
2728 cmd.commandArgument = cmdArgument;
2729 cmd.dataPresent = false;
2730 cmd.enableAutoResponseErrorCheck = false;
2731 cmd.respType = CY_SD_HOST_RESPONSE_LEN_48;
2732 cmd.enableCrcCheck = false;
2733 cmd.enableIdxCheck = false;
2734 cmd.cmdType = CY_SD_HOST_CMD_NORMAL;
2735
2736 /* Send the application command (CMD55) */
2737 ret = Cy_SD_Host_OpsSendAppCmd(base, context);
2738
2739 if (CY_SD_HOST_SUCCESS == ret)
2740 {
2741 ret = Cy_SD_Host_SendCommand(base, &cmd);
2742
2743 if (CY_SD_HOST_SUCCESS == ret)
2744 {
2745 /* Wait for the Command Complete event. */
2746 ret = Cy_SD_Host_PollCmdComplete(base);
2747 }
2748
2749 Cy_SysLib_DelayUs(CY_SD_HOST_NCC_MIN_US);
2750
2751 (void)Cy_SD_Host_GetResponse(base, (uint32_t *)&response, false);
2752
2753 *ocrReg = response;
2754
2755 if (0x0UL == cmdArgument)
2756 {
2757 /* Voltage window = 0 */
2758 }
2759 else if (0UL == (response & CY_SD_HOST_ARG_ACMD41_BUSY))
2760 {
2761 /* Set an error */
2762 ret = CY_SD_HOST_OPERATION_INPROGRESS;
2763 }
2764 else
2765 {
2766 /* Success */
2767 }
2768 }
2769
2770 return ret;
2771 }
2772
2773
2774 /*******************************************************************************
2775 * Function Name: Cy_SD_Host_MmcOpsSendOpCond
2776 ****************************************************************************//**
2777 *
2778 * Send CMD1 (Send MMC operation condition command).
2779 *
2780 * \param *base
2781 * The SD host registers structure pointer.
2782 *
2783 * \param *ocrReg
2784 * The Operation Condition register (OCR).
2785 *
2786 * \param cmdArgument
2787 * The command argument.
2788 *
2789 * \return \ref cy_en_sd_host_status_t
2790 *
2791 *******************************************************************************/
Cy_SD_Host_MmcOpsSendOpCond(SDHC_Type * base,uint32_t * ocrReg,uint32_t cmdArgument)2792 static cy_en_sd_host_status_t Cy_SD_Host_MmcOpsSendOpCond(SDHC_Type *base,
2793 uint32_t *ocrReg,
2794 uint32_t cmdArgument)
2795 {
2796 cy_stc_sd_host_cmd_config_t cmd;
2797 cy_en_sd_host_status_t ret;
2798 uint32_t response = 0UL;
2799
2800 cmd.commandIndex = CY_SD_HOST_SD_CMD1;
2801 cmd.commandArgument = cmdArgument;
2802 cmd.dataPresent = false;
2803 cmd.enableAutoResponseErrorCheck = false;
2804 cmd.respType = CY_SD_HOST_RESPONSE_LEN_48; /* R3 response */
2805 cmd.enableCrcCheck = false;
2806 cmd.enableIdxCheck = false;
2807 cmd.cmdType = CY_SD_HOST_CMD_NORMAL;
2808
2809 ret = Cy_SD_Host_SendCommand(base, &cmd);
2810
2811 if (CY_SD_HOST_SUCCESS == ret)
2812 {
2813 /* Wait for the Command Complete event. */
2814 ret = Cy_SD_Host_PollCmdComplete(base);
2815 }
2816
2817 Cy_SysLib_DelayUs(CY_SD_HOST_NCC_MIN_US);
2818
2819 /* Get the OCR register */
2820 (void)Cy_SD_Host_GetResponse(base, (uint32_t *)&response, false);
2821
2822 *ocrReg = response;
2823
2824 if (CY_SD_HOST_OCR_BUSY_BIT != (CY_SD_HOST_OCR_BUSY_BIT & response))
2825 {
2826 ret = CY_SD_HOST_OPERATION_INPROGRESS;
2827 }
2828
2829 return ret;
2830 }
2831
2832 /* The SD driver low-level section */
2833
2834 /*******************************************************************************
2835 * Function Name: Cy_SD_Host_SdCardChangeClock
2836 ****************************************************************************//**
2837 *
2838 * Changes the Host controller SD clock.
2839 *
2840 * \param *base
2841 * The SD host registers structure pointer.
2842 *
2843 * \param frequency
2844 * The frequency in Hz.
2845 *
2846 * \return \ref cy_en_sd_host_status_t
2847 *
2848 *******************************************************************************/
Cy_SD_Host_SdCardChangeClock(SDHC_Type * base,uint32_t frequency)2849 static cy_en_sd_host_status_t Cy_SD_Host_SdCardChangeClock(SDHC_Type *base, uint32_t frequency)
2850 {
2851 cy_en_sd_host_status_t ret = CY_SD_HOST_ERROR_INVALID_PARAMETER;
2852 uint32_t clkDiv;
2853 uint32_t clockInput = CY_SD_HOST_PERI_FREQUENCY;
2854
2855 CY_ASSERT_L2(CY_SD_HOST_IS_FREQ_VALID(frequency));
2856
2857 if (NULL != base)
2858 {
2859 clkDiv = (clockInput / frequency) >> 1UL;
2860 Cy_SD_Host_DisableSdClk(base);
2861 ret = Cy_SD_Host_SetSdClkDiv(base, (uint16_t)clkDiv);
2862 Cy_SD_Host_EnableSdClk(base);
2863 }
2864
2865 return ret;
2866 }
2867
2868
2869 /*******************************************************************************
2870 * Function Name: Cy_SD_Host_Init
2871 ****************************************************************************//**
2872 *
2873 * Initializes the SD host module.
2874 *
2875 * \param *base
2876 * The SD host registers structure pointer.
2877 *
2878 * \param config
2879 * The SD host module configuration.
2880 *
2881 * \param context
2882 * The pointer to the context structure \ref cy_stc_sd_host_context_t allocated
2883 * by the user. The structure is used during the SD host operation for internal
2884 * configuration and data retention. The user must not modify anything
2885 * in this structure.
2886 * If only the SD host functions which do not require context will be used, pass NULL
2887 * as the pointer to the context.
2888 *
2889 * \return \ref cy_en_sd_host_status_t
2890 *
2891 *******************************************************************************/
Cy_SD_Host_Init(SDHC_Type * base,const cy_stc_sd_host_init_config_t * config,cy_stc_sd_host_context_t * context)2892 cy_en_sd_host_status_t Cy_SD_Host_Init(SDHC_Type *base,
2893 const cy_stc_sd_host_init_config_t *config,
2894 cy_stc_sd_host_context_t *context)
2895 {
2896 cy_en_sd_host_status_t ret = CY_SD_HOST_SUCCESS;
2897
2898 /* Check for the NULL pointer. */
2899 if ((NULL != base) && (NULL != config) && (NULL != context))
2900 {
2901 CY_ASSERT_L3(CY_SD_HOST_IS_DMA_VALID(config->dmaType));
2902
2903 SDHC_CORE_GP_OUT_R(base) = _VAL2FLD(SDHC_CORE_GP_OUT_R_IO_VOLT_SEL_OE, 1u) | /* The IO voltage selection signal. */
2904 _VAL2FLD(SDHC_CORE_GP_OUT_R_CARD_MECH_WRITE_PROT_EN, 1u) | /* The mechanical write protection. */
2905 _VAL2FLD(SDHC_CORE_GP_OUT_R_LED_CTRL_OE, config->enableLedControl ? 1u : 0u) | /* The LED Control. */
2906 _VAL2FLD(SDHC_CORE_GP_OUT_R_CARD_CLOCK_OE, 1u) | /* The Sd Clk. */
2907 _VAL2FLD(SDHC_CORE_GP_OUT_R_CARD_IF_PWR_EN_OE, 1u) | /* Enable the card_if_pwr_en. */
2908 _VAL2FLD(SDHC_CORE_GP_OUT_R_CARD_DETECT_EN, 1u); /* Enable the card detection. */
2909
2910 SDHC_CORE_XFER_MODE_R(base) = 0U;
2911
2912 context->dmaType = config->dmaType;
2913
2914 if (config->emmc)
2915 {
2916 /* Save the card type. */
2917 context->cardType = CY_SD_HOST_EMMC;
2918
2919 /* Set the eMMC Card present. */
2920 SDHC_CORE_EMMC_CTRL_R(base) = (uint16_t)_CLR_SET_FLD16U(SDHC_CORE_EMMC_CTRL_R(base),
2921 SDHC_CORE_EMMC_CTRL_R_CARD_IS_EMMC,
2922 1U);
2923
2924 }
2925 else
2926 {
2927 /* Save the card type. */
2928 context->cardType = CY_SD_HOST_NOT_EMMC;
2929 }
2930
2931 if (config->enableLedControl)
2932 {
2933 /* LED Control. */
2934 SDHC_CORE_HOST_CTRL1_R(base) = (uint8_t)_CLR_SET_FLD8U(SDHC_CORE_HOST_CTRL1_R(base),
2935 SDHC_CORE_HOST_CTRL1_R_LED_CTRL,
2936 1U);
2937 }
2938
2939 /* Select ADMA or not. */
2940 SDHC_CORE_HOST_CTRL1_R(base) = (uint8_t)_CLR_SET_FLD8U(SDHC_CORE_HOST_CTRL1_R(base),
2941 SDHC_CORE_HOST_CTRL1_R_DMA_SEL,
2942 config->dmaType);
2943
2944 /* Set the data timeout to the max. */
2945 SDHC_CORE_TOUT_CTRL_R(base) = _CLR_SET_FLD8U(SDHC_CORE_TOUT_CTRL_R(base),
2946 SDHC_CORE_TOUT_CTRL_R_TOUT_CNT,
2947 CY_SD_HOST_MAX_TIMEOUT);
2948
2949 /* Enable all statuses. */
2950 Cy_SD_Host_SetNormalInterruptEnable(base, CY_SD_HOST_NORMAL_INT_MSK);
2951 Cy_SD_Host_SetErrorInterruptEnable(base, CY_SD_HOST_ERROR_INT_MSK);
2952
2953 /* Enable Host Version 4. */
2954 SDHC_CORE_HOST_CTRL2_R(base) = (uint16_t)_CLR_SET_FLD16U(SDHC_CORE_HOST_CTRL2_R(base),
2955 SDHC_CORE_HOST_CTRL2_R_HOST_VER4_ENABLE,
2956 1U);
2957
2958 /* Wait for the Host stable voltage. */
2959 Cy_SysLib_Delay(CY_SD_HOST_SUPPLY_RAMP_UP_TIME_MS);
2960
2961 /* Reset normal events. */
2962 Cy_SD_Host_NormalReset(base);
2963 }
2964 else
2965 {
2966 ret = CY_SD_HOST_ERROR_INVALID_PARAMETER;
2967 }
2968
2969 return ret;
2970 }
2971
2972
2973 /*******************************************************************************
2974 * Function Name: Cy_SD_Host_DeInit
2975 ****************************************************************************//**
2976 *
2977 * Restores the SD Host block registers back to default.
2978 *
2979 * \param *base
2980 * The SD host registers structure pointer.
2981 *
2982 *******************************************************************************/
Cy_SD_Host_DeInit(SDHC_Type * base)2983 void Cy_SD_Host_DeInit(SDHC_Type *base)
2984 {
2985 /* Check for the NULL pointer. */
2986 if (NULL != base)
2987 {
2988 (void)Cy_SD_Host_PollCmdLineFree(base);
2989 (void)Cy_SD_Host_PollDataLineNotInhibit(base);
2990
2991 Cy_SD_Host_SoftwareReset(base, CY_SD_HOST_RESET_ALL);
2992
2993 /* Disable the SDHC block. */
2994 SDHC_WRAP_CTL(base) = _CLR_SET_FLD32U(SDHC_WRAP_CTL(base),
2995 SDHC_WRAP_CTL_ENABLE,
2996 0UL);
2997 }
2998 }
2999
3000
3001 /*******************************************************************************
3002 * Function Name: Cy_SD_Host_AbortTransfer
3003 ****************************************************************************//**
3004 *
3005 * Calling this function causes abortion of the currently executing command with
3006 * data. It doesn't issue a reset, that is the users responsibility.
3007 *
3008 * \param *base
3009 * The SD host registers structure pointer.
3010 *
3011 * \param context
3012 * The pointer to the context structure \ref cy_stc_sd_host_context_t allocated
3013 * by the user. The structure is used during the SD host operation for internal
3014 * configuration and data retention. The user must not modify anything
3015 * in this structure.
3016 * If only the SD host functions which do not require context will be used, pass NULL
3017 * as the pointer to the context.
3018 *
3019 * \return \ref cy_en_sd_host_status_t
3020 *
3021 *******************************************************************************/
Cy_SD_Host_AbortTransfer(SDHC_Type * base,cy_stc_sd_host_context_t const * context)3022 cy_en_sd_host_status_t Cy_SD_Host_AbortTransfer(SDHC_Type *base,
3023 cy_stc_sd_host_context_t const *context)
3024 {
3025 cy_stc_sd_host_cmd_config_t cmd;
3026 cy_en_sd_host_status_t ret = CY_SD_HOST_ERROR_INVALID_PARAMETER;
3027 uint32_t response = 0UL;
3028 uint32_t retry;
3029
3030 /* Check for the NULL pointer. */
3031 if ((NULL != base) && (NULL != context))
3032 {
3033 /* Check the card - Memory or SDIO? */
3034 if (CY_SD_HOST_SDIO == context->cardType)
3035 {
3036 ret = Cy_SD_Host_OpsSendIoRwDirectCmd(base,
3037 1UL,
3038 0UL,
3039 0UL,
3040 CY_SD_HOST_CCCR_IO_ABORT,
3041 1UL);
3042 }
3043 else
3044 {
3045 cmd.commandArgument = context->RCA << CY_SD_HOST_RCA_SHIFT;
3046 cmd.dataPresent = false;
3047 cmd.enableAutoResponseErrorCheck = false;
3048 cmd.enableCrcCheck = true;
3049 cmd.enableIdxCheck = true;
3050
3051 /* Issue CMD12. */
3052 cmd.respType = CY_SD_HOST_RESPONSE_LEN_48B;
3053 cmd.commandIndex = CY_SD_HOST_SD_CMD12;
3054 cmd.cmdType = CY_SD_HOST_CMD_ABORT;
3055 ret = Cy_SD_Host_SendCommand(base, &cmd);
3056
3057 if (CY_SD_HOST_SUCCESS == ret)
3058 {
3059 /* Wait for the Command Complete event. */
3060 ret = Cy_SD_Host_PollCmdComplete(base);
3061 }
3062
3063 if (CY_SD_HOST_SUCCESS == ret)
3064 {
3065 Cy_SysLib_DelayUs(CY_SD_HOST_NCC_MIN_US);
3066
3067 ret = CY_SD_HOST_ERROR_TIMEOUT;
3068 retry = CY_SD_HOST_RETRY_TIME;
3069
3070 /* Waiting for DAT0 deassertion in scope of R1b response */
3071 while (retry > 0UL)
3072 {
3073 /* Command Complete */
3074 if ((Cy_SD_Host_GetPresentState(base) & CY_SD_HOST_DAT_0_Msk) == CY_SD_HOST_DAT_0_Msk)
3075 {
3076 ret = CY_SD_HOST_SUCCESS;
3077 break;
3078 }
3079
3080 Cy_SysLib_DelayUs(CY_SD_HOST_CMD_TIMEOUT_MS);
3081 retry--;
3082 }
3083 }
3084
3085 if (CY_SD_HOST_SUCCESS != ret)
3086 {
3087 return ret;
3088 }
3089
3090 Cy_SysLib_DelayUs(CY_SD_HOST_NCC_MIN_US);
3091
3092 Cy_SD_Host_ErrorReset(base);
3093
3094 /* Issue CMD13. */
3095 cmd.respType = CY_SD_HOST_RESPONSE_LEN_48;
3096 cmd.commandIndex = CY_SD_HOST_SD_CMD13;
3097 cmd.cmdType = CY_SD_HOST_CMD_NORMAL;
3098 ret = Cy_SD_Host_SendCommand(base, &cmd);
3099
3100 if (CY_SD_HOST_SUCCESS == ret)
3101 {
3102 /* Wait for the Command Complete event. */
3103 ret = Cy_SD_Host_PollCmdComplete(base);
3104 }
3105
3106 if (CY_SD_HOST_SUCCESS != ret)
3107 {
3108 return ret;
3109 }
3110
3111 Cy_SysLib_DelayUs(CY_SD_HOST_NCC_MIN_US);
3112
3113 /* Get R1 */
3114 (void)Cy_SD_Host_GetResponse(base, (uint32_t *)&response, false);
3115
3116 /* Check if the card is in the transition state. */
3117 if ((CY_SD_HOST_CARD_TRAN << CY_SD_HOST_CMD13_CURRENT_STATE) !=
3118 (response & CY_SD_HOST_CMD13_CURRENT_STATE_MSK))
3119 {
3120 /* Issue CMD12 */
3121 cmd.respType = CY_SD_HOST_RESPONSE_LEN_48B;
3122 cmd.commandIndex = CY_SD_HOST_SD_CMD12;
3123 cmd.cmdType = CY_SD_HOST_CMD_ABORT;
3124 ret = Cy_SD_Host_SendCommand(base, &cmd);
3125
3126 if (CY_SD_HOST_SUCCESS == ret)
3127 {
3128 /* Wait for the Command Complete event. */
3129 ret = Cy_SD_Host_PollCmdComplete(base);
3130 }
3131
3132 if (CY_SD_HOST_SUCCESS == ret)
3133 {
3134 Cy_SysLib_DelayUs(CY_SD_HOST_NCC_MIN_US);
3135
3136 ret = CY_SD_HOST_ERROR_TIMEOUT;
3137 retry = CY_SD_HOST_RETRY_TIME;
3138
3139 /* Waiting for DAT0 deassertion in scope of R1b response */
3140 while (retry > 0UL)
3141 {
3142 /* Command Complete */
3143 if ((Cy_SD_Host_GetPresentState(base) & CY_SD_HOST_DAT_0_Msk) == CY_SD_HOST_DAT_0_Msk)
3144 {
3145 ret = CY_SD_HOST_SUCCESS;
3146 break;
3147 }
3148
3149 Cy_SysLib_DelayUs(CY_SD_HOST_CMD_TIMEOUT_MS);
3150 retry--;
3151 }
3152 }
3153
3154 if (CY_SD_HOST_SUCCESS != ret)
3155 {
3156 return ret;
3157 }
3158
3159 Cy_SysLib_DelayUs(CY_SD_HOST_NCC_MIN_US);
3160
3161 Cy_SD_Host_ErrorReset(base);
3162
3163 /* Issue CMD13. */
3164 cmd.respType = CY_SD_HOST_RESPONSE_LEN_48;
3165 cmd.commandIndex = CY_SD_HOST_SD_CMD13;
3166 cmd.cmdType = CY_SD_HOST_CMD_NORMAL;
3167 ret = Cy_SD_Host_SendCommand(base, &cmd);
3168
3169 if (CY_SD_HOST_SUCCESS == ret)
3170 {
3171 /* Wait for the Command Complete event. */
3172 ret = Cy_SD_Host_PollCmdComplete(base);
3173 }
3174 if (CY_SD_HOST_SUCCESS == ret)
3175 {
3176 Cy_SysLib_DelayUs(CY_SD_HOST_NCC_MIN_US);
3177
3178 /* Get R1. */
3179 (void)Cy_SD_Host_GetResponse(base, (uint32_t *)&response, false);
3180
3181 /* Check if the card is in the transition state. */
3182 if ((CY_SD_HOST_CARD_TRAN << CY_SD_HOST_CMD13_CURRENT_STATE) !=
3183 (response & CY_SD_HOST_CMD13_CURRENT_STATE_MSK))
3184 {
3185 ret = CY_SD_HOST_ERROR;
3186 }
3187 }
3188 }
3189 }
3190 }
3191
3192 return ret;
3193 }
3194
3195
3196 /*******************************************************************************
3197 * Function Name: Cy_SD_Host_WriteProtect
3198 ****************************************************************************//**
3199 *
3200 * Write protects the blocks of data from the SD card.
3201 * This function should only be called after Cy_SD_Host_SDCard_Init()/eMMC_Init().
3202 *
3203 * \param *base
3204 * The SD host registers structure pointer.
3205 *
3206 * \param writeProtect
3207 * \ref cy_en_sd_host_write_protect_t.
3208 *
3209 * \param context
3210 * The pointer to the context structure \ref cy_stc_sd_host_context_t allocated
3211 * by the user. The structure is used during the SD host operation for internal
3212 * configuration and data retention. The user must not modify anything
3213 * in this structure.
3214 * If only the SD host functions which do not require context will be used, pass NULL
3215 * as the pointer to the context.
3216 *
3217 * \return \ref cy_en_sd_host_status_t
3218 *
3219 *******************************************************************************/
Cy_SD_Host_WriteProtect(SDHC_Type * base,cy_en_sd_host_write_protect_t writeProtect,cy_stc_sd_host_context_t * context)3220 cy_en_sd_host_status_t Cy_SD_Host_WriteProtect(SDHC_Type *base,
3221 cy_en_sd_host_write_protect_t writeProtect,
3222 cy_stc_sd_host_context_t *context)
3223 {
3224 cy_en_sd_host_status_t ret = CY_SD_HOST_SUCCESS;
3225 uint32_t csdReg;
3226
3227 /* Check for the NULL pointer. */
3228 if ((NULL != base) && (NULL != context))
3229 {
3230 switch (writeProtect)
3231 {
3232 case CY_SD_HOST_PERMANENT:
3233 csdReg = 1UL << CY_SD_HOST_CSD_PERM_WRITE_PROTECT;
3234 break;
3235 case CY_SD_HOST_ENABLE_TEMPORARY:
3236 csdReg = 1UL << CY_SD_HOST_CSD_TEMP_WRITE_PROTECT;
3237 break;
3238 case CY_SD_HOST_DISABLE_TEMPORARY:
3239 csdReg = 0UL;
3240 break;
3241 default:
3242 ret = CY_SD_HOST_ERROR_INVALID_PARAMETER;
3243 break;
3244 }
3245
3246 if (CY_SD_HOST_SUCCESS == ret)
3247 {
3248 ret = Cy_SD_Host_OpsProgramCsd(base, csdReg, context);
3249 }
3250 }
3251 else
3252 {
3253 ret = CY_SD_HOST_ERROR_INVALID_PARAMETER;
3254 }
3255
3256 return ret;
3257 }
3258
3259
3260 /*******************************************************************************
3261 * Function Name: Cy_SD_Host_GetCardStatus
3262 ****************************************************************************//**
3263 *
3264 * Returns the card status.
3265 *
3266 * \param *base
3267 * The SD host registers structure pointer.
3268 *
3269 * \param context
3270 * The pointer to the context structure \ref cy_stc_sd_host_context_t allocated
3271 * by the user. The structure is used during the SD host operation for internal
3272 * configuration and data retention. The user must not modify anything
3273 * in this structure.
3274 * If only the SD host functions which do not require context will be used, pass NULL
3275 * as the pointer to the context.
3276 *
3277 * \return uint32_t
3278 * The card status (the result of the CMD13 command). To get the details of
3279 * card status, "AND" returned value with \ref cy_en_sd_host_r1_response_t.
3280 *
3281 *******************************************************************************/
Cy_SD_Host_GetCardStatus(SDHC_Type * base,cy_stc_sd_host_context_t const * context)3282 uint32_t Cy_SD_Host_GetCardStatus(SDHC_Type *base,
3283 cy_stc_sd_host_context_t const *context)
3284 {
3285 cy_stc_sd_host_cmd_config_t cmd;
3286 cy_en_sd_host_status_t ret = CY_SD_HOST_ERROR_INVALID_PARAMETER;
3287 uint32_t response = 0UL;
3288 uint32_t status = (1UL << CY_SD_HOST_CMD13_ERROR);
3289
3290 /* Check for the NULL pointer. */
3291 if ((NULL != base) && (NULL != context))
3292 {
3293 cmd.commandIndex = CY_SD_HOST_SD_CMD13;
3294 cmd.commandArgument = context->RCA << CY_SD_HOST_RCA_SHIFT;
3295 cmd.dataPresent = false;
3296 cmd.enableAutoResponseErrorCheck = false;
3297 cmd.respType = CY_SD_HOST_RESPONSE_LEN_48;
3298 cmd.enableCrcCheck = true;
3299 cmd.enableIdxCheck = true;
3300 cmd.cmdType = CY_SD_HOST_CMD_NORMAL;
3301
3302 ret = Cy_SD_Host_SendCommand(base, &cmd);
3303
3304 if (CY_SD_HOST_SUCCESS == ret)
3305 {
3306 /* Wait for the Command Complete event. */
3307 ret = Cy_SD_Host_PollCmdComplete(base);
3308 }
3309
3310 if (CY_SD_HOST_SUCCESS == ret)
3311 {
3312 (void)Cy_SD_Host_GetResponse(base, (uint32_t *)&response, false);
3313 status = response;
3314 }
3315 else
3316 {
3317 status = (1UL << CY_SD_HOST_CMD13_ERROR);
3318 }
3319 }
3320
3321 return status;
3322 }
3323
3324
3325 /*******************************************************************************
3326 * Function Name: Cy_SD_Host_GetSdStatus
3327 ****************************************************************************//**
3328 *
3329 * Returns the SD status from the card.
3330 *
3331 * \param *base
3332 * The SD host registers structure pointer.
3333 *
3334 * \param *sdStatus
3335 * The pointer to where to store the SD status array.
3336 *
3337 * \param context
3338 * The pointer to the context structure \ref cy_stc_sd_host_context_t allocated
3339 * by the user. The structure is used during the SD host operation for internal
3340 * configuration and data retention. The user must not modify anything
3341 * in this structure.
3342 * If only the SD host functions which do not require context will be used, pass NULL
3343 * as the pointer to the context.
3344 *
3345 * \return \ref cy_en_sd_host_status_t
3346 *
3347 *******************************************************************************/
Cy_SD_Host_GetSdStatus(SDHC_Type * base,uint32_t * sdStatus,cy_stc_sd_host_context_t const * context)3348 cy_en_sd_host_status_t Cy_SD_Host_GetSdStatus(SDHC_Type *base,
3349 uint32_t *sdStatus,
3350 cy_stc_sd_host_context_t const *context)
3351 {
3352 cy_en_sd_host_status_t ret = CY_SD_HOST_ERROR_INVALID_PARAMETER;
3353 cy_stc_sd_host_cmd_config_t cmd;
3354 cy_stc_sd_host_data_config_t dataConfig;
3355
3356 /* Check for the NULL pointer */
3357 if ((NULL != base) && (NULL != sdStatus) && (NULL != context))
3358 {
3359 ret = Cy_SD_Host_OpsSendAppCmd(base, context);
3360 if (CY_SD_HOST_SUCCESS == ret)
3361 {
3362 cmd.commandIndex = CY_SD_HOST_SD_CMD13;
3363 cmd.commandArgument = context->RCA << CY_SD_HOST_RCA_SHIFT;
3364 cmd.dataPresent = true;
3365 cmd.enableAutoResponseErrorCheck = false;
3366 cmd.respType = CY_SD_HOST_RESPONSE_LEN_48;
3367 cmd.enableCrcCheck = true;
3368 cmd.enableIdxCheck = true;
3369 cmd.cmdType = CY_SD_HOST_CMD_NORMAL;
3370
3371 dataConfig.blockSize = CY_SD_HOST_SD_STATUS_BLOCKS;
3372 dataConfig.numberOfBlock = 1UL;
3373 dataConfig.enableDma = false;
3374 dataConfig.autoCommand = CY_SD_HOST_AUTO_CMD_NONE;
3375 dataConfig.read = true;
3376 dataConfig.data = sdStatus;
3377 dataConfig.dataTimeout = CY_SD_HOST_MAX_TIMEOUT;
3378 dataConfig.enableIntAtBlockGap = false;
3379 dataConfig.enReliableWrite = false;
3380
3381 (void)Cy_SD_Host_InitDataTransfer(base, &dataConfig);
3382
3383 ret = Cy_SD_Host_SendCommand(base, &cmd);
3384
3385 if (CY_SD_HOST_SUCCESS == ret)
3386 {
3387 /* Wait for the Command Complete event. */
3388 ret = Cy_SD_Host_PollCmdComplete(base);
3389 }
3390
3391 if (CY_SD_HOST_SUCCESS == ret)
3392 {
3393 ret = Cy_SD_Host_CmdRxData(base, &dataConfig);
3394 }
3395 }
3396 }
3397
3398 return ret;
3399 }
3400
3401
3402 /*******************************************************************************
3403 * Function Name: Cy_SD_Host_GetOcr
3404 ****************************************************************************//**
3405 *
3406 * Reads the Operating Condition Register (OCR) register from the card.
3407 *
3408 * \note This function can be used only if the card is in the Idle state.
3409 *
3410 * \param *base
3411 * The SD host registers structure pointer.
3412 *
3413 * \param context
3414 * The pointer to the context structure \ref cy_stc_sd_host_context_t allocated
3415 * by the user. The structure is used during the SD host operation for internal
3416 * configuration and data retention. The user must not modify anything
3417 * in this structure.
3418 * If only the SD host functions which do not require context will be used, pass NULL
3419 * as the pointer to the context.
3420 *
3421 * \return uint32_t
3422 * The OCR register.
3423 *
3424 * \note For combo cards, the function returns the OCR register for the IO portion only.
3425 *
3426 *******************************************************************************/
Cy_SD_Host_GetOcr(SDHC_Type * base,cy_stc_sd_host_context_t const * context)3427 uint32_t Cy_SD_Host_GetOcr(SDHC_Type *base, cy_stc_sd_host_context_t const *context)
3428 {
3429 uint32_t ocrReg = 0UL;
3430
3431 if (CY_SD_HOST_SD == context->cardType)
3432 {
3433 (void)Cy_SD_Host_OpsSdSendOpCond(base, &ocrReg, 0UL, context);
3434 }
3435 else if (CY_SD_HOST_EMMC == context->cardType)
3436 {
3437 (void)Cy_SD_Host_MmcOpsSendOpCond(base, &ocrReg, 0UL);
3438 }
3439 else if ((CY_SD_HOST_SDIO == context->cardType) ||
3440 (CY_SD_HOST_COMBO == context->cardType))
3441 {
3442 (void)Cy_SD_Host_OpsSdioSendOpCond(base, &ocrReg, 0UL);
3443 }
3444 else
3445 {
3446 /* Invalid card. */
3447 }
3448
3449 return ocrReg;
3450 }
3451
3452
3453 /*******************************************************************************
3454 * Function Name: Cy_SD_Host_GetCid
3455 ****************************************************************************//**
3456 *
3457 * Returns the Card Identification Register (CID) contents.
3458 *
3459 * \note This function can be used only if the card is in the Ready state.
3460 *
3461 * \param *base
3462 * The SD host registers structure pointer.
3463 *
3464 * \param cid
3465 * The pointer to where to store the CID register.
3466 *
3467 * \return \ref cy_en_sd_host_status_t
3468 *
3469 *******************************************************************************/
Cy_SD_Host_GetCid(SDHC_Type * base,uint32_t * cid)3470 cy_en_sd_host_status_t Cy_SD_Host_GetCid(SDHC_Type *base,
3471 uint32_t *cid)
3472 {
3473 cy_stc_sd_host_cmd_config_t cmd;
3474 cy_en_sd_host_status_t ret = CY_SD_HOST_ERROR_INVALID_PARAMETER;
3475 uint32_t i;
3476 uint32_t response[CY_SD_HOST_RESPONSE_SIZE] = { 0UL };
3477
3478 /* Check for the NULL pointer */
3479 if ((NULL != base) && (NULL != cid))
3480 {
3481 cmd.commandIndex = CY_SD_HOST_SD_CMD2;
3482 cmd.commandArgument = 0UL;
3483 cmd.dataPresent = false;
3484 cmd.enableAutoResponseErrorCheck = false;
3485 cmd.respType = CY_SD_HOST_RESPONSE_LEN_136;
3486 cmd.enableCrcCheck = true;
3487 cmd.enableIdxCheck = false;
3488 cmd.cmdType = CY_SD_HOST_CMD_NORMAL;
3489
3490 ret = Cy_SD_Host_SendCommand(base, &cmd);
3491
3492 if (CY_SD_HOST_SUCCESS == ret)
3493 {
3494 /* Wait for the Command Complete event. */
3495 ret = Cy_SD_Host_PollCmdComplete(base);
3496 }
3497
3498 if (CY_SD_HOST_SUCCESS == ret)
3499 {
3500 (void)Cy_SD_Host_GetResponse(base, (uint32_t *)response, true);
3501
3502 /* Get CID from the response. */
3503 for ( i = 0UL; i < CY_SD_HOST_CID_SIZE; i++ )
3504 {
3505 cid[i] = *((uint32_t *)(response + i));
3506 }
3507 }
3508 }
3509
3510 return ret;
3511 }
3512
3513
3514 /*******************************************************************************
3515 * Function Name: Cy_SD_Host_GetCsd
3516 ****************************************************************************//**
3517 *
3518 * Returns the Card Specific Data (CSD) register contents.
3519 *
3520 * \note This function can be used only if the card is in the Stand-by state.
3521 *
3522 * \param *base
3523 * The SD host registers structure pointer.
3524 *
3525 * \param *csd
3526 * The pointer to where to store the CSD register.
3527 *
3528 * \param context
3529 * The pointer to the context structure \ref cy_stc_sd_host_context_t allocated
3530 * by the user. The structure is used during the SD host operation for internal
3531 * configuration and data retention. The user must not modify anything
3532 * in this structure.
3533 * If only the SD host functions which do not require context will be used, pass NULL
3534 * as the pointer to the context.
3535 *
3536 * \return \ref cy_en_sd_host_status_t
3537 *
3538 *******************************************************************************/
Cy_SD_Host_GetCsd(SDHC_Type * base,uint32_t * csd,cy_stc_sd_host_context_t * context)3539 cy_en_sd_host_status_t Cy_SD_Host_GetCsd(SDHC_Type *base,
3540 uint32_t *csd,
3541 cy_stc_sd_host_context_t *context)
3542 {
3543 cy_stc_sd_host_cmd_config_t cmd;
3544 cy_en_sd_host_status_t ret = CY_SD_HOST_ERROR_INVALID_PARAMETER;
3545 uint32_t response[CY_SD_HOST_RESPONSE_SIZE] = { 0UL };
3546 uint32_t numSector;
3547 uint32_t cSize;
3548 uint32_t cSizeMult;
3549 uint32_t readBlLen;
3550
3551 /* Check for the NULL pointer */
3552 if ((NULL != base) && (NULL != csd) && (NULL != context))
3553 {
3554 cmd.commandIndex = CY_SD_HOST_SD_CMD9;
3555 cmd.commandArgument = context->RCA << CY_SD_HOST_RCA_SHIFT;
3556 cmd.dataPresent = false;
3557 cmd.enableAutoResponseErrorCheck = false;
3558 cmd.respType = CY_SD_HOST_RESPONSE_LEN_136;
3559 cmd.enableCrcCheck = true;
3560 cmd.enableIdxCheck = false;
3561 cmd.cmdType = CY_SD_HOST_CMD_NORMAL;
3562
3563 ret = Cy_SD_Host_SendCommand(base, &cmd);
3564
3565 if (CY_SD_HOST_SUCCESS == ret)
3566 {
3567 /* Wait for the Command Complete event. */
3568 ret = Cy_SD_Host_PollCmdComplete(base);
3569 }
3570
3571 if (ret == CY_SD_HOST_SUCCESS)
3572 {
3573 (void)Cy_SD_Host_GetResponse(base, (uint32_t *)response, true);
3574
3575 (void)memcpy(csd, response, sizeof(response));
3576 (void)memcpy(context->csd, response, sizeof(response));
3577
3578 if ((CY_SD_HOST_SDHC == context->cardCapacity) ||
3579 (CY_SD_HOST_SDXC == context->cardCapacity)) /* High/Ext. Capacity (CSD version 2.0) */
3580 {
3581 cSize = (response[1] & CY_SD_HOST_CSD_V2_C_SIZE_MASK) >>
3582 CY_SD_HOST_CSD_V2_C_SIZE_POS;
3583
3584 numSector = (cSize + 1UL) << CY_SD_HOST_CSD_V2_SECTOR_MULT;
3585 }
3586 else /* Standard Capacity (CSD version 1.0) */
3587 {
3588 cSize = (response[2] & CY_SD_HOST_CSD_V1_C_SIZE_MSB_MASK) <<
3589 CY_SD_HOST_CSD_V1_C_SIZE_MSB_MULT; /* C_SIZE3 */
3590 cSize +=((response[1] & CY_SD_HOST_CSD_V1_C_SIZE_ISB_MASK) >>
3591 CY_SD_HOST_CSD_V1_C_SIZE_ISB_POS) <<
3592 CY_SD_HOST_CSD_V1_C_SIZE_ISB_MULT; /* C_SIZE2 */
3593 cSize += (response[1] & CY_SD_HOST_CSD_V1_C_SIZE_LSB_MASK) >>
3594 CY_SD_HOST_CSD_V1_C_SIZE_LSB_POS; /* C_SIZE1 */
3595
3596 cSizeMult = ((response[1] & CY_SD_HOST_CSD_V1_C_SIZE_MULT_MASK) >>
3597 CY_SD_HOST_CSD_V1_C_SIZE_MULT_POS);
3598
3599 readBlLen = (response[2] & CY_SD_HOST_CSD_V1_READ_BL_LEN_MASK) >>
3600 CY_SD_HOST_CSD_V1_READ_BL_LEN_POS; /* READ_BL_LEN */
3601
3602 numSector = (cSize + 1UL) << (cSizeMult + 2UL);
3603
3604 if (CY_SD_HOST_CSD_V1_BL_LEN_1024 == readBlLen)
3605 {
3606 numSector *= CY_SD_HOST_CSD_V1_1024_SECT_FACTOR;
3607 }
3608 else if (CY_SD_HOST_CSD_V1_BL_LEN_2048 == readBlLen)
3609 {
3610 numSector *= CY_SD_HOST_CSD_V1_2048_SECT_FACTOR;
3611 }
3612 else
3613 {
3614 /* Block length = 512 bytes (readBlLen = 9u) */
3615 }
3616 }
3617
3618 context->maxSectorNum = numSector;
3619 }
3620 }
3621
3622 return ret;
3623 }
3624
3625
3626 /*******************************************************************************
3627 * Function Name: Cy_SD_Host_GetExtCsd
3628 ****************************************************************************//**
3629 *
3630 * Returns the EXTCSD Register contents. This is only for EMMC cards.
3631 * There are 512 bytes of data being read.
3632 *
3633 * \param *base
3634 * The SD host registers structure pointer.
3635 *
3636 * \param *extCsd
3637 * The pointer to where to store the EXTCSD register.
3638 *
3639 * \param context
3640 * The pointer to the context structure \ref cy_stc_sd_host_context_t allocated
3641 * by the user. The structure is used during the SD host operation for internal
3642 * configuration and data retention. The user must not modify anything
3643 * in this structure.
3644 * If only the SD host functions which do not require context will be used, pass NULL
3645 * as the pointer to the context.
3646 *
3647 * \return \ref cy_en_sd_host_status_t
3648 *
3649 *******************************************************************************/
Cy_SD_Host_GetExtCsd(SDHC_Type * base,uint32_t * extCsd,cy_stc_sd_host_context_t * context)3650 cy_en_sd_host_status_t Cy_SD_Host_GetExtCsd(SDHC_Type *base, uint32_t *extCsd,
3651 cy_stc_sd_host_context_t *context)
3652 {
3653 cy_stc_sd_host_cmd_config_t cmd;
3654 cy_en_sd_host_status_t ret = CY_SD_HOST_ERROR_INVALID_PARAMETER;
3655 cy_stc_sd_host_data_config_t dataConfig;
3656
3657 /* Check for the NULL pointer */
3658 if ((NULL != base) && (NULL != extCsd) && (NULL != context))
3659 {
3660 cmd.commandIndex = CY_SD_HOST_MMC_CMD8;
3661 cmd.commandArgument = context->RCA << CY_SD_HOST_RCA_SHIFT;
3662 cmd.dataPresent = true;
3663 cmd.enableAutoResponseErrorCheck = false;
3664 cmd.respType = CY_SD_HOST_RESPONSE_LEN_48;
3665 cmd.enableCrcCheck = true;
3666 cmd.enableIdxCheck = true;
3667 cmd.cmdType = CY_SD_HOST_CMD_NORMAL;
3668
3669 dataConfig.blockSize = CY_SD_HOST_BLOCK_SIZE;
3670 dataConfig.numberOfBlock = 1UL;
3671 dataConfig.enableDma = false;
3672 dataConfig.autoCommand = CY_SD_HOST_AUTO_CMD_NONE;
3673 dataConfig.read = true;
3674 dataConfig.data = extCsd;
3675 dataConfig.dataTimeout = CY_SD_HOST_MAX_TIMEOUT;
3676 dataConfig.enableIntAtBlockGap = false;
3677 dataConfig.enReliableWrite = false;
3678
3679 (void)Cy_SD_Host_InitDataTransfer(base, &dataConfig);
3680
3681 ret = Cy_SD_Host_SendCommand(base, &cmd);
3682
3683 if (CY_SD_HOST_SUCCESS == ret)
3684 {
3685 /* Wait for the Command Complete event. */
3686 ret = Cy_SD_Host_PollCmdComplete(base);
3687 }
3688
3689 if (CY_SD_HOST_SUCCESS == ret)
3690 {
3691 ret = Cy_SD_Host_CmdRxData(base, &dataConfig);
3692 }
3693
3694 if (CY_SD_HOST_SUCCESS == ret)
3695 {
3696 context->maxSectorNum = extCsd[CY_SD_HOST_EXTCSD_SEC_COUNT];
3697
3698 context->cardCapacity = CY_SD_HOST_EMMC_LESS_2G;
3699
3700 /* Check if the eMMC capacity is greater than 2GB */
3701 if ((CY_SD_HOST_MMC_LEGACY_SIZE_BYTES/CY_SD_HOST_BLOCK_SIZE) <
3702 context->maxSectorNum)
3703 {
3704 context->cardCapacity = CY_SD_HOST_EMMC_GREATER_2G;
3705 }
3706 }
3707 }
3708
3709 return ret;
3710 }
3711
3712
3713 /*******************************************************************************
3714 * Function Name: Cy_SD_Host_GetRca
3715 ****************************************************************************//**
3716 *
3717 * Reads the Relative Card Address (RCA) register from the card.
3718 *
3719 * \note This function can be used only if the card is in the Identification or
3720 * Stand-by state.
3721 *
3722 * \param *base
3723 * The SD host registers structure pointer.
3724 *
3725 * \return uint32_t
3726 * The RCA register.
3727 *
3728 *******************************************************************************/
Cy_SD_Host_GetRca(SDHC_Type * base)3729 uint32_t Cy_SD_Host_GetRca(SDHC_Type *base)
3730 {
3731 cy_stc_sd_host_cmd_config_t cmd;
3732 uint32_t response = 0UL;
3733
3734 cmd.commandIndex = CY_SD_HOST_SD_CMD3;
3735 cmd.commandArgument = 0UL;
3736 cmd.dataPresent = false;
3737 cmd.enableAutoResponseErrorCheck = false;
3738 cmd.respType = CY_SD_HOST_RESPONSE_LEN_48;
3739 cmd.enableCrcCheck = true;
3740 cmd.enableIdxCheck = true;
3741 cmd.cmdType = CY_SD_HOST_CMD_NORMAL;
3742
3743 (void)Cy_SD_Host_SendCommand(base, &cmd);
3744
3745 /* Wait for the Command Complete event. */
3746 (void)Cy_SD_Host_PollCmdComplete(base);
3747
3748 Cy_SysLib_DelayUs(CY_SD_HOST_NCC_MIN_US);
3749
3750 (void)Cy_SD_Host_GetResponse(base, (uint32_t *)&response, false);
3751
3752 return (response >> CY_SD_HOST_RCA_SHIFT);
3753 }
3754
3755
3756 /*******************************************************************************
3757 * Function Name: Cy_SD_Host_GetScr
3758 ****************************************************************************//**
3759 *
3760 * Returns the SD Card Configuration Register (SCR) Register contents.
3761 *
3762 * \note This function can be used only if the card is in the Transition state.
3763 *
3764 * \param *base
3765 * The SD host registers structure pointer.
3766 *
3767 * \param *scr
3768 * The pointer to where to store the SCR register.
3769 *
3770 * \param context
3771 * The pointer to the context structure \ref cy_stc_sd_host_context_t allocated
3772 * by the user. The structure is used during the SD host operation for internal
3773 * configuration and data retention. The user must not modify anything
3774 * in this structure.
3775 * If only the SD host functions which do not require context will be used, pass NULL
3776 * as the pointer to the context.
3777 *
3778 * \return \ref cy_en_sd_host_status_t
3779 *
3780 *******************************************************************************/
Cy_SD_Host_GetScr(SDHC_Type * base,uint32_t * scr,cy_stc_sd_host_context_t const * context)3781 cy_en_sd_host_status_t Cy_SD_Host_GetScr(SDHC_Type *base,
3782 uint32_t *scr,
3783 cy_stc_sd_host_context_t const *context)
3784 {
3785 cy_stc_sd_host_cmd_config_t cmd;
3786 cy_en_sd_host_status_t ret = CY_SD_HOST_ERROR_INVALID_PARAMETER;
3787 cy_stc_sd_host_data_config_t dataConfig;
3788
3789 /* Check for the NULL pointer */
3790 if ((NULL != base) && (NULL != scr) && (NULL != context))
3791 {
3792 ret = Cy_SD_Host_OpsSendAppCmd(base, context);
3793 if (CY_SD_HOST_SUCCESS == ret)
3794 {
3795 cmd.commandIndex = CY_SD_HOST_SD_ACMD51;
3796 cmd.commandArgument = context->RCA << CY_SD_HOST_RCA_SHIFT;
3797 cmd.dataPresent = true;
3798 cmd.enableAutoResponseErrorCheck = false;
3799 cmd.respType = CY_SD_HOST_RESPONSE_LEN_48B;
3800 cmd.enableCrcCheck = true;
3801 cmd.enableIdxCheck = true;
3802 cmd.cmdType = CY_SD_HOST_CMD_NORMAL;
3803
3804 dataConfig.blockSize = CY_SD_HOST_SCR_BLOCKS;
3805 dataConfig.numberOfBlock = 1UL;
3806 dataConfig.enableDma = false;
3807 dataConfig.autoCommand = CY_SD_HOST_AUTO_CMD_NONE;
3808 dataConfig.read = true;
3809 dataConfig.data = (uint32_t *)scr;
3810 dataConfig.dataTimeout = CY_SD_HOST_MAX_TIMEOUT;
3811 dataConfig.enableIntAtBlockGap = false;
3812 dataConfig.enReliableWrite = false;
3813
3814 (void)Cy_SD_Host_InitDataTransfer(base, &dataConfig);
3815
3816 ret = Cy_SD_Host_SendCommand(base, &cmd);
3817
3818 if (CY_SD_HOST_SUCCESS == ret)
3819 {
3820 /* Wait for the Command Complete event. */
3821 ret = Cy_SD_Host_PollCmdComplete(base);
3822 }
3823
3824 if (CY_SD_HOST_SUCCESS == ret)
3825 {
3826 ret = Cy_SD_Host_CmdRxData(base, &dataConfig);
3827 }
3828 }
3829 }
3830
3831 return ret;
3832 }
3833
3834
3835 /*******************************************************************************
3836 * Function Name: Cy_SD_Host_ErrorReset
3837 ****************************************************************************//**
3838 *
3839 * Checks for error event and resets it. Then resets the CMD line.
3840 *
3841 * \param *base
3842 * The SD host registers structure pointer.
3843 *
3844 *******************************************************************************/
Cy_SD_Host_ErrorReset(SDHC_Type * base)3845 static void Cy_SD_Host_ErrorReset(SDHC_Type *base)
3846 {
3847 uint32_t intError; /* The error events mask. */
3848
3849 intError = Cy_SD_Host_GetErrorInterruptStatus(base);
3850
3851 /* Check the error event. */
3852 if (0UL < intError)
3853 {
3854 /* Clear the error event. */
3855 Cy_SD_Host_ClearErrorInterruptStatus(base, intError);
3856
3857 Cy_SD_Host_SoftwareReset(base, CY_SD_HOST_RESET_CMD_LINE);
3858 }
3859 }
3860
3861
3862 /*******************************************************************************
3863 * Function Name: Cy_SD_Host_NormalReset
3864 ****************************************************************************//**
3865 *
3866 * Checks for a normal event and resets it.
3867 *
3868 * \param *base
3869 * The SD host registers structure pointer.
3870 *
3871 *******************************************************************************/
Cy_SD_Host_NormalReset(SDHC_Type * base)3872 static void Cy_SD_Host_NormalReset(SDHC_Type *base)
3873 {
3874 uint32_t intNormal; /* The normal events mask. */
3875
3876 intNormal = Cy_SD_Host_GetNormalInterruptStatus(base);
3877
3878 /* Check the normal event. */
3879 if (0UL < intNormal)
3880 {
3881 /* Clear the normal event. */
3882 Cy_SD_Host_ClearNormalInterruptStatus(base, intNormal);
3883 }
3884 }
3885
3886
3887 /*******************************************************************************
3888 * Function Name: Cy_SD_Host_VoltageCheck
3889 ****************************************************************************//**
3890 *
3891 * resets the card (CMD0) and checks the voltage (CMD8).
3892 *
3893 * \param *base
3894 * The SD host registers structure pointer.
3895 *
3896 * \return The CMD8 valid flag (f8).
3897 *
3898 *******************************************************************************/
Cy_SD_Host_VoltageCheck(SDHC_Type * base)3899 __STATIC_INLINE bool Cy_SD_Host_VoltageCheck(SDHC_Type *base)
3900 {
3901 cy_en_sd_host_status_t ret;
3902 bool f8Flag = false; /* The CMD8 valid flag. */
3903 uint32_t response = 0UL; /* The CMD response. */
3904 uint32_t retry = CY_SD_HOST_VOLTAGE_CHECK_RETRY;
3905
3906 while (retry > 0UL)
3907 {
3908 /* Reset Card (CMD0). */
3909 ret = Cy_SD_Host_OpsGoIdle(base); /* The Idle state. */
3910
3911 /* Software reset for the CMD line. */
3912 Cy_SD_Host_SoftwareReset(base, CY_SD_HOST_RESET_CMD_LINE);
3913
3914 /* Voltage check (CMD8). */
3915 ret = Cy_SD_Host_OpsSendIfCond(base,
3916 CY_SD_HOST_CMD8_VHS_27_36 |
3917 CY_SD_HOST_CMD8_CHECK_PATTERN,
3918 false);
3919
3920 /* Check the response. */
3921 (void)Cy_SD_Host_GetResponse(base,
3922 (uint32_t *)&response,
3923 false);
3924
3925 /* Check the pattern. */
3926 if (CY_SD_HOST_CMD8_CHECK_PATTERN == (response &
3927 CY_SD_HOST_CMD8_PATTERN_MASK))
3928 {
3929 /* The pattern is valid. */
3930 f8Flag = true;
3931 }
3932 else if (CY_SD_HOST_VOLTAGE_CHECK_RETRY == retry)
3933 {
3934 /* CMD8 fails. Retry one more time */
3935 }
3936 else
3937 {
3938 /* The unusable card or the SDIO card. */
3939 ret = CY_SD_HOST_ERROR_UNUSABLE_CARD;
3940 }
3941
3942 if ((CY_SD_HOST_ERROR_TIMEOUT == ret) || (f8Flag))
3943 {
3944 /* The pattern is valid or voltage mismatch (No response). */
3945 break;
3946 }
3947
3948 retry--;
3949 }
3950
3951 if (CY_SD_HOST_SUCCESS != ret) /* The Idle state. */
3952 {
3953 /* Reset the error and the CMD line for the case of the SDIO card. */
3954 Cy_SD_Host_ErrorReset(base);
3955 Cy_SD_Host_NormalReset(base);
3956 }
3957
3958 return f8Flag;
3959 }
3960
3961
3962 /*******************************************************************************
3963 * Function Name: Cy_SD_Host_IoOcr
3964 ****************************************************************************//**
3965 *
3966 * Sends CMD5 to get IO OCR. Checks if IO is present (sdio),
3967 * if the memory is present (mpFlag) and if 1.8 signaling can be supported (s18aFlag).
3968 *
3969 * \param *base
3970 * The SD host registers structure pointer.
3971 *
3972 * \param lowVoltageSignaling
3973 * The lowVoltageSignaling flag.
3974 *
3975 * \param *s18aFlag
3976 * The S18A flag (1.8 signaling support).
3977 *
3978 * \param *sdioFlag
3979 * The IO flag (the number of IO functions).
3980 *
3981 * \param *mpFlag
3982 * The MEM flag (memory support).
3983 *
3984 * \param *ocrReg
3985 * The Operation Condition register (OCR).
3986 *
3987 * \return \ref cy_en_sd_host_status_t
3988 *
3989 *******************************************************************************/
Cy_SD_Host_IoOcr(SDHC_Type * base,bool lowVoltageSignaling,uint32_t * s18aFlag,uint32_t * sdioFlag,bool * mpFlag,uint32_t * ocrReg)3990 __STATIC_INLINE cy_en_sd_host_status_t Cy_SD_Host_IoOcr(SDHC_Type *base,
3991 bool lowVoltageSignaling,
3992 uint32_t *s18aFlag,
3993 uint32_t *sdioFlag,
3994 bool *mpFlag,
3995 uint32_t *ocrReg)
3996 {
3997 cy_en_sd_host_status_t ret;
3998 uint32_t retry;
3999
4000 /* Get IO OCR (CMD5) */
4001 ret = Cy_SD_Host_OpsSdioSendOpCond(base, ocrReg, 0UL);
4002
4003 /* Get the number of IO functions. */
4004 *sdioFlag = *ocrReg & CY_SD_HOST_CMD5_IO_NUM_MASK;
4005
4006 if (0UL < *sdioFlag)
4007 {
4008 if (true == lowVoltageSignaling)
4009 {
4010 /* Set the OCR to change the signal
4011 * voltage to 1.8 V for the UHS-I mode.
4012 */
4013 *ocrReg = (*ocrReg & CY_SD_HOST_IO_OCR_MASK) |
4014 CY_SD_HOST_ACMD41_S18R;
4015 }
4016
4017 retry = CY_SD_HOST_RETRY_TIME;
4018 while (retry > 0UL)
4019 {
4020 /* Set S18R and the voltage window in IO OCR (CMD5). */
4021 ret = Cy_SD_Host_OpsSdioSendOpCond(base,
4022 ocrReg,
4023 *ocrReg);
4024
4025 /* Check the IO power up status. */
4026 if (CY_SD_HOST_SUCCESS == ret)
4027 {
4028 if (CY_SD_HOST_IO_OCR_C == (*ocrReg & CY_SD_HOST_IO_OCR_C))
4029 {
4030 /* The SDIO card supports 1.8 signaling. */
4031 *s18aFlag = 1UL;
4032 }
4033
4034 if(CY_SD_HOST_CMD5_MP_MASK == (*ocrReg & CY_SD_HOST_CMD5_MP_MASK))
4035 {
4036 /* MP = 1. (The memory is supported.) */
4037 *mpFlag = true;
4038 }
4039
4040 /* IO > 0. */
4041 break;
4042 }
4043
4044 Cy_SysLib_DelayUs(CY_SD_HOST_SDIO_CMD5_TIMEOUT_MS); /* 1 sec timeout. */
4045 retry--;
4046 }
4047
4048 if (CY_SD_HOST_SUCCESS != ret)
4049 {
4050 /* IO = 0. */
4051 *sdioFlag = 0UL;
4052 }
4053 }
4054 else
4055 {
4056 /* Software reset for the DAT line. */
4057 Cy_SD_Host_SoftwareReset(base, CY_SD_HOST_RESET_DATALINE);
4058
4059 /* IO = 0. We have the SD memory card. Reset errors. */
4060 Cy_SD_Host_ErrorReset(base);
4061
4062 }
4063
4064 Cy_SysLib_DelayUs(CY_SD_HOST_NCC_MIN_US);
4065
4066 return ret;
4067 }
4068
4069
4070 /*******************************************************************************
4071 * Function Name: Cy_SD_Host_SdOcr
4072 ****************************************************************************//**
4073 *
4074 * Sends ACMD41 to get SD OCR.
4075 *
4076 * \param *base
4077 * The SD host registers structure pointer.
4078 *
4079 * \param lowVoltageSignaling
4080 * The lowVoltageSignaling flag.
4081 *
4082 * \param *s18aFlag
4083 * The S18A flag (1.8 signaling support).
4084 *
4085 * \param *mpFlag
4086 * The MEM flag (memory support).
4087 *
4088 * \param f8Flag
4089 * The CMD8 flag.
4090 *
4091 * \param *ocrReg
4092 * The Operation Condition register (OCR).
4093 *
4094 * \param context
4095 * The pointer to the context structure \ref cy_stc_sd_host_context_t allocated
4096 * by the user. The structure is used during the SD host operation for internal
4097 * configuration and data retention. The user must not modify anything
4098 * in this structure.
4099 * If only the SD host functions which do not require context will be used, pass NULL
4100 * as the pointer to the context.
4101 *
4102 * \return \ref cy_en_sd_host_status_t
4103 *
4104 *******************************************************************************/
Cy_SD_Host_SdOcr(SDHC_Type * base,bool lowVoltageSignaling,uint32_t * s18aFlag,bool * mpFlag,bool f8Flag,uint32_t * ocrReg,cy_stc_sd_host_context_t * context)4105 __STATIC_INLINE cy_en_sd_host_status_t Cy_SD_Host_SdOcr(SDHC_Type *base,
4106 bool lowVoltageSignaling,
4107 uint32_t *s18aFlag,
4108 bool *mpFlag,
4109 bool f8Flag,
4110 uint32_t *ocrReg,
4111 cy_stc_sd_host_context_t *context)
4112 {
4113 cy_en_sd_host_status_t ret;
4114 uint32_t response = 0UL; /* The CMD response. */
4115 uint32_t retry;
4116 uint32_t cmdArgument;
4117
4118 /* Get OCR (ACMD41). The voltage window = 0. */
4119 ret = Cy_SD_Host_OpsSdSendOpCond(base,
4120 ocrReg,
4121 0x00000000UL,
4122 context);
4123
4124 if (CY_SD_HOST_SUCCESS == ret)
4125 {
4126 /* Set the voltage window from 2.7 to 3.6 V. */
4127 cmdArgument = CY_SD_HOST_ACMD41_VOLTAGE_MASK;
4128
4129 if (f8Flag)
4130 {
4131 /* Set the SDHC supported bit.*/
4132 cmdArgument |= CY_SD_HOST_ACMD41_HCS;
4133
4134 if (true == lowVoltageSignaling)
4135 {
4136 /* Set the 1.8 V request bit.*/
4137 cmdArgument |= CY_SD_HOST_ACMD41_S18R;
4138 }
4139 }
4140
4141 /* Set OCR (ACMD41). */
4142 retry = CY_SD_HOST_RETRY_TIME;
4143 while (retry > 0UL)
4144 {
4145 ret = Cy_SD_Host_OpsSdSendOpCond(base,
4146 ocrReg,
4147 cmdArgument,
4148 context);
4149 if (CY_SD_HOST_SUCCESS == ret)
4150 {
4151 break;
4152 }
4153 Cy_SysLib_DelayUs(CY_SD_HOST_ACMD41_TIMEOUT_MS);
4154 retry--;
4155 }
4156
4157 /* Check the response. */
4158 (void)Cy_SD_Host_GetResponse(base,
4159 (uint32_t *)&response,
4160 false);
4161
4162 if (0UL == (response & CY_SD_HOST_OCR_CAPACITY_MASK))
4163 {
4164 /* The SDSC card. */
4165 context->cardCapacity = CY_SD_HOST_SDSC;
4166 }
4167
4168 /* Check S18A. */
4169 if (CY_SD_HOST_OCR_S18A == (response &
4170 CY_SD_HOST_OCR_S18A))
4171 {
4172 /* The SD card supports the 1.8 signaling. */
4173 *s18aFlag |= 1UL;
4174 }
4175
4176 if (CY_SD_HOST_SUCCESS == ret)
4177 {
4178 /* MP = 1. (The memory is supported.) */
4179 *mpFlag = true;
4180 }
4181 else
4182 {
4183 /* MP = 0. (The memory is not supported.) */
4184 *mpFlag = false;
4185 }
4186 }
4187 else if (false == f8Flag)
4188 {
4189 /* Not a SD card */
4190 ret = CY_SD_HOST_ERROR_UNUSABLE_CARD;
4191 context->cardType = CY_SD_HOST_UNUSABLE;
4192 }
4193 else
4194 {
4195 /* The card is not present or busy */
4196 }
4197
4198 Cy_SysLib_DelayUs(CY_SD_HOST_NCC_MIN_US);
4199
4200 return ret;
4201 }
4202
4203
4204 /*******************************************************************************
4205 * Function Name: Cy_SD_Host_Enable
4206 ****************************************************************************//**
4207 *
4208 * Enables the SD host block.
4209 *
4210 * \param *base
4211 * The SD host registers structure pointer.
4212 *
4213 *******************************************************************************/
Cy_SD_Host_Enable(SDHC_Type * base)4214 void Cy_SD_Host_Enable(SDHC_Type *base)
4215 {
4216 uint32_t retry;
4217
4218 /* Check for the NULL pointer */
4219 if (NULL != base)
4220 {
4221 /* Enable the SDHC block. */
4222 SDHC_WRAP_CTL(base) = _CLR_SET_FLD32U(SDHC_WRAP_CTL(base),
4223 SDHC_WRAP_CTL_ENABLE,
4224 1UL);
4225
4226 retry = CY_SD_HOST_RETRY_TIME;
4227
4228 /* Enable the Internal clock. */
4229 SDHC_CORE_CLK_CTRL_R(base) = (uint16_t)_CLR_SET_FLD16U(SDHC_CORE_CLK_CTRL_R(base),
4230 SDHC_CORE_CLK_CTRL_R_INTERNAL_CLK_EN,
4231 1UL);
4232
4233 while((true != _FLD2BOOL(SDHC_CORE_CLK_CTRL_R_INTERNAL_CLK_STABLE, SDHC_CORE_CLK_CTRL_R(base)))
4234 && (retry > 0UL))
4235 {
4236 /* Wait for the stable Internal Clock . */
4237 Cy_SysLib_DelayUs(CY_SD_HOST_INT_CLK_STABLE_TIMEOUT_MS);
4238 retry--;
4239 }
4240 }
4241 }
4242
4243
4244 /*******************************************************************************
4245 * Function Name: Cy_SD_Host_Disable
4246 ****************************************************************************//**
4247 *
4248 * Disables the SD host block.
4249 *
4250 * \param *base
4251 * The SD host registers structure pointer.
4252 *
4253 *******************************************************************************/
Cy_SD_Host_Disable(SDHC_Type * base)4254 void Cy_SD_Host_Disable(SDHC_Type *base)
4255 {
4256 /* Check for the NULL pointer */
4257 if (NULL != base)
4258 {
4259 Cy_SD_Host_DisableSdClk(base);
4260
4261 /* Disable the Internal clock. */
4262 SDHC_CORE_CLK_CTRL_R(base) = (uint16_t)_CLR_SET_FLD16U(SDHC_CORE_CLK_CTRL_R(base),
4263 SDHC_CORE_CLK_CTRL_R_INTERNAL_CLK_EN,
4264 0UL);
4265
4266 /* Disable the SDHC block. */
4267 SDHC_WRAP_CTL(base) = _CLR_SET_FLD32U(SDHC_WRAP_CTL(base),
4268 SDHC_WRAP_CTL_ENABLE,
4269 0UL);
4270 }
4271 }
4272
4273
4274 /*******************************************************************************
4275 * Function Name: Cy_SD_Host_SetSdClkDiv
4276 ****************************************************************************//**
4277 *
4278 * Changes the speed of the SD bus. This function should be called along
4279 * with \ref Cy_SD_Host_SetHostSpeedMode to configure the bus correctly.
4280 *
4281 * \note
4282 * The divider is clocked from the CLK_HF clock (100 MHz). To determine
4283 * the SD bus speed divide the clock CLK_HF by the divider value passed
4284 * in this function. The divider value is 2*clkDiv.
4285 *
4286 * \param *base
4287 * The SD host registers structure pointer.
4288 *
4289 * \param clkDiv
4290 * The clock divider for the SD clock.
4291 *
4292 * \return \ref cy_en_sd_host_status_t
4293 *
4294 *******************************************************************************/
Cy_SD_Host_SetSdClkDiv(SDHC_Type * base,uint16_t clkDiv)4295 cy_en_sd_host_status_t Cy_SD_Host_SetSdClkDiv(SDHC_Type *base, uint16_t clkDiv)
4296 {
4297 cy_en_sd_host_status_t ret = CY_SD_HOST_ERROR_INVALID_PARAMETER;
4298
4299 /* Check for the NULL pointer */
4300 if (NULL != base)
4301 {
4302 SDHC_CORE_CLK_CTRL_R(base) = (uint16_t)(((uint32_t)SDHC_CORE_CLK_CTRL_R(base) &
4303 ~(SDHC_CORE_CLK_CTRL_R_FREQ_SEL_Msk | /* Clear the first LSB 8 bits */
4304 SDHC_CORE_CLK_CTRL_R_UPPER_FREQ_SEL_Msk)) | /* Clear the upper 2 bits */
4305 _VAL2FLD(SDHC_CORE_CLK_CTRL_R_FREQ_SEL, ((uint32_t)clkDiv & CY_SD_HOST_FREQ_SEL_MSK)) | /* Set the first LSB 8 bits */
4306 _VAL2FLD(SDHC_CORE_CLK_CTRL_R_UPPER_FREQ_SEL, ((uint32_t)clkDiv >> CY_SD_HOST_UPPER_FREQ_SEL_POS))); /* Set the upper 2 bits */
4307
4308 /* Wait for at least 3 card clock periods */
4309 Cy_SysLib_DelayUs(CY_SD_HOST_3_PERIODS_US);
4310
4311 ret = CY_SD_HOST_SUCCESS;
4312 }
4313
4314 return ret;
4315 }
4316
4317
4318 /*******************************************************************************
4319 * Function Name: Cy_SD_Host_IsWpSet
4320 ****************************************************************************//**
4321 *
4322 * Returns the state of the write protect switch on the SD card.
4323 *
4324 * \param *base
4325 * The SD host registers structure pointer.
4326 *
4327 * \return bool
4328 * true - the write protect is set, false - the write protect is not set.
4329 *
4330 *******************************************************************************/
Cy_SD_Host_IsWpSet(SDHC_Type const * base)4331 __WEAK bool Cy_SD_Host_IsWpSet(SDHC_Type const *base)
4332 {
4333 return _FLD2BOOL(SDHC_CORE_PSTATE_REG_WR_PROTECT_SW_LVL, SDHC_CORE_PSTATE_REG(base));
4334 }
4335
4336
4337 /*******************************************************************************
4338 * Function Name: Cy_SD_Host_SetHostBusWidth
4339 ****************************************************************************//**
4340 *
4341 * Only changes the bus width on the host side.
4342 * It doesn't change the bus width on the card side.
4343 * To change the bus width on the card, call Cy_SD_Host_SetBusWidth().
4344 *
4345 * \param *base
4346 * The SD host registers structure pointer.
4347 *
4348 * \param width
4349 * The width of the data bus.
4350 *
4351 * \return \ref cy_en_sd_host_status_t
4352 *
4353 *******************************************************************************/
Cy_SD_Host_SetHostBusWidth(SDHC_Type * base,cy_en_sd_host_bus_width_t width)4354 cy_en_sd_host_status_t Cy_SD_Host_SetHostBusWidth(SDHC_Type *base,
4355 cy_en_sd_host_bus_width_t width)
4356 {
4357 cy_en_sd_host_status_t ret = CY_SD_HOST_ERROR_INVALID_PARAMETER;
4358
4359 /* Check for the NULL pointer */
4360 if (NULL != base)
4361 {
4362 SDHC_CORE_HOST_CTRL1_R(base) = (uint8_t)(((uint32_t)SDHC_CORE_HOST_CTRL1_R(base) &
4363 ~(SDHC_CORE_HOST_CTRL1_R_EXT_DAT_XFER_Msk |
4364 SDHC_CORE_HOST_CTRL1_R_DAT_XFER_WIDTH_Msk)) |
4365 (_BOOL2FLD(SDHC_CORE_HOST_CTRL1_R_EXT_DAT_XFER, (CY_SD_HOST_BUS_WIDTH_8_BIT == width)) |
4366 _BOOL2FLD(SDHC_CORE_HOST_CTRL1_R_DAT_XFER_WIDTH, (CY_SD_HOST_BUS_WIDTH_4_BIT == width))));
4367
4368 ret = CY_SD_HOST_SUCCESS;
4369 }
4370
4371 return ret;
4372 }
4373
4374
4375 /*******************************************************************************
4376 * Function Name: Cy_SD_Host_SetHostSpeedMode
4377 ****************************************************************************//**
4378 *
4379 * Only updates the host register to indicate bus speed mode and the general
4380 * purpose output register to select card clock input and output delay.
4381 * This function doesn't change the speed on the bus, or change anything
4382 * in the card.
4383 *
4384 * \param *base
4385 * The SD host registers structure pointer.
4386 *
4387 * \param speedMode
4388 * Bus Speed mode.
4389 *
4390 * \return \ref cy_en_sd_host_status_t
4391 *
4392 *******************************************************************************/
Cy_SD_Host_SetHostSpeedMode(SDHC_Type * base,cy_en_sd_host_bus_speed_mode_t speedMode)4393 cy_en_sd_host_status_t Cy_SD_Host_SetHostSpeedMode(SDHC_Type *base,
4394 cy_en_sd_host_bus_speed_mode_t speedMode)
4395 {
4396 cy_en_sd_host_status_t ret = CY_SD_HOST_SUCCESS;
4397 uint32_t inDelay = 0UL;
4398 uint32_t outDelay = 0UL;
4399 uint32_t ultraHighSpeed = 0UL;
4400
4401 /* Check for the NULL pointer */
4402 if (NULL != base)
4403 {
4404 /* UHS Mode/eMMC Speed Mode Select */
4405 switch (speedMode)
4406 {
4407 case CY_SD_HOST_BUS_SPEED_EMMC_LEGACY:
4408 case CY_SD_HOST_BUS_SPEED_DEFAULT:
4409 case CY_SD_HOST_BUS_SPEED_SDR12_5:
4410 ultraHighSpeed = CY_SD_HOST_SDR12_SPEED; /* Max clock = 25 MHz */
4411 break;
4412 case CY_SD_HOST_BUS_SPEED_EMMC_HIGHSPEED_SDR:
4413 case CY_SD_HOST_BUS_SPEED_SDR25:
4414 case CY_SD_HOST_BUS_SPEED_HIGHSPEED:
4415 ultraHighSpeed = CY_SD_HOST_SDR25_SPEED; /* Max clock = 50 MHz */
4416 break;
4417 case CY_SD_HOST_BUS_SPEED_SDR50:
4418 ultraHighSpeed = CY_SD_HOST_SDR50_SPEED; /* Max clock = 100 MHz */
4419 break;
4420 case CY_SD_HOST_BUS_SPEED_DDR50:
4421 ultraHighSpeed = CY_SD_HOST_DDR50_SPEED; /* Max clock = 50 MHz */
4422 break;
4423 default:
4424 ret = CY_SD_HOST_ERROR_INVALID_PARAMETER;
4425 break;
4426 }
4427
4428 /* Card clock output delay select */
4429 switch (speedMode)
4430 {
4431 case CY_SD_HOST_BUS_SPEED_EMMC_LEGACY:
4432 case CY_SD_HOST_BUS_SPEED_DEFAULT:
4433 case CY_SD_HOST_BUS_SPEED_SDR12_5:
4434 case CY_SD_HOST_BUS_SPEED_HIGHSPEED:
4435 outDelay = CY_SD_HOST_SDR12_OUT_DELAY;
4436 break;
4437 case CY_SD_HOST_BUS_SPEED_EMMC_HIGHSPEED_SDR:
4438 case CY_SD_HOST_BUS_SPEED_SDR25:
4439 case CY_SD_HOST_BUS_SPEED_SDR50:
4440 outDelay = CY_SD_HOST_SDR25_OUT_DELAY;
4441 break;
4442 case CY_SD_HOST_BUS_SPEED_DDR50:
4443 outDelay = CY_SD_HOST_DDR50_OUT_DELAY;
4444 break;
4445 default:
4446 ret = CY_SD_HOST_ERROR_INVALID_PARAMETER;
4447 break;
4448 }
4449
4450 /* Card clock input delay select */
4451 switch (speedMode)
4452 {
4453 case CY_SD_HOST_BUS_SPEED_EMMC_LEGACY:
4454 case CY_SD_HOST_BUS_SPEED_DEFAULT:
4455 case CY_SD_HOST_BUS_SPEED_SDR12_5:
4456 inDelay = CY_SD_HOST_SDR12_IN_DELAY;
4457 break;
4458 case CY_SD_HOST_BUS_SPEED_SDR25:
4459 case CY_SD_HOST_BUS_SPEED_SDR50:
4460 inDelay = CY_SD_HOST_SDR25_IN_DELAY;
4461 break;
4462 case CY_SD_HOST_BUS_SPEED_HIGHSPEED:
4463 case CY_SD_HOST_BUS_SPEED_EMMC_HIGHSPEED_SDR:
4464 inDelay = CY_SD_HOST_HIGH_SPEED_IN_DELAY;
4465 break;
4466 case CY_SD_HOST_BUS_SPEED_DDR50:
4467 inDelay = CY_SD_HOST_DDR50_IN_DELAY;
4468 break;
4469 default:
4470 ret = CY_SD_HOST_ERROR_INVALID_PARAMETER;
4471 break;
4472 }
4473
4474 if (CY_SD_HOST_ERROR_INVALID_PARAMETER != ret)
4475 {
4476 SDHC_CORE_HOST_CTRL1_R(base) = (uint8_t)_CLR_SET_FLD8U(SDHC_CORE_HOST_CTRL1_R(base),
4477 SDHC_CORE_HOST_CTRL1_R_HIGH_SPEED_EN,
4478 ((CY_SD_HOST_BUS_SPEED_HIGHSPEED == speedMode) ? 1UL : 0UL));
4479
4480 SDHC_CORE_HOST_CTRL2_R(base) = (uint16_t)_CLR_SET_FLD16U(SDHC_CORE_HOST_CTRL2_R(base),
4481 SDHC_CORE_HOST_CTRL2_R_UHS_MODE_SEL,
4482 ultraHighSpeed);
4483
4484 SDHC_CORE_GP_OUT_R(base) = (uint16_t)_CLR_SET_FLD16U(SDHC_CORE_GP_OUT_R(base),
4485 SDHC_CORE_GP_OUT_R_CARD_CLOCK_IN_DLY,
4486 inDelay);
4487
4488 SDHC_CORE_GP_OUT_R(base) = (uint16_t)_CLR_SET_FLD16U(SDHC_CORE_GP_OUT_R(base),
4489 SDHC_CORE_GP_OUT_R_CARD_CLOCK_OUT_DLY,
4490 outDelay);
4491 }
4492 }
4493 else
4494 {
4495 ret = CY_SD_HOST_ERROR_INVALID_PARAMETER;
4496 }
4497
4498 return ret;
4499 }
4500
4501
4502 /*******************************************************************************
4503 * Function Name: Cy_SD_Host_SetBusSpeedMode
4504 ****************************************************************************//**
4505 *
4506 * Negotiates with the card to change the bus speed mode of the card
4507 * and the host. It doesn't change the SD clock frequency that must be done
4508 * separately.
4509 *
4510 * \param *base
4511 * The SD host registers structure pointer.
4512 *
4513 * \param speedMode
4514 * Bus speed mode.
4515 *
4516 * \param context
4517 * The pointer to the context structure \ref cy_stc_sd_host_context_t allocated
4518 * by the user. The structure is used during the SD host operation for internal
4519 * configuration and data retention. The user must not modify anything
4520 * in this structure.
4521 * If only the SD host functions which do not require context will be used, pass NULL
4522 * as the pointer to the context.
4523 *
4524 * \return \ref cy_en_sd_host_status_t
4525 *
4526 *******************************************************************************/
Cy_SD_Host_SetBusSpeedMode(SDHC_Type * base,cy_en_sd_host_bus_speed_mode_t speedMode,cy_stc_sd_host_context_t const * context)4527 cy_en_sd_host_status_t Cy_SD_Host_SetBusSpeedMode(SDHC_Type *base,
4528 cy_en_sd_host_bus_speed_mode_t speedMode,
4529 cy_stc_sd_host_context_t const *context)
4530 {
4531 cy_en_sd_host_status_t ret = CY_SD_HOST_SUCCESS;
4532 uint32_t highSpeedValue = CY_SD_HOST_DEFAULT_SPEED;
4533 uint32_t cmdArgument = 0UL;
4534 uint32_t response[CY_SD_HOST_RESPONSE_SIZE] = { 0UL };
4535
4536 /* Check for the NULL pointer */
4537 if (NULL != base)
4538 {
4539 CY_ASSERT_L3(CY_SD_HOST_IS_SPEED_MODE_VALID(speedMode));
4540
4541 /* 1. Does the card support memory? */
4542 if ((CY_SD_HOST_SD == context->cardType) ||
4543 (CY_SD_HOST_EMMC == context->cardType) ||
4544 (CY_SD_HOST_COMBO == context->cardType))
4545 {
4546 /* 2. Change Bus Speed Mode: Issue CMD6 with mode 1 */
4547 switch (speedMode)
4548 {
4549 case CY_SD_HOST_BUS_SPEED_EMMC_LEGACY:
4550 case CY_SD_HOST_BUS_SPEED_DEFAULT:
4551 case CY_SD_HOST_BUS_SPEED_SDR12_5:
4552 highSpeedValue = CY_SD_HOST_SDR12_SPEED; /* Max clock = 25 MHz */
4553 break;
4554 case CY_SD_HOST_BUS_SPEED_EMMC_HIGHSPEED_SDR:
4555 case CY_SD_HOST_BUS_SPEED_SDR25:
4556 case CY_SD_HOST_BUS_SPEED_HIGHSPEED:
4557 highSpeedValue = CY_SD_HOST_SDR25_SPEED; /* Max clock = 50 MHz */
4558 break;
4559 case CY_SD_HOST_BUS_SPEED_SDR50:
4560 highSpeedValue = CY_SD_HOST_SDR50_SPEED; /* Max clock = 100 MHz */
4561 break;
4562 case CY_SD_HOST_BUS_SPEED_DDR50:
4563 highSpeedValue = CY_SD_HOST_DDR50_SPEED; /* Max clock = 50 MHz */
4564 break;
4565 default:
4566 ret = CY_SD_HOST_ERROR_INVALID_PARAMETER;
4567 break;
4568 }
4569
4570 if (CY_SD_HOST_SUCCESS == ret)
4571 {
4572 if ((CY_SD_HOST_SD == context->cardType) ||
4573 (CY_SD_HOST_COMBO == context->cardType))
4574 {
4575 /* Set the mode bit to 1 and select the default function */
4576 cmdArgument = (1UL << CY_SD_HOST_SWITCH_FUNCTION_BIT);
4577
4578 /* Set the High Speed/SDR25 bit */
4579 cmdArgument |= highSpeedValue & 0xFUL;
4580
4581 /* Send CMD6 and parse response */
4582 ret = Cy_SD_Host_SdCardSwitchFunc(base, cmdArgument, context->cardType);
4583 }
4584 else
4585 {
4586 cmdArgument = (CY_SD_HOST_EMMC_ACCESS_WRITE_BYTE << CY_SD_HOST_EMMC_CMD6_ACCESS_OFFSET) |
4587 (CY_SD_HOST_EMMC_HS_TIMING_ADDR << CY_SD_HOST_EMMC_CMD6_IDX_OFFSET) |
4588 (highSpeedValue << CY_SD_HOST_EMMC_CMD6_VALUE_OFFSET) |
4589 (0x0UL << CY_SD_HOST_EMMC_CMD6_CMD_SET_OFFSET);
4590
4591 /* Send CMD6 */
4592 ret = Cy_SD_Host_OpsSwitchFunc(base, cmdArgument);
4593 }
4594 }
4595 }
4596
4597 /* 5. Is SDIO Supported? */
4598 if ((CY_SD_HOST_SDIO == context->cardType) ||
4599 (CY_SD_HOST_COMBO == context->cardType))
4600 {
4601 /* 6. Change Bus Speed Mode: Set EHS or BSS[2:0] in CCCR */
4602 ret = Cy_SD_Host_OpsSendIoRwDirectCmd(base,
4603 0UL,
4604 0UL,
4605 0UL,
4606 CY_SD_HOST_CCCR_SPEED_CONTROL,
4607 0UL);
4608
4609 (void)Cy_SD_Host_GetResponse(base, (uint32_t *)response, false);
4610
4611 /* Check the SHS bit - the High Speed mode operation ability */
4612 if (0UL != (response[0] & CY_SD_HOST_CCCR_SPEED_SHS_MASK))
4613 {
4614 switch (speedMode)
4615 {
4616 case CY_SD_HOST_BUS_SPEED_DEFAULT:
4617 case CY_SD_HOST_BUS_SPEED_SDR12_5:
4618 /* BSS0 = 0, BSS1 = 0 */
4619 break;
4620 case CY_SD_HOST_BUS_SPEED_SDR25:
4621 case CY_SD_HOST_BUS_SPEED_HIGHSPEED:
4622 response[0] |= CY_SD_HOST_CCCR_SPEED_BSS0_MASK;
4623 break;
4624 case CY_SD_HOST_BUS_SPEED_SDR50:
4625 response[0] |= CY_SD_HOST_CCCR_SPEED_BSS1_MASK;
4626 break;
4627 case CY_SD_HOST_BUS_SPEED_DDR50:
4628 response[0] |= CY_SD_HOST_CCCR_SPEED_BSS2_MASK;
4629 break;
4630 default:
4631 ret = CY_SD_HOST_ERROR_INVALID_PARAMETER;
4632 break;
4633 }
4634
4635 /* Set the EHS bit to enable High Speed mode */
4636 if (CY_SD_HOST_SUCCESS == ret)
4637 {
4638 highSpeedValue = response[0] & (CY_SD_HOST_CCCR_SPEED_BSS0_MASK |
4639 CY_SD_HOST_CCCR_SPEED_BSS1_MASK |
4640 CY_SD_HOST_CCCR_SPEED_SHS_MASK);
4641
4642 ret = Cy_SD_Host_OpsSendIoRwDirectCmd(base,
4643 1UL,
4644 0UL,
4645 0UL,
4646 CY_SD_HOST_CCCR_SPEED_CONTROL,
4647 response[0]);
4648
4649 (void)Cy_SD_Host_GetResponse(base, (uint32_t *)response, false);
4650
4651 response[0] = response[0] & (CY_SD_HOST_CCCR_SPEED_BSS0_MASK |
4652 CY_SD_HOST_CCCR_SPEED_BSS1_MASK |
4653 CY_SD_HOST_CCCR_SPEED_SHS_MASK);
4654
4655 if(highSpeedValue != response[0])
4656 {
4657 ret = CY_SD_HOST_ERROR_UNINITIALIZED;
4658 }
4659 }
4660 }
4661 else
4662 {
4663 /* The card can operate in High Speed mode only. */
4664 }
4665 }
4666
4667 /* 3 and 7. Bus Speed Mode changed Successfully */
4668 if (CY_SD_HOST_SUCCESS == ret)
4669 {
4670 /* 4 and 8. Set the same bus speed mode in the host controller */
4671 ret = Cy_SD_Host_SetHostSpeedMode(base, speedMode);
4672 }
4673 }
4674 else
4675 {
4676 ret = CY_SD_HOST_ERROR_INVALID_PARAMETER;
4677 }
4678
4679 return ret;
4680 }
4681
4682
4683 /*******************************************************************************
4684 * Function Name: Cy_SD_Host_FindBusSpeedMode
4685 ****************************************************************************//**
4686 *
4687 * Negotiates with the card to find the highest supported bus speed mode
4688 * of the card.
4689 *
4690 * \param *base
4691 * The SD host registers structure pointer.
4692 *
4693 * \param lowVoltageSignaling
4694 * Support for 1.8V signaling in card and host.
4695 *
4696 * \param cardType
4697 * The type of card.
4698 *
4699 * \note
4700 * This function is applicable only for \ref CY_SD_HOST_SD &
4701 * \ref CY_SD_HOST_COMBO card types
4702 *
4703 * \return \ref cy_en_sd_host_bus_speed_mode_t
4704 *
4705 *******************************************************************************/
Cy_SD_Host_FindBusSpeedMode(SDHC_Type * base,bool lowVoltageSignaling,cy_en_sd_host_card_type_t cardType)4706 static cy_en_sd_host_bus_speed_mode_t Cy_SD_Host_FindBusSpeedMode(SDHC_Type *base,
4707 bool lowVoltageSignaling,
4708 cy_en_sd_host_card_type_t cardType)
4709 {
4710 cy_stc_sd_host_cmd_config_t cmd;
4711 cy_stc_sd_host_data_config_t dataConfig;
4712 uint32_t status[CY_SD_HOST_SWITCH_STATUS_LEN];
4713 cy_en_sd_host_status_t ret = CY_SD_HOST_SUCCESS;
4714 cy_en_sd_host_bus_speed_mode_t speedMode = CY_SD_HOST_BUS_SPEED_DEFAULT;
4715
4716 cmd.commandIndex = CY_SD_HOST_SD_CMD6;
4717 cmd.commandArgument = 0x0UL;
4718 cmd.dataPresent = true;
4719 cmd.enableAutoResponseErrorCheck = false;
4720 cmd.respType = CY_SD_HOST_RESPONSE_LEN_48;
4721 cmd.enableCrcCheck = true;
4722 cmd.enableIdxCheck = true;
4723 cmd.cmdType = CY_SD_HOST_CMD_NORMAL;
4724
4725 dataConfig.blockSize = CY_SD_HOST_SD_STATUS_BLOCKS;
4726 dataConfig.numberOfBlock = 1UL;
4727 dataConfig.enableDma = false;
4728 dataConfig.autoCommand = CY_SD_HOST_AUTO_CMD_NONE;
4729 dataConfig.read = true;
4730 dataConfig.data = status;
4731 dataConfig.dataTimeout = CY_SD_HOST_MAX_TIMEOUT;
4732 dataConfig.enableIntAtBlockGap = false;
4733 dataConfig.enReliableWrite = false;
4734
4735 /* Check for the NULL pointer */
4736 if (NULL != base)
4737 {
4738 if ((cardType == CY_SD_HOST_SD) || (cardType == CY_SD_HOST_COMBO))
4739 {
4740 (void)Cy_SD_Host_InitDataTransfer(base, &dataConfig);
4741
4742 ret = Cy_SD_Host_SendCommand(base, &cmd);
4743
4744 if (CY_SD_HOST_SUCCESS == ret)
4745 {
4746 /* Wait for the Command Complete event. */
4747 ret = Cy_SD_Host_PollCmdComplete(base);
4748 }
4749
4750 if (CY_SD_HOST_SUCCESS == ret)
4751 {
4752 /* Wait for the response on the DAT lines. */
4753 ret = Cy_SD_Host_CmdRxData(base, &dataConfig);
4754 }
4755
4756 if (CY_SD_HOST_SUCCESS == ret)
4757 {
4758 /* Parse the response on DAT lines and assign bus.speed mode */
4759 if ((bool)(status[3] & 0x0000800UL)) /* Bit 404 refers to DDR50 support in 512 bit SD status */
4760 {
4761 speedMode = CY_SD_HOST_BUS_SPEED_DDR50;
4762 }
4763 else if ((bool)(status[3] & 0x00002000UL)) /* Bit 402 refers to SDR50 support in 512 bit SD status */
4764 {
4765 speedMode = CY_SD_HOST_BUS_SPEED_SDR50;
4766 }
4767 else if ((bool)(status[3] & 0x00004000UL)) /* Bit 401 refers to SDR25/High-Speed support in 512 bit SD status */
4768 {
4769 if (lowVoltageSignaling)
4770 {
4771 speedMode = CY_SD_HOST_BUS_SPEED_SDR25;
4772 }
4773 else
4774 {
4775 speedMode = CY_SD_HOST_BUS_SPEED_HIGHSPEED;
4776 }
4777 }
4778 else if ((bool)(status[3] & 0x00008000UL)) /* Bit 400 refers to SDR12_5/Default support in 512 bit SD status */
4779 {
4780 if (lowVoltageSignaling)
4781 {
4782 speedMode = CY_SD_HOST_BUS_SPEED_SDR12_5;
4783 }
4784 else
4785 {
4786 speedMode = CY_SD_HOST_BUS_SPEED_DEFAULT;
4787 }
4788 }
4789 else
4790 {
4791 speedMode = CY_SD_HOST_BUS_SPEED_DEFAULT;
4792 }
4793 }
4794
4795 Cy_SysLib_DelayUs(CY_SD_HOST_NCC_MIN_US);
4796 }
4797 }
4798
4799 return speedMode;
4800 }
4801
4802
4803 /*******************************************************************************
4804 * Function Name: Cy_SD_Host_SelBusVoltage
4805 ****************************************************************************//**
4806 *
4807 * Negotiates with the SD card to change the bus signaling level to 1.8V.
4808 * After this function is called, the card is in the ready state.
4809 *
4810 * \note The host needs to change the regulator supplying voltage to
4811 * the VDDIO of the SD block in order to operate at 1.8V.
4812 * \note This function changes RCA to 0 in the context. RCA in the context
4813 * should be updated (context.RCA = Cy_SD_Host_GetRca();)
4814 * when the card is in the Identification state.
4815 * \note This function is applicable for SD cards only.
4816 *
4817 * \param *base
4818 * The SD host registers structure pointer.
4819 *
4820 * \param enable18VSignal
4821 * If true, use the 1.8V signaling, false - use the 3.3V signaling.
4822 *
4823 * \param context
4824 * The pointer to the context structure \ref cy_stc_sd_host_context_t allocated
4825 * by the user. The structure is used during the SD host operation for internal
4826 * configuration and data retention. The user must not modify anything
4827 * in this structure.
4828 * If only the SD host functions which do not require context will be used, pass NULL
4829 * as the pointer to the context.
4830 *
4831 * \return \ref cy_en_sd_host_status_t
4832 *
4833 * \note The SD card power supply should be disabled and initialized again when
4834 * this function returns CY_SD_HOST_ERROR_UNUSABLE_CARD.
4835 *
4836 * \note The dedicated io_volt_sel pin is used to change the regulator supplying
4837 * voltage to the VDDIO of the SD block in order to operate at 1.8V. To configure
4838 * the custom IO pin in order to control (using the GPIO driver) the regulator
4839 * supplying voltage, the user must implement weak Cy_SD_Host_ChangeIoVoltage().
4840 * Also, this function must set the SIGNALING_EN bit of the SDHC_CORE_HOST_CTRL2_R
4841 * register when ioVoltage = CY_SD_HOST_IO_VOLT_1_8V.
4842 *******************************************************************************/
Cy_SD_Host_SelBusVoltage(SDHC_Type * base,bool enable18VSignal,cy_stc_sd_host_context_t * context)4843 cy_en_sd_host_status_t Cy_SD_Host_SelBusVoltage(SDHC_Type *base,
4844 bool enable18VSignal,
4845 cy_stc_sd_host_context_t *context)
4846 {
4847 cy_en_sd_host_status_t ret;
4848 uint32_t ocrReg; /* The Operation Condition register. */
4849 uint32_t s18aFlag = 0UL; /* The S18A flag. */
4850 bool f8Flag = false; /* The CMD8 flag. */
4851 bool mpFlag = false; /* The MEM flag. */
4852
4853 context->RCA = 0UL;
4854
4855 /* Send CMD0 and CMD8 commands. */
4856 f8Flag = Cy_SD_Host_VoltageCheck(base);
4857
4858 /* Clear the insert event */
4859 Cy_SD_Host_NormalReset(base);
4860
4861 /* Send ACMD41 */
4862 ret = Cy_SD_Host_SdOcr(base,
4863 enable18VSignal,
4864 &s18aFlag,
4865 &mpFlag,
4866 f8Flag,
4867 &ocrReg,
4868 context);
4869
4870 if ((CY_SD_HOST_SUCCESS == ret) && (enable18VSignal) && (1UL == s18aFlag))
4871 {
4872 /* Voltage switch (CMD11). */
4873 ret = Cy_SD_Host_OpsVoltageSwitch(base, context);
4874 }
4875
4876 return ret;
4877 }
4878
4879
4880 /*******************************************************************************
4881 * Function Name: Cy_SD_Host_EnableCardVoltage
4882 ****************************************************************************//**
4883 *
4884 * Sets the card_if_pwr_en pin high.
4885 * This pin can be used to enable a voltage regulator used to power the card.
4886 *
4887 * \param *base
4888 * The SD host registers structure pointer.
4889 *
4890 *******************************************************************************/
Cy_SD_Host_EnableCardVoltage(SDHC_Type * base)4891 __WEAK void Cy_SD_Host_EnableCardVoltage(SDHC_Type *base)
4892 {
4893 SDHC_CORE_PWR_CTRL_R(base) = _CLR_SET_FLD8U(SDHC_CORE_PWR_CTRL_R(base), SDHC_CORE_PWR_CTRL_R_SD_BUS_PWR_VDD1, 1UL);
4894 }
4895
4896
4897 /*******************************************************************************
4898 * Function Name: Cy_SD_Host_DisableCardVoltage
4899 ****************************************************************************//**
4900 *
4901 * Sets the card_if_pwr_en pin low.
4902 * This pin can be used to disable a voltage regulator used to power the card.
4903 *
4904 * \param *base
4905 * The SD host registers structure pointer.
4906 *
4907 *******************************************************************************/
Cy_SD_Host_DisableCardVoltage(SDHC_Type * base)4908 __WEAK void Cy_SD_Host_DisableCardVoltage(SDHC_Type *base)
4909 {
4910
4911 SDHC_CORE_PWR_CTRL_R(base) = _CLR_SET_FLD8U(SDHC_CORE_PWR_CTRL_R(base), SDHC_CORE_PWR_CTRL_R_SD_BUS_PWR_VDD1, 0UL);
4912 }
4913
4914
4915 /*******************************************************************************
4916 * Function Name: Cy_SD_Host_GetResponse
4917 ****************************************************************************//**
4918 *
4919 * This function reads the response register from the last completed command.
4920 *
4921 * \param *base
4922 * The SD host registers structure pointer.
4923 *
4924 * \param *responsePtr
4925 * The pointer to response data.
4926 *
4927 * \param largeResponse
4928 * If true, the response is 136 bits, false - 32 bits.
4929 *
4930 * \return \ref cy_en_sd_host_status_t
4931 *
4932 *******************************************************************************/
Cy_SD_Host_GetResponse(SDHC_Type const * base,uint32_t * responsePtr,bool largeResponse)4933 cy_en_sd_host_status_t Cy_SD_Host_GetResponse(SDHC_Type const *base,
4934 uint32_t *responsePtr,
4935 bool largeResponse)
4936 {
4937 cy_en_sd_host_status_t ret = CY_SD_HOST_ERROR_INVALID_PARAMETER;
4938 volatile uint32_t const *responseBaseAddr;
4939 uint8_t i;
4940 uint8_t responseLength = (true == largeResponse) ? CY_SD_HOST_RESPONSE_SIZE : 1U;
4941
4942 if ((NULL != base) &&
4943 (NULL != responsePtr))
4944 {
4945 /* Get the Response Register 0 address */
4946 responseBaseAddr = &SDHC_CORE_RESP01_R(base);
4947
4948 /* Read the largeResponse Response registers values */
4949 for (i = 0U; i < responseLength; i++)
4950 {
4951 *responsePtr = *responseBaseAddr;
4952 responsePtr++;
4953 responseBaseAddr++;
4954 }
4955
4956 ret = CY_SD_HOST_SUCCESS;
4957 }
4958
4959 return ret;
4960 }
4961
4962
4963 /*******************************************************************************
4964 * Function Name: Cy_SD_Host_InitDataTransfer
4965 ****************************************************************************//**
4966 *
4967 * Initializes the SD block for a data transfer. It does not start a transfer.
4968 * To start a transfer call Cy_SD_Host_SendCommand() after calling this function.
4969 * If DMA is not used for data transfer, the buffer needs to be filled
4970 * with data first if this is a write.
4971 *
4972 * \param *base
4973 * The SD host registers structure pointer.
4974 *
4975 * \param dataConfig
4976 * The pointer to the data transfer configuration structure.
4977 *
4978 * \return \ref cy_en_sd_host_status_t
4979 *
4980 *******************************************************************************/
Cy_SD_Host_InitDataTransfer(SDHC_Type * base,cy_stc_sd_host_data_config_t const * dataConfig)4981 cy_en_sd_host_status_t Cy_SD_Host_InitDataTransfer(SDHC_Type *base,
4982 cy_stc_sd_host_data_config_t const *dataConfig)
4983 {
4984 cy_en_sd_host_status_t ret = CY_SD_HOST_SUCCESS;
4985 uint32_t dmaMode;
4986 uint32_t transferMode;
4987
4988 if ((NULL != base) && (NULL != dataConfig) && (NULL != dataConfig->data))
4989 {
4990 CY_ASSERT_L3(CY_SD_HOST_IS_AUTO_CMD_VALID(dataConfig->autoCommand));
4991 CY_ASSERT_L2(CY_SD_HOST_IS_TIMEOUT_VALID(dataConfig->dataTimeout));
4992 CY_ASSERT_L2(CY_SD_HOST_IS_BLK_SIZE_VALID(dataConfig->blockSize, _FLD2VAL(SDHC_CORE_HOST_CTRL2_R_UHS_MODE_SEL, SDHC_CORE_HOST_CTRL2_R(base))));
4993
4994 dmaMode = _FLD2VAL(SDHC_CORE_HOST_CTRL1_R_DMA_SEL, SDHC_CORE_HOST_CTRL1_R(base));
4995
4996 SDHC_CORE_BLOCKSIZE_R(base) = 0U;
4997 SDHC_CORE_XFER_MODE_R(base) = 0U;
4998
4999 if (((uint32_t)CY_SD_HOST_DMA_ADMA2_ADMA3 == dmaMode) && (dataConfig->enableDma))
5000 {
5001 /* ADMA3 Integrated Descriptor Address. */
5002 SDHC_CORE_ADMA_ID_LOW_R(base) = (uint32_t)dataConfig->data;
5003 }
5004 else
5005 {
5006 if (dataConfig->enableDma)
5007 {
5008 /* Set the ADMA descriptor table. */
5009 if ((uint32_t)CY_SD_HOST_DMA_SDMA == dmaMode)
5010 {
5011 /* Set 512K bytes SDMA Buffer Boundary. */
5012 SDHC_CORE_BLOCKSIZE_R(base) = _CLR_SET_FLD16U(SDHC_CORE_BLOCKSIZE_R(base),
5013 SDHC_CORE_BLOCKSIZE_R_SDMA_BUF_BDARY,
5014 CY_SD_HOST_SDMA_BUF_BYTES_512K);
5015
5016 if (true == _FLD2BOOL(SDHC_CORE_HOST_CTRL2_R_HOST_VER4_ENABLE, SDHC_CORE_HOST_CTRL2_R(base)))
5017 {
5018 /* The data address. */
5019 SDHC_CORE_ADMA_SA_LOW_R(base) = (uint32_t)dataConfig->data;
5020
5021 /* Set the block count. */
5022 SDHC_CORE_SDMASA_R(base) = dataConfig->numberOfBlock;
5023 }
5024 else
5025 {
5026 /* The data address. */
5027 SDHC_CORE_SDMASA_R(base) = (uint32_t)dataConfig->data;
5028 }
5029 }
5030 else
5031 {
5032 /* The data address. */
5033 SDHC_CORE_ADMA_SA_LOW_R(base) = (uint32_t)dataConfig->data;
5034 }
5035 }
5036 else
5037 {
5038 /* Set the block count. */
5039 SDHC_CORE_SDMASA_R(base) = dataConfig->numberOfBlock;
5040 }
5041
5042 /* Set the block size. */
5043 SDHC_CORE_BLOCKSIZE_R(base) = _CLR_SET_FLD16U(SDHC_CORE_BLOCKSIZE_R(base),
5044 SDHC_CORE_BLOCKSIZE_R_XFER_BLOCK_SIZE,
5045 dataConfig->blockSize);
5046
5047 /* Set the block count. */
5048 SDHC_CORE_BLOCKCOUNT_R(base) = (uint16_t)dataConfig->numberOfBlock;
5049
5050
5051 /* Set a multi- or single-block transfer.*/
5052 transferMode = _BOOL2FLD(SDHC_CORE_XFER_MODE_R_MULTI_BLK_SEL, (1U < dataConfig->numberOfBlock));
5053
5054 /* Set the data transfer direction. */
5055 transferMode |= _BOOL2FLD(SDHC_CORE_XFER_MODE_R_DATA_XFER_DIR, dataConfig->read);
5056
5057 /* Set the block count enable. */
5058 transferMode |= SDHC_CORE_XFER_MODE_R_BLOCK_COUNT_ENABLE_Msk;
5059
5060 /* Enable the DMA or not. */
5061 transferMode |= _BOOL2FLD(SDHC_CORE_XFER_MODE_R_DMA_ENABLE, dataConfig->enableDma);
5062
5063 /* Set an interrupt at the block gap. */
5064 SDHC_CORE_BGAP_CTRL_R(base) = (uint8_t)_CLR_SET_FLD8U(SDHC_CORE_BGAP_CTRL_R(base),
5065 SDHC_CORE_BGAP_CTRL_R_INT_AT_BGAP,
5066 ((dataConfig->enableIntAtBlockGap) ? 1UL : 0UL));
5067
5068 /* Set the data timeout (Base clock*2^27). */
5069 SDHC_CORE_TOUT_CTRL_R(base) = _CLR_SET_FLD8U(SDHC_CORE_TOUT_CTRL_R(base),
5070 SDHC_CORE_TOUT_CTRL_R_TOUT_CNT,
5071 dataConfig->dataTimeout);
5072
5073 /* The reliable write setting. */
5074 if (dataConfig->enReliableWrite)
5075 {
5076 ret = Cy_SD_Host_OpsSetBlockCount(base,
5077 dataConfig->enReliableWrite,
5078 dataConfig->numberOfBlock);
5079 }
5080
5081 /* The auto-command setting. */
5082 switch (dataConfig->autoCommand)
5083 {
5084 case CY_SD_HOST_AUTO_CMD_NONE:
5085 transferMode |= _VAL2FLD(SDHC_CORE_XFER_MODE_R_AUTO_CMD_ENABLE, 0UL);
5086 break;
5087 case CY_SD_HOST_AUTO_CMD_12:
5088 transferMode |= _VAL2FLD(SDHC_CORE_XFER_MODE_R_AUTO_CMD_ENABLE, 1UL);
5089 break;
5090 case CY_SD_HOST_AUTO_CMD_23:
5091 transferMode |= _VAL2FLD(SDHC_CORE_XFER_MODE_R_AUTO_CMD_ENABLE, 2UL);
5092 break;
5093 case CY_SD_HOST_AUTO_CMD_AUTO:
5094 transferMode |= _VAL2FLD(SDHC_CORE_XFER_MODE_R_AUTO_CMD_ENABLE, 3UL);
5095 break;
5096 default:
5097 ret = CY_SD_HOST_ERROR_INVALID_PARAMETER;
5098 break;
5099 }
5100
5101 SDHC_CORE_XFER_MODE_R(base) = (uint16_t)transferMode;
5102 }
5103 }
5104
5105 return ret;
5106 }
5107
5108
5109 /*******************************************************************************
5110 * Function Name: Cy_SD_Host_ChangeIoVoltage
5111 ****************************************************************************//**
5112 *
5113 * Changes the logic level on the sd_io_volt_sel line. It assumes that
5114 * this line is used to control a regulator connected to the VDDIO of the PSoC.
5115 * This regulator allows for switching between the 3.3V and 1.8V signaling.
5116 *
5117 * \note The dedicated io_volt_sel pin is used to change the regulator supplying
5118 * voltage to the VDDIO of the SD block in order to operate at 1.8V. To configure
5119 * the custom IO pin in order to control (using the GPIO driver) the regulator
5120 * supplying voltage, the user must implement weak Cy_SD_Host_ChangeIoVoltage().
5121 * Also, this function must set the SIGNALING_EN bit of the SDHC_CORE_HOST_CTRL2_R
5122 * register when ioVoltage = CY_SD_HOST_IO_VOLT_1_8V.
5123 *
5124 * \param *base
5125 * The SD host registers structure pointer.
5126 *
5127 * \param ioVoltage
5128 * The voltage for IO.
5129 *
5130 *******************************************************************************/
Cy_SD_Host_ChangeIoVoltage(SDHC_Type * base,cy_en_sd_host_io_voltage_t ioVoltage)5131 __WEAK void Cy_SD_Host_ChangeIoVoltage(SDHC_Type *base, cy_en_sd_host_io_voltage_t ioVoltage)
5132 {
5133 /* Set the 1.8V signaling enable. */
5134 SDHC_CORE_HOST_CTRL2_R(base) = _CLR_SET_FLD16U(SDHC_CORE_HOST_CTRL2_R(base),
5135 SDHC_CORE_HOST_CTRL2_R_SIGNALING_EN,
5136 (CY_SD_HOST_IO_VOLT_1_8V == ioVoltage) ? 1UL : 0UL);
5137 }
5138
5139
5140 /*******************************************************************************
5141 * Function Name: Cy_SD_Host_IsCardConnected
5142 ****************************************************************************//**
5143 *
5144 * Checks to see if a card is currently connected.
5145 *
5146 * \note You can use any GPIO custom pin for Card Detect. Add the SD Host driver
5147 * Cy_SD_Host_IsCardConnected() function with the __WEAK type to your code.
5148 * This function could read the value from any GPIO pin and return true when
5149 * the card is connected.
5150 *
5151 * \param *base
5152 * The SD host registers structure pointer.
5153 *
5154 * \return bool
5155 * true - the card is connected, false - the card is removed (not connected).
5156 *
5157 *******************************************************************************/
Cy_SD_Host_IsCardConnected(SDHC_Type const * base)5158 __WEAK bool Cy_SD_Host_IsCardConnected(SDHC_Type const *base)
5159 {
5160 while(true != _FLD2BOOL(SDHC_CORE_PSTATE_REG_CARD_STABLE, SDHC_CORE_PSTATE_REG(base)))
5161 {
5162 /* Wait until the card is stable. */
5163 }
5164
5165 return _FLD2BOOL(SDHC_CORE_PSTATE_REG_CARD_INSERTED, SDHC_CORE_PSTATE_REG(base));
5166 }
5167
5168
5169 /*******************************************************************************
5170 * Function Name: Cy_SD_Host_SoftwareReset
5171 ****************************************************************************//**
5172 *
5173 * Issues the software reset command to the SD card.
5174 *
5175 * \param *base
5176 * The SD host registers structure pointer.
5177 *
5178 * \param reset
5179 * The reset type.
5180 *
5181 *******************************************************************************/
Cy_SD_Host_SoftwareReset(SDHC_Type * base,cy_en_sd_host_reset_t reset)5182 void Cy_SD_Host_SoftwareReset(SDHC_Type *base,
5183 cy_en_sd_host_reset_t reset)
5184 {
5185 switch (reset)
5186 {
5187 case CY_SD_HOST_RESET_DATALINE:
5188 SDHC_CORE_SW_RST_R(base) = (uint8_t)_VAL2FLD(SDHC_CORE_SW_RST_R_SW_RST_DAT, 1UL);
5189
5190 /* Wait for at least 3 card clock periods */
5191 Cy_SysLib_DelayUs(CY_SD_HOST_3_PERIODS_US);
5192
5193 while(false != _FLD2BOOL(SDHC_CORE_SW_RST_R_SW_RST_DAT, SDHC_CORE_SW_RST_R(base)))
5194 {
5195 /* Wait until the reset completes. */
5196 }
5197
5198 break;
5199 case CY_SD_HOST_RESET_CMD_LINE:
5200 SDHC_CORE_SW_RST_R(base) = (uint8_t)_VAL2FLD(SDHC_CORE_SW_RST_R_SW_RST_CMD, 1UL);
5201
5202 /* Wait for at least 3 card clock periods */
5203 Cy_SysLib_DelayUs(CY_SD_HOST_3_PERIODS_US);
5204
5205 while(false != _FLD2BOOL(SDHC_CORE_SW_RST_R_SW_RST_CMD, SDHC_CORE_SW_RST_R(base)))
5206 {
5207 /* Wait until the reset completes. */
5208 }
5209
5210 break;
5211 case CY_SD_HOST_RESET_ALL:
5212
5213 SDHC_CORE_CLK_CTRL_R(base) = 0U;
5214
5215 /* Wait for at least 3 card clock periods */
5216 Cy_SysLib_DelayUs(CY_SD_HOST_3_PERIODS_US);
5217
5218 SDHC_CORE_SW_RST_R(base) = (uint8_t)_VAL2FLD(SDHC_CORE_SW_RST_R_SW_RST_ALL, 1UL);
5219
5220 while(false != _FLD2BOOL(SDHC_CORE_SW_RST_R_SW_RST_ALL, SDHC_CORE_SW_RST_R(base)))
5221 {
5222 /* Wait until the reset completes. */
5223 }
5224
5225 /* Enable the Internal clock. */
5226 SDHC_CORE_CLK_CTRL_R(base) = (uint16_t)_CLR_SET_FLD16U(SDHC_CORE_CLK_CTRL_R(base),
5227 SDHC_CORE_CLK_CTRL_R_INTERNAL_CLK_EN,
5228 1UL);
5229
5230 while(true != _FLD2BOOL(SDHC_CORE_CLK_CTRL_R_INTERNAL_CLK_STABLE, SDHC_CORE_CLK_CTRL_R(base)))
5231 {
5232 /* Wait for the stable Internal Clock. */
5233 }
5234
5235 break;
5236 default:
5237 /* Unknown Reset selection*/
5238 break;
5239 }
5240 }
5241
5242
5243 /*******************************************************************************
5244 * Function Name: Cy_SD_Host_GetPresentState
5245 ****************************************************************************//**
5246 *
5247 * Returns the values of the present state register.
5248 *
5249 * \param *base
5250 * The SD host registers structure pointer.
5251 *
5252 * \return The value of the present state register.
5253 *
5254 *******************************************************************************/
Cy_SD_Host_GetPresentState(SDHC_Type const * base)5255 uint32_t Cy_SD_Host_GetPresentState(SDHC_Type const *base)
5256 {
5257 uint32_t ret;
5258
5259 ret = SDHC_CORE_PSTATE_REG(base);
5260
5261 return ret;
5262 }
5263
5264
5265 /*******************************************************************************
5266 * Function Name: Cy_SD_Host_DeepSleepCallback
5267 ****************************************************************************//**
5268 *
5269 * This function handles the transition of the SD Host into and out of
5270 * Deep Sleep mode. It disables SD CLK before going to Deep Sleep mode and
5271 * enables SD CLK after wake up from Deep Sleep mode.
5272 * If the DAT line is active, or a read (write) transfer is being executed on
5273 * the bus, the device cannot enter Deep Sleep mode.
5274 *
5275 * This function must be called during execution of \ref Cy_SysPm_CpuEnterDeepSleep.
5276 * To do it, register this function as a callback before calling
5277 * \ref Cy_SysPm_CpuEnterDeepSleep : specify \ref CY_SYSPM_DEEPSLEEP as the callback
5278 * type and call \ref Cy_SysPm_RegisterCallback.
5279 *
5280 * \note When waking up from Deep Sleep, the SD Host driver requires up to 1 us
5281 * for clock stabilization. By default the SD Host driver will wait this length
5282 * of time on power up. The waiting loop is implemented in this function.
5283 * If the application is time sensitive this delay can be overridden by the
5284 * application by defining \ref CY_SD_HOST_CLK_RAMP_UP_TIME_US_WAKEUP.
5285 * This allows the application to perform other operations while the clock
5286 * is stabilizing in the background. However, the application must still make sure
5287 * that the SD Host clock has had time to stabilize before attempting to use the
5288 * SD card. The recommended way to override the value is to specify this as
5289 * a custom define on the compiler command line. This can be done by appending
5290 * the entry to the DEFINES variable in the application Makefile.
5291 * Eg: DEFINES+=CY_SD_HOST_CLK_RAMP_UP_TIME_US_WAKEUP=40.
5292 *
5293 * \param callbackParams
5294 * The pointer to the callback parameters structure
5295 * \ref cy_stc_syspm_callback_params_t.
5296 *
5297 * \param mode
5298 * Callback mode, see \ref cy_en_syspm_callback_mode_t
5299 *
5300 * \return
5301 * \ref cy_en_syspm_status_t
5302 *
5303 *******************************************************************************/
Cy_SD_Host_DeepSleepCallback(cy_stc_syspm_callback_params_t * callbackParams,cy_en_syspm_callback_mode_t mode)5304 cy_en_syspm_status_t Cy_SD_Host_DeepSleepCallback(cy_stc_syspm_callback_params_t *callbackParams,
5305 cy_en_syspm_callback_mode_t mode)
5306 {
5307 cy_en_syspm_status_t ret = CY_SYSPM_FAIL;
5308 SDHC_Type *locBase = (SDHC_Type *) (callbackParams->base);
5309
5310 switch(mode)
5311 {
5312 case CY_SYSPM_CHECK_READY:
5313 {
5314 /* Check DAT Line Active */
5315 uint32_t pState = Cy_SD_Host_GetPresentState(locBase);
5316 if ((CY_SD_HOST_DAT_LINE_ACTIVE != (pState & CY_SD_HOST_DAT_LINE_ACTIVE)) &&
5317 (CY_SD_HOST_CMD_CMD_INHIBIT_DAT != (pState & CY_SD_HOST_CMD_CMD_INHIBIT_DAT)))
5318 {
5319 ret = CY_SYSPM_SUCCESS;
5320 }
5321 }
5322 break;
5323
5324 case CY_SYSPM_CHECK_FAIL:
5325 {
5326 ret = CY_SYSPM_SUCCESS;
5327 }
5328 break;
5329
5330 case CY_SYSPM_BEFORE_TRANSITION:
5331 {
5332 /* Disable SD CLK before going to Deep Sleep mode */
5333 Cy_SD_Host_DisableSdClk(locBase);
5334
5335 ret = CY_SYSPM_SUCCESS;
5336 }
5337 break;
5338
5339 case CY_SYSPM_AFTER_TRANSITION:
5340 {
5341 /* Enable SD CLK after wake up from Deep Sleep mode */
5342 Cy_SD_Host_EnableSdClk(locBase);
5343
5344 /* Wait for the stable CLK */
5345 Cy_SysLib_DelayUs(CY_SD_HOST_CLK_RAMP_UP_TIME_US_WAKEUP);
5346
5347 ret = CY_SYSPM_SUCCESS;
5348 }
5349 break;
5350
5351 default:
5352 /* Unknown state */
5353 break;
5354 }
5355
5356 return (ret);
5357 }
5358
5359 /*******************************************************************************
5360 * Function Name: Cy_SD_Host_GetBlockCount
5361 ****************************************************************************//**
5362 *
5363 * Returns the Block count in SD/eMMC Card.
5364 *
5365 * \param *base
5366 * The SD host registers structure pointer.
5367 *
5368 * \param *block_count
5369 * The pointer to store the block_count.
5370 *
5371 * \param context
5372 * The pointer to the context structure \ref cy_stc_sd_host_context_t allocated
5373 * by the user. The structure is used during the SD host operation for internal
5374 * configuration and data retention. The user must not modify anything
5375 * in this structure.
5376 *
5377 * \return \ref cy_en_sd_host_status_t
5378 *
5379 *******************************************************************************/
Cy_SD_Host_GetBlockCount(SDHC_Type * base,uint32_t * block_count,cy_stc_sd_host_context_t * context)5380 cy_en_sd_host_status_t Cy_SD_Host_GetBlockCount(SDHC_Type *base,
5381 uint32_t *block_count,
5382 cy_stc_sd_host_context_t *context)
5383 {
5384 cy_en_sd_host_status_t ret = CY_SD_HOST_SUCCESS;
5385
5386 /* Check for the NULL pointer */
5387 if ((NULL != base) && (NULL != block_count) && (NULL != context))
5388 {
5389 if ((CY_SD_HOST_SD == context->cardType) || (CY_SD_HOST_EMMC == context->cardType))
5390 {
5391 *block_count = context->maxSectorNum;
5392 }
5393 }
5394 else
5395 {
5396 ret = CY_SD_HOST_ERROR_INVALID_PARAMETER;
5397 }
5398
5399 return ret;
5400 }
5401
5402
5403 CY_MISRA_BLOCK_END('MISRA C-2012 Rule 18.1')
5404
5405 #if defined(__cplusplus)
5406 }
5407 #endif
5408
5409 #endif /* CY_IP_MXSDHC */
5410
5411 /* [] END OF FILE */
5412