1 /*
2 * Copyright 2021-2024 NXP
3 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 */
6
7 /**
8 * @file Qspi_Ip_Sfdp.c
9 *
10 * @addtogroup IPV_QSPI
11 * @{
12 */
13
14
15 #ifdef __cplusplus
16 extern "C"{
17 #endif
18
19 #include "OsIf.h"
20 #include "Qspi_Ip_Controller.h"
21 #include "Qspi_Ip.h"
22 #include "Qspi_Ip_Common.h"
23
24 /*==================================================================================================
25 * SOURCE FILE VERSION INFORMATION
26 ==================================================================================================*/
27 #define QSPI_IP_VENDOR_ID_C 43
28 #define QSPI_IP_AR_RELEASE_MAJOR_VERSION_C 4
29 #define QSPI_IP_AR_RELEASE_MINOR_VERSION_C 7
30 #define QSPI_IP_AR_RELEASE_REVISION_VERSION_C 0
31 #define QSPI_IP_SW_MAJOR_VERSION_C 2
32 #define QSPI_IP_SW_MINOR_VERSION_C 0
33 #define QSPI_IP_SW_PATCH_VERSION_C 0
34 /*==================================================================================================
35 * FILE VERSION CHECKS
36 ==================================================================================================*/
37 #ifndef DISABLE_MCAL_INTERMODULE_ASR_CHECK
38 /* Check if current file and OsIf.h header file are of the same Autosar version */
39 #if ((QSPI_IP_AR_RELEASE_MAJOR_VERSION_C != OSIF_AR_RELEASE_MAJOR_VERSION) || \
40 (QSPI_IP_AR_RELEASE_MINOR_VERSION_C != OSIF_AR_RELEASE_MINOR_VERSION) \
41 )
42 #error "AutoSar Version Numbers of Qspi_Ip_Sfdp.c and OsIf.h are different"
43 #endif
44 #endif
45
46 /* Check if current file and Qspi_Ip_Controller header file are of the same vendor */
47 #if (QSPI_IP_VENDOR_ID_C != QSPI_IP_CONTROLLER_VENDOR_ID_H)
48 #error "Qspi_Ip_Sfdp.c and Qspi_Ip_Controller.h have different vendor ids"
49 #endif
50 /* Check if current file and Qspi_Ip_Controller header file are of the same Autosar version */
51 #if ((QSPI_IP_AR_RELEASE_MAJOR_VERSION_C != QSPI_IP_CONTROLLER_AR_RELEASE_MAJOR_VERSION_H) || \
52 (QSPI_IP_AR_RELEASE_MINOR_VERSION_C != QSPI_IP_CONTROLLER_AR_RELEASE_MINOR_VERSION_H) || \
53 (QSPI_IP_AR_RELEASE_REVISION_VERSION_C != QSPI_IP_CONTROLLER_AR_RELEASE_REVISION_VERSION_H) \
54 )
55 #error "AutoSar Version Numbers of Qspi_Ip_Sfdp.c and Qspi_Ip_Controller.h are different"
56 #endif
57 /* Check if current file and Qspi_Ip_Controller header file are of the same Software version */
58 #if ((QSPI_IP_SW_MAJOR_VERSION_C != QSPI_IP_CONTROLLER_SW_MAJOR_VERSION_H) || \
59 (QSPI_IP_SW_MINOR_VERSION_C != QSPI_IP_CONTROLLER_SW_MINOR_VERSION_H) || \
60 (QSPI_IP_SW_PATCH_VERSION_C != QSPI_IP_CONTROLLER_SW_PATCH_VERSION_H) \
61 )
62 #error "Software Version Numbers of Qspi_Ip_Sfdp.c and Qspi_Ip_Controller.h are different"
63 #endif
64
65 /* Check if current file and Qspi_Ip_Common header file are of the same vendor */
66 #if (QSPI_IP_VENDOR_ID_C != QSPI_IP_COMMON_VENDOR_ID_H)
67 #error "Qspi_Ip_Sfdp.c and Qspi_Ip_Common.h have different vendor ids"
68 #endif
69 /* Check if current file and Qspi_Ip_Common header file are of the same Autosar version */
70 #if ((QSPI_IP_AR_RELEASE_MAJOR_VERSION_C != QSPI_IP_COMMON_AR_RELEASE_MAJOR_VERSION_H) || \
71 (QSPI_IP_AR_RELEASE_MINOR_VERSION_C != QSPI_IP_COMMON_AR_RELEASE_MINOR_VERSION_H) || \
72 (QSPI_IP_AR_RELEASE_REVISION_VERSION_C != QSPI_IP_COMMON_AR_RELEASE_REVISION_VERSION_H) \
73 )
74 #error "AutoSar Version Numbers of Qspi_Ip_Sfdp.c and Qspi_Ip_Common.h are different"
75 #endif
76 /* Check if current file and Qspi_Ip_Common header file are of the same Software version */
77 #if ((QSPI_IP_SW_MAJOR_VERSION_C != QSPI_IP_COMMON_SW_MAJOR_VERSION_H) || \
78 (QSPI_IP_SW_MINOR_VERSION_C != QSPI_IP_COMMON_SW_MINOR_VERSION_H) || \
79 (QSPI_IP_SW_PATCH_VERSION_C != QSPI_IP_COMMON_SW_PATCH_VERSION_H) \
80 )
81 #error "Software Version Numbers of Qspi_Ip_Sfdp.c and Qspi_Ip_Common.h are different"
82 #endif
83
84 /* Check if current file and Qspi_Ip header file are of the same vendor */
85 #if (QSPI_IP_VENDOR_ID_C != QSPI_IP_VENDOR_ID_H)
86 #error "Qspi_Ip_Sfdp.c and Qspi_Ip.h have different vendor ids"
87 #endif
88 /* Check if current file and Qspi_Ip header file are of the same Autosar version */
89 #if ((QSPI_IP_AR_RELEASE_MAJOR_VERSION_C != QSPI_IP_AR_RELEASE_MAJOR_VERSION_H) || \
90 (QSPI_IP_AR_RELEASE_MINOR_VERSION_C != QSPI_IP_AR_RELEASE_MINOR_VERSION_H) || \
91 (QSPI_IP_AR_RELEASE_REVISION_VERSION_C != QSPI_IP_AR_RELEASE_REVISION_VERSION_H) \
92 )
93 #error "AutoSar Version Numbers of Qspi_Ip_Sfdp.c and Qspi_Ip.h are different"
94 #endif
95 /* Check if current file and Qspi_Ip header file are of the same Software version */
96 #if ((QSPI_IP_SW_MAJOR_VERSION_C != QSPI_IP_SW_MAJOR_VERSION_H) || \
97 (QSPI_IP_SW_MINOR_VERSION_C != QSPI_IP_SW_MINOR_VERSION_H) || \
98 (QSPI_IP_SW_PATCH_VERSION_C != QSPI_IP_SW_PATCH_VERSION_H) \
99 )
100 #error "Software Version Numbers of Qspi_Ip_Sfdp.c and Qspi_Ip.h are different"
101 #endif
102
103 /*******************************************************************************
104 * Definitions.
105 ******************************************************************************/
106
107 #define QSPI_IP_CMD_SFDP_READ 0x5AU /* Instruction for Read SFDP command */
108 #define QSPI_IP_CMD_BASIC_READ 0x03U /* Basic read instruction */
109 #define QSPI_IP_CMD_BASIC_READ_4B 0x13U /* Basic read instruction - 4 bytes address */
110 #define QSPI_IP_CMD_BASIC_WRITE 0x02U /* Basic write (page program) instruction */
111 #define QSPI_IP_CMD_BASIC_READ_SR 0x05U /* Basic instruction for read status reg. command */
112 #define QSPI_IP_CMD_BASIC_WRITE_SR 0x01U /* Basic instruction for write status reg. command */
113 #define QSPI_IP_CMD_BASIC_WRITE_ENABLE 0x06U /* Basic instruction for write enable command */
114 #define QSPI_IP_CMD_BASIC_CHIP_ERASE 0x60U /* Basic instruction for chip erase command */
115 #define QSPI_IP_CMD_XSPI_WRITE 0x12U /* XSPI profile 1.0 Instruction for Program command */
116 #define QSPI_IP_CMD_XSPI_CHIP_ERASE 0xC7U /* XSPI profile 1.0 Instruction for Chip Erase command */
117 #define QSPI_IP_CMD_XSPI_READ_SR 0x05U /* XSPI profile 1.0 Instruction for read status reg. command */
118 #define QSPI_IP_CMD_XSPI_WRITE_SR 0x01U /* XSPI profile 1.0 Instruction for write status reg. command */
119 #define QSPI_IP_CMD_XSPI_WRITE_ENABLE 0x06U /* XSPI profile 1.0 Instruction for write enable command */
120 #define QSPI_IP_CMD_XSPI_RESET 0xF0U /* XSPI profile 1.0 Instruction for soft reset command */
121 #define QSPI_IP_CMD_XSPI_RESET_ENABLE 0x66U /* XSPI profile 1.0 Instruction for reset enable command */
122 #define QSPI_IP_CMD_XSPI_RESET_DEF 0x99U /* XSPI profile 1.0 Instruction for soft reset and enter default protocol mode command */
123
124 #define QSPI_IP_TABLE_SIZE_BASIC 20U /* Max basic flash parameter table length */
125 #define QSPI_IP_TABLE_SIZE_4BADD 2U /* Max 4-byte address instruction table length */
126 #define QSPI_IP_TABLE_SIZE_XSPI1 5U /* Max extended serial peripheral interface table length */
127 #define QSPI_IP_TABLE_SIZE_SRMAP 28U /* Max status, control and configuration register map length */
128 #define QSPI_IP_TABLE_SIZE_2DOPI 8U /* Max command sequence to change to octal ddr length */
129
130 #define QSPI_IP_SFDP_MAJOR_REVISION 1U
131 #define QSPI_IP_SFDP_MINOR_REVISION_REV_0 0U
132 #define QSPI_IP_SFDP_MINOR_REVISION_REV_A 5U
133
134 #define QSPI_IP_SFDP_ACCESS_PROTOCOL_HYPERBUS 0xFAU /* xSPI NOR Profile 2 HYPERBUS, (8D, 8D, 8D) operation */
135 #define QSPI_IP_SFDP_ACCESS_PROTOCOL_LEGACY 0xFFU /* Legacy option (1S-1S-1S), (2S-2S-2S) or (4S-4S-4S) operation, 3-byte addressing for SFDP */
136
137 /**** Constants for retrieving SFDP parameters - Basic flash parameters table *****/
138
139 /* Flash Size */
140 #define QSPI_IP_SFDP_BASIC_MEM_SIZE_DWORD 2U
141 #define QSPI_IP_SFDP_BASIC_MEM_SIZE_SHIFT 0U
142 #define QSPI_IP_SFDP_BASIC_MEM_SIZE_WIDTH 32U
143 /* Page Size */
144 #define QSPI_IP_SFDP_BASIC_PAGE_SIZE_DWORD 11U
145 #define QSPI_IP_SFDP_BASIC_PAGE_SIZE_SHIFT 4U
146 #define QSPI_IP_SFDP_BASIC_PAGE_SIZE_WIDTH 4U
147 /* Octal DTR (8D-8D-8D) Command and Command Extension */
148 #define QSPI_IP_SFDP_BASIC_CMD_EXT_DWORD 18U
149 #define QSPI_IP_SFDP_BASIC_CMD_EXT_SHIFT 29U
150 #define QSPI_IP_SFDP_BASIC_CMD_EXT_WIDTH 2U
151 /* Erase type 1 - instruction and size */
152 #define QSPI_IP_SFDP_BASIC_ERASE1_INST_DWORD 8U
153 #define QSPI_IP_SFDP_BASIC_ERASE1_INST_SHIFT 8U
154 #define QSPI_IP_SFDP_BASIC_ERASE1_INST_WIDTH 8U
155 #define QSPI_IP_SFDP_BASIC_ERASE1_SIZE_DWORD 8U
156 #define QSPI_IP_SFDP_BASIC_ERASE1_SIZE_SHIFT 0U
157 #define QSPI_IP_SFDP_BASIC_ERASE1_SIZE_WIDTH 8U
158 /* Erase type 2 - instruction and size */
159 #define QSPI_IP_SFDP_BASIC_ERASE2_INST_DWORD 8U
160 #define QSPI_IP_SFDP_BASIC_ERASE2_INST_SHIFT 24U
161 #define QSPI_IP_SFDP_BASIC_ERASE2_INST_WIDTH 8U
162 #define QSPI_IP_SFDP_BASIC_ERASE2_SIZE_DWORD 8U
163 #define QSPI_IP_SFDP_BASIC_ERASE2_SIZE_SHIFT 16U
164 #define QSPI_IP_SFDP_BASIC_ERASE2_SIZE_WIDTH 8U
165 /* Erase type 3 - instruction and size */
166 #define QSPI_IP_SFDP_BASIC_ERASE3_INST_DWORD 9U
167 #define QSPI_IP_SFDP_BASIC_ERASE3_INST_SHIFT 8U
168 #define QSPI_IP_SFDP_BASIC_ERASE3_INST_WIDTH 8U
169 #define QSPI_IP_SFDP_BASIC_ERASE3_SIZE_DWORD 9U
170 #define QSPI_IP_SFDP_BASIC_ERASE3_SIZE_SHIFT 0U
171 #define QSPI_IP_SFDP_BASIC_ERASE3_SIZE_WIDTH 8U
172 /* Erase type 4 - instruction and size */
173 #define QSPI_IP_SFDP_BASIC_ERASE4_INST_DWORD 9U
174 #define QSPI_IP_SFDP_BASIC_ERASE4_INST_SHIFT 24U
175 #define QSPI_IP_SFDP_BASIC_ERASE4_INST_WIDTH 8U
176 #define QSPI_IP_SFDP_BASIC_ERASE4_SIZE_DWORD 9U
177 #define QSPI_IP_SFDP_BASIC_ERASE4_SIZE_SHIFT 16U
178 #define QSPI_IP_SFDP_BASIC_ERASE4_SIZE_WIDTH 8U
179 /* Erase suspend instruction */
180 #define QSPI_IP_SFDP_BASIC_ESUS_INSTR_DWORD 13U
181 #define QSPI_IP_SFDP_BASIC_ESUS_INSTR_SHIFT 24U
182 #define QSPI_IP_SFDP_BASIC_ESUS_INSTR_WIDTH 8U
183 /* Erase resume instruction */
184 #define QSPI_IP_SFDP_BASIC_ERES_INSTR_DWORD 13U
185 #define QSPI_IP_SFDP_BASIC_ERES_INSTR_SHIFT 16U
186 #define QSPI_IP_SFDP_BASIC_ERES_INSTR_WIDTH 8U
187 /* Program suspend instruction */
188 #define QSPI_IP_SFDP_BASIC_PSUS_INSTR_DWORD 13U
189 #define QSPI_IP_SFDP_BASIC_PSUS_INSTR_SHIFT 8U
190 #define QSPI_IP_SFDP_BASIC_PSUS_INSTR_WIDTH 8U
191 /* Program resume instruction */
192 #define QSPI_IP_SFDP_BASIC_PRES_INSTR_DWORD 13U
193 #define QSPI_IP_SFDP_BASIC_PRES_INSTR_SHIFT 0U
194 #define QSPI_IP_SFDP_BASIC_PRES_INSTR_WIDTH 8U
195 /* Quad Enable Requirements */
196 #define QSPI_IP_SFDP_BASIC_QE_REQ_DWORD 15U
197 #define QSPI_IP_SFDP_BASIC_QE_REQ_SHIFT 20U
198 #define QSPI_IP_SFDP_BASIC_QE_REQ_WIDTH 3U
199 /* Soft Reset */
200 #define QSPI_IP_SFDP_BASIC_SW_RESET_DWORD 16U
201 #define QSPI_IP_SFDP_BASIC_SW_RESET_SHIFT 8U
202 #define QSPI_IP_SFDP_BASIC_SW_RESET_WIDTH 6U
203 /* Write Enable Instruction Select for Writing to Volatile Status Register */
204 #define QSPI_IP_SFDP_BASIC_WREN_SR_DWORD 1U
205 #define QSPI_IP_SFDP_BASIC_WREN_SR_SHIFT 3U
206 #define QSPI_IP_SFDP_BASIC_WREN_SR_WIDTH 2U
207 /* 4-4-4 mode enable sequences */
208 #define QSPI_IP_SFDP_BASIC_444_SWITCH_DWORD 15U
209 #define QSPI_IP_SFDP_BASIC_444_SWITCH_SHIFT 4U
210 #define QSPI_IP_SFDP_BASIC_444_SWITCH_WIDTH 5U
211
212 /* Fast read instructions/mode bits/dummy bits */
213 #define QSPI_IP_SFDP_BASIC_READ112_SUP_DWORD 1U
214 #define QSPI_IP_SFDP_BASIC_READ122_SUP_DWORD 1U
215 #define QSPI_IP_SFDP_BASIC_READ114_SUP_DWORD 1U
216 #define QSPI_IP_SFDP_BASIC_READ144_SUP_DWORD 1U
217 #define QSPI_IP_SFDP_BASIC_READ444_SUP_DWORD 5U
218 #define QSPI_IP_SFDP_BASIC_READ118_SUP_DWORD 17U
219 #define QSPI_IP_SFDP_BASIC_READ188_SUP_DWORD 17U
220
221 #define QSPI_IP_SFDP_BASIC_READ112_SUP_SHIFT 16U
222 #define QSPI_IP_SFDP_BASIC_READ122_SUP_SHIFT 20U
223 #define QSPI_IP_SFDP_BASIC_READ114_SUP_SHIFT 22U
224 #define QSPI_IP_SFDP_BASIC_READ144_SUP_SHIFT 21U
225 #define QSPI_IP_SFDP_BASIC_READ444_SUP_SHIFT 4U
226 #define QSPI_IP_SFDP_BASIC_READ118_SUP_SHIFT 24U
227 #define QSPI_IP_SFDP_BASIC_READ188_SUP_SHIFT 8U
228
229 #define QSPI_IP_SFDP_BASIC_READ112_SUP_WIDTH 1U
230 #define QSPI_IP_SFDP_BASIC_READ122_SUP_WIDTH 1U
231 #define QSPI_IP_SFDP_BASIC_READ114_SUP_WIDTH 1U
232 #define QSPI_IP_SFDP_BASIC_READ144_SUP_WIDTH 1U
233 #define QSPI_IP_SFDP_BASIC_READ444_SUP_WIDTH 1U
234 #define QSPI_IP_SFDP_BASIC_READ118_SUP_WIDTH 8U
235 #define QSPI_IP_SFDP_BASIC_READ188_SUP_WIDTH 8U
236
237 #define QSPI_IP_SFDP_BASIC_READ112_INST_DWORD 4U
238 #define QSPI_IP_SFDP_BASIC_READ122_INST_DWORD 4U
239 #define QSPI_IP_SFDP_BASIC_READ114_INST_DWORD 3U
240 #define QSPI_IP_SFDP_BASIC_READ144_INST_DWORD 3U
241 #define QSPI_IP_SFDP_BASIC_READ444_INST_DWORD 7U
242 #define QSPI_IP_SFDP_BASIC_READ118_INST_DWORD 17U
243 #define QSPI_IP_SFDP_BASIC_READ188_INST_DWORD 17U
244
245 #define QSPI_IP_SFDP_BASIC_READ112_INST_SHIFT 8U
246 #define QSPI_IP_SFDP_BASIC_READ122_INST_SHIFT 24U
247 #define QSPI_IP_SFDP_BASIC_READ114_INST_SHIFT 24U
248 #define QSPI_IP_SFDP_BASIC_READ144_INST_SHIFT 8U
249 #define QSPI_IP_SFDP_BASIC_READ444_INST_SHIFT 24U
250 #define QSPI_IP_SFDP_BASIC_READ118_INST_SHIFT 24U
251 #define QSPI_IP_SFDP_BASIC_READ188_INST_SHIFT 8U
252
253 #define QSPI_IP_SFDP_BASIC_READ112_INST_WIDTH 8U
254 #define QSPI_IP_SFDP_BASIC_READ122_INST_WIDTH 8U
255 #define QSPI_IP_SFDP_BASIC_READ114_INST_WIDTH 8U
256 #define QSPI_IP_SFDP_BASIC_READ144_INST_WIDTH 8U
257 #define QSPI_IP_SFDP_BASIC_READ444_INST_WIDTH 8U
258 #define QSPI_IP_SFDP_BASIC_READ118_INST_WIDTH 8U
259 #define QSPI_IP_SFDP_BASIC_READ188_INST_WIDTH 8U
260
261 #define QSPI_IP_SFDP_BASIC_READ112_MODE_DWORD 4U
262 #define QSPI_IP_SFDP_BASIC_READ122_MODE_DWORD 4U
263 #define QSPI_IP_SFDP_BASIC_READ114_MODE_DWORD 3U
264 #define QSPI_IP_SFDP_BASIC_READ144_MODE_DWORD 3U
265 #define QSPI_IP_SFDP_BASIC_READ444_MODE_DWORD 7U
266 #define QSPI_IP_SFDP_BASIC_READ118_MODE_DWORD 17U
267 #define QSPI_IP_SFDP_BASIC_READ188_MODE_DWORD 17U
268
269 #define QSPI_IP_SFDP_BASIC_READ112_MODE_SHIFT 5U
270 #define QSPI_IP_SFDP_BASIC_READ122_MODE_SHIFT 21U
271 #define QSPI_IP_SFDP_BASIC_READ114_MODE_SHIFT 21U
272 #define QSPI_IP_SFDP_BASIC_READ144_MODE_SHIFT 5U
273 #define QSPI_IP_SFDP_BASIC_READ444_MODE_SHIFT 21U
274 #define QSPI_IP_SFDP_BASIC_READ118_MODE_SHIFT 21U
275 #define QSPI_IP_SFDP_BASIC_READ188_MODE_SHIFT 5U
276
277 #define QSPI_IP_SFDP_BASIC_READ112_MODE_WIDTH 3U
278 #define QSPI_IP_SFDP_BASIC_READ122_MODE_WIDTH 3U
279 #define QSPI_IP_SFDP_BASIC_READ114_MODE_WIDTH 3U
280 #define QSPI_IP_SFDP_BASIC_READ144_MODE_WIDTH 3U
281 #define QSPI_IP_SFDP_BASIC_READ444_MODE_WIDTH 3U
282 #define QSPI_IP_SFDP_BASIC_READ118_MODE_WIDTH 3U
283 #define QSPI_IP_SFDP_BASIC_READ188_MODE_WIDTH 3U
284
285 #define QSPI_IP_SFDP_BASIC_READ112_DUMMY_DWORD 4U
286 #define QSPI_IP_SFDP_BASIC_READ122_DUMMY_DWORD 4U
287 #define QSPI_IP_SFDP_BASIC_READ114_DUMMY_DWORD 3U
288 #define QSPI_IP_SFDP_BASIC_READ144_DUMMY_DWORD 3U
289 #define QSPI_IP_SFDP_BASIC_READ444_DUMMY_DWORD 7U
290 #define QSPI_IP_SFDP_BASIC_READ118_DUMMY_DWORD 17U
291 #define QSPI_IP_SFDP_BASIC_READ188_DUMMY_DWORD 17U
292
293 #define QSPI_IP_SFDP_BASIC_READ112_DUMMY_SHIFT 0U
294 #define QSPI_IP_SFDP_BASIC_READ122_DUMMY_SHIFT 16U
295 #define QSPI_IP_SFDP_BASIC_READ114_DUMMY_SHIFT 16U
296 #define QSPI_IP_SFDP_BASIC_READ144_DUMMY_SHIFT 0U
297 #define QSPI_IP_SFDP_BASIC_READ444_DUMMY_SHIFT 16U
298 #define QSPI_IP_SFDP_BASIC_READ118_DUMMY_SHIFT 16U
299 #define QSPI_IP_SFDP_BASIC_READ188_DUMMY_SHIFT 0U
300
301 #define QSPI_IP_SFDP_BASIC_READ112_DUMMY_WIDTH 5U
302 #define QSPI_IP_SFDP_BASIC_READ122_DUMMY_WIDTH 5U
303 #define QSPI_IP_SFDP_BASIC_READ114_DUMMY_WIDTH 5U
304 #define QSPI_IP_SFDP_BASIC_READ144_DUMMY_WIDTH 5U
305 #define QSPI_IP_SFDP_BASIC_READ444_DUMMY_WIDTH 5U
306 #define QSPI_IP_SFDP_BASIC_READ118_DUMMY_WIDTH 5U
307 #define QSPI_IP_SFDP_BASIC_READ188_DUMMY_WIDTH 5U
308
309 #define QSPI_IP_SFDP_BASIC_ADDR_BYTES_DWORD 1U
310 #define QSPI_IP_SFDP_BASIC_ADDR_BYTES_SHIFT 17U
311 #define QSPI_IP_SFDP_BASIC_ADDR_BYTES_WIDTH 2U
312
313 #define QSPI_IP_SFDP_BASIC_ADDR_SWITCH_DWORD 16U
314 #define QSPI_IP_SFDP_BASIC_ADDR_SWITCH_SHIFT 24U
315 #define QSPI_IP_SFDP_BASIC_ADDR_SWITCH_WIDTH 8U
316
317
318 /**** Constants for retrieving SFDP parameters - xSPI 1.0 table *****/
319
320 /* Read fast command */
321 #define QSPI_IP_SFDP_XSPI1_READ_FAST_DWORD 1U
322 #define QSPI_IP_SFDP_XSPI1_READ_FAST_SHIFT 8U
323 #define QSPI_IP_SFDP_XSPI1_READ_FAST_WIDTH 8U
324 /* Max. number of dummy cycles */
325 #define QSPI_IP_SFDP_XSPI1_DUMMY_DWORD 4U
326 #define QSPI_IP_SFDP_XSPI1_DUMMY_SHIFT 7U
327 #define QSPI_IP_SFDP_XSPI1_DUMMY_WIDTH 5U
328 /* Chip erase support */
329 #define QSPI_IP_SFDP_XSPI1_CHIP_ERASE_DWORD 3U
330 #define QSPI_IP_SFDP_XSPI1_CHIP_ERASE_SHIFT 26U
331 #define QSPI_IP_SFDP_XSPI1_CHIP_ERASE_WIDTH 1U
332 /* Soft Reset support */
333 #define QSPI_IP_SFDP_XSPI1_RESET_DWORD 3U
334 #define QSPI_IP_SFDP_XSPI1_RESET_SHIFT 13U
335 #define QSPI_IP_SFDP_XSPI1_RESET_WIDTH 1U
336 /* Reset Enable support */
337 #define QSPI_IP_SFDP_XSPI1_RESET_EN_DWORD 3U
338 #define QSPI_IP_SFDP_XSPI1_RESET_EN_SHIFT 12U
339 #define QSPI_IP_SFDP_XSPI1_RESET_EN_WIDTH 1U
340 /* Soft Reset and Enter default protocol mode support */
341 #define QSPI_IP_SFDP_XSPI1_RESET_DEF_DWORD 3U
342 #define QSPI_IP_SFDP_XSPI1_RESET_DEF_SHIFT 11U
343 #define QSPI_IP_SFDP_XSPI1_RESET_DEF_WIDTH 1U
344
345 /**** Constants for retrieving SFDP parameters - Status, Control and Configuration Register Map *****/
346
347 /* Busy (WIP) flag offset */
348 #define QSPI_IP_SFDP_SRMAP_WIP_OFFSET_DWORD 5U
349 #define QSPI_IP_SFDP_SRMAP_WIP_OFFSET_SHIFT 24U
350 #define QSPI_IP_SFDP_SRMAP_WIP_OFFSET_WIDTH 3U
351 /* Busy (WIP) flag value */
352 #define QSPI_IP_SFDP_SRMAP_WIP_VALUE_DWORD 5U
353 #define QSPI_IP_SFDP_SRMAP_WIP_VALUE_SHIFT 30U
354 #define QSPI_IP_SFDP_SRMAP_WIP_VALUE_WIDTH 1U
355 /* Write Enable (WEL) flag offset */
356 #define QSPI_IP_SFDP_SRMAP_WEL_OFFSET_DWORD 6U
357 #define QSPI_IP_SFDP_SRMAP_WEL_OFFSET_SHIFT 24U
358 #define QSPI_IP_SFDP_SRMAP_WEL_OFFSET_WIDTH 3U
359 /* Dummy cycles in 8D-8D-8D mode */
360 #define QSPI_IP_SFDP_SRMAP_DUMMY_8D_DWORD 3U
361 #define QSPI_IP_SFDP_SRMAP_DUMMY_8D_SHIFT 6U
362 #define QSPI_IP_SFDP_SRMAP_DUMMY_8D_WIDTH 4U
363 /* SR read is direct command (not using address) */
364 #define QSPI_IP_SFDP_SRMAP_USE_ADDR_DWORD 5U
365 #define QSPI_IP_SFDP_SRMAP_USE_ADDR_SHIFT 28U
366 #define QSPI_IP_SFDP_SRMAP_USE_ADDR_WIDTH 1U
367 /* Address offset for volatile registers */
368 #define QSPI_IP_SFDP_SRMAP_OFFSET_DWORD 1U
369 #define QSPI_IP_SFDP_SRMAP_OFFSET_SHIFT 0U
370 #define QSPI_IP_SFDP_SRMAP_OFFSET_WIDTH 32U
371 /* Number of address bytes used for Generic Addressable Read/Write Status/Control register commands for volatile registers */
372 #define QSPI_IP_SFDP_SRMAP_NBYTES_DWORD 3U
373 #define QSPI_IP_SFDP_SRMAP_NBYTES_SHIFT 28U
374 #define QSPI_IP_SFDP_SRMAP_NBYTES_WIDTH 2U
375 /* SR local address */
376 #define QSPI_IP_SFDP_SRMAP_SR_ADDR_DWORD 5U
377 #define QSPI_IP_SFDP_SRMAP_SR_ADDR_SHIFT 16U
378 #define QSPI_IP_SFDP_SRMAP_SR_ADDR_WIDTH 8U
379 /* SR address shift (before adding to the offset) */
380 #define QSPI_IP_SFDP_SRMAP_SR_SHIFT_DWORD 5U
381 #define QSPI_IP_SFDP_SRMAP_SR_SHIFT_SHIFT 27U
382 #define QSPI_IP_SFDP_SRMAP_SR_SHIFT_WIDTH 1U
383
384 /**** Constants for retrieving SFDP parameters - Command Sequences to Change to Octal DDR (8D-8D-8D) mode *****/
385
386 /* Length of command sequence */
387 #define QSPI_IP_SFDP_2DOPI_CMD_LEN_SHIFT 24U
388 #define QSPI_IP_SFDP_2DOPI_CMD_LEN_WIDTH 8U
389 /* Bytes of command sequence */
390 #define QSPI_IP_SFDP_2DOPI_CMD_BYTE1_SHIFT 16U
391 #define QSPI_IP_SFDP_2DOPI_CMD_BYTE2_SHIFT 8U
392 #define QSPI_IP_SFDP_2DOPI_CMD_BYTE3_SHIFT 0U
393 #define QSPI_IP_SFDP_2DOPI_CMD_BYTE4_SHIFT 24U
394 #define QSPI_IP_SFDP_2DOPI_CMD_BYTE5_SHIFT 16U
395 #define QSPI_IP_SFDP_2DOPI_CMD_BYTE6_SHIFT 8U
396 #define QSPI_IP_SFDP_2DOPI_CMD_BYTE7_SHIFT 0U
397
398 /**** Constants for retrieving SFDP parameters - 4-byte Address Instructions *****/
399
400 #define QSPI_IP_SFDP_4BADD_INSTR_SUP_DWORD 1U
401 #define QSPI_IP_SFDP_4BADD_INSTR_SUP_WIDTH 1U
402 #define QSPI_IP_SFDP_4BADD_ERASE_INST_DWORD 2U
403 #define QSPI_IP_SFDP_4BADD_ERASE_INST_WIDTH 8U
404 #define QSPI_IP_SFDP_4BADD_ERASE1_SUP_SHIFT 9U
405 #define QSPI_IP_SFDP_4BADD_ERASE2_SUP_SHIFT 10U
406 #define QSPI_IP_SFDP_4BADD_ERASE3_SUP_SHIFT 11U
407 #define QSPI_IP_SFDP_4BADD_ERASE4_SUP_SHIFT 12U
408 #define QSPI_IP_SFDP_4BADD_ERASE1_INST_SHIFT 0U
409 #define QSPI_IP_SFDP_4BADD_ERASE2_INST_SHIFT 8U
410 #define QSPI_IP_SFDP_4BADD_ERASE3_INST_SHIFT 16U
411 #define QSPI_IP_SFDP_4BADD_ERASE4_INST_SHIFT 24U
412
413 #define QSPI_IP_SFDP_4BADD_READ112_SUP_DWORD 1U
414 #define QSPI_IP_SFDP_4BADD_READ122_SUP_DWORD 1U
415 #define QSPI_IP_SFDP_4BADD_READ114_SUP_DWORD 1U
416 #define QSPI_IP_SFDP_4BADD_READ144_SUP_DWORD 1U
417 #define QSPI_IP_SFDP_4BADD_READ444_SUP_DWORD 0xFFU /* invalid */
418 #define QSPI_IP_SFDP_4BADD_READ118_SUP_DWORD 1U
419 #define QSPI_IP_SFDP_4BADD_READ188_SUP_DWORD 1U
420
421 #define QSPI_IP_SFDP_4BADD_READ111_SUP_SHIFT 0U
422 #define QSPI_IP_SFDP_4BADD_READ112_SUP_SHIFT 2U
423 #define QSPI_IP_SFDP_4BADD_READ122_SUP_SHIFT 3U
424 #define QSPI_IP_SFDP_4BADD_READ114_SUP_SHIFT 4U
425 #define QSPI_IP_SFDP_4BADD_READ144_SUP_SHIFT 5U
426 #define QSPI_IP_SFDP_4BADD_READ444_SUP_SHIFT 1U /* use 1-1-1 fast read */
427 #define QSPI_IP_SFDP_4BADD_READ118_SUP_SHIFT 20U
428 #define QSPI_IP_SFDP_4BADD_READ188_SUP_SHIFT 21U
429
430
431 #define QSPI_IP_SFDP_4BADD_WRITE112_SUP_DWORD 0xFFU /* invalid */
432 #define QSPI_IP_SFDP_4BADD_WRITE122_SUP_DWORD 0xFFU /* invalid */
433 #define QSPI_IP_SFDP_4BADD_WRITE114_SUP_DWORD 1U
434 #define QSPI_IP_SFDP_4BADD_WRITE144_SUP_DWORD 1U
435 #define QSPI_IP_SFDP_4BADD_WRITE444_SUP_DWORD 1U
436 #define QSPI_IP_SFDP_4BADD_WRITE118_SUP_DWORD 1U
437 #define QSPI_IP_SFDP_4BADD_WRITE188_SUP_DWORD 1U
438
439 #define QSPI_IP_SFDP_4BADD_WRITE112_SUP_SHIFT 0U
440 #define QSPI_IP_SFDP_4BADD_WRITE122_SUP_SHIFT 0U
441 #define QSPI_IP_SFDP_4BADD_WRITE114_SUP_SHIFT 7U
442 #define QSPI_IP_SFDP_4BADD_WRITE144_SUP_SHIFT 8U
443 #define QSPI_IP_SFDP_4BADD_WRITE444_SUP_SHIFT 6U /* use 1-1-1 write */
444 #define QSPI_IP_SFDP_4BADD_WRITE118_SUP_SHIFT 23U
445 #define QSPI_IP_SFDP_4BADD_WRITE188_SUP_SHIFT 24U
446
447 /* fast read modes */
448 #define QSPI_IP_SFDP_READ_MODE_112 0x00U /* 1-1-2 fast read mode */
449 #define QSPI_IP_SFDP_READ_MODE_122 0x01U /* 1-2-2 fast read mode */
450 #define QSPI_IP_SFDP_READ_MODE_114 0x02U /* 1-1-4 fast read mode */
451 #define QSPI_IP_SFDP_READ_MODE_144 0x03U /* 1-4-4 fast read mode */
452 #define QSPI_IP_SFDP_READ_MODE_444 0x04U /* 4-4-4 fast read mode */
453 #define QSPI_IP_SFDP_READ_MODE_118 0x05U /* 1-1-8 fast read mode */
454 #define QSPI_IP_SFDP_READ_MODE_188 0x06U /* 1-8-8 fast read mode */
455 #define QSPI_IP_SFDP_READ_MODE_MAX 0x07U /* Number of read modes */
456
457
458 /*******************************************************************************
459 * Enumerations.
460 ******************************************************************************/
461
462 #if (QSPI_IP_MEM_INSTANCE_COUNT > 0)
463
464 /* sfdp modes */
465 typedef enum
466 {
467 QSPI_IP_SFDP_1S_1S_1S = 0x00U, /*!< 1S-1S-1S mode */
468 QSPI_IP_SFDP_2S_2S_2S = 0x01U, /*!< 2S-2S-2S mode */
469 QSPI_IP_SFDP_4S_4S_4S = 0x02U, /*!< 4S-4S-4S mode */
470 QSPI_IP_SFDP_4S_4D_4D = 0x03U, /*!< 4S-4D-4D mode */
471 QSPI_IP_SFDP_8D_8D_8D = 0x04U, /*!< 8D-8D-8D mode */
472 } Qspi_Ip_SfdpModes;
473
474 /* sfdp table types */
475 typedef enum
476 {
477 QSPI_IP_SFDP_TABLE_BASIC = 0x00U, /*!< Basic flash parameter table */
478 QSPI_IP_SFDP_TABLE_4BADD = 0x84U, /*!< 4-byte Address Instruction Table */
479 QSPI_IP_SFDP_TABLE_XSPI1 = 0x05U, /*!< eXtended Serial Peripheral Interface (xSPI) Profile 1.0 */
480 QSPI_IP_SFDP_TABLE_SRMAP = 0x87U, /*!< Status, Control and Configuration Register Map */
481 QSPI_IP_SFDP_TABLE_2DOPI = 0x0AU, /*!< Command Sequences to change to DOPI (8D-8D-8D) mode */
482 } Qspi_Ip_SfdpTables;
483
484 /* structure containing sfdp tables */
485 typedef struct
486 {
487 uint32 paramTable_basic[QSPI_IP_TABLE_SIZE_BASIC];
488 uint32 paramTable_4badd[QSPI_IP_TABLE_SIZE_4BADD];
489 uint32 paramTable_xspi1[QSPI_IP_TABLE_SIZE_XSPI1];
490 uint32 paramTable_srmap[QSPI_IP_TABLE_SIZE_SRMAP];
491 uint32 paramTable_2dopi[QSPI_IP_TABLE_SIZE_2DOPI];
492 uint8 paramTableLength_basic;
493 uint8 paramTableLength_4badd;
494 uint8 paramTableLength_xspi1;
495 uint8 paramTableLength_srmap;
496 uint8 paramTableLength_2dopi;
497 } Qspi_Ip_SfdpTablesContainer;
498
499 /*******************************************************************************
500 * Local Variables
501 ******************************************************************************/
502
503 #define MEM_43_EXFLS_START_SEC_VAR_CLEARED_16
504 #include "Mem_43_EXFLS_MemMap.h"
505
506 static uint16 lutCount; /* Current number of operations in the LUT table */
507
508 #define MEM_43_EXFLS_STOP_SEC_VAR_CLEARED_16
509 #include "Mem_43_EXFLS_MemMap.h"
510
511
512 #define MEM_43_EXFLS_START_SEC_VAR_CLEARED_8
513 #include "Mem_43_EXFLS_MemMap.h"
514
515 static uint8 initOpCount; /* Current number of operations in the initial operations list */
516 static uint8 basicAddrBits; /* Current number of operations in the initial operations list */
517 static uint8 modeIndex; /* Index of the selected read mode */
518
519 #define MEM_43_EXFLS_STOP_SEC_VAR_CLEARED_8
520 #include "Mem_43_EXFLS_MemMap.h"
521
522
523 #define MEM_43_EXFLS_START_SEC_VAR_CLEARED_UNSPECIFIED
524 #include "Mem_43_EXFLS_MemMap.h"
525
526 static Qspi_Ip_LutPadsType cmdPads; /* Pads to use for commands (e.g. 4 if the selected operation mode is 4-4-4) */
527 static Qspi_Ip_LutPadsType cmdPadsInit; /* Number of pads used for commands in the initial state */
528
529 #define MEM_43_EXFLS_STOP_SEC_VAR_CLEARED_UNSPECIFIED
530 #include "Mem_43_EXFLS_MemMap.h"
531
532
533 #define MEM_43_EXFLS_START_SEC_VAR_CLEARED_BOOLEAN
534 #include "Mem_43_EXFLS_MemMap.h"
535
536 static boolean overflow; /* Either LUT or initial operations list was not big enough */
537 static boolean quadAvailable; /* Quad mode can be used */
538
539 #define MEM_43_EXFLS_STOP_SEC_VAR_CLEARED_BOOLEAN
540 #include "Mem_43_EXFLS_MemMap.h"
541
542
543 #define MEM_43_EXFLS_START_SEC_VAR_INIT_BOOLEAN
544 #include "Mem_43_EXFLS_MemMap.h"
545
546 static boolean bootModeLegacyXPI = (boolean)TRUE; /* Memory device boots up in xSPI or HyperBus mode (default is XPI) */
547
548 #define MEM_43_EXFLS_STOP_SEC_VAR_INIT_BOOLEAN
549 #include "Mem_43_EXFLS_MemMap.h"
550
551 /* tables for extracting parameters from SFDP table */
552
553 #define MEM_43_EXFLS_START_SEC_VAR_INIT_8
554 #include "Mem_43_EXFLS_MemMap.h"
555
556 static uint8 eraseInstDword[4U] = {
557 QSPI_IP_SFDP_BASIC_ERASE1_INST_DWORD,
558 QSPI_IP_SFDP_BASIC_ERASE2_INST_DWORD,
559 QSPI_IP_SFDP_BASIC_ERASE3_INST_DWORD,
560 QSPI_IP_SFDP_BASIC_ERASE4_INST_DWORD
561 };
562 static uint8 eraseInstShift[4U] = {
563 QSPI_IP_SFDP_BASIC_ERASE1_INST_SHIFT,
564 QSPI_IP_SFDP_BASIC_ERASE2_INST_SHIFT,
565 QSPI_IP_SFDP_BASIC_ERASE3_INST_SHIFT,
566 QSPI_IP_SFDP_BASIC_ERASE4_INST_SHIFT
567 };
568 static uint8 eraseInstWidth[4U] = {
569 QSPI_IP_SFDP_BASIC_ERASE1_INST_WIDTH,
570 QSPI_IP_SFDP_BASIC_ERASE2_INST_WIDTH,
571 QSPI_IP_SFDP_BASIC_ERASE3_INST_WIDTH,
572 QSPI_IP_SFDP_BASIC_ERASE4_INST_WIDTH
573 };
574 static uint8 eraseSizeDword[4U] = {
575 QSPI_IP_SFDP_BASIC_ERASE1_SIZE_DWORD,
576 QSPI_IP_SFDP_BASIC_ERASE2_SIZE_DWORD,
577 QSPI_IP_SFDP_BASIC_ERASE3_SIZE_DWORD,
578 QSPI_IP_SFDP_BASIC_ERASE4_SIZE_DWORD
579 };
580 static uint8 eraseSizeShift[4U] = {
581 QSPI_IP_SFDP_BASIC_ERASE1_SIZE_SHIFT,
582 QSPI_IP_SFDP_BASIC_ERASE2_SIZE_SHIFT,
583 QSPI_IP_SFDP_BASIC_ERASE3_SIZE_SHIFT,
584 QSPI_IP_SFDP_BASIC_ERASE4_SIZE_SHIFT
585 };
586 static uint8 eraseSizeWidth[4U] = {
587 QSPI_IP_SFDP_BASIC_ERASE1_SIZE_WIDTH,
588 QSPI_IP_SFDP_BASIC_ERASE2_SIZE_WIDTH,
589 QSPI_IP_SFDP_BASIC_ERASE3_SIZE_WIDTH,
590 QSPI_IP_SFDP_BASIC_ERASE4_SIZE_WIDTH
591 };
592
593 static uint8 erase4ByteSupShift[4U] = {
594 QSPI_IP_SFDP_4BADD_ERASE1_SUP_SHIFT,
595 QSPI_IP_SFDP_4BADD_ERASE2_SUP_SHIFT,
596 QSPI_IP_SFDP_4BADD_ERASE3_SUP_SHIFT,
597 QSPI_IP_SFDP_4BADD_ERASE4_SUP_SHIFT
598 };
599
600 static uint8 erase4ByteInstShift[4U] = {
601 QSPI_IP_SFDP_4BADD_ERASE1_INST_SHIFT,
602 QSPI_IP_SFDP_4BADD_ERASE2_INST_SHIFT,
603 QSPI_IP_SFDP_4BADD_ERASE3_INST_SHIFT,
604 QSPI_IP_SFDP_4BADD_ERASE4_INST_SHIFT
605 };
606
607 /* Erase instruction with 4-Byte Address, specified by JESD216D */
608 static uint8 erase4ByteInst[4U] = {
609 0x21U, /* 4-KB erase */
610 0x5CU, /* 32-KB erase */
611 0xDCU, /* 64-KB erase */
612 0xDCU /* 256-KB erase */
613 };
614
615 static uint8 dopiSwitchShift[7U] = {
616 QSPI_IP_SFDP_2DOPI_CMD_BYTE1_SHIFT,
617 QSPI_IP_SFDP_2DOPI_CMD_BYTE2_SHIFT,
618 QSPI_IP_SFDP_2DOPI_CMD_BYTE3_SHIFT,
619 QSPI_IP_SFDP_2DOPI_CMD_BYTE4_SHIFT,
620 QSPI_IP_SFDP_2DOPI_CMD_BYTE5_SHIFT,
621 QSPI_IP_SFDP_2DOPI_CMD_BYTE6_SHIFT,
622 QSPI_IP_SFDP_2DOPI_CMD_BYTE7_SHIFT,
623 };
624 static uint8 dopiSwitchWord[7U] = {
625 0U,
626 0U,
627 0U,
628 1U,
629 1U,
630 1U,
631 1U,
632 };
633
634 static uint8 readSupDword[QSPI_IP_SFDP_READ_MODE_MAX] = {
635 QSPI_IP_SFDP_BASIC_READ112_SUP_DWORD,
636 QSPI_IP_SFDP_BASIC_READ122_SUP_DWORD,
637 QSPI_IP_SFDP_BASIC_READ114_SUP_DWORD,
638 QSPI_IP_SFDP_BASIC_READ144_SUP_DWORD,
639 QSPI_IP_SFDP_BASIC_READ444_SUP_DWORD,
640 QSPI_IP_SFDP_BASIC_READ118_SUP_DWORD,
641 QSPI_IP_SFDP_BASIC_READ188_SUP_DWORD
642 };
643
644 static uint8 readSupShift[QSPI_IP_SFDP_READ_MODE_MAX] = {
645 QSPI_IP_SFDP_BASIC_READ112_SUP_SHIFT,
646 QSPI_IP_SFDP_BASIC_READ122_SUP_SHIFT,
647 QSPI_IP_SFDP_BASIC_READ114_SUP_SHIFT,
648 QSPI_IP_SFDP_BASIC_READ144_SUP_SHIFT,
649 QSPI_IP_SFDP_BASIC_READ444_SUP_SHIFT,
650 QSPI_IP_SFDP_BASIC_READ118_SUP_SHIFT,
651 QSPI_IP_SFDP_BASIC_READ188_SUP_SHIFT
652 };
653
654 static uint8 readSupWitdh[QSPI_IP_SFDP_READ_MODE_MAX] = {
655 QSPI_IP_SFDP_BASIC_READ112_SUP_WIDTH,
656 QSPI_IP_SFDP_BASIC_READ122_SUP_WIDTH,
657 QSPI_IP_SFDP_BASIC_READ114_SUP_WIDTH,
658 QSPI_IP_SFDP_BASIC_READ144_SUP_WIDTH,
659 QSPI_IP_SFDP_BASIC_READ444_SUP_WIDTH,
660 QSPI_IP_SFDP_BASIC_READ118_SUP_WIDTH,
661 QSPI_IP_SFDP_BASIC_READ188_SUP_WIDTH
662 };
663
664 static uint8 read4ByteSupDword[QSPI_IP_SFDP_READ_MODE_MAX] = {
665 QSPI_IP_SFDP_4BADD_READ112_SUP_DWORD,
666 QSPI_IP_SFDP_4BADD_READ122_SUP_DWORD,
667 QSPI_IP_SFDP_4BADD_READ114_SUP_DWORD,
668 QSPI_IP_SFDP_4BADD_READ144_SUP_DWORD,
669 QSPI_IP_SFDP_4BADD_READ444_SUP_DWORD,
670 QSPI_IP_SFDP_4BADD_READ118_SUP_DWORD,
671 QSPI_IP_SFDP_4BADD_READ188_SUP_DWORD
672 };
673
674 static uint8 read4ByteSupShift[QSPI_IP_SFDP_READ_MODE_MAX] = {
675 QSPI_IP_SFDP_4BADD_READ112_SUP_SHIFT,
676 QSPI_IP_SFDP_4BADD_READ122_SUP_SHIFT,
677 QSPI_IP_SFDP_4BADD_READ114_SUP_SHIFT,
678 QSPI_IP_SFDP_4BADD_READ144_SUP_SHIFT,
679 QSPI_IP_SFDP_4BADD_READ444_SUP_SHIFT,
680 QSPI_IP_SFDP_4BADD_READ118_SUP_SHIFT,
681 QSPI_IP_SFDP_4BADD_READ188_SUP_SHIFT
682 };
683
684 static uint8 write4ByteSupDword[QSPI_IP_SFDP_READ_MODE_MAX] = {
685 QSPI_IP_SFDP_4BADD_WRITE112_SUP_DWORD,
686 QSPI_IP_SFDP_4BADD_WRITE122_SUP_DWORD,
687 QSPI_IP_SFDP_4BADD_WRITE114_SUP_DWORD,
688 QSPI_IP_SFDP_4BADD_WRITE144_SUP_DWORD,
689 QSPI_IP_SFDP_4BADD_WRITE444_SUP_DWORD,
690 QSPI_IP_SFDP_4BADD_WRITE118_SUP_DWORD,
691 QSPI_IP_SFDP_4BADD_WRITE188_SUP_DWORD
692 };
693
694 static uint8 write4ByteSupShift[QSPI_IP_SFDP_READ_MODE_MAX] = {
695 QSPI_IP_SFDP_4BADD_WRITE112_SUP_SHIFT,
696 QSPI_IP_SFDP_4BADD_WRITE122_SUP_SHIFT,
697 QSPI_IP_SFDP_4BADD_WRITE114_SUP_SHIFT,
698 QSPI_IP_SFDP_4BADD_WRITE144_SUP_SHIFT,
699 QSPI_IP_SFDP_4BADD_WRITE444_SUP_SHIFT,
700 QSPI_IP_SFDP_4BADD_WRITE118_SUP_SHIFT,
701 QSPI_IP_SFDP_4BADD_WRITE188_SUP_SHIFT
702 };
703
704 static uint8 read4ByteInst[QSPI_IP_SFDP_READ_MODE_MAX] = {
705 0x3CU,
706 0xBCU,
707 0x6CU,
708 0xECU,
709 0x13U,
710 0x7CU,
711 0xCCU
712 };
713
714 static uint8 write4ByteInst[QSPI_IP_SFDP_READ_MODE_MAX] = {
715 0x00U,
716 0x00U,
717 0x34U,
718 0x3EU,
719 0x12U,
720 0x84U,
721 0x8EU
722 };
723
724 static uint8 readInstDword[QSPI_IP_SFDP_READ_MODE_MAX] = {
725 QSPI_IP_SFDP_BASIC_READ112_INST_DWORD,
726 QSPI_IP_SFDP_BASIC_READ122_INST_DWORD,
727 QSPI_IP_SFDP_BASIC_READ114_INST_DWORD,
728 QSPI_IP_SFDP_BASIC_READ144_INST_DWORD,
729 QSPI_IP_SFDP_BASIC_READ444_INST_DWORD,
730 QSPI_IP_SFDP_BASIC_READ118_INST_DWORD,
731 QSPI_IP_SFDP_BASIC_READ188_INST_DWORD
732 };
733
734 static uint8 readInstShift[QSPI_IP_SFDP_READ_MODE_MAX] = {
735 QSPI_IP_SFDP_BASIC_READ112_INST_SHIFT,
736 QSPI_IP_SFDP_BASIC_READ122_INST_SHIFT,
737 QSPI_IP_SFDP_BASIC_READ114_INST_SHIFT,
738 QSPI_IP_SFDP_BASIC_READ144_INST_SHIFT,
739 QSPI_IP_SFDP_BASIC_READ444_INST_SHIFT,
740 QSPI_IP_SFDP_BASIC_READ118_INST_SHIFT,
741 QSPI_IP_SFDP_BASIC_READ188_INST_SHIFT
742 };
743
744 static uint8 readInstWidth[QSPI_IP_SFDP_READ_MODE_MAX] = {
745 QSPI_IP_SFDP_BASIC_READ112_INST_WIDTH,
746 QSPI_IP_SFDP_BASIC_READ122_INST_WIDTH,
747 QSPI_IP_SFDP_BASIC_READ114_INST_WIDTH,
748 QSPI_IP_SFDP_BASIC_READ144_INST_WIDTH,
749 QSPI_IP_SFDP_BASIC_READ444_INST_WIDTH,
750 QSPI_IP_SFDP_BASIC_READ118_INST_WIDTH,
751 QSPI_IP_SFDP_BASIC_READ188_INST_WIDTH
752 };
753
754 static uint8 readModeDword[QSPI_IP_SFDP_READ_MODE_MAX] = {
755 QSPI_IP_SFDP_BASIC_READ112_MODE_DWORD,
756 QSPI_IP_SFDP_BASIC_READ122_MODE_DWORD,
757 QSPI_IP_SFDP_BASIC_READ114_MODE_DWORD,
758 QSPI_IP_SFDP_BASIC_READ144_MODE_DWORD,
759 QSPI_IP_SFDP_BASIC_READ444_MODE_DWORD,
760 QSPI_IP_SFDP_BASIC_READ118_MODE_DWORD,
761 QSPI_IP_SFDP_BASIC_READ188_MODE_DWORD
762 };
763
764 static uint8 readModeShift[QSPI_IP_SFDP_READ_MODE_MAX] = {
765 QSPI_IP_SFDP_BASIC_READ112_MODE_SHIFT,
766 QSPI_IP_SFDP_BASIC_READ122_MODE_SHIFT,
767 QSPI_IP_SFDP_BASIC_READ114_MODE_SHIFT,
768 QSPI_IP_SFDP_BASIC_READ144_MODE_SHIFT,
769 QSPI_IP_SFDP_BASIC_READ444_MODE_SHIFT,
770 QSPI_IP_SFDP_BASIC_READ118_MODE_SHIFT,
771 QSPI_IP_SFDP_BASIC_READ188_MODE_SHIFT
772 };
773
774 static uint8 readModeWidth[QSPI_IP_SFDP_READ_MODE_MAX] = {
775 QSPI_IP_SFDP_BASIC_READ112_MODE_WIDTH,
776 QSPI_IP_SFDP_BASIC_READ122_MODE_WIDTH,
777 QSPI_IP_SFDP_BASIC_READ114_MODE_WIDTH,
778 QSPI_IP_SFDP_BASIC_READ144_MODE_WIDTH,
779 QSPI_IP_SFDP_BASIC_READ444_MODE_WIDTH,
780 QSPI_IP_SFDP_BASIC_READ118_MODE_WIDTH,
781 QSPI_IP_SFDP_BASIC_READ188_MODE_WIDTH
782 };
783
784 static uint8 readDummyDword[QSPI_IP_SFDP_READ_MODE_MAX] = {
785 QSPI_IP_SFDP_BASIC_READ112_DUMMY_DWORD,
786 QSPI_IP_SFDP_BASIC_READ122_DUMMY_DWORD,
787 QSPI_IP_SFDP_BASIC_READ114_DUMMY_DWORD,
788 QSPI_IP_SFDP_BASIC_READ144_DUMMY_DWORD,
789 QSPI_IP_SFDP_BASIC_READ444_DUMMY_DWORD,
790 QSPI_IP_SFDP_BASIC_READ118_DUMMY_DWORD,
791 QSPI_IP_SFDP_BASIC_READ188_DUMMY_DWORD
792 };
793
794 static uint8 readDummyShift[QSPI_IP_SFDP_READ_MODE_MAX] = {
795 QSPI_IP_SFDP_BASIC_READ112_DUMMY_SHIFT,
796 QSPI_IP_SFDP_BASIC_READ122_DUMMY_SHIFT,
797 QSPI_IP_SFDP_BASIC_READ114_DUMMY_SHIFT,
798 QSPI_IP_SFDP_BASIC_READ144_DUMMY_SHIFT,
799 QSPI_IP_SFDP_BASIC_READ444_DUMMY_SHIFT,
800 QSPI_IP_SFDP_BASIC_READ118_DUMMY_SHIFT,
801 QSPI_IP_SFDP_BASIC_READ188_DUMMY_SHIFT
802 };
803
804 static uint8 readDummyWidth[QSPI_IP_SFDP_READ_MODE_MAX] = {
805 QSPI_IP_SFDP_BASIC_READ112_DUMMY_WIDTH,
806 QSPI_IP_SFDP_BASIC_READ122_DUMMY_WIDTH,
807 QSPI_IP_SFDP_BASIC_READ114_DUMMY_WIDTH,
808 QSPI_IP_SFDP_BASIC_READ144_DUMMY_WIDTH,
809 QSPI_IP_SFDP_BASIC_READ444_DUMMY_WIDTH,
810 QSPI_IP_SFDP_BASIC_READ118_DUMMY_WIDTH,
811 QSPI_IP_SFDP_BASIC_READ188_DUMMY_WIDTH
812 };
813
814 #define MEM_43_EXFLS_STOP_SEC_VAR_INIT_8
815 #include "Mem_43_EXFLS_MemMap.h"
816
817
818 #define MEM_43_EXFLS_START_SEC_VAR_INIT_UNSPECIFIED
819 #include "Mem_43_EXFLS_MemMap.h"
820
821 static Qspi_Ip_LutPadsType readModeInstPads[QSPI_IP_SFDP_READ_MODE_MAX] = {
822 QSPI_IP_LUT_PADS_1,
823 QSPI_IP_LUT_PADS_1,
824 QSPI_IP_LUT_PADS_1,
825 QSPI_IP_LUT_PADS_1,
826 QSPI_IP_LUT_PADS_4,
827 QSPI_IP_LUT_PADS_1,
828 QSPI_IP_LUT_PADS_1
829 };
830
831 static Qspi_Ip_LutPadsType readModeAddrPads[QSPI_IP_SFDP_READ_MODE_MAX] = {
832 QSPI_IP_LUT_PADS_1,
833 QSPI_IP_LUT_PADS_2,
834 QSPI_IP_LUT_PADS_1,
835 QSPI_IP_LUT_PADS_4,
836 QSPI_IP_LUT_PADS_4,
837 QSPI_IP_LUT_PADS_1,
838 QSPI_IP_LUT_PADS_8
839 };
840
841 static Qspi_Ip_LutPadsType readModeDataPads[QSPI_IP_SFDP_READ_MODE_MAX] = {
842 QSPI_IP_LUT_PADS_2,
843 QSPI_IP_LUT_PADS_2,
844 QSPI_IP_LUT_PADS_4,
845 QSPI_IP_LUT_PADS_4,
846 QSPI_IP_LUT_PADS_4,
847 QSPI_IP_LUT_PADS_8,
848 QSPI_IP_LUT_PADS_8
849 };
850
851 #define MEM_43_EXFLS_STOP_SEC_VAR_INIT_UNSPECIFIED
852 #include "Mem_43_EXFLS_MemMap.h"
853
854
855 /*==================================================================================================
856 *LOCAL FUNCTION PROTOTYPES
857 ==================================================================================================*/
858 #define MEM_43_EXFLS_START_SEC_CODE
859 #include "Mem_43_EXFLS_MemMap.h"
860
861 static inline Qspi_Ip_InstrOpType Qspi_Ip_PackLut(Qspi_Ip_LutCommandsType cmd,
862 Qspi_Ip_LutPadsType pad,
863 uint8 op
864 );
865
866 static inline void Qspi_Ip_SfdpLutInit(void);
867
868 static inline void Qspi_Ip_SfdpLutAdd(const Qspi_Ip_LutConfigType *lutSequences,
869 Qspi_Ip_InstrOpType instr
870 );
871
872 static inline uint32 Qspi_Ip_SfdpGetBasicParam(const Qspi_Ip_SfdpTablesContainer *sfdpTables,
873 uint8 dword,
874 uint8 shift,
875 uint8 width,
876 uint32 defaultValue
877 );
878
879 static inline uint32 Qspi_Ip_SfdpGet4BAddParam(const Qspi_Ip_SfdpTablesContainer *sfdpTables,
880 uint8 dword,
881 uint8 shift,
882 uint8 width,
883 uint32 defaultValue
884 );
885
886 static inline uint32 Qspi_Ip_SfdpGetXspi1Param(const Qspi_Ip_SfdpTablesContainer *sfdpTables,
887 uint8 dword,
888 uint8 shift,
889 uint8 width,
890 uint32 defaultValue
891 );
892
893 static inline uint32 Qspi_Ip_SfdpGetSRMapParam(const Qspi_Ip_SfdpTablesContainer *sfdpTables,
894 uint8 dword,
895 uint8 shift,
896 uint8 width,
897 uint32 defaultValue
898 );
899
900 static inline uint32 Qspi_Ip_SfdpGet2DopiParam(const Qspi_Ip_SfdpTablesContainer *sfdpTables,
901 uint8 dword,
902 uint8 shift,
903 uint8 width,
904 uint32 defaultValue
905 );
906
907 static void Qspi_Ip_SfdpLutAddSrAddr(const Qspi_Ip_LutConfigType *lutSequences,
908 const Qspi_Ip_SfdpTablesContainer *sfdpTables
909 );
910
911 static inline boolean Qspi_Ip_SfdpSignatureCheck(const uint8 *data);
912
913 static inline void Qspi_Ip_SfdpInitLut(uint32 instance,
914 Qspi_Ip_SfdpModes mode
915 );
916
917 static void Qspi_Ip_WaitAfterReset(void);
918
919 static void Qspi_Ip_SfdpInitReset(uint32 instance,
920 uint32 baseAddress
921 );
922
923 static void Qspi_Ip_SfdpInitReset_4S4S4S(uint32 instance,
924 uint32 baseAddress
925 );
926
927 static void Qspi_Ip_SfdpExitQPI(uint32 instance,
928 uint32 baseAddress
929 );
930
931
932 static void Qspi_Ip_SfdpInitReset_8D8D8D(uint32 instance,
933 uint32 baseAddress
934 );
935
936 static void Qspi_Ip_SfdpPackLutEnterLegacySPI(uint32 sequenceIndex,
937 uint32 *lutData
938 );
939
940 static void Qspi_Ip_SfdpLutInitEnterLegacySPI(Qspi_Ip_MemoryConfigType const *pConfig);
941
942 static void Qspi_Ip_SfdpEnterLegacySPI(uint32 instance,
943 uint32 baseAddress
944 );
945
946 static void Qspi_Ip_SfdpExitDOPI(uint32 instance,
947 uint32 baseAddress
948 );
949
950 static Qspi_Ip_StatusType Qspi_Ip_SfdpCheck(uint32 instance,
951 uint32 baseAddress
952 );
953
954 static Qspi_Ip_StatusType Qspi_Ip_SfdpFindWorkingMode(uint32 instance,
955 uint32 baseAddress
956 );
957
958 static inline boolean Qspi_Ip_SfdpCheckMinorRevision(uint8 minorRevision);
959
960 static inline uint8 Qspi_Ip_SfdpGetCmdExt(const Qspi_Ip_SfdpTablesContainer *sfdpTables,
961 uint8 instruction
962 );
963
964 static inline uint32 Qspi_Ip_SfdpGetParamTableAddress(const uint8 * paramHeader,
965 uint8 accessProtocol
966 );
967
968 static inline boolean Qspi_Ip_SfdpCheckNewerRevision(uint8 paramIdLSB,
969 uint8 tableType,
970 uint8 majorRevision,
971 uint8 minorRevision,
972 sint16 minorRevisionMax
973 );
974
975 static Qspi_Ip_StatusType Qspi_Ip_SfdpFindTable(uint32 instance,
976 uint32 baseAddress,
977 Qspi_Ip_SfdpTables tableType,
978 uint32 * paramTable,
979 uint8 * paramTableLength
980 );
981
982 static Qspi_Ip_StatusType Qspi_Ip_SfdpReadTables(uint32 instance,
983 uint32 baseAddress,
984 Qspi_Ip_SfdpTablesContainer *sfdpTables
985 );
986
987 static void Qspi_Ip_SfdpInitSimpleCmd(uint8 cmd,
988 const Qspi_Ip_MemoryConfigType *pConfig
989 );
990
991 static uint8 Qspi_Ip_SfdpGetWeSrInstr(const Qspi_Ip_SfdpTablesContainer *sfdpTables);
992
993 static void Qspi_Ip_SfdpInitWriteReg(uint8 cmd,
994 uint8 wrenCmd,
995 uint8 size,
996 uint32 value,
997 const Qspi_Ip_MemoryConfigType *pConfig
998 );
999
1000 static Qspi_Ip_StatusType Qspi_Ip_Sfdp4byteAddrSwitch_01(const Qspi_Ip_MemoryConfigType * pConfig);
1001 static Qspi_Ip_StatusType Qspi_Ip_Sfdp4byteAddrSwitch_02(const Qspi_Ip_MemoryConfigType * pConfig);
1002 static Qspi_Ip_StatusType Qspi_Ip_Sfdp4byteAddrSwitch_08(const Qspi_Ip_MemoryConfigType * pConfig);
1003 static Qspi_Ip_StatusType Qspi_Ip_Sfdp4byteAddrSwitch_16(const Qspi_Ip_MemoryConfigType * pConfig);
1004
1005 static Qspi_Ip_StatusType Qspi_Ip_Sfdp4byteAddrSwitch(const Qspi_Ip_SfdpTablesContainer *sfdpTables,
1006 const Qspi_Ip_MemoryConfigType *pConfig
1007 );
1008
1009 static void Qspi_Ip_SfdpGetBasicAddrBits(const Qspi_Ip_SfdpTablesContainer *sfdpTables,
1010 const Qspi_Ip_MemoryConfigType *pConfig
1011 );
1012
1013 static void Qspi_Ip_SfdpConfigureQE(const Qspi_Ip_SfdpTablesContainer *sfdpTables,
1014 const Qspi_Ip_MemoryConfigType *pConfig
1015 );
1016
1017 static Qspi_Ip_LutCommandsType Qspi_Ip_SfdpGetModeInstr(uint8 modeClocks,
1018 Qspi_Ip_LutPadsType addrPads
1019 );
1020
1021 static void Qspi_Ip_SfdpGetSpiReadInstr(const Qspi_Ip_SfdpTablesContainer *sfdpTables,
1022 uint8 cnt,
1023 uint8 *instruction,
1024 uint8 *addrBits
1025 );
1026
1027 static void Qspi_Ip_SfdpConfigBasicRead(const Qspi_Ip_SfdpTablesContainer *sfdpTables,
1028 Qspi_Ip_MemoryConfigType *pConfig
1029 );
1030
1031 static Qspi_Ip_StatusType Qspi_Ip_Sfdp444Switch_01(const Qspi_Ip_MemoryConfigType * pConfig);
1032 static Qspi_Ip_StatusType Qspi_Ip_Sfdp444Switch_04(const Qspi_Ip_MemoryConfigType * pConfig);
1033 static Qspi_Ip_StatusType Qspi_Ip_Sfdp444Switch_08(const Qspi_Ip_MemoryConfigType * pConfig);
1034 static Qspi_Ip_StatusType Qspi_Ip_Sfdp444Switch_16(const Qspi_Ip_MemoryConfigType * pConfig);
1035
1036 static Qspi_Ip_StatusType Qspi_Ip_Sfdp444Switch(const Qspi_Ip_SfdpTablesContainer *sfdpTables,
1037 const Qspi_Ip_MemoryConfigType *pConfig
1038 );
1039
1040 static void Qspi_Ip_SfdpGetBasicReadInfo(const Qspi_Ip_SfdpTablesContainer *sfdpTables,
1041 Qspi_Ip_MemoryConfigType *pConfig
1042 );
1043
1044 static void Qspi_Ip_SfdpGetBasicWriteInfo(const Qspi_Ip_SfdpTablesContainer *sfdpTables,
1045 Qspi_Ip_MemoryConfigType *pConfig
1046 );
1047
1048 static void Qspi_Ip_SfdpGetXspi1ReadInfo(const Qspi_Ip_SfdpTablesContainer *sfdpTables,
1049 Qspi_Ip_MemoryConfigType * pConfig
1050 );
1051
1052 static void Qspi_Ip_SfdpGetXspi1WriteInfo(const Qspi_Ip_SfdpTablesContainer *sfdpTables,
1053 Qspi_Ip_MemoryConfigType *pConfig
1054 );
1055
1056 static uint8 Qspi_Ip_SfdpGetBasicEraseInstr(const Qspi_Ip_SfdpTablesContainer *sfdpTables,
1057 uint8 cnt,
1058 uint8 *addrbits
1059 );
1060
1061 static uint8 Qspi_Ip_SfdpGetXspi1EraseInstr(const Qspi_Ip_SfdpTablesContainer *sfdpTables,
1062 uint8 cnt);
1063
1064 static void Qspi_Ip_SfdpGetBasicEraseInfo(const Qspi_Ip_SfdpTablesContainer *sfdpTables,
1065 Qspi_Ip_MemoryConfigType *pConfig
1066 );
1067
1068 static void Qspi_Ip_SfdpGetXspi1EraseInfo(const Qspi_Ip_SfdpTablesContainer *sfdpTables,
1069 Qspi_Ip_MemoryConfigType *pConfig
1070 );
1071
1072 static void Qspi_Ip_SfdpConfigureInitReadStatus(const Qspi_Ip_SfdpTablesContainer *sfdpTables,
1073 Qspi_Ip_MemoryConfigType *pConfig,
1074 uint8 instruction
1075 );
1076
1077 static void Qspi_Ip_SfdpGetBasicStatusInfo(const Qspi_Ip_SfdpTablesContainer *sfdpTables,
1078 Qspi_Ip_MemoryConfigType *pConfig
1079 );
1080
1081 static void Qspi_Ip_SfdpGetXspi1StatusInfo(const Qspi_Ip_SfdpTablesContainer *sfdpTables,
1082 Qspi_Ip_MemoryConfigType *pConfig
1083 );
1084
1085 static void Qspi_Ip_SfdpConfigReset1(const Qspi_Ip_MemoryConfigType *pConfig,
1086 const Qspi_Ip_ResetConfigType *resetSettings,
1087 Qspi_Ip_LutPadsType pads
1088 );
1089
1090 static void Qspi_Ip_SfdpConfigReset2(const Qspi_Ip_MemoryConfigType *pConfig,
1091 const Qspi_Ip_ResetConfigType *resetSettings,
1092 Qspi_Ip_LutPadsType pads
1093 );
1094
1095 static void Qspi_Ip_SfdpConfigReset4(const Qspi_Ip_MemoryConfigType *pConfig,
1096 const Qspi_Ip_ResetConfigType *resetSettings,
1097 Qspi_Ip_LutPadsType pads
1098 );
1099
1100 static void Qspi_Ip_SfdpConfigReset8(const Qspi_Ip_MemoryConfigType *pConfig,
1101 Qspi_Ip_ResetConfigType *resetSettings,
1102 Qspi_Ip_LutPadsType pads
1103 );
1104
1105 static void Qspi_Ip_SfdpConfigReset16(const Qspi_Ip_MemoryConfigType *pConfig,
1106 Qspi_Ip_ResetConfigType *resetSettings,
1107 Qspi_Ip_LutPadsType pads
1108 );
1109
1110 static void Qspi_Ip_SfdpConfigResetOthers(uint8 resetOption,
1111 const Qspi_Ip_MemoryConfigType * pConfig,
1112 Qspi_Ip_ResetConfigType *resetSettings,
1113 Qspi_Ip_LutPadsType pads
1114 );
1115
1116 static void Qspi_Ip_SfdpGetBasicResetInfo(const Qspi_Ip_SfdpTablesContainer *sfdpTables,
1117 const Qspi_Ip_MemoryConfigType *pConfig,
1118 Qspi_Ip_ResetConfigType *resetSettings,
1119 Qspi_Ip_LutPadsType pads
1120 );
1121
1122 static void Qspi_Ip_SfdpGetXspi1ResetInfo(const Qspi_Ip_SfdpTablesContainer *sfdpTables,
1123 Qspi_Ip_MemoryConfigType *pConfig
1124 );
1125
1126 static void Qspi_Ip_SfdpGetXspi1InitResetInfo(const Qspi_Ip_SfdpTablesContainer *sfdpTables,
1127 Qspi_Ip_MemoryConfigType *pConfig
1128 );
1129
1130 static void Qspi_Ip_SfdpGetBasicSuspendInfo(const Qspi_Ip_SfdpTablesContainer *sfdpTables,
1131 Qspi_Ip_MemoryConfigType *pConfig
1132 );
1133
1134 static void Qspi_Ip_SfdpGetXspi1SuspendInfo(const Qspi_Ip_SfdpTablesContainer *sfdpTables,
1135 Qspi_Ip_MemoryConfigType *pConfig
1136 );
1137
1138 static void Qspi_Ip_SfdpAdd2dopiOperation(const Qspi_Ip_MemoryConfigType *pConfig,
1139 uint8 seqSize,
1140 const uint32 *words
1141 );
1142
1143 static void Qspi_Ip_SfdpAddCheckBusyOperation(const Qspi_Ip_MemoryConfigType *pConfig);
1144
1145 static void Qspi_Ip_SfdpGetXspi1InitOpInfo(const Qspi_Ip_SfdpTablesContainer *sfdpTables,
1146 Qspi_Ip_MemoryConfigType *pConfig
1147 );
1148
1149 static void Qspi_Ip_SfdpGetBasicInitOpInfo(Qspi_Ip_MemoryConfigType *pConfig);
1150
1151 static void Qspi_Ip_SfdpGet0xxInfo(const Qspi_Ip_SfdpTablesContainer *sfdpTables,
1152 Qspi_Ip_MemoryConfigType *pConfig
1153 );
1154
1155 static void Qspi_Ip_SfdpConfigureOther(Qspi_Ip_MemoryConfigType *pConfig);
1156
1157 static void Qspi_Ip_SfdpGetSize(const Qspi_Ip_SfdpTablesContainer *sfdpTables,
1158 Qspi_Ip_MemoryConfigType *pConfig
1159 );
1160
1161 static Qspi_Ip_StatusType Qspi_Ip_ConfigureBasic(const Qspi_Ip_SfdpTablesContainer *sfdpTables,
1162 Qspi_Ip_MemoryConfigType *pConfig
1163 );
1164
1165 static Qspi_Ip_StatusType Qspi_Ip_ConfigureXspi1(const Qspi_Ip_SfdpTablesContainer *sfdpTables,
1166 Qspi_Ip_MemoryConfigType *pConfig
1167 );
1168
1169 static inline void Qspi_Ip_SfdpGetBasicInfo(const Qspi_Ip_SfdpTablesContainer *sfdpTables,
1170 Qspi_Ip_MemoryConfigType *pConfig
1171 );
1172
1173 static inline void Qspi_Ip_SfdpGetXspi1Info(const Qspi_Ip_SfdpTablesContainer *sfdpTables,
1174 Qspi_Ip_MemoryConfigType *pConfig
1175 );
1176
1177 #define MEM_43_EXFLS_STOP_SEC_CODE
1178 #include "Mem_43_EXFLS_MemMap.h"
1179
1180
1181 /*******************************************************************************
1182 * Private Functions
1183 ******************************************************************************/
1184
1185 #define MEM_43_EXFLS_START_SEC_CODE
1186 #include "Mem_43_EXFLS_MemMap.h"
1187
1188
1189 /*FUNCTION**********************************************************************
1190 *
1191 * Function Name : Qspi_Ip_PackLut
1192 * Description : Packs command, pads count and operand in a LUT entry
1193 */
Qspi_Ip_PackLut(Qspi_Ip_LutCommandsType cmd,Qspi_Ip_LutPadsType pad,uint8 op)1194 static inline Qspi_Ip_InstrOpType Qspi_Ip_PackLut(Qspi_Ip_LutCommandsType cmd,
1195 Qspi_Ip_LutPadsType pad,
1196 uint8 op
1197 )
1198 {
1199 return (Qspi_Ip_InstrOpType)((Qspi_Ip_InstrOpType)cmd | (Qspi_Ip_InstrOpType)pad | (Qspi_Ip_InstrOpType)op);
1200 }
1201
1202
1203 /*FUNCTION**********************************************************************
1204 *
1205 * Function Name : Qspi_Ip_SfdpLutInit
1206 * Description : Initializes LUT and init operations counters
1207 */
Qspi_Ip_SfdpLutInit(void)1208 static inline void Qspi_Ip_SfdpLutInit(void)
1209 {
1210 lutCount = 0U;
1211 initOpCount = 0U;
1212 overflow = FALSE;
1213 quadAvailable = TRUE;
1214 }
1215
1216
1217 /*FUNCTION**********************************************************************
1218 *
1219 * Function Name : Qspi_Ip_SfdpLutAdd
1220 * Description : Initializes LUT and init operations counters
1221 */
Qspi_Ip_SfdpLutAdd(const Qspi_Ip_LutConfigType * lutSequences,Qspi_Ip_InstrOpType instr)1222 static inline void Qspi_Ip_SfdpLutAdd(const Qspi_Ip_LutConfigType *lutSequences,
1223 Qspi_Ip_InstrOpType instr
1224 )
1225 {
1226 if (lutCount < lutSequences->opCount)
1227 {
1228 lutSequences->lutOps[lutCount] = instr;
1229 lutCount++;
1230 }
1231 else
1232 {
1233 overflow = TRUE;
1234 }
1235 }
1236
1237
1238 /*FUNCTION**********************************************************************
1239 *
1240 * Function Name : Qspi_Ip_SfdpGetBasicParam
1241 * Description : Returns a bitfield from the SFDP tables
1242 */
Qspi_Ip_SfdpGetBasicParam(const Qspi_Ip_SfdpTablesContainer * sfdpTables,uint8 dword,uint8 shift,uint8 width,uint32 defaultValue)1243 static inline uint32 Qspi_Ip_SfdpGetBasicParam(const Qspi_Ip_SfdpTablesContainer *sfdpTables,
1244 uint8 dword,
1245 uint8 shift,
1246 uint8 width,
1247 uint32 defaultValue
1248 )
1249 {
1250 const uint32* tablePtr = NULL_PTR;
1251 uint8 tableSize = 0U;
1252 volatile uint32 mask = 0UL;
1253 volatile uint32 result = 0UL;
1254
1255 tablePtr = sfdpTables->paramTable_basic;
1256 tableSize = sfdpTables->paramTableLength_basic;
1257
1258 if ((NULL_PTR != tablePtr) && (dword <= tableSize) )
1259 {
1260 /* get required field */
1261 mask = (1UL << (uint32)(width)) - 1UL;
1262 result = ((uint32)(tablePtr[dword - 1U] >> shift)) & mask;
1263 }
1264 else
1265 {
1266 /* table too short, use default */
1267 result = defaultValue;
1268 }
1269
1270 return result;
1271 }
1272
1273 /*FUNCTION**********************************************************************
1274 *
1275 * Function Name : Qspi_Ip_SfdpGet4BAddParam
1276 * Description : Returns a bitfield from the SFDP tables
1277 */
Qspi_Ip_SfdpGet4BAddParam(const Qspi_Ip_SfdpTablesContainer * sfdpTables,uint8 dword,uint8 shift,uint8 width,uint32 defaultValue)1278 static inline uint32 Qspi_Ip_SfdpGet4BAddParam(const Qspi_Ip_SfdpTablesContainer *sfdpTables,
1279 uint8 dword,
1280 uint8 shift,
1281 uint8 width,
1282 uint32 defaultValue
1283 )
1284 {
1285 const uint32* tablePtr = NULL_PTR;
1286 uint8 tableSize = 0U;
1287 volatile uint32 mask = 0UL;
1288 volatile uint32 result = 0UL;
1289
1290 tablePtr = sfdpTables->paramTable_4badd;
1291 tableSize = sfdpTables->paramTableLength_4badd;
1292
1293 if ((NULL_PTR != tablePtr) && (dword <= tableSize) )
1294 {
1295 /* get required field */
1296 mask = (1UL << (uint32)(width)) - 1UL;
1297 result = ((uint32)(tablePtr[dword - 1U] >> shift)) & mask;
1298 }
1299 else
1300 {
1301 /* table too short, use default */
1302 result = defaultValue;
1303 }
1304
1305 return result;
1306 }
1307
1308 /*FUNCTION**********************************************************************
1309 *
1310 * Function Name : Qspi_Ip_SfdpGetXspi1Param
1311 * Description : Returns a bitfield from the SFDP tables
1312 */
Qspi_Ip_SfdpGetXspi1Param(const Qspi_Ip_SfdpTablesContainer * sfdpTables,uint8 dword,uint8 shift,uint8 width,uint32 defaultValue)1313 static inline uint32 Qspi_Ip_SfdpGetXspi1Param(const Qspi_Ip_SfdpTablesContainer *sfdpTables,
1314 uint8 dword,
1315 uint8 shift,
1316 uint8 width,
1317 uint32 defaultValue
1318 )
1319 {
1320 const uint32* tablePtr = NULL_PTR;
1321 uint8 tableSize = 0U;
1322 volatile uint32 mask = 0UL;
1323 volatile uint32 result = 0UL;
1324
1325 tablePtr = sfdpTables->paramTable_xspi1;
1326 tableSize = sfdpTables->paramTableLength_xspi1;
1327
1328 if ((NULL_PTR != tablePtr) && (dword <= tableSize) )
1329 {
1330 /* get required field */
1331 mask = (1UL << (uint32)(width)) - 1UL;
1332 result = ((uint32)(tablePtr[dword - 1U] >> shift)) & mask;
1333 }
1334 else
1335 {
1336 /* table too short, use default */
1337 result = defaultValue;
1338 }
1339
1340 return result;
1341 }
1342
1343 /*FUNCTION**********************************************************************
1344 *
1345 * Function Name : Qspi_Ip_SfdpGetSRMapParam
1346 * Description : Returns a bitfield from the SFDP tables
1347 */
Qspi_Ip_SfdpGetSRMapParam(const Qspi_Ip_SfdpTablesContainer * sfdpTables,uint8 dword,uint8 shift,uint8 width,uint32 defaultValue)1348 static inline uint32 Qspi_Ip_SfdpGetSRMapParam(const Qspi_Ip_SfdpTablesContainer *sfdpTables,
1349 uint8 dword,
1350 uint8 shift,
1351 uint8 width,
1352 uint32 defaultValue
1353 )
1354 {
1355 const uint32* tablePtr = NULL_PTR;
1356 uint8 tableSize = 0U;
1357 volatile uint32 mask = 0UL;
1358 volatile uint32 result = 0UL;
1359
1360 tablePtr = sfdpTables->paramTable_srmap;
1361 tableSize = sfdpTables->paramTableLength_srmap;
1362
1363 if ((NULL_PTR != tablePtr) && (dword <= tableSize) )
1364 {
1365 /* get required field */
1366 mask = (1UL << (uint32)(width)) - 1UL;
1367 result = ((uint32)(tablePtr[dword - 1U] >> shift)) & mask;
1368 }
1369 else
1370 {
1371 /* table too short, use default */
1372 result = defaultValue;
1373 }
1374
1375 return result;
1376 }
1377
1378 /*FUNCTION**********************************************************************
1379 *
1380 * Function Name : Qspi_Ip_SfdpGet2DopiParam
1381 * Description : Returns a bitfield from the SFDP tables
1382 */
Qspi_Ip_SfdpGet2DopiParam(const Qspi_Ip_SfdpTablesContainer * sfdpTables,uint8 dword,uint8 shift,uint8 width,uint32 defaultValue)1383 static inline uint32 Qspi_Ip_SfdpGet2DopiParam(const Qspi_Ip_SfdpTablesContainer *sfdpTables,
1384 uint8 dword,
1385 uint8 shift,
1386 uint8 width,
1387 uint32 defaultValue
1388 )
1389 {
1390 const uint32* tablePtr = NULL_PTR;
1391 uint8 tableSize = 0U;
1392 volatile uint32 mask = 0UL;
1393 volatile uint32 result = 0UL;
1394
1395 tablePtr = sfdpTables->paramTable_2dopi;
1396 tableSize = sfdpTables->paramTableLength_2dopi;
1397
1398 if ((NULL_PTR != tablePtr) && (dword <= tableSize) )
1399 {
1400 /* get required field */
1401 mask = (1UL << (uint32)(width)) - 1UL;
1402 result = ((uint32)(tablePtr[dword - 1U] >> shift)) & mask;
1403 }
1404 else
1405 {
1406 /* table too short, use default */
1407 result = defaultValue;
1408 }
1409
1410 return result;
1411 }
1412
1413
1414 /*FUNCTION**********************************************************************
1415 *
1416 * Function Name : Qspi_Ip_SfdpLutAddSrAddr
1417 * Description : Initializes LUT and init operations counters
1418 */
Qspi_Ip_SfdpLutAddSrAddr(const Qspi_Ip_LutConfigType * lutSequences,const Qspi_Ip_SfdpTablesContainer * sfdpTables)1419 static void Qspi_Ip_SfdpLutAddSrAddr(const Qspi_Ip_LutConfigType *lutSequences,
1420 const Qspi_Ip_SfdpTablesContainer *sfdpTables
1421 )
1422 {
1423 uint32 addrOffset;
1424 uint8 srAddr;
1425 uint8 srShift;
1426 uint8 nBytes;
1427 sint8 cnt;
1428 uint8 directCmd;
1429
1430 /* SR read is direct command (not using address */
1431 directCmd = (uint8)Qspi_Ip_SfdpGetSRMapParam(sfdpTables, QSPI_IP_SFDP_SRMAP_USE_ADDR_DWORD,
1432 QSPI_IP_SFDP_SRMAP_USE_ADDR_SHIFT, QSPI_IP_SFDP_SRMAP_USE_ADDR_WIDTH, 0x0U);
1433 if (directCmd == 0U)
1434 {
1435 /* direct command - nothing to do */
1436 }
1437 else
1438 {
1439 /* Address offset for volatile registers */
1440 addrOffset = (uint32)Qspi_Ip_SfdpGetSRMapParam(sfdpTables, QSPI_IP_SFDP_SRMAP_OFFSET_DWORD,
1441 QSPI_IP_SFDP_SRMAP_OFFSET_SHIFT, QSPI_IP_SFDP_SRMAP_OFFSET_WIDTH, 0x0U);
1442 /* Number of address bytes used for Generic Addressable Read/Write Status/Control register commands for volatile registers */
1443 nBytes = (uint8)Qspi_Ip_SfdpGetSRMapParam(sfdpTables, QSPI_IP_SFDP_SRMAP_NBYTES_DWORD,
1444 QSPI_IP_SFDP_SRMAP_NBYTES_SHIFT, QSPI_IP_SFDP_SRMAP_NBYTES_WIDTH, 0x0U);
1445 /* SR local address */
1446 srAddr = (uint8)Qspi_Ip_SfdpGetSRMapParam(sfdpTables, QSPI_IP_SFDP_SRMAP_SR_ADDR_DWORD,
1447 QSPI_IP_SFDP_SRMAP_SR_ADDR_SHIFT, QSPI_IP_SFDP_SRMAP_SR_ADDR_WIDTH, 0x0U);
1448 /* SR address shift (before adding to the offset) */
1449 srShift = (uint8)Qspi_Ip_SfdpGetSRMapParam(sfdpTables, QSPI_IP_SFDP_SRMAP_SR_SHIFT_DWORD,
1450 QSPI_IP_SFDP_SRMAP_SR_SHIFT_SHIFT, QSPI_IP_SFDP_SRMAP_SR_SHIFT_WIDTH, 0x0U);
1451
1452 /* compute SR address */
1453 addrOffset = addrOffset + ((uint32)srAddr << (srShift * 8U));
1454 /* add address to LUT sequence. Use CMD in case addr is out of range */
1455 for (cnt = (sint8)nBytes; cnt >= 0; cnt--)
1456 {
1457 srAddr = (uint8)((addrOffset >> ((uint8)cnt * 8U)) & 0xFFU);
1458 Qspi_Ip_SfdpLutAdd(lutSequences, Qspi_Ip_PackLut(QSPI_IP_LUT_INSTR_CMD_DDR, QSPI_IP_LUT_PADS_8, srAddr));
1459 }
1460 }
1461
1462 return;
1463 }
1464
1465
1466 /*FUNCTION**********************************************************************
1467 *
1468 * Function Name : Qspi_Ip_SfdpSignatureCheck
1469 * Description : Checks SFDP signature
1470 */
Qspi_Ip_SfdpSignatureCheck(const uint8 * data)1471 static inline boolean Qspi_Ip_SfdpSignatureCheck(const uint8 *data)
1472 {
1473 boolean retCode = FALSE;
1474
1475 if ((data[0] == 0x53U) && (data[1] == 0x46U) && (data[2] == 0x44U) && (data[3] == 0x50U))
1476 {
1477 retCode = TRUE;
1478 }
1479
1480 return retCode;
1481 }
1482
1483
1484 /*FUNCTION**********************************************************************
1485 *
1486 * Function Name : Qspi_Ip_SfdpInitLut
1487 * Description : Initializes LUT table for reading SFDP information, using the specified format
1488 */
Qspi_Ip_SfdpInitLut(uint32 instance,Qspi_Ip_SfdpModes mode)1489 static inline void Qspi_Ip_SfdpInitLut(uint32 instance,
1490 Qspi_Ip_SfdpModes mode
1491 )
1492 {
1493 Qspi_Ip_LutCommandsType instCmd;
1494 Qspi_Ip_LutCommandsType addrCmd;
1495 Qspi_Ip_LutCommandsType dataCmd;
1496 Qspi_Ip_LutPadsType pads;
1497 uint32 lutData[3U]; /* Data to be written to the physical LUTs */
1498
1499 /* Set command parameters according to mode */
1500 instCmd = QSPI_IP_LUT_INSTR_CMD;
1501 addrCmd = QSPI_IP_LUT_INSTR_ADDR;
1502 dataCmd = QSPI_IP_LUT_INSTR_READ;
1503 if (QSPI_IP_SFDP_8D_8D_8D == mode)
1504 {
1505 pads = QSPI_IP_LUT_PADS_8;
1506 instCmd = QSPI_IP_LUT_INSTR_CMD_DDR;
1507 addrCmd = QSPI_IP_LUT_INSTR_ADDR_DDR;
1508 dataCmd = QSPI_IP_LUT_INSTR_READ_DDR;
1509 }
1510 else if (QSPI_IP_SFDP_4S_4D_4D == mode)
1511 {
1512 pads = QSPI_IP_LUT_PADS_4;
1513 addrCmd = QSPI_IP_LUT_INSTR_ADDR_DDR;
1514 dataCmd = QSPI_IP_LUT_INSTR_READ_DDR;
1515 }
1516 else if (QSPI_IP_SFDP_4S_4S_4S == mode)
1517 {
1518 pads = QSPI_IP_LUT_PADS_4;
1519 }
1520 else if (QSPI_IP_SFDP_2S_2S_2S == mode)
1521 {
1522 pads = QSPI_IP_LUT_PADS_2;
1523 }
1524 else
1525 {
1526 pads = QSPI_IP_LUT_PADS_1;
1527 }
1528
1529 /* Build SFDP Read Sequence */
1530 lutData[0] = QSPI_IP_PACK_LUT_REG(Qspi_Ip_PackLut(instCmd, pads, QSPI_IP_CMD_SFDP_READ), /* READ SFDP command on 1 data line */
1531 Qspi_Ip_PackLut(addrCmd, pads, 24U)); /* 24-bit address on 1 data line */
1532
1533 lutData[1] = QSPI_IP_PACK_LUT_REG(Qspi_Ip_PackLut(QSPI_IP_LUT_INSTR_DUMMY, pads, 8U), /* 8 Dummy cycles */
1534 Qspi_Ip_PackLut(dataCmd, pads, 0x10U)); /* Read data on "pads" data lines */
1535
1536 lutData[2] = QSPI_IP_PACK_LUT_REG(QSPI_IP_LUT_SEQ_END, QSPI_IP_LUT_SEQ_END); /* End of sequence */
1537
1538 /* Write the SFDP Read Sequence into physical LUT registers */
1539 Qspi_Ip_WriteLuts(instance, QSPI_IP_COMMAND_LUT * FEATURE_QSPI_LUT_SEQUENCE_SIZE, lutData, 3U);
1540 }
1541
1542
1543 /*FUNCTION**********************************************************************
1544 *
1545 * Function Name : Qspi_Ip_WaitAfterReset
1546 * Description : Wait until external memory is available for operation after a reset
1547 */
Qspi_Ip_WaitAfterReset(void)1548 static void Qspi_Ip_WaitAfterReset(void)
1549 {
1550 uint32 u32ElapsedTicks = 0U;
1551 uint32 u32TimeoutTicks;
1552 uint32 u32CurrentTicks;
1553
1554 /* Prepare timeout counter */
1555 u32TimeoutTicks = OsIf_MicrosToTicks(QSPI_IP_RESET_TIMEOUT, (OsIf_CounterType)QSPI_IP_TIMEOUT_TYPE);
1556 u32CurrentTicks = OsIf_GetCounter((OsIf_CounterType)QSPI_IP_TIMEOUT_TYPE);
1557 /* Wait for the specified time */
1558 do
1559 {
1560 u32ElapsedTicks += OsIf_GetElapsed(&u32CurrentTicks, (OsIf_CounterType)QSPI_IP_TIMEOUT_TYPE);
1561 }
1562 while (u32ElapsedTicks < u32TimeoutTicks);
1563 }
1564
1565
1566 /*FUNCTION**********************************************************************
1567 *
1568 * Function Name : Qspi_Ip_SfdpInitReset_4S4S4S
1569 * Description : Sends 4S-4S-4S reset commands to force device to exit the QPI mode.
1570 */
Qspi_Ip_SfdpInitReset_4S4S4S(uint32 instance,uint32 baseAddress)1571 static void Qspi_Ip_SfdpInitReset_4S4S4S(uint32 instance,
1572 uint32 baseAddress
1573 )
1574 {
1575 /* Data to be written to the physical LUTs */
1576 uint32 lutData;
1577
1578 const uint8 lutRegister = QSPI_IP_COMMAND_LUT * FEATURE_QSPI_LUT_SEQUENCE_SIZE;
1579
1580 const Qspi_Ip_LutCommandsType cmd = QSPI_IP_LUT_INSTR_CMD;
1581 const Qspi_Ip_LutPadsType pad = QSPI_IP_LUT_PADS_4;
1582
1583 /* Send Reset Enable Command */
1584 lutData = QSPI_IP_PACK_LUT_REG(Qspi_Ip_PackLut(cmd, pad, (uint8)QSPI_IP_CMD_XSPI_RESET_ENABLE),
1585 QSPI_IP_LUT_SEQ_END);
1586 Qspi_Ip_WriteLuts(instance, lutRegister, &lutData, 1U);
1587 (void)Qspi_Ip_IpCommand(instance, QSPI_IP_COMMAND_LUT, baseAddress);
1588
1589 /* Send Reset Command */
1590 lutData = QSPI_IP_PACK_LUT_REG(Qspi_Ip_PackLut(cmd, pad, (uint8)QSPI_IP_CMD_XSPI_RESET_DEF),
1591 QSPI_IP_LUT_SEQ_END);
1592 Qspi_Ip_WriteLuts(instance, lutRegister, &lutData, 1U);
1593 (void)Qspi_Ip_IpCommand(instance, QSPI_IP_COMMAND_LUT, baseAddress);
1594
1595 /* Wait for reset to complete */
1596 Qspi_Ip_WaitAfterReset();
1597 }
1598
1599
1600 /*FUNCTION**********************************************************************
1601 *
1602 * Function Name : Qspi_Ip_SfdpExitQPI
1603 * Description : Attempt to exit the memory device from QPI (4-4-4) mode.
1604 */
Qspi_Ip_SfdpExitQPI(uint32 instance,uint32 baseAddress)1605 static void Qspi_Ip_SfdpExitQPI(uint32 instance,
1606 uint32 baseAddress
1607 )
1608 {
1609 /* Workaround: send 4S-4S-4S reset command */
1610 Qspi_Ip_SfdpInitReset_4S4S4S(instance, baseAddress);
1611 }
1612
1613
1614
1615 /*FUNCTION**********************************************************************
1616 *
1617 * Function Name : Qspi_Ip_SfdpInitReset_8D8D8D
1618 * Description : Sends 8D-8D-8D reset commands to force device to enter SPI mode.
1619 */
Qspi_Ip_SfdpInitReset_8D8D8D(uint32 instance,uint32 baseAddress)1620 static void Qspi_Ip_SfdpInitReset_8D8D8D(uint32 instance,
1621 uint32 baseAddress
1622 )
1623 {
1624 /* Data to be written to the physical LUTs */
1625 uint32 lutData[2U] =
1626 {
1627 QSPI_IP_PACK_LUT_REG(QSPI_IP_LUT_SEQ_END, QSPI_IP_LUT_SEQ_END),
1628 QSPI_IP_PACK_LUT_REG(QSPI_IP_LUT_SEQ_END, QSPI_IP_LUT_SEQ_END)
1629 };
1630
1631 const uint8 lutRegister = QSPI_IP_COMMAND_LUT * FEATURE_QSPI_LUT_SEQUENCE_SIZE;
1632
1633 const Qspi_Ip_LutCommandsType cmd = QSPI_IP_LUT_INSTR_CMD_DDR;
1634 const Qspi_Ip_LutPadsType pad = QSPI_IP_LUT_PADS_8;
1635
1636 /* As we don't know yet the command extension convention of the device, try both ways */
1637 /* 1. Command Extension is the inverse of the Command */
1638 /* Send Reset Enable Command */
1639 lutData[0] = QSPI_IP_PACK_LUT_REG(Qspi_Ip_PackLut(cmd, pad, (uint8)QSPI_IP_CMD_XSPI_RESET_ENABLE), /* Reset Enable command in DOPI Mode */
1640 Qspi_Ip_PackLut(cmd, pad, (uint8)~QSPI_IP_CMD_XSPI_RESET_ENABLE)); /* command extension */
1641 Qspi_Ip_WriteLuts(instance, lutRegister, lutData, 2U);
1642 (void)Qspi_Ip_IpCommand(instance, QSPI_IP_COMMAND_LUT, baseAddress);
1643
1644 /* Send Reset Command */
1645 lutData[0] = QSPI_IP_PACK_LUT_REG(Qspi_Ip_PackLut(cmd, pad, (uint8)QSPI_IP_CMD_XSPI_RESET_DEF), /* Reset command in DOPI Mode */
1646 Qspi_Ip_PackLut(cmd, pad, (uint8)~QSPI_IP_CMD_XSPI_RESET_DEF)); /* command extension */
1647 Qspi_Ip_WriteLuts(instance, lutRegister, lutData, 2U);
1648 (void)Qspi_Ip_IpCommand(instance, QSPI_IP_COMMAND_LUT, baseAddress);
1649
1650 /* 2. Command Extension is the same as the Command */
1651 /* Send Reset Enable Command */
1652 lutData[0] = QSPI_IP_PACK_LUT_REG(Qspi_Ip_PackLut(cmd, pad, (uint8)QSPI_IP_CMD_XSPI_RESET_ENABLE), /* Reset Enable command in DOPI Mode */
1653 Qspi_Ip_PackLut(cmd, pad, (uint8)QSPI_IP_CMD_XSPI_RESET_ENABLE)); /* command extension */
1654 Qspi_Ip_WriteLuts(instance, lutRegister, lutData, 2U);
1655 (void)Qspi_Ip_IpCommand(instance, QSPI_IP_COMMAND_LUT, baseAddress);
1656
1657 /* Send Reset Command */
1658 lutData[0] = QSPI_IP_PACK_LUT_REG(Qspi_Ip_PackLut(cmd, pad, (uint8)QSPI_IP_CMD_XSPI_RESET_DEF), /* Reset command in DOPI Mode */
1659 Qspi_Ip_PackLut(cmd, pad, (uint8)QSPI_IP_CMD_XSPI_RESET_DEF)); /* command extension */
1660 Qspi_Ip_WriteLuts(instance, lutRegister, lutData, 2U);
1661 (void)Qspi_Ip_IpCommand(instance, QSPI_IP_COMMAND_LUT, baseAddress);
1662
1663 /* Wait for reset to complete */
1664 Qspi_Ip_WaitAfterReset();
1665 }
1666
1667
1668 /*FUNCTION**********************************************************************
1669 *
1670 * Function Name : Qspi_Ip_SfdpPackLutEnterLegacySPI
1671 * Description : Pack the Enter Default Protocol Mode command is a sequence of three Write Register Linear commands.
1672 */
Qspi_Ip_SfdpPackLutEnterLegacySPI(uint32 sequenceIndex,uint32 * lutData)1673 static void Qspi_Ip_SfdpPackLutEnterLegacySPI(uint32 sequenceIndex, uint32 *lutData)
1674 {
1675 /* - Hyperbus Write Transaction: 6-byte Command/Address + 2-byte Data
1676 - The address is split into 2 parts: half-page address and word address
1677 - With DDR timing, using four clock cycles (eight clock edges) to send 8-byte
1678
1679 ____ Address=555h, Data=00AAh ___
1680 CS# \_______________________________/
1681
1682 ___ ___ ___ ___
1683 CK ______/ 1 \___/ 2 \___/ 3 \___/ 4 \_____
1684
1685 __ __ __ __ __ __ __ __
1686 DQ[7-0] ____/00\/00\/00\/AA\/00\/05\/00\/AA\____
1687 \__/\__/\__/\__/\__/\__/\__/\__/
1688 */
1689
1690 if (0U == sequenceIndex)
1691 {
1692 /* First command: Write Register Linear with Address=555h, Data=00AAh */
1693 lutData[0] = QSPI_IP_PACK_LUT_REG(Qspi_Ip_PackLut(QSPI_IP_LUT_INSTR_CMD_DDR, QSPI_IP_LUT_PADS_8, 0x00U),
1694 Qspi_Ip_PackLut(QSPI_IP_LUT_INSTR_CMD_DDR, QSPI_IP_LUT_PADS_8, 0x00U));
1695
1696 lutData[1] = QSPI_IP_PACK_LUT_REG(Qspi_Ip_PackLut(QSPI_IP_LUT_INSTR_CMD_DDR, QSPI_IP_LUT_PADS_8, 0x00U),
1697 Qspi_Ip_PackLut(QSPI_IP_LUT_INSTR_CMD_DDR, QSPI_IP_LUT_PADS_8, 0xAAU));
1698
1699 lutData[2] = QSPI_IP_PACK_LUT_REG(Qspi_Ip_PackLut(QSPI_IP_LUT_INSTR_CMD_DDR, QSPI_IP_LUT_PADS_8, 0x00U),
1700 Qspi_Ip_PackLut(QSPI_IP_LUT_INSTR_CMD_DDR, QSPI_IP_LUT_PADS_8, 0x05U));
1701
1702 lutData[3] = QSPI_IP_PACK_LUT_REG(Qspi_Ip_PackLut(QSPI_IP_LUT_INSTR_CMD_DDR, QSPI_IP_LUT_PADS_8, 0x00U),
1703 Qspi_Ip_PackLut(QSPI_IP_LUT_INSTR_CMD_DDR, QSPI_IP_LUT_PADS_8, 0xAAU));
1704 }
1705 else if (1U == sequenceIndex)
1706 {
1707 /* Second command: Write Register Linear with Address=2AAh, Data=0055h */
1708 lutData[0] = QSPI_IP_PACK_LUT_REG(Qspi_Ip_PackLut(QSPI_IP_LUT_INSTR_CMD_DDR, QSPI_IP_LUT_PADS_8, 0x00U),
1709 Qspi_Ip_PackLut(QSPI_IP_LUT_INSTR_CMD_DDR, QSPI_IP_LUT_PADS_8, 0x00U));
1710
1711 lutData[1] = QSPI_IP_PACK_LUT_REG(Qspi_Ip_PackLut(QSPI_IP_LUT_INSTR_CMD_DDR, QSPI_IP_LUT_PADS_8, 0x00U),
1712 Qspi_Ip_PackLut(QSPI_IP_LUT_INSTR_CMD_DDR, QSPI_IP_LUT_PADS_8, 0x55U));
1713
1714 lutData[2] = QSPI_IP_PACK_LUT_REG(Qspi_Ip_PackLut(QSPI_IP_LUT_INSTR_CMD_DDR, QSPI_IP_LUT_PADS_8, 0x00U),
1715 Qspi_Ip_PackLut(QSPI_IP_LUT_INSTR_CMD_DDR, QSPI_IP_LUT_PADS_8, 0x02U));
1716
1717 lutData[3] = QSPI_IP_PACK_LUT_REG(Qspi_Ip_PackLut(QSPI_IP_LUT_INSTR_CMD_DDR, QSPI_IP_LUT_PADS_8, 0x00U),
1718 Qspi_Ip_PackLut(QSPI_IP_LUT_INSTR_CMD_DDR, QSPI_IP_LUT_PADS_8, 0x55U));
1719 }
1720 else /* sequenceIndex is 2U */
1721 {
1722 /* Third command: Write Register Linear with Address=555h, Data=00F5h */
1723 lutData[0] = QSPI_IP_PACK_LUT_REG(Qspi_Ip_PackLut(QSPI_IP_LUT_INSTR_CMD_DDR, QSPI_IP_LUT_PADS_8, 0x00U),
1724 Qspi_Ip_PackLut(QSPI_IP_LUT_INSTR_CMD_DDR, QSPI_IP_LUT_PADS_8, 0x00U));
1725
1726 lutData[1] = QSPI_IP_PACK_LUT_REG(Qspi_Ip_PackLut(QSPI_IP_LUT_INSTR_CMD_DDR, QSPI_IP_LUT_PADS_8, 0x00U),
1727 Qspi_Ip_PackLut(QSPI_IP_LUT_INSTR_CMD_DDR, QSPI_IP_LUT_PADS_8, 0xAAU));
1728
1729 lutData[2] = QSPI_IP_PACK_LUT_REG(Qspi_Ip_PackLut(QSPI_IP_LUT_INSTR_CMD_DDR, QSPI_IP_LUT_PADS_8, 0x00U),
1730 Qspi_Ip_PackLut(QSPI_IP_LUT_INSTR_CMD_DDR, QSPI_IP_LUT_PADS_8, 0x05U));
1731
1732 lutData[3] = QSPI_IP_PACK_LUT_REG(Qspi_Ip_PackLut(QSPI_IP_LUT_INSTR_CMD_DDR, QSPI_IP_LUT_PADS_8, 0x00U),
1733 Qspi_Ip_PackLut(QSPI_IP_LUT_INSTR_CMD_DDR, QSPI_IP_LUT_PADS_8, 0xF5U));
1734 }
1735 }
1736
1737
1738 /*FUNCTION**********************************************************************
1739 *
1740 * Function Name : Qspi_Ip_SfdpLutInitEnterLegacySPI
1741 * Description : Builds the enter XPI protocol initial operations (needed for devices booting-up in Hyperbus mode)
1742 */
Qspi_Ip_SfdpLutInitEnterLegacySPI(Qspi_Ip_MemoryConfigType const * pConfig)1743 static void Qspi_Ip_SfdpLutInitEnterLegacySPI(Qspi_Ip_MemoryConfigType const *pConfig)
1744 {
1745 Qspi_Ip_InitOperationType *operation;
1746 uint32 lutData[4U]; /* Data to be written to the physical LUTs */
1747 uint32 sequenceIndex;
1748
1749 /* Only needed for devices do not boot in legacy XPI mode */
1750 if ((boolean)FALSE == bootModeLegacyXPI)
1751 {
1752 for (sequenceIndex = 0U; sequenceIndex < 3U; sequenceIndex++)
1753 {
1754 operation = &(pConfig->initConfiguration.operations[initOpCount]);
1755 initOpCount++;
1756
1757 /* Build operation */
1758 operation->opType = QSPI_IP_OP_TYPE_CMD;
1759 operation->command1Lut = lutCount;
1760 operation->addr = 0U;
1761
1762 /* Pack the command sequence */
1763 Qspi_Ip_SfdpPackLutEnterLegacySPI(sequenceIndex, lutData);
1764
1765 /* Build LUT sequence (copy into the virtual LUT table of the configuration) */
1766 Qspi_Ip_SfdpLutAdd(&(pConfig->lutSequences), (uint16)(lutData[0] >> 0U));
1767 Qspi_Ip_SfdpLutAdd(&(pConfig->lutSequences), (uint16)(lutData[0] >> 16U));
1768 Qspi_Ip_SfdpLutAdd(&(pConfig->lutSequences), (uint16)(lutData[1] >> 0U));
1769 Qspi_Ip_SfdpLutAdd(&(pConfig->lutSequences), (uint16)(lutData[1] >> 16U));
1770 Qspi_Ip_SfdpLutAdd(&(pConfig->lutSequences), (uint16)(lutData[2] >> 0U));
1771 Qspi_Ip_SfdpLutAdd(&(pConfig->lutSequences), (uint16)(lutData[2] >> 16U));
1772 Qspi_Ip_SfdpLutAdd(&(pConfig->lutSequences), (uint16)(lutData[3] >> 0U));
1773 Qspi_Ip_SfdpLutAdd(&(pConfig->lutSequences), (uint16)(lutData[3] >> 16U));
1774 Qspi_Ip_SfdpLutAdd(&(pConfig->lutSequences), QSPI_IP_LUT_SEQ_END); /* End of sequence */
1775
1776 /* Other operation fields are unused */
1777 operation->command2Lut = QSPI_IP_LUT_INVALID;
1778 operation->weLut = QSPI_IP_LUT_INVALID;
1779 operation->size = 0U;
1780 operation->shift = 0U;
1781 operation->width = 0U;
1782 operation->value = 0U;
1783 operation->ctrlCfgPtr = NULL_PTR;
1784 }
1785 }
1786 }
1787
1788
1789 /*FUNCTION**********************************************************************
1790 *
1791 * Function Name : Qspi_Ip_SfdpEnterLegacySPI
1792 * Description : The Enter Default Protocol Mode command is a sequence of three Write Register Linear commands.
1793 */
Qspi_Ip_SfdpEnterLegacySPI(uint32 instance,uint32 baseAddress)1794 static void Qspi_Ip_SfdpEnterLegacySPI(uint32 instance,
1795 uint32 baseAddress
1796 )
1797 {
1798 uint32 sequenceIndex;
1799 uint32 lutData[5U]; /* Data to be written to the physical LUTs */
1800 lutData[4] = QSPI_IP_PACK_LUT_REG(QSPI_IP_LUT_SEQ_END, QSPI_IP_LUT_SEQ_END); /* End of sequence */
1801
1802 const uint8 lutRegister = QSPI_IP_COMMAND_LUT * FEATURE_QSPI_LUT_SEQUENCE_SIZE;
1803
1804 /* We need 5 LUT registers: 4 for the command sequence, plus 1 for the end of sequence.
1805 - For platforms that have 4 LUT registers that make up a LUT sequence:
1806 only the first 4 LUT registers will be written to avoid overwriting the next sequence
1807
1808 - For platforms that have 5 LUT registers that make up a LUT sequence:
1809 all 5 LUT registers will be written
1810
1811 Because: The instructions are executed sequentially until the last instruction or the STOP instruction is encountered.
1812
1813 Note:
1814 - This will not work if FEATURE_QSPI_LUT_SEQUENCE_SIZE is less than 4
1815 - In that case, QSPI_IP_LUT_INSTR_WRITE_DDR must be used (data will be placed in the TBDR to save the number of LUTs)
1816 */
1817 uint8 lutSize = 5U;
1818
1819 #if (FEATURE_QSPI_LUT_SEQUENCE_SIZE == 4)
1820 lutSize = 4U;
1821 #elif (FEATURE_QSPI_LUT_SEQUENCE_SIZE < 4)
1822 /* Note for future platforms */
1823 #error LUT sequence is not big enough.
1824 #endif
1825
1826 /* Issue the three command sequences */
1827 for (sequenceIndex = 0U; sequenceIndex < 3U; sequenceIndex++)
1828 {
1829 Qspi_Ip_SfdpPackLutEnterLegacySPI(sequenceIndex, lutData); /* Pack the command sequence */
1830 Qspi_Ip_WriteLuts(instance, lutRegister, lutData, lutSize); /* Write them to physical hardware LUT registers */
1831 (void)Qspi_Ip_IpCommand(instance, QSPI_IP_COMMAND_LUT, baseAddress); /* Issue the command sequence */
1832 }
1833 }
1834
1835
1836 /*FUNCTION**********************************************************************
1837 *
1838 * Function Name : Qspi_Ip_SfdpExitDOPI
1839 * Description : Attempt to exit the memory device from DTR-Octal (8D-8D-8D) mode.
1840 */
Qspi_Ip_SfdpExitDOPI(uint32 instance,uint32 baseAddress)1841 static void Qspi_Ip_SfdpExitDOPI(uint32 instance,
1842 uint32 baseAddress
1843 )
1844 {
1845 /* Workaround 1: send 8D-8D-8D reset commands as specified by xSPI Profile 1.0 */
1846 Qspi_Ip_SfdpInitReset_8D8D8D(instance, baseAddress);
1847
1848 /* Workaround 2: send Enter Default Protocol Mode command sequence (1S-1S-1S) as specified by xSPI Profile 2.0 */
1849 Qspi_Ip_SfdpEnterLegacySPI(instance, baseAddress);
1850 }
1851
1852
1853 /*FUNCTION**********************************************************************
1854 *
1855 * Function Name : Qspi_Ip_SfdpInitReset
1856 * Description : Sends reset commands to force device to enter SPI mode.
1857 */
Qspi_Ip_SfdpInitReset(uint32 instance,uint32 baseAddress)1858 static void Qspi_Ip_SfdpInitReset(uint32 instance,
1859 uint32 baseAddress
1860 )
1861 {
1862 /* Attempt to read SFDP in DOPI mode */
1863 Qspi_Ip_SfdpExitDOPI(instance, baseAddress);
1864
1865 /* Attempt to read SFDP in QPI mode */
1866 Qspi_Ip_SfdpExitQPI(instance, baseAddress);
1867 }
1868
1869 /*FUNCTION**********************************************************************
1870 *
1871 * Function Name : Qspi_Ip_SfdpFindWorkingMode
1872 * Description : Tries each mode to find the mode in which the flash device is working.
1873 */
Qspi_Ip_SfdpFindWorkingMode(uint32 instance,uint32 baseAddress)1874 static Qspi_Ip_StatusType Qspi_Ip_SfdpFindWorkingMode(uint32 instance,
1875 uint32 baseAddress
1876 )
1877 {
1878 /* List of sfdp modes attempt to read and the corresponding pad return values */
1879 const Qspi_Ip_SfdpModes modes[4U] = {QSPI_IP_SFDP_4S_4D_4D, QSPI_IP_SFDP_4S_4S_4S, QSPI_IP_SFDP_2S_2S_2S, QSPI_IP_SFDP_1S_1S_1S};
1880 const Qspi_Ip_LutPadsType pads[4U] = {QSPI_IP_LUT_PADS_4, QSPI_IP_LUT_PADS_4, QSPI_IP_LUT_PADS_2, QSPI_IP_LUT_PADS_1 };
1881 const uint32 maxAttempts = 4U;
1882 Qspi_Ip_StatusType status;
1883 uint8 data[4U];
1884 uint32 idx;
1885
1886 /* Attempt to read SFDP modes */
1887 for (idx = 0U; idx < maxAttempts; idx++)
1888 {
1889 Qspi_Ip_SfdpInitLut(instance, modes[idx]);
1890 status = Qspi_Ip_IpRead(instance, QSPI_IP_COMMAND_LUT, baseAddress, data, NULL_PTR, 4U);
1891 if ((STATUS_QSPI_IP_SUCCESS == status) && Qspi_Ip_SfdpSignatureCheck(data))
1892 {
1893 /* Found a supported mode */
1894 cmdPadsInit = pads[idx];
1895 break;
1896 }
1897 }
1898
1899 /* All read attempts failed, device does not support SFDP */
1900 if (idx >= maxAttempts)
1901 {
1902 status = STATUS_QSPI_IP_ERROR;
1903 }
1904
1905 return status;
1906 }
1907
1908
1909 /*FUNCTION**********************************************************************
1910 *
1911 * Function Name : Qspi_Ip_SfdpCheck
1912 * Description : Checks the existence of SFDP support.
1913 */
Qspi_Ip_SfdpCheck(uint32 instance,uint32 baseAddress)1914 static Qspi_Ip_StatusType Qspi_Ip_SfdpCheck(uint32 instance,
1915 uint32 baseAddress
1916 )
1917 {
1918 Qspi_Ip_StatusType status;
1919
1920 /* First attempt to check if SFDP is supported or not */
1921 status = Qspi_Ip_SfdpFindWorkingMode(instance, baseAddress);
1922 if (STATUS_QSPI_IP_SUCCESS != status)
1923 {
1924 /* The first check has failed, try to issue reset commands in various modes */
1925 Qspi_Ip_SfdpInitReset(instance, baseAddress);
1926 /* Then try for the second attempt */
1927 status = Qspi_Ip_SfdpFindWorkingMode(instance, baseAddress);
1928 }
1929
1930 return status;
1931 }
1932
1933
1934 /*FUNCTION**********************************************************************
1935 *
1936 * Function Name : Qspi_Ip_SfdpCheckMinorRevision
1937 * Description : Verifies validity of sfdp minor revision
1938 *
1939 *END**************************************************************************/
Qspi_Ip_SfdpCheckMinorRevision(uint8 minorRevision)1940 static inline boolean Qspi_Ip_SfdpCheckMinorRevision(uint8 minorRevision)
1941 {
1942 /* Revision and size must match the specifications of JESD216, JESD216A or JESD216B; also accept newer revisions */
1943 return ((QSPI_IP_SFDP_MINOR_REVISION_REV_0 == minorRevision) ||
1944 (minorRevision >= QSPI_IP_SFDP_MINOR_REVISION_REV_A));
1945 }
1946
1947
1948 /*FUNCTION**********************************************************************
1949 *
1950 * Function Name : Qspi_Ip_SfdpGetCmdExt
1951 * Description : Builds configuration for octal DDR (DOPI) mode.
1952 */
Qspi_Ip_SfdpGetCmdExt(const Qspi_Ip_SfdpTablesContainer * sfdpTables,uint8 instruction)1953 static inline uint8 Qspi_Ip_SfdpGetCmdExt(const Qspi_Ip_SfdpTablesContainer *sfdpTables,
1954 uint8 instruction
1955 )
1956 {
1957 uint8 cmdExt;
1958
1959 /* Get Command Extension */
1960 cmdExt = (uint8)Qspi_Ip_SfdpGetBasicParam(sfdpTables, QSPI_IP_SFDP_BASIC_CMD_EXT_DWORD,
1961 QSPI_IP_SFDP_BASIC_CMD_EXT_SHIFT, QSPI_IP_SFDP_BASIC_CMD_EXT_WIDTH, 0x1U);
1962 if (cmdExt == 0U)
1963 {
1964 cmdExt = instruction;
1965 }
1966 else
1967 {
1968 cmdExt = ~instruction;
1969 }
1970 return cmdExt;
1971 }
1972
1973
1974 /*FUNCTION**********************************************************************
1975 *
1976 * Function Name : Qspi_Ip_SfdpClearTable
1977 * Description : Clears parameter table before reading it. This is to avoid MISRA non-initialized value errors.
1978 */
Qspi_Ip_SfdpClearTable(uint32 * paramTable,uint8 paramTableLength)1979 static void Qspi_Ip_SfdpClearTable(uint32 * paramTable,
1980 uint8 paramTableLength
1981 )
1982 {
1983 uint8 count;
1984 for (count = 0U; count < paramTableLength; count++)
1985 {
1986 paramTable[count] = 0U;
1987 }
1988 }
1989
1990 /*FUNCTION**********************************************************************
1991 *
1992 * Function Name : Qspi_Ip_SfdpCheckNewerRevision
1993 * Description : Check SFDP Parameter Table revision is newer or not
1994 */
Qspi_Ip_SfdpCheckNewerRevision(uint8 paramIdLSB,uint8 tableType,uint8 majorRevision,uint8 minorRevision,sint16 minorRevisionMax)1995 static inline boolean Qspi_Ip_SfdpCheckNewerRevision(uint8 paramIdLSB,
1996 uint8 tableType,
1997 uint8 majorRevision,
1998 uint8 minorRevision,
1999 sint16 minorRevisionMax
2000 )
2001 {
2002 boolean retVal;
2003
2004 if ((paramIdLSB == (uint8)tableType) &&
2005 (QSPI_IP_SFDP_MAJOR_REVISION == majorRevision) &&
2006 ((sint16)minorRevision > minorRevisionMax))
2007 {
2008 retVal = TRUE;
2009 }
2010 else
2011 {
2012 retVal = FALSE;
2013 }
2014
2015 return retVal;
2016 }
2017
2018 /*FUNCTION**********************************************************************
2019 *
2020 * Function Name : Qspi_Ip_SfdpGetParamTableAddress
2021 * Description : Gets the address of parameter table from the parameter header.
2022 * Converts to byte address if the device is hyperbus.
2023 */
Qspi_Ip_SfdpGetParamTableAddress(const uint8 * paramHeader,uint8 accessProtocol)2024 static inline uint32 Qspi_Ip_SfdpGetParamTableAddress(const uint8 * paramHeader,
2025 uint8 accessProtocol
2026 )
2027 {
2028 /* Get the table address from pointer byte 2, 1 and 0 */
2029 uint32 paramTableAddress = ((uint32)paramHeader[6U] << 16U) | ((uint32)paramHeader[5U] << 8U) | (uint32)paramHeader[4U];
2030
2031 /* The memory is a hyperbus device, convert from word address to byte address */
2032 if (accessProtocol == QSPI_IP_SFDP_ACCESS_PROTOCOL_HYPERBUS)
2033 {
2034 bootModeLegacyXPI = (boolean)FALSE; /* The memory device booting up in xSPI NOR Profile 2 HYPERBUS */
2035 paramTableAddress <<= 1U;
2036 }
2037
2038 return paramTableAddress;
2039 }
2040
2041 /*FUNCTION**********************************************************************
2042 *
2043 * Function Name : Qspi_Ip_SfdpFindTable
2044 * Description : Finds requested parameters table in SFDP table, if it exists.
2045 */
Qspi_Ip_SfdpFindTable(uint32 instance,uint32 baseAddress,Qspi_Ip_SfdpTables tableType,uint32 * paramTable,uint8 * paramTableLength)2046 static Qspi_Ip_StatusType Qspi_Ip_SfdpFindTable(uint32 instance,
2047 uint32 baseAddress,
2048 Qspi_Ip_SfdpTables tableType,
2049 uint32 * paramTable,
2050 uint8 * paramTableLength
2051 )
2052 {
2053 Qspi_Ip_StatusType status;
2054 uint8 data[8U];
2055 uint8 paramHeaders = 0U;
2056 uint8 majorRevision;
2057 uint8 minorRevision;
2058 sint16 minorRevisionMax = -1;
2059 uint8 paramIdLSB;
2060 uint32 currAddr;
2061 uint32 paramTableBaseAddr = 0U;
2062 uint8 tableLength;
2063 uint8 tableLengthMax = 0U;
2064 boolean minorVerFlag = FALSE;
2065 uint8 accessProtocol = QSPI_IP_SFDP_ACCESS_PROTOCOL_LEGACY; /* default value as Legacy option */
2066
2067 Qspi_Ip_SfdpClearTable(paramTable, *paramTableLength);
2068 /* read second part of SFDP header to check version and get number of parameter headers */
2069 status = Qspi_Ip_IpRead(instance, QSPI_IP_COMMAND_LUT, baseAddress + 4U, data, NULL_PTR, 4U);
2070 if (STATUS_QSPI_IP_SUCCESS == status)
2071 {
2072 /* check SFDP revision; minor revision can be greater than expected, because backward compatibility is guaranteed */
2073 majorRevision = data[1];
2074 minorRevision = data[0];
2075 paramHeaders = (uint8)(data[2] + 1U);
2076 accessProtocol = data[3]; /* [31:24] SFDP Access Protocol field */
2077 minorVerFlag = Qspi_Ip_SfdpCheckMinorRevision(minorRevision);
2078 if ((QSPI_IP_SFDP_MAJOR_REVISION != majorRevision) || (TRUE != minorVerFlag))
2079 {
2080 paramHeaders = 0U;
2081 status = STATUS_QSPI_IP_ERROR;
2082 }
2083 }
2084
2085 /* If paramHeaders is greater than zero means the SFDP revision is correct */
2086 /* iterate through parameter headers */
2087 currAddr = 8U;
2088 for (; paramHeaders > (uint8)0U; paramHeaders--)
2089 {
2090 /* read current parameter header */
2091 status = Qspi_Ip_IpRead(instance, QSPI_IP_COMMAND_LUT, baseAddress + currAddr, data, NULL_PTR, 8U);
2092 if (status != STATUS_QSPI_IP_SUCCESS)
2093 {
2094 break;
2095 }
2096 majorRevision = data[2];
2097 minorRevision = data[1];
2098 paramIdLSB = data[0];
2099 tableLength = data[3];
2100 if (TRUE == Qspi_Ip_SfdpCheckNewerRevision(paramIdLSB, (uint8)tableType, majorRevision, minorRevision, minorRevisionMax))
2101 {
2102 /* Found SFDP Basic Parameter Table with newer revision */
2103 paramTableBaseAddr = Qspi_Ip_SfdpGetParamTableAddress(data, accessProtocol);
2104 minorRevisionMax = (sint16)minorRevision;
2105 tableLengthMax = tableLength;
2106 }
2107 currAddr += 8U;
2108 }
2109
2110 /* If minorRevisionMax is not negative, it means that a SFDP table was found */
2111 if (minorRevisionMax >= 0)
2112 {
2113 /* Adjust table length in case of newer revisions */
2114 if (tableLengthMax > *paramTableLength)
2115 {
2116 tableLengthMax = *paramTableLength;
2117 }
2118 /* Read parameter table */
2119 status = Qspi_Ip_IpRead(instance, QSPI_IP_COMMAND_LUT, baseAddress + paramTableBaseAddr, (uint8 *)paramTable, NULL_PTR, (uint32)tableLengthMax * 4U);
2120 if (STATUS_QSPI_IP_SUCCESS == status)
2121 {
2122 *paramTableLength = tableLengthMax;
2123 }
2124 }
2125 else
2126 {
2127 /* Could not find a table of the requested kind */
2128 *paramTableLength = 0U;
2129 }
2130
2131 return status;
2132 }
2133
2134
2135 /*FUNCTION**********************************************************************
2136 *
2137 * Function Name : Qspi_Ip_SfdpReadTables
2138 * Description : Finds requested parameters table in SFDP table, if it exists.
2139 */
Qspi_Ip_SfdpReadTables(uint32 instance,uint32 baseAddress,Qspi_Ip_SfdpTablesContainer * sfdpTables)2140 static Qspi_Ip_StatusType Qspi_Ip_SfdpReadTables(uint32 instance,
2141 uint32 baseAddress,
2142 Qspi_Ip_SfdpTablesContainer *sfdpTables
2143 )
2144 {
2145 Qspi_Ip_StatusType status;
2146
2147 /* Initialize each table length to max specified by JESD216 rev. D */
2148 sfdpTables->paramTableLength_basic = QSPI_IP_TABLE_SIZE_BASIC;
2149 sfdpTables->paramTableLength_4badd = QSPI_IP_TABLE_SIZE_4BADD;
2150 sfdpTables->paramTableLength_xspi1 = QSPI_IP_TABLE_SIZE_XSPI1;
2151 sfdpTables->paramTableLength_srmap = QSPI_IP_TABLE_SIZE_SRMAP;
2152 sfdpTables->paramTableLength_2dopi = QSPI_IP_TABLE_SIZE_2DOPI;
2153
2154 /* Search Basic Flash Parameter Table */
2155 status = Qspi_Ip_SfdpFindTable(instance, baseAddress, QSPI_IP_SFDP_TABLE_BASIC,
2156 sfdpTables->paramTable_basic, &(sfdpTables->paramTableLength_basic));
2157 if ((status != STATUS_QSPI_IP_SUCCESS) || (sfdpTables->paramTableLength_basic == 0U))
2158 {
2159 status = STATUS_QSPI_IP_ERROR;
2160 }
2161
2162 if (STATUS_QSPI_IP_SUCCESS == status)
2163 {
2164 /* Search 4-byte Address Instruction Table */
2165 status = Qspi_Ip_SfdpFindTable(instance, baseAddress, QSPI_IP_SFDP_TABLE_4BADD,
2166 sfdpTables->paramTable_4badd, &(sfdpTables->paramTableLength_4badd));
2167 }
2168
2169 if (STATUS_QSPI_IP_SUCCESS == status)
2170 {
2171 /* Search eXtended Serial Peripheral Interface (xSPI) Profile 1.0 Table */
2172 status = Qspi_Ip_SfdpFindTable(instance, baseAddress, QSPI_IP_SFDP_TABLE_XSPI1,
2173 sfdpTables->paramTable_xspi1, &(sfdpTables->paramTableLength_xspi1));
2174 }
2175
2176 if (STATUS_QSPI_IP_SUCCESS == status)
2177 {
2178 /* Search Status, Control and Configuration Register Map Table */
2179 status = Qspi_Ip_SfdpFindTable(instance, baseAddress, QSPI_IP_SFDP_TABLE_SRMAP,
2180 sfdpTables->paramTable_srmap, &(sfdpTables->paramTableLength_srmap));
2181 }
2182
2183 if (STATUS_QSPI_IP_SUCCESS == status)
2184 {
2185 /* Command Sequences to change to DOPI (8D-8D-8D) mode */
2186 status = Qspi_Ip_SfdpFindTable(instance, baseAddress, QSPI_IP_SFDP_TABLE_2DOPI,
2187 sfdpTables->paramTable_2dopi, &(sfdpTables->paramTableLength_2dopi));
2188 }
2189
2190 return status;
2191 }
2192
2193
2194 /*FUNCTION**********************************************************************
2195 *
2196 * Function Name : Qspi_Ip_SfdpInitSimpleCmd
2197 * Description : Builds an initial operation containing a simple command.
2198 */
Qspi_Ip_SfdpInitSimpleCmd(uint8 cmd,const Qspi_Ip_MemoryConfigType * pConfig)2199 static void Qspi_Ip_SfdpInitSimpleCmd(uint8 cmd,
2200 const Qspi_Ip_MemoryConfigType *pConfig
2201 )
2202 {
2203 Qspi_Ip_InitOperationType *operation;
2204
2205 if (initOpCount >= pConfig->initConfiguration.opCount)
2206 {
2207 /* operations list not big enough */
2208 overflow = TRUE;
2209 }
2210 else
2211 {
2212 operation = &(pConfig->initConfiguration.operations[initOpCount]);
2213 initOpCount++;
2214 /* Build operation */
2215 operation->opType = QSPI_IP_OP_TYPE_CMD;
2216 operation->command1Lut = lutCount;
2217 operation->addr = 0U;
2218 /* Build LUT sequence */
2219 Qspi_Ip_SfdpLutAdd(&(pConfig->lutSequences), Qspi_Ip_PackLut(QSPI_IP_LUT_INSTR_CMD, QSPI_IP_LUT_PADS_1, cmd));
2220 Qspi_Ip_SfdpLutAdd(&(pConfig->lutSequences), Qspi_Ip_PackLut(QSPI_IP_LUT_INSTR_STOP, QSPI_IP_LUT_PADS_1, 0x0U));
2221 /* Other operation fields are unused */
2222 operation->command2Lut = QSPI_IP_LUT_INVALID;
2223 operation->weLut = QSPI_IP_LUT_INVALID;
2224 operation->size = 0U;
2225 operation->shift = 0U;
2226 operation->width = 0U;
2227 operation->value = 0U;
2228 operation->ctrlCfgPtr = NULL_PTR;
2229 }
2230
2231 return;
2232 }
2233
2234
2235 /*FUNCTION**********************************************************************
2236 *
2237 * Function Name : Qspi_Ip_SfdpGetWeSrInstr
2238 * Description : Returns instruction for write enable on SR register.
2239 */
Qspi_Ip_SfdpGetWeSrInstr(const Qspi_Ip_SfdpTablesContainer * sfdpTables)2240 static uint8 Qspi_Ip_SfdpGetWeSrInstr(const Qspi_Ip_SfdpTablesContainer *sfdpTables)
2241 {
2242 uint8 wrEnSr;
2243
2244 /* Check "Write Enable Instruction Select for Writing to Volatile Status Register" bitfield */
2245 wrEnSr = (uint8)Qspi_Ip_SfdpGetBasicParam(sfdpTables, QSPI_IP_SFDP_BASIC_WREN_SR_DWORD,
2246 QSPI_IP_SFDP_BASIC_WREN_SR_SHIFT, QSPI_IP_SFDP_BASIC_WREN_SR_WIDTH, 0x1U);
2247 if (wrEnSr == 1U)
2248 {
2249 wrEnSr = 0x50U;
2250 }
2251 else
2252 {
2253 wrEnSr = 0x06U;
2254 }
2255 return wrEnSr;
2256 }
2257
2258
2259 /*FUNCTION**********************************************************************
2260 *
2261 * Function Name : Qspi_Ip_SfdpInitWriteReg
2262 * Description : Builds an initial operation containing a register write command.
2263 */
Qspi_Ip_SfdpInitWriteReg(uint8 cmd,uint8 wrenCmd,uint8 size,uint32 value,const Qspi_Ip_MemoryConfigType * pConfig)2264 static void Qspi_Ip_SfdpInitWriteReg(uint8 cmd,
2265 uint8 wrenCmd,
2266 uint8 size,
2267 uint32 value,
2268 const Qspi_Ip_MemoryConfigType *pConfig
2269 )
2270 {
2271 Qspi_Ip_InitOperationType *operation;
2272
2273 if (initOpCount >= pConfig->initConfiguration.opCount)
2274 {
2275 /* operations list not big enough */
2276 overflow = TRUE;
2277 }
2278 else
2279 {
2280 operation = &(pConfig->initConfiguration.operations[initOpCount]);
2281 initOpCount++;
2282 /* Build operation */
2283 operation->opType = QSPI_IP_OP_TYPE_WRITE_REG;
2284 operation->addr = 0U;
2285 operation->weLut = lutCount;
2286 operation->size = size;
2287 operation->value = value;
2288 /* Build WE LUT sequence */
2289 Qspi_Ip_SfdpLutAdd(&(pConfig->lutSequences), Qspi_Ip_PackLut(QSPI_IP_LUT_INSTR_CMD, QSPI_IP_LUT_PADS_1, wrenCmd));
2290 Qspi_Ip_SfdpLutAdd(&(pConfig->lutSequences), Qspi_Ip_PackLut(QSPI_IP_LUT_INSTR_STOP, QSPI_IP_LUT_PADS_1, 0x0U));
2291 operation->command1Lut = lutCount;
2292 /* Build write SR LUT sequence */
2293 Qspi_Ip_SfdpLutAdd(&(pConfig->lutSequences), Qspi_Ip_PackLut(QSPI_IP_LUT_INSTR_CMD, QSPI_IP_LUT_PADS_1, cmd));
2294 Qspi_Ip_SfdpLutAdd(&(pConfig->lutSequences), Qspi_Ip_PackLut(QSPI_IP_LUT_INSTR_WRITE, QSPI_IP_LUT_PADS_1, 0x1U));
2295 Qspi_Ip_SfdpLutAdd(&(pConfig->lutSequences), Qspi_Ip_PackLut(QSPI_IP_LUT_INSTR_STOP, QSPI_IP_LUT_PADS_1, 0x0U));
2296
2297 /* Other operation fields are unused */
2298 operation->command2Lut = QSPI_IP_LUT_INVALID;
2299 operation->shift = 0U;
2300 operation->width = 0U;
2301 operation->ctrlCfgPtr = NULL_PTR;
2302 }
2303
2304 return;
2305 }
2306
2307
2308 /*FUNCTION**********************************************************************
2309 *
2310 * Function Name : Qspi_Ip_Sfdp4byteAddrSwitch_01
2311 * Description : Switch to 4-byte addressing mode.
2312 */
Qspi_Ip_Sfdp4byteAddrSwitch_01(const Qspi_Ip_MemoryConfigType * pConfig)2313 static Qspi_Ip_StatusType Qspi_Ip_Sfdp4byteAddrSwitch_01(const Qspi_Ip_MemoryConfigType * pConfig)
2314 {
2315 /* issue instruction B7h (preceding write enable not required) */
2316 Qspi_Ip_SfdpInitSimpleCmd(0xB7U, pConfig);
2317 return STATUS_QSPI_IP_SUCCESS;
2318 }
2319
2320
2321 /*FUNCTION**********************************************************************
2322 *
2323 * Function Name : Qspi_Ip_Sfdp4byteAddrSwitch_02
2324 * Description : Switch to 4-byte addressing mode.
2325 */
Qspi_Ip_Sfdp4byteAddrSwitch_02(const Qspi_Ip_MemoryConfigType * pConfig)2326 static Qspi_Ip_StatusType Qspi_Ip_Sfdp4byteAddrSwitch_02(const Qspi_Ip_MemoryConfigType * pConfig)
2327 {
2328 /* issue write enable instruction 06h, then issue instruction B7h */
2329 Qspi_Ip_SfdpInitSimpleCmd(0x06U, pConfig);
2330 Qspi_Ip_SfdpInitSimpleCmd(0xB7U, pConfig);
2331 return STATUS_QSPI_IP_SUCCESS;
2332 }
2333
2334
2335 /*FUNCTION**********************************************************************
2336 *
2337 * Function Name : Qspi_Ip_Sfdp4byteAddrSwitch_08
2338 * Description : Switch to 4-byte addressing mode.
2339 */
Qspi_Ip_Sfdp4byteAddrSwitch_08(const Qspi_Ip_MemoryConfigType * pConfig)2340 static Qspi_Ip_StatusType Qspi_Ip_Sfdp4byteAddrSwitch_08(const Qspi_Ip_MemoryConfigType * pConfig)
2341 {
2342 /* 8-bit volatile bank register used to define A[30:A24] bits. MSB (bit[7]) is used to enable/disable 4-byte address mode.
2343 When MSB is set to ‘1’, 4-byte address mode is active and A[30:24] bits are don’t care. Read with instruction 16h.
2344 Write instruction is 17h with 1 byte of data. When MSB is cleared to ‘0’, select the active 128 Mbit segment by setting
2345 the appropriate A[30:24] bits and use 3-Byte addressing */
2346 /* Not implemented */
2347 (void)pConfig;
2348 return STATUS_QSPI_IP_ERROR;
2349 }
2350
2351
2352 /*FUNCTION**********************************************************************
2353 *
2354 * Function Name : Qspi_Ip_Sfdp4byteAddrSwitch_16
2355 * Description : Switch to 4-byte addressing mode.
2356 */
Qspi_Ip_Sfdp4byteAddrSwitch_16(const Qspi_Ip_MemoryConfigType * pConfig)2357 static Qspi_Ip_StatusType Qspi_Ip_Sfdp4byteAddrSwitch_16(const Qspi_Ip_MemoryConfigType * pConfig)
2358 {
2359 /* A 16-bit nonvolatile configuration register controls 3-Byte/4-Byte address mode. Read instruction is B5h.
2360 Bit[0] controls address mode [0=3-Byte; 1=4-Byte]. Write configuration register instruction is B1h, data length is 2 bytes */
2361 /* Not implemented */
2362 (void)pConfig;
2363 return STATUS_QSPI_IP_ERROR;
2364 }
2365
2366
2367 /*FUNCTION**********************************************************************
2368 *
2369 * Function Name : Qspi_Ip_Sfdp4byteAddrSwitch
2370 * Description : Switch to 4-byte addressing mode.
2371 */
Qspi_Ip_Sfdp4byteAddrSwitch(const Qspi_Ip_SfdpTablesContainer * sfdpTables,const Qspi_Ip_MemoryConfigType * pConfig)2372 static Qspi_Ip_StatusType Qspi_Ip_Sfdp4byteAddrSwitch(const Qspi_Ip_SfdpTablesContainer *sfdpTables,
2373 const Qspi_Ip_MemoryConfigType * pConfig
2374 )
2375 {
2376 Qspi_Ip_StatusType status = STATUS_QSPI_IP_SUCCESS;
2377 uint8 addrSwitch;
2378
2379 /* Check 4-byte addr enable mode */
2380 addrSwitch = (uint8)Qspi_Ip_SfdpGetBasicParam(sfdpTables, QSPI_IP_SFDP_BASIC_ADDR_SWITCH_DWORD,
2381 QSPI_IP_SFDP_BASIC_ADDR_SWITCH_SHIFT, QSPI_IP_SFDP_BASIC_ADDR_SWITCH_WIDTH, 0x0U);
2382 if ((addrSwitch & 0x01U) != 0U)
2383 {
2384 /* issue instruction B7h (preceding write enable not required) */
2385 status = Qspi_Ip_Sfdp4byteAddrSwitch_01(pConfig);
2386 }
2387 else if ((addrSwitch & 0x02U) != 0U)
2388 {
2389 /* issue write enable instruction 06h, then issue instruction B7h */
2390 status = Qspi_Ip_Sfdp4byteAddrSwitch_02(pConfig);
2391 }
2392 else if ((addrSwitch & 0x08U) != 0U)
2393 {
2394 /* 8-bit volatile bank register used to define A[30:A24] bits. MSB (bit[7]) is used to enable/disable 4-byte address mode */
2395 status = Qspi_Ip_Sfdp4byteAddrSwitch_08(pConfig);
2396 }
2397 else if ((addrSwitch & 0x10U) != 0U)
2398 {
2399 /* A 16-bit nonvolatile configuration register controls 3-Byte/4-Byte address mode. */
2400 status = Qspi_Ip_Sfdp4byteAddrSwitch_16(pConfig);
2401 }
2402 else
2403 {
2404 /* Can't switch to 4-byte addr. mode */
2405 status = STATUS_QSPI_IP_ERROR;
2406 }
2407 return status;
2408 }
2409
2410
2411 /*FUNCTION**********************************************************************
2412 *
2413 * Function Name : Qspi_Ip_SfdpGetBasicAddrBits
2414 * Description : Returns number of address bits.
2415 */
Qspi_Ip_SfdpGetBasicAddrBits(const Qspi_Ip_SfdpTablesContainer * sfdpTables,const Qspi_Ip_MemoryConfigType * pConfig)2416 static void Qspi_Ip_SfdpGetBasicAddrBits(const Qspi_Ip_SfdpTablesContainer *sfdpTables,
2417 const Qspi_Ip_MemoryConfigType * pConfig
2418 )
2419 {
2420 uint8 addrBytes;
2421 Qspi_Ip_StatusType status;
2422
2423 /* Check number of address bytes */
2424 addrBytes = (uint8)Qspi_Ip_SfdpGetBasicParam(sfdpTables, QSPI_IP_SFDP_BASIC_ADDR_BYTES_DWORD,
2425 QSPI_IP_SFDP_BASIC_ADDR_BYTES_SHIFT, QSPI_IP_SFDP_BASIC_ADDR_BYTES_WIDTH, 0x0U);
2426 switch (addrBytes)
2427 {
2428 case 0U:
2429 /* 3-Byte only addressing */
2430 basicAddrBits = 24U;
2431 break;
2432 case 1U:
2433 /* 3 or 4 byte addressing, try to switch to 4 */
2434 status = Qspi_Ip_Sfdp4byteAddrSwitch(sfdpTables, pConfig);
2435 if (STATUS_QSPI_IP_SUCCESS == status)
2436 {
2437 basicAddrBits = 32U;
2438 }
2439 else
2440 {
2441 basicAddrBits = 24U;
2442 }
2443 break;
2444 case 2U:
2445 /* 4-Byte only addressing */
2446 basicAddrBits = 32U;
2447 break;
2448 default:
2449 /* reseved, should not happen, default to 3-byte */
2450 basicAddrBits = 24U;
2451 break;
2452 }
2453 }
2454
2455
2456 /*FUNCTION**********************************************************************
2457 *
2458 * Function Name : Qspi_Ip_SfdpConfigureQE
2459 * Description : Adds initial operation to set QE bit, if required.
2460 */
Qspi_Ip_SfdpConfigureQE(const Qspi_Ip_SfdpTablesContainer * sfdpTables,const Qspi_Ip_MemoryConfigType * pConfig)2461 static void Qspi_Ip_SfdpConfigureQE(const Qspi_Ip_SfdpTablesContainer *sfdpTables,
2462 const Qspi_Ip_MemoryConfigType *pConfig
2463 )
2464 {
2465 uint8 qeReq;
2466 uint8 wrenCmd;
2467 boolean qeBit = TRUE;
2468
2469 /* Check "Quad Enable Requirements (QER)" field */
2470 qeReq = (uint8)Qspi_Ip_SfdpGetBasicParam(sfdpTables, QSPI_IP_SFDP_BASIC_QE_REQ_DWORD,
2471 QSPI_IP_SFDP_BASIC_QE_REQ_SHIFT, QSPI_IP_SFDP_BASIC_QE_REQ_WIDTH, 0x7U);
2472 wrenCmd = Qspi_Ip_SfdpGetWeSrInstr(sfdpTables);
2473 switch (qeReq)
2474 {
2475 case 0U:
2476 /* Device does not have a QE bit. Device detects 1-1-4 and 1-4-4 reads based on instruction.
2477 (the quad commands are available without setting any bits) */
2478 qeBit = FALSE;
2479 break;
2480 case 1U:
2481 /* QE is bit 1 of status register 2. It is set via Write Status with two data bytes where bit 1 of the second byte is one. It is cleared via
2482 Write Status with two data bytes where bit 1 of the second byte is zero. Writing only one byte to the status register has the side-effect
2483 of clearing status register 2, including the QE bit */
2484 Qspi_Ip_SfdpInitWriteReg(0x01U, wrenCmd, 2U, 0x0002U, pConfig);
2485 break;
2486 case 2U:
2487 /* QE is bit 6 of status register 1. It is set via Write Status with one data byte where bit 6 is one.
2488 It is cleared via Write Status with one data byte where bit 6 is zero. */
2489 Qspi_Ip_SfdpInitWriteReg(0x01U, wrenCmd, 1U, 0x40U, pConfig);
2490 break;
2491 case 3U:
2492 /* QE is bit 7 of status register 2. It is set via Write status register 2 instruction 3Eh with one data byte where bit 7 is one.
2493 It is cleared via Write status register 2 instruction 3Eh with one data byte where bit 7 is zero. The status register 2 is read using instruction 3Fh. */
2494 Qspi_Ip_SfdpInitWriteReg(0x3EU, wrenCmd, 1U, 0x80U, pConfig);
2495 break;
2496 case 4U:
2497 /* QE is bit 1 of status register 2. It is set via Write Status with two data bytes where bit 1 of the second byte is one. It is cleared via
2498 Write Status with two data bytes where bit 1 of the second byte is zero. In contrast to the 001b code, writing one byte to the status
2499 register does not modify status register 2. */
2500 Qspi_Ip_SfdpInitWriteReg(0x01U, wrenCmd, 2U, 0x0002U, pConfig);
2501 break;
2502 case 5U:
2503 /* QE is bit 1 of the status register 2. Status register 1 is read using Read Status instruction 05h. Status register 2 is read using instruction 35h.
2504 QE is set via Write Status instruction 01h with two data bytes where bit 1 of the second byte is one. It is cleared via Write Status with
2505 two data bytes where bit 1 of the second byte is zero. */
2506 Qspi_Ip_SfdpInitWriteReg(0x01U, wrenCmd, 2U, 0x0002U, pConfig);
2507 break;
2508 case 6U:
2509 /* QE is bit 1 of the status register 2. Status register 1 is read using Read Status instruction 05h. Status register 2 is read using instruction
2510 35h, and status register 3 is read using instruction 15h. QE is set via Write Status Register instruction 31h with one data byte where
2511 bit 1 is one. It is cleared via Write Status Register instruction 31h with one data byte where bit 1 is zero. */
2512 Qspi_Ip_SfdpInitWriteReg(0x31U, wrenCmd, 1U, 0x02U, pConfig);
2513 break;
2514 default:
2515 /* Unknown QE bit setting procedure or table too short, disable quad commands */
2516 quadAvailable = FALSE;
2517 qeBit = FALSE;
2518 break;
2519 }
2520
2521 if (TRUE == qeBit)
2522 {
2523 /* Add a wait operation to ensure the write to non-volatile QE bit is completed */
2524 Qspi_Ip_SfdpAddCheckBusyOperation(pConfig);
2525 }
2526 }
2527
2528
2529 /*FUNCTION**********************************************************************
2530 *
2531 * Function Name : Qspi_Ip_SfdpGetModeInstr
2532 * Description : Returns MODE instructions to use for read commands.
2533 */
Qspi_Ip_SfdpGetModeInstr(uint8 modeClocks,Qspi_Ip_LutPadsType addrPads)2534 static Qspi_Ip_LutCommandsType Qspi_Ip_SfdpGetModeInstr(uint8 modeClocks,
2535 Qspi_Ip_LutPadsType addrPads
2536 )
2537 {
2538 uint8 modeBits;
2539 Qspi_Ip_LutCommandsType mode = QSPI_IP_LUT_INSTR_MODE;
2540
2541 /* compute the number of mode bits from pads and mode clocks */
2542 modeBits = modeClocks * (1U << (uint8)((uint32)addrPads >> 8U));
2543 switch (modeBits)
2544 {
2545 case 2U:
2546 mode = QSPI_IP_LUT_INSTR_MODE2;
2547 break;
2548 case 4U:
2549 mode = QSPI_IP_LUT_INSTR_MODE4;
2550 break;
2551 case 8U:
2552 mode = QSPI_IP_LUT_INSTR_MODE;
2553 break;
2554 default:
2555 /* unsupported mode */
2556 break;
2557 }
2558 return mode;
2559 }
2560
2561
2562 /*FUNCTION**********************************************************************
2563 *
2564 * Function Name : Qspi_Ip_SfdpGetSpiReadInstr
2565 * Description : Returns instructions for read type <cnt>.
2566 */
Qspi_Ip_SfdpGetSpiReadInstr(const Qspi_Ip_SfdpTablesContainer * sfdpTables,uint8 cnt,uint8 * instruction,uint8 * addrBits)2567 static void Qspi_Ip_SfdpGetSpiReadInstr(const Qspi_Ip_SfdpTablesContainer *sfdpTables,
2568 uint8 cnt,
2569 uint8 *instruction,
2570 uint8 *addrBits
2571 )
2572 {
2573 uint8 sup4badd;
2574
2575 /* Check 4-byte instr. support */
2576 sup4badd = (uint8)Qspi_Ip_SfdpGet4BAddParam(sfdpTables, read4ByteSupDword[cnt],
2577 read4ByteSupShift[cnt], QSPI_IP_SFDP_4BADD_INSTR_SUP_WIDTH, 0x0U);
2578 if (sup4badd == 1U)
2579 {
2580 /* Use 4-byte address instruction specified in SFDP standard */
2581 *instruction = read4ByteInst[cnt];
2582 *addrBits = 32U;
2583 }
2584 else
2585 {
2586 /* Get instruction from basic parameters table */
2587 *instruction = (uint8)Qspi_Ip_SfdpGetBasicParam(sfdpTables, readInstDword[cnt],
2588 readInstShift[cnt], readInstWidth[cnt], 0x0U);
2589 *addrBits = basicAddrBits;
2590 }
2591 }
2592
2593
2594 /*FUNCTION**********************************************************************
2595 *
2596 * Function Name : Qspi_Ip_SfdpConfigBasicRead
2597 * Description : Configures basic 1-1-1 read.
2598 */
Qspi_Ip_SfdpConfigBasicRead(const Qspi_Ip_SfdpTablesContainer * sfdpTables,Qspi_Ip_MemoryConfigType * pConfig)2599 static void Qspi_Ip_SfdpConfigBasicRead(const Qspi_Ip_SfdpTablesContainer *sfdpTables,
2600 Qspi_Ip_MemoryConfigType *pConfig
2601 )
2602 {
2603 uint8 addrBits;
2604 uint8 instruction;
2605
2606 /* Check 4-byte instr. support */
2607 addrBits = (uint8)Qspi_Ip_SfdpGet4BAddParam(sfdpTables, QSPI_IP_SFDP_4BADD_INSTR_SUP_DWORD,
2608 QSPI_IP_SFDP_4BADD_READ111_SUP_SHIFT, QSPI_IP_SFDP_4BADD_INSTR_SUP_WIDTH, 0x0U);
2609 if (addrBits == 0U)
2610 {
2611 instruction = QSPI_IP_CMD_BASIC_READ;
2612 addrBits = basicAddrBits;
2613 }
2614 else
2615 {
2616 instruction = QSPI_IP_CMD_BASIC_READ_4B;
2617 addrBits = 32U;
2618 }
2619 /* Get LUT index */
2620 pConfig->readLut = lutCount;
2621 /* Build LUT */
2622 Qspi_Ip_SfdpLutAdd(&(pConfig->lutSequences), Qspi_Ip_PackLut(QSPI_IP_LUT_INSTR_CMD, QSPI_IP_LUT_PADS_1, instruction));
2623 Qspi_Ip_SfdpLutAdd(&(pConfig->lutSequences), Qspi_Ip_PackLut(QSPI_IP_LUT_INSTR_ADDR, QSPI_IP_LUT_PADS_1, addrBits));
2624 Qspi_Ip_SfdpLutAdd(&(pConfig->lutSequences), Qspi_Ip_PackLut(QSPI_IP_LUT_INSTR_READ, QSPI_IP_LUT_PADS_1, 0x10U));
2625 Qspi_Ip_SfdpLutAdd(&(pConfig->lutSequences), Qspi_Ip_PackLut(QSPI_IP_LUT_INSTR_STOP, QSPI_IP_LUT_PADS_1, 0x0U));
2626 }
2627
2628
2629 /*FUNCTION**********************************************************************
2630 *
2631 * Function Name : Qspi_Ip_Sfdp444Switch
2632 * Description : Add commands to switch to 4-4-4 mode in operations list
2633 */
Qspi_Ip_Sfdp444Switch_01(const Qspi_Ip_MemoryConfigType * pConfig)2634 static Qspi_Ip_StatusType Qspi_Ip_Sfdp444Switch_01(const Qspi_Ip_MemoryConfigType * pConfig)
2635 {
2636 /* 01: set QE per QER description above, then issue instruction 38h */
2637 /* 02: issue instruction 38h */
2638 Qspi_Ip_SfdpInitSimpleCmd(0x38U, pConfig);
2639 return STATUS_QSPI_IP_SUCCESS;
2640 }
2641
2642
2643 /*FUNCTION**********************************************************************
2644 *
2645 * Function Name : Qspi_Ip_Sfdp444Switch
2646 * Description : Add commands to switch to 4-4-4 mode in operations list
2647 */
Qspi_Ip_Sfdp444Switch_04(const Qspi_Ip_MemoryConfigType * pConfig)2648 static Qspi_Ip_StatusType Qspi_Ip_Sfdp444Switch_04(const Qspi_Ip_MemoryConfigType * pConfig)
2649 {
2650 /* issue instruction 35h */
2651 Qspi_Ip_SfdpInitSimpleCmd(0x35U, pConfig);
2652 return STATUS_QSPI_IP_SUCCESS;
2653 }
2654
2655
2656 /*FUNCTION**********************************************************************
2657 *
2658 * Function Name : Qspi_Ip_Sfdp444Switch
2659 * Description : Add commands to switch to 4-4-4 mode in operations list
2660 */
Qspi_Ip_Sfdp444Switch_08(const Qspi_Ip_MemoryConfigType * pConfig)2661 static Qspi_Ip_StatusType Qspi_Ip_Sfdp444Switch_08(const Qspi_Ip_MemoryConfigType * pConfig)
2662 {
2663 /* device uses a read-modify-write sequence of operations: read configuration using instruction 65h followed by address 800003h, set bit 6,
2664 write configuration using instruction 71h followed by address 800003h. This configuration is volatile. */
2665 /* Not implemented */
2666 (void)pConfig;
2667 return STATUS_QSPI_IP_ERROR;
2668 }
2669
2670
2671 /*FUNCTION**********************************************************************
2672 *
2673 * Function Name : Qspi_Ip_Sfdp444Switch
2674 * Description : Add commands to switch to 4-4-4 mode in operations list
2675 */
Qspi_Ip_Sfdp444Switch_16(const Qspi_Ip_MemoryConfigType * pConfig)2676 static Qspi_Ip_StatusType Qspi_Ip_Sfdp444Switch_16(const Qspi_Ip_MemoryConfigType * pConfig)
2677 {
2678 /* Device uses a read-modify-write sequence of operations: Read Volatile Enhanced Configuration Register using instruction 65h,
2679 no address is required, reset bit 7 to 0. Write Volatile Enhanced Configuration Register using instruction 61h,
2680 no address is required. This configuration is volatile. */
2681 /* Not implemented */
2682 (void)pConfig;
2683 return STATUS_QSPI_IP_ERROR;
2684 }
2685
2686
2687 /*FUNCTION**********************************************************************
2688 *
2689 * Function Name : Qspi_Ip_Sfdp444Switch
2690 * Description : Add commands to switch to 4-4-4 mode in operations list
2691 */
Qspi_Ip_Sfdp444Switch(const Qspi_Ip_SfdpTablesContainer * sfdpTables,const Qspi_Ip_MemoryConfigType * pConfig)2692 static Qspi_Ip_StatusType Qspi_Ip_Sfdp444Switch(const Qspi_Ip_SfdpTablesContainer *sfdpTables,
2693 const Qspi_Ip_MemoryConfigType * pConfig
2694 )
2695 {
2696 uint8 quadSwitch;
2697 Qspi_Ip_StatusType status = STATUS_QSPI_IP_SUCCESS;
2698
2699 /* Check 4-4-4 mode enable sequences */
2700 quadSwitch = (uint8)Qspi_Ip_SfdpGetBasicParam(sfdpTables, QSPI_IP_SFDP_BASIC_444_SWITCH_DWORD,
2701 QSPI_IP_SFDP_BASIC_444_SWITCH_SHIFT, QSPI_IP_SFDP_BASIC_444_SWITCH_WIDTH, 0x0U);
2702 if ((quadSwitch & 0x3U) != 0U)
2703 {
2704 /* 01: set QE per QER description above, then issue instruction 38h */
2705 /* 02: issue instruction 38h */
2706 status = Qspi_Ip_Sfdp444Switch_01(pConfig);
2707 }
2708 else if ((quadSwitch & 0x4U) != 0U)
2709 {
2710 /* issue instruction 35h */
2711 status = Qspi_Ip_Sfdp444Switch_04(pConfig);
2712 }
2713 else if ((quadSwitch & 0x8U) != 0U)
2714 { /* device uses a read-modify-write sequence of operations */
2715 status = Qspi_Ip_Sfdp444Switch_08(pConfig);
2716 }
2717 else if ((quadSwitch & 0x16U) != 0U)
2718 { /* device uses a read-modify-write sequence of operations */
2719 status = Qspi_Ip_Sfdp444Switch_16(pConfig);
2720 }
2721 else
2722 {
2723 /* can't do the switch to 4-4-4 mode */
2724 status = STATUS_QSPI_IP_ERROR;
2725 }
2726 return status;
2727 }
2728
2729
2730 /*FUNCTION**********************************************************************
2731 *
2732 * Function Name : Qspi_Ip_SfdpGetBasicReadInfo
2733 * Description : Builds configuration for basic (SPI) read.
2734 */
Qspi_Ip_SfdpGetBasicReadInfo(const Qspi_Ip_SfdpTablesContainer * sfdpTables,Qspi_Ip_MemoryConfigType * pConfig)2735 static void Qspi_Ip_SfdpGetBasicReadInfo(const Qspi_Ip_SfdpTablesContainer *sfdpTables,
2736 Qspi_Ip_MemoryConfigType * pConfig
2737 )
2738 {
2739 uint8 supported = 0U;
2740 uint8 crtMode;
2741 uint8 modeClocks;
2742 uint8 dummyClocks;
2743 Qspi_Ip_LutPadsType instPads;
2744 Qspi_Ip_LutPadsType addrPads;
2745 Qspi_Ip_LutPadsType dataPads;
2746 uint8 addrBits;
2747 uint8 instruction;
2748 Qspi_Ip_LutCommandsType modeInstr;
2749 Qspi_Ip_StatusType status = STATUS_QSPI_IP_SUCCESS;
2750
2751 /* Find the best supported fast read mode */
2752 /* Check if read mode is supported */
2753 for (crtMode = (uint8)QSPI_IP_SFDP_READ_MODE_MAX; crtMode > 0U; crtMode-- )
2754 {
2755 modeIndex = (uint8)(crtMode - 1U);
2756 if ((QSPI_IP_LUT_PADS_4 == readModeDataPads[modeIndex]) && (FALSE == quadAvailable))
2757 {
2758 /* Quad mode not available ignore quad commands */
2759 continue;
2760 }
2761 supported = (uint8)Qspi_Ip_SfdpGetBasicParam(sfdpTables, readSupDword[modeIndex],
2762 readSupShift[modeIndex], readSupWitdh[modeIndex], 0x0U);
2763 if (supported != 0U)
2764 {
2765 if ((uint8)QSPI_IP_SFDP_READ_MODE_444 == modeIndex)
2766 {
2767 /* 4-4-4 read mode, add commands to switch to this mode in operation list */
2768 status = Qspi_Ip_Sfdp444Switch(sfdpTables, pConfig);
2769 /* Will use 4 cmd pads for all commands */
2770 cmdPads = QSPI_IP_LUT_PADS_4;
2771 }
2772 else
2773 {
2774 status = STATUS_QSPI_IP_SUCCESS;
2775 cmdPads = QSPI_IP_LUT_PADS_1;
2776 }
2777 if (STATUS_QSPI_IP_SUCCESS == status)
2778 {
2779 /* Get read instruction */
2780 Qspi_Ip_SfdpGetSpiReadInstr(sfdpTables, modeIndex, &instruction, &addrBits);
2781 /* Get mode and dummy clocks */
2782 modeClocks = (uint8)Qspi_Ip_SfdpGetBasicParam(sfdpTables, readModeDword[modeIndex],
2783 readModeShift[modeIndex], readModeWidth[modeIndex], 0x0U);
2784 dummyClocks = (uint8)Qspi_Ip_SfdpGetBasicParam(sfdpTables, readDummyDword[modeIndex],
2785 readDummyShift[modeIndex], readDummyWidth[modeIndex], 0x0U);
2786 /* Get other command parameters */
2787 instPads = readModeInstPads[modeIndex];
2788 addrPads = readModeAddrPads[modeIndex];
2789 dataPads = readModeDataPads[modeIndex];
2790 /* Build LUT */
2791 pConfig->readLut = lutCount;
2792 Qspi_Ip_SfdpLutAdd(&(pConfig->lutSequences), Qspi_Ip_PackLut(QSPI_IP_LUT_INSTR_CMD, instPads, instruction));
2793 Qspi_Ip_SfdpLutAdd(&(pConfig->lutSequences), Qspi_Ip_PackLut(QSPI_IP_LUT_INSTR_ADDR, addrPads, addrBits));
2794 if (modeClocks > 0U)
2795 {
2796 modeInstr = Qspi_Ip_SfdpGetModeInstr(modeClocks, addrPads);
2797 Qspi_Ip_SfdpLutAdd(&(pConfig->lutSequences), Qspi_Ip_PackLut(modeInstr, addrPads, 0x0U));
2798 }
2799 if (dummyClocks > 0U)
2800 {
2801 Qspi_Ip_SfdpLutAdd(&(pConfig->lutSequences), Qspi_Ip_PackLut(QSPI_IP_LUT_INSTR_DUMMY, addrPads, dummyClocks));
2802 }
2803 Qspi_Ip_SfdpLutAdd(&(pConfig->lutSequences), Qspi_Ip_PackLut(QSPI_IP_LUT_INSTR_READ, dataPads, 0x10U));
2804 Qspi_Ip_SfdpLutAdd(&(pConfig->lutSequences), Qspi_Ip_PackLut(QSPI_IP_LUT_INSTR_STOP, QSPI_IP_LUT_PADS_1, 0x0U));
2805 /* Found read command, exit loop */
2806 break;
2807 }
2808 }
2809 }
2810
2811 if (supported == 0U)
2812 {
2813 /* No supported fast read mode found, use default */
2814 Qspi_Ip_SfdpConfigBasicRead(sfdpTables, pConfig);
2815 }
2816 }
2817
2818
2819 /*FUNCTION**********************************************************************
2820 *
2821 * Function Name : Qspi_Ip_SfdpGetBasicWriteInfo
2822 * Description : Builds configuration for basic (SPI) write
2823 */
Qspi_Ip_SfdpGetBasicWriteInfo(const Qspi_Ip_SfdpTablesContainer * sfdpTables,Qspi_Ip_MemoryConfigType * pConfig)2824 static void Qspi_Ip_SfdpGetBasicWriteInfo(const Qspi_Ip_SfdpTablesContainer *sfdpTables,
2825 Qspi_Ip_MemoryConfigType * pConfig
2826 )
2827 {
2828 uint8 supported;
2829 Qspi_Ip_LutPadsType instPads;
2830 Qspi_Ip_LutPadsType addrPads;
2831 Qspi_Ip_LutPadsType dataPads;
2832 uint8 addrBits;
2833 uint8 instruction;
2834
2835 /* check if 4-byte write corresponding to the current read mode is supported */
2836 supported = (uint8)Qspi_Ip_SfdpGet4BAddParam(sfdpTables, write4ByteSupDword[modeIndex],
2837 write4ByteSupShift[modeIndex], QSPI_IP_SFDP_4BADD_INSTR_SUP_DWORD, 0x0);
2838 if (supported == 1U)
2839 {
2840 addrBits = 32U;
2841 instruction = write4ByteInst[modeIndex];
2842 instPads = readModeInstPads[modeIndex];
2843 addrPads = readModeAddrPads[modeIndex];
2844 dataPads = readModeDataPads[modeIndex];
2845 }
2846 else
2847 {
2848 /* No 4-byte write support, use basic write since SFDP does not specify other write modes */
2849 addrBits = basicAddrBits;
2850 instruction = QSPI_IP_CMD_BASIC_WRITE;
2851 instPads = cmdPads;
2852 addrPads = cmdPads;
2853 dataPads = cmdPads;
2854 }
2855 /* Get LUT index */
2856 pConfig->writeLut = lutCount;
2857 /* Build LUT */
2858 Qspi_Ip_SfdpLutAdd(&(pConfig->lutSequences), Qspi_Ip_PackLut(QSPI_IP_LUT_INSTR_CMD, instPads, instruction));
2859 Qspi_Ip_SfdpLutAdd(&(pConfig->lutSequences), Qspi_Ip_PackLut(QSPI_IP_LUT_INSTR_ADDR, addrPads, addrBits));
2860 Qspi_Ip_SfdpLutAdd(&(pConfig->lutSequences), Qspi_Ip_PackLut(QSPI_IP_LUT_INSTR_WRITE, dataPads, 0x10U));
2861 Qspi_Ip_SfdpLutAdd(&(pConfig->lutSequences), Qspi_Ip_PackLut(QSPI_IP_LUT_INSTR_STOP, QSPI_IP_LUT_PADS_1, 0x0U));
2862 }
2863
2864
2865 /*FUNCTION**********************************************************************
2866 *
2867 * Function Name : Qspi_Ip_SfdpGetXspi1ReadInfo
2868 * Description : Builds configuration for octal DDR (DOPI) mode.
2869 */
Qspi_Ip_SfdpGetXspi1ReadInfo(const Qspi_Ip_SfdpTablesContainer * sfdpTables,Qspi_Ip_MemoryConfigType * pConfig)2870 static void Qspi_Ip_SfdpGetXspi1ReadInfo(const Qspi_Ip_SfdpTablesContainer *sfdpTables,
2871 Qspi_Ip_MemoryConfigType *pConfig
2872 )
2873 {
2874 uint8 readInst;
2875 uint8 cmdExt;
2876 uint8 dummy;
2877
2878 /* Get fast read instruction */
2879 readInst = (uint8)Qspi_Ip_SfdpGetXspi1Param(sfdpTables, QSPI_IP_SFDP_XSPI1_READ_FAST_DWORD,
2880 QSPI_IP_SFDP_XSPI1_READ_FAST_SHIFT, QSPI_IP_SFDP_XSPI1_READ_FAST_WIDTH, 0xEEU);
2881 /* Get Command Extension */
2882 cmdExt = Qspi_Ip_SfdpGetCmdExt(sfdpTables, readInst);
2883 /* Get Dummy cycles */
2884 dummy = (uint8)Qspi_Ip_SfdpGetXspi1Param(sfdpTables, QSPI_IP_SFDP_XSPI1_DUMMY_DWORD,
2885 QSPI_IP_SFDP_XSPI1_DUMMY_SHIFT, QSPI_IP_SFDP_XSPI1_DUMMY_WIDTH, 20U);
2886
2887 /* Get LUT index */
2888 pConfig->readLut = lutCount;
2889 /* Build LUT command */
2890 Qspi_Ip_SfdpLutAdd(&(pConfig->lutSequences), Qspi_Ip_PackLut(QSPI_IP_LUT_INSTR_CMD_DDR, QSPI_IP_LUT_PADS_8, readInst));
2891 Qspi_Ip_SfdpLutAdd(&(pConfig->lutSequences), Qspi_Ip_PackLut(QSPI_IP_LUT_INSTR_CMD_DDR, QSPI_IP_LUT_PADS_8, cmdExt));
2892 Qspi_Ip_SfdpLutAdd(&(pConfig->lutSequences), Qspi_Ip_PackLut(QSPI_IP_LUT_INSTR_ADDR_DDR, QSPI_IP_LUT_PADS_8, (uint8)32U));
2893 Qspi_Ip_SfdpLutAdd(&(pConfig->lutSequences), Qspi_Ip_PackLut(QSPI_IP_LUT_INSTR_DUMMY, QSPI_IP_LUT_PADS_8, dummy));
2894 Qspi_Ip_SfdpLutAdd(&(pConfig->lutSequences), Qspi_Ip_PackLut(QSPI_IP_LUT_INSTR_READ_DDR, QSPI_IP_LUT_PADS_8, 0x10U));
2895 Qspi_Ip_SfdpLutAdd(&(pConfig->lutSequences), Qspi_Ip_PackLut(QSPI_IP_LUT_INSTR_STOP, QSPI_IP_LUT_PADS_1, 0x0U));
2896 }
2897
2898
2899 /*FUNCTION**********************************************************************
2900 *
2901 * Function Name : Qspi_Ip_SfdpGetXspi1WriteInfo
2902 * Description : Builds configuration for octal DDR (DOPI) mode.
2903 */
Qspi_Ip_SfdpGetXspi1WriteInfo(const Qspi_Ip_SfdpTablesContainer * sfdpTables,Qspi_Ip_MemoryConfigType * pConfig)2904 static void Qspi_Ip_SfdpGetXspi1WriteInfo(const Qspi_Ip_SfdpTablesContainer *sfdpTables,
2905 Qspi_Ip_MemoryConfigType *pConfig
2906 )
2907 {
2908 uint8 writeInst;
2909 uint8 cmdExt;
2910
2911 /* Page program instruction - not in SFDP table */
2912 writeInst = QSPI_IP_CMD_XSPI_WRITE;
2913 /* Get Command Extension */
2914 cmdExt = Qspi_Ip_SfdpGetCmdExt(sfdpTables, writeInst);
2915
2916 /* Get LUT index */
2917 pConfig->writeLut = lutCount;
2918 /* Build LUT command */
2919 Qspi_Ip_SfdpLutAdd(&(pConfig->lutSequences), Qspi_Ip_PackLut(QSPI_IP_LUT_INSTR_CMD_DDR, QSPI_IP_LUT_PADS_8, writeInst));
2920 Qspi_Ip_SfdpLutAdd(&(pConfig->lutSequences), Qspi_Ip_PackLut(QSPI_IP_LUT_INSTR_CMD_DDR, QSPI_IP_LUT_PADS_8, cmdExt));
2921 Qspi_Ip_SfdpLutAdd(&(pConfig->lutSequences), Qspi_Ip_PackLut(QSPI_IP_LUT_INSTR_ADDR_DDR, QSPI_IP_LUT_PADS_8, (uint8)32U));
2922 Qspi_Ip_SfdpLutAdd(&(pConfig->lutSequences), Qspi_Ip_PackLut(QSPI_IP_LUT_INSTR_WRITE_DDR, QSPI_IP_LUT_PADS_8, 0x10U));
2923 Qspi_Ip_SfdpLutAdd(&(pConfig->lutSequences), Qspi_Ip_PackLut(QSPI_IP_LUT_INSTR_STOP, QSPI_IP_LUT_PADS_1, 0x0U));
2924 }
2925
2926
2927 /*FUNCTION**********************************************************************
2928 *
2929 * Function Name : Qspi_Ip_SfdpGetBasicEraseInstr
2930 * Description : Returns instructions for erase type <cnt>.
2931 */
Qspi_Ip_SfdpGetBasicEraseInstr(const Qspi_Ip_SfdpTablesContainer * sfdpTables,uint8 cnt,uint8 * addrbits)2932 static uint8 Qspi_Ip_SfdpGetBasicEraseInstr(const Qspi_Ip_SfdpTablesContainer *sfdpTables,
2933 uint8 cnt,
2934 uint8 *addrbits
2935 )
2936 {
2937 uint8 addr4;
2938 uint8 eraseInst;
2939
2940 /* Check 4-byte instr. support */
2941 addr4 = (uint8)Qspi_Ip_SfdpGet4BAddParam(sfdpTables, QSPI_IP_SFDP_4BADD_INSTR_SUP_DWORD,
2942 erase4ByteSupShift[cnt], QSPI_IP_SFDP_4BADD_INSTR_SUP_WIDTH, 0x0U);
2943 if (addr4 == 1U)
2944 {
2945 /* Get erase instruction from 4-byte address instructions table */
2946 eraseInst = (uint8)Qspi_Ip_SfdpGet4BAddParam(sfdpTables, QSPI_IP_SFDP_4BADD_ERASE_INST_DWORD,
2947 erase4ByteInstShift[cnt], QSPI_IP_SFDP_4BADD_ERASE_INST_WIDTH, 0x0U);
2948 *addrbits = 32U;
2949 }
2950 else
2951 {
2952 /* Get erase instruction from basic parameters table */
2953 eraseInst = (uint8)Qspi_Ip_SfdpGetBasicParam(sfdpTables, eraseInstDword[cnt],
2954 eraseInstShift[cnt], eraseInstWidth[cnt], 0x0U);
2955
2956 /* No matter the device is operating in 3-Byte or 4-byte Address Mode,
2957 the Erase with 4-Byte Address instruction will always require 32-bit address */
2958 if (eraseInst == erase4ByteInst[cnt])
2959 {
2960 *addrbits = 32U;
2961 }
2962 else
2963 {
2964 *addrbits = basicAddrBits;
2965 }
2966 }
2967 return eraseInst;
2968 }
2969
2970
2971 /*FUNCTION**********************************************************************
2972 *
2973 * Function Name : Qspi_Ip_SfdpGetXspi1EraseInstr
2974 * Description : Returns instructions for erase type <cnt>.
2975 */
Qspi_Ip_SfdpGetXspi1EraseInstr(const Qspi_Ip_SfdpTablesContainer * sfdpTables,uint8 cnt)2976 static uint8 Qspi_Ip_SfdpGetXspi1EraseInstr(const Qspi_Ip_SfdpTablesContainer *sfdpTables,
2977 uint8 cnt
2978 )
2979 {
2980 uint8 addr4;
2981 uint8 eraseInst;
2982
2983 /* Check 4-byte instr. support */
2984 addr4 = (uint8)Qspi_Ip_SfdpGet4BAddParam(sfdpTables, QSPI_IP_SFDP_4BADD_INSTR_SUP_DWORD,
2985 erase4ByteSupShift[cnt], QSPI_IP_SFDP_4BADD_INSTR_SUP_WIDTH, 0x0U);
2986 if (addr4 == 1U)
2987 {
2988 /* Get erase instruction from 4-byte address instructions table */
2989 eraseInst = (uint8)Qspi_Ip_SfdpGet4BAddParam(sfdpTables, QSPI_IP_SFDP_4BADD_ERASE_INST_DWORD,
2990 erase4ByteInstShift[cnt], QSPI_IP_SFDP_4BADD_ERASE_INST_WIDTH, 0x0U);
2991 }
2992 else
2993 {
2994 /* Get erase instruction from basic parameters table */
2995 eraseInst = (uint8)Qspi_Ip_SfdpGetBasicParam(sfdpTables, eraseInstDword[cnt],
2996 eraseInstShift[cnt], eraseInstWidth[cnt], 0x0U);
2997 }
2998 return eraseInst;
2999 }
3000
3001
3002 /*FUNCTION**********************************************************************
3003 *
3004 * Function Name : Qspi_Ip_SfdpGetBasicEraseInfo
3005 * Description : Builds configuration for SPI mode.
3006 */
Qspi_Ip_SfdpGetBasicEraseInfo(const Qspi_Ip_SfdpTablesContainer * sfdpTables,Qspi_Ip_MemoryConfigType * pConfig)3007 static void Qspi_Ip_SfdpGetBasicEraseInfo(const Qspi_Ip_SfdpTablesContainer *sfdpTables,
3008 Qspi_Ip_MemoryConfigType * pConfig
3009 )
3010 {
3011 uint8 eraseInst;
3012 uint8 eraseSize;
3013 uint8 addrbits;
3014 uint8 cnt;
3015
3016 /* Loop through the 4 possible erase types */
3017 for (cnt = 0U; cnt < 4U; cnt++)
3018 {
3019 /* Get erase size */
3020 eraseSize = (uint8)Qspi_Ip_SfdpGetBasicParam(sfdpTables, eraseSizeDword[cnt],
3021 eraseSizeShift[cnt], eraseSizeWidth[cnt], 0x0U);
3022 pConfig->eraseSettings.eraseTypes[cnt].size = eraseSize;
3023 if (eraseSize > 0U)
3024 {
3025 /* Get erase instruction */
3026 eraseInst = Qspi_Ip_SfdpGetBasicEraseInstr(sfdpTables, cnt, &addrbits);
3027 /* Get LUT index */
3028 pConfig->eraseSettings.eraseTypes[cnt].eraseLut = lutCount;
3029 /* Build LUT command */
3030 Qspi_Ip_SfdpLutAdd(&(pConfig->lutSequences), Qspi_Ip_PackLut(QSPI_IP_LUT_INSTR_CMD, cmdPads, eraseInst));
3031 Qspi_Ip_SfdpLutAdd(&(pConfig->lutSequences), Qspi_Ip_PackLut(QSPI_IP_LUT_INSTR_ADDR, cmdPads, (uint8)addrbits));
3032 Qspi_Ip_SfdpLutAdd(&(pConfig->lutSequences), Qspi_Ip_PackLut(QSPI_IP_LUT_INSTR_STOP, QSPI_IP_LUT_PADS_1, 0x0U));
3033 }
3034 else
3035 {
3036 /* Erase type not supported */
3037 pConfig->eraseSettings.eraseTypes[cnt].eraseLut = QSPI_IP_LUT_INVALID;
3038 }
3039 }
3040
3041 /* Chip erase */
3042 eraseInst = QSPI_IP_CMD_BASIC_CHIP_ERASE;
3043 pConfig->eraseSettings.chipEraseLut = lutCount;
3044 Qspi_Ip_SfdpLutAdd(&(pConfig->lutSequences), Qspi_Ip_PackLut(QSPI_IP_LUT_INSTR_CMD, cmdPads, eraseInst));
3045 Qspi_Ip_SfdpLutAdd(&(pConfig->lutSequences), Qspi_Ip_PackLut(QSPI_IP_LUT_INSTR_STOP, QSPI_IP_LUT_PADS_1, 0x0U));
3046 }
3047
3048
3049 /*FUNCTION**********************************************************************
3050 *
3051 * Function Name : Qspi_Ip_SfdpGetXspi1EraseInfo
3052 * Description : Builds configuration for octal DDR (DOPI) mode.
3053 */
Qspi_Ip_SfdpGetXspi1EraseInfo(const Qspi_Ip_SfdpTablesContainer * sfdpTables,Qspi_Ip_MemoryConfigType * pConfig)3054 static void Qspi_Ip_SfdpGetXspi1EraseInfo(const Qspi_Ip_SfdpTablesContainer *sfdpTables,
3055 Qspi_Ip_MemoryConfigType *pConfig
3056 )
3057 {
3058 uint8 eraseInst;
3059 uint8 eraseSize;
3060 uint8 eraseExt;
3061 uint8 cnt;
3062
3063 /* Loop through the 4 possible erase types */
3064 for (cnt = 0U; cnt < 4U; cnt++)
3065 {
3066 /* Get erase size */
3067 eraseSize = (uint8)Qspi_Ip_SfdpGetBasicParam(sfdpTables, eraseSizeDword[cnt],
3068 eraseSizeShift[cnt], eraseSizeWidth[cnt], 0x0U);
3069 pConfig->eraseSettings.eraseTypes[cnt].size = eraseSize;
3070 if (eraseSize > 0U)
3071 {
3072 /* Get erase instruction */
3073 eraseInst = Qspi_Ip_SfdpGetXspi1EraseInstr(sfdpTables, cnt);
3074 eraseExt = Qspi_Ip_SfdpGetCmdExt(sfdpTables, eraseInst);
3075 /* Get LUT index */
3076 pConfig->eraseSettings.eraseTypes[cnt].eraseLut = lutCount;
3077 /* Build LUT command */
3078 Qspi_Ip_SfdpLutAdd(&(pConfig->lutSequences), Qspi_Ip_PackLut(QSPI_IP_LUT_INSTR_CMD_DDR, QSPI_IP_LUT_PADS_8, eraseInst));
3079 Qspi_Ip_SfdpLutAdd(&(pConfig->lutSequences), Qspi_Ip_PackLut(QSPI_IP_LUT_INSTR_CMD_DDR, QSPI_IP_LUT_PADS_8, eraseExt));
3080 Qspi_Ip_SfdpLutAdd(&(pConfig->lutSequences), Qspi_Ip_PackLut(QSPI_IP_LUT_INSTR_ADDR_DDR, QSPI_IP_LUT_PADS_8, (uint8)32U));
3081 Qspi_Ip_SfdpLutAdd(&(pConfig->lutSequences), Qspi_Ip_PackLut(QSPI_IP_LUT_INSTR_STOP, QSPI_IP_LUT_PADS_1, 0x0U));
3082 }
3083 else
3084 {
3085 /* Erase type not supported */
3086 pConfig->eraseSettings.eraseTypes[cnt].eraseLut = QSPI_IP_LUT_INVALID;
3087 }
3088 }
3089
3090 /* Check chip erase support */
3091 eraseInst = (uint8)Qspi_Ip_SfdpGetXspi1Param(sfdpTables, QSPI_IP_SFDP_XSPI1_CHIP_ERASE_DWORD,
3092 QSPI_IP_SFDP_XSPI1_CHIP_ERASE_SHIFT, QSPI_IP_SFDP_XSPI1_CHIP_ERASE_WIDTH, 0x0U);
3093 if (eraseInst == 0U)
3094 {
3095 pConfig->eraseSettings.chipEraseLut = QSPI_IP_LUT_INVALID;
3096 }
3097 else
3098 {
3099 pConfig->eraseSettings.chipEraseLut = lutCount;
3100 /* Build LUT command */
3101 eraseInst = QSPI_IP_CMD_XSPI_CHIP_ERASE;
3102 eraseExt = Qspi_Ip_SfdpGetCmdExt(sfdpTables, eraseInst);
3103 Qspi_Ip_SfdpLutAdd(&(pConfig->lutSequences), Qspi_Ip_PackLut(QSPI_IP_LUT_INSTR_CMD_DDR, QSPI_IP_LUT_PADS_8, eraseInst));
3104 Qspi_Ip_SfdpLutAdd(&(pConfig->lutSequences), Qspi_Ip_PackLut(QSPI_IP_LUT_INSTR_CMD_DDR, QSPI_IP_LUT_PADS_8, eraseExt));
3105 Qspi_Ip_SfdpLutAdd(&(pConfig->lutSequences), Qspi_Ip_PackLut(QSPI_IP_LUT_INSTR_STOP, QSPI_IP_LUT_PADS_1, 0x0U));
3106 }
3107 }
3108
3109
3110 /*FUNCTION**********************************************************************
3111 *
3112 * Function Name : Qspi_Ip_SfdpGetBasicStatusInfo
3113 * Description : Builds configuration for SPI mode.
3114 */
Qspi_Ip_SfdpGetBasicStatusInfo(const Qspi_Ip_SfdpTablesContainer * sfdpTables,Qspi_Ip_MemoryConfigType * pConfig)3115 static void Qspi_Ip_SfdpGetBasicStatusInfo(const Qspi_Ip_SfdpTablesContainer *sfdpTables,
3116 Qspi_Ip_MemoryConfigType *pConfig
3117 )
3118 {
3119 uint8 instruction;
3120 Qspi_Ip_StatusConfigType *statusConfig;
3121
3122 statusConfig = &(pConfig->statusConfig);
3123
3124 /* Build LUT sequence for read status reg. */
3125 if (QSPI_IP_LUT_PADS_1 == cmdPads)
3126 {
3127 /* Use same sequence */
3128 statusConfig->statusRegReadLut = statusConfig->statusRegInitReadLut;
3129 }
3130 else
3131 {
3132 statusConfig->statusRegReadLut = lutCount;
3133 instruction = QSPI_IP_CMD_BASIC_READ_SR;
3134 Qspi_Ip_SfdpLutAdd(&(pConfig->lutSequences), Qspi_Ip_PackLut(QSPI_IP_LUT_INSTR_CMD, cmdPads, instruction));
3135 Qspi_Ip_SfdpLutAdd(&(pConfig->lutSequences), Qspi_Ip_PackLut(QSPI_IP_LUT_INSTR_READ, cmdPads, 0x10));
3136 Qspi_Ip_SfdpLutAdd(&(pConfig->lutSequences), Qspi_Ip_PackLut(QSPI_IP_LUT_INSTR_STOP, QSPI_IP_LUT_PADS_1, 0x0U));
3137 }
3138
3139 /* Build LUT sequence for write status reg. */
3140 statusConfig->statusRegWriteLut = lutCount;
3141 instruction = QSPI_IP_CMD_BASIC_WRITE_SR;
3142 Qspi_Ip_SfdpLutAdd(&(pConfig->lutSequences), Qspi_Ip_PackLut(QSPI_IP_LUT_INSTR_CMD, cmdPads, instruction));
3143 Qspi_Ip_SfdpLutAdd(&(pConfig->lutSequences), Qspi_Ip_PackLut(QSPI_IP_LUT_INSTR_WRITE, cmdPads, 0x1U));
3144 Qspi_Ip_SfdpLutAdd(&(pConfig->lutSequences), Qspi_Ip_PackLut(QSPI_IP_LUT_INSTR_STOP, QSPI_IP_LUT_PADS_1, 0x0U));
3145
3146 /* Build LUT sequence for write enable */
3147 statusConfig->writeEnableLut = lutCount;
3148 instruction = QSPI_IP_CMD_BASIC_WRITE_ENABLE;
3149 Qspi_Ip_SfdpLutAdd(&(pConfig->lutSequences), Qspi_Ip_PackLut(QSPI_IP_LUT_INSTR_CMD, cmdPads, instruction));
3150 Qspi_Ip_SfdpLutAdd(&(pConfig->lutSequences), Qspi_Ip_PackLut(QSPI_IP_LUT_INSTR_STOP, QSPI_IP_LUT_PADS_1, 0x0U));
3151
3152 /* Build LUT sequence for SR write enable */
3153 instruction = Qspi_Ip_SfdpGetWeSrInstr(sfdpTables);
3154 if (QSPI_IP_CMD_BASIC_WRITE_ENABLE == instruction)
3155 {
3156 statusConfig->writeEnableSRLut = statusConfig->writeEnableLut;
3157 }
3158 else
3159 {
3160 statusConfig->writeEnableSRLut = lutCount;
3161 Qspi_Ip_SfdpLutAdd(&(pConfig->lutSequences), Qspi_Ip_PackLut(QSPI_IP_LUT_INSTR_CMD, cmdPads, instruction));
3162 Qspi_Ip_SfdpLutAdd(&(pConfig->lutSequences), Qspi_Ip_PackLut(QSPI_IP_LUT_INSTR_STOP, QSPI_IP_LUT_PADS_1, 0x0U));
3163 }
3164 }
3165
3166
3167 /*FUNCTION**********************************************************************
3168 *
3169 * Function Name : Qspi_Ip_SfdpGetXspi1StatusInfo
3170 * Description : Builds configuration for octal DDR (DOPI) mode.
3171 */
Qspi_Ip_SfdpGetXspi1StatusInfo(const Qspi_Ip_SfdpTablesContainer * sfdpTables,Qspi_Ip_MemoryConfigType * pConfig)3172 static void Qspi_Ip_SfdpGetXspi1StatusInfo(const Qspi_Ip_SfdpTablesContainer *sfdpTables,
3173 Qspi_Ip_MemoryConfigType *pConfig
3174 )
3175 {
3176 uint8 instruction;
3177 uint8 cmdExt;
3178 uint8 dummy;
3179 Qspi_Ip_StatusConfigType *statusConfig;
3180
3181 statusConfig = &(pConfig->statusConfig);
3182
3183 /* Build LUT sequence for read status reg. */
3184 statusConfig->statusRegReadLut = lutCount;
3185 instruction = QSPI_IP_CMD_XSPI_READ_SR;
3186 cmdExt = Qspi_Ip_SfdpGetCmdExt(sfdpTables, instruction);
3187 dummy = (uint8)Qspi_Ip_SfdpGetSRMapParam(sfdpTables, QSPI_IP_SFDP_SRMAP_DUMMY_8D_DWORD,
3188 QSPI_IP_SFDP_SRMAP_DUMMY_8D_SHIFT, QSPI_IP_SFDP_SRMAP_DUMMY_8D_WIDTH, 0x0U);
3189 Qspi_Ip_SfdpLutAdd(&(pConfig->lutSequences), Qspi_Ip_PackLut(QSPI_IP_LUT_INSTR_CMD_DDR, QSPI_IP_LUT_PADS_8, instruction));
3190 Qspi_Ip_SfdpLutAdd(&(pConfig->lutSequences), Qspi_Ip_PackLut(QSPI_IP_LUT_INSTR_CMD_DDR, QSPI_IP_LUT_PADS_8, cmdExt));
3191 Qspi_Ip_SfdpLutAddSrAddr(&(pConfig->lutSequences), sfdpTables);
3192 if (dummy != 0U)
3193 {
3194 Qspi_Ip_SfdpLutAdd(&(pConfig->lutSequences), Qspi_Ip_PackLut(QSPI_IP_LUT_INSTR_DUMMY, QSPI_IP_LUT_PADS_8, dummy));
3195 }
3196 Qspi_Ip_SfdpLutAdd(&(pConfig->lutSequences), Qspi_Ip_PackLut(QSPI_IP_LUT_INSTR_READ_DDR, QSPI_IP_LUT_PADS_8, 0x10));
3197 Qspi_Ip_SfdpLutAdd(&(pConfig->lutSequences), Qspi_Ip_PackLut(QSPI_IP_LUT_INSTR_STOP, QSPI_IP_LUT_PADS_1, 0x0U));
3198
3199 /* Build LUT sequence for write status reg. */
3200 statusConfig->statusRegWriteLut = lutCount;
3201 instruction = QSPI_IP_CMD_XSPI_WRITE_SR;
3202 cmdExt = Qspi_Ip_SfdpGetCmdExt(sfdpTables, instruction);
3203 Qspi_Ip_SfdpLutAdd(&(pConfig->lutSequences), Qspi_Ip_PackLut(QSPI_IP_LUT_INSTR_CMD_DDR, QSPI_IP_LUT_PADS_8, instruction));
3204 Qspi_Ip_SfdpLutAdd(&(pConfig->lutSequences), Qspi_Ip_PackLut(QSPI_IP_LUT_INSTR_CMD_DDR, QSPI_IP_LUT_PADS_8, cmdExt));
3205 Qspi_Ip_SfdpLutAddSrAddr(&(pConfig->lutSequences), sfdpTables);
3206 /* Use SDR write because reg. size is 1 */
3207 Qspi_Ip_SfdpLutAdd(&(pConfig->lutSequences), Qspi_Ip_PackLut(QSPI_IP_LUT_INSTR_WRITE, QSPI_IP_LUT_PADS_8, 0x2U));
3208 Qspi_Ip_SfdpLutAdd(&(pConfig->lutSequences), Qspi_Ip_PackLut(QSPI_IP_LUT_INSTR_STOP, QSPI_IP_LUT_PADS_1, 0x0U));
3209
3210 /* Build LUT sequence for write enable */
3211 statusConfig->writeEnableSRLut = lutCount;
3212 statusConfig->writeEnableLut = lutCount;
3213 instruction = QSPI_IP_CMD_XSPI_WRITE_ENABLE;
3214 cmdExt = Qspi_Ip_SfdpGetCmdExt(sfdpTables, instruction);
3215 Qspi_Ip_SfdpLutAdd(&(pConfig->lutSequences), Qspi_Ip_PackLut(QSPI_IP_LUT_INSTR_CMD_DDR, QSPI_IP_LUT_PADS_8, instruction));
3216 Qspi_Ip_SfdpLutAdd(&(pConfig->lutSequences), Qspi_Ip_PackLut(QSPI_IP_LUT_INSTR_CMD_DDR, QSPI_IP_LUT_PADS_8, cmdExt));
3217 Qspi_Ip_SfdpLutAdd(&(pConfig->lutSequences), Qspi_Ip_PackLut(QSPI_IP_LUT_INSTR_STOP, QSPI_IP_LUT_PADS_1, 0x0U));
3218 }
3219
3220
3221 /*FUNCTION**********************************************************************
3222 *
3223 * Function Name : Qspi_Ip_SfdpConfigReset1
3224 * Description : Configure reset settings - option 1.
3225 */
Qspi_Ip_SfdpConfigReset1(const Qspi_Ip_MemoryConfigType * pConfig,const Qspi_Ip_ResetConfigType * resetSettings,Qspi_Ip_LutPadsType pads)3226 static void Qspi_Ip_SfdpConfigReset1(const Qspi_Ip_MemoryConfigType * pConfig,
3227 const Qspi_Ip_ResetConfigType *resetSettings,
3228 Qspi_Ip_LutPadsType pads
3229 )
3230 {
3231 /* drive Fh on all 4 data wires for 8 clocks */
3232 /* Not implemented */
3233 (void)pConfig;
3234 (void)resetSettings;
3235 (void)pads;
3236 }
3237
3238
3239 /*FUNCTION**********************************************************************
3240 *
3241 * Function Name : Qspi_Ip_SfdpConfigReset2
3242 * Description : Configure reset settings - option 2.
3243 */
Qspi_Ip_SfdpConfigReset2(const Qspi_Ip_MemoryConfigType * pConfig,const Qspi_Ip_ResetConfigType * resetSettings,Qspi_Ip_LutPadsType pads)3244 static void Qspi_Ip_SfdpConfigReset2(const Qspi_Ip_MemoryConfigType * pConfig,
3245 const Qspi_Ip_ResetConfigType *resetSettings,
3246 Qspi_Ip_LutPadsType pads
3247 )
3248 {
3249 /* drive Fh on all 4 data wires for 10 clocks if device is operating in 4-byte address mode */
3250 /* Not implemented */
3251 (void)pConfig;
3252 (void)resetSettings;
3253 (void)pads;
3254 }
3255
3256
3257 /*FUNCTION**********************************************************************
3258 *
3259 * Function Name : Qspi_Ip_SfdpConfigReset4
3260 * Description : Configure reset settings - option 4.
3261 */
Qspi_Ip_SfdpConfigReset4(const Qspi_Ip_MemoryConfigType * pConfig,const Qspi_Ip_ResetConfigType * resetSettings,Qspi_Ip_LutPadsType pads)3262 static void Qspi_Ip_SfdpConfigReset4(const Qspi_Ip_MemoryConfigType * pConfig,
3263 const Qspi_Ip_ResetConfigType *resetSettings,
3264 Qspi_Ip_LutPadsType pads
3265 )
3266 {
3267 /* drive Fh on all 4 data wires for 16 clocks */
3268 /* Not implemented */
3269 (void)pConfig;
3270 (void)resetSettings;
3271 (void)pads;
3272 }
3273
3274
3275 /*FUNCTION**********************************************************************
3276 *
3277 * Function Name : Qspi_Ip_SfdpConfigReset8
3278 * Description : Configure reset settings - option 8.
3279 */
Qspi_Ip_SfdpConfigReset8(const Qspi_Ip_MemoryConfigType * pConfig,Qspi_Ip_ResetConfigType * resetSettings,Qspi_Ip_LutPadsType pads)3280 static void Qspi_Ip_SfdpConfigReset8(const Qspi_Ip_MemoryConfigType * pConfig,
3281 Qspi_Ip_ResetConfigType *resetSettings,
3282 Qspi_Ip_LutPadsType pads
3283 )
3284 {
3285 /* issue instruction F0h */
3286 resetSettings->resetCmdLut = lutCount;
3287 resetSettings->resetCmdCount = 1U;
3288 /* Build LUT sequence */
3289 Qspi_Ip_SfdpLutAdd(&(pConfig->lutSequences), Qspi_Ip_PackLut(QSPI_IP_LUT_INSTR_CMD, pads, 0xF0U));
3290 Qspi_Ip_SfdpLutAdd(&(pConfig->lutSequences), Qspi_Ip_PackLut(QSPI_IP_LUT_INSTR_STOP, QSPI_IP_LUT_PADS_1, 0x0U));
3291 }
3292
3293
3294 /*FUNCTION**********************************************************************
3295 *
3296 * Function Name : Qspi_Ip_SfdpConfigReset16
3297 * Description : Configure reset settings - option 16.
3298 */
Qspi_Ip_SfdpConfigReset16(const Qspi_Ip_MemoryConfigType * pConfig,Qspi_Ip_ResetConfigType * resetSettings,Qspi_Ip_LutPadsType pads)3299 static void Qspi_Ip_SfdpConfigReset16(const Qspi_Ip_MemoryConfigType * pConfig,
3300 Qspi_Ip_ResetConfigType *resetSettings,
3301 Qspi_Ip_LutPadsType pads
3302 )
3303 {
3304 /* issue reset enable instruction 66h, then issue reset instruction 99h.
3305 The reset enable, reset sequence may be issued on 1, 2, 4, or 8 wires depending on the device operating mode. */
3306 resetSettings->resetCmdLut = lutCount;
3307 resetSettings->resetCmdCount = 2U;
3308 /* 1st LUT sequence - 0x66 */
3309 Qspi_Ip_SfdpLutAdd(&(pConfig->lutSequences), Qspi_Ip_PackLut(QSPI_IP_LUT_INSTR_CMD, pads, 0x66U));
3310 Qspi_Ip_SfdpLutAdd(&(pConfig->lutSequences), Qspi_Ip_PackLut(QSPI_IP_LUT_INSTR_STOP, QSPI_IP_LUT_PADS_1, 0x0U));
3311 /* 2nd LUT sequence - 0x99 */
3312 Qspi_Ip_SfdpLutAdd(&(pConfig->lutSequences), Qspi_Ip_PackLut(QSPI_IP_LUT_INSTR_CMD, pads, 0x99U));
3313 Qspi_Ip_SfdpLutAdd(&(pConfig->lutSequences), Qspi_Ip_PackLut(QSPI_IP_LUT_INSTR_STOP, QSPI_IP_LUT_PADS_1, 0x0U));
3314 }
3315
3316 /*FUNCTION**********************************************************************
3317 *
3318 * Function Name : Qspi_Ip_SfdpConfigResetOthers
3319 * Description : Configure reset settings for 1, 2, 4 wires
3320 */
Qspi_Ip_SfdpConfigResetOthers(uint8 resetOption,const Qspi_Ip_MemoryConfigType * pConfig,Qspi_Ip_ResetConfigType * resetSettings,Qspi_Ip_LutPadsType pads)3321 static void Qspi_Ip_SfdpConfigResetOthers(uint8 resetOption,
3322 const Qspi_Ip_MemoryConfigType * pConfig,
3323 Qspi_Ip_ResetConfigType *resetSettings,
3324 Qspi_Ip_LutPadsType pads
3325 )
3326 {
3327 if ((resetOption & 0x1U) != 0U)
3328 {
3329 Qspi_Ip_SfdpConfigReset1(pConfig, resetSettings, pads);
3330 /* drive Fh on all 4 data wires for 8 clocks */
3331 }
3332 else if ((resetOption & 0x2U) != 0U)
3333 {
3334 Qspi_Ip_SfdpConfigReset2(pConfig, resetSettings, pads);
3335 /* drive Fh on all 4 data wires for 10 clocks if device is operating in 4-byte address mode */
3336 }
3337 else if ((resetOption & 0x4U) != 0U)
3338 {
3339 Qspi_Ip_SfdpConfigReset4(pConfig, resetSettings, pads);
3340 /* drive Fh on all 4 data wires for 16 clocks */
3341 }
3342 else
3343 {
3344 /* unknown reset sequence */
3345 resetSettings->resetCmdLut = QSPI_IP_LUT_INVALID;
3346 resetSettings->resetCmdCount = 0U;
3347 }
3348 }
3349
3350 /*FUNCTION**********************************************************************
3351 *
3352 * Function Name : Qspi_Ip_SfdpGetBasicResetInfo
3353 * Description : Configure reset settings - XPI mode.
3354 */
Qspi_Ip_SfdpGetBasicResetInfo(const Qspi_Ip_SfdpTablesContainer * sfdpTables,const Qspi_Ip_MemoryConfigType * pConfig,Qspi_Ip_ResetConfigType * resetSettings,Qspi_Ip_LutPadsType pads)3355 static void Qspi_Ip_SfdpGetBasicResetInfo(const Qspi_Ip_SfdpTablesContainer *sfdpTables,
3356 const Qspi_Ip_MemoryConfigType *pConfig,
3357 Qspi_Ip_ResetConfigType *resetSettings,
3358 Qspi_Ip_LutPadsType pads
3359 )
3360 {
3361 uint8 resetOption;
3362
3363 resetOption = (uint8)Qspi_Ip_SfdpGetBasicParam(sfdpTables, QSPI_IP_SFDP_BASIC_SW_RESET_DWORD,
3364 QSPI_IP_SFDP_BASIC_SW_RESET_SHIFT, QSPI_IP_SFDP_BASIC_SW_RESET_WIDTH, 0x0U);
3365 if ((resetOption & 0x10U) != 0U)
3366 {
3367 /* issue reset enable instruction 66h, then issue reset instruction 99h.
3368 The reset enable, reset sequence may be issued on 1, 2, 4, or 8 wires depending on the device operating mode. */
3369 Qspi_Ip_SfdpConfigReset16(pConfig, resetSettings, pads);
3370 }
3371 else if ((resetOption & 0x8U) != 0U)
3372 {
3373 Qspi_Ip_SfdpConfigReset8(pConfig, resetSettings, pads);
3374 /* issue instruction F0h */
3375 }
3376 else
3377 {
3378 Qspi_Ip_SfdpConfigResetOthers(resetOption, pConfig, resetSettings, pads);
3379 }
3380 }
3381
3382
3383 /*FUNCTION**********************************************************************
3384 *
3385 * Function Name : Qspi_Ip_SfdpGetXspi1ResetInfo
3386 * Description : Configure reset settings - XPI mode.
3387 */
Qspi_Ip_SfdpGetXspi1ResetInfo(const Qspi_Ip_SfdpTablesContainer * sfdpTables,Qspi_Ip_MemoryConfigType * pConfig)3388 static void Qspi_Ip_SfdpGetXspi1ResetInfo(const Qspi_Ip_SfdpTablesContainer *sfdpTables,
3389 Qspi_Ip_MemoryConfigType *pConfig
3390 )
3391 {
3392 uint8 rSup;
3393 uint8 rEnSup;
3394 uint8 instruction;
3395 uint8 cmdExt;
3396
3397 pConfig->resetSettings.resetCmdLut = QSPI_IP_LUT_INVALID;
3398 pConfig->resetSettings.resetCmdCount = 0U;
3399
3400 rEnSup = (uint8)Qspi_Ip_SfdpGetXspi1Param(sfdpTables, QSPI_IP_SFDP_XSPI1_RESET_EN_DWORD,
3401 QSPI_IP_SFDP_XSPI1_RESET_EN_SHIFT, QSPI_IP_SFDP_XSPI1_RESET_EN_WIDTH, 0x0U);
3402 rSup = (uint8)Qspi_Ip_SfdpGetXspi1Param(sfdpTables, QSPI_IP_SFDP_XSPI1_RESET_DEF_DWORD,
3403 QSPI_IP_SFDP_XSPI1_RESET_DEF_SHIFT, QSPI_IP_SFDP_XSPI1_RESET_DEF_WIDTH, 0x0U);
3404 if ((rEnSup == 1U) && (rSup == 1U))
3405 {
3406 /* 0x66, 0x99 reset sequence */
3407 pConfig->resetSettings.resetCmdLut = lutCount;
3408 pConfig->resetSettings.resetCmdCount = 2U;
3409 instruction = QSPI_IP_CMD_XSPI_RESET_ENABLE;
3410 cmdExt = Qspi_Ip_SfdpGetCmdExt(sfdpTables, instruction);
3411 Qspi_Ip_SfdpLutAdd(&(pConfig->lutSequences), Qspi_Ip_PackLut(QSPI_IP_LUT_INSTR_CMD_DDR, QSPI_IP_LUT_PADS_8, instruction));
3412 Qspi_Ip_SfdpLutAdd(&(pConfig->lutSequences), Qspi_Ip_PackLut(QSPI_IP_LUT_INSTR_CMD_DDR, QSPI_IP_LUT_PADS_8, cmdExt));
3413 Qspi_Ip_SfdpLutAdd(&(pConfig->lutSequences), Qspi_Ip_PackLut(QSPI_IP_LUT_INSTR_STOP, QSPI_IP_LUT_PADS_1, 0x0U));
3414
3415 instruction = QSPI_IP_CMD_XSPI_RESET_DEF;
3416 cmdExt = Qspi_Ip_SfdpGetCmdExt(sfdpTables, instruction);
3417 Qspi_Ip_SfdpLutAdd(&(pConfig->lutSequences), Qspi_Ip_PackLut(QSPI_IP_LUT_INSTR_CMD_DDR, QSPI_IP_LUT_PADS_8, instruction));
3418 Qspi_Ip_SfdpLutAdd(&(pConfig->lutSequences), Qspi_Ip_PackLut(QSPI_IP_LUT_INSTR_CMD_DDR, QSPI_IP_LUT_PADS_8, cmdExt));
3419 Qspi_Ip_SfdpLutAdd(&(pConfig->lutSequences), Qspi_Ip_PackLut(QSPI_IP_LUT_INSTR_STOP, QSPI_IP_LUT_PADS_1, 0x0U));
3420 }
3421 else
3422 {
3423 rSup = (uint8)Qspi_Ip_SfdpGetXspi1Param(sfdpTables, QSPI_IP_SFDP_XSPI1_RESET_DWORD,
3424 QSPI_IP_SFDP_XSPI1_RESET_SHIFT, QSPI_IP_SFDP_XSPI1_RESET_WIDTH, 0x0U);
3425 if (rSup == 1U)
3426 {
3427 /* 0xF0 reset command */
3428 pConfig->resetSettings.resetCmdLut = lutCount;
3429 pConfig->resetSettings.resetCmdCount = 1U;
3430 instruction = QSPI_IP_CMD_XSPI_RESET;
3431 cmdExt = Qspi_Ip_SfdpGetCmdExt(sfdpTables, instruction);
3432 Qspi_Ip_SfdpLutAdd(&(pConfig->lutSequences), Qspi_Ip_PackLut(QSPI_IP_LUT_INSTR_CMD_DDR, QSPI_IP_LUT_PADS_8, instruction));
3433 Qspi_Ip_SfdpLutAdd(&(pConfig->lutSequences), Qspi_Ip_PackLut(QSPI_IP_LUT_INSTR_CMD_DDR, QSPI_IP_LUT_PADS_8, cmdExt));
3434 Qspi_Ip_SfdpLutAdd(&(pConfig->lutSequences), Qspi_Ip_PackLut(QSPI_IP_LUT_INSTR_STOP, QSPI_IP_LUT_PADS_1, 0x0U));
3435 }
3436 }
3437 }
3438
3439
3440 /*FUNCTION**********************************************************************
3441 *
3442 * Function Name : Qspi_Ip_SfdpGetXspi1InitResetInfo
3443 * Description : Configure initial reset settings - XPI mode
3444 */
Qspi_Ip_SfdpGetXspi1InitResetInfo(const Qspi_Ip_SfdpTablesContainer * sfdpTables,Qspi_Ip_MemoryConfigType * pConfig)3445 static void Qspi_Ip_SfdpGetXspi1InitResetInfo(const Qspi_Ip_SfdpTablesContainer *sfdpTables,
3446 Qspi_Ip_MemoryConfigType *pConfig
3447 )
3448 {
3449 uint8 rSup;
3450 uint8 rEnSup;
3451 uint8 instruction;
3452
3453 /* Set the default value to be disabled */
3454 pConfig->initResetSettings.resetCmdLut = QSPI_IP_LUT_INVALID;
3455 pConfig->initResetSettings.resetCmdCount = 0U;
3456
3457 rEnSup = (uint8)Qspi_Ip_SfdpGetXspi1Param(sfdpTables, QSPI_IP_SFDP_XSPI1_RESET_EN_DWORD,
3458 QSPI_IP_SFDP_XSPI1_RESET_EN_SHIFT, QSPI_IP_SFDP_XSPI1_RESET_EN_WIDTH, 0x0U);
3459 rSup = (uint8)Qspi_Ip_SfdpGetXspi1Param(sfdpTables, QSPI_IP_SFDP_XSPI1_RESET_DEF_DWORD,
3460 QSPI_IP_SFDP_XSPI1_RESET_DEF_SHIFT, QSPI_IP_SFDP_XSPI1_RESET_DEF_WIDTH, 0x0U);
3461 if ((rEnSup == 1U) && (rSup == 1U))
3462 {
3463 /* 0x66, 0x99 reset sequence */
3464 pConfig->initResetSettings.resetCmdLut = lutCount;
3465 pConfig->initResetSettings.resetCmdCount = 2U;
3466 instruction = QSPI_IP_CMD_XSPI_RESET_ENABLE;
3467 Qspi_Ip_SfdpLutAdd(&(pConfig->lutSequences), Qspi_Ip_PackLut(QSPI_IP_LUT_INSTR_CMD, cmdPadsInit, instruction));
3468 Qspi_Ip_SfdpLutAdd(&(pConfig->lutSequences), Qspi_Ip_PackLut(QSPI_IP_LUT_INSTR_STOP, cmdPadsInit, 0x0U));
3469
3470 instruction = QSPI_IP_CMD_XSPI_RESET_DEF;
3471 Qspi_Ip_SfdpLutAdd(&(pConfig->lutSequences), Qspi_Ip_PackLut(QSPI_IP_LUT_INSTR_CMD, cmdPadsInit, instruction));
3472 Qspi_Ip_SfdpLutAdd(&(pConfig->lutSequences), Qspi_Ip_PackLut(QSPI_IP_LUT_INSTR_STOP, cmdPadsInit, 0x0U));
3473 }
3474 else
3475 {
3476 rSup = (uint8)Qspi_Ip_SfdpGetXspi1Param(sfdpTables, QSPI_IP_SFDP_XSPI1_RESET_DWORD,
3477 QSPI_IP_SFDP_XSPI1_RESET_SHIFT, QSPI_IP_SFDP_XSPI1_RESET_WIDTH, 0x0U);
3478 if (rSup == 1U)
3479 {
3480 /* 0xF0 reset command */
3481 pConfig->initResetSettings.resetCmdLut = lutCount;
3482 pConfig->initResetSettings.resetCmdCount = 1U;
3483 instruction = QSPI_IP_CMD_XSPI_RESET;
3484 Qspi_Ip_SfdpLutAdd(&(pConfig->lutSequences), Qspi_Ip_PackLut(QSPI_IP_LUT_INSTR_CMD, cmdPadsInit, instruction));
3485 Qspi_Ip_SfdpLutAdd(&(pConfig->lutSequences), Qspi_Ip_PackLut(QSPI_IP_LUT_INSTR_STOP, cmdPadsInit, 0x0U));
3486 }
3487 }
3488 }
3489
3490
3491 /*FUNCTION**********************************************************************
3492 *
3493 * Function Name : Qspi_Ip_SfdpGetBasicSuspendInfo
3494 * Description : Configure suspend settings - SPI mode
3495 */
Qspi_Ip_SfdpGetBasicSuspendInfo(const Qspi_Ip_SfdpTablesContainer * sfdpTables,Qspi_Ip_MemoryConfigType * pConfig)3496 static void Qspi_Ip_SfdpGetBasicSuspendInfo(const Qspi_Ip_SfdpTablesContainer *sfdpTables,
3497 Qspi_Ip_MemoryConfigType * pConfig
3498 )
3499 {
3500 uint8 esus;
3501 uint8 eres;
3502 uint8 psus;
3503 uint8 pres;
3504
3505 esus = (uint8)Qspi_Ip_SfdpGetBasicParam(sfdpTables, QSPI_IP_SFDP_BASIC_ESUS_INSTR_DWORD,
3506 QSPI_IP_SFDP_BASIC_ESUS_INSTR_SHIFT, QSPI_IP_SFDP_BASIC_ESUS_INSTR_WIDTH, 0xB0U);
3507 eres = (uint8)Qspi_Ip_SfdpGetBasicParam(sfdpTables, QSPI_IP_SFDP_BASIC_ERES_INSTR_DWORD,
3508 QSPI_IP_SFDP_BASIC_ERES_INSTR_SHIFT, QSPI_IP_SFDP_BASIC_ERES_INSTR_WIDTH, 0x30U);
3509 psus = (uint8)Qspi_Ip_SfdpGetBasicParam(sfdpTables, QSPI_IP_SFDP_BASIC_PSUS_INSTR_DWORD,
3510 QSPI_IP_SFDP_BASIC_PSUS_INSTR_SHIFT, QSPI_IP_SFDP_BASIC_PSUS_INSTR_WIDTH, 0xB0U);
3511 pres = (uint8)Qspi_Ip_SfdpGetBasicParam(sfdpTables, QSPI_IP_SFDP_BASIC_PRES_INSTR_DWORD,
3512 QSPI_IP_SFDP_BASIC_PRES_INSTR_SHIFT, QSPI_IP_SFDP_BASIC_PRES_INSTR_WIDTH, 0x30U);
3513
3514 /* Erase suspend sequence */
3515 pConfig->suspendSettings.eraseSuspendLut = lutCount;
3516 Qspi_Ip_SfdpLutAdd(&(pConfig->lutSequences), Qspi_Ip_PackLut(QSPI_IP_LUT_INSTR_CMD, cmdPads, esus));
3517 Qspi_Ip_SfdpLutAdd(&(pConfig->lutSequences), Qspi_Ip_PackLut(QSPI_IP_LUT_INSTR_STOP, QSPI_IP_LUT_PADS_1, 0x0U));
3518 /* Erase resume sequence */
3519 pConfig->suspendSettings.eraseResumeLut = lutCount;
3520 Qspi_Ip_SfdpLutAdd(&(pConfig->lutSequences), Qspi_Ip_PackLut(QSPI_IP_LUT_INSTR_CMD, cmdPads, eres));
3521 Qspi_Ip_SfdpLutAdd(&(pConfig->lutSequences), Qspi_Ip_PackLut(QSPI_IP_LUT_INSTR_STOP, QSPI_IP_LUT_PADS_1, 0x0U));
3522 /* Program suspend sequence */
3523 if (esus == psus)
3524 {
3525 pConfig->suspendSettings.programSuspendLut = pConfig->suspendSettings.eraseSuspendLut;
3526 }
3527 else
3528 {
3529 pConfig->suspendSettings.programSuspendLut = lutCount;
3530 Qspi_Ip_SfdpLutAdd(&(pConfig->lutSequences), Qspi_Ip_PackLut(QSPI_IP_LUT_INSTR_CMD, cmdPads, psus));
3531 Qspi_Ip_SfdpLutAdd(&(pConfig->lutSequences), Qspi_Ip_PackLut(QSPI_IP_LUT_INSTR_STOP, QSPI_IP_LUT_PADS_1, 0x0U));
3532 }
3533 /* Program resume sequence */
3534 if (eres == pres)
3535 {
3536 pConfig->suspendSettings.programResumeLut = pConfig->suspendSettings.eraseResumeLut;
3537 }
3538 else
3539 {
3540 pConfig->suspendSettings.programResumeLut = lutCount;
3541 Qspi_Ip_SfdpLutAdd(&(pConfig->lutSequences), Qspi_Ip_PackLut(QSPI_IP_LUT_INSTR_CMD, cmdPads, pres));
3542 Qspi_Ip_SfdpLutAdd(&(pConfig->lutSequences), Qspi_Ip_PackLut(QSPI_IP_LUT_INSTR_STOP, QSPI_IP_LUT_PADS_1, 0x0U));
3543 }
3544 }
3545
3546
3547 /*FUNCTION**********************************************************************
3548 *
3549 * Function Name : Qspi_Ip_SfdpGetXspi1SuspendInfo
3550 * Description : Configure suspend settings - XPI mode
3551 */
Qspi_Ip_SfdpGetXspi1SuspendInfo(const Qspi_Ip_SfdpTablesContainer * sfdpTables,Qspi_Ip_MemoryConfigType * pConfig)3552 static void Qspi_Ip_SfdpGetXspi1SuspendInfo(const Qspi_Ip_SfdpTablesContainer *sfdpTables,
3553 Qspi_Ip_MemoryConfigType *pConfig
3554 )
3555 {
3556 uint8 esus;
3557 uint8 eres;
3558 uint8 psus;
3559 uint8 pres;
3560 uint8 cmdExt;
3561
3562 esus = (uint8)Qspi_Ip_SfdpGetXspi1Param(sfdpTables, QSPI_IP_SFDP_BASIC_ESUS_INSTR_DWORD,
3563 QSPI_IP_SFDP_BASIC_ESUS_INSTR_SHIFT, QSPI_IP_SFDP_BASIC_ESUS_INSTR_WIDTH, 0xB0U);
3564 eres = (uint8)Qspi_Ip_SfdpGetXspi1Param(sfdpTables, QSPI_IP_SFDP_BASIC_ERES_INSTR_DWORD,
3565 QSPI_IP_SFDP_BASIC_ERES_INSTR_SHIFT, QSPI_IP_SFDP_BASIC_ERES_INSTR_WIDTH, 0x30U);
3566 psus = (uint8)Qspi_Ip_SfdpGetXspi1Param(sfdpTables, QSPI_IP_SFDP_BASIC_PSUS_INSTR_DWORD,
3567 QSPI_IP_SFDP_BASIC_PSUS_INSTR_SHIFT, QSPI_IP_SFDP_BASIC_PSUS_INSTR_WIDTH, 0xB0U);
3568 pres = (uint8)Qspi_Ip_SfdpGetXspi1Param(sfdpTables, QSPI_IP_SFDP_BASIC_PRES_INSTR_DWORD,
3569 QSPI_IP_SFDP_BASIC_PRES_INSTR_SHIFT, QSPI_IP_SFDP_BASIC_PRES_INSTR_WIDTH, 0x30U);
3570
3571 /* Erase suspend sequence */
3572 pConfig->suspendSettings.eraseSuspendLut = lutCount;
3573 cmdExt = Qspi_Ip_SfdpGetCmdExt(sfdpTables, esus);
3574 Qspi_Ip_SfdpLutAdd(&(pConfig->lutSequences), Qspi_Ip_PackLut(QSPI_IP_LUT_INSTR_CMD_DDR, QSPI_IP_LUT_PADS_8, esus));
3575 Qspi_Ip_SfdpLutAdd(&(pConfig->lutSequences), Qspi_Ip_PackLut(QSPI_IP_LUT_INSTR_CMD_DDR, QSPI_IP_LUT_PADS_8, cmdExt));
3576 Qspi_Ip_SfdpLutAdd(&(pConfig->lutSequences), Qspi_Ip_PackLut(QSPI_IP_LUT_INSTR_STOP, QSPI_IP_LUT_PADS_1, 0x0U));
3577 /* Erase resume sequence */
3578 pConfig->suspendSettings.eraseResumeLut = lutCount;
3579 cmdExt = Qspi_Ip_SfdpGetCmdExt(sfdpTables, eres);
3580 Qspi_Ip_SfdpLutAdd(&(pConfig->lutSequences), Qspi_Ip_PackLut(QSPI_IP_LUT_INSTR_CMD_DDR, QSPI_IP_LUT_PADS_8, eres));
3581 Qspi_Ip_SfdpLutAdd(&(pConfig->lutSequences), Qspi_Ip_PackLut(QSPI_IP_LUT_INSTR_CMD_DDR, QSPI_IP_LUT_PADS_8, cmdExt));
3582 Qspi_Ip_SfdpLutAdd(&(pConfig->lutSequences), Qspi_Ip_PackLut(QSPI_IP_LUT_INSTR_STOP, QSPI_IP_LUT_PADS_1, 0x0U));
3583 /* Program suspend sequence */
3584 if (esus == psus)
3585 {
3586 pConfig->suspendSettings.programSuspendLut = pConfig->suspendSettings.eraseSuspendLut;
3587 }
3588 else
3589 {
3590 pConfig->suspendSettings.programSuspendLut = lutCount;
3591 cmdExt = Qspi_Ip_SfdpGetCmdExt(sfdpTables, psus);
3592 Qspi_Ip_SfdpLutAdd(&(pConfig->lutSequences), Qspi_Ip_PackLut(QSPI_IP_LUT_INSTR_CMD_DDR, QSPI_IP_LUT_PADS_8, psus));
3593 Qspi_Ip_SfdpLutAdd(&(pConfig->lutSequences), Qspi_Ip_PackLut(QSPI_IP_LUT_INSTR_CMD_DDR, QSPI_IP_LUT_PADS_8, cmdExt));
3594 Qspi_Ip_SfdpLutAdd(&(pConfig->lutSequences), Qspi_Ip_PackLut(QSPI_IP_LUT_INSTR_STOP, QSPI_IP_LUT_PADS_1, 0x0U));
3595 }
3596 /* Program resume sequence */
3597 if (eres == pres)
3598 {
3599 pConfig->suspendSettings.programResumeLut = pConfig->suspendSettings.eraseResumeLut;
3600 }
3601 else
3602 {
3603 pConfig->suspendSettings.programResumeLut = lutCount;
3604 cmdExt = Qspi_Ip_SfdpGetCmdExt(sfdpTables, pres);
3605 Qspi_Ip_SfdpLutAdd(&(pConfig->lutSequences), Qspi_Ip_PackLut(QSPI_IP_LUT_INSTR_CMD_DDR, QSPI_IP_LUT_PADS_8, pres));
3606 Qspi_Ip_SfdpLutAdd(&(pConfig->lutSequences), Qspi_Ip_PackLut(QSPI_IP_LUT_INSTR_CMD_DDR, QSPI_IP_LUT_PADS_8, cmdExt));
3607 Qspi_Ip_SfdpLutAdd(&(pConfig->lutSequences), Qspi_Ip_PackLut(QSPI_IP_LUT_INSTR_STOP, QSPI_IP_LUT_PADS_1, 0x0U));
3608 }
3609 }
3610
3611
3612 /*FUNCTION**********************************************************************
3613 *
3614 * Function Name : Qspi_Ip_SfdpAdd2dopiOperation
3615 * Description : Add a DOPI switch command to the operation list
3616 */
Qspi_Ip_SfdpAdd2dopiOperation(const Qspi_Ip_MemoryConfigType * pConfig,uint8 seqSize,const uint32 * words)3617 static void Qspi_Ip_SfdpAdd2dopiOperation(const Qspi_Ip_MemoryConfigType *pConfig,
3618 uint8 seqSize,
3619 const uint32 *words
3620 )
3621 {
3622 Qspi_Ip_InitOperationType *operation;
3623 uint8 nextByte;
3624 uint8 cnt;
3625
3626 if (initOpCount >= pConfig->initConfiguration.opCount)
3627 {
3628 /* operations list not big enough */
3629 overflow = TRUE;
3630 }
3631 else
3632 {
3633 operation = &(pConfig->initConfiguration.operations[initOpCount]);
3634 initOpCount++;
3635 operation->opType = QSPI_IP_OP_TYPE_CMD;
3636 operation->command1Lut = lutCount;
3637 operation->addr = 0U;
3638 /* Build LUT sequence for this command */
3639 for (cnt = 0U; cnt < seqSize; cnt++)
3640 {
3641 nextByte = (uint8)((words[dopiSwitchWord[cnt]] >> dopiSwitchShift[cnt]) & 0xFFU);
3642 Qspi_Ip_SfdpLutAdd(&(pConfig->lutSequences), Qspi_Ip_PackLut(QSPI_IP_LUT_INSTR_CMD, QSPI_IP_LUT_PADS_1, nextByte));
3643 }
3644 /* Add STOP instruction */
3645 Qspi_Ip_SfdpLutAdd(&(pConfig->lutSequences), Qspi_Ip_PackLut(QSPI_IP_LUT_INSTR_STOP, QSPI_IP_LUT_PADS_1, 0x0U));
3646 /* Other operation fields are unused */
3647 operation->command2Lut = QSPI_IP_LUT_INVALID;
3648 operation->weLut = QSPI_IP_LUT_INVALID;
3649 operation->size = 0U;
3650 operation->shift = 0U;
3651 operation->width = 0U;
3652 operation->value = 0U;
3653 operation->ctrlCfgPtr = NULL_PTR;
3654 }
3655
3656 return;
3657 }
3658
3659
3660 /*FUNCTION**********************************************************************
3661 *
3662 * Function Name : Qspi_Ip_SfdpAddCheckBusyOperation
3663 * Description : Add a READ_REG operation to check the BUSY flag of the status register.
3664 */
Qspi_Ip_SfdpAddCheckBusyOperation(const Qspi_Ip_MemoryConfigType * pConfig)3665 static void Qspi_Ip_SfdpAddCheckBusyOperation(const Qspi_Ip_MemoryConfigType *pConfig)
3666 {
3667 Qspi_Ip_InitOperationType *operation;
3668 const Qspi_Ip_StatusConfigType *statusConfig;
3669
3670 if (initOpCount >= pConfig->initConfiguration.opCount)
3671 {
3672 /* operations list not big enough */
3673 overflow = TRUE;
3674 }
3675 else
3676 {
3677 /* Build a read operation to check the BUSY flag of the status register */
3678 operation = &(pConfig->initConfiguration.operations[initOpCount]);
3679 initOpCount++;
3680
3681 /* Use the initial read status reg that was configured before */
3682 statusConfig = &(pConfig->statusConfig);
3683
3684 operation->opType = QSPI_IP_OP_TYPE_READ_REG;
3685 operation->command1Lut = statusConfig->statusRegInitReadLut;
3686 operation->size = statusConfig->regSize;
3687 operation->shift = statusConfig->busyOffset;
3688 operation->value = 1U - (uint32)statusConfig->busyValue; /* Reverse: wait until not busy */
3689 operation->width = 1U;
3690
3691 /* Other operation fields are unused */
3692 operation->command2Lut = QSPI_IP_LUT_INVALID;
3693 operation->weLut = QSPI_IP_LUT_INVALID;
3694 operation->addr = 0U;
3695 operation->ctrlCfgPtr = NULL_PTR;
3696 }
3697 }
3698
3699
3700
3701 /*FUNCTION**********************************************************************
3702 *
3703 * Function Name : Qspi_Ip_SfdpGetXspi1InitOpInfo
3704 * Description : Configure initial operations list - XPI mode
3705 */
Qspi_Ip_SfdpGetXspi1InitOpInfo(const Qspi_Ip_SfdpTablesContainer * sfdpTables,Qspi_Ip_MemoryConfigType * pConfig)3706 static void Qspi_Ip_SfdpGetXspi1InitOpInfo(const Qspi_Ip_SfdpTablesContainer *sfdpTables,
3707 Qspi_Ip_MemoryConfigType *pConfig
3708 )
3709 {
3710 uint8 cnt;
3711 uint8 seqSize;
3712
3713 if (sfdpTables->paramTableLength_2dopi > 0U)
3714 {
3715 for (cnt = 0U; cnt < (sfdpTables->paramTableLength_2dopi - 1U); cnt += 2U)
3716 {
3717 seqSize = (uint8)Qspi_Ip_SfdpGet2DopiParam(sfdpTables, cnt + 1U,
3718 QSPI_IP_SFDP_2DOPI_CMD_LEN_SHIFT, QSPI_IP_SFDP_2DOPI_CMD_LEN_WIDTH, 0x0U);
3719 if (seqSize == 0U)
3720 {
3721 /* No more commands */
3722 break;
3723 }
3724 /* Add a wait operation to ensure the previous command is completed, needed for write in a non-volatile register */
3725 Qspi_Ip_SfdpAddCheckBusyOperation(pConfig);
3726
3727 Qspi_Ip_SfdpAdd2dopiOperation(pConfig, seqSize, &sfdpTables->paramTable_2dopi[cnt]);
3728 }
3729 }
3730 /* Update operations count */
3731 pConfig->initConfiguration.opCount = initOpCount;
3732 }
3733
3734
3735 /*FUNCTION**********************************************************************
3736 *
3737 * Function Name : Qspi_Ip_SfdpGetBasicInitOpInfo
3738 * Description : Configure initial operations list - XPI mode
3739 */
Qspi_Ip_SfdpGetBasicInitOpInfo(Qspi_Ip_MemoryConfigType * pConfig)3740 static void Qspi_Ip_SfdpGetBasicInitOpInfo(Qspi_Ip_MemoryConfigType * pConfig)
3741 {
3742 /* Init operations already added, update operations count */
3743 pConfig->initConfiguration.opCount = initOpCount;
3744 }
3745
3746
3747 /*FUNCTION**********************************************************************
3748 *
3749 * Function Name : Qspi_Ip_SfdpGet0xxInfo
3750 * Description : Configure 0xx capabilities - XPI mode
3751 */
Qspi_Ip_SfdpGet0xxInfo(const Qspi_Ip_SfdpTablesContainer * sfdpTables,Qspi_Ip_MemoryConfigType * pConfig)3752 static void Qspi_Ip_SfdpGet0xxInfo(const Qspi_Ip_SfdpTablesContainer *sfdpTables,
3753 Qspi_Ip_MemoryConfigType * pConfig
3754 )
3755 {
3756 /* Not implemented */
3757 (void)sfdpTables;
3758 pConfig->read0xxLut = QSPI_IP_LUT_INVALID;
3759 pConfig->read0xxLutAHB = QSPI_IP_LUT_INVALID;
3760 }
3761
3762
3763 /*FUNCTION**********************************************************************
3764 *
3765 * Function Name : Qspi_Ip_SfdpConfigureOther
3766 * Description : Configure unsupported features
3767 */
Qspi_Ip_SfdpConfigureOther(Qspi_Ip_MemoryConfigType * pConfig)3768 static void Qspi_Ip_SfdpConfigureOther(Qspi_Ip_MemoryConfigType * pConfig)
3769 {
3770 pConfig->readIdSettings.readIdLut = QSPI_IP_LUT_INVALID;
3771 pConfig->initCallout = NULL_PTR;
3772 pConfig->resetCallout = NULL_PTR;
3773 pConfig->errorCheckCallout = NULL_PTR;
3774 pConfig->ctrlAutoCfgPtr = NULL_PTR;
3775 }
3776
3777
3778
3779 /*FUNCTION**********************************************************************
3780 *
3781 * Function Name : Qspi_Ip_SfdpGetSize
3782 * Description : Builds configuration for octal DDR (DOPI) mode.
3783 */
Qspi_Ip_SfdpGetSize(const Qspi_Ip_SfdpTablesContainer * sfdpTables,Qspi_Ip_MemoryConfigType * pConfig)3784 static void Qspi_Ip_SfdpGetSize(const Qspi_Ip_SfdpTablesContainer *sfdpTables,
3785 Qspi_Ip_MemoryConfigType *pConfig
3786 )
3787 {
3788 uint32 size;
3789
3790 /* Dword 2 of parameter table: Flash Memory Density */
3791 size = Qspi_Ip_SfdpGetBasicParam(sfdpTables, QSPI_IP_SFDP_BASIC_MEM_SIZE_DWORD,
3792 QSPI_IP_SFDP_BASIC_MEM_SIZE_SHIFT, QSPI_IP_SFDP_BASIC_MEM_SIZE_WIDTH, 0xFFFFFU);
3793 /* check MSB */
3794 if ((size & 0x80000000U) == 0U)
3795 {
3796 pConfig->memSize = (size + 1U) >> 3U;
3797 }
3798 else
3799 {
3800 pConfig->memSize = ((uint32)1U << ((size & (~(uint32)0x80000000U)) - (uint32)3U));
3801 }
3802
3803 /* Dword 11 of parameter table: Page Size */
3804 size = Qspi_Ip_SfdpGetBasicParam(sfdpTables, QSPI_IP_SFDP_BASIC_PAGE_SIZE_DWORD,
3805 QSPI_IP_SFDP_BASIC_PAGE_SIZE_SHIFT, QSPI_IP_SFDP_BASIC_PAGE_SIZE_WIDTH, 8U);
3806 pConfig->pageSize = ((uint32)1U << size);
3807 }
3808
3809
3810 /*FUNCTION**********************************************************************
3811 *
3812 * Function Name : Qspi_Ip_GetBasicInfo
3813 * Description : Builds basic configurations
3814 */
Qspi_Ip_SfdpGetBasicInfo(const Qspi_Ip_SfdpTablesContainer * sfdpTables,Qspi_Ip_MemoryConfigType * pConfig)3815 static inline void Qspi_Ip_SfdpGetBasicInfo(const Qspi_Ip_SfdpTablesContainer *sfdpTables,
3816 Qspi_Ip_MemoryConfigType * pConfig
3817 )
3818 {
3819 /* Configure read command */
3820 Qspi_Ip_SfdpGetBasicReadInfo(sfdpTables, pConfig);
3821 /* Configure write command */
3822 Qspi_Ip_SfdpGetBasicWriteInfo(sfdpTables, pConfig);
3823 /* Configure erase commands */
3824 Qspi_Ip_SfdpGetBasicEraseInfo(sfdpTables, pConfig);
3825 /* Configure status register */
3826 Qspi_Ip_SfdpGetBasicStatusInfo(sfdpTables, pConfig);
3827
3828 /* Configure reset settings */
3829 Qspi_Ip_SfdpGetBasicResetInfo(sfdpTables, pConfig, &(pConfig->resetSettings), cmdPads);
3830 /* Configure initial reset settings */
3831 Qspi_Ip_SfdpGetBasicResetInfo(sfdpTables, pConfig, &(pConfig->initResetSettings), cmdPadsInit);
3832
3833 /* Configure suspend settings */
3834 Qspi_Ip_SfdpGetBasicSuspendInfo(sfdpTables, pConfig);
3835 /* Configure initial operations list */
3836 Qspi_Ip_SfdpGetBasicInitOpInfo(pConfig);
3837 }
3838
3839
3840 /*FUNCTION**********************************************************************
3841 *
3842 * Function Name : Qspi_Ip_SfdpConfigureInitReadStatus
3843 * Description : Builds configuration for initial read status reg.
3844 */
Qspi_Ip_SfdpConfigureInitReadStatus(const Qspi_Ip_SfdpTablesContainer * sfdpTables,Qspi_Ip_MemoryConfigType * pConfig,uint8 instruction)3845 static void Qspi_Ip_SfdpConfigureInitReadStatus(const Qspi_Ip_SfdpTablesContainer *sfdpTables,
3846 Qspi_Ip_MemoryConfigType *pConfig,
3847 uint8 instruction
3848 )
3849 {
3850 Qspi_Ip_StatusConfigType *statusConfig;
3851
3852 statusConfig = &(pConfig->statusConfig);
3853
3854 statusConfig->regSize = 1U;
3855 statusConfig->blockProtectionOffset = 0U;
3856 statusConfig->blockProtectionWidth = 0U;
3857 statusConfig->blockProtectionValue = 0U;
3858 statusConfig->busyOffset = (uint8)Qspi_Ip_SfdpGetSRMapParam(sfdpTables, QSPI_IP_SFDP_SRMAP_WIP_OFFSET_DWORD,
3859 QSPI_IP_SFDP_SRMAP_WIP_OFFSET_SHIFT, QSPI_IP_SFDP_SRMAP_WIP_OFFSET_WIDTH, 0x0U);
3860 /* Busy bit meaning is reversed (0: Positive (WIP=1 means write is in progress); 1: Inverted (WIP=0 means write is in progress) */
3861 statusConfig->busyValue = (uint8)(1U - Qspi_Ip_SfdpGetSRMapParam(sfdpTables, QSPI_IP_SFDP_SRMAP_WIP_VALUE_DWORD,
3862 QSPI_IP_SFDP_SRMAP_WIP_VALUE_SHIFT, QSPI_IP_SFDP_SRMAP_WIP_VALUE_WIDTH, 0x0U));
3863 statusConfig->writeEnableOffset = (uint8)Qspi_Ip_SfdpGetSRMapParam(sfdpTables, QSPI_IP_SFDP_SRMAP_WEL_OFFSET_DWORD,
3864 QSPI_IP_SFDP_SRMAP_WEL_OFFSET_SHIFT, QSPI_IP_SFDP_SRMAP_WEL_OFFSET_WIDTH, 0x1U);
3865 /* Build LUT sequence for initial read status reg. */
3866 statusConfig->statusRegInitReadLut = lutCount;
3867 Qspi_Ip_SfdpLutAdd(&(pConfig->lutSequences), Qspi_Ip_PackLut(QSPI_IP_LUT_INSTR_CMD, QSPI_IP_LUT_PADS_1, instruction));
3868 Qspi_Ip_SfdpLutAdd(&(pConfig->lutSequences), Qspi_Ip_PackLut(QSPI_IP_LUT_INSTR_READ, QSPI_IP_LUT_PADS_1, 0x1U));
3869 Qspi_Ip_SfdpLutAdd(&(pConfig->lutSequences), Qspi_Ip_PackLut(QSPI_IP_LUT_INSTR_STOP, QSPI_IP_LUT_PADS_1, 0x0U));
3870 }
3871
3872
3873 /*FUNCTION**********************************************************************
3874 *
3875 * Function Name : Qspi_Ip_ConfigureBasic
3876 * Description : Builds configuration for octal DDR (DOPI) mode.
3877 */
Qspi_Ip_ConfigureBasic(const Qspi_Ip_SfdpTablesContainer * sfdpTables,Qspi_Ip_MemoryConfigType * pConfig)3878 static Qspi_Ip_StatusType Qspi_Ip_ConfigureBasic(const Qspi_Ip_SfdpTablesContainer *sfdpTables,
3879 Qspi_Ip_MemoryConfigType *pConfig
3880 )
3881 {
3882 Qspi_Ip_StatusType status = STATUS_QSPI_IP_SUCCESS;
3883
3884 /* Get size, page size */
3885 Qspi_Ip_SfdpGetSize(sfdpTables, pConfig);
3886 /* Get addres size for read/write commands */
3887 Qspi_Ip_SfdpGetBasicAddrBits(sfdpTables, pConfig);
3888
3889 /* Configure initial read status register */
3890 Qspi_Ip_SfdpConfigureInitReadStatus(sfdpTables, pConfig, QSPI_IP_CMD_BASIC_READ_SR);
3891
3892 /* Check QE bit */
3893 Qspi_Ip_SfdpConfigureQE(sfdpTables, pConfig);
3894
3895 /* Get basic info: read, write, erase, reset, suspend */
3896 Qspi_Ip_SfdpGetBasicInfo(sfdpTables, pConfig);
3897
3898 /* Configure 0xx capabilities */
3899 Qspi_Ip_SfdpGet0xxInfo(sfdpTables, pConfig);
3900 /* Configure unsupported features */
3901 Qspi_Ip_SfdpConfigureOther(pConfig);
3902
3903 /* Check for LUT or Init operations overflow */
3904 if (overflow == TRUE)
3905 {
3906 status = STATUS_QSPI_IP_ERROR;
3907 }
3908 return status;
3909 }
3910
3911 /*FUNCTION**********************************************************************
3912 *
3913 * Function Name : Qspi_Ip_SfdpGetXspi1ResetConfig
3914 * Description : Builds Xspi1 configure reset settings and initial reset settings.
3915 */
Qspi_Ip_SfdpGetXspi1ResetConfig(const Qspi_Ip_SfdpTablesContainer * sfdpTables,Qspi_Ip_MemoryConfigType * pConfig)3916 static void Qspi_Ip_SfdpGetXspi1ResetConfig(const Qspi_Ip_SfdpTablesContainer *sfdpTables,
3917 Qspi_Ip_MemoryConfigType * pConfig
3918 )
3919 {
3920 /* Configure reset settings */
3921 Qspi_Ip_SfdpGetXspi1ResetInfo(sfdpTables, pConfig);
3922 /* Configure initial reset settings */
3923 Qspi_Ip_SfdpGetXspi1InitResetInfo(sfdpTables, pConfig);
3924 }
3925
3926
3927 /*FUNCTION**********************************************************************
3928 *
3929 * Function Name : Qspi_Ip_SfdpGetXspi1Info
3930 * Description : Builds Xspi1 configurations.
3931 */
Qspi_Ip_SfdpGetXspi1Info(const Qspi_Ip_SfdpTablesContainer * sfdpTables,Qspi_Ip_MemoryConfigType * pConfig)3932 static inline void Qspi_Ip_SfdpGetXspi1Info(const Qspi_Ip_SfdpTablesContainer *sfdpTables,
3933 Qspi_Ip_MemoryConfigType * pConfig
3934 )
3935 {
3936 /* Configure read command */
3937 Qspi_Ip_SfdpGetXspi1ReadInfo(sfdpTables, pConfig);
3938 /* Configure write command */
3939 Qspi_Ip_SfdpGetXspi1WriteInfo(sfdpTables, pConfig);
3940 /* Configure erase commands */
3941 Qspi_Ip_SfdpGetXspi1EraseInfo(sfdpTables, pConfig);
3942 /* Configure status register */
3943 Qspi_Ip_SfdpGetXspi1StatusInfo(sfdpTables, pConfig);
3944
3945 /* Configure reset settings and initial reset settings */
3946 Qspi_Ip_SfdpGetXspi1ResetConfig(sfdpTables, pConfig);
3947 /* Configure suspend settings */
3948 Qspi_Ip_SfdpGetXspi1SuspendInfo(sfdpTables, pConfig);
3949 /* Configure initial operations list */
3950 Qspi_Ip_SfdpGetXspi1InitOpInfo(sfdpTables, pConfig);
3951 }
3952
3953
3954 /*FUNCTION**********************************************************************
3955 *
3956 * Function Name : Qspi_Ip_ConfigureXspi1
3957 * Description : Builds octal DDR (DOPI) configuration for xSPI 1.0 devices.
3958 */
Qspi_Ip_ConfigureXspi1(const Qspi_Ip_SfdpTablesContainer * sfdpTables,Qspi_Ip_MemoryConfigType * pConfig)3959 static Qspi_Ip_StatusType Qspi_Ip_ConfigureXspi1(const Qspi_Ip_SfdpTablesContainer *sfdpTables,
3960 Qspi_Ip_MemoryConfigType *pConfig
3961 )
3962 {
3963 Qspi_Ip_StatusType status = STATUS_QSPI_IP_SUCCESS;
3964
3965 /* Get size, page size */
3966 Qspi_Ip_SfdpGetSize(sfdpTables, pConfig);
3967
3968 /* Configure initial read status register */
3969 Qspi_Ip_SfdpConfigureInitReadStatus(sfdpTables, pConfig, QSPI_IP_CMD_XSPI_READ_SR);
3970
3971 /* Get Xspi1 info: read, write, erase, reset, suspend */
3972 Qspi_Ip_SfdpGetXspi1Info(sfdpTables, pConfig);
3973
3974 /* Configure 0xx capabilities */
3975 Qspi_Ip_SfdpGet0xxInfo(sfdpTables, pConfig);
3976 /* Configure unsupported features */
3977 Qspi_Ip_SfdpConfigureOther(pConfig);
3978
3979 /* Check for LUT or Init operations overflow */
3980 if (overflow == TRUE)
3981 {
3982 status = STATUS_QSPI_IP_ERROR;
3983 }
3984 return status;
3985 }
3986
3987
3988 /*******************************************************************************
3989 * Code
3990 ******************************************************************************/
3991
3992 /*FUNCTION**********************************************************************
3993 *
3994 * Function Name : Qspi_Ip_SfdpConfigure
3995 * Description : Check xSPI 1.0 support
3996 */
Qspi_Ip_SfdpConfigure(const Qspi_Ip_SfdpTablesContainer * sfdpTables,Qspi_Ip_MemoryConfigType * pConfig)3997 static Qspi_Ip_StatusType Qspi_Ip_SfdpConfigure(const Qspi_Ip_SfdpTablesContainer *sfdpTables,
3998 Qspi_Ip_MemoryConfigType *pConfig
3999 )
4000 {
4001 Qspi_Ip_StatusType status;
4002 if (sfdpTables->paramTableLength_xspi1 > 0U)
4003 {
4004 status = Qspi_Ip_ConfigureXspi1(sfdpTables, pConfig);
4005 }
4006 else
4007 {
4008 status = Qspi_Ip_ConfigureBasic(sfdpTables, pConfig);
4009 }
4010 return status;
4011 }
4012
4013 /*FUNCTION**********************************************************************
4014 *
4015 * Function Name : Qspi_Ip_ReadSfdp
4016 * Description : Auto-fills configuration from SFDP information
4017 * @implements Qspi_Ip_ReadSfdp_Activity */
Qspi_Ip_ReadSfdp(Qspi_Ip_MemoryConfigType * pConfig,const Qspi_Ip_MemoryConnectionType * pConnect)4018 Qspi_Ip_StatusType Qspi_Ip_ReadSfdp(Qspi_Ip_MemoryConfigType * pConfig,
4019 const Qspi_Ip_MemoryConnectionType * pConnect
4020 )
4021 {
4022 Qspi_Ip_StatusType status = STATUS_QSPI_IP_SUCCESS;
4023 uint32 baseAddress;
4024 /* SFDP Tables */
4025 Qspi_Ip_SfdpTablesContainer sfdpTables;
4026
4027 #if (QSPI_IP_DEV_ERROR_DETECT == STD_ON)
4028 /* Check for valid parameters */
4029 DEV_ASSERT_QSPI(pConnect != NULL_PTR);
4030 DEV_ASSERT_QSPI(pConfig != NULL_PTR);
4031 DEV_ASSERT_QSPI((pConfig->lutSequences.lutOps != NULL_PTR) && (pConfig->lutSequences.opCount > 0U));
4032 #endif
4033
4034 /* Get device base address */
4035 baseAddress = Qspi_Ip_GetBaseAdress(pConnect->qspiInstance, pConnect->connectionType);
4036 /* Initiate communication with flash, check SFDP support */
4037 status = Qspi_Ip_SfdpCheck(pConnect->qspiInstance, baseAddress);
4038 if (status != STATUS_QSPI_IP_SUCCESS)
4039 {
4040 /* direct command - nothing to do */
4041 }
4042 else
4043 {
4044 /* Read SFDP tables of interest */
4045 status = Qspi_Ip_SfdpReadTables(pConnect->qspiInstance, baseAddress, &sfdpTables);
4046 if (status != STATUS_QSPI_IP_SUCCESS)
4047 {
4048 /* direct command - nothing to do */
4049 }
4050 else
4051 {
4052 /* Initialize LUT and init operations count */
4053 Qspi_Ip_SfdpLutInit();
4054 /* Build the enter legacy XPI protocol initial operation */
4055 Qspi_Ip_SfdpLutInitEnterLegacySPI(pConfig);
4056 /* Check xSPI 1.0 support */
4057 status = Qspi_Ip_SfdpConfigure(&sfdpTables, pConfig);
4058 }
4059 }
4060
4061 return status;
4062 }
4063
4064
4065
4066 #define MEM_43_EXFLS_STOP_SEC_CODE
4067 #include "Mem_43_EXFLS_MemMap.h"
4068
4069 #endif /* (QSPI_IP_MEM_INSTANCE_COUNT > 0) */
4070
4071
4072 #ifdef __cplusplus
4073 }
4074 #endif
4075
4076 /** @} */
4077
4078