1 /*
2 * Copyright 2020-2023 NXP
3 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 */
6
7 /**
8 * @file Qspi_Ip.c
9 *
10 * @addtogroup IPV_QSPI QSPI IPV Driver
11 * @{
12 */
13
14 /* implements Qspi_Ip.c_Artifact */
15
16 #ifdef __cplusplus
17 extern "C"{
18 #endif
19
20 #include "Mcal.h"
21 #include "OsIf.h"
22 #include "Qspi_Ip_Controller.h"
23 #include "Qspi_Ip_Common.h"
24 #include "Qspi_Ip.h"
25 #include "Qspi_Ip_Hyperflash.h"
26
27
28 /*==================================================================================================
29 * SOURCE FILE VERSION INFORMATION
30 ==================================================================================================*/
31 #define QSPI_IP_VENDOR_ID_C 43
32 #define QSPI_IP_AR_RELEASE_MAJOR_VERSION_C 4
33 #define QSPI_IP_AR_RELEASE_MINOR_VERSION_C 7
34 #define QSPI_IP_AR_RELEASE_REVISION_VERSION_C 0
35 #define QSPI_IP_SW_MAJOR_VERSION_C 3
36 #define QSPI_IP_SW_MINOR_VERSION_C 0
37 #define QSPI_IP_SW_PATCH_VERSION_C 0
38 /*==================================================================================================
39 * FILE VERSION CHECKS
40 ==================================================================================================*/
41 #ifndef DISABLE_MCAL_INTERMODULE_ASR_CHECK
42 /* Check if current file and Mcal.h header file are of the same Autosar version */
43 #if ((QSPI_IP_AR_RELEASE_MAJOR_VERSION_C != MCAL_AR_RELEASE_MAJOR_VERSION) || \
44 (QSPI_IP_AR_RELEASE_MINOR_VERSION_C != MCAL_AR_RELEASE_MINOR_VERSION) \
45 )
46 #error "AutoSar Version Numbers of Qspi_Ip.c and Mcal.h are different"
47 #endif
48
49 /* Check if current file and OsIf.h header file are of the same Autosar version */
50 #if ((QSPI_IP_AR_RELEASE_MAJOR_VERSION_C != OSIF_AR_RELEASE_MAJOR_VERSION) || \
51 (QSPI_IP_AR_RELEASE_MINOR_VERSION_C != OSIF_AR_RELEASE_MINOR_VERSION) \
52 )
53 #error "AutoSar Version Numbers of Qspi_Ip.c and OsIf.h are different"
54 #endif
55 #endif
56
57 /* Check if current file and Qspi_Ip_Controller header file are of the same vendor */
58 #if (QSPI_IP_VENDOR_ID_C != QSPI_IP_CONTROLLER_VENDOR_ID_H)
59 #error "Qspi_Ip.c and Qspi_Ip_Controller.h have different vendor ids"
60 #endif
61 /* Check if current file and Qspi_Ip_Controller header file are of the same Autosar version */
62 #if ((QSPI_IP_AR_RELEASE_MAJOR_VERSION_C != QSPI_IP_CONTROLLER_AR_RELEASE_MAJOR_VERSION_H) || \
63 (QSPI_IP_AR_RELEASE_MINOR_VERSION_C != QSPI_IP_CONTROLLER_AR_RELEASE_MINOR_VERSION_H) || \
64 (QSPI_IP_AR_RELEASE_REVISION_VERSION_C != QSPI_IP_CONTROLLER_AR_RELEASE_REVISION_VERSION_H) \
65 )
66 #error "AutoSar Version Numbers of Qspi_Ip.c and Qspi_Ip_Controller.h are different"
67 #endif
68 /* Check if current file and Qspi_Ip_Controller header file are of the same Software version */
69 #if ((QSPI_IP_SW_MAJOR_VERSION_C != QSPI_IP_CONTROLLER_SW_MAJOR_VERSION_H) || \
70 (QSPI_IP_SW_MINOR_VERSION_C != QSPI_IP_CONTROLLER_SW_MINOR_VERSION_H) || \
71 (QSPI_IP_SW_PATCH_VERSION_C != QSPI_IP_CONTROLLER_SW_PATCH_VERSION_H) \
72 )
73 #error "Software Version Numbers of Qspi_Ip.c and Qspi_Ip_Controller.h are different"
74 #endif
75
76 /* Check if current file and Qspi_Ip_Common header file are of the same vendor */
77 #if (QSPI_IP_VENDOR_ID_C != QSPI_IP_COMMON_VENDOR_ID_H)
78 #error "Qspi_Ip.c and Qspi_Ip_Common.h have different vendor ids"
79 #endif
80 /* Check if current file and Qspi_Ip_Common header file are of the same Autosar version */
81 #if ((QSPI_IP_AR_RELEASE_MAJOR_VERSION_C != QSPI_IP_COMMON_AR_RELEASE_MAJOR_VERSION_H) || \
82 (QSPI_IP_AR_RELEASE_MINOR_VERSION_C != QSPI_IP_COMMON_AR_RELEASE_MINOR_VERSION_H) || \
83 (QSPI_IP_AR_RELEASE_REVISION_VERSION_C != QSPI_IP_COMMON_AR_RELEASE_REVISION_VERSION_H) \
84 )
85 #error "AutoSar Version Numbers of Qspi_Ip.c and Qspi_Ip_Common.h are different"
86 #endif
87 /* Check if current file and Qspi_Ip_Common header file are of the same Software version */
88 #if ((QSPI_IP_SW_MAJOR_VERSION_C != QSPI_IP_COMMON_SW_MAJOR_VERSION_H) || \
89 (QSPI_IP_SW_MINOR_VERSION_C != QSPI_IP_COMMON_SW_MINOR_VERSION_H) || \
90 (QSPI_IP_SW_PATCH_VERSION_C != QSPI_IP_COMMON_SW_PATCH_VERSION_H) \
91 )
92 #error "Software Version Numbers of Qspi_Ip.c and Qspi_Ip_Common.h are different"
93 #endif
94
95 /* Check if current file and Qspi_Ip header file are of the same vendor */
96 #if (QSPI_IP_VENDOR_ID_C != QSPI_IP_VENDOR_ID_H)
97 #error "Qspi_Ip.c and Qspi_Ip.h have different vendor ids"
98 #endif
99 /* Check if current file and Qspi_Ip header file are of the same Autosar version */
100 #if ((QSPI_IP_AR_RELEASE_MAJOR_VERSION_C != QSPI_IP_AR_RELEASE_MAJOR_VERSION_H) || \
101 (QSPI_IP_AR_RELEASE_MINOR_VERSION_C != QSPI_IP_AR_RELEASE_MINOR_VERSION_H) || \
102 (QSPI_IP_AR_RELEASE_REVISION_VERSION_C != QSPI_IP_AR_RELEASE_REVISION_VERSION_H) \
103 )
104 #error "AutoSar Version Numbers of Qspi_Ip.c and Qspi_Ip.h are different"
105 #endif
106 /* Check if current file and Qspi_Ip header file are of the same Software version */
107 #if ((QSPI_IP_SW_MAJOR_VERSION_C != QSPI_IP_SW_MAJOR_VERSION_H) || \
108 (QSPI_IP_SW_MINOR_VERSION_C != QSPI_IP_SW_MINOR_VERSION_H) || \
109 (QSPI_IP_SW_PATCH_VERSION_C != QSPI_IP_SW_PATCH_VERSION_H) \
110 )
111 #error "Software Version Numbers of Qspi_Ip.c and Qspi_Ip.h are different"
112 #endif
113
114 /* Check if current file and Qspi_Ip_Hyperflash header file are of the same vendor */
115 #if (QSPI_IP_VENDOR_ID_C != QSPI_IP_HYPERFLASH_VENDOR_ID_H)
116 #error "Qspi_Ip.c and Qspi_Ip_Hyperflash.h have different vendor ids"
117 #endif
118 /* Check if current file and Qspi_Ip_Hyperflash header file are of the same Autosar version */
119 #if ((QSPI_IP_AR_RELEASE_MAJOR_VERSION_C != QSPI_IP_HYPERFLASH_AR_RELEASE_MAJOR_VERSION_H) || \
120 (QSPI_IP_AR_RELEASE_MINOR_VERSION_C != QSPI_IP_HYPERFLASH_AR_RELEASE_MINOR_VERSION_H) || \
121 (QSPI_IP_AR_RELEASE_REVISION_VERSION_C != QSPI_IP_HYPERFLASH_AR_RELEASE_REVISION_VERSION_H) \
122 )
123 #error "AutoSar Version Numbers of Qspi_Ip.c and Qspi_Ip_Hyperflash.h are different"
124 #endif
125 /* Check if current file and Qspi_Ip_Hyperflash header file are of the same Software version */
126 #if ((QSPI_IP_SW_MAJOR_VERSION_C != QSPI_IP_HYPERFLASH_SW_MAJOR_VERSION_H) || \
127 (QSPI_IP_SW_MINOR_VERSION_C != QSPI_IP_HYPERFLASH_SW_MINOR_VERSION_H) || \
128 (QSPI_IP_SW_PATCH_VERSION_C != QSPI_IP_HYPERFLASH_SW_PATCH_VERSION_H) \
129 )
130 #error "Software Version Numbers of Qspi_Ip.c and Qspi_Ip_Hyperflash.h are different"
131 #endif
132
133
134 /*******************************************************************************
135 * Variables
136 ******************************************************************************/
137 #if (QSPI_IP_MEM_INSTANCE_COUNT > 0)
138
139 #define FLS_START_SEC_VAR_CLEARED_UNSPECIFIED
140 #include "Fls_MemMap.h"
141
142 /* Pointer to runtime state structures */
143 Qspi_Ip_StateType Qspi_Ip_MemoryStateStructure[QSPI_IP_MEM_INSTANCE_COUNT];
144
145 #define FLS_STOP_SEC_VAR_CLEARED_UNSPECIFIED
146 #include "Fls_MemMap.h"
147
148 /*******************************************************************************
149 * Macros
150 ******************************************************************************/
151
152
153 /*******************************************************************************
154 * Private Functions
155 ******************************************************************************/
156
157 #define FLS_START_SEC_CODE
158 #include "Fls_MemMap.h"
159
160 static Qspi_Ip_StatusType Qspi_Ip_WriteEnable(uint32 instance);
161
162 static Qspi_Ip_StatusType Qspi_Ip_InitReset(uint32 instance,
163 uint16 resetCmdLut,
164 uint8 resetCmdCount,
165 const Qspi_Ip_StateType *state
166 );
167
168 static Qspi_Ip_StatusType Qspi_Ip_InitWriteReg(uint32 instance,
169 const Qspi_Ip_InitOperationType *operation
170 );
171
172 static Qspi_Ip_StatusType Qspi_Ip_InitRMWReg(uint32 instance,
173 const Qspi_Ip_InitOperationType *operation
174 );
175
176 static Qspi_Ip_StatusType Qspi_Ip_InitReadReg(uint32 instance,
177 const Qspi_Ip_InitOperationType *operation
178 );
179
180 static Qspi_Ip_StatusType Qspi_Ip_InitProtection(uint32 instance,
181 const Qspi_Ip_StateType *state
182 );
183
184 static Qspi_Ip_StatusType Qspi_Ip_InitOperation(uint32 instance,
185 const Qspi_Ip_StateType *state,
186 uint8 initOp
187 );
188
189 static inline uint32 Qspi_Ip_CalcPaddingRead(const Qspi_Ip_StateType *state,
190 uint32 *address,
191 uint32 *size
192 );
193
194 static uint16 Qspi_Ip_InitLutSeq(uint32 instance,
195 uint16 VirtualLut,
196 uint8 LutRegister
197 );
198
199 /*FUNCTION**********************************************************************
200 *
201 * Function Name : Qspi_Ip_InitLutSeq
202 * Description : Initializes one sequence in the LUT table from a virtual table sequence. Returns start index of next sequence.
203 * @implements Qspi_Ip_InitLutSeq_Activity */
Qspi_Ip_InitLutSeq(uint32 instance,uint16 VirtualLut,uint8 LutRegister)204 static uint16 Qspi_Ip_InitLutSeq(uint32 instance,
205 uint16 VirtualLut,
206 uint8 LutRegister
207 )
208 {
209 const Qspi_Ip_StateType * state = &(Qspi_Ip_MemoryStateStructure[instance]);
210 const Qspi_Ip_InstrOpType *virtualLutTable = state->configuration->lutSequences.lutOps;
211 Qspi_Ip_InstrOpType operation1, operation2;
212 uint16 vLutIdx = VirtualLut; /* Index in virtual LUT */
213 uint8 lutIdx = 0U; /* Index in physical LUT */
214 uint32 lutData[FEATURE_QSPI_LUT_SEQUENCE_SIZE]; /* Data to be written to the physical LUTs */
215
216 do
217 {
218 DEV_ASSERT_QSPI(vLutIdx < state->configuration->lutSequences.opCount);
219 operation1 = virtualLutTable[vLutIdx];
220 vLutIdx++;
221 operation2 = QSPI_IP_LUT_SEQ_END;
222 if (operation1 != QSPI_IP_LUT_SEQ_END)
223 {
224 DEV_ASSERT_QSPI(vLutIdx < state->configuration->lutSequences.opCount);
225 operation2 = virtualLutTable[vLutIdx];
226 vLutIdx++;
227 }
228 /* Add two operations to lut sequence */
229 DEV_ASSERT_QSPI(lutIdx < FEATURE_QSPI_LUT_SEQUENCE_SIZE);
230 lutData[lutIdx] = QSPI_IP_PACK_LUT_REG(operation1, operation2);
231 lutIdx++;
232 }
233 while (operation2 != QSPI_IP_LUT_SEQ_END);
234
235 #if (FEATURE_QSPI_HAS_SFP == 1)
236 /* Clear the rest of sequence to avoid the effect of the previous command.
237 This prevent the SFP block from identifying the wrong type of transaction.
238 */
239 for ( ; lutIdx < FEATURE_QSPI_LUT_SEQUENCE_SIZE; lutIdx++)
240 {
241 lutData[lutIdx] = QSPI_IP_PACK_LUT_REG(QSPI_IP_LUT_SEQ_END, QSPI_IP_LUT_SEQ_END);
242 }
243 #endif
244
245 /* Write data to physical LUT registers */
246 Qspi_Ip_WriteLuts(state->connection->qspiInstance, FEATURE_QSPI_LUT_SEQUENCE_SIZE * LutRegister, lutData, lutIdx);
247
248 return vLutIdx;
249 }
250
251
252
253 /*FUNCTION**********************************************************************
254 *
255 * Function Name : Qspi_Ip_SetValue
256 * Description : Converts a long value in data to be sent to flash
257 * @implements Qspi_Ip_SetValue_Activity */
Qspi_Ip_SetValue(uint8 * data,uint8 size,uint32 value)258 static inline void Qspi_Ip_SetValue(uint8 *data,
259 uint8 size,
260 uint32 value
261 )
262 {
263 uint8 cnt;
264 uint32 temp = value;
265
266 /* Put value in the data buffer */
267 for (cnt = 0U; cnt < size; cnt++)
268 {
269 data[cnt] = (uint8)(temp & 0xFFU);
270 temp >>= 8U;
271 }
272 }
273
274 /*FUNCTION**********************************************************************
275 *
276 * Function Name : Qspi_Ip_SetBitfield
277 * Description : Sets a new value in a register bitfield
278 * @implements Qspi_Ip_SetBitfield_Activity */
Qspi_Ip_SetBitfield(uint8 * data,uint8 size,uint8 shift,uint8 width,uint32 value)279 static void Qspi_Ip_SetBitfield(uint8 *data,
280 uint8 size,
281 uint8 shift,
282 uint8 width,
283 uint32 value
284 )
285 {
286 uint8 cnt;
287 uint32 longData = 0UL;
288 uint32 mask;
289
290 /* Pack data in a long value */
291 for (cnt = 0U; cnt < size; cnt++)
292 {
293 longData = (longData << 8U) + data[size - 1U - cnt];
294 }
295 /* Apply change */
296 mask = ((1UL << (uint32)width) - 1UL) << (uint32)shift;
297 longData &= ~mask;
298 longData |= (value << shift) & mask;
299 /* Put data back in the data buffer */
300 for (cnt = 0U; cnt < size; cnt++)
301 {
302 data[cnt] = (uint8)(longData & 0xFFU);
303 longData >>= 8U;
304 }
305 }
306
307
308 /*FUNCTION**********************************************************************
309 *
310 * Function Name : Qspi_Ip_GetBitfield
311 * Description : Extracts the value of a register bitfield
312 * @implements Qspi_Ip_GetBitfield_Activity */
Qspi_Ip_GetBitfield(const uint8 * data,uint8 size,uint8 shift,uint8 width)313 static uint32 Qspi_Ip_GetBitfield(const uint8 *data,
314 uint8 size,
315 uint8 shift,
316 uint8 width
317 )
318 {
319 uint8 cnt;
320 uint32 longData = 0U;
321 uint32 mask;
322 uint32 value;
323
324 /* Pack data in a long value */
325 for (cnt = 0U; cnt < size; cnt++)
326 {
327 longData = (longData << 8U) + data[size - 1U - cnt];
328 }
329 /* Extract field */
330 mask = (1UL << (uint32)width) - 1UL;
331 value = (longData >> shift) & mask;
332 return value;
333 }
334
335
336 /*FUNCTION**********************************************************************
337 *
338 * Function Name : Qspi_Ip_UpdateStatusReg
339 * Description : Updates a bitfield in the status register
340 * @implements Qspi_Ip_UpdateStatusReg_Activity */
Qspi_Ip_UpdateStatusReg(uint32 instance,uint8 offset,uint8 width,uint8 value)341 static Qspi_Ip_StatusType Qspi_Ip_UpdateStatusReg(uint32 instance,
342 uint8 offset,
343 uint8 width,
344 uint8 value
345 )
346 {
347 const Qspi_Ip_StateType * state = &(Qspi_Ip_MemoryStateStructure[instance]);
348 const Qspi_Ip_StatusConfigType *statusConfig = &(state->configuration->statusConfig);
349 uint8 data[4U];
350 Qspi_Ip_StatusType status;
351
352 /* Read status register */
353 status = Qspi_Ip_RunReadCommand(instance, statusConfig->statusRegReadLut, 0U, data, NULL_PTR, statusConfig->regSize);
354
355 if (STATUS_QSPI_IP_SUCCESS == status)
356 {
357 /* Check existing value, write status register only if needed */
358 if (value != Qspi_Ip_GetBitfield(data, statusConfig->regSize, offset, width))
359 {
360 Qspi_Ip_SetBitfield(data, statusConfig->regSize, offset, width, value);
361 }
362 /* send WREN command for status register */
363 if (statusConfig->writeEnableSRLut != QSPI_IP_LUT_INVALID)
364 {
365 status = Qspi_Ip_RunCommand(instance, statusConfig->writeEnableSRLut, 0U);
366 }
367 if (STATUS_QSPI_IP_SUCCESS == status)
368 {
369 /* send write status register command */
370 status = Qspi_Ip_RunWriteCommand(instance, statusConfig->statusRegWriteLut, 0U, data, statusConfig->regSize);
371 }
372 }
373
374 return status;
375 }
376
377 /*FUNCTION**********************************************************************
378 *
379 * Function Name : Qspi_Ip_CheckStatusReg
380 * Description : Checks a bitfield in the status register
381 * @implements Qspi_Ip_CheckStatusReg_Activity */
Qspi_Ip_CheckStatusReg(uint32 instance,uint8 offset,uint8 width,uint8 * value)382 static Qspi_Ip_StatusType Qspi_Ip_CheckStatusReg(uint32 instance,
383 uint8 offset,
384 uint8 width,
385 uint8 *value
386 )
387 {
388 const Qspi_Ip_StateType * state = &(Qspi_Ip_MemoryStateStructure[instance]);
389 const Qspi_Ip_StatusConfigType *statusConfig = &(state->configuration->statusConfig);
390 uint8 data[4];
391 Qspi_Ip_StatusType status;
392
393 /* Read status register */
394 status = Qspi_Ip_RunReadCommand(instance, statusConfig->statusRegReadLut, 0U, data, NULL_PTR, statusConfig->regSize);
395 if (STATUS_QSPI_IP_SUCCESS == status)
396 {
397 /* Extract bit-field */
398 *value = (uint8)Qspi_Ip_GetBitfield(data, statusConfig->regSize, offset, width);
399 }
400
401 return status;
402 }
403
404
405 /*FUNCTION**********************************************************************
406 *
407 * Function Name : Qspi_Ip_WriteEnable
408 * Description : Enables the serial flash memory for a program or erase operation
409 * @implements Qspi_Ip_WriteEnable_Activity */
Qspi_Ip_WriteEnable(uint32 instance)410 static Qspi_Ip_StatusType Qspi_Ip_WriteEnable(uint32 instance)
411 {
412 const Qspi_Ip_StateType * state = &(Qspi_Ip_MemoryStateStructure[instance]);
413 const Qspi_Ip_StatusConfigType *statusConfig = &(state->configuration->statusConfig);
414
415 uint32 retries = QSPI_IP_MAX_RETRY + 1U;
416 Qspi_Ip_StatusType status = STATUS_QSPI_IP_TIMEOUT;
417 Qspi_Ip_StatusType cmdStatus;
418 uint8 welValue = 0U;
419
420 MCAL_FAULT_INJECTION_POINT(FLS_FIP_FR_ERROR_IPCOMMAND_WAIT_IN_WREN);
421
422 while (retries > 0UL)
423 {
424 /* send WREN command */
425 cmdStatus = Qspi_Ip_RunCommand(instance, statusConfig->writeEnableLut, 0U);
426 if (cmdStatus != STATUS_QSPI_IP_SUCCESS)
427 {
428 status = cmdStatus;
429 }
430 /* check WEL bit */
431 cmdStatus = Qspi_Ip_CheckStatusReg(instance, statusConfig->writeEnableOffset, 1U, &welValue);
432 if (STATUS_QSPI_IP_SUCCESS == cmdStatus)
433 {
434 /* 1 == check WEL */
435 if (1U == welValue)
436 {
437 status = STATUS_QSPI_IP_SUCCESS;
438 break;
439 }
440 }
441 else
442 {
443 /* record error */
444 status = cmdStatus;
445 }
446 retries--;
447 }
448
449 return status;
450 }
451
452
453 /*FUNCTION**********************************************************************
454 *
455 * Function Name : Qspi_Ip_SerialflashSectorErase
456 * Description : Erase a sector in the serial flash.
457 */
Qspi_Ip_SerialflashSectorErase(uint32 instance,uint32 address,uint16 eraseLut)458 static Qspi_Ip_StatusType Qspi_Ip_SerialflashSectorErase(uint32 instance,
459 uint32 address,
460 uint16 eraseLut
461 )
462 {
463 Qspi_Ip_StatusType status;
464
465 /* enable write before erasing */
466 status = Qspi_Ip_WriteEnable(instance);
467
468 MCAL_FAULT_INJECTION_POINT(FLS_FIP_FR_ERROR_IPCOMMAND_WAIT_IN_BASICERS);
469
470 if (STATUS_QSPI_IP_SUCCESS == status)
471 {
472 /* launch erase command and return */
473 status = Qspi_Ip_RunCommand(instance, eraseLut, address);
474 }
475
476 return status;
477 }
478
479
480 /*FUNCTION**********************************************************************
481 *
482 * Function Name : Qspi_Ip_BasicErase
483 * Description : Perform one of the supported erase types in the serial flash.
484 * @implements Qspi_Ip_BasicErase_Activity */
Qspi_Ip_BasicErase(uint32 instance,uint32 address,uint16 eraseLut)485 static Qspi_Ip_StatusType Qspi_Ip_BasicErase(uint32 instance,
486 uint32 address,
487 uint16 eraseLut
488 )
489 {
490 const Qspi_Ip_StateType * state = &(Qspi_Ip_MemoryStateStructure[instance]);
491 Qspi_Ip_StatusType status = STATUS_QSPI_IP_ERROR;
492
493 /* Check device type */
494 if (QSPI_IP_SERIAL_FLASH == state->configuration->memType)
495 {
496 status = Qspi_Ip_SerialflashSectorErase(instance, address, eraseLut);
497 }
498 else /*QSPI_IP_HYPER_FLASH == state->configuration->memType */
499 {
500 status = Qspi_Ip_HyperflashSectorErase(instance, address);
501 }
502 return status;
503 }
504
505
506 /*FUNCTION**********************************************************************
507 *
508 * Function Name : Qspi_Ip_CheckMemoryStatus
509 * Description : Check that the memory is idle. Used internally by the driver during initialization
510 */
Qspi_Ip_CheckMemoryStatus(uint32 instance,uint16 VirtualLut)511 static Qspi_Ip_StatusType Qspi_Ip_CheckMemoryStatus(uint32 instance,
512 uint16 VirtualLut
513 )
514 {
515 Qspi_Ip_StatusType status;
516 uint8 busyValue;
517 uint8 data[4];
518 const Qspi_Ip_StateType * state = &(Qspi_Ip_MemoryStateStructure[instance]);
519 const Qspi_Ip_StatusConfigType *statusConfig = &(state->configuration->statusConfig);
520
521 /* Check if the QuadSPI controller is idle */
522 status = Qspi_Ip_ControllerGetStatus(state->connection->qspiInstance);
523 if (STATUS_QSPI_IP_SUCCESS == status)
524 {
525 /* Check if the operation has finished in the serial flash */
526 /* Read status register */
527 status = Qspi_Ip_RunReadCommand(instance, VirtualLut, 0U, data, NULL_PTR, statusConfig->regSize);
528 if (STATUS_QSPI_IP_SUCCESS == status)
529 {
530 /* Extract bit-field */
531 busyValue = (uint8)Qspi_Ip_GetBitfield(data, statusConfig->regSize, statusConfig->busyOffset, 1U);
532 if (busyValue == statusConfig->busyValue)
533 {
534 /* Flash device is busy */
535 status = STATUS_QSPI_IP_BUSY;
536 }
537 MCAL_FAULT_INJECTION_POINT(FLS_FIP_SR_BUSY_CHECKCOMMANDCOMPLETE);
538 }
539 }
540
541 return status;
542 }
543
544
545 /*FUNCTION**********************************************************************
546 *
547 * Function Name : Qspi_Ip_CheckCommandComplete
548 * Description : Wait until external memory is not busy
549 * @implements Qspi_Ip_CheckCommandComplete_Activity */
Qspi_Ip_CheckCommandComplete(uint32 instance,uint16 VirtualLut)550 static Qspi_Ip_StatusType Qspi_Ip_CheckCommandComplete(uint32 instance,
551 uint16 VirtualLut
552 )
553 {
554 Qspi_Ip_StatusType status = STATUS_QSPI_IP_SUCCESS;
555 uint32 u32ElapsedTicks = 0UL;
556 uint32 u32TimeoutTicks;
557 uint32 u32CurrentTicks;
558
559 /* Prepare timeout counter */
560 u32TimeoutTicks = OsIf_MicrosToTicks(QSPI_IP_FLS_INIT_TIMEOUT, (OsIf_CounterType)QSPI_IP_TIMEOUT_TYPE);
561 u32CurrentTicks = OsIf_GetCounter((OsIf_CounterType)QSPI_IP_TIMEOUT_TYPE);
562 /* Wait for the command to complete */
563 do
564 {
565 /* Get memory status */
566 status = Qspi_Ip_CheckMemoryStatus(instance, VirtualLut);
567 u32ElapsedTicks += OsIf_GetElapsed(&u32CurrentTicks, (OsIf_CounterType)QSPI_IP_TIMEOUT_TYPE);
568 /* Check timeout */
569 if (u32ElapsedTicks >= u32TimeoutTicks)
570 {
571 status = STATUS_QSPI_IP_TIMEOUT;
572 break;
573 }
574 }
575 while (STATUS_QSPI_IP_BUSY == status);
576 return status;
577 }
578
579
580 /*FUNCTION**********************************************************************
581 *
582 * Function Name : Qspi_Ip_CheckResetComplete
583 * Description : Wait until external memory is available for operation after a reset
584 * @implements Qspi_Ip_CheckResetComplete_Activity */
Qspi_Ip_CheckResetComplete(void)585 static void Qspi_Ip_CheckResetComplete(void)
586 {
587 uint32 u32ElapsedTicks = 0UL;
588 uint32 u32TimeoutTicks;
589 uint32 u32CurrentTicks;
590
591 /* Prepare timeout counter */
592 u32TimeoutTicks = OsIf_MicrosToTicks(QSPI_IP_RESET_TIMEOUT, (OsIf_CounterType)QSPI_IP_TIMEOUT_TYPE);
593 u32CurrentTicks = OsIf_GetCounter((OsIf_CounterType)QSPI_IP_TIMEOUT_TYPE);
594 /* Wait for the specified time */
595 do
596 {
597 u32ElapsedTicks += OsIf_GetElapsed(&u32CurrentTicks, (OsIf_CounterType)QSPI_IP_TIMEOUT_TYPE);
598 }
599 while (u32ElapsedTicks < u32TimeoutTicks);
600 }
601
602
603 /*FUNCTION**********************************************************************
604 *
605 * Function Name : Qspi_Ip_InitWriteReg
606 * Description : Write the configured value into a register of external flash device
607 * @implements Qspi_Ip_InitWriteReg_Activity */
Qspi_Ip_InitWriteReg(uint32 instance,const Qspi_Ip_InitOperationType * operation)608 static Qspi_Ip_StatusType Qspi_Ip_InitWriteReg(uint32 instance,
609 const Qspi_Ip_InitOperationType * operation
610 )
611 {
612 Qspi_Ip_StatusType status = STATUS_QSPI_IP_SUCCESS;
613 uint8 value[4U];
614
615 /* write a value in a register */
616 if (QSPI_IP_LUT_INVALID != operation->weLut)
617 {
618 /* send WREN command */
619 status = Qspi_Ip_RunCommand(instance, operation->weLut, operation->addr);
620 }
621 if (STATUS_QSPI_IP_SUCCESS == status)
622 {
623 Qspi_Ip_SetValue(value, operation->size, operation->value);
624 status = Qspi_Ip_RunWriteCommand(instance, operation->command1Lut, operation->addr, value, operation->size);
625 }
626
627 return status;
628 }
629
630
631 /*FUNCTION**********************************************************************
632 *
633 * Function Name : Qspi_Ip_InitRMWReg
634 * Description : Change a bitfield in a register of external flash device
635 * @implements Qspi_Ip_InitRMWReg_Activity */
Qspi_Ip_InitRMWReg(uint32 instance,const Qspi_Ip_InitOperationType * operation)636 static Qspi_Ip_StatusType Qspi_Ip_InitRMWReg(uint32 instance,
637 const Qspi_Ip_InitOperationType *operation
638 )
639 {
640 Qspi_Ip_StatusType status;
641 uint32 fieldVal;
642 uint8 value[4U];
643
644 /* Read current register value */
645 status = Qspi_Ip_RunReadCommand(instance, operation->command1Lut, operation->addr, value, NULL_PTR, operation->size);
646 if (STATUS_QSPI_IP_SUCCESS == status)
647 {
648 /* Retrieve target bitfield */
649 fieldVal = Qspi_Ip_GetBitfield(value, operation->size, operation->shift, operation->width);
650 if (fieldVal != operation->value)
651 {
652 /* Modify target bitfield */
653 Qspi_Ip_SetBitfield(value, operation->size, operation->shift, operation->width, operation->value);
654 if (QSPI_IP_LUT_INVALID != operation->weLut)
655 {
656 /* Send WREN command */
657 status = Qspi_Ip_RunCommand(instance, operation->weLut, operation->addr);
658 }
659 if (STATUS_QSPI_IP_SUCCESS == status)
660 {
661 /* Write back register value; use second LUT command */
662 status = Qspi_Ip_RunWriteCommand(instance, operation->command2Lut, operation->addr, (uint8 *)&value, operation->size);
663 }
664 }
665 }
666
667 return status;
668 }
669
670
671 /*FUNCTION**********************************************************************
672 *
673 * Function Name : Qspi_Ip_InitReadReg
674 * Description : Read the register's value of external flash device and loop until matching the configured one
675 * @implements Qspi_Ip_InitReadReg_Activity */
Qspi_Ip_InitReadReg(uint32 instance,const Qspi_Ip_InitOperationType * operation)676 static Qspi_Ip_StatusType Qspi_Ip_InitReadReg(uint32 instance,
677 const Qspi_Ip_InitOperationType *operation
678 )
679 {
680 Qspi_Ip_StatusType status;
681 uint32 fieldVal = 0UL;
682 uint8 value[4U];
683 uint32 u32ElapsedTicks = 0UL;
684 uint32 u32TimeoutTicks;
685 uint32 u32CurrentTicks;
686
687 /* Prepare timeout counter */
688 u32TimeoutTicks = OsIf_MicrosToTicks(QSPI_IP_FLS_INIT_TIMEOUT, (OsIf_CounterType)QSPI_IP_TIMEOUT_TYPE);
689 u32CurrentTicks = OsIf_GetCounter((OsIf_CounterType)QSPI_IP_TIMEOUT_TYPE);
690 do
691 {
692 /* read current register value */
693 status = Qspi_Ip_RunReadCommand(instance, operation->command1Lut, operation->addr, value, NULL_PTR, operation->size);
694 if (STATUS_QSPI_IP_SUCCESS == status)
695 {
696 /* retrieve target bitfield */
697 fieldVal = Qspi_Ip_GetBitfield(value, operation->size, operation->shift, operation->width);
698 }
699 u32ElapsedTicks += OsIf_GetElapsed(&u32CurrentTicks, (OsIf_CounterType)QSPI_IP_TIMEOUT_TYPE);
700 if (u32ElapsedTicks >= u32TimeoutTicks)
701 {
702 status = STATUS_QSPI_IP_TIMEOUT;
703 break;
704 }
705 }
706 while (fieldVal != operation->value);
707
708 return status;
709 }
710
711 /*FUNCTION**********************************************************************
712 *
713 * Function Name : Qspi_Ip_InitOperation
714 * Description : Execute initialization sequence to get the serial flash memory in the target state for operation */
Qspi_Ip_InitOperation(uint32 instance,const Qspi_Ip_StateType * state,uint8 initOp)715 static Qspi_Ip_StatusType Qspi_Ip_InitOperation(uint32 instance,
716 const Qspi_Ip_StateType *state,
717 uint8 initOp
718 )
719 {
720 const Qspi_Ip_InitOperationType *initOperations;
721 Qspi_Ip_StatusType status;
722
723 status = STATUS_QSPI_IP_SUCCESS;
724 initOperations = state->configuration->initConfiguration.operations;
725
726 switch (initOperations[initOp].opType)
727 {
728 case QSPI_IP_OP_TYPE_CMD:
729 /* Execute a simple command */
730 status = Qspi_Ip_RunCommand(instance, initOperations[initOp].command1Lut, initOperations[initOp].addr);
731 break;
732
733 case QSPI_IP_OP_TYPE_WRITE_REG:
734 /* Write value into the register */
735 status = Qspi_Ip_InitWriteReg(instance, &initOperations[initOp]);
736 break;
737
738 case QSPI_IP_OP_TYPE_RMW_REG:
739 /* Change a bitfield in the register */
740 status = Qspi_Ip_InitRMWReg(instance, &initOperations[initOp]);
741 break;
742
743 case QSPI_IP_OP_TYPE_READ_REG:
744 /* Check a bitfield in the register */
745 status = Qspi_Ip_InitReadReg(instance, &initOperations[initOp]);
746 break;
747
748 case QSPI_IP_OP_TYPE_QSPI_CFG:
749 /* Re-initialize QSPI controller with the given configuration */
750 (void)Qspi_Ip_ControllerDeinit(state->connection->qspiInstance);
751 status = Qspi_Ip_ControllerInit(state->connection->qspiInstance, initOperations[initOp].ctrlCfgPtr);
752 break;
753
754 default:
755 ; /* unknown operation */
756 break;
757 } /* switch */
758
759 return status;
760
761 }
762
763 /*FUNCTION**********************************************************************
764 *
765 * Function Name : Qspi_Ip_InitDevice
766 * Description : Execute initialization sequence to get the serial flash memory in the target state for operation
767 * @implements Qspi_Ip_InitDevice_Activity */
Qspi_Ip_InitDevice(uint32 instance,const Qspi_Ip_StateType * state)768 static Qspi_Ip_StatusType Qspi_Ip_InitDevice(uint32 instance,
769 const Qspi_Ip_StateType *state
770 )
771 {
772 Qspi_Ip_StatusType status = STATUS_QSPI_IP_SUCCESS;
773 uint8 initConfigOpCount = state->configuration->initConfiguration.opCount;
774 uint8 initOp;
775
776 MCAL_FAULT_INJECTION_POINT(FLS_FIP_FR_ERROR_IPCOMMAND_INITDEVICE);
777
778 /* Perform operations in initialization list (common) */
779 for (initOp = 0; initOp < initConfigOpCount; initOp++)
780 {
781 status = Qspi_Ip_InitOperation(instance, state, initOp);
782
783 if (STATUS_QSPI_IP_SUCCESS != status)
784 {
785 break;
786 }
787 }
788
789 /* Perform device initialization (specific) */
790 if (STATUS_QSPI_IP_SUCCESS == status)
791 {
792 if (QSPI_IP_SERIAL_FLASH == state->configuration->memType)
793 {
794 /* Nothing to do with Serial flash */
795 }
796 else
797 {
798 /* Call Hyperflash init function */
799 status = Qspi_Ip_HyperflashInit(instance);
800 }
801 }
802 return status;
803 }
804
805
806 /*FUNCTION**********************************************************************
807 *
808 * Function Name : Qspi_Ip_InitProtection
809 * Description : Update the protection configuration value if needed
810 * @implements Qspi_Ip_InitProtection_Activity */
Qspi_Ip_InitProtection(uint32 instance,const Qspi_Ip_StateType * state)811 static Qspi_Ip_StatusType Qspi_Ip_InitProtection(uint32 instance,
812 const Qspi_Ip_StateType *state
813 )
814 {
815 Qspi_Ip_StatusType status = STATUS_QSPI_IP_SUCCESS;
816 uint8 configProtection = state->configuration->statusConfig.blockProtectionValue;
817 uint8 getProtection = 0U;
818
819 if (state->configuration->statusConfig.blockProtectionWidth != 0U)
820 {
821 /* Ensure the previous command is completed */
822 status = Qspi_Ip_CheckCommandComplete(instance, state->configuration->statusConfig.statusRegReadLut);
823 if (STATUS_QSPI_IP_SUCCESS == status)
824 {
825 /* Read and check the current setting */
826 status = Qspi_Ip_GetProtection(instance, &getProtection);
827 if ((STATUS_QSPI_IP_SUCCESS == status) && (getProtection != configProtection))
828 {
829 /* Set new setting */
830 status = Qspi_Ip_SetProtection(instance, configProtection);
831 if (STATUS_QSPI_IP_SUCCESS == status)
832 {
833 /* Ensure the write is completed */
834 status = Qspi_Ip_CheckCommandComplete(instance, state->configuration->statusConfig.statusRegReadLut);
835 }
836 }
837 }
838 }
839
840 return status;
841 }
842
843
844 /*FUNCTION**********************************************************************
845 *
846 * Function Name : Qspi_Ip_InitReset
847 * Description : Perform the software reset sequence
848 * @implements Qspi_Ip_InitReset_Activity */
Qspi_Ip_InitReset(uint32 instance,uint16 resetCmdLut,uint8 resetCmdCount,const Qspi_Ip_StateType * state)849 static Qspi_Ip_StatusType Qspi_Ip_InitReset(uint32 instance,
850 uint16 resetCmdLut,
851 uint8 resetCmdCount,
852 const Qspi_Ip_StateType *state
853 )
854 {
855 Qspi_Ip_StatusType status = STATUS_QSPI_IP_SUCCESS;
856 uint16 crtLut = resetCmdLut;
857 uint8 cnt;
858
859 if (QSPI_IP_LUT_INVALID != resetCmdLut)
860 {
861 for (cnt = 0U; cnt < resetCmdCount; cnt++)
862 {
863 /* Copy sequence in LUT registers */
864 crtLut = Qspi_Ip_InitLutSeq(instance, crtLut, QSPI_IP_COMMAND_LUT);
865
866 /* Run QSPI command */
867 status = Qspi_Ip_IpCommand(state->connection->qspiInstance, QSPI_IP_COMMAND_LUT, state->baseAddress);
868 if (status != STATUS_QSPI_IP_SUCCESS)
869 {
870 break;
871 }
872 }
873 if (STATUS_QSPI_IP_SUCCESS == status)
874 {
875 /* Ensure flash is ready after reset */
876 Qspi_Ip_CheckResetComplete();
877 }
878 }
879
880 return status;
881 }
882
883
884 /*FUNCTION**********************************************************************
885 *
886 * Function Name : Qspi_Ip_SerialflashEraseChip
887 * Description : Erase the entire serial flash
888 */
Qspi_Ip_SerialflashEraseChip(uint32 instance)889 static Qspi_Ip_StatusType Qspi_Ip_SerialflashEraseChip(uint32 instance)
890 {
891 Qspi_Ip_StatusType status = STATUS_QSPI_IP_ERROR;
892 const Qspi_Ip_StateType * state = &(Qspi_Ip_MemoryStateStructure[instance]);
893
894 if (state->configuration->eraseSettings.chipEraseLut != QSPI_IP_LUT_INVALID)
895 {
896 /* enable write before erasing */
897 status = Qspi_Ip_WriteEnable(instance);
898 if (STATUS_QSPI_IP_SUCCESS == status)
899 {
900 /* launch erase command */
901 status = Qspi_Ip_RunCommand(instance, state->configuration->eraseSettings.chipEraseLut, 0U);
902 }
903 }
904
905 return status;
906 }
907
908
909 /*FUNCTION**********************************************************************
910 *
911 * Function Name : Qspi_Ip_SerialflashGetMemoryStatus
912 * Description : Get the status of the last operation
913 */
Qspi_Ip_SerialflashGetMemoryStatus(uint32 instance)914 static Qspi_Ip_StatusType Qspi_Ip_SerialflashGetMemoryStatus(uint32 instance)
915 {
916 const Qspi_Ip_StateType * state = &(Qspi_Ip_MemoryStateStructure[instance]);
917 const Qspi_Ip_StatusConfigType *statusConfig = &(state->configuration->statusConfig);
918 uint8 busyValue = 0xFFU; /* Invalid initial value */
919 Qspi_Ip_StatusType status;
920
921 /* Get the value of busy bit */
922 status = Qspi_Ip_CheckStatusReg(instance, statusConfig->busyOffset, 1U, &busyValue);
923 /* Check BUSY value */
924 if (busyValue == statusConfig->busyValue)
925 {
926 /* Write/erase in progress */
927 status = STATUS_QSPI_IP_BUSY;
928 }
929
930 return status;
931 }
932
933
934 /*FUNCTION**********************************************************************
935 *
936 * Function Name : Qspi_Ip_PatchReadCommand
937 * Description : Patch the command sequence before using
938 */
Qspi_Ip_PatchReadCommand(uint32 instance,uint16 readLut)939 static void Qspi_Ip_PatchReadCommand(uint32 instance,
940 uint16 readLut
941 )
942 {
943 const Qspi_Ip_StateType * state = &(Qspi_Ip_MemoryStateStructure[instance]);
944
945 /* Check device type */
946 if (QSPI_IP_SERIAL_FLASH == state->configuration->memType)
947 {
948 /* Nothing to do with Serial flash */
949 (void)readLut;
950 }
951 else
952 {
953 Qspi_Ip_HyperflashPatchReadCommand(instance, readLut);
954 }
955 }
956
957
958 /*******************************************************************************
959 * Code
960 ******************************************************************************/
961
962 /*FUNCTION**********************************************************************
963 *
964 * Function Name : Qspi_Ip_RunCommand
965 * Description : Launches a simple command for the serial flash
966 * @implements Qspi_Ip_RunCommand_Activity */
Qspi_Ip_RunCommand(uint32 instance,uint16 lut,uint32 addr)967 Qspi_Ip_StatusType Qspi_Ip_RunCommand(uint32 instance,
968 uint16 lut,
969 uint32 addr
970 )
971 {
972 Qspi_Ip_StatusType status = STATUS_QSPI_IP_SUCCESS;
973 const Qspi_Ip_StateType * state = &(Qspi_Ip_MemoryStateStructure[instance]);
974
975 DEV_ASSERT_QSPI(instance < QSPI_IP_MEM_INSTANCE_COUNT);
976 DEV_ASSERT_QSPI(lut != QSPI_IP_LUT_INVALID);
977 DEV_ASSERT_QSPI(addr < state->configuration->memSize);
978 if (QSPI_IP_LUT_INVALID == lut)
979 {
980 status = STATUS_QSPI_IP_ERROR;
981 }
982 else
983 {
984 /* Copy sequence in LUT registers */
985 (void)Qspi_Ip_InitLutSeq(instance, lut, QSPI_IP_COMMAND_LUT);
986
987 /* Run QSPI command */
988 status = Qspi_Ip_IpCommand(state->connection->qspiInstance, QSPI_IP_COMMAND_LUT, state->baseAddress + addr);
989 }
990
991 return status;
992 }
993
994
995 /*FUNCTION**********************************************************************
996 *
997 * Function Name : Qspi_Ip_RunReadCommand
998 * Description : Launches a read command for the serial flash
999 * @implements Qspi_Ip_RunReadCommand_Activity */
Qspi_Ip_RunReadCommand(uint32 instance,uint16 lut,uint32 addr,uint8 * dataRead,const uint8 * dataCmp,uint32 size)1000 Qspi_Ip_StatusType Qspi_Ip_RunReadCommand(uint32 instance,
1001 uint16 lut,
1002 uint32 addr,
1003 uint8 * dataRead,
1004 const uint8 * dataCmp,
1005 uint32 size
1006 )
1007 {
1008 Qspi_Ip_StatusType status = STATUS_QSPI_IP_SUCCESS;
1009 const Qspi_Ip_StateType * state = &(Qspi_Ip_MemoryStateStructure[instance]);
1010
1011 DEV_ASSERT_QSPI(instance < QSPI_IP_MEM_INSTANCE_COUNT);
1012 DEV_ASSERT_QSPI(lut != QSPI_IP_LUT_INVALID);
1013 DEV_ASSERT_QSPI(addr < state->configuration->memSize);
1014 DEV_ASSERT_QSPI((size > 0UL) && ((addr + size) <= state->configuration->memSize));
1015
1016 if (QSPI_IP_LUT_INVALID == lut)
1017 {
1018 status = STATUS_QSPI_IP_ERROR;
1019 }
1020 else
1021 {
1022 /* Copy sequence in LUT registers */
1023 (void)Qspi_Ip_InitLutSeq(instance, lut, QSPI_IP_COMMAND_LUT);
1024
1025 /* Run QSPI command */
1026 status = Qspi_Ip_IpRead(state->connection->qspiInstance, QSPI_IP_COMMAND_LUT, state->baseAddress + addr, dataRead, dataCmp, size);
1027 }
1028
1029 return status;
1030 }
1031
1032
1033 /*FUNCTION**********************************************************************
1034 *
1035 * Function Name : Qspi_Ip_RunWriteCommand
1036 * Description : Launches a write command for the serial flash
1037 * @implements Qspi_Ip_RunWriteCommand_Activity */
Qspi_Ip_RunWriteCommand(uint32 instance,uint16 lut,uint32 addr,const uint8 * data,uint32 size)1038 Qspi_Ip_StatusType Qspi_Ip_RunWriteCommand(uint32 instance,
1039 uint16 lut,
1040 uint32 addr,
1041 const uint8 * data,
1042 uint32 size
1043 )
1044 {
1045 Qspi_Ip_StatusType status = STATUS_QSPI_IP_SUCCESS;
1046 const Qspi_Ip_StateType * state = &(Qspi_Ip_MemoryStateStructure[instance]);
1047
1048 DEV_ASSERT_QSPI(instance < QSPI_IP_MEM_INSTANCE_COUNT);
1049 DEV_ASSERT_QSPI(lut != QSPI_IP_LUT_INVALID);
1050 DEV_ASSERT_QSPI(addr < state->configuration->memSize);
1051 DEV_ASSERT_QSPI((size > 0UL) && ((addr + size) <= state->configuration->memSize));
1052 DEV_ASSERT_QSPI(data != NULL_PTR);
1053
1054 if (QSPI_IP_LUT_INVALID == lut)
1055 {
1056 status = STATUS_QSPI_IP_ERROR;
1057 }
1058 else
1059 {
1060 /* Copy sequence in LUT registers */
1061 (void)Qspi_Ip_InitLutSeq(instance, lut, QSPI_IP_COMMAND_LUT);
1062
1063 /* Run QSPI command */
1064 status = Qspi_Ip_IpWrite(state->connection->qspiInstance, QSPI_IP_COMMAND_LUT, state->baseAddress + addr, data, size);
1065 }
1066
1067 return status;
1068 }
1069
1070
1071
1072 /*FUNCTION**********************************************************************
1073 *
1074 * Function Name : Qspi_Ip_EraseBlock
1075 * Description : Erase a sector in the serial flash.
1076 * The size must match one of the device's erase types.
1077 * @implements Qspi_Ip_EraseBlock_Activity */
Qspi_Ip_EraseBlock(uint32 instance,uint32 address,uint32 size)1078 Qspi_Ip_StatusType Qspi_Ip_EraseBlock(uint32 instance,
1079 uint32 address,
1080 uint32 size
1081 )
1082 {
1083 Qspi_Ip_StateType * state = &(Qspi_Ip_MemoryStateStructure[instance]);
1084 Qspi_Ip_StatusType status = STATUS_QSPI_IP_ERROR;
1085 uint8 eraseType;
1086
1087 DEV_ASSERT_QSPI(instance < QSPI_IP_MEM_INSTANCE_COUNT);
1088 DEV_ASSERT_QSPI(address < state->configuration->memSize);
1089 DEV_ASSERT_QSPI((size > 0UL) && ((address + size) <= state->configuration->memSize));
1090 /* Check address range */
1091 if (address < state->configuration->memSize)
1092 {
1093 /* find the suited erase type */
1094 for (eraseType = 0U; eraseType < QSPI_IP_ERASE_TYPES; eraseType++)
1095 {
1096 if ((state->configuration->eraseSettings.eraseTypes[eraseType].eraseLut != QSPI_IP_LUT_INVALID) &&
1097 (size == (uint32)((uint32)1U << (state->configuration->eraseSettings.eraseTypes[eraseType].size))))
1098 {
1099 break;
1100 }
1101 }
1102 /* if erase type was found, launch the erase */
1103 if (eraseType < QSPI_IP_ERASE_TYPES)
1104 {
1105 status = Qspi_Ip_BasicErase(instance, address, state->configuration->eraseSettings.eraseTypes[eraseType].eraseLut);
1106 if (STATUS_QSPI_IP_SUCCESS == status)
1107 {
1108 state->lastCommand = QSPI_IP_LAST_COMMAND_ERASE;
1109 }
1110 }
1111 }
1112
1113 return status;
1114 }
1115
1116
1117 /*FUNCTION**********************************************************************
1118 *
1119 * Function Name : Qspi_Ip_EraseChip
1120 * Description : Erase the entire serial flash
1121 * @implements Qspi_Ip_EraseChip_Activity */
Qspi_Ip_EraseChip(uint32 instance)1122 Qspi_Ip_StatusType Qspi_Ip_EraseChip(uint32 instance)
1123 {
1124 DEV_ASSERT_QSPI(instance < QSPI_IP_MEM_INSTANCE_COUNT);
1125
1126 Qspi_Ip_StateType * state = &(Qspi_Ip_MemoryStateStructure[instance]);
1127 Qspi_Ip_StatusType status = STATUS_QSPI_IP_ERROR;
1128
1129 /* Check device type */
1130 if (QSPI_IP_SERIAL_FLASH == state->configuration->memType)
1131 {
1132 status = Qspi_Ip_SerialflashEraseChip(instance);
1133 }
1134 else
1135 {
1136 status = Qspi_Ip_HyperflashChipErase(instance);
1137 }
1138 if (STATUS_QSPI_IP_SUCCESS == status)
1139 {
1140 state->lastCommand = QSPI_IP_LAST_COMMAND_ERASE;
1141 }
1142
1143 return status;
1144 }
1145
1146
1147 /*FUNCTION**********************************************************************
1148 *
1149 * Function Name : Qspi_Ip_ProgramSuspend
1150 * Description : Suspends a program operation
1151 * @implements Qspi_Ip_ProgramSuspend_Activity */
Qspi_Ip_ProgramSuspend(uint32 instance)1152 Qspi_Ip_StatusType Qspi_Ip_ProgramSuspend(uint32 instance)
1153 {
1154 DEV_ASSERT_QSPI(instance < QSPI_IP_MEM_INSTANCE_COUNT);
1155
1156 Qspi_Ip_StateType * state = &(Qspi_Ip_MemoryStateStructure[instance]);
1157 Qspi_Ip_StatusType status;
1158
1159 /* Issue the Program Suspend command */
1160 status = Qspi_Ip_RunCommand(instance, state->configuration->suspendSettings.programSuspendLut, 0U);
1161 state->lastCommand = QSPI_IP_LAST_COMMAND_WRITE_SUSPEND;
1162
1163 return status;
1164 }
1165
1166
1167 /*FUNCTION**********************************************************************
1168 *
1169 * Function Name : Qspi_Ip_ProgramResume
1170 * Description : Resumes a program operation
1171 * @implements Qspi_Ip_ProgramResume_Activity */
Qspi_Ip_ProgramResume(uint32 instance)1172 Qspi_Ip_StatusType Qspi_Ip_ProgramResume(uint32 instance)
1173 {
1174 DEV_ASSERT_QSPI(instance < QSPI_IP_MEM_INSTANCE_COUNT);
1175
1176 Qspi_Ip_StateType * state = &(Qspi_Ip_MemoryStateStructure[instance]);
1177 Qspi_Ip_StatusType status;
1178
1179 /* Issue the Program Resume command */
1180 status = Qspi_Ip_RunCommand(instance, state->configuration->suspendSettings.programResumeLut, 0U);
1181 state->lastCommand = QSPI_IP_LAST_COMMAND_WRITE;
1182
1183 return status;
1184 }
1185
1186
1187 /*FUNCTION**********************************************************************
1188 *
1189 * Function Name : Qspi_Ip_EraseSuspend
1190 * Description : Suspends an erase operation
1191 * @implements Qspi_Ip_EraseSuspend_Activity */
Qspi_Ip_EraseSuspend(uint32 instance)1192 Qspi_Ip_StatusType Qspi_Ip_EraseSuspend(uint32 instance)
1193 {
1194 DEV_ASSERT_QSPI(instance < QSPI_IP_MEM_INSTANCE_COUNT);
1195
1196 Qspi_Ip_StateType * state = &(Qspi_Ip_MemoryStateStructure[instance]);
1197 Qspi_Ip_StatusType status;
1198
1199 /* Issue the Erase Suspend command */
1200 status = Qspi_Ip_RunCommand(instance, state->configuration->suspendSettings.eraseSuspendLut, 0U);
1201 state->lastCommand = QSPI_IP_LAST_COMMAND_ERASE_SUSPEND;
1202
1203 return status;
1204 }
1205
1206
1207 /*FUNCTION**********************************************************************
1208 *
1209 * Function Name : Qspi_Ip_EraseResume
1210 * Description : Resumes an erase operation
1211 * @implements Qspi_Ip_EraseResume_Activity */
Qspi_Ip_EraseResume(uint32 instance)1212 Qspi_Ip_StatusType Qspi_Ip_EraseResume(uint32 instance)
1213 {
1214 DEV_ASSERT_QSPI(instance < QSPI_IP_MEM_INSTANCE_COUNT);
1215
1216 Qspi_Ip_StateType * state = &(Qspi_Ip_MemoryStateStructure[instance]);
1217 Qspi_Ip_StatusType status;
1218
1219 /* Issue the Erase Resume command */
1220 status = Qspi_Ip_RunCommand(instance, state->configuration->suspendSettings.eraseResumeLut, 0U);
1221 state->lastCommand = QSPI_IP_LAST_COMMAND_ERASE;
1222
1223 return status;
1224 }
1225
1226
1227 /*FUNCTION**********************************************************************
1228 *
1229 * Function Name : Qspi_Ip_Reset
1230 * Description : Issues a software reset command
1231 * @implements Qspi_Ip_Reset_Activity */
Qspi_Ip_Reset(uint32 instance)1232 Qspi_Ip_StatusType Qspi_Ip_Reset(uint32 instance)
1233 {
1234 uint16 resetCmdLut; /*!< First command in reset sequence */
1235 uint8 resetCmdCount; /*!< Number of commands in reset sequence */
1236 const Qspi_Ip_StateType * state = &(Qspi_Ip_MemoryStateStructure[instance]);
1237 Qspi_Ip_StatusType status = STATUS_QSPI_IP_ERROR;
1238
1239 DEV_ASSERT_QSPI(instance < QSPI_IP_MEM_INSTANCE_COUNT);
1240 resetCmdLut = state->configuration->resetSettings.resetCmdLut;
1241 if (QSPI_IP_LUT_INVALID != resetCmdLut)
1242 {
1243 resetCmdCount = state->configuration->resetSettings.resetCmdCount;
1244 /* Perform reset */
1245 status = Qspi_Ip_InitReset(instance, resetCmdLut, resetCmdCount, state);
1246 /* Bring corresponding controller to initial configuration if required */
1247 if ((STATUS_QSPI_IP_SUCCESS == status) && (state->configuration->ctrlAutoCfgPtr != NULL_PTR))
1248 {
1249 status = Qspi_Ip_ControllerInit(state->connection->qspiInstance, state->configuration->ctrlAutoCfgPtr);
1250 }
1251 if (STATUS_QSPI_IP_SUCCESS == status)
1252 {
1253 /* Execute initial setup of external device */
1254 status = Qspi_Ip_InitDevice(instance, state);
1255 }
1256 }
1257
1258 /* If enabled, call the reset callout. */
1259 if (NULL_PTR != state->configuration->resetCallout)
1260 {
1261 status = state->configuration->resetCallout(instance);
1262 }
1263
1264 return status;
1265 }
1266
1267
1268 /*FUNCTION**********************************************************************
1269 *
1270 * Function Name : Qspi_Ip_GetMemoryStatus
1271 * Description : Get the status of the last operation
1272 * @implements Qspi_Ip_GetMemoryStatus_Activity */
Qspi_Ip_GetMemoryStatus(uint32 instance)1273 Qspi_Ip_StatusType Qspi_Ip_GetMemoryStatus(uint32 instance)
1274 {
1275 DEV_ASSERT_QSPI(instance < QSPI_IP_MEM_INSTANCE_COUNT);
1276
1277 Qspi_Ip_StatusType status;
1278 Qspi_Ip_StateType * state = &(Qspi_Ip_MemoryStateStructure[instance]);
1279
1280 /* Check if the QuadSPI command is complete */
1281 status = Qspi_Ip_ControllerGetStatus(state->connection->qspiInstance);
1282
1283 if (STATUS_QSPI_IP_SUCCESS == status)
1284 {
1285 /* Check device type */
1286 if (QSPI_IP_SERIAL_FLASH == state->configuration->memType)
1287 {
1288 status = Qspi_Ip_SerialflashGetMemoryStatus(instance);
1289 }
1290 else
1291 {
1292 /* Check if the operation has finished in the hyper flash */
1293 status = Qspi_Ip_HyperflashGetMemoryStatus(instance);
1294 }
1295 }
1296
1297 if (STATUS_QSPI_IP_SUCCESS == status)
1298 {
1299 /* Call user callout, if available, to check operation result */
1300 if ((state->lastCommand != QSPI_IP_LAST_COMMAND_NONE) && (NULL_PTR != state->configuration->errorCheckCallout))
1301 {
1302 status = state->configuration->errorCheckCallout(instance);
1303 }
1304 state->lastCommand = QSPI_IP_LAST_COMMAND_NONE;
1305 }
1306
1307 return status;
1308 }
1309
1310
1311 /*FUNCTION**********************************************************************
1312 *
1313 * Function Name : Qspi_Ip_CalcPaddingRead
1314 * Description : Calculates the number of padding bytes to handle reading from unaligned addresses
1315 */
Qspi_Ip_CalcPaddingRead(const Qspi_Ip_StateType * state,uint32 * address,uint32 * size)1316 static inline uint32 Qspi_Ip_CalcPaddingRead(const Qspi_Ip_StateType *state,
1317 uint32 *address,
1318 uint32 *size
1319 )
1320 {
1321 uint32 qspiInstance = state->connection->qspiInstance;
1322 uint32 readAlignment = state->connection->memAlignment;
1323
1324 /* Checking for unaligned addresses */
1325 uint32 offset = *address & ((uint32)readAlignment - 1U);
1326 if (offset != 0U)
1327 {
1328 /* The number of padding bytes to handle unaligned address */
1329 Qspi_Ip_MemoryPadding[qspiInstance] = (uint8)offset;
1330 /* Decreasing the address */
1331 *address -= offset;
1332 /* Increasing the size to compensate */
1333 *size += offset;
1334 }
1335
1336 return offset;
1337 }
1338
1339
1340 /*FUNCTION**********************************************************************
1341 *
1342 * Function Name : Qspi_Ip_Read
1343 * Description : Read data from serial flash
1344 * @implements Qspi_Ip_Read_Activity */
Qspi_Ip_Read(uint32 instance,uint32 address,uint8 * data,uint32 size)1345 Qspi_Ip_StatusType Qspi_Ip_Read(uint32 instance,
1346 uint32 address,
1347 uint8 * data,
1348 uint32 size
1349 )
1350 {
1351 Qspi_Ip_StatusType status = STATUS_QSPI_IP_SUCCESS;
1352 const Qspi_Ip_StateType * state = &(Qspi_Ip_MemoryStateStructure[instance]);
1353 uint32 crtAddress = address;
1354 uint8 * crtData = data;
1355 uint32 crtSize = size;
1356 uint32 chunkSize = QSPI_IP_MAX_READ_SIZE;
1357 uint32 offset;
1358 uint32 u32ElapsedTicks = 0UL;
1359 uint32 u32TimeoutTicks;
1360 uint32 u32CurrentTicks;
1361
1362 DEV_ASSERT_QSPI(crtAddress < state->configuration->memSize);
1363 DEV_ASSERT_QSPI((crtSize > 0UL) && ((crtAddress + crtSize) <= state->configuration->memSize));
1364 DEV_ASSERT_QSPI(instance < QSPI_IP_MEM_INSTANCE_COUNT);
1365 DEV_ASSERT_QSPI(data != NULL_PTR);
1366
1367 /* Checks and handles unaligned addresses */
1368 offset = Qspi_Ip_CalcPaddingRead(state, &crtAddress, &crtSize);
1369
1370 /* Prepare timeout counter */
1371 u32TimeoutTicks = OsIf_MicrosToTicks(QSPI_IP_READ_TIMEOUT, (OsIf_CounterType)QSPI_IP_TIMEOUT_TYPE);
1372 u32CurrentTicks = OsIf_GetCounter((OsIf_CounterType)QSPI_IP_TIMEOUT_TYPE);
1373 while ((crtSize > 0UL) && (STATUS_QSPI_IP_SUCCESS == status))
1374 {
1375 if (chunkSize > crtSize)
1376 {
1377 /* Adjust size for last chunk */
1378 chunkSize = crtSize;
1379 }
1380 /* Check timeout */
1381 u32ElapsedTicks += OsIf_GetElapsed(&u32CurrentTicks, (OsIf_CounterType)QSPI_IP_TIMEOUT_TYPE);
1382 if (u32ElapsedTicks >= u32TimeoutTicks)
1383 {
1384 status = STATUS_QSPI_IP_TIMEOUT;
1385 break;
1386 }
1387
1388 /* Patch the command sequence before using */
1389 Qspi_Ip_PatchReadCommand(instance, state->activeReadLut);
1390 status = Qspi_Ip_RunReadCommand(instance, state->activeReadLut, crtAddress, crtData, NULL_PTR, chunkSize);
1391 /* Move to next chunk */
1392 crtSize -= chunkSize;
1393 crtAddress += chunkSize;
1394 crtData = &(crtData[chunkSize - offset]); /* Handle alignment for the first read */
1395 offset = 0U;
1396
1397 /* Call user callout, if available, to check ecc status */
1398 if ( (STATUS_QSPI_IP_SUCCESS == status) && (NULL_PTR != state->configuration->eccCheckCallout) )
1399 {
1400 status = state->configuration->eccCheckCallout(instance, crtAddress, chunkSize);
1401 }
1402 }
1403 return status;
1404 }
1405
1406
1407 /*FUNCTION**********************************************************************
1408 *
1409 * Function Name : Qspi_Ip_ReadId
1410 * Description : Read manufacturer ID from serial flash
1411 * @implements Qspi_Ip_ReadId_Activity */
Qspi_Ip_ReadId(uint32 instance,uint8 * data)1412 Qspi_Ip_StatusType Qspi_Ip_ReadId(uint32 instance,
1413 uint8 * data
1414 )
1415 {
1416 DEV_ASSERT_QSPI(instance < QSPI_IP_MEM_INSTANCE_COUNT);
1417 DEV_ASSERT_QSPI(data != NULL_PTR);
1418
1419 const Qspi_Ip_StateType * state = &(Qspi_Ip_MemoryStateStructure[instance]);
1420 Qspi_Ip_StatusType status = STATUS_QSPI_IP_ERROR;
1421
1422 /* Check device type */
1423 if (QSPI_IP_SERIAL_FLASH == state->configuration->memType)
1424 {
1425 status = Qspi_Ip_RunReadCommand(instance,
1426 state->configuration->readIdSettings.readIdLut,
1427 0U,
1428 data,
1429 NULL_PTR,
1430 state->configuration->readIdSettings.readIdSize);
1431 }
1432 else
1433 {
1434 status = Qspi_Ip_HyperflashReadId(instance,
1435 state->configuration->hfConfig->deviceIdWordAddress,
1436 data,
1437 state->configuration->readIdSettings.readIdSize);
1438 }
1439 return status;
1440 }
1441
1442
1443 /*FUNCTION**********************************************************************
1444 *
1445 * Function Name : Qspi_Ip_ProgramVerify
1446 * Description : Verifies data written in serial flash
1447 * @implements Qspi_Ip_ProgramVerify_Activity */
Qspi_Ip_ProgramVerify(uint32 instance,uint32 address,const uint8 * data,uint32 size)1448 Qspi_Ip_StatusType Qspi_Ip_ProgramVerify(uint32 instance,
1449 uint32 address,
1450 const uint8 * data,
1451 uint32 size
1452 )
1453 {
1454 Qspi_Ip_StatusType status = STATUS_QSPI_IP_SUCCESS;
1455 const Qspi_Ip_StateType * state = &(Qspi_Ip_MemoryStateStructure[instance]);
1456 uint32 crtAddress = address;
1457 const uint8 * crtData = data;
1458 uint32 crtSize = size;
1459 uint32 chunkSize = QSPI_IP_MAX_READ_SIZE;
1460 uint32 offset;
1461 uint32 u32ElapsedTicks = 0UL;
1462 uint32 u32TimeoutTicks;
1463 uint32 u32CurrentTicks;
1464
1465 DEV_ASSERT_QSPI(crtAddress < state->configuration->memSize);
1466 DEV_ASSERT_QSPI((crtSize > 0UL) && ((crtAddress + crtSize) <= state->configuration->memSize));
1467 DEV_ASSERT_QSPI(data != NULL_PTR);
1468 DEV_ASSERT_QSPI(instance < QSPI_IP_MEM_INSTANCE_COUNT);
1469
1470 /* Checks and handles unaligned addresses */
1471 offset = Qspi_Ip_CalcPaddingRead(state, &crtAddress, &crtSize);
1472
1473 /* Prepare timeout counter */
1474 u32TimeoutTicks = OsIf_MicrosToTicks(QSPI_IP_READ_TIMEOUT, (OsIf_CounterType)QSPI_IP_TIMEOUT_TYPE);
1475 u32CurrentTicks = OsIf_GetCounter((OsIf_CounterType)QSPI_IP_TIMEOUT_TYPE);
1476 while ((crtSize > 0U) && (STATUS_QSPI_IP_SUCCESS == status))
1477 {
1478 if (chunkSize > crtSize)
1479 {
1480 /* Adjust size for last chunk */
1481 chunkSize = crtSize;
1482 }
1483 /* Check timeout */
1484 u32ElapsedTicks += OsIf_GetElapsed(&u32CurrentTicks, (OsIf_CounterType)QSPI_IP_TIMEOUT_TYPE);
1485 if (u32ElapsedTicks >= u32TimeoutTicks)
1486 {
1487 status = STATUS_QSPI_IP_TIMEOUT;
1488 break;
1489 }
1490
1491 /* Patch the command sequence before using */
1492 Qspi_Ip_PatchReadCommand(instance, state->activeReadLut);
1493 status = Qspi_Ip_RunReadCommand(instance, state->activeReadLut, crtAddress, NULL_PTR, crtData, chunkSize);
1494 /* Move to next chunk */
1495 crtSize -= chunkSize;
1496 crtAddress += chunkSize;
1497 crtData = &(crtData[chunkSize - offset]); /* Handle alignment for the first read */
1498 offset = 0U;
1499 }
1500 return status;
1501 }
1502
1503
1504
1505 /*FUNCTION**********************************************************************
1506 *
1507 * Function Name : Qspi_Ip_EraseVerify
1508 * Description : Verifies that an area in serial flash is in erased state
1509 * @implements Qspi_Ip_EraseVerify_Activity */
Qspi_Ip_EraseVerify(uint32 instance,uint32 address,uint32 size)1510 Qspi_Ip_StatusType Qspi_Ip_EraseVerify(uint32 instance,
1511 uint32 address,
1512 uint32 size
1513 )
1514 {
1515 Qspi_Ip_StatusType status = STATUS_QSPI_IP_SUCCESS;
1516 const Qspi_Ip_StateType * state = &(Qspi_Ip_MemoryStateStructure[instance]);
1517 uint32 crtAddress = address;
1518 uint32 crtSize = size;
1519 uint32 chunkSize = QSPI_IP_MAX_READ_SIZE;
1520 uint32 u32ElapsedTicks = 0UL;
1521 uint32 u32TimeoutTicks;
1522 uint32 u32CurrentTicks;
1523
1524 DEV_ASSERT_QSPI(crtAddress < state->configuration->memSize);
1525 DEV_ASSERT_QSPI((crtSize > 0UL) && ((crtAddress + crtSize) <= state->configuration->memSize));
1526 DEV_ASSERT_QSPI(instance < QSPI_IP_MEM_INSTANCE_COUNT);
1527
1528 /* Checks and handles unaligned addresses */
1529 (void)Qspi_Ip_CalcPaddingRead(state, &crtAddress, &crtSize);
1530
1531 /* Prepare timeout counter */
1532 u32TimeoutTicks = OsIf_MicrosToTicks(QSPI_IP_READ_TIMEOUT, (OsIf_CounterType)QSPI_IP_TIMEOUT_TYPE);
1533 u32CurrentTicks = OsIf_GetCounter((OsIf_CounterType)QSPI_IP_TIMEOUT_TYPE);
1534 while ((crtSize > 0UL) && (STATUS_QSPI_IP_SUCCESS == status))
1535 {
1536 if (chunkSize > crtSize)
1537 {
1538 /* Adjust size for last chunk */
1539 chunkSize = crtSize;
1540 }
1541 /* Check timeout */
1542 u32ElapsedTicks += OsIf_GetElapsed(&u32CurrentTicks, (OsIf_CounterType)QSPI_IP_TIMEOUT_TYPE);
1543 if (u32ElapsedTicks >= u32TimeoutTicks)
1544 {
1545 status = STATUS_QSPI_IP_TIMEOUT;
1546 break;
1547 }
1548
1549 /* Patch the command sequence before issuing */
1550 Qspi_Ip_PatchReadCommand(instance, state->activeReadLut);
1551 status = Qspi_Ip_RunReadCommand(instance, state->activeReadLut, crtAddress, NULL_PTR, NULL_PTR, chunkSize);
1552 /* Move to next chunk */
1553 crtSize -= chunkSize;
1554 crtAddress += chunkSize;
1555 }
1556 return status;
1557 }
1558
1559
1560 /*FUNCTION**********************************************************************
1561 *
1562 * Function Name : Qspi_Ip_CalcPaddingWrite
1563 * Description : Calculates the number of padding bytes to handle writing to unaligned addresses
1564 */
Qspi_Ip_CalcPaddingWrite(const Qspi_Ip_StateType * state,uint32 address,uint32 size)1565 static inline uint32 Qspi_Ip_CalcPaddingWrite(const Qspi_Ip_StateType *state,
1566 uint32 address,
1567 uint32 size
1568 )
1569 {
1570 uint32 qspiInstance = state->connection->qspiInstance;
1571 uint32 alignmentMask = (uint32)(state->connection->memAlignment) - 1UL;
1572
1573 /* The number of pre-padding bytes */
1574 uint32 prePadding = address & alignmentMask;
1575
1576 /* The number of post-padding bytes */
1577 uint32 endAddr = address + size - 1UL;
1578 uint32 postPadding = alignmentMask - (endAddr & alignmentMask);
1579
1580 /* Store padding information */
1581 Qspi_Ip_MemoryPadding[qspiInstance] = (uint8)((prePadding << 4UL) | postPadding);
1582
1583 /* Decreasing the address */
1584 return (address - prePadding);
1585 }
1586
1587
1588 /*FUNCTION**********************************************************************
1589 *
1590 * Function Name : Qspi_Ip_Program
1591 * Description : Writes data in serial flash
1592 * @implements Qspi_Ip_Program_Activity */
Qspi_Ip_Program(uint32 instance,uint32 address,const uint8 * data,uint32 size)1593 Qspi_Ip_StatusType Qspi_Ip_Program(uint32 instance,
1594 uint32 address,
1595 const uint8 * data,
1596 uint32 size
1597 )
1598 {
1599 Qspi_Ip_StatusType status = STATUS_QSPI_IP_SUCCESS;
1600 Qspi_Ip_StateType * state = &(Qspi_Ip_MemoryStateStructure[instance]);
1601 uint32 alignedAddress;
1602
1603 DEV_ASSERT_QSPI(instance < QSPI_IP_MEM_INSTANCE_COUNT);
1604 DEV_ASSERT_QSPI(address < state->configuration->memSize);
1605 DEV_ASSERT_QSPI(data != NULL_PTR);
1606 DEV_ASSERT_QSPI((size > 0UL) && ((address + size) <= state->configuration->memSize));
1607
1608 /* Check address range and page size */
1609 if ((address >= state->configuration->memSize) || ((size > state->configuration->pageSize)))
1610 {
1611 status = STATUS_QSPI_IP_ERROR;
1612 }
1613 else
1614 {
1615 /* Write data to the flash device */
1616 if (QSPI_IP_SERIAL_FLASH == state->configuration->memType)
1617 {
1618 /* enable write before programming */
1619 status = Qspi_Ip_WriteEnable(instance);
1620 if (STATUS_QSPI_IP_SUCCESS == status)
1621 {
1622 /* Perform alignment checking before write data */
1623 alignedAddress = Qspi_Ip_CalcPaddingWrite(state, address, size);
1624 /* Write data to serial flash */
1625 status = Qspi_Ip_RunWriteCommand(instance, state->configuration->writeLut, alignedAddress, data, size);
1626 }
1627 }
1628 else /*QSPI_IP_HYPER_FLASH == state->configuration->memType */
1629 {
1630 /* Perform alignment checking before write data */
1631 alignedAddress = Qspi_Ip_CalcPaddingWrite(state, address, size);
1632 /* Write data to hyper flash */
1633 status = Qspi_Ip_HyperflashProgram(instance, alignedAddress, data, size);
1634 }
1635 if (STATUS_QSPI_IP_SUCCESS == status)
1636 {
1637 state->lastCommand = QSPI_IP_LAST_COMMAND_WRITE;
1638 }
1639 }
1640
1641 return status;
1642 }
1643
1644
1645 /*FUNCTION**********************************************************************
1646 *
1647 * Function Name : Qspi_Ip_Enter0XX
1648 * Description : Enters 0-X-X mode (no command for read instructions)
1649 * @implements Qspi_Ip_Enter0XX_Activity */
Qspi_Ip_Enter0XX(uint32 instance)1650 Qspi_Ip_StatusType Qspi_Ip_Enter0XX(uint32 instance)
1651 {
1652 Qspi_Ip_StatusType status = STATUS_QSPI_IP_ERROR;
1653 Qspi_Ip_StateType * state = &(Qspi_Ip_MemoryStateStructure[instance]);
1654 uint8 dummyData;
1655
1656 DEV_ASSERT_QSPI(instance < QSPI_IP_MEM_INSTANCE_COUNT);
1657 if (state->configuration->read0xxLut != QSPI_IP_LUT_INVALID)
1658 {
1659 state->activeReadLut = state->configuration->read0xxLut;
1660 /* Perform a dummy read to activate 0-X-X mode */
1661 status = Qspi_Ip_RunReadCommand(instance, state->activeReadLut, 0U, &dummyData, NULL_PTR, 1U);
1662 }
1663
1664 if (state->configuration->read0xxLutAHB != QSPI_IP_LUT_INVALID)
1665 {
1666 /* Set 0-x-x mode LUT sequence for AHB */
1667 (void)Qspi_Ip_InitLutSeq(instance, state->configuration->read0xxLutAHB, QSPI_IP_AHB_LUT);
1668 }
1669
1670 return status;
1671 }
1672
1673
1674 /*FUNCTION**********************************************************************
1675 *
1676 * Function Name : Qspi_Ip_Exit0XX
1677 * Description : Exits 0-X-X mode (no command for read instructions)
1678 * @implements Qspi_Ip_Exit0XX_Activity */
Qspi_Ip_Exit0XX(uint32 instance)1679 Qspi_Ip_StatusType Qspi_Ip_Exit0XX(uint32 instance)
1680 {
1681 Qspi_Ip_StateType * state = &(Qspi_Ip_MemoryStateStructure[instance]);
1682 Qspi_Ip_StatusType status = STATUS_QSPI_IP_ERROR;
1683 uint8 dummyData;
1684
1685 DEV_ASSERT_QSPI(instance < QSPI_IP_MEM_INSTANCE_COUNT);
1686 if (state->configuration->read0xxLut != QSPI_IP_LUT_INVALID)
1687 {
1688 state->activeReadLut = state->configuration->readLut;
1689 /* Perform a dummy read to disable 0-X-X mode */
1690 status = Qspi_Ip_RunReadCommand(instance, state->activeReadLut, 0U, &dummyData, NULL_PTR, 1U);
1691 }
1692
1693 if (state->configuration->read0xxLutAHB != QSPI_IP_LUT_INVALID)
1694 {
1695 /* Set back to normal mode LUT sequence for AHB */
1696 (void)Qspi_Ip_InitLutSeq(instance, state->configuration->readLut, QSPI_IP_AHB_LUT);
1697 }
1698
1699 return status;
1700 }
1701
1702
1703 /*FUNCTION**********************************************************************
1704 *
1705 * Function Name : Qspi_Ip_SetProtection
1706 * Description : Sets the protection bits of the device
1707 * @implements Qspi_Ip_SetProtection_Activity */
Qspi_Ip_SetProtection(uint32 instance,uint8 value)1708 Qspi_Ip_StatusType Qspi_Ip_SetProtection(uint32 instance,
1709 uint8 value
1710 )
1711 {
1712 const Qspi_Ip_StateType * state = &(Qspi_Ip_MemoryStateStructure[instance]);
1713 const Qspi_Ip_StatusConfigType *statusConfig = &(state->configuration->statusConfig);
1714
1715 DEV_ASSERT_QSPI(instance < QSPI_IP_MEM_INSTANCE_COUNT);
1716
1717 return Qspi_Ip_UpdateStatusReg(instance, statusConfig->blockProtectionOffset, statusConfig->blockProtectionWidth, value);
1718 }
1719
1720
1721 /*FUNCTION**********************************************************************
1722 *
1723 * Function Name : Qspi_Ip_GetProtection
1724 * Description : Returns the current protection bits of the device
1725 * @implements Qspi_Ip_GetProtection_Activity */
Qspi_Ip_GetProtection(uint32 instance,uint8 * value)1726 Qspi_Ip_StatusType Qspi_Ip_GetProtection(uint32 instance,
1727 uint8 *value
1728 )
1729 {
1730 const Qspi_Ip_StateType * state = &(Qspi_Ip_MemoryStateStructure[instance]);
1731 const Qspi_Ip_StatusConfigType *statusConfig = &(state->configuration->statusConfig);
1732
1733 DEV_ASSERT_QSPI(instance < QSPI_IP_MEM_INSTANCE_COUNT);
1734 DEV_ASSERT_QSPI(value != NULL_PTR);
1735
1736 return Qspi_Ip_CheckStatusReg(instance, statusConfig->blockProtectionOffset, statusConfig->blockProtectionWidth, value);
1737 }
1738
1739
1740 /*FUNCTION**********************************************************************
1741 *
1742 * Function Name : Qspi_Ip_AhbReadEnable
1743 * Description : Enables AHB reads for the current flash device
1744 * @implements Qspi_Ip_AhbReadEnable_Activity */
Qspi_Ip_AhbReadEnable(uint32 instance)1745 Qspi_Ip_StatusType Qspi_Ip_AhbReadEnable(uint32 instance)
1746 {
1747 const Qspi_Ip_StateType * state = &(Qspi_Ip_MemoryStateStructure[instance]);
1748 Qspi_Ip_StatusType status = STATUS_QSPI_IP_ERROR;
1749
1750 DEV_ASSERT_QSPI(instance < QSPI_IP_MEM_INSTANCE_COUNT);
1751 if (state->activeReadLut != QSPI_IP_LUT_INVALID)
1752 {
1753 /* Patch the command sequence before using */
1754 Qspi_Ip_PatchReadCommand(instance, state->activeReadLut);
1755 /* Copy sequence in LUT registers */
1756 (void)Qspi_Ip_InitLutSeq(instance, state->activeReadLut, QSPI_IP_AHB_LUT);
1757 /* Set sequence number */
1758 Qspi_Ip_SetAhbSeqId(state->connection->qspiInstance, QSPI_IP_AHB_LUT);
1759 status = STATUS_QSPI_IP_SUCCESS;
1760 }
1761 return status;
1762 }
1763
1764
1765 /*FUNCTION**********************************************************************
1766 *
1767 * Function Name : Qspi_Ip_Init
1768 * Description : Initialize the serial flash memory driver
1769 *
1770 * @implements Qspi_Ip_Init_Activity */
Qspi_Ip_Init(uint32 instance,const Qspi_Ip_MemoryConfigType * pConfig,const Qspi_Ip_MemoryConnectionType * pConnect)1771 Qspi_Ip_StatusType Qspi_Ip_Init(uint32 instance,
1772 const Qspi_Ip_MemoryConfigType * pConfig,
1773 const Qspi_Ip_MemoryConnectionType * pConnect
1774 )
1775 {
1776 Qspi_Ip_StatusType status = STATUS_QSPI_IP_SUCCESS;
1777 Qspi_Ip_StateType * state = &(Qspi_Ip_MemoryStateStructure[instance]);
1778
1779 DEV_ASSERT_QSPI(instance < QSPI_IP_MEM_INSTANCE_COUNT);
1780 DEV_ASSERT_QSPI(pConfig != NULL_PTR);
1781 DEV_ASSERT_QSPI(pConnect != NULL_PTR);
1782
1783 /* Copy configuration information to state structure */
1784 DEV_ASSERT_QSPI(NULL_PTR == state->configuration);
1785 state->configuration = pConfig;
1786 state->connection = pConnect;
1787 state->activeReadLut = pConfig->readLut; /* 0-X-X mode disabled by default */
1788 state->lastCommand = QSPI_IP_LAST_COMMAND_NONE;
1789 state->baseAddress = Qspi_Ip_GetBaseAdress(pConnect->qspiInstance, pConnect->connectionType);
1790
1791 /* Initialize corresponding controller if required */
1792 if (pConfig->ctrlAutoCfgPtr != NULL_PTR)
1793 {
1794 status = Qspi_Ip_ControllerInit(pConnect->qspiInstance, pConfig->ctrlAutoCfgPtr);
1795 }
1796 if (STATUS_QSPI_IP_SUCCESS == status)
1797 {
1798 /* Perform initial reset */
1799 status = Qspi_Ip_InitReset(instance, pConfig->initResetSettings.resetCmdLut, pConfig->initResetSettings.resetCmdCount, state);
1800 }
1801 if (STATUS_QSPI_IP_SUCCESS == status)
1802 {
1803 /* Execute initial setup of external device */
1804 status = Qspi_Ip_InitDevice(instance, state);
1805 }
1806
1807 /* If enabled, call the init callout, for additional QSPI IP or external memory settings. */
1808 if ((STATUS_QSPI_IP_SUCCESS == status) && (NULL_PTR != pConfig->initCallout))
1809 {
1810 status = pConfig->initCallout(instance);
1811 }
1812
1813 /* Perform protection configuration */
1814 if (STATUS_QSPI_IP_SUCCESS == status)
1815 {
1816 status = Qspi_Ip_InitProtection(instance, state);
1817 }
1818
1819 return status;
1820 }
1821
1822
1823 /*FUNCTION**********************************************************************
1824 *
1825 * Function Name : Qspi_Ip_Deinit
1826 * Description : De-initialize the serial flash memory driver
1827 * @implements Qspi_Ip_Deinit_Activity */
Qspi_Ip_Deinit(uint32 instance)1828 Qspi_Ip_StatusType Qspi_Ip_Deinit(uint32 instance)
1829 {
1830 Qspi_Ip_StateType * state = &(Qspi_Ip_MemoryStateStructure[instance]);
1831
1832 DEV_ASSERT_QSPI(instance < QuadSPI_INSTANCE_COUNT);
1833 DEV_ASSERT_QSPI(state->configuration != NULL_PTR);
1834 state->configuration = NULL_PTR;
1835 return STATUS_QSPI_IP_SUCCESS;
1836 }
1837
1838 #define FLS_STOP_SEC_CODE
1839 #include "Fls_MemMap.h"
1840
1841 #endif /* (QSPI_IP_MEM_INSTANCE_COUNT > 0) */
1842
1843
1844 #ifdef __cplusplus
1845 }
1846 #endif
1847
1848 /** @} */
1849