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