1 /*
2 * Copyright 2020-2023 NXP
3 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 */
6
7 /**
8 * @file Qspi_Ip_Controller.c
9 *
10 * @addtogroup IPV_QSPI QSPI IPV Driver
11 * @{
12 */
13
14 /* implements Qspi_Ip_Controller.c_Artifact */
15
16 #ifdef __cplusplus
17 extern "C"{
18 #endif
19
20 #include "Mcal.h"
21 #include "OsIf.h"
22 #include "Qspi_Ip.h"
23 #include "Qspi_Ip_Controller.h"
24 #include "Qspi_Ip_HwAccess.h"
25
26 /*==================================================================================================
27 * SOURCE FILE VERSION INFORMATION
28 ==================================================================================================*/
29 #define QSPI_IP_CONTROLLER_VENDOR_ID_C 43
30 #define QSPI_IP_CONTROLLER_AR_RELEASE_MAJOR_VERSION_C 4
31 #define QSPI_IP_CONTROLLER_AR_RELEASE_MINOR_VERSION_C 7
32 #define QSPI_IP_CONTROLLER_AR_RELEASE_REVISION_VERSION_C 0
33 #define QSPI_IP_CONTROLLER_SW_MAJOR_VERSION_C 3
34 #define QSPI_IP_CONTROLLER_SW_MINOR_VERSION_C 0
35 #define QSPI_IP_CONTROLLER_SW_PATCH_VERSION_C 0
36
37 /*==================================================================================================
38 * FILE VERSION CHECKS
39 ==================================================================================================*/
40 #ifndef DISABLE_MCAL_INTERMODULE_ASR_CHECK
41 /* Check if current file and Mcal.h header file are of the same Autosar version */
42 #if ((QSPI_IP_CONTROLLER_AR_RELEASE_MAJOR_VERSION_C != MCAL_AR_RELEASE_MAJOR_VERSION) || \
43 (QSPI_IP_CONTROLLER_AR_RELEASE_MINOR_VERSION_C != MCAL_AR_RELEASE_MINOR_VERSION) \
44 )
45 #error "AutoSar Version Numbers of Qspi_Ip_Controller.c and Mcal.h are different"
46 #endif
47
48 /* Check if current file and OsIf.h header file are of the same Autosar version */
49 #if ((QSPI_IP_CONTROLLER_AR_RELEASE_MAJOR_VERSION_C != OSIF_AR_RELEASE_MAJOR_VERSION) || \
50 (QSPI_IP_CONTROLLER_AR_RELEASE_MINOR_VERSION_C != OSIF_AR_RELEASE_MINOR_VERSION) \
51 )
52 #error "AutoSar Version Numbers of Qspi_Ip_Controller.c and OsIf.h are different"
53 #endif
54 #endif
55
56 /* Check if current file and Qspi_Ip_Controller header file are of the same vendor */
57 #if (QSPI_IP_CONTROLLER_VENDOR_ID_C != QSPI_IP_CONTROLLER_VENDOR_ID_H)
58 #error "Qspi_Ip_Controller.c and Qspi_Ip_Controller.h have different vendor ids"
59 #endif
60 /* Check if current file and Qspi_Ip_Controller header file are of the same Autosar version */
61 #if ((QSPI_IP_CONTROLLER_AR_RELEASE_MAJOR_VERSION_C != QSPI_IP_CONTROLLER_AR_RELEASE_MAJOR_VERSION_H) || \
62 (QSPI_IP_CONTROLLER_AR_RELEASE_MINOR_VERSION_C != QSPI_IP_CONTROLLER_AR_RELEASE_MINOR_VERSION_H) || \
63 (QSPI_IP_CONTROLLER_AR_RELEASE_REVISION_VERSION_C != QSPI_IP_CONTROLLER_AR_RELEASE_REVISION_VERSION_H) \
64 )
65 #error "AutoSar Version Numbers of Qspi_Ip_Controller.c and Qspi_Ip_Controller.h are different"
66 #endif
67 /* Check if current file and Qspi_Ip_Controller header file are of the same Software version */
68 #if ((QSPI_IP_CONTROLLER_SW_MAJOR_VERSION_C != QSPI_IP_CONTROLLER_SW_MAJOR_VERSION_H) || \
69 (QSPI_IP_CONTROLLER_SW_MINOR_VERSION_C != QSPI_IP_CONTROLLER_SW_MINOR_VERSION_H) || \
70 (QSPI_IP_CONTROLLER_SW_PATCH_VERSION_C != QSPI_IP_CONTROLLER_SW_PATCH_VERSION_H) \
71 )
72 #error "Software Version Numbers of Qspi_Ip_Controller.c and Qspi_Ip_Controller.h are different"
73 #endif
74
75 /* Check if current file and Qspi_Ip_HwAccess header file are of the same vendor */
76 #if (QSPI_IP_CONTROLLER_VENDOR_ID_C != QSPI_IP_HW_ACCESS_VENDOR_ID_H)
77 #error "Qspi_Ip_Controller.c and Qspi_Ip_HwAccess.h have different vendor ids"
78 #endif
79 /* Check if current file and Qspi_Ip_HwAccess header file are of the same Autosar version */
80 #if ((QSPI_IP_CONTROLLER_AR_RELEASE_MAJOR_VERSION_C != QSPI_IP_HW_ACCESS_AR_RELEASE_MAJOR_VERSION_H) || \
81 (QSPI_IP_CONTROLLER_AR_RELEASE_MINOR_VERSION_C != QSPI_IP_HW_ACCESS_AR_RELEASE_MINOR_VERSION_H) || \
82 (QSPI_IP_CONTROLLER_AR_RELEASE_REVISION_VERSION_C != QSPI_IP_HW_ACCESS_AR_RELEASE_REVISION_VERSION_H) \
83 )
84 #error "AutoSar Version Numbers of Qspi_Ip_Controller.c and Qspi_Ip_HwAccess.h are different"
85 #endif
86 /* Check if current file and Qspi_Ip_HwAccess header file are of the same Software version */
87 #if ((QSPI_IP_CONTROLLER_SW_MAJOR_VERSION_C != QSPI_IP_HW_ACCESS_SW_MAJOR_VERSION_H) || \
88 (QSPI_IP_CONTROLLER_SW_MINOR_VERSION_C != QSPI_IP_HW_ACCESS_SW_MINOR_VERSION_H) || \
89 (QSPI_IP_CONTROLLER_SW_PATCH_VERSION_C != QSPI_IP_HW_ACCESS_SW_PATCH_VERSION_H) \
90 )
91 #error "Software Version Numbers of Qspi_Ip_Controller.c and Qspi_Ip_HwAccess.h are different"
92 #endif
93
94 /* Check if current file and Qspi_Ip header file are of the same vendor */
95 #if (QSPI_IP_CONTROLLER_VENDOR_ID_C != QSPI_IP_VENDOR_ID_H)
96 #error "Qspi_Ip_Controller.c and Qspi_Ip.h have different vendor ids"
97 #endif
98 /* Check if current file and Qspi_Ip header file are of the same Autosar version */
99 #if ((QSPI_IP_CONTROLLER_AR_RELEASE_MAJOR_VERSION_C != QSPI_IP_AR_RELEASE_MAJOR_VERSION_H) || \
100 (QSPI_IP_CONTROLLER_AR_RELEASE_MINOR_VERSION_C != QSPI_IP_AR_RELEASE_MINOR_VERSION_H) || \
101 (QSPI_IP_CONTROLLER_AR_RELEASE_REVISION_VERSION_C != QSPI_IP_AR_RELEASE_REVISION_VERSION_H) \
102 )
103 #error "AutoSar Version Numbers of Qspi_Ip_Controller.c and Qspi_Ip.h are different"
104 #endif
105 /* Check if current file and Qspi_Ip header file are of the same Software version */
106 #if ((QSPI_IP_CONTROLLER_SW_MAJOR_VERSION_C != QSPI_IP_SW_MAJOR_VERSION_H) || \
107 (QSPI_IP_CONTROLLER_SW_MINOR_VERSION_C != QSPI_IP_SW_MINOR_VERSION_H) || \
108 (QSPI_IP_CONTROLLER_SW_PATCH_VERSION_C != QSPI_IP_SW_PATCH_VERSION_H) \
109 )
110 #error "Software Version Numbers of Qspi_Ip_Controller.c and Qspi_Ip.h are different"
111 #endif
112
113 #if (QSPI_IP_MEM_INSTANCE_COUNT > 0)
114
115 /*******************************************************************************
116 * Definitions
117 ******************************************************************************/
118 #if defined(FEATURE_QSPI_CHIP_OPTIONS_S32K148)
119 /* Bit-fields of chip-specific MCR[SCLKCFG] field */
120 #define QSPI_MCR_SCLKCFG_INPUT_EN 0x80U /* Enable input buffer of QSPI pads */
121 #define QSPI_MCR_SCLKCFG_CLK_MOD 0x40U /* Quadspi Clocking mode selection */
122 #define QSPI_MCR_SCLKCFG_EXT_DQS 0x20U /* Use external DQS (HyperRAM mode) */
123 #define QSPI_MCR_SCLKCFG_CLK_SRC 0x10U /* QuadSPI source clock selection */
124 #define QSPI_MCR_SCLKCFG_DQS_INV_B 0x08U /* B-side DQS invert */
125 #define QSPI_MCR_SCLKCFG_DQS_SEL_B 0x04U /* B-side DQS select */
126 #define QSPI_MCR_SCLKCFG_DQS_INV_A 0x02U /* A-side DQS invert */
127 #define QSPI_MCR_SCLKCFG_DQS_SEL_A 0x01U /* A-side DQS select */
128
129 /* Bit-fields of chip-specific SOCCR[SOCCFG] field */
130 /* Programmable Divider Selection */
131 #define QuadSPI_SOCCR_PD_MASK 0xE0000000u
132 #define QuadSPI_SOCCR_PD_SHIFT 29u
133 #define QuadSPI_SOCCR_PD(x) (((uint32)(((uint32)(x))<<QuadSPI_SOCCR_PD_SHIFT))&QuadSPI_SOCCR_PD_MASK)
134 /* Programmable Divider Disable */
135 #define QuadSPI_SOCCR_PDD_MASK 0x10000000u
136
137 #define QuadSPI_SOCCR_DSQ_DEL_B 8u
138 #define QuadSPI_SOCCR_DSQ_DEL_A 0u
139 #endif /* (FEATURE_QSPI_CHIP_OPTIONS_S32K148) */
140
141 #if (FEATURE_QSPI_HAS_SFP == 1)
142
143 #if (QSPI_IP_ENABLE_USER_MODE_SUPPORT == STD_ON)
144
145 #define Qspi_Ip_Sfp_Configure(baseAddr, userConfigPtr) OsIf_Trusted_Call2params(Qspi_Ip_Sfp_Configure_Privileged, baseAddr, userConfigPtr)
146 #define Qspi_Ip_ResetPrivilegedRegisters(baseAddr) OsIf_Trusted_Call1param(Qspi_Ip_ResetPrivilegedRegisters_Privileged, baseAddr)
147 #define Qspi_Ip_Sfp_ClearLatchedErrors(baseAddr) OsIf_Trusted_Call1param(Qspi_Ip_Sfp_ClearLatchedErrors_Privileged, baseAddr)
148
149 #else /* QSPI_IP_ENABLE_USER_MODE_SUPPORT */
150
151 #define Qspi_Ip_Sfp_Configure(baseAddr, userConfigPtr) Qspi_Ip_Sfp_Configure_Privileged(baseAddr, userConfigPtr)
152 #define Qspi_Ip_ResetPrivilegedRegisters(baseAddr) Qspi_Ip_ResetPrivilegedRegisters_Privileged(baseAddr)
153 #define Qspi_Ip_Sfp_ClearLatchedErrors(baseAddr) Qspi_Ip_Sfp_ClearLatchedErrors_Privileged(baseAddr)
154
155 #endif /* QSPI_IP_ENABLE_USER_MODE_SUPPORT */
156
157 #endif /* FEATURE_QSPI_HAS_SFP */
158
159 /*******************************************************************************
160 * Variables
161 ******************************************************************************/
162
163 /*! @cond DRIVER_INTERNAL_USE_ONLY */
164
165 /* Mask of QuadSPI IP-related error flags */
166 #ifndef QuadSPI_FR_IPAEF_MASK
167 #define QuadSPI_FR_IPAEF_MASK (0U)
168 #endif
169
170 #define QSPI_ERR_FLAGS_MASK (QuadSPI_FR_TBUF_MASK | \
171 QuadSPI_FR_ILLINE_MASK | \
172 QuadSPI_FR_RBOF_MASK | \
173 QuadSPI_FR_IPAEF_MASK | \
174 QuadSPI_FR_IPIEF_MASK)
175
176
177 #define FLS_START_SEC_CONST_UNSPECIFIED
178 #include "Fls_MemMap.h"
179
180 /* Table of base addresses for QuadSPI instances. */
181 QuadSPI_Type * const Qspi_Ip_BaseAddress[QuadSPI_INSTANCE_COUNT] = IP_QuadSPI_BASE_PTRS;
182 /* Table of AHB addresses for QuadSPI instances. */
183 const uint32 Qspi_Ip_AhbAddress[QuadSPI_INSTANCE_COUNT] = QuadSPI_AHB_PTRS;
184
185 #define FLS_STOP_SEC_CONST_UNSPECIFIED
186 #include "Fls_MemMap.h"
187
188
189 #define FLS_START_SEC_VAR_CLEARED_8
190 #include "Fls_MemMap.h"
191
192 /* The padding bytes information to handle unaligned read/write operation for QuadSPI instances:
193 - For read:
194 [7:0] the number of padding bytes to handle read from unaligned address
195 - For write:
196 [7:4] the number of pre-padding bytes to handle write from unaligned start address
197 [3:0] the number of post-padding bytes to handle write from unaligned end address
198 */
199 uint8 Qspi_Ip_MemoryPadding[QuadSPI_INSTANCE_COUNT];
200
201 #define FLS_STOP_SEC_VAR_CLEARED_8
202 #include "Fls_MemMap.h"
203
204 #define FLS_START_SEC_VAR_CLEARED_32
205 #include "Fls_MemMap.h"
206
207 /* Pointer to runtime configuration structures (storing the DLL configuration for runtime usage) */
208 const Qspi_Ip_ControllerConfigType * Qspi_Ip_ControllerConfig[QuadSPI_INSTANCE_COUNT];
209
210 #define FLS_STOP_SEC_VAR_CLEARED_32
211 #include "Fls_MemMap.h"
212
213 /*******************************************************************************
214 * Private Functions
215 ******************************************************************************/
216
217 #define FLS_START_SEC_CODE
218 #include "Fls_MemMap.h"
219
220 static inline uint32 Qspi_Ip_GetWordSize(uint32 sizeRemaining);
221
222 #if (FEATURE_QSPI_HAS_SFP == 1)
223
224 void Qspi_Ip_Sfp_Configure_Privileged(QuadSPI_Type * baseAddr, Qspi_Ip_ControllerConfigType const * userConfigPtr);
225 void Qspi_Ip_ResetPrivilegedRegisters_Privileged(QuadSPI_Type *BaseAddr);
226 void Qspi_Ip_Sfp_ClearLatchedErrors_Privileged(QuadSPI_Type * BaseAddr);
227
228 #endif /* FEATURE_QSPI_HAS_SFP */
229
230 inline static void Qspi_Ip_ResetAllRegisters(QuadSPI_Type *BaseAddr);
231
232 static Qspi_Ip_StatusType Qspi_Ip_CmdWaitComplete(uint32 instance);
233
234 /*FUNCTION**********************************************************************
235 *
236 * Function Name : Qspi_Ip_GetWordSize
237 * Description : Calculates the word size for the up coming loop
238 */
Qspi_Ip_GetWordSize(uint32 sizeRemaining)239 static inline uint32 Qspi_Ip_GetWordSize(uint32 sizeRemaining)
240 {
241 return (sizeRemaining > 4U) ? 4U : sizeRemaining;
242 }
243
244 /*FUNCTION**********************************************************************
245 *
246 * Function Name : Qspi_Ip_ProcessDataRead
247 * Description : Processes read data
248 * @implements Qspi_Ip_ProcessDataRead_Activity */
Qspi_Ip_ProcessDataRead(uint8 * dataRead,uint32 size,const QuadSPI_Type * baseAddr,uint32 padding)249 static inline Qspi_Ip_StatusType Qspi_Ip_ProcessDataRead(uint8 *dataRead,
250 uint32 size,
251 const QuadSPI_Type *baseAddr,
252 uint32 padding
253 )
254 {
255 uint8 * data = dataRead;
256 uint32 cnt = 0U;
257 uint32 recvData;
258 const uint8 *recvDataPtr = (uint8 *)(&recvData);
259 uint32 wordSize;
260 uint32 byteCnt;
261 uint32 sizeRemaining = size;
262 uint32 paddingBytes = padding;
263
264 if (0U != paddingBytes)
265 {
266 /* Ignore all padding words, jump to the fist data */
267 cnt = paddingBytes >> 2U;
268 sizeRemaining -= cnt << 2U;
269 paddingBytes &= 0x3U;
270
271 /* Get first received word */
272 recvData = baseAddr->RBDR[cnt];
273 cnt++;
274 /* Get wordSize for the loop */
275 wordSize = Qspi_Ip_GetWordSize(sizeRemaining);
276
277 /* Ignore padding bytes and copy the rest to buffer */
278 for (byteCnt = paddingBytes; byteCnt < wordSize; byteCnt++)
279 {
280 #if (defined(CORE_BIG_ENDIAN))
281 *data = recvDataPtr[3U - byteCnt];
282 #else
283 *data = recvDataPtr[byteCnt];
284 #endif
285
286 data++;
287 }
288 sizeRemaining -= wordSize;
289 }
290
291 /* Check user buffer alignment */
292 if (((Qspi_Ip_UintPtrType)data & 0x3U) == 0U)
293 {
294 /* Process 4 bytes at a time to speed up read */
295 while (sizeRemaining >= 4U)
296 {
297 *((uint32 *)((Qspi_Ip_UintPtrType)data)) = baseAddr->RBDR[cnt]; /* Casting through uint32 to avoid Misra 11.3 */
298 data = &(data[4U]);
299 cnt++;
300 sizeRemaining -= 4U;
301 }
302 }
303
304 /* Process remaining bytes one by one */
305 while (sizeRemaining > 0U)
306 {
307 /* Get next received word */
308 recvData = baseAddr->RBDR[cnt];
309 /* get wordSize for the loop */
310 wordSize = Qspi_Ip_GetWordSize(sizeRemaining);
311 for (byteCnt = 0U; byteCnt < wordSize; byteCnt++)
312 {
313 #if (defined(CORE_BIG_ENDIAN))
314 *data = (uint8)(recvData >> 24U);
315 recvData <<= 8U;
316 #else
317 *data = (uint8)(recvData & 0xFFU);
318 recvData >>= 8U;
319 #endif
320 data++;
321 sizeRemaining--;
322 }
323 cnt++;
324 }
325 return STATUS_QSPI_IP_SUCCESS;
326 }
327
328
329 /*FUNCTION**********************************************************************
330 *
331 * Function Name : Qspi_Ip_ProcessDataVerify
332 * Description : Processes program verify data
333 * @implements Qspi_Ip_ProcessDataVerify_Activity */
Qspi_Ip_ProcessDataVerify(const uint8 * dataCmp,uint32 size,const QuadSPI_Type * baseAddr,uint32 padding)334 static inline Qspi_Ip_StatusType Qspi_Ip_ProcessDataVerify(const uint8 *dataCmp,
335 uint32 size,
336 const QuadSPI_Type *baseAddr,
337 uint32 padding
338 )
339 {
340 const uint8 * roData = dataCmp;
341 uint32 cnt = 0U;
342 uint32 recvData;
343 uint8 recvByte;
344 const uint8 *recvDataPtr = (uint8 *)(&recvData);
345 Qspi_Ip_StatusType status = STATUS_QSPI_IP_SUCCESS;
346 uint32 byteCnt;
347 uint32 wordSize;
348 uint32 paddingBytes = padding;
349 uint32 sizeRemaining = size;
350
351 if (0U != paddingBytes)
352 {
353 /* Ignore all padding words, jump to the fist data */
354 cnt = paddingBytes >> 2U;
355 sizeRemaining -= cnt << 2U;
356 paddingBytes &= 0x3U;
357
358 /* Get first received word */
359 recvData = baseAddr->RBDR[cnt];
360 cnt++;
361 /* Get wordSize for the loop */
362 wordSize = Qspi_Ip_GetWordSize(sizeRemaining);
363 sizeRemaining -= wordSize;
364
365 /* Ignore padding bytes and compare the rest with user buffer */
366 for (byteCnt = paddingBytes; byteCnt < wordSize; byteCnt++)
367 {
368 #if (defined(CORE_BIG_ENDIAN))
369 recvByte = recvDataPtr[3U - byteCnt];
370 #else
371 recvByte = recvDataPtr[byteCnt];
372 #endif
373
374 /* return STATUS_QSPI_IP_ERROR_PROGRAM_VERIFY if the data is not match */
375 if (*roData != recvByte)
376 {
377 status = STATUS_QSPI_IP_ERROR_PROGRAM_VERIFY;
378 sizeRemaining = 0U;
379 break;
380 }
381 roData++;
382 }
383 }
384
385 /* Check user buffer alignment */
386 if (((Qspi_Ip_UintPtrType)roData & 0x3U) == 0U)
387 {
388 while (sizeRemaining >= 4U)
389 {
390 /* Process 4 bytes at a time to speed up read */
391 if (*((const uint32 *)((Qspi_Ip_UintPtrType)roData)) != baseAddr->RBDR[cnt])
392 {
393 /* return STATUS_QSPI_IP_ERROR_PROGRAM_VERIFY if the data is not match */
394 status = STATUS_QSPI_IP_ERROR_PROGRAM_VERIFY;
395 sizeRemaining = 0U;
396 break;
397 }
398 /* update the roData */
399 roData = &(roData[4U]);
400 cnt++;
401 sizeRemaining -= 4U;
402 }
403 }
404
405 /* Process remaining bytes one by one */
406 while (sizeRemaining > 0U)
407 {
408 /* Get next received word */
409 recvData = baseAddr->RBDR[cnt];
410 /* get wordSize for the loop */
411 wordSize = Qspi_Ip_GetWordSize(sizeRemaining);
412 for (byteCnt = 0U; byteCnt < wordSize; byteCnt++)
413 {
414 #if (defined(CORE_BIG_ENDIAN))
415 recvByte = (uint8)(recvData >> 24U);
416 recvData <<= 8U;
417 #else
418 recvByte = (uint8)(recvData & 0xFFU);
419 recvData >>= 8U;
420 #endif
421 /* return STATUS_QSPI_IP_ERROR_PROGRAM_VERIFY if the data is not match */
422 if (*roData != recvByte)
423 {
424 status = STATUS_QSPI_IP_ERROR_PROGRAM_VERIFY;
425 sizeRemaining = 0U;
426 break;
427 }
428 else
429 {
430 /* update the roData, sizeRemaining */
431 roData++;
432 sizeRemaining--;
433 }
434 }
435 cnt++;
436 }
437 return status;
438 }
439
440
441 /*FUNCTION**********************************************************************
442 *
443 * Function Name : Qspi_Ip_ProcessDataBlankCheck
444 * Description : Processes blank check data
445 * @implements Qspi_Ip_ProcessDataBlankCheck_Activity */
Qspi_Ip_ProcessDataBlankCheck(uint32 size,const QuadSPI_Type * baseAddr,uint32 padding)446 static inline Qspi_Ip_StatusType Qspi_Ip_ProcessDataBlankCheck(uint32 size,
447 const QuadSPI_Type *baseAddr,
448 uint32 padding
449 )
450 {
451 uint32 cnt = 0U;
452 uint32 recvData = 0U;
453 Qspi_Ip_StatusType status = STATUS_QSPI_IP_SUCCESS;
454 uint32 dataSize;
455 uint32 sizeRemaining = size;
456 uint32 paddingBytes = padding;
457
458 if (0U != paddingBytes)
459 {
460 /* Ignore all padding words, jump to the fist data */
461 cnt = paddingBytes >> 2U;
462 sizeRemaining -= cnt << 2U;
463 paddingBytes &= 0x3U;
464
465 /* Get first received word */
466 recvData = ~(baseAddr->RBDR[cnt]);
467 cnt++;
468 /* Get wordSize for the blank check */
469 dataSize = Qspi_Ip_GetWordSize(sizeRemaining);
470 sizeRemaining -= dataSize;
471
472 /* Mask data: ignore padding at the beginning and unused bytes at the end */
473 #if (defined(CORE_BIG_ENDIAN))
474 recvData &= 0xFFFFFFFFUL << ((4UL - dataSize) * 8UL);
475 recvData &= 0xFFFFFFFFUL >> (paddingBytes * 8UL);
476 #else
477 recvData &= 0xFFFFFFFFUL >> ((4UL - dataSize) * 8UL);
478 recvData &= 0xFFFFFFFFUL << (paddingBytes * 8UL);
479 #endif
480 if (recvData != 0U)
481 {
482 /* The data is not blank */
483 status = STATUS_QSPI_IP_ERROR;
484 sizeRemaining = 0U;
485 }
486 }
487
488 /* Blank check */
489 while (sizeRemaining >= 4U)
490 {
491 if (baseAddr->RBDR[cnt] != 0xFFFFFFFFU)
492 {
493 /* The data is not blank */
494 status = STATUS_QSPI_IP_ERROR;
495 sizeRemaining = 0U;
496 break;
497 }
498 cnt++;
499 sizeRemaining -= 4U;
500 }
501
502 if (sizeRemaining != 0U)
503 {
504 /* Process last few bytes */
505 recvData = baseAddr->RBDR[size >> 2U];
506 #if (defined(CORE_BIG_ENDIAN))
507 if ((~recvData & ~(((uint32)1U << (((uint32)4U - sizeRemaining) * 8U)) - 1U)) != 0U)
508 #else
509 if ((~recvData & (((uint32)1U << (sizeRemaining * 8U)) - 1U)) != 0U)
510 #endif
511 {
512 /* The data is not blank */
513 status = STATUS_QSPI_IP_ERROR;
514 }
515 }
516 return status;
517 }
518
519 /*FUNCTION**********************************************************************
520 *
521 * Function Name : Qspi_Ip_FillTxBuf
522 * Description : Fill Tx buffer with the specified number of 4-byte entries
523 * @implements Qspi_Ip_FillTxBuf_Activity */
Qspi_Ip_FillTxBuf(QuadSPI_Type * baseAddr,const uint8 * roData,uint32 size,uint32 paddingInfo)524 static void Qspi_Ip_FillTxBuf(QuadSPI_Type *baseAddr,
525 const uint8 *roData,
526 uint32 size,
527 uint32 paddingInfo
528 )
529 {
530 uint32 sizeLeft = size;
531 uint32 wordSize;
532 uint32 data = 0xFFFFFFFFUL;
533 uint8 *dataPtr = (uint8 *)(&data);
534 uint32 byteCnt;
535 const uint8 * roDataPtr = roData;
536
537 uint32 prePadding = paddingInfo >> 4U;
538 uint32 postPadding = paddingInfo & 0x0FU;
539
540 /* Insert prePadding words */
541 while (prePadding >= 4U)
542 {
543 Qspi_Ip_WriteTxData(baseAddr, 0xFFFFFFFFUL);
544 prePadding -= 4U;
545 }
546
547 if (prePadding != 0U)
548 {
549 wordSize = prePadding + sizeLeft;
550
551 if (wordSize > 4U)
552 {
553 wordSize = 4U;
554 sizeLeft -= (4U - prePadding);
555 }
556 else
557 {
558 /* Note for special case: prePadding + Data + postPadding are fit into a word
559 Decreaseing postPadding is not needed because out of user data, all branches below will be skipped
560 */
561 sizeLeft = 0U;
562 }
563
564 /* Fill user data between prePadding and postPadding */
565 for (byteCnt = prePadding; byteCnt < wordSize; byteCnt++)
566 {
567 #if (defined(CORE_BIG_ENDIAN))
568 dataPtr[3U - byteCnt] = *roDataPtr;
569 #else
570 dataPtr[byteCnt] = *roDataPtr;
571 #endif
572
573 roDataPtr++;
574 }
575 Qspi_Ip_WriteTxData(baseAddr, data);
576 }
577
578 /* Check user buffer alignment */
579 if (((Qspi_Ip_UintPtrType)roDataPtr & 0x3U) == 0U)
580 {
581 /* Process 4 bytes at a time to speed things up */
582 while (sizeLeft >= 4U)
583 {
584 data = *(const uint32 *)((Qspi_Ip_UintPtrType)roDataPtr); /* Casting through uint32 to avoid Misra 11.3 */
585 sizeLeft -= 4U;
586 roDataPtr = &(roDataPtr[4U]);
587 Qspi_Ip_WriteTxData(baseAddr, data);
588 }
589 }
590
591 /* Process remaining bytes one by one */
592 while (sizeLeft > 0U)
593 {
594 /* Processes last few data bytes (less than 4) */
595 data = 0xFFFFFFFFUL;
596 wordSize = Qspi_Ip_GetWordSize(sizeLeft);
597
598 for (byteCnt = 0U; byteCnt < wordSize; byteCnt++)
599 {
600 #if (defined(CORE_BIG_ENDIAN))
601 dataPtr[3U - byteCnt] = *roDataPtr;
602 #else
603 dataPtr[byteCnt] = *roDataPtr;
604 #endif
605
606 roDataPtr++;
607 }
608 Qspi_Ip_WriteTxData(baseAddr, data);
609 sizeLeft -= wordSize;
610 }
611
612 /* Insert postPadding words */
613 while (postPadding >= 4U)
614 {
615 Qspi_Ip_WriteTxData(baseAddr, 0xFFFFFFFFUL);
616 postPadding -= 4U;
617 }
618 }
619
620
621 /*FUNCTION**********************************************************************
622 *
623 * Function Name : Qspi_Ip_ErrorCheck
624 * Description : Checks if there were errors during IP command execution
625 * @implements Qspi_Ip_ErrorCheck_Activity */
Qspi_Ip_ErrorCheck(QuadSPI_Type * baseAddr)626 static inline Qspi_Ip_StatusType Qspi_Ip_ErrorCheck(QuadSPI_Type *baseAddr)
627 {
628 Qspi_Ip_StatusType status;
629
630 if ((baseAddr->FR & QSPI_ERR_FLAGS_MASK) != 0U)
631 {
632 /* clear error flags */
633 baseAddr->FR = QSPI_ERR_FLAGS_MASK;
634 status = STATUS_QSPI_IP_ERROR;
635 }
636 #if (FEATURE_QSPI_HAS_SFP == 1)
637 else if (baseAddr->ERRSTAT != 0UL)
638 {
639 status = STATUS_QSPI_IP_ERROR;
640 }
641 #endif /* FEATURE_QSPI_HAS_SFP */
642 else
643 {
644 status = STATUS_QSPI_IP_SUCCESS;
645 }
646
647 return status;
648 }
649
650
651 /*FUNCTION**********************************************************************
652 *
653 * Function Name : Qspi_Ip_SwResetDelay
654 * Description : Insert waiting loops after changing the value of the software reset bits
655 */
Qspi_Ip_SwResetDelay(void)656 static inline void Qspi_Ip_SwResetDelay(void)
657 {
658 volatile uint32 u32CurrentTicks;
659 /* Prepare timeout counter */
660 u32CurrentTicks = QSPI_IP_SOFTWARE_RESET_DELAY;
661 /* Insert delay after changing the value of the software reset bits. */
662 while (u32CurrentTicks > 0U)
663 {
664 u32CurrentTicks--;
665 }
666 }
667
668
669 /*FUNCTION**********************************************************************
670 *
671 * Function Name : Qspi_Ip_SwReset
672 * Description : Resets the QuadSPI device
673 * @implements Qspi_Ip_SwReset_Activity */
Qspi_Ip_SwReset(QuadSPI_Type * baseAddr)674 static void Qspi_Ip_SwReset(QuadSPI_Type *baseAddr)
675 {
676 /* Software reset AHB domain and Serial Flash domain at the same time. */
677 Qspi_Ip_SwResetOn(baseAddr);
678 /* Insert delay after changing the value of the reset bits. */
679 Qspi_Ip_SwResetDelay();
680 /* Disable QuadSPI module before de-asserting the reset bits. */
681 Qspi_Ip_Disable(baseAddr);
682 /* De-asset Software reset AHB domain and Serial Flash domain bits. */
683 Qspi_Ip_SwResetOff(baseAddr);
684 /* Re-enable QuadSPI module after reset. */
685 Qspi_Ip_Enable(baseAddr);
686 /* Insert delay after changing the value of the reset bits. */
687 Qspi_Ip_SwResetDelay();
688 }
689
690 /*FUNCTION**********************************************************************
691 *
692 * Function Name : Qspi_Ip_AhbFlush
693 * Description : Reset AHB buffers
694 */
Qspi_Ip_AhbFlush(QuadSPI_Type * baseAddr)695 static void Qspi_Ip_AhbFlush(QuadSPI_Type *baseAddr)
696 {
697 #ifdef QuadSPI_SPTRCLR_ABRT_CLR_MASK
698 uint32 u32ElapsedTicks = 0UL;
699 uint32 u32TimeoutTicks;
700 uint32 u32CurrentTicks;
701
702 /* Use the AHB buffer clear bit to avoid losing the DLL lock */
703 Qspi_Ip_ClearAhbBuf(baseAddr);
704
705 /* Prepare timeout counter */
706 u32TimeoutTicks = OsIf_MicrosToTicks(QSPI_IP_CMD_COMPLETE_TIMEOUT, (OsIf_CounterType)QSPI_IP_TIMEOUT_TYPE);
707 u32CurrentTicks = OsIf_GetCounter((OsIf_CounterType)QSPI_IP_TIMEOUT_TYPE);
708
709 /* Wait for clearing the AHB buffer pointers */
710 while (!Qspi_Ip_GetClrAhbStatus(baseAddr))
711 {
712 /* An exit point for safety purpose only, because this loop is not expected to happen in practice */
713 u32ElapsedTicks += OsIf_GetElapsed(&u32CurrentTicks, (OsIf_CounterType)QSPI_IP_TIMEOUT_TYPE);
714 if ( u32ElapsedTicks >= u32TimeoutTicks )
715 {
716 break;
717 }
718 }
719
720 #else
721 /* Otherwise use the software reset */
722 Qspi_Ip_SwReset(baseAddr);
723 #endif
724 }
725
726
727 /*FUNCTION**********************************************************************
728 *
729 * Function Name : Qspi_Ip_WaitDLLASlaveLock
730 * Description : DLL side A - Wait for slave high lock status or DLL lock status
731 */
Qspi_Ip_WaitDLLASlaveLock(const QuadSPI_Type * baseAddr,boolean waitSlaveLock)732 static Qspi_Ip_StatusType Qspi_Ip_WaitDLLASlaveLock(const QuadSPI_Type *baseAddr,
733 boolean waitSlaveLock
734 )
735 {
736 Qspi_Ip_StatusType status = STATUS_QSPI_IP_SUCCESS;
737 boolean LockStatus;
738
739 /* Prepare timeout counter */
740 uint32 u32ElapsedTicks = 0UL;
741 uint32 u32TimeoutTicks = OsIf_MicrosToTicks(QSPI_IP_DLL_LOCK_TIMEOUT, (OsIf_CounterType)QSPI_IP_TIMEOUT_TYPE);
742 uint32 u32CurrentTicks = OsIf_GetCounter((OsIf_CounterType)QSPI_IP_TIMEOUT_TYPE);
743
744 do
745 {
746 /* Wait for slave high lock status or DLL lock status */
747 LockStatus = (waitSlaveLock) ? Qspi_Ip_DLLGetSlaveLockStatusA(baseAddr) : Qspi_Ip_DLLGetLockStatusA(baseAddr);
748
749 /* Check for errors reported by DLL */
750 if (Qspi_Ip_DLLGetErrorStatusA(baseAddr))
751 {
752 status = STATUS_QSPI_IP_ERROR;
753 }
754 else
755 {
756 /* Check for timeout */
757 u32ElapsedTicks += OsIf_GetElapsed(&u32CurrentTicks, (OsIf_CounterType)QSPI_IP_TIMEOUT_TYPE);
758 if (u32ElapsedTicks >= u32TimeoutTicks)
759 {
760 status = STATUS_QSPI_IP_TIMEOUT;
761 }
762 }
763
764 if (STATUS_QSPI_IP_SUCCESS != status)
765 {
766 break;
767 }
768 }
769 while (!LockStatus);
770
771 return status;
772 }
773
774 /*FUNCTION**********************************************************************
775 *
776 * Function Name : Qspi_Ip_ConfigureDLLAByPass
777 * Description : Configures DLL - Side A (bypass mode)
778 */
Qspi_Ip_ConfigureDLLAByPass(QuadSPI_Type * baseAddr,const Qspi_Ip_ControllerConfigType * userConfigPtr)779 static Qspi_Ip_StatusType Qspi_Ip_ConfigureDLLAByPass(QuadSPI_Type *baseAddr,
780 const Qspi_Ip_ControllerConfigType *userConfigPtr
781 )
782 {
783 Qspi_Ip_StatusType status = STATUS_QSPI_IP_SUCCESS;
784
785 /* Set DLL in bypass mode and configure coarse and fine delays */
786 Qspi_Ip_DLLSlaveBypassA(baseAddr, TRUE);
787 #ifdef QuadSPI_DLLCRA_SLAVE_AUTO_UPDT_MASK
788 Qspi_Ip_DLLSlaveAutoUpdateA(baseAddr, FALSE);
789 #endif /* QuadSPI_DLLCRA_SLAVE_AUTO_UPDT_MASK */
790 Qspi_Ip_DLLSetCoarseDelayA(baseAddr, userConfigPtr->dllSettingsA.coarseDelay);
791 Qspi_Ip_DLLSetFineOffsetA(baseAddr, userConfigPtr->dllSettingsA.fineDelay);
792 Qspi_Ip_DLLFreqEnA(baseAddr, userConfigPtr->dllSettingsA.freqEnable);
793
794 /* Trigger slave chain update */
795 Qspi_Ip_DLLSlaveUpdateA(baseAddr, TRUE);
796
797 /* Wait for slave delay chain update */
798 status = Qspi_Ip_WaitDLLASlaveLock(baseAddr, (boolean)TRUE);
799
800 /* Disable slave chain update */
801 Qspi_Ip_DLLSlaveUpdateA(baseAddr, FALSE);
802
803 return status;
804 }
805
806 /*FUNCTION**********************************************************************
807 *
808 * Function Name : Qspi_Ip_ConfigureDLLAUpdate
809 * Description : Configures DLL - Side A (manual update or auto update mode)
810 */
Qspi_Ip_ConfigureDLLAUpdate(QuadSPI_Type * baseAddr,const Qspi_Ip_ControllerConfigType * userConfigPtr)811 static Qspi_Ip_StatusType Qspi_Ip_ConfigureDLLAUpdate(QuadSPI_Type *baseAddr,
812 const Qspi_Ip_ControllerConfigType *userConfigPtr
813 )
814 {
815 Qspi_Ip_StatusType status = STATUS_QSPI_IP_SUCCESS;
816
817 /* Set DLL in auto update mode and configure coarse and fine delays */
818 Qspi_Ip_DLLSlaveBypassA(baseAddr, FALSE);
819 #ifdef QuadSPI_DLLCRA_SLAVE_AUTO_UPDT_MASK
820 Qspi_Ip_DLLSlaveAutoUpdateA(baseAddr, (QSPI_IP_DLL_AUTO_UPDATE == userConfigPtr->dllSettingsA.dllMode));
821 #endif /* QuadSPI_DLLCRA_SLAVE_AUTO_UPDT_MASK */
822 Qspi_Ip_DLLSetReferenceCounterA(baseAddr, userConfigPtr->dllSettingsA.referenceCounter);
823 #ifdef QuadSPI_DLLCRA_DLLRES_MASK
824 Qspi_Ip_DLLSetResolutionA(baseAddr, userConfigPtr->dllSettingsA.resolution);
825 #endif /* QuadSPI_DLLCRA_DLLRES_MASK */
826 Qspi_Ip_DLLSetCoarseOffsetA(baseAddr, userConfigPtr->dllSettingsA.coarseDelay);
827 Qspi_Ip_DLLSetFineOffsetA(baseAddr, userConfigPtr->dllSettingsA.fineDelay);
828 Qspi_Ip_DLLFreqEnA(baseAddr, userConfigPtr->dllSettingsA.freqEnable);
829
830 if (QSPI_IP_DLL_AUTO_UPDATE == userConfigPtr->dllSettingsA.dllMode)
831 {
832 /* For auto update mode, trigger slave chain update */
833 Qspi_Ip_DLLSlaveUpdateA(baseAddr, TRUE);
834 }
835 #ifdef QuadSPI_DLLCRA_DLLEN_MASK
836 /* Enable DLL */
837 Qspi_Ip_DLLEnableA(baseAddr, TRUE);
838 #endif /* QuadSPI_DLLCRA_DLLEN_MASK */
839 if (QSPI_IP_DLL_MANUAL_UPDATE == userConfigPtr->dllSettingsA.dllMode)
840 {
841 /* For manual update mode, wait for DLL lock before triggering slave chain update */
842 status = Qspi_Ip_WaitDLLASlaveLock(baseAddr, (boolean)FALSE);
843
844 Qspi_Ip_DLLSlaveUpdateA(baseAddr, TRUE);
845 }
846
847 /* Wait for slave delay chain update */
848 if (STATUS_QSPI_IP_SUCCESS == status)
849 {
850 status = Qspi_Ip_WaitDLLASlaveLock(baseAddr, (boolean)TRUE);
851 }
852
853 /* Disable slave chain update */
854 Qspi_Ip_DLLSlaveUpdateA(baseAddr, FALSE);
855
856 return status;
857 }
858
859 /*FUNCTION**********************************************************************
860 *
861 * Function Name : Qspi_Ip_ConfigureDLLA
862 * Description : Configures DLL - Side A
863 * @implements Qspi_Ip_ConfigureDLLA_Activity */
Qspi_Ip_ConfigureDLLA(uint32 instance,QuadSPI_Type * baseAddr,const Qspi_Ip_ControllerConfigType * userConfigPtr)864 static Qspi_Ip_StatusType Qspi_Ip_ConfigureDLLA(uint32 instance,
865 QuadSPI_Type *baseAddr,
866 const Qspi_Ip_ControllerConfigType *userConfigPtr
867 )
868 {
869 (void)instance;
870 Qspi_Ip_StatusType status = STATUS_QSPI_IP_SUCCESS;
871
872 /* Ensure DLL and slave chain update are off */
873 Qspi_Ip_DLLSlaveUpdateA(baseAddr, FALSE);
874 #ifdef QuadSPI_DLLCRA_DLLEN_MASK
875 Qspi_Ip_DLLEnableA(baseAddr, FALSE);
876 #endif /* QuadSPI_DLLCRA_DLLEN_MASK */
877
878 /* Enable DQS slave delay chain before any settings take place */
879 Qspi_Ip_DLLSlaveEnA(baseAddr, TRUE);
880
881 if (QSPI_IP_DLL_BYPASSED == userConfigPtr->dllSettingsA.dllMode)
882 {
883 status = Qspi_Ip_ConfigureDLLAByPass(baseAddr, userConfigPtr);
884 }
885 else /* QSPI_DLL_MANUAL_UPDATE or QSPI_DLL_AUTO_UPDATE */
886 {
887 status = Qspi_Ip_ConfigureDLLAUpdate(baseAddr, userConfigPtr);
888 }
889
890 return status;
891 }
892
893
894 /*FUNCTION**********************************************************************
895 *
896 * Function Name : Qspi_Ip_ConfigureDLL
897 * Description : Configure the DLL chain
898 *
899 *END**************************************************************************/
Qspi_Ip_ConfigureDLL(uint32 instance,const Qspi_Ip_ControllerConfigType * userConfigPtr)900 static Qspi_Ip_StatusType Qspi_Ip_ConfigureDLL(uint32 instance,
901 const Qspi_Ip_ControllerConfigType * userConfigPtr
902 )
903 {
904 Qspi_Ip_StatusType status = STATUS_QSPI_IP_SUCCESS;
905 QuadSPI_Type *baseAddr = Qspi_Ip_BaseAddress[instance];
906
907 /* Configure DLL */
908 if ((userConfigPtr->memSizeA1 + userConfigPtr->memSizeA2) > 0U)
909 {
910 status = Qspi_Ip_ConfigureDLLA(instance, baseAddr, userConfigPtr);
911 }
912
913 return status;
914 }
915
916
917 /*FUNCTION**********************************************************************
918 *
919 * Function Name : Qspi_Ip_ConfigureChipOptions
920 * Description : Configures chip-specific settings, e.g. SOCCR
921 ***********************************************************************/
922 #if defined(FEATURE_QSPI_CHIP_OPTIONS_S32K148)
Qspi_Ip_ConfigureChipOptions(QuadSPI_Type * baseAddr,const Qspi_Ip_ControllerConfigType * userConfigPtr)923 static void Qspi_Ip_ConfigureChipOptions(QuadSPI_Type *baseAddr,
924 const Qspi_Ip_ControllerConfigType *userConfigPtr
925 )
926 {
927 /* always enable pads input buffers */
928 uint8 clkOption = QSPI_MCR_SCLKCFG_INPUT_EN;
929 uint32 chipOption = 0U;
930
931 /* Configure MCR_SCLKCFG options */
932 /* Configure module clock selection */
933 if (QSPI_IP_CLK_SRC_BUS_CLK == userConfigPtr->clockSrc)
934 {
935 clkOption |= QSPI_MCR_SCLKCFG_CLK_MOD;
936 }
937 /* Configure internal reference clock selection */
938 if (QSPI_IP_CLK_REF_FIRC_DIV1 == userConfigPtr->clockRef)
939 {
940 clkOption |= QSPI_MCR_SCLKCFG_CLK_SRC;
941 }
942 /* Configure external DQS mode for Flash B (HyperRAM Enabled) */
943 if (QSPI_IP_READ_MODE_EXTERNAL_DQS == userConfigPtr->readModeB)
944 {
945 clkOption |= QSPI_MCR_SCLKCFG_EXT_DQS;
946 }
947 /* Select reference clock for DQS for each side */
948 if (QSPI_IP_READ_MODE_LOOPBACK == userConfigPtr->readModeA)
949 {
950 clkOption |= (uint8)(QSPI_MCR_SCLKCFG_DQS_SEL_A);
951 }
952 if (QSPI_IP_READ_MODE_LOOPBACK == userConfigPtr->readModeB)
953 {
954 clkOption |= (uint8)(QSPI_MCR_SCLKCFG_DQS_SEL_B);
955 }
956 /* Configure inverted DQS: 0-Inverted / 1-Not Inverted */
957 if ((boolean)FALSE == userConfigPtr->dqsInvertA)
958 {
959 clkOption |= (uint8)(QSPI_MCR_SCLKCFG_DQS_INV_A);
960 }
961 if ((boolean)FALSE == userConfigPtr->dqsInvertB)
962 {
963 clkOption |= (uint8)(QSPI_MCR_SCLKCFG_DQS_INV_B);
964 }
965 Qspi_Ip_SetClockOptions(baseAddr, clkOption);
966
967 /* Configure SOCCR options */
968 /* Disable divider before configuring it */
969 Qspi_Ip_SetChipOptions(baseAddr, QuadSPI_SOCCR_PDD_MASK);
970 chipOption |= QuadSPI_SOCCR_PD((uint32)userConfigPtr->clockRefDiv - 1U);
971 chipOption |= ((uint32)userConfigPtr->dqsDelayA << QuadSPI_SOCCR_DSQ_DEL_A) +
972 ((uint32)userConfigPtr->dqsDelayB << QuadSPI_SOCCR_DSQ_DEL_B);
973 /* Write configuration, keep divider disabled */
974 Qspi_Ip_SetChipOptions(baseAddr, chipOption | QuadSPI_SOCCR_PDD_MASK);
975 /* Enable divider */
976 Qspi_Ip_SetChipOptions(baseAddr, chipOption);
977 }
978
979 #elif defined(FEATURE_QSPI_CHIP_OPTIONS_S32K3)
Qspi_Ip_ConfigureChipOptions(QuadSPI_Type * baseAddr,const Qspi_Ip_ControllerConfigType * userConfigPtr)980 static void Qspi_Ip_ConfigureChipOptions(QuadSPI_Type *baseAddr, const Qspi_Ip_ControllerConfigType * userConfigPtr)
981 {
982 (void)userConfigPtr;
983 Qspi_Ip_SetChipOptions(baseAddr, 0x0000000E); /* set ibe=1, obe=1, dse=1 and sre=0 */
984 }
985
986 #else
Qspi_Ip_ConfigureChipOptions(const QuadSPI_Type * baseAddr,const Qspi_Ip_ControllerConfigType * userConfigPtr)987 static void Qspi_Ip_ConfigureChipOptions(const QuadSPI_Type *baseAddr, const Qspi_Ip_ControllerConfigType * userConfigPtr)
988 {
989 /* Do nothing */
990 (void)userConfigPtr;
991 (void)baseAddr;
992 }
993 #endif
994
995
996 /*FUNCTION**********************************************************************
997 *
998 * Function Name : Qspi_Ip_ConfigureReadOptions
999 * Description : Configures data read settings
1000 * @implements Qspi_Ip_ConfigureReadOptions_Activity */
Qspi_Ip_ConfigureReadOptions(QuadSPI_Type * baseAddr,const Qspi_Ip_ControllerConfigType * userConfigPtr)1001 static void Qspi_Ip_ConfigureReadOptions(QuadSPI_Type *baseAddr,
1002 const Qspi_Ip_ControllerConfigType *userConfigPtr
1003 )
1004 {
1005 /* Always enable DQS */
1006 QSPI_DQS_Enable(baseAddr);
1007
1008 if (QSPI_IP_DATA_RATE_SDR == userConfigPtr->dataRate)
1009 {
1010 #ifdef QuadSPI_MCR_DDR_EN_MASK
1011 QSPI_DDR_Disable(baseAddr);
1012 #endif /* QuadSPI_MCR_DDR_EN_MASK */
1013 #ifdef QuadSPI_FLSHCR_TDH_MASK
1014 /* Ignore output data align setting in SDR mode */
1015 Qspi_Ip_SetDataInHoldTime(baseAddr, QSPI_IP_FLASH_DATA_ALIGN_REFCLK);
1016 #endif /* QuadSPI_FLSHCR_TDH_MASK */
1017 }
1018 else /* QSPI_IP_DATA_RATE_DDR */
1019 {
1020 #ifdef QuadSPI_MCR_DDR_EN_MASK
1021 QSPI_DDR_Enable(baseAddr);
1022 #endif /* QuadSPI_MCR_DDR_EN_MASK */
1023 #ifdef QuadSPI_FLSHCR_TDH_MASK
1024 Qspi_Ip_SetDataInHoldTime(baseAddr, userConfigPtr->dataAlign);
1025 #endif /* QuadSPI_FLSHCR_TDH_MASK */
1026 }
1027
1028 /* select DQS A source (internal/loopback/external) */
1029 Qspi_Ip_SetDQSSourceA(baseAddr, userConfigPtr->readModeA);
1030
1031 /* Select DLL tap in SMPR register */
1032 Qspi_Ip_SetRxDLLTapA(baseAddr, userConfigPtr->dllSettingsA.tapSelect);
1033
1034
1035 (void)userConfigPtr;
1036 }
1037
1038
1039 /*FUNCTION**********************************************************************
1040 *
1041 * Function Name : Qspi_Ip_AhbSetup
1042 * Description : Sets up AHB accesses to the serial flash
1043 * @implements Qspi_Ip_AhbSetup_Activity */
Qspi_Ip_AhbSetup(uint32 instance,const Qspi_Ip_ControllerAhbConfigType * config)1044 static Qspi_Ip_StatusType Qspi_Ip_AhbSetup(uint32 instance,
1045 const Qspi_Ip_ControllerAhbConfigType *config
1046 )
1047 {
1048 QuadSPI_Type *baseAddr;
1049
1050 DEV_ASSERT_QSPI(instance < QuadSPI_INSTANCE_COUNT);
1051 DEV_ASSERT_QSPI(0U == (config->sizes[0U] & 7U));
1052 DEV_ASSERT_QSPI(((uint32)config->sizes[0U] +
1053 (uint32)config->sizes[1U] +
1054 (uint32)config->sizes[2U] +
1055 (uint32)config->sizes[3U]) <= FEATURE_QSPI_AHB_BUF_SIZE);
1056 /* Get base address of instance */
1057 baseAddr = Qspi_Ip_BaseAddress[instance];
1058
1059 /* configure AHB transfer sizes to match the buffer sizes */
1060 /* Set AHB buffer 0 */
1061 Qspi_Ip_SetAhbBuf0(baseAddr, config->sizes[0U], config->masters[0U]);
1062 /* Set AHB buffer 1 */
1063 Qspi_Ip_SetAhbBuf1(baseAddr, config->sizes[1U], config->masters[1U]);
1064 /* Set AHB buffer 2 */
1065 Qspi_Ip_SetAhbBuf2(baseAddr, config->sizes[2U], config->masters[2U]);
1066 /* Set AHB buffer 3 */
1067 Qspi_Ip_SetAhbBuf3(baseAddr, config->sizes[3U], config->masters[3U], config->allMasters);
1068 /* Set AHB buffer index 0 */
1069 Qspi_Ip_SetAhbBuf0Ind(baseAddr, (uint32)config->sizes[0U]);
1070 /* Set AHB buffer index 1 */
1071 Qspi_Ip_SetAhbBuf1Ind(baseAddr, (uint32)config->sizes[0U] + (uint32)config->sizes[1U]);
1072 /* Set AHB buffer index 2 */
1073 Qspi_Ip_SetAhbBuf2Ind(baseAddr, (uint32)config->sizes[0U] + (uint32)config->sizes[1U] + (uint32)config->sizes[2U]);
1074
1075 return STATUS_QSPI_IP_SUCCESS;
1076 }
1077
1078 /** * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
1079 * @brief Program the SFAR & IPCR registers.
1080 *
1081 * @param[in] BaseAddress base address of the given QuadSPI instance
1082 * @param[in] Address address to be written into SFAR
1083 * @param[in] DataSize data size to be written into IPCR
1084 * @param[in] SeqId sequence id where the command is stored in the physical lut
1085 *
1086 * @retval STATUS_QSPI_IP_SUCCESS SFAR and IPCR writes passed the MDAD checks
1087 * @retval STATUS_QSPI_IP_ERROR a common or a queue error has occurred
1088 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
Qspi_Ip_NewIpsTransaction(QuadSPI_Type * BaseAddress,uint32 Address,uint16 DataSize,uint8 SeqId)1089 static void Qspi_Ip_NewIpsTransaction
1090 (
1091 QuadSPI_Type * BaseAddress,
1092 uint32 Address,
1093 uint16 DataSize,
1094 uint8 SeqId)
1095 {
1096 #if (FEATURE_QSPI_HAS_SFP == 1)
1097 Qspi_Ip_Sfp_ClearLatchedErrors(BaseAddress);
1098 #endif
1099
1100 Qspi_Ip_SetIpAddr(BaseAddress, Address);
1101 Qspi_Ip_IpTrigger(BaseAddress, SeqId, DataSize);
1102 }
1103
1104 #if (FEATURE_QSPI_HAS_SFP == 1)
1105
1106 /** * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
1107 * @brief Clear the errors latched in SFP registers.
1108 *
1109 * Error Status (ERRSTAT):
1110 * - FRADn Access Error (FRADnACC)
1111 * - No FRAD Match Error (FRADMTCH)
1112 * FlashSeq Request (FLSEQREQ):
1113 * - Clear (CLR)
1114 * IPS Error (IPSERROR):
1115 * - Clear (CLR)
1116 * Target Group n SFAR Status (TG0SFARS - TG1SFARS):
1117 * - Clear (CLR)
1118 * Target Group n IPCR Status (TG0IPCRS - TG1IPCRS):
1119 * - Clear (CLR)
1120 *
1121 * @param[in] BaseAddr base address of the given QuadSPI instance
1122 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
Qspi_Ip_Sfp_ClearLatchedErrors_Privileged(QuadSPI_Type * BaseAddr)1123 void Qspi_Ip_Sfp_ClearLatchedErrors_Privileged
1124 (
1125 QuadSPI_Type * BaseAddr)
1126 {
1127 BaseAddr->ERRSTAT |= 0x1FFUL;
1128 BaseAddr->FLSEQREQ |= QuadSPI_FLSEQREQ_CLR_MASK;
1129 BaseAddr->IPSERROR |= QuadSPI_IPSERROR_CLR_MASK;
1130
1131 for (uint8 Mdad = 0U; Mdad < QuadSPI_MDAD_COUNT; ++Mdad)
1132 {
1133 BaseAddr->MDAD[Mdad].TGSFARS |= QuadSPI_TGSFARS_CLR_MASK;
1134 BaseAddr->MDAD[Mdad].TGIPCRS |= QuadSPI_TGIPCRS_CLR_MASK;
1135 }
1136 }
1137
1138 /** * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
1139 * @brief Wait for the current transaction to reach a given state
1140 *
1141 * @param[in] BaseAddress base address of the given QuadSPI instance
1142 * @param[in] State the STATE field value that is to be expected
1143 *
1144 * @retval STATUS_QSPI_IP_SUCCESS
1145 * @retval STATUS_QSPI_IP_TIMEOUT
1146 * @retval STATUS_QSPI_IP_ERROR
1147 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
Qspi_Ip_Sfp_WaitFsmState(QuadSPI_Type const * BaseAddress,uint32 State)1148 static Qspi_Ip_StatusType Qspi_Ip_Sfp_WaitFsmState
1149 (
1150 QuadSPI_Type const * BaseAddress,
1151 uint32 State)
1152 {
1153 Qspi_Ip_StatusType Status = STATUS_QSPI_IP_ERROR;
1154 uint32 FsmStat = 0U;
1155 uint32 FsmStatValid = 0U;
1156 uint32 FsmStatState = 0U;
1157 uint32 ElapsedTicks = 0U;
1158 uint32 TimeoutTicks = OsIf_MicrosToTicks(QSPI_IP_QSPI_IDLE_TIMEOUT, QSPI_IP_TIMEOUT_TYPE);;
1159 uint32 CurrentTicks = OsIf_GetCounter(QSPI_IP_TIMEOUT_TYPE);;
1160
1161 do
1162 {
1163 FsmStat = BaseAddress->FSMSTAT;
1164 FsmStatValid = (FsmStat & QuadSPI_FSMSTAT_VLD_MASK) >> QuadSPI_FSMSTAT_VLD_SHIFT;
1165 FsmStatState = (FsmStat & QuadSPI_FSMSTAT_STATE_MASK) >> QuadSPI_FSMSTAT_STATE_SHIFT;
1166 if ((FsmStatValid != 0U) && (FsmStatState == State))
1167 {
1168 Status = STATUS_QSPI_IP_SUCCESS;
1169 break;
1170 }
1171
1172 ElapsedTicks += OsIf_GetElapsed(&CurrentTicks, QSPI_IP_TIMEOUT_TYPE);
1173 } while (ElapsedTicks < TimeoutTicks);
1174
1175 if (ElapsedTicks >= TimeoutTicks)
1176 {
1177 Status = STATUS_QSPI_IP_TIMEOUT;
1178 }
1179
1180 return Status;
1181 }
1182
1183 #endif /* FEATURE_QSPI_HAS_SFP */
1184
1185 /*! @endcond */
1186
1187 /*******************************************************************************
1188 * Code
1189 ******************************************************************************/
1190
1191 /*FUNCTION**********************************************************************
1192 *
1193 * Function Name : Qspi_Ip_SetLut
1194 * Description : Configures a pair of LUT commands in the specified LUT register
1195 *
1196 *END**************************************************************************/
Qspi_Ip_SetLut(uint32 instance,uint8 LutRegister,Qspi_Ip_InstrOpType operation0,Qspi_Ip_InstrOpType operation1)1197 void Qspi_Ip_SetLut(uint32 instance,
1198 uint8 LutRegister,
1199 Qspi_Ip_InstrOpType operation0,
1200 Qspi_Ip_InstrOpType operation1
1201 )
1202 {
1203 QuadSPI_Type *baseAddr;
1204
1205 DEV_ASSERT_QSPI(instance < QuadSPI_INSTANCE_COUNT);
1206 DEV_ASSERT_QSPI(LutRegister < QuadSPI_LUT_COUNT);
1207 baseAddr = Qspi_Ip_BaseAddress[instance];
1208 baseAddr->LUT[LutRegister] = QSPI_IP_PACK_LUT_REG(operation0, operation1);
1209 }
1210
1211
1212 /*FUNCTION**********************************************************************
1213 *
1214 * Function Name : Qspi_Ip_WriteLuts_Privileged
1215 * Description : Configures pairs of LUT commands from the specified LUT register
1216 *
1217 *END**************************************************************************/
Qspi_Ip_WriteLuts_Privileged(uint32 Instance,uint8 StartLutRegister,const uint32 * Data,uint8 Size)1218 void Qspi_Ip_WriteLuts_Privileged(uint32 Instance,
1219 uint8 StartLutRegister,
1220 const uint32 *Data,
1221 uint8 Size
1222 )
1223 {
1224 DEV_ASSERT_QSPI(Instance < QuadSPI_INSTANCE_COUNT);
1225 DEV_ASSERT_QSPI(StartLutRegister < QuadSPI_LUT_COUNT);
1226 DEV_ASSERT_QSPI(Size <= FEATURE_QSPI_LUT_SEQUENCE_SIZE);
1227 DEV_ASSERT_QSPI((StartLutRegister + Size) <= QuadSPI_LUT_COUNT);
1228
1229 QuadSPI_Type *BaseAddr = Qspi_Ip_BaseAddress[Instance];
1230 uint8 Idx;
1231
1232 for (Idx = 0U; Idx < Size; Idx++)
1233 {
1234 BaseAddr->LUT[StartLutRegister + Idx] = Data[Idx];
1235 }
1236 }
1237
1238
1239 /*FUNCTION**********************************************************************
1240 *
1241 * Function Name : Qspi_Ip_SetAhbSeqId_Privileged
1242 * Description : Sets sequence ID for AHB operations
1243 *
1244 *END**************************************************************************/
Qspi_Ip_SetAhbSeqId_Privileged(uint32 instance,uint8 seqID)1245 void Qspi_Ip_SetAhbSeqId_Privileged(uint32 instance,
1246 uint8 seqID
1247 )
1248 {
1249 QuadSPI_Type *baseAddr;
1250
1251 DEV_ASSERT_QSPI(instance < QuadSPI_INSTANCE_COUNT);
1252 baseAddr = Qspi_Ip_BaseAddress[instance];
1253 baseAddr->BFGENCR = QuadSPI_BFGENCR_SEQID(seqID);
1254 }
1255
1256
1257 /*FUNCTION**********************************************************************
1258 *
1259 * Function Name : Qspi_Ip_SetSerialFlashAddr
1260 * Description : Configure the Serial Flash Memory Address
1261 *
1262 *END**************************************************************************/
Qspi_Ip_SetSerialFlashAddress(QuadSPI_Type * baseAddr,const Qspi_Ip_ControllerConfigType * userConfigPtr)1263 static inline void Qspi_Ip_SetSerialFlashAddress(QuadSPI_Type *baseAddr,
1264 const Qspi_Ip_ControllerConfigType * userConfigPtr
1265 )
1266 {
1267 Qspi_Ip_SetAddrOptions(baseAddr, userConfigPtr->columnAddr, userConfigPtr->wordAddresable);
1268
1269 Qspi_Ip_SetByteSwap(baseAddr, userConfigPtr->byteSwap);
1270 }
1271
1272
1273 /*FUNCTION**********************************************************************
1274 *
1275 * Function Name : Qspi_Ip_SetCsTime
1276 * Description : Configure the CS holdtime and CS setup time
1277 *
1278 *END**************************************************************************/
Qspi_Ip_SetCsTime(QuadSPI_Type * baseAddr,const Qspi_Ip_ControllerConfigType * userConfigPtr)1279 static inline void Qspi_Ip_SetCsTime(QuadSPI_Type *baseAddr,
1280 const Qspi_Ip_ControllerConfigType * userConfigPtr
1281 )
1282 {
1283 /* Configure the CS holdtime and CS setup time */
1284 Qspi_Ip_SetCsHoldTime(baseAddr, userConfigPtr->csHoldTime);
1285 Qspi_Ip_SetCsSetupTime(baseAddr, userConfigPtr->csSetupTime);
1286 }
1287
1288
1289 /*FUNCTION**********************************************************************
1290 *
1291 * Function Name : Qspi_Ip_ConfigureBuffers
1292 * Description : Configure the Tx, Rx and AHB buffers
1293 *
1294 *END**************************************************************************/
Qspi_Ip_ConfigureBuffers(uint32 instance,QuadSPI_Type * baseAddr,const Qspi_Ip_ControllerConfigType * userConfigPtr)1295 static inline void Qspi_Ip_ConfigureBuffers(uint32 instance,
1296 QuadSPI_Type *baseAddr,
1297 const Qspi_Ip_ControllerConfigType * userConfigPtr
1298 )
1299 {
1300 #ifdef QuadSPI_RBCT_RXBRD_MASK
1301 /* Read Rx buffer through RBDR registers */
1302 Qspi_Ip_SetRxBufReadout(baseAddr, QSPI_IP_RX_READOUT_IP);
1303 #endif
1304 /* Set watermarks */
1305 Qspi_Ip_SetTxWatermark(baseAddr, 1U);
1306 Qspi_Ip_SetRxWatermark(baseAddr, 1U);
1307 /* Configure AHB buffers settings */
1308 (void)Qspi_Ip_AhbSetup(instance, &(userConfigPtr->ahbConfig));
1309 }
1310
1311
1312 /*FUNCTION**********************************************************************
1313 *
1314 * Function Name : Qspi_Ip_ConfigureControllerA
1315 * Description : Configure for side A
1316 *
1317 *END**************************************************************************/
Qspi_Ip_ConfigureControllerA(uint32 instance,const Qspi_Ip_ControllerConfigType * userConfigPtr)1318 static inline void Qspi_Ip_ConfigureControllerA(uint32 instance,
1319 const Qspi_Ip_ControllerConfigType *userConfigPtr)
1320 {
1321 QuadSPI_Type *baseAddr = Qspi_Ip_BaseAddress[instance];
1322
1323 /* Configure external flash memory map Size A */
1324 Qspi_Ip_SetMemMapSizeA(instance, baseAddr, userConfigPtr->memSizeA1, userConfigPtr->memSizeA2);
1325
1326 /* Configure idle line value side A */
1327 Qspi_Ip_SetIdleLineValuesA(baseAddr, userConfigPtr->io2IdleValueA, userConfigPtr->io3IdleValueA);
1328
1329
1330 }
1331
1332
1333
1334
1335 /*FUNCTION**********************************************************************
1336 *
1337 * Function Name : Qspi_Ip_ConfigureController
1338 * Description : Configure the controller register following user configurations
1339 *
1340 *END**************************************************************************/
Qspi_Ip_ConfigureController(uint32 instance,const Qspi_Ip_ControllerConfigType * userConfigPtr)1341 static inline void Qspi_Ip_ConfigureController(uint32 instance,
1342 const Qspi_Ip_ControllerConfigType * userConfigPtr
1343 )
1344 {
1345 QuadSPI_Type *baseAddr = Qspi_Ip_BaseAddress[instance];
1346
1347 Qspi_Ip_ConfigureControllerA(instance, userConfigPtr);
1348
1349
1350 /* Configure the Serial Flash Memory Address */
1351 Qspi_Ip_SetSerialFlashAddress(baseAddr, userConfigPtr);
1352
1353 Qspi_Ip_SetRxCfg(baseAddr, userConfigPtr->sampleDelay, userConfigPtr->samplePhase);
1354
1355 /* Configure the CS holdtime and CS setup time */
1356 Qspi_Ip_SetCsTime(baseAddr, userConfigPtr);
1357
1358 /* Configure buffers */
1359 Qspi_Ip_ConfigureBuffers(instance, baseAddr, userConfigPtr);
1360
1361 /* Configure read options */
1362 Qspi_Ip_ConfigureReadOptions(baseAddr, userConfigPtr);
1363
1364 /* Configure chip-specific options */
1365 Qspi_Ip_ConfigureChipOptions(baseAddr, userConfigPtr);
1366
1367 #if (FEATURE_QSPI_HAS_SFP == 1)
1368 Qspi_Ip_Sfp_Configure(baseAddr, userConfigPtr);
1369 #endif
1370 }
1371
1372
1373 /*FUNCTION**********************************************************************
1374 *
1375 * Function Name : Qspi_Ip_ControllerInit
1376 * Description : Initializes the qspi controller
1377 * @implements Qspi_Ip_ControllerInit_Activity */
Qspi_Ip_ControllerInit(uint32 instance,const Qspi_Ip_ControllerConfigType * userConfigPtr)1378 Qspi_Ip_StatusType Qspi_Ip_ControllerInit(uint32 instance,
1379 const Qspi_Ip_ControllerConfigType * userConfigPtr
1380 )
1381 {
1382 QuadSPI_Type *baseAddr;
1383 Qspi_Ip_StatusType status = STATUS_QSPI_IP_SUCCESS;
1384
1385 DEV_ASSERT_QSPI(instance < QuadSPI_INSTANCE_COUNT);
1386 DEV_ASSERT_QSPI(userConfigPtr != NULL_PTR);
1387 /* Initialize driver status structure */
1388
1389 baseAddr = Qspi_Ip_BaseAddress[instance];
1390
1391 /* Ensure module is disabled */
1392 Qspi_Ip_Disable(baseAddr);
1393
1394 /* Ensure all registers contain their reset value */
1395 Qspi_Ip_ResetAllRegisters(baseAddr);
1396
1397 /* Configure the controller following the user configurations */
1398 Qspi_Ip_ConfigureController(instance, userConfigPtr);
1399
1400 /* Enable QuadSPI module */
1401 Qspi_Ip_Enable(baseAddr);
1402
1403 /* Reset serial flash and AHB domains */
1404 Qspi_Ip_SwReset(baseAddr);
1405
1406 /* Store user configuration for runtime usage */
1407 Qspi_Ip_ControllerConfig[instance] = userConfigPtr;
1408 /* Configure the DLL */
1409 status = Qspi_Ip_ConfigureDLL(instance, userConfigPtr);
1410
1411 /* Workaround to clear CRC and ECC errors flags */
1412 baseAddr->FR = (uint32)0xFFFFFFFFUL;
1413
1414 return status;
1415 }
1416
1417
1418 /*FUNCTION**********************************************************************
1419 *
1420 * Function Name : Qspi_Ip_ControllerDeinit
1421 * Description : De-initialize the qspi driver
1422 * @implements Qspi_Ip_ControllerDeinit_Activity */
Qspi_Ip_ControllerDeinit(uint32 instance)1423 Qspi_Ip_StatusType Qspi_Ip_ControllerDeinit(uint32 instance)
1424 {
1425 QuadSPI_Type *baseAddr;
1426
1427 DEV_ASSERT_QSPI(instance < QuadSPI_INSTANCE_COUNT);
1428 baseAddr = Qspi_Ip_BaseAddress[instance];
1429
1430 /* Disable QuadSPI module */
1431 Qspi_Ip_Disable(baseAddr);
1432
1433 /* Detach the configuration pointer */
1434 Qspi_Ip_ControllerConfig[instance] = NULL_PTR;
1435
1436 return STATUS_QSPI_IP_SUCCESS;
1437 }
1438
1439 /*FUNCTION**********************************************************************
1440 *
1441 * Function Name : Qspi_Ip_Abort
1442 * Description : Force the Qspi controller to cancel any on-going transactions by performing the software reset requence.
1443 * This can be used to recover the hardware controller from being stuck in BUSY state.
1444 * Re-configure DLL is needed to avoid side-effects on the DLL after the S/W reset.
1445 */
Qspi_Ip_Abort(uint32 instance)1446 Qspi_Ip_StatusType Qspi_Ip_Abort(uint32 instance)
1447 {
1448 DEV_ASSERT_QSPI(instance < QuadSPI_INSTANCE_COUNT);
1449
1450 QuadSPI_Type *baseAddr = Qspi_Ip_BaseAddress[instance];
1451 Qspi_Ip_StatusType status = STATUS_QSPI_IP_SUCCESS;
1452
1453 /* Reset serial flash and AHB domains */
1454 Qspi_Ip_SwReset(baseAddr);
1455
1456 /* S/W reset would also loose any Slave-chain upate, therefore re-configure DLL sequence is needed */
1457 if (Qspi_Ip_ControllerConfig[instance] != NULL_PTR)
1458 {
1459 /* Perform the DLL config only if the user configuration is available.
1460 Because there will be the case when user skip the controller configuration at initialization time.
1461 */
1462 status = Qspi_Ip_ConfigureDLL(instance, Qspi_Ip_ControllerConfig[instance]);
1463 }
1464
1465 return status;
1466 }
1467
1468
1469 /*FUNCTION**********************************************************************
1470 *
1471 * Function Name : Qspi_Ip_GetBaseAdress
1472 * Description : Returns the physical base address of a flash device on the AHB bus.
1473 * The controller must be initialized prior to calling this function.
1474 * @implements Qspi_Ip_GetBaseAdress_Activity */
Qspi_Ip_GetBaseAdress(uint32 instance,Qspi_Ip_ConnectionType connectionType)1475 uint32 Qspi_Ip_GetBaseAdress(uint32 instance,
1476 Qspi_Ip_ConnectionType connectionType
1477 )
1478 {
1479 const QuadSPI_Type *baseAddr;
1480 uint32 address = 0U;
1481
1482 DEV_ASSERT_QSPI(instance < QuadSPI_INSTANCE_COUNT);
1483 /* get the base address base on the instance */
1484 baseAddr = Qspi_Ip_BaseAddress[instance];
1485
1486 switch (connectionType)
1487 {
1488 case QSPI_IP_SIDE_A1:
1489 /* get base address of side A1 */
1490 address = Qspi_Ip_AhbAddress[instance];
1491 break;
1492 case QSPI_IP_SIDE_A2:
1493 /* get base address of side A2 */
1494 address = baseAddr->SFA1AD;
1495 break;
1496 default:
1497 ; /* Not possible */
1498 break;
1499 }
1500
1501 return address;
1502 }
1503
1504 /*FUNCTION**********************************************************************
1505 *
1506 * Function Name : Qspi_Ip_IpCommand
1507 * Description : Launches a simple IP command
1508 * @implements Qspi_Ip_IpCommand_Activity */
Qspi_Ip_IpCommand(uint32 instance,uint8 SeqId,uint32 addr)1509 Qspi_Ip_StatusType Qspi_Ip_IpCommand(uint32 instance,
1510 uint8 SeqId,
1511 uint32 addr
1512 )
1513 {
1514 QuadSPI_Type *baseAddr;
1515 Qspi_Ip_StatusType status;
1516
1517 DEV_ASSERT_QSPI(instance < QuadSPI_INSTANCE_COUNT);
1518 DEV_ASSERT_QSPI(SeqId < (QuadSPI_LUT_COUNT / FEATURE_QSPI_LUT_SEQUENCE_SIZE));
1519 baseAddr = Qspi_Ip_BaseAddress[instance];
1520
1521 /* Reset AHB buffers to force re-read from memory after erase operation */
1522 Qspi_Ip_AhbFlush(baseAddr);
1523
1524 /* Launch the IP command */
1525 Qspi_Ip_NewIpsTransaction(baseAddr, addr, 0U, SeqId);
1526
1527 /* Add Fault Injection point for FR_ILLINE flag */
1528 MCAL_FAULT_INJECTION_POINT(FLS_FIP_FR_ERROR_IPCOMMAND);
1529
1530 status = Qspi_Ip_CmdWaitComplete(instance);
1531
1532 /* Make sure there is no garbage in Rx fifo in case of triggering a dummy READ instruction.
1533 This clears RBSR[RDBFL] to ensure QuadSPI is idle from SFP point of view and avoid the Master timeout error.
1534 */
1535 Qspi_Ip_ClearRxBuf(baseAddr);
1536
1537 return status;
1538 }
1539
1540 /*FUNCTION**********************************************************************
1541 *
1542 * Function Name : Qspi_Ip_CmdWaitComplete
1543 * Description : Wait until Qspi controller is not busy or timeout
1544 */
Qspi_Ip_CmdWaitComplete(uint32 instance)1545 static Qspi_Ip_StatusType Qspi_Ip_CmdWaitComplete(uint32 instance)
1546 {
1547 Qspi_Ip_StatusType status = STATUS_QSPI_IP_SUCCESS;
1548 uint32 u32ElapsedTicks = 0UL;
1549 uint32 u32TimeoutTicks;
1550 uint32 u32CurrentTicks;
1551
1552 /* Prepare timeout counter */
1553 u32TimeoutTicks = OsIf_MicrosToTicks(QSPI_IP_CMD_COMPLETE_TIMEOUT, (OsIf_CounterType)QSPI_IP_TIMEOUT_TYPE);
1554 u32CurrentTicks = OsIf_GetCounter((OsIf_CounterType)QSPI_IP_TIMEOUT_TYPE);
1555
1556 MCAL_FAULT_INJECTION_POINT(QSPI_IP_FMEA_WAIT_TRANSACTION_COMPLETE);
1557
1558 /* Wait for command to be completed */
1559 do
1560 {
1561 u32ElapsedTicks += OsIf_GetElapsed(&u32CurrentTicks, (OsIf_CounterType)QSPI_IP_TIMEOUT_TYPE);
1562 status = Qspi_Ip_ControllerGetStatus(instance);
1563 }
1564 while ((u32ElapsedTicks < u32TimeoutTicks) && (STATUS_QSPI_IP_BUSY == status));
1565
1566 if (STATUS_QSPI_IP_BUSY == status)
1567 {
1568 status = STATUS_QSPI_IP_TIMEOUT;
1569 }
1570
1571 return status;
1572 }
1573
1574 /*FUNCTION**********************************************************************
1575 *
1576 * Function Name : Qspi_Ip_IpRead
1577 * Description : Launches an IP read command
1578 * @implements Qspi_Ip_IpRead_Activity */
Qspi_Ip_IpRead(uint32 instance,uint8 SeqId,uint32 addr,uint8 * dataRead,const uint8 * dataCmp,uint32 size)1579 Qspi_Ip_StatusType Qspi_Ip_IpRead(uint32 instance,
1580 uint8 SeqId,
1581 uint32 addr,
1582 uint8 * dataRead,
1583 const uint8 * dataCmp,
1584 uint32 size
1585 )
1586 {
1587 Qspi_Ip_StatusType status = STATUS_QSPI_IP_ERROR;
1588 QuadSPI_Type *baseAddr;
1589 uint32 padding;
1590 uint16 Idatsz = 0U;
1591
1592 DEV_ASSERT_QSPI(instance < QuadSPI_INSTANCE_COUNT);
1593 DEV_ASSERT_QSPI(SeqId < (QuadSPI_LUT_COUNT / FEATURE_QSPI_LUT_SEQUENCE_SIZE));
1594 DEV_ASSERT_QSPI(size <= FEATURE_QSPI_RX_BUF_SIZE);
1595
1596 baseAddr = Qspi_Ip_BaseAddress[instance];
1597 padding = (uint32)(Qspi_Ip_MemoryPadding[instance]);
1598
1599 /* If size is odd, round up to even size; this is needed in octal DDR mode */
1600 Idatsz = (uint16)((size + 1U) & (~1U));
1601
1602 /* Make sure there is no garbage in Rx fifo */
1603 Qspi_Ip_ClearRxBuf(baseAddr);
1604
1605 Qspi_Ip_NewIpsTransaction(baseAddr, addr, Idatsz, SeqId);
1606
1607 /* Add Fault Injection point for FR_ILLINE flag */
1608 MCAL_FAULT_INJECTION_POINT(FLS_FIP_FR_ERROR_IPREAD);
1609
1610 /* Wait until the command is sent */
1611 status = Qspi_Ip_CmdWaitComplete(instance);
1612
1613 if (STATUS_QSPI_IP_SUCCESS == status)
1614 {
1615 /* Process received data */
1616 if (dataRead != NULL_PTR)
1617 {
1618 /* Normal read */
1619 status = Qspi_Ip_ProcessDataRead(dataRead, size, baseAddr, padding);
1620 }
1621 else if (dataCmp != NULL_PTR)
1622 {
1623 /* Verify */
1624 status = Qspi_Ip_ProcessDataVerify(dataCmp, size, baseAddr, padding);
1625 }
1626 else
1627 {
1628 /* Blank check */
1629 status = Qspi_Ip_ProcessDataBlankCheck(size, baseAddr, padding);
1630 }
1631 }
1632
1633 /* Reset Rx fifo */
1634 Qspi_Ip_ClearRxBuf(baseAddr);
1635
1636 /* Clear padding, only needed for the first read */
1637 Qspi_Ip_MemoryPadding[instance] = 0U;
1638
1639 return status;
1640 }
1641
1642 /*FUNCTION**********************************************************************
1643 *
1644 * Function Name : Qspi_Ip_InvalidateTxBuf
1645 * Description : Invalidates the TX buffer content and wait until it is completed or timed out
1646 * @implements Qspi_Ip_InvalidateTxBuf_Activity */
Qspi_Ip_InvalidateTxBuf(uint32 instance)1647 static inline void Qspi_Ip_InvalidateTxBuf(uint32 instance)
1648 {
1649 QuadSPI_Type *baseAddr = Qspi_Ip_BaseAddress[instance];
1650 volatile uint32 u32CurrentTicks;
1651
1652 /* Start TX FIFO reset */
1653 Qspi_Ip_ClearTxBuf(baseAddr);
1654
1655 /* Prepare timeout counter */
1656 u32CurrentTicks = QSPI_IP_TX_BUFFER_RESET_DELAY;
1657 /* Insert delay to ensure TX FIFO reset is complete */
1658 while (u32CurrentTicks > 0U)
1659 {
1660 u32CurrentTicks--;
1661 }
1662 }
1663
1664
1665 /*FUNCTION**********************************************************************
1666 *
1667 * Function Name : Qspi_Ip_PadTxBuf
1668 * Description : Pad Tx buffer up to a minimum number of entries required
1669 * by the device for transmission to start
1670 *
1671 *END**************************************************************************/
1672 #if (FEATURE_QSPI_TX_MIN_BUF_FILL > 1)
Qspi_Ip_PadTxBuf(QuadSPI_Type * baseAddr)1673 static void Qspi_Ip_PadTxBuf(QuadSPI_Type *baseAddr)
1674 {
1675 uint32 bufFill = Qspi_Ip_GetTxBufFill(baseAddr);
1676 /* Pad buffer will blank data */
1677 while ((bufFill < FEATURE_QSPI_TX_MIN_BUF_FILL) || ((bufFill & 3U) != 0U))
1678 {
1679 Qspi_Ip_WriteTxData(baseAddr, 0xFFFFFFFFU);
1680 bufFill++;
1681 }
1682 }
1683 #else
Qspi_Ip_PadTxBuf(const QuadSPI_Type * baseAddr)1684 static void Qspi_Ip_PadTxBuf(const QuadSPI_Type *baseAddr)
1685 {
1686 /* Remove unused variable */
1687 (void)baseAddr;
1688 }
1689 #endif
1690
1691
1692 /*FUNCTION**********************************************************************
1693 *
1694 * Function Name : Qspi_Ip_IpWrite
1695 * Description : Launches an IP write command
1696 * @implements Qspi_Ip_IpWrite_Activity */
Qspi_Ip_IpWrite(uint32 instance,uint8 SeqId,uint32 addr,const uint8 * data,uint32 size)1697 Qspi_Ip_StatusType Qspi_Ip_IpWrite(uint32 instance,
1698 uint8 SeqId,
1699 uint32 addr,
1700 const uint8 * data,
1701 uint32 size
1702 )
1703 {
1704 QuadSPI_Type *baseAddr;
1705 Qspi_Ip_StatusType status = STATUS_QSPI_IP_ERROR;
1706 uint32 padding;
1707 uint16 TotalSize = 0U;
1708
1709 baseAddr = Qspi_Ip_BaseAddress[instance];
1710 DEV_ASSERT_QSPI(instance < QuadSPI_INSTANCE_COUNT);
1711 DEV_ASSERT_QSPI(size <= (uint16)FEATURE_QSPI_TX_BUF_SIZE);
1712 DEV_ASSERT_QSPI(SeqId < (QuadSPI_LUT_COUNT / FEATURE_QSPI_LUT_SEQUENCE_SIZE));
1713 DEV_ASSERT_QSPI(data != NULL_PTR);
1714
1715 /* Reset AHB buffers to force re-read from memory after write operation */
1716 Qspi_Ip_AhbFlush(baseAddr);
1717
1718 /* Ensure there is no garbage in Tx FIFO */
1719 Qspi_Ip_InvalidateTxBuf(instance);
1720
1721 padding = Qspi_Ip_MemoryPadding[instance];
1722 TotalSize = (uint16)(size + (padding >> 4U) + (padding & 0x0FU));
1723 Qspi_Ip_MemoryPadding[instance] = 0U; /* Clear padding */
1724
1725 #if (FEATURE_QSPI_HAS_SFP == 1)
1726
1727 /* Setup water mark according to the transfer size to avoid underrun issue. */
1728 Qspi_Ip_SetTxWatermark( baseAddr, (uint8)( (FEATURE_QSPI_TX_BUF_SIZE / 4U) - ((TotalSize / 4U) - 1U) ) );
1729
1730 Qspi_Ip_NewIpsTransaction(baseAddr, addr, TotalSize, SeqId);
1731
1732 /* 01 - TBDR lock is open. QuadSPI considers IPS transfer. Master counter is started. */
1733 if (STATUS_QSPI_IP_SUCCESS == Qspi_Ip_Sfp_WaitFsmState(baseAddr, 1U))
1734 {
1735 /* Fill Tx buffer */
1736 Qspi_Ip_FillTxBuf(baseAddr, data, size, padding);
1737
1738 /* Pad Tx buffer up to the minimum number of entries required by the device */
1739 Qspi_Ip_PadTxBuf(baseAddr);
1740
1741 MCAL_DATA_SYNC_BARRIER();
1742 MCAL_INSTRUCTION_SYNC_BARRIER();
1743 /* 10 - TX buffer filled above threshold. Write transfer is triggered. SEQID is written. */
1744 if (((baseAddr->FSMSTAT & QuadSPI_FSMSTAT_STATE_MASK) >> QuadSPI_FSMSTAT_STATE_SHIFT) == 2U)
1745 {
1746 /* Add Fault Injection point for FR_TBUF flag */
1747 MCAL_FAULT_INJECTION_POINT(FLS_FIP_FR_ERROR_IPWRITE);
1748
1749 /* Wait until the command is sent */
1750 status = Qspi_Ip_CmdWaitComplete(instance);
1751 }
1752 }
1753
1754 #else /* FEATURE_QSPI_HAS_SFP */
1755
1756 /* Set write address */
1757 Qspi_Ip_SetIpAddr(baseAddr, addr);
1758
1759 /* Fill Tx buffer */
1760 Qspi_Ip_FillTxBuf(baseAddr, data, size, padding);
1761
1762 /* Pad Tx buffer up to the minimum number of entries required by the device */
1763 Qspi_Ip_PadTxBuf(baseAddr);
1764
1765 /* Trigger IP command with specified sequence and size */
1766 Qspi_Ip_IpTrigger(baseAddr, SeqId, TotalSize);
1767
1768 /* Add Fault Injection point for FR_TBUF flag */
1769 MCAL_FAULT_INJECTION_POINT(FLS_FIP_FR_ERROR_IPWRITE);
1770
1771 /* Wait until the command is sent */
1772 status = Qspi_Ip_CmdWaitComplete(instance);
1773
1774 #endif /* FEATURE_QSPI_HAS_SFP */
1775
1776 return status;
1777 }
1778
1779
1780 /*FUNCTION**********************************************************************
1781 *
1782 * Function Name : Qspi_Ip_ControllerGetStatus
1783 * Description : Checks the status of the currently running IP command
1784 * @implements Qspi_Ip_ControllerGetStatus_Activity */
Qspi_Ip_ControllerGetStatus(uint32 instance)1785 Qspi_Ip_StatusType Qspi_Ip_ControllerGetStatus(uint32 instance)
1786 {
1787 QuadSPI_Type *baseAddr;
1788 Qspi_Ip_StatusType status;
1789
1790 DEV_ASSERT_QSPI((instance < QuadSPI_INSTANCE_COUNT));
1791 baseAddr = Qspi_Ip_BaseAddress[instance];
1792
1793 MCAL_FAULT_INJECTION_POINT(QSPI_IP_FMEA_CONTROLLER_GET_STATUS);
1794 /* Check device for busy status */
1795 if (Qspi_Ip_GetBusyStatus(baseAddr))
1796 {
1797 status = STATUS_QSPI_IP_BUSY;
1798 }
1799 else
1800 {
1801 /* Check for errors reported by the QuadSPI */
1802 status = Qspi_Ip_ErrorCheck(baseAddr);
1803 }
1804 return status;
1805 }
1806
1807 #if (FEATURE_QSPI_HAS_SFP == 1)
1808 #if (QSPI_IP_SFP_ENABLE_GLOBAL == STD_ON)
1809
1810 #if (QSPI_IP_SFP_ENABLE_MDAD == STD_ON)
1811 /**
1812 * Configure the MDAD registers.
1813 */
Qspi_Ip_Sfp_Configure_Mdad(QuadSPI_Type * baseAddr,Qspi_Ip_ControllerConfigType const * userConfigPtr)1814 static void Qspi_Ip_Sfp_Configure_Mdad(QuadSPI_Type *baseAddr,
1815 Qspi_Ip_ControllerConfigType const *userConfigPtr)
1816 {
1817 for (uint8 Index = 0U; Index < QuadSPI_MDAD_COUNT; ++Index)
1818 {
1819 if (TRUE == userConfigPtr->SfpCfg.Tg[Index].Valid)
1820 {
1821 Qspi_Ip_Sfp_SetTgSecureAttribute(baseAddr, Index, userConfigPtr->SfpCfg.Tg[Index].SecureAttribute);
1822 Qspi_Ip_Sfp_SetTgMaskType(baseAddr, Index, userConfigPtr->SfpCfg.Tg[Index].MaskType);
1823 Qspi_Ip_Sfp_SetTgMask(baseAddr, Index, userConfigPtr->SfpCfg.Tg[Index].Mask);
1824 Qspi_Ip_Sfp_SetTgDomainIdMatch(baseAddr, Index, userConfigPtr->SfpCfg.Tg[Index].DomainId);
1825 Qspi_Ip_Sfp_SetTgValid(baseAddr, Index, userConfigPtr->SfpCfg.Tg[Index].Valid);
1826 }
1827 }
1828 }
1829 #endif /* QSPI_IP_SFP_ENABLE_MDAD */
1830
1831
1832 #if (QSPI_IP_SFP_ENABLE_FRAD == STD_ON)
1833 /**
1834 * Configure the FRAD registers.
1835 */
Qspi_Ip_Sfp_Configure_Frad(QuadSPI_Type * baseAddr,Qspi_Ip_ControllerConfigType const * userConfigPtr)1836 static void Qspi_Ip_Sfp_Configure_Frad(QuadSPI_Type *baseAddr,
1837 Qspi_Ip_ControllerConfigType const *userConfigPtr)
1838 {
1839 for (uint8 Index = 0U; Index < QuadSPI_FRAD_COUNT; ++Index)
1840 {
1841 if (TRUE == userConfigPtr->SfpCfg.Frad[Index].Valid)
1842 {
1843 Qspi_Ip_Sfp_SetFradStartAddress(baseAddr, Index, userConfigPtr->SfpCfg.Frad[Index].StartAddress);
1844 Qspi_Ip_Sfp_SetFradEndAddress(baseAddr, Index, userConfigPtr->SfpCfg.Frad[Index].EndAddress);
1845 Qspi_Ip_Sfp_SetFradMd0Acp(baseAddr, Index, (uint8)userConfigPtr->SfpCfg.Frad[Index].Md0Acp);
1846 Qspi_Ip_Sfp_SetFradMd1Acp(baseAddr, Index, (uint8)userConfigPtr->SfpCfg.Frad[Index].Md1Acp);
1847 Qspi_Ip_Sfp_SetFradEaLock(baseAddr, Index, userConfigPtr->SfpCfg.Frad[Index].ExclusiveAccessLock);
1848 Qspi_Ip_Sfp_SetFradEaOwner(baseAddr, Index, userConfigPtr->SfpCfg.Frad[Index].ExclusiveAccessOwner);
1849 Qspi_Ip_Sfp_SetFradValid(baseAddr, Index, userConfigPtr->SfpCfg.Frad[Index].Valid);
1850 }
1851 }
1852 }
1853 #endif /* QSPI_IP_SFP_ENABLE_FRAD */
1854
1855 #endif /* QSPI_IP_SFP_ENABLE_GLOBAL */
1856
1857 /** * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
1858 * @brief Configure the SFP registers.
1859 *
1860 * @param[in] BaseAddr base address of the given QuadSPI instance
1861 * @param[in] userConfigPtr QSPI controller configuration structure
1862 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
Qspi_Ip_Sfp_Configure_Privileged(QuadSPI_Type * baseAddr,Qspi_Ip_ControllerConfigType const * userConfigPtr)1863 void Qspi_Ip_Sfp_Configure_Privileged(QuadSPI_Type * baseAddr,
1864 Qspi_Ip_ControllerConfigType const * userConfigPtr)
1865 {
1866 /* Workaround for K396: QSPI must be enabled in order to write into SFP registers */
1867 /* Enable QuadSPI module */
1868 Qspi_Ip_Enable(baseAddr);
1869
1870 Qspi_Ip_Sfp_SetAccessControls(baseAddr, QSPI_IP_SFP_ALL, QSPI_IP_SFP_ENABLE_GLOBAL);
1871 Qspi_Ip_Sfp_SetAccessControls(baseAddr, QSPI_IP_SFP_MDAD, QSPI_IP_SFP_ENABLE_MDAD);
1872 Qspi_Ip_Sfp_SetAccessControls(baseAddr, QSPI_IP_SFP_FRAD, QSPI_IP_SFP_ENABLE_FRAD);
1873
1874 #if (QSPI_IP_SFP_ENABLE_GLOBAL == STD_ON)
1875
1876 #if (QSPI_IP_SFP_ENABLE_MDAD == STD_ON)
1877 Qspi_Ip_Sfp_Configure_Mdad(baseAddr, userConfigPtr);
1878 #endif
1879
1880 #if (QSPI_IP_SFP_ENABLE_FRAD == STD_ON)
1881 Qspi_Ip_Sfp_Configure_Frad(baseAddr, userConfigPtr);
1882 #endif
1883
1884 Qspi_Ip_Sfp_SetMasterTimeout(baseAddr, userConfigPtr->SfpCfg.MasterTimeout);
1885
1886 #else
1887 (void)userConfigPtr;
1888 #endif /* QSPI_IP_SFP_ENABLE_GLOBAL */
1889
1890 }
1891
1892 /**
1893 * Reset the registers the require privilege access for programming.
1894 */
Qspi_Ip_ResetPrivilegedRegisters_Privileged(QuadSPI_Type * BaseAddr)1895 void Qspi_Ip_ResetPrivilegedRegisters_Privileged(QuadSPI_Type *BaseAddr)
1896 {
1897 uint8 cnt;
1898
1899 /* reset BFGENCR register */
1900 BaseAddr->BFGENCR = (uint32)0x00000000UL;
1901
1902 /* reset LUT0 register */
1903 BaseAddr->LUT[0] = (uint32)0x08180403UL;
1904 /* reset LUT1 register */
1905 BaseAddr->LUT[1] = (uint32)0x24001C08UL;
1906 for (cnt = 2U; cnt < QuadSPI_LUT_COUNT; cnt++)
1907 {
1908 BaseAddr->LUT[cnt] = (uint32)0x00000000UL;
1909 }
1910
1911 /* reset Secure Flash Protection registers */
1912 for (cnt = 0U; cnt < QuadSPI_FRAD_COUNT; ++cnt)
1913 {
1914 BaseAddr->FRAD[cnt].WORD0 = 0x00000000UL;
1915 BaseAddr->FRAD[cnt].WORD1 = 0x0000FFFFUL;
1916 BaseAddr->FRAD[cnt].WORD2 = 0x00000000UL;
1917 BaseAddr->FRAD[cnt].WORD3 = 0x00000000UL;
1918 }
1919 for (cnt = 0U; cnt < QuadSPI_MDAD_COUNT; ++cnt)
1920 {
1921 BaseAddr->MDAD[cnt].TGMDAD = 0x00000000UL;
1922 BaseAddr->MDAD[cnt].TGSFARS = 0x00000000UL;
1923 BaseAddr->MDAD[cnt].TGIPCRS = 0x00000000UL;
1924 }
1925 BaseAddr->MGC = 0xA8000000UL;
1926 BaseAddr->MRC = 0x00500E07UL;
1927 BaseAddr->MTO = 0xFFFFFFFFUL;
1928 BaseAddr->FLSEQREQ = 0x20000000UL;
1929 BaseAddr->IPSERROR = 0x20000000UL;
1930 BaseAddr->ERRSTAT = 0x000001FFUL;
1931 BaseAddr->INT_EN = 0x00000000UL;
1932 }
1933
1934 #endif /* FEATURE_QSPI_HAS_SFP */
1935
1936 /*
1937 * Set all hardware registers to their reset value
1938 */
Qspi_Ip_ResetAllRegisters(QuadSPI_Type * BaseAddr)1939 inline static void Qspi_Ip_ResetAllRegisters(QuadSPI_Type *BaseAddr)
1940 {
1941 uint8 cnt = 0U;
1942
1943 #if (FEATURE_QSPI_HAS_SFP == 1) /* platforms support SFP */
1944
1945 /* reset MCR register */
1946 BaseAddr->MCR = (uint32)0x000F404CUL;
1947 /* reset FLSHCR register */
1948 BaseAddr->FLSHCR = (uint32)0x00000303UL;
1949 /* reset BUF0CR register */
1950 BaseAddr->BUF0CR = (uint32)0x00000003UL;
1951 /* reset BUF1CR register */
1952 BaseAddr->BUF1CR = (uint32)0x00000002UL;
1953 /* reset BUF2CR register */
1954 BaseAddr->BUF2CR = (uint32)0x00000001UL;
1955 /* reset BUF3CR register */
1956 BaseAddr->BUF3CR = (uint32)0x80000000UL;
1957 /* reset SOCCR register */
1958 BaseAddr->SOCCR = (uint32)0x00000000UL;
1959 /* reset BUF0IND register */
1960 BaseAddr->BUF0IND = (uint32)0x00000000UL;
1961 /* reset BUF1IND register */
1962 BaseAddr->BUF1IND = (uint32)0x00000000UL;
1963 /* reset BUF2IND register */
1964 BaseAddr->BUF2IND = (uint32)0x00000000UL;
1965 #ifdef QuadSPI_AWRCR_AWTRGLVL_MASK
1966 /* reset AWRCR register */
1967 BaseAddr->AWRCR = (uint32)0x00000000UL;
1968 #endif
1969 /* reset DLLCRA register */
1970 BaseAddr->DLLCRA = (uint32)0x01200000UL;
1971 #ifdef QuadSPI_PARITYCR_CRCBIN_FA_MASK
1972 /* reset PARITYCR register */
1973 BaseAddr->PARITYCR = (uint32)0x00000000UL;
1974 #endif
1975 /* reset SFACR register */
1976 BaseAddr->SFACR = (uint32)0x00000800UL;
1977 /* reset SMPR register */
1978 BaseAddr->SMPR = (uint32)0x00000000UL;
1979 /* reset RBCT register */
1980 BaseAddr->RBCT = (uint32)0x00000000UL;
1981 #ifdef QuadSPI_DLCR_DLP_SEL_FA_MASK
1982 /* reset DLCR register */
1983 BaseAddr->DLCR = (uint32)0x40FF40FFUL;
1984 #endif
1985 /* reset FR register, Write 1 to clear */
1986 BaseAddr->FR = (uint32)0x9D83F541UL;
1987 /* reset RSER register */
1988 BaseAddr->RSER = (uint32)0x00000000UL;
1989 /* reset SPTRCLR register: clear both IP and AHB sequence pointers */
1990 BaseAddr->SPTRCLR = (uint32)0x01000000UL | (uint32)QuadSPI_SPTRCLR_BFPTRC_MASK | (uint32)QuadSPI_SPTRCLR_IPPTRC_MASK;
1991 /* reset SFA1AD register */
1992 BaseAddr->SFA1AD = (uint32)0x70000000UL;
1993 /* reset SFA2AD register */
1994 BaseAddr->SFA2AD = (uint32)0x70000000UL;
1995 #ifdef QuadSPI_DLPR_DLPV_MASK
1996 /* reset DLPR register */
1997 BaseAddr->DLPR = (uint32)0xAA553443UL;
1998 #endif
1999 /* reset LUTKEY register */
2000 BaseAddr->LUTKEY = (uint32)0x5AF05AF0UL;
2001 /* reset LCKCR register */
2002 BaseAddr->LCKCR = (uint32)0x00000002UL;
2003
2004 Qspi_Ip_ResetPrivilegedRegisters(BaseAddr);
2005
2006 #else /* platforms do not support SFP */
2007
2008 /* reset MCR register */
2009 BaseAddr->MCR = (uint32)0x000F404CUL;
2010 /* reset IPCR register */
2011 BaseAddr->IPCR = (uint32)0x00000000UL;
2012 /* reset FLSHCR register */
2013 BaseAddr->FLSHCR = (uint32)0x00000303UL;
2014 /* reset BUF0CR register */
2015 BaseAddr->BUF0CR = (uint32)0x00000003UL;
2016 /* reset BUF1CR register */
2017 BaseAddr->BUF1CR = (uint32)0x00000002UL;
2018 /* reset BUF2CR register */
2019 BaseAddr->BUF2CR = (uint32)0x00000001UL;
2020 /* reset BUF3CR register */
2021 BaseAddr->BUF3CR = (uint32)0x80000000UL;
2022 /* reset BFGENCR register */
2023 BaseAddr->BFGENCR = (uint32)0x00000000UL;
2024 /* reset SOCCR register */
2025 BaseAddr->SOCCR = (uint32)0x00000000UL;
2026 /* reset BUF0IND register */
2027 BaseAddr->BUF0IND = (uint32)0x00000000UL;
2028 /* reset BUF1IND register */
2029 BaseAddr->BUF1IND = (uint32)0x00000000UL;
2030 /* reset BUF2IND register */
2031 BaseAddr->BUF2IND = (uint32)0x00000000UL;
2032 /* reset DLLCRA register */
2033 BaseAddr->DLLCRA = (uint32)0x01200000UL;
2034 /* reset SFAR register */
2035 BaseAddr->SFAR = (uint32)0x00000000UL;
2036 /* reset SMPR register */
2037 BaseAddr->SMPR = (uint32)0xFF000000UL;
2038 /* reset RBCT register */
2039 BaseAddr->RBCT = (uint32)0x00000000UL;
2040 /* reset TBDR register */
2041 BaseAddr->TBDR = (uint32)0x00000000UL;
2042 /* reset TBCT register */
2043 BaseAddr->TBCT = (uint32)0x00000000UL;
2044 /* reset FR register - Write 1 to clear */
2045 BaseAddr->FR = (uint32)0x0C8378C1UL;
2046 /* reset RSER register */
2047 BaseAddr->RSER = (uint32)0x00000000UL;
2048 /* reset SPTRCLR register: clear both IP and AHB sequence pointers */
2049 BaseAddr->SPTRCLR = (uint32)QuadSPI_SPTRCLR_BFPTRC_MASK | (uint32)QuadSPI_SPTRCLR_IPPTRC_MASK;
2050 /* reset SFA1AD register */
2051 BaseAddr->SFA1AD = (uint32)0x70000000UL;
2052 /* reset SFA2AD register */
2053 BaseAddr->SFA2AD = (uint32)0x70000000UL;
2054 /* reset LUTKEY register */
2055 BaseAddr->LUTKEY = (uint32)0x5AF05AF0UL;
2056 /* reset LCKCR register */
2057 BaseAddr->LCKCR = (uint32)0x00000002UL;
2058 /* reset LUT0 register */
2059 BaseAddr->LUT[0] = (uint32)0x08180403UL;
2060 /* reset LUT1 register */
2061 BaseAddr->LUT[1] = (uint32)0x24001C08UL;
2062 for (cnt = 2U; cnt < QuadSPI_LUT_COUNT; cnt++)
2063 {
2064 BaseAddr->LUT[cnt] = (uint32)0x00000000UL;
2065 }
2066 #endif
2067
2068 /* avoid warning unused variable */
2069 (void)cnt;
2070 }
2071
2072 #define FLS_STOP_SEC_CODE
2073 #include "Fls_MemMap.h"
2074
2075 #endif /* (QSPI_IP_MEM_INSTANCE_COUNT > 0) */
2076
2077
2078 #ifdef __cplusplus
2079 }
2080 #endif
2081
2082 /** @} */
2083