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