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