1 /***************************************************************************//**
2 * \file cy_flash_v2.c
3 * \version 1.0
4 *
5 * \brief
6 * Provides the public functions for the API for the Flash Driver.
7 *
8 ********************************************************************************
9 * \copyright
10 * Copyright 2021, Cypress Semiconductor Corporation. All rights reserved.
11 * You may use this file only in accordance with the license, terms, conditions,
12 * disclaimers, and limitations in the end user license agreement accompanying
13 * the software package with which this file was provided.
14 *******************************************************************************/
15 #include "cy_device.h"
16 #if defined(CY_IP_MXFLASHC_VERSION_ECT)
17
18 #include "cy_flash.h"
19 #include "cy_sysint.h"
20 #include "cy_ipc_drv.h"
21 #include "cy_syslib.h"
22
23 /** SROM API flash region ID shift for flash row information */
24 #define CY_FLASH_REGION_ID_SHIFT (16U)
25 #define CY_FLASH_ROW_ID_MASK (0xFFFFU)
26 /** SROM API flash region IDs */
27 #define CY_FLASH_REGION_ID_MAIN (0UL)
28 #define CY_FLASH_REGION_ID_WFLASH (1UL)
29
30 #define ADDRESS_LENGTH_32_BIT (4U)
31 #define ADDRESS_LENGTH_256_BIT (32U)
32 #define DATA_LENGTH_32_BIT (1U)
33 #define DATA_LENGTH_256_BIT (8U)
34
35 static cy_en_flashdrv_status_t Cy_Flash_GetRowDetails(uint32_t rowAddr, uint8_t *rowID, cy_en_flash_checksum_bank_t *bank, cy_en_flash_checksum_region_t *region);
36 static cy_en_flashdrv_status_t Cy_Flash_CalculateHash_Ext(const cy_stc_flash_computehash_config_t *config, uint32_t* hashPtr);
37 static cy_en_flashdrv_status_t Cy_Flash_EraseSector_Ext(const cy_stc_flash_erasesector_config_t *config, cy_en_flash_driver_blocking_t block);
38 static en_flash_bounds_t Cy_Flash_WorkBoundsCheck(uint32_t address);
39 static en_flash_bounds_t Cy_Flash_MainBoundsCheck(uint32_t address);
40 static en_flash_bounds_t Cy_Flash_BoundsCheck(uint32_t flashAddr);
41 static cy_en_flashdrv_status_t Cy_Flash_ProcessOpcode(uint32_t opcode);
42 static uint8_t g_non_block_context = 0;
43
44 /*******************************************************************************
45 * Function Name: Cy_Flash_CallSromApiForFlashWrite
46 ****************************************************************************//**
47 *
48 * This function call SROM API driver for flash writing (e.g. program row,
49 * erase sector). Then, processes response message of the
50 * driver API and response message of SROM API if required.
51 *
52 * apiArgs pointer to SROM API arguments.
53 *
54 * block driver blocking mode cy_en_flash_driver_blocking_t
55 *
56 * Returns the status of the Flash operation.
57 *
58 *******************************************************************************/
Cy_Flash_CallSromApiForFlashWrite(const un_srom_api_args_t * apiArgs,cy_en_flash_driver_blocking_t block)59 static cy_en_flashdrv_status_t Cy_Flash_CallSromApiForFlashWrite(const un_srom_api_args_t* apiArgs, cy_en_flash_driver_blocking_t block)
60 {
61 if(block == CY_FLASH_DRIVER_BLOCKING)
62 {
63 un_srom_api_resps_t apiResp = {{ 0UL }};
64
65 /* Call SROM API with blocking mode */
66 cy_en_srom_driver_status_t sromDrvStatus;
67 sromDrvStatus = Cy_Srom_CallApi(apiArgs, &apiResp);
68 if(sromDrvStatus == CY_SROM_DR_IPC_BUSY)
69 {
70 return CY_FLASH_DRV_IPC_BUSY;
71 }
72 else if(sromDrvStatus == CY_SROM_DR_TIMEOUT)
73 {
74 return CY_FLASH_DRV_SROM_API_TIMEOUT;
75 }
76 else if(sromDrvStatus == CY_SROM_DR_API_UNKNOWN)
77 {
78 return CY_FLASH_DRV_ERR_UNC;
79 }
80 else
81 {
82 cy_en_flashdrv_status_t result;
83 result = Cy_Flash_ProcessOpcode(apiResp.resp[0]);
84 if(result != CY_FLASH_DRV_SUCCESS)
85 {
86 return result;
87 }
88
89 /* Invalidates the flash cache and buffer */
90 FLASHC_FLASH_CMD = _VAL2FLD(FLASHC_FLASH_CMD_INV, 1U);
91
92 // Wait for completion (HW will clear bit)
93 while (_FLD2VAL(FLASHC_FLASH_CMD_INV, FLASHC_FLASH_CMD) != 0U)
94 {
95 }
96
97 return CY_FLASH_DRV_SUCCESS;
98 }
99 }
100 else
101 {
102 /* Call SROM API with non-blocking mode */
103 cy_en_srom_driver_status_t status = Cy_Srom_CallApi_NonBlock(apiArgs);
104
105 if ( status != CY_SROM_DR_SUCCEEDED)
106 {
107 /* The IPC structure is already locked by another process */
108 return CY_FLASH_DRV_IPC_BUSY;
109 }
110 return CY_FLASH_DRV_SUCCESS;
111 }
112 }
113
114
115 /*******************************************************************************
116 * Function Name: Cy_Flash_Program_WorkFlash
117 ****************************************************************************//**
118 *
119 * This function writes an array of data to work flash. Reports success or
120 * or a reason for failure.
121 * Returns immediately and reports a CY_FLASH_DRV_IPC_BUSY error in the case when another
122 * process is operating flash. User firmware should not enter the hibernate
123 * mode until flash Write is complete. The Flash operation is allowed in Sleep and
124 * Deep-sleep modes. During the Flash operation, the device should not be reset,
125 * including the XRES pin, a software reset, and watchdog reset sources. Also,
126 * low-voltage detect circuits should be configured to generate an interrupt instead
127 * of a reset. Otherwise, portions of flash may undergo unexpected changes.
128 *
129 * config configuration of this function.
130 * This parameter is defined by the cy_stc_flash_programrow_config_t
131 * in group_flash_srom_config_structure macro.
132 *
133 * Returns the status of the Flash operation (see cy_en_flashdrv_status_t).
134 *
135 * Note: row or page is same and of the size 512 bytes
136 *
137 *******************************************************************************/
Cy_Flash_Program_WorkFlash(const cy_stc_flash_programrow_config_t * config)138 cy_en_flashdrv_status_t Cy_Flash_Program_WorkFlash(const cy_stc_flash_programrow_config_t* config)
139 {
140 cy_en_flashdrv_status_t status = CY_FLASH_DRV_INVALID_INPUT_PARAMETERS;
141
142 /* Checks if input pointers are not NULL */
143 if(config == NULL)
144 {
145 return status;
146 }
147
148 /* Checks if input address are valid */
149 if((Cy_Flash_WorkBoundsCheck((uint32_t)config->destAddr) == CY_FLASH_OUT_OF_BOUNDS) || (config->dataAddr == NULL))
150 {
151 return status;
152 }
153 /* Prepares arguments to be passed to SROM API */
154 un_srom_api_args_t apiArgs = {{ 0UL }};
155 apiArgs.ProgramRow.arg0.opcode = (uint32_t)CY_SROM_OP_FLASH_PROGRAM_WFLASH;
156 apiArgs.ProgramRow.arg0.blocking = (uint32_t)CY_FLASH_PROGRAMROW_BLOCKING;
157 apiArgs.ProgramRow.arg0.skipBlankCheck = (uint32_t)config->skipBC;
158 apiArgs.ProgramRow.arg1.dataLoc = (uint32_t)config->dataLoc;
159 apiArgs.ProgramRow.arg1.dataSize = (uint32_t)config->dataSize;
160 apiArgs.ProgramRow.arg1.interruptMask = (uint32_t)config->intrMask;
161 apiArgs.ProgramRow.arg2.dstAddr = (uint32_t)config->destAddr;
162 apiArgs.ProgramRow.arg3.srcAddr = (uint32_t)config->dataAddr;
163 /* Call SROM API driver and process response */
164 status = Cy_Flash_CallSromApiForFlashWrite(&apiArgs, CY_FLASH_DRIVER_BLOCKING);
165 return status;
166 }
167
168 /*******************************************************************************
169 * Function Name: Cy_Flash_Program
170 ****************************************************************************//**
171 *
172 * This function writes an array of data to a single row of flash. Reports success or
173 * or a reason for failure.
174 * Returns immediately and reports a CY_FLASH_DRV_IPC_BUSY error in the case when another
175 * process is operating flash. User firmware should not enter the hibernate
176 * mode until flash Write is complete. The Flash operation is allowed in Sleep and
177 * Deep-sleep modes. During the Flash operation, the device should not be reset,
178 * including the XRES pin, a software reset, and watchdog reset sources. Also,
179 * low-voltage detect circuits should be configured to generate an interrupt instead
180 * of a reset. Otherwise, portions of flash may undergo unexpected changes.
181 *
182 * config configuration of this function.
183 * This parameter is defined by the cy_stc_flash_programrow_config_t
184 * in group_flash_srom_config_structure macro.
185 *
186 * Returns the status of the Flash operation (see cy_en_flashdrv_status_t).
187 *
188 * Note: row or page is same and of the size 512 bytes
189 *
190 *******************************************************************************/
Cy_Flash_Program(const cy_stc_flash_programrow_config_t * config,cy_en_flash_driver_blocking_t block)191 cy_en_flashdrv_status_t Cy_Flash_Program(const cy_stc_flash_programrow_config_t* config, cy_en_flash_driver_blocking_t block)
192 {
193 cy_en_flashdrv_status_t status;
194
195 /* Checks if input pointers are not NULL */
196 if(config == NULL)
197 {
198 return CY_FLASH_DRV_INVALID_INPUT_PARAMETERS;
199 }
200
201 /* Checks if input address are valid */
202 if((Cy_Flash_BoundsCheck((uint32_t)config->destAddr) == CY_FLASH_OUT_OF_BOUNDS) || (config->dataAddr == NULL))
203 {
204 return CY_FLASH_DRV_INVALID_INPUT_PARAMETERS;
205 }
206
207 /* Prepares arguments to be passed to SROM API */
208 un_srom_api_args_t apiArgs = {{ 0UL }};
209 apiArgs.ProgramRow.arg0.opcode = (uint32_t)CY_SROM_OP_FLASH_PROGRAM_ROW;
210 apiArgs.ProgramRow.arg0.blocking = (uint32_t)config->blocking;
211 apiArgs.ProgramRow.arg0.skipBlankCheck = (uint32_t)config->skipBC;
212 apiArgs.ProgramRow.arg1.dataLoc = (uint32_t)config->dataLoc;
213 apiArgs.ProgramRow.arg1.dataSize = (uint32_t)config->dataSize;
214 apiArgs.ProgramRow.arg1.interruptMask = (uint32_t)config->intrMask;
215 apiArgs.ProgramRow.arg2.dstAddr = (uint32_t)config->destAddr;
216 apiArgs.ProgramRow.arg3.srcAddr = (uint32_t)config->dataAddr;
217 /* Call SROM API driver and process response */
218 status = Cy_Flash_CallSromApiForFlashWrite(&apiArgs, block);
219
220 if(status == CY_FLASH_DRV_SUCCESS && block == CY_FLASH_DRIVER_NON_BLOCKING)
221 {
222 g_non_block_context = (uint8_t)(FLASHC_FM_CTL_ECT_STATUS_PGM_WORK_Msk | FLASHC_FM_CTL_ECT_STATUS_PGM_CODE_Msk);
223 status = CY_FLASH_DRV_OPERATION_STARTED;
224 }
225 return status;
226 }
227
228 /*******************************************************************************
229 * Function Name: Cy_Flash_Checksum
230 ****************************************************************************//**
231 *
232 * Returns a checksum value of the specified flash row. supports only blocking
233 * mode for now.
234 * rowNum The Checksum is calculated to the flash row.
235 *
236 * checksumPtr The pointer to the address where checksum is to be stored
237 *
238 * Returns the status of the Flash operation.
239 *
240 * Note:row or page is same and of the size 512 bytes
241 *
242 *******************************************************************************/
Cy_Flash_Checksum(const cy_stc_flash_checksum_config_t * config,uint32_t * checksumPtr)243 cy_en_flashdrv_status_t Cy_Flash_Checksum(const cy_stc_flash_checksum_config_t *config, uint32_t* checksumPtr)
244 {
245 /* Checks whether the input parameters are valid */
246 if (config->rowId >= CY_FLASH_NUMBER_ROWS)
247 {
248 return CY_FLASH_DRV_INVALID_INPUT_PARAMETERS;
249 }
250 /* Prepares arguments to be passed to SROM API */
251 un_srom_api_args_t apiArgs = {{ 0UL }};
252 CY_MISRA_DEVIATE_BLOCK_START('MISRA C-2012 Rule 14.3', 1, \
253 'Checked manually. Intentional expression will always be true for CAT1C devices.')
254 if(CPUSS_FLASH_SIZE >= 4096u)
255 {
256 apiArgs.CheckSum.arg0.opcode = (uint32_t)CY_SROM_OP_FLASH_CHECKSUM;
257 apiArgs.CheckSum.arg0.region = (uint32_t)config->region;
258 apiArgs.CheckSum.arg0.whole = (uint32_t)config->whole;
259 apiArgs.CheckSum.arg0.row_id = (uint32_t)config->rowId;
260 apiArgs.CheckSum.arg0.bank = (uint32_t)config->bank;
261 }
262 else
263 {
264 apiArgs.CheckSumLessThan4M.arg0.opcode = (uint32_t)CY_SROM_OP_FLASH_CHECKSUM;
265 apiArgs.CheckSumLessThan4M.arg0.region = (uint32_t)config->region;
266 apiArgs.CheckSumLessThan4M.arg0.whole = (uint32_t)config->whole;
267 apiArgs.CheckSumLessThan4M.arg0.row_id = (uint32_t)config->rowId;
268 apiArgs.CheckSumLessThan4M.arg0.bank = (uint32_t)config->bank;
269 }
270 CY_MISRA_BLOCK_END('MISRA C-2012 Rule 14.3')
271 /* Call SROM API with blocking mode */
272 un_srom_api_resps_t apiResp = {{ 0UL }};
273 cy_en_srom_driver_status_t sromDrvStatus;
274 sromDrvStatus = Cy_Srom_CallApi(&apiArgs, &apiResp);
275 if(sromDrvStatus == CY_SROM_DR_IPC_BUSY)
276 {
277 return CY_FLASH_DRV_IPC_BUSY;
278 }
279 else if(sromDrvStatus == CY_SROM_DR_TIMEOUT)
280 {
281 return CY_FLASH_DRV_SROM_API_TIMEOUT;
282 }
283 else if(sromDrvStatus == CY_SROM_DR_API_UNKNOWN)
284 {
285 return CY_FLASH_DRV_ERR_UNC;
286 }
287 else
288 {
289 /* non-empty terminating "else" statement. */
290 }
291
292 /* Process response message from API */
293 cy_en_flashdrv_status_t result;
294 result = Cy_Flash_ProcessOpcode(apiResp.resp[0]);
295 if(result == CY_FLASH_DRV_SUCCESS)
296 {
297 // checksum is in data1 not data0. the the pointer returned is to data0.
298 uint32_t data[2];
299 // CY_MISRA_DEVIATE_LINE('MISRA C-2012 Rule 10.1','Checked manually. Intentional Non boolean type is interpreted as boolean.');
300 Cy_IPC_Drv_ReadDDataValue(Cy_IPC_Drv_GetIpcBaseAddress((uint32_t)CY_IPC_CHAN_SYSCALL), data );
301 *checksumPtr = data[1];
302 }
303 return result;
304 }
305
306
307 /*******************************************************************************
308 * Function Name: Cy_Flash_CalculateHash_Ext
309 ****************************************************************************//**
310 *
311 * Returns a hash value of the specified region of flash. supports only blocking
312 * mode for now.
313 * data Start the data address.
314 *
315 * numberOfBytes The hash value is calculated for the number of bytes after the
316 * start data address (0 - 1 byte, 1- 2 bytes etc).
317 *
318 * hashPtr The pointer to the address where hash is to be stored
319 *
320 * Returns the status of the Flash operation.
321 *
322 *******************************************************************************/
Cy_Flash_CalculateHash_Ext(const cy_stc_flash_computehash_config_t * config,uint32_t * hashPtr)323 static cy_en_flashdrv_status_t Cy_Flash_CalculateHash_Ext(const cy_stc_flash_computehash_config_t *config, uint32_t* hashPtr)
324 {
325 /* Checks whether the input parameters are valid */
326 if ((config->startAddr == NULL) || (config->numOfByte == 0UL) || (hashPtr == NULL))
327 {
328 return CY_FLASH_DRV_INVALID_INPUT_PARAMETERS;
329 }
330 /* Prepares arguments to be passed to SROM API */
331 un_srom_api_args_t apiArgs = {{ 0UL }};
332 apiArgs.ComputeHash.arg0.opcode = (uint32_t)CY_SROM_OP_FLASH_HASH;
333 apiArgs.ComputeHash.arg0.type = (uint32_t)config->type;
334 apiArgs.ComputeHash.arg1.start_addr = (uint32_t)config->startAddr;
335 apiArgs.ComputeHash.arg2.number_byte = (config->numOfByte - 1UL);
336
337 /* Call SROM API with blocking mode */
338 un_srom_api_resps_t apiResp = {{ 0UL }};
339 cy_en_srom_driver_status_t sromDrvStatus;
340 sromDrvStatus = Cy_Srom_CallApi(&apiArgs, &apiResp);
341 if(sromDrvStatus == CY_SROM_DR_IPC_BUSY)
342 {
343 return CY_FLASH_DRV_IPC_BUSY;
344 }
345 else if(sromDrvStatus == CY_SROM_DR_TIMEOUT)
346 {
347 return CY_FLASH_DRV_SROM_API_TIMEOUT;
348 }
349 else if(sromDrvStatus == CY_SROM_DR_API_UNKNOWN)
350 {
351 return CY_FLASH_DRV_ERR_UNC;
352 }
353 else
354 {
355 /* non-empty terminating "else" statement. */
356 }
357
358 /* Process response message from API */
359 cy_en_flashdrv_status_t result;
360 result = Cy_Flash_ProcessOpcode(apiResp.resp[0]);
361 if(result == CY_FLASH_DRV_SUCCESS)
362 {
363 *hashPtr = apiResp.ComputeHash.resp0.hash_crc;
364 }
365 return result;
366 }
367
368
369 /*******************************************************************************
370 * Function Name: Cy_Flash_WorkBoundsCheck
371 ****************************************************************************//**
372 *
373 * Checks if Flash address is out of work region.
374 *
375 * address Address to be checked
376 *
377 * en_flash_bounds_t
378 *
379 *******************************************************************************/
Cy_Flash_WorkBoundsCheck(uint32_t address)380 static en_flash_bounds_t Cy_Flash_WorkBoundsCheck(uint32_t address)
381 {
382 cy_en_bankmode_t bankmode = Cy_Flashc_GetWorkBankMode();
383 if(bankmode == CY_FLASH_SINGLE_BANK_MODE)
384 {
385 if(( CY_WFLASH_LG_SBM_TOP <= address) && (address < CY_WFLASH_LG_SBM_END))
386 {
387 return(CY_FLASH_IN_BOUNDS);
388 }
389
390 if((CY_WFLASH_SM_SBM_TOP <= address) && (address < CY_WFLASH_SM_SBM_END))
391 {
392 return(CY_FLASH_IN_BOUNDS);
393 }
394 }
395 else
396 {
397 if(( CY_WFLASH_LG_DBM0_TOP <= address) && (address < CY_WFLASH_LG_DBM0_END))
398 {
399 return(CY_FLASH_IN_BOUNDS);
400 }
401
402 if(( CY_WFLASH_SM_DBM0_TOP <= address) && (address < CY_WFLASH_SM_DBM0_END))
403 {
404 return(CY_FLASH_IN_BOUNDS);
405 }
406
407 if(( CY_WFLASH_LG_DBM1_TOP <= address) && (address < CY_WFLASH_LG_DBM1_END))
408 {
409 return(CY_FLASH_IN_BOUNDS);
410 }
411
412 if(( CY_WFLASH_SM_DBM1_TOP <= address) && (address < CY_WFLASH_SM_DBM1_END))
413 {
414 return(CY_FLASH_IN_BOUNDS);
415 }
416 }
417
418 return(CY_FLASH_OUT_OF_BOUNDS);
419 }
420
421 /*******************************************************************************
422 * Function Name: Cy_Flash_MainBoundsCheck
423 ****************************************************************************//**
424 *
425 * Returns 1 if Flash address is out of main region, otherwise returns 0.
426 *
427 * address Address to be checked
428 *
429 * 1 - out of bound, 0 - in flash bounds
430 *
431 *******************************************************************************/
Cy_Flash_MainBoundsCheck(uint32_t address)432 static en_flash_bounds_t Cy_Flash_MainBoundsCheck(uint32_t address)
433 {
434 cy_en_bankmode_t bankmode = Cy_Flashc_GetMainBankMode();
435 if(bankmode == CY_FLASH_SINGLE_BANK_MODE)
436 {
437 if(( CY_FLASH_LG_SBM_TOP <= address) && (address < CY_FLASH_LG_SBM_END))
438 {
439 return(CY_FLASH_IN_BOUNDS);
440 }
441
442 if(( CY_FLASH_SM_SBM_TOP <= address) && (address < CY_FLASH_SM_SBM_END))
443 {
444 return(CY_FLASH_IN_BOUNDS);
445 }
446 }
447 else
448 {
449 if(( CY_FLASH_LG_DBM0_TOP <= address) && (address < CY_FLASH_LG_DBM0_END))
450 {
451 return(CY_FLASH_IN_BOUNDS);
452 }
453
454 if(( CY_FLASH_SM_DBM0_TOP <= address) && (address < CY_FLASH_SM_DBM0_END))
455 {
456 return(CY_FLASH_IN_BOUNDS);
457 }
458
459 if(( CY_FLASH_LG_DBM1_TOP <= address) && (address < CY_FLASH_LG_DBM1_END))
460 {
461 return(CY_FLASH_IN_BOUNDS);
462 }
463
464 if(( CY_FLASH_SM_DBM1_TOP <= address) && (address < CY_FLASH_SM_DBM1_END))
465 {
466 return(CY_FLASH_IN_BOUNDS);
467 }
468 }
469
470 return(CY_FLASH_OUT_OF_BOUNDS);
471 }
472
473 /*******************************************************************************
474 * Function Name: Cy_Flash_BoundsCheck
475 ****************************************************************************//**
476 *
477 * Returns 1 if Flash address is out of boundary, otherwise returns 0.
478 *
479 * flashAddr Address to be checked
480 *
481 * 1 - out of bound, 0 - in flash bounds
482 *
483 *******************************************************************************/
Cy_Flash_BoundsCheck(uint32_t flashAddr)484 static en_flash_bounds_t Cy_Flash_BoundsCheck(uint32_t flashAddr)
485 {
486 if(Cy_Flash_WorkBoundsCheck(flashAddr) == CY_FLASH_IN_BOUNDS)
487 {
488 return(CY_FLASH_IN_BOUNDS);
489 }
490
491 if(Cy_Flash_MainBoundsCheck(flashAddr) == CY_FLASH_IN_BOUNDS)
492 {
493 return(CY_FLASH_IN_BOUNDS);
494 }
495
496 return (CY_FLASH_OUT_OF_BOUNDS);
497 }
498
499 /*******************************************************************************
500 * Function Name: Cy_Flash_ProcessOpcode
501 ****************************************************************************//**
502 *
503 * Converts System Call returns to the Flash driver return defines.
504 *
505 * opcode The value returned by the System Call.
506 *
507 * Flash driver return. cy_en_flashdrv_status_t only support a
508 * part of SROM response. please use Cy_Srom_GetApiResponse to
509 * get complete status of SROM API.
510 *
511 *******************************************************************************/
Cy_Flash_ProcessOpcode(uint32_t opcode)512 static cy_en_flashdrv_status_t Cy_Flash_ProcessOpcode(uint32_t opcode)
513 {
514 cy_en_flashdrv_status_t retVal;
515 cy_en_srom_api_status_t apiStatus;
516 apiStatus = Cy_Srom_ConvertRespToStatus(opcode);
517
518 // Process error code
519 switch (apiStatus)
520 {
521 case CY_SROM_STATUS_SUCCESS:
522 retVal = CY_FLASH_DRV_SUCCESS;
523 break;
524 case CY_SROM_STATUS_INVALID:
525 retVal = CY_FLASH_DRV_ERR_UNC;
526 break;
527 case CY_SROM_STATUS_INVALID_PROTECTION:
528 retVal = CY_FLASH_DRV_INV_PROT;
529 break;
530 case CY_SROM_STATUS_INVALID_FM_PL:
531 retVal = CY_FLASH_DRV_INVALID_FM_PL;
532 break;
533 case CY_SROM_STATUS_INVALID_FLASH_ADDR:
534 retVal = CY_FLASH_DRV_INVALID_FLASH_ADDR;
535 break;
536 case CY_SROM_STATUS_NVM_PROTECTED:
537 retVal = CY_FLASH_DRV_ROW_PROTECTED;
538 break;
539 case CY_SROM_STATUS_INVALID_IPC_STRUCT:
540 retVal = CY_FLASH_DRV_IPC_BUSY;
541 break;
542 case CY_SROM_STAUTS_CHECKSUM_NON_ZERO:
543 retVal = CY_FLASH_DRV_CHECKSUM_NON_ZERO;
544 break;
545 case CY_SROM_STATUS_SECTOR_SUSPEND:
546 retVal = CY_FLASH_DRV_SECTOR_SUSPEND;
547 break;
548 case CY_SROM_STATUS_NO_ERASE_SUSPEND:
549 retVal = CY_FLASH_DRV_NO_ERASE_SUSPEND;
550 break;
551 case CY_SROM_STATUS_FLASH_NOT_ERASED:
552 retVal = CY_FLASH_DRV_FLASH_NOT_ERASED;
553 break;
554 case CY_SROM_STATUS_NO_ERASE_ONGOING:
555 retVal = CY_FLASH_DRV_NO_ERASE_ONGOING;
556 break;
557 case CY_SROM_STATUS_ACTIVE_ERASE:
558 retVal = CY_FLASH_DRV_ACTIVE_ERASE;
559 break;
560 case CY_SROM_STAUTS_INVALID_DATA_WIDTH:
561 retVal = CY_FLASH_DRV_INVALID_DATA_WIDTH;
562 break;
563 case CY_SROM_STATUS_FLASH_SAFTEY_ENABLED:
564 retVal = CY_FLASH_DRV_FLASH_SAFTEY_ENABLED;
565 break;
566 case CY_SROM_STATUS_INVALID_SFLASH_ADDR:
567 retVal = CY_FLASH_DRV_INVALID_SFLASH_ADDR;
568 break;
569 case CY_SROM_STATUS_SFLASH_BACKUP_ERASED:
570 retVal = CY_FLASH_DRV_SFLASH_BACKUP_ERASED;
571 break;
572 default:
573 retVal = CY_FLASH_DRV_ERR_UNC;
574 break;
575 }
576
577 return (retVal);
578 }
579
580 /*******************************************************************************
581 * Function Name: Cy_Flash_EraseSector_Ext
582 ****************************************************************************//**
583 *
584 * This function Starts the sector erase operation on the specified sector.
585 * This function cannot be called on SFLASH. Reports success
586 * or a reason for failure.
587 * Returns immediately and reports a CY_FLASH_DRV_IPC_BUSY error in the case when another
588 * process is operating flash. User firmware should not enter the hibernate
589 * mode until flash Erase is complete. The Flash operation is allowed in Sleep and
590 * Deep-sleep modes. During the Flash operation, the device should not be reset,
591 * including the XRES pin, a software reset, and watchdog reset sources. Also,
592 * low-voltage detect circuits should be configured to generate an interrupt instead
593 * of a reset. Otherwise, portions of flash may undergo unexpected changes.
594 *
595 * config configuration of this function.
596 * This parameter is defined by the cy_stc_flash_erasesector_config_t
597 * in group_flash_srom_config_structure macro.
598 *
599 * Returns the status of the Flash operation (see cy_en_flashdrv_status_t).
600 *
601 *******************************************************************************/
Cy_Flash_EraseSector_Ext(const cy_stc_flash_erasesector_config_t * config,cy_en_flash_driver_blocking_t block)602 static cy_en_flashdrv_status_t Cy_Flash_EraseSector_Ext(const cy_stc_flash_erasesector_config_t *config, cy_en_flash_driver_blocking_t block)
603 {
604 cy_en_flashdrv_status_t status;
605 /* Checks if input pointers are not NULL */
606 if (config == NULL)
607 {
608 return CY_FLASH_DRV_INVALID_INPUT_PARAMETERS;
609 }
610
611 /* Checks if input address is in work/main region */
612 if(Cy_Flash_BoundsCheck((uint32_t)(config->sectorAddr)) == CY_FLASH_OUT_OF_BOUNDS)
613 {
614 return CY_FLASH_DRV_INVALID_INPUT_PARAMETERS;
615 }
616
617 /* Checks if input address is word aligned */
618 if(((uint32_t)(config->sectorAddr) % sizeof(uint32_t)) != 0UL)
619 {
620 return CY_FLASH_DRV_INVALID_INPUT_PARAMETERS;
621 }
622 /* Prepares arguments to be passed to SROM API */
623 un_srom_api_args_t apiArgs = {{ 0UL }};
624 apiArgs.EraseSector.arg0.opcode = (uint32_t)CY_SROM_OP_FLASH_ERASE_SECTOR;
625 apiArgs.EraseSector.arg0.blocking = (uint32_t)config->blocking;
626 apiArgs.EraseSector.arg0.interruptMask = (uint32_t)config->intrMask;
627 apiArgs.EraseSector.arg1.address = (uint32_t)config->sectorAddr;
628
629 /* Call SROM API driver and process response */
630 status = Cy_Flash_CallSromApiForFlashWrite(&apiArgs, block);
631 return status;
632 }
633
634 /*******************************************************************************
635 * Function Name: Cy_Flash_EraseSuspend
636 ****************************************************************************//**
637 *
638 * This function suspends an ongoing erase operation. User should not read from a
639 * sector which is suspended from an erase operation. Cy_Flash_ProgramRow function
640 * will return error if invoked on suspended sector.
641 * This function cannot be called on SFLASH. Reports success
642 * or a reason for failure. Does not return until the Erase operation is complete.
643 * Returns immediately and reports a CY_FLASH_DRV_IPC_BUSY error in the case when another
644 * process is operating flash.
645 * This function supports only blocking mode for now.
646 *
647 * Returns the status of the Flash operation (see cy_en_flashdrv_status_t).
648 *
649 *******************************************************************************/
Cy_Flash_EraseSuspend(void)650 cy_en_flashdrv_status_t Cy_Flash_EraseSuspend(void)
651 {
652 /* Prepares arguments to be passed to SROM API */
653 un_srom_api_args_t apiArgs = {{ 0UL }};
654 apiArgs.EraseSuspend.arg0.opcode = (uint32_t)CY_SROM_OP_FLASH_ERASE_SUSPEND;
655
656 /* Call SROM API with blocking mode */
657 un_srom_api_resps_t apiResp = {{ 0UL }};
658 cy_en_srom_driver_status_t sromDrvStatus;
659 sromDrvStatus = Cy_Srom_CallApi(&apiArgs, &apiResp);
660 if(sromDrvStatus == CY_SROM_DR_IPC_BUSY)
661 {
662 return CY_FLASH_DRV_IPC_BUSY;
663 }
664 else if(sromDrvStatus == CY_SROM_DR_TIMEOUT)
665 {
666 return CY_FLASH_DRV_SROM_API_TIMEOUT;
667 }
668 else if(sromDrvStatus == CY_SROM_DR_API_UNKNOWN)
669 {
670 return CY_FLASH_DRV_ERR_UNC;
671 }
672 else
673 {
674 /* non-empty terminating "else" statement. */
675 }
676
677 /* Process response message from API */
678 cy_en_flashdrv_status_t result;
679 result = Cy_Flash_ProcessOpcode(apiResp.resp[0]);
680 if(result == CY_FLASH_DRV_SUCCESS)
681 {
682 /* Invalidates the flash cache and buffer */
683 FLASHC_FLASH_CMD = _VAL2FLD(FLASHC_FLASH_CMD_INV, 1U);
684
685 // Wait for completion (HW will clear bit)
686 while (_FLD2VAL(FLASHC_FLASH_CMD_INV, FLASHC_FLASH_CMD) != 0U)
687 {
688 }
689 }
690 return result;
691 }
692
693 /*******************************************************************************
694 * Function Name: Cy_Flash_EraseResume
695 ****************************************************************************//**
696 *
697 * This function calls to resume a suspended erase operation.
698 * Reports success or a reason for failure.
699 * Returns immediately and reports a CY_FLASH_DRV_IPC_BUSY error in the case when another
700 * process is operating flash.
701 *
702 * config configuration of this function.
703 * This parameter is defined by the cy_stc_flash_eraseresume_config_t
704 * in group_flash_srom_config_structure macro.
705 *
706 * Returns the status of the Flash operation (see cy_en_flashdrv_status_t).
707 *
708 *******************************************************************************/
Cy_Flash_EraseResume(const cy_stc_flash_eraseresume_config_t * config)709 cy_en_flashdrv_status_t Cy_Flash_EraseResume(const cy_stc_flash_eraseresume_config_t *config)
710 {
711 /* Checks if input pointers are not NULL */
712 if (config == NULL)
713 {
714 return (cy_en_flashdrv_status_t)CY_FLASH_DRV_INVALID_INPUT_PARAMETERS;
715 }
716 /* Prepares arguments to be passed to SROM API */
717 un_srom_api_args_t apiArgs = {{ 0UL }};
718 apiArgs.EraseResume.arg0.opcode = (uint32_t)CY_SROM_OP_FLASH_ERASE_RESUME;
719 apiArgs.EraseResume.arg0.blocking = (uint32_t)config->intrMask;
720 apiArgs.EraseResume.arg0.intrmask = (uint32_t)config->blocking;
721
722 /* Call SROM API with blocking mode */
723 un_srom_api_resps_t apiResp = {{ 0UL }};
724 cy_en_srom_driver_status_t sromDrvStatus;
725 sromDrvStatus = Cy_Srom_CallApi(&apiArgs, &apiResp);
726 if(sromDrvStatus == CY_SROM_DR_IPC_BUSY)
727 {
728 return CY_FLASH_DRV_IPC_BUSY;
729 }
730 else if(sromDrvStatus == CY_SROM_DR_TIMEOUT)
731 {
732 return CY_FLASH_DRV_SROM_API_TIMEOUT;
733 }
734 else if(sromDrvStatus == CY_SROM_DR_API_UNKNOWN)
735 {
736 return CY_FLASH_DRV_ERR_UNC;
737 }
738 else
739 {
740 /* Process response message from API */
741 cy_en_flashdrv_status_t result;
742 result = Cy_Flash_ProcessOpcode(apiResp.resp[0]);
743 return result;
744 }
745 }
746
747
748 /*******************************************************************************
749 * Function Name: Cy_Flash_BlankCheck
750 ****************************************************************************//**
751 *
752 * This function performs blank check on the addressed work FLASH.
753 * Reports success or a reason for failure.
754 * Returns immediately and reports a CY_FLASH_DRV_IPC_BUSY error in the case when another
755 * process is operating flash.
756 *
757 * config configuration of this function.
758 * This parameter is defined by the cy_stc_flash_blankcheck_config_t
759 * in group_flash_srom_config_structure macro.
760 *
761 * Returns the status of the Flash operation (see cy_en_flashdrv_status_t).
762 *
763 *******************************************************************************/
Cy_Flash_BlankCheck(const cy_stc_flash_blankcheck_config_t * config,cy_en_flash_driver_blocking_t block)764 cy_en_flashdrv_status_t Cy_Flash_BlankCheck(const cy_stc_flash_blankcheck_config_t *config, cy_en_flash_driver_blocking_t block)
765 {
766 /* Checks if input pointers are not NULL */
767 if (config == NULL)
768 {
769 return (cy_en_flashdrv_status_t)CY_FLASH_DRV_INVALID_INPUT_PARAMETERS;
770 }
771
772 if(config->numOfWordsToBeChecked == 0UL)
773 {
774 return CY_FLASH_DRV_INVALID_INPUT_PARAMETERS;
775 }
776 /* Checks if input address are valid */
777 if ((Cy_Flash_WorkBoundsCheck((uint32_t)config->addrToBeChecked) == CY_FLASH_OUT_OF_BOUNDS) ||
778 (Cy_Flash_WorkBoundsCheck((uint32_t)config->addrToBeChecked + config->numOfWordsToBeChecked*4UL - 1UL) == CY_FLASH_OUT_OF_BOUNDS))
779 {
780 return CY_FLASH_DRV_INVALID_INPUT_PARAMETERS;
781 }
782
783 /* Prepares arguments to be passed to SROM API */
784 un_srom_api_args_t apiArgs = {{ 0UL }};
785 apiArgs.BlankCheck.arg0.opcode = (uint32_t)CY_SROM_OP_FLASH_BLANK_CHECK;
786 apiArgs.BlankCheck.arg1.addrToBeChecked = (uint32_t)config->addrToBeChecked;
787 apiArgs.BlankCheck.arg2.numOfWordsToBeChecked = (config->numOfWordsToBeChecked - 1UL);
788
789 /* Tries to acquire the IPC structure and pass the arguments to SROM API */
790 if(block == CY_FLASH_DRIVER_BLOCKING)
791 {
792 /* Call SROM API with blocking mode */
793 un_srom_api_resps_t apiResp = {{ 0UL }};
794 cy_en_srom_driver_status_t sromDrvStatus;
795 sromDrvStatus = Cy_Srom_CallApi(&apiArgs, &apiResp);
796 if(sromDrvStatus == CY_SROM_DR_IPC_BUSY)
797 {
798 return CY_FLASH_DRV_IPC_BUSY;
799 }
800 else if(sromDrvStatus == CY_SROM_DR_TIMEOUT)
801 {
802 return CY_FLASH_DRV_SROM_API_TIMEOUT;
803 }
804 else if(sromDrvStatus == CY_SROM_DR_API_UNKNOWN)
805 {
806 return CY_FLASH_DRV_ERR_UNC;
807 }
808 else
809 {
810 /* Process response message from API */
811 cy_en_flashdrv_status_t result;
812 result = Cy_Flash_ProcessOpcode(apiResp.resp[0]);
813 return result;
814 }
815 }
816 else
817 {
818 g_non_block_context = (uint8_t)FLASHC_FM_CTL_ECT_STATUS_BLANK_CHECK_WORK_Msk;
819 /* Send message by IPC */
820 cy_en_srom_driver_status_t status = Cy_Srom_CallApi_NonBlock(&apiArgs);
821 if (status != CY_SROM_DR_SUCCEEDED)
822 {
823 /* The IPC structure is already locked by another process */
824 return CY_FLASH_DRV_IPC_BUSY;
825 }
826 return CY_FLASH_DRV_SUCCESS;
827 }
828 }
829
830 /*******************************************************************************
831 * Function Name: Cy_Flashc_InjectECC
832 ****************************************************************************//**
833 *
834 * This function enables ECC injection and sets the address where a parity will be injected
835 * and the parity value.
836 * Reports success or a reason for failure.
837 *
838 * region An indicator which region (Code/Work/Cache) ECC parity will be injected to.
839 * This parameter is defined by the cy_en_region_t
840 * in group_flash_macro macro.
841 *
842 * address The address where ECC parity will be injected.
843 *
844 * parity The parity value which will be injected.
845 *
846 * Returns the status of the Flash operation (see cy_en_flashdrv_status_t).
847 *
848 *******************************************************************************/
Cy_Flashc_InjectECC(cy_en_region_t region,uint32_t address,uint8_t parity)849 cy_en_flashdrv_status_t Cy_Flashc_InjectECC(cy_en_region_t region, uint32_t address, uint8_t parity)
850 {
851 cy_en_flashdrv_status_t result =CY_FLASH_DRV_SUCCESS;
852
853 switch(region)
854 {
855 case CY_FLASH_MAIN_REGION:
856 if (Cy_Flash_MainBoundsCheck(address) == CY_FLASH_OUT_OF_BOUNDS)
857 {
858 return CY_FLASH_DRV_INVALID_INPUT_PARAMETERS;
859 }
860 FLASHC_FLASH_CTL |= _VAL2FLD(FLASHC_FLASH_CTL_MAIN_ECC_INJ_EN, 1U);
861 FLASHC_ECC_CTL = (_VAL2FLD(FLASHC_ECC_CTL_WORD_ADDR, address) |
862 _VAL2FLD(FLASHC_ECC_CTL_PARITY, parity ));
863 break;
864 case CY_FLASH_WORK_REGION:
865 if (Cy_Flash_WorkBoundsCheck(address) == CY_FLASH_OUT_OF_BOUNDS)
866 {
867 return CY_FLASH_DRV_INVALID_INPUT_PARAMETERS;
868 }
869 FLASHC_FLASH_CTL |= _VAL2FLD(FLASHC_FLASH_CTL_WORK_ECC_INJ_EN, 1U);
870 FLASHC_ECC_CTL = (_VAL2FLD(FLASHC_ECC_CTL_WORD_ADDR, address) |
871 _VAL2FLD(FLASHC_ECC_CTL_PARITY, parity ));
872 break;
873 case CY_FLASH_CA_CM0P_REGION:
874 if (Cy_Flash_MainBoundsCheck(address) == CY_FLASH_OUT_OF_BOUNDS)
875 {
876 return CY_FLASH_DRV_INVALID_INPUT_PARAMETERS;
877 }
878 FLASHC_FLASH_CTL |= _VAL2FLD(FLASHC_CM0_CA_CTL0_RAM_ECC_INJ_EN, 1U);
879 FLASHC_ECC_CTL = (_VAL2FLD(FLASHC_ECC_CTL_WORD_ADDR, address) |
880 _VAL2FLD(FLASHC_ECC_CTL_PARITY, parity ));
881 break;
882 default:
883 // Default case. Nothing to do.
884 break;
885 }
886
887 return result;
888 }
889
890 /*******************************************************************************
891 * Function Name: Cy_Flash_OperationStatus
892 ****************************************************************************//**
893 *
894 * Checks the status of the Flash Operation, and returns it.
895 *
896 *******************************************************************************/
Cy_Flash_OperationStatus(void)897 cy_en_flashdrv_status_t Cy_Flash_OperationStatus(void)
898 {
899 un_srom_api_resps_t resp = {{ 0UL }};
900 if(0UL != (FLASHC_FM_CTL_ECT_FLASH_STATUS & g_non_block_context))
901 {
902 return CY_FLASH_DRV_OPERATION_STARTED;
903 }
904 else
905 {
906 g_non_block_context = 0;
907 cy_en_srom_api_status_t status = Cy_Srom_GetApiResponse(&resp);
908 if(CY_SROM_STATUS_SUCCESS == status)
909 {
910 return Cy_Flash_ProcessOpcode(resp.resp[0]);
911 }
912 else
913 {
914 return CY_FLASH_DRV_ERR_UNC;
915 }
916
917 }
918 }
919
920 /*******************************************************************************
921 * Function Name: Cy_Flash_StartWrite
922 ****************************************************************************//**
923 *
924 * Starts programming the flash row with
925 * the input data. Returns immediately and reports a successful start
926 * or reason for failure. Reports a \ref CY_FLASH_DRV_IPC_BUSY error
927 * in the case when another process is writing to flash. User
928 * firmware should not enter the Hibernate or Deep-Sleep mode until
929 * flash Write is complete. The Flash operation is allowed in Sleep mode.
930 * During the flash operation, the device should not be reset, including the
931 * XRES pin, a software reset, and watchdog reset sources. Also, the low-voltage
932 * detect circuits should be configured to generate an interrupt instead of a reset.
933 * Otherwise, portions of flash may undergo unexpected changes.
934 * \note Before reading data from previously programmed/erased flash rows, the
935 * user must clear the flash cache with the Cy_SysLib_ClearFlashCacheAndBuffer()
936 * function.
937 *
938 * rowAddr Address of the flash row number.
939 * The Read-while-Write violation occurs when the flash read operation is
940 * initiated in the same flash sector where the flash write operation is
941 * performing. Refer to the device datasheet for the details.
942 * Address must match row start address.
943 *
944 * data The pointer to the data to be written to flash. The size
945 * of the data array must be equal to the flash row size. The flash row size for
946 * the selected device is defined by the \ref CY_FLASH_SIZEOF_ROW macro. Refer to
947 * the device datasheet for the details.
948 *
949 * Returns the status of the Flash operation,
950 * see \ref cy_en_flashdrv_status_t.
951 *
952 *******************************************************************************/
Cy_Flash_StartWrite(uint32_t rowAddr,const uint32_t * data)953 cy_en_flashdrv_status_t Cy_Flash_StartWrite(uint32_t rowAddr, const uint32_t* data)
954 {
955 cy_en_flashdrv_status_t result = CY_FLASH_DRV_INVALID_INPUT_PARAMETERS;
956 uint32_t prog_length = (uint32_t)ADDRESS_LENGTH_32_BIT;
957 uint32_t data_length = (uint32_t)DATA_LENGTH_32_BIT;
958 if (data == NULL)
959 {
960 return CY_FLASH_DRV_INVALID_INPUT_PARAMETERS;
961 }
962 else
963 {
964
965 cy_stc_flash_programrow_config_t flash_programrow_config =
966 {
967 .destAddr = (const uint32_t *)rowAddr,
968 .dataAddr = (const uint32_t *)data,
969 .blocking = CY_FLASH_PROGRAMROW_NON_BLOCKING,
970 .skipBC = CY_FLASH_PROGRAMROW_SKIP_BLANK_CHECK,
971 .dataSize = CY_FLASH_PROGRAMROW_DATA_SIZE_32BIT,
972 .dataLoc = CY_FLASH_PROGRAMROW_DATA_LOCATION_SRAM,
973 .intrMask = CY_FLASH_PROGRAMROW_SET_INTR_MASK,
974 };
975 /* Checks whether the input parameters are valid */
976 if(Cy_Flash_WorkBoundsCheck(rowAddr) == CY_FLASH_IN_BOUNDS)
977 {
978 flash_programrow_config.dataSize = CY_FLASH_PROGRAMROW_DATA_SIZE_32BIT;
979 }
980 else if(Cy_Flash_MainBoundsCheck(rowAddr) == CY_FLASH_IN_BOUNDS)
981 {
982 prog_length = ADDRESS_LENGTH_256_BIT;
983 data_length = DATA_LENGTH_256_BIT;
984 flash_programrow_config.dataSize = CY_FLASH_PROGRAMROW_DATA_SIZE_256BIT;
985 }
986 else
987 {
988 /* non-empty terminating "else" statement */
989 }
990
991 for(uint32_t i_addr = rowAddr; i_addr < rowAddr + CY_FLASH_SIZEOF_ROW; i_addr+=prog_length)
992 {
993 flash_programrow_config.destAddr = (const uint32_t *)i_addr;
994 flash_programrow_config.dataAddr = (const uint32_t *)(data);
995 g_non_block_context = (uint8_t)(FLASHC_FM_CTL_ECT_STATUS_PGM_WORK_Msk | FLASHC_FM_CTL_ECT_STATUS_PGM_CODE_Msk);
996 result = Cy_Flash_Program(&flash_programrow_config,CY_FLASH_DRIVER_NON_BLOCKING);
997 if(result == CY_FLASH_DRV_OPERATION_STARTED)
998 {
999 while((Cy_Flash_IsOperationComplete() != CY_FLASH_DRV_SUCCESS))
1000 {
1001 }
1002 data+=data_length;
1003 }
1004 else
1005 {
1006 return result;
1007 }
1008 }
1009 }
1010 return CY_FLASH_DRV_OPERATION_STARTED;
1011 }
1012
1013 /*******************************************************************************
1014 * Function Name: Cy_Flash_StartEraseSector
1015 ****************************************************************************//**
1016 *
1017 * Starts erasing a sector of flash. Returns immediately
1018 * and reports a successful start or reason for failure.
1019 * Reports a CY_FLASH_DRV_IPC_BUSY error in the case when IPC structure is locked
1020 * by another process. User firmware should not enter the Hibernate or Deep Sleep mode until
1021 * flash Erase is complete. The Flash operation is allowed in Sleep mode.
1022 * During the flash operation, the device should not be reset, including the
1023 * XRES pin, a software reset, and watchdog reset sources. Also, the low-voltage
1024 * detect circuits should be configured to generate an interrupt instead of a reset.
1025 * Otherwise, portions of flash may undergo unexpected changes.
1026 * Before reading data from previously programmed/erased flash rows, the
1027 * user must clear the flash cache with the Cy_SysLib_ClearFlashCacheAndBuffer()
1028 * function.
1029 *
1030 *
1031 *******************************************************************************/
Cy_Flash_StartEraseSector(uint32_t sectorAddr)1032 cy_en_flashdrv_status_t Cy_Flash_StartEraseSector(uint32_t sectorAddr)
1033 {
1034 cy_en_flashdrv_status_t result = CY_FLASH_DRV_INVALID_INPUT_PARAMETERS;
1035
1036 /* Checks whether the input parameters are valid */
1037 if(Cy_Flash_BoundsCheck((uint32_t)(sectorAddr)) == CY_FLASH_OUT_OF_BOUNDS)
1038 {
1039 return CY_FLASH_DRV_INVALID_INPUT_PARAMETERS;
1040 }
1041 cy_stc_flash_erasesector_config_t flash_erasesector_config =
1042 {
1043 .sectorAddr = (const uint32_t *)sectorAddr,
1044 .blocking = CY_FLASH_ERASESECTOR_NON_BLOCKING,
1045 .intrMask = CY_FLASH_ERASESECTOR_SET_INTR_MASK,
1046 };
1047 g_non_block_context = (uint8_t)(FLASHC_FM_CTL_ECT_STATUS_ERASE_CODE_Msk | FLASHC_FM_CTL_ECT_STATUS_ERASE_WORK_Msk);
1048 result = Cy_Flash_EraseSector_Ext(&flash_erasesector_config, CY_FLASH_DRIVER_NON_BLOCKING);
1049 if(result != CY_FLASH_DRV_SUCCESS)
1050 {
1051 return result;
1052 }
1053
1054 return CY_FLASH_DRV_OPERATION_STARTED;
1055 }
1056
1057 /*******************************************************************************
1058 * Function Name: Cy_Flash_ProgramRow
1059 ****************************************************************************//**
1060 *
1061 * This function writes an array of data to a single row of flash. Reports
1062 * success or a reason for failure. Does not return until the Program operation
1063 * is complete.
1064 * Returns immediately and reports a \ref CY_FLASH_DRV_IPC_BUSY error in the case
1065 * when another process is writing to flash. User firmware should not enter the
1066 * Hibernate or Deep-sleep mode until flash Write is complete. The Flash operation
1067 * is allowed in Sleep mode. During the Flash operation, the device should not be
1068 * reset, including the XRES pin, a software reset, and watchdog reset sources.
1069 * Also, low-voltage detect circuits should be configured to generate an interrupt
1070 * instead of a reset. Otherwise, portions of flash may undergo unexpected
1071 * changes.\n
1072 * Before calling this function, the target flash region must be erased by
1073 * the StartErase/EraseRow function.\n
1074 * Data to be programmed must be located in the SRAM memory region.
1075 * \note Before reading data from previously programmed/erased flash rows, the
1076 * user must clear the flash cache with the Cy_SysLib_ClearFlashCacheAndBuffer()
1077 * function.
1078 *
1079 *******************************************************************************/
Cy_Flash_ProgramRow(uint32_t rowAddr,const uint32_t * data)1080 cy_en_flashdrv_status_t Cy_Flash_ProgramRow(uint32_t rowAddr, const uint32_t* data)
1081 {
1082 cy_en_flashdrv_status_t result = CY_FLASH_DRV_INVALID_INPUT_PARAMETERS;
1083 uint32_t prog_length = (uint32_t)ADDRESS_LENGTH_32_BIT;
1084 uint32_t data_length = (uint32_t)DATA_LENGTH_32_BIT;
1085
1086 if (data == NULL)
1087 {
1088 return CY_FLASH_DRV_INVALID_INPUT_PARAMETERS;
1089 }
1090 cy_stc_flash_programrow_config_t flash_programrow_config =
1091 {
1092 .destAddr = (const uint32_t *)rowAddr,
1093 .dataAddr = (const uint32_t *)data,
1094 .blocking = CY_FLASH_PROGRAMROW_BLOCKING,
1095 .skipBC = CY_FLASH_PROGRAMROW_SKIP_BLANK_CHECK,
1096 .dataSize = CY_FLASH_PROGRAMROW_DATA_SIZE_32BIT,
1097 .dataLoc = CY_FLASH_PROGRAMROW_DATA_LOCATION_SRAM,
1098 .intrMask = CY_FLASH_PROGRAMROW_NOT_SET_INTR_MASK,
1099 };
1100 /* Checks whether the input parameters are valid */
1101 if(Cy_Flash_WorkBoundsCheck(rowAddr) == CY_FLASH_IN_BOUNDS)
1102 {
1103 flash_programrow_config.dataSize = CY_FLASH_PROGRAMROW_DATA_SIZE_32BIT;
1104 }
1105 else if(Cy_Flash_MainBoundsCheck(rowAddr) == CY_FLASH_IN_BOUNDS)
1106 {
1107 prog_length = ADDRESS_LENGTH_256_BIT;
1108 data_length = DATA_LENGTH_256_BIT;
1109 flash_programrow_config.dataSize = CY_FLASH_PROGRAMROW_DATA_SIZE_256BIT;
1110 }
1111 else
1112 {
1113 /* empty else statement. */
1114 }
1115 for(uint32_t i_addr = rowAddr; i_addr < rowAddr + CY_FLASH_SIZEOF_ROW; i_addr+=prog_length)
1116 {
1117 flash_programrow_config.destAddr = (const uint32_t *)i_addr;
1118 flash_programrow_config.dataAddr = (const uint32_t *)(data);
1119 result = Cy_Flash_Program(&flash_programrow_config, CY_FLASH_DRIVER_BLOCKING);
1120 if(result != CY_FLASH_DRV_SUCCESS)
1121 {
1122 break;
1123 }
1124 data+=data_length;
1125 }
1126 return (result);
1127 }
1128
1129 /*******************************************************************************
1130 * Function Name: Cy_Flash_EraseSector
1131 ****************************************************************************//**
1132 *
1133 * This function erases a sector of flash. Reports success or
1134 * a reason for failure. Does not return until the Erase operation is
1135 * complete. Returns immediately and reports a \ref CY_FLASH_DRV_IPC_BUSY error in
1136 * the case when another process is writing to flash or erasing the row.
1137 * User firmware should not enter the Hibernate or Deep Sleep mode until flash Erase
1138 * is complete. The Flash operation is allowed in Sleep mode.
1139 * During the Flash operation, the device should not be reset, including the
1140 * XRES pin, a software reset, and watchdog reset sources. Also, low-voltage
1141 * detect circuits should be configured to generate an interrupt instead of a
1142 * reset. Otherwise, portions of flash may undergo unexpected changes.
1143 *
1144 * \param sectorAddr Address of the flash row number.
1145 * The Read-while-Write violation occurs when the flash read operation is
1146 * initiated in the same flash sector where the flash write operation is
1147 * performing. Refer to the device datasheet for the details.
1148 * Address must match row start address.
1149 *
1150 * \return Returns the status of the Flash operation,
1151 * see \ref cy_en_flashdrv_status_t.
1152 *
1153 *******************************************************************************/
Cy_Flash_EraseSector(uint32_t sectorAddr)1154 cy_en_flashdrv_status_t Cy_Flash_EraseSector(uint32_t sectorAddr)
1155 {
1156 cy_en_flashdrv_status_t result = CY_FLASH_DRV_INVALID_INPUT_PARAMETERS;
1157
1158 /* Checks whether the input parameters are valid */
1159 if(Cy_Flash_BoundsCheck((uint32_t)(sectorAddr)) == CY_FLASH_OUT_OF_BOUNDS)
1160 {
1161 return CY_FLASH_DRV_INVALID_INPUT_PARAMETERS;
1162 }
1163 cy_stc_flash_erasesector_config_t flash_erasesector_config =
1164 {
1165 .sectorAddr = (const uint32_t *)sectorAddr,
1166 .blocking = CY_FLASH_ERASESECTOR_BLOCKING,
1167 .intrMask = CY_FLASH_ERASESECTOR_NOT_SET_INTR_MASK,
1168 };
1169 result = Cy_Flash_EraseSector_Ext(&flash_erasesector_config, CY_FLASH_DRIVER_BLOCKING);
1170
1171 return (result);
1172 }
1173
1174 /*******************************************************************************
1175 * Function Name: Cy_Flash_CalculateHash
1176 ****************************************************************************//**
1177 *
1178 * Returns a hash value of the specified region of flash.
1179 *
1180 *******************************************************************************/
Cy_Flash_CalculateHash(const uint32_t * data,uint32_t numberOfBytes,uint32_t * hashPtr)1181 cy_en_flashdrv_status_t Cy_Flash_CalculateHash(const uint32_t* data, uint32_t numberOfBytes, uint32_t* hashPtr)
1182 {
1183 cy_en_flashdrv_status_t result = CY_FLASH_DRV_INVALID_INPUT_PARAMETERS;
1184
1185 /* Checks whether the input parameters are valid */
1186 if ((data == NULL) || (numberOfBytes == 0UL) || (hashPtr == NULL))
1187 {
1188 return CY_FLASH_DRV_INVALID_INPUT_PARAMETERS;
1189 }
1190 cy_stc_flash_computehash_config_t flash_computehash_config =
1191 {
1192 .startAddr = (const uint32_t *)data,
1193 .numOfByte = numberOfBytes,
1194 .type = CY_FLASH_COMPUTEHASH_BASIC,
1195 };
1196 result = Cy_Flash_CalculateHash_Ext(&flash_computehash_config, hashPtr);
1197
1198 return (result);
1199 }
1200
1201 /*******************************************************************************
1202 * Function Name: Cy_Flash_RowChecksum
1203 ****************************************************************************//**
1204 *
1205 * Returns a checksum value of the specified flash row.
1206 *
1207 * \note Now Cy_Flash_RowChecksum() requires the row <b>address</b> (rowAddr)
1208 * as a parameter. In previous versions of the driver, this function used
1209 * the row <b>number</b> (rowNum) for this parameter.
1210 *
1211 * rowAddr The address of the flash row.
1212 *
1213 * checksumPtr The pointer to the address where checksum is to be stored
1214 *
1215 * Returns the status of the Flash operation.
1216 *
1217 *******************************************************************************/
Cy_Flash_RowChecksum(uint32_t rowAddr,uint32_t * checksumPtr)1218 cy_en_flashdrv_status_t Cy_Flash_RowChecksum(uint32_t rowAddr, uint32_t* checksumPtr)
1219 {
1220 cy_en_flashdrv_status_t result = CY_FLASH_DRV_INVALID_INPUT_PARAMETERS;
1221 uint8_t rowID = 0;
1222 cy_en_flash_checksum_bank_t bank = CY_FLASH_CHECKSUM_BANK0;
1223 cy_en_flash_checksum_region_t region = CY_FLASH_CHECKSUM_MAIN;
1224
1225 /* Checks whether the input parameters are valid */
1226 if ((Cy_Flash_BoundsCheck(rowAddr)== CY_FLASH_OUT_OF_BOUNDS) || (checksumPtr == NULL))
1227 {
1228 return CY_FLASH_DRV_INVALID_INPUT_PARAMETERS;
1229 }
1230 if (CY_FLASH_DRV_SUCCESS == Cy_Flash_GetRowDetails(rowAddr,&rowID, &bank, ®ion))
1231 {
1232 cy_stc_flash_checksum_config_t flash_computechecksum_config =
1233 {
1234 .rowId = rowID,
1235 .bank = bank,
1236 .whole = CY_FLASH_CHECKSUM_PAGE,
1237 .region = region,
1238 };
1239 result = Cy_Flash_Checksum(&flash_computechecksum_config, checksumPtr);
1240 }
1241
1242 return (result);
1243 }
1244
1245 /*******************************************************************************
1246 * Function Name: Cy_Flash_GetRowDetails
1247 ****************************************************************************//**
1248 *
1249 * Returns flash region ID, Bank and row number of the Flash address.
1250 *******************************************************************************/
Cy_Flash_GetRowDetails(uint32_t rowAddr,uint8_t * rowID,cy_en_flash_checksum_bank_t * bank,cy_en_flash_checksum_region_t * region)1251 static cy_en_flashdrv_status_t Cy_Flash_GetRowDetails(uint32_t rowAddr, uint8_t *rowID, cy_en_flash_checksum_bank_t *bank, cy_en_flash_checksum_region_t *region)
1252 {
1253 cy_en_flashdrv_status_t result = CY_FLASH_DRV_SUCCESS;
1254 if (Cy_Flash_WorkBoundsCheck(rowAddr) == CY_FLASH_OUT_OF_BOUNDS)
1255 {
1256 return CY_FLASH_DRV_INVALID_INPUT_PARAMETERS;
1257 }
1258 cy_en_bankmode_t bankmode = Cy_Flashc_GetMainBankMode();
1259 if(bankmode == CY_FLASH_SINGLE_BANK_MODE)
1260 {
1261
1262 if ((rowAddr >= CY_WFLASH_LG_SBM_TOP) && (rowAddr < CY_WFLASH_SM_SBM_END))
1263 {
1264 *rowID = (uint8_t)((CY_FLASH_REGION_ID_WFLASH << CY_FLASH_REGION_ID_SHIFT) |
1265 ((rowAddr - CY_WFLASH_LG_SBM_TOP) / CY_FLASH_SIZEOF_ROW));
1266 *bank = CY_FLASH_CHECKSUM_BANK0;
1267 *region = CY_FLASH_CHECKSUM_WORK;
1268 }
1269 else if ((rowAddr >= CY_FLASH_LG_SBM_TOP) && (rowAddr < CY_FLASH_SM_SBM_END))
1270 {
1271 *rowID = (uint8_t)((CY_FLASH_REGION_ID_WFLASH << CY_FLASH_REGION_ID_SHIFT) |
1272 ((rowAddr - CY_WFLASH_LG_SBM_TOP) / CY_FLASH_SIZEOF_ROW));
1273 *bank = CY_FLASH_CHECKSUM_BANK0;
1274 *region = CY_FLASH_CHECKSUM_MAIN;
1275 }
1276 else
1277 {
1278 /* rowAddr oout of bounds. */
1279 }
1280 }
1281 else
1282 {
1283 if ((rowAddr >= CY_WFLASH_LG_DBM0_TOP) && (rowAddr < CY_WFLASH_SM_DBM0_END))
1284 {
1285 *rowID = (uint8_t)((CY_FLASH_REGION_ID_WFLASH << CY_FLASH_REGION_ID_SHIFT) |
1286 ((rowAddr - CY_WFLASH_LG_DBM0_TOP) / CY_FLASH_SIZEOF_ROW));
1287 *bank = CY_FLASH_CHECKSUM_BANK0;
1288 *region = CY_FLASH_CHECKSUM_WORK;
1289 }
1290 else if ((rowAddr >= CY_WFLASH_LG_DBM1_TOP) && (rowAddr < CY_WFLASH_SM_DBM1_END))
1291 {
1292 *rowID = (uint8_t)((CY_FLASH_REGION_ID_WFLASH << CY_FLASH_REGION_ID_SHIFT) |
1293 ((rowAddr - CY_WFLASH_LG_SBM_TOP) / CY_FLASH_SIZEOF_ROW));
1294 *bank = CY_FLASH_CHECKSUM_BANK1;
1295 *region = CY_FLASH_CHECKSUM_WORK;
1296 }
1297 else if ((rowAddr >= CY_FLASH_LG_DBM0_TOP) && (rowAddr < CY_FLASH_SM_DBM0_END))
1298 {
1299 *rowID = (uint8_t)((CY_FLASH_REGION_ID_MAIN << CY_FLASH_REGION_ID_SHIFT) |
1300 ((rowAddr - CY_FLASH_LG_DBM0_TOP) / CY_FLASH_SIZEOF_ROW));
1301 *bank = CY_FLASH_CHECKSUM_BANK0;
1302 *region = CY_FLASH_CHECKSUM_MAIN;
1303 }
1304 else if ((rowAddr >= CY_FLASH_LG_DBM1_TOP) && (rowAddr < CY_FLASH_SM_DBM1_END))
1305 {
1306 *rowID = (uint8_t)((CY_FLASH_REGION_ID_MAIN << CY_FLASH_REGION_ID_SHIFT) |
1307 ((rowAddr - CY_FLASH_LG_DBM1_TOP) / CY_FLASH_SIZEOF_ROW));
1308 *bank = CY_FLASH_CHECKSUM_BANK1;
1309 *region = CY_FLASH_CHECKSUM_MAIN;
1310 }
1311 else
1312 {
1313 /* rowAddr oout of bounds. */
1314 }
1315
1316 }
1317
1318 return (result);
1319 }
1320
1321 /*******************************************************************************
1322 * Function Name: Cy_Flash_Init
1323 ****************************************************************************//**
1324 *
1325 * Initiates all needed prerequisites to support flash erase/write.
1326 * Should be called from each core.
1327 *
1328 * This function is called in the SystemInit() function, for proper flash write
1329 * and erase operations. If the default startup file is not used, or the function
1330 * SystemInit() is not called in your project, ensure to perform the following steps
1331 * before any flash or EmEEPROM write/erase operations:
1332 *
1333 *******************************************************************************/
Cy_Flash_Init(void)1334 void Cy_Flash_Init(void)
1335 {
1336 /* In Blocking mode the calling function get's the response and sends it to the user.
1337 * In Non blocking mode user will call operation status and gets the response in return.
1338 * There is no need for the driver to handle error in the interrupt handler.
1339 * Error needs to be passed to the user.
1340 */
1341 Cy_Srom_SetResponseHandler(NULL);
1342 }
1343
1344 /*******************************************************************************
1345 * Function Name: Cy_Flash_IsOperationComplete
1346 ****************************************************************************//**
1347 *
1348 * Reports a successful operation result, reason of failure or busy status
1349 * ( CY_FLASH_DRV_OPCODE_BUSY ).
1350 *******************************************************************************/
Cy_Flash_IsOperationComplete(void)1351 cy_en_flashdrv_status_t Cy_Flash_IsOperationComplete(void)
1352 {
1353 return (Cy_Flash_OperationStatus());
1354 }
1355
1356
1357 /*******************************************************************************
1358 * Function Name: Cy_Flashc_MainWriteEnable
1359 ****************************************************************************//**
1360 *
1361 * Enable writing main flash
1362 *
1363 *******************************************************************************/
Cy_Flashc_MainWriteEnable(void)1364 void Cy_Flashc_MainWriteEnable(void)
1365 {
1366 FLASHC_FM_CTL_ECT_MAIN_FLASH_SAFETY |= FLASHC_FM_CTL_ECT_MAIN_FLASH_SAFETY_MAINFLASHWRITEENABLE_Msk;
1367 }
1368
1369 /*******************************************************************************
1370 * Function Name: Cy_Flashc_MainWriteDisable
1371 ****************************************************************************//**
1372 *
1373 * Disable writing main flash
1374 *
1375 *******************************************************************************/
Cy_Flashc_MainWriteDisable(void)1376 void Cy_Flashc_MainWriteDisable(void)
1377 {
1378 FLASHC_FM_CTL_ECT_MAIN_FLASH_SAFETY &= (uint32_t) ~FLASHC_FM_CTL_ECT_MAIN_FLASH_SAFETY_MAINFLASHWRITEENABLE_Msk;
1379 }
1380
1381 /*******************************************************************************
1382 * Function Name: Cy_Flashc_WorkWriteEnable
1383 ****************************************************************************//**
1384 *
1385 * Enable writing work flash
1386 *
1387 *******************************************************************************/
Cy_Flashc_WorkWriteEnable(void)1388 void Cy_Flashc_WorkWriteEnable(void)
1389 {
1390 FLASHC_FM_CTL_ECT_WORK_FLASH_SAFETY |= FLASHC_FM_CTL_ECT_WORK_FLASH_SAFETY_WORKFLASHWRITEENABLE_Msk;
1391 }
1392
1393 /*******************************************************************************
1394 * Function Name: Cy_Flashc_WorkWriteDisable
1395 ****************************************************************************//**
1396 *
1397 * Disable writing work flash
1398 *
1399 *******************************************************************************/
Cy_Flashc_WorkWriteDisable(void)1400 void Cy_Flashc_WorkWriteDisable(void)
1401 {
1402 FLASHC_FM_CTL_ECT_WORK_FLASH_SAFETY &= (uint32_t) ~FLASHC_FM_CTL_ECT_WORK_FLASH_SAFETY_WORKFLASHWRITEENABLE_Msk;
1403 }
1404
1405 /*******************************************************************************
1406 * Function Name: Cy_Flashc_WorkECCEnable
1407 ****************************************************************************//**
1408 *
1409 * Enables ECC for work flash
1410 *
1411 *******************************************************************************/
Cy_Flashc_WorkECCEnable(void)1412 void Cy_Flashc_WorkECCEnable(void)
1413 {
1414 FLASHC_FLASH_CTL |= FLASHC_FLASH_CTL_WORK_ECC_EN_Msk;
1415 }
1416
1417 /*******************************************************************************
1418 * Function Name: Cy_Flashc_WorkECCDisable
1419 ****************************************************************************//**
1420 *
1421 * Disables ECC for work flash
1422 *
1423 *******************************************************************************/
Cy_Flashc_WorkECCDisable(void)1424 void Cy_Flashc_WorkECCDisable(void)
1425 {
1426 FLASHC_FLASH_CTL &= (uint32_t) ~FLASHC_FLASH_CTL_WORK_ECC_EN_Msk;
1427 }
1428
1429 /*******************************************************************************
1430 * Function Name: Cy_Flashc_MainECCEnable
1431 ****************************************************************************//**
1432 *
1433 * Enables ECC for main flash
1434 *
1435 *******************************************************************************/
Cy_Flashc_MainECCEnable(void)1436 void Cy_Flashc_MainECCEnable(void)
1437 {
1438 FLASHC_FLASH_CTL |= FLASHC_FLASH_CTL_MAIN_ECC_EN_Msk;
1439 }
1440
1441 /*******************************************************************************
1442 * Function Name: Cy_Flashc_MainECCDisable
1443 ****************************************************************************//**
1444 *
1445 * Disables ECC for main flash
1446 *
1447 *******************************************************************************/
Cy_Flashc_MainECCDisable(void)1448 void Cy_Flashc_MainECCDisable(void)
1449 {
1450 FLASHC_FLASH_CTL &= (uint32_t) ~FLASHC_FLASH_CTL_MAIN_ECC_EN_Msk;
1451 }
1452
1453 /*******************************************************************************
1454 * Function Name: Cy_Flashc_SetWorkBankMode
1455 ****************************************************************************//**
1456 *
1457 * Sets bank mode for work flash
1458 *
1459 * mode bank mode to be set
1460 *
1461 *******************************************************************************/
Cy_Flashc_SetWorkBankMode(cy_en_bankmode_t mode)1462 void Cy_Flashc_SetWorkBankMode(cy_en_bankmode_t mode)
1463 {
1464 if(CY_FLASH_DUAL_BANK_MODE == mode)
1465 {
1466 FLASHC_FLASH_CTL |= FLASHC_FLASH_CTL_WORK_BANK_MODE_Msk;
1467 }
1468 else
1469 {
1470 FLASHC_FLASH_CTL &= (uint32_t) ~FLASHC_FLASH_CTL_WORK_BANK_MODE_Msk;
1471 }
1472 }
1473
1474 /*******************************************************************************
1475 * Function Name: Cy_Flashc_GetWorkBankMode
1476 ****************************************************************************//**
1477 *
1478 * Gets current bank mode for work flash
1479 *
1480 *******************************************************************************/
Cy_Flashc_GetWorkBankMode(void)1481 cy_en_bankmode_t Cy_Flashc_GetWorkBankMode(void)
1482 {
1483 uint32_t bank_mode = _FLD2VAL(FLASHC_FLASH_CTL_WORK_BANK_MODE, FLASHC_FLASH_CTL);
1484 if(bank_mode == 0UL)
1485 {
1486 return CY_FLASH_SINGLE_BANK_MODE;
1487 }
1488 else
1489 {
1490 return CY_FLASH_DUAL_BANK_MODE;
1491 }
1492 }
1493
1494 /*******************************************************************************
1495 * Function Name: Cy_Flashc_SetMainBankMode
1496 ****************************************************************************//**
1497 *
1498 * Sets bank mode for main flash
1499 *
1500 * mode bank mode to be set
1501 *
1502 *******************************************************************************/
Cy_Flashc_SetMainBankMode(cy_en_bankmode_t mode)1503 void Cy_Flashc_SetMainBankMode(cy_en_bankmode_t mode)
1504 {
1505 if(CY_FLASH_DUAL_BANK_MODE == mode)
1506 {
1507 FLASHC_FLASH_CTL |= FLASHC_FLASH_CTL_MAIN_BANK_MODE_Msk;
1508 }
1509 else
1510 {
1511 FLASHC_FLASH_CTL &= (uint32_t) ~FLASHC_FLASH_CTL_MAIN_BANK_MODE_Msk;
1512 }
1513 }
1514
1515 /*******************************************************************************
1516 * Function Name: Cy_Flashc_GetMainBankMode
1517 ****************************************************************************//**
1518 *
1519 * Gets current bank mode for main flash
1520 *
1521 *******************************************************************************/
Cy_Flashc_GetMainBankMode(void)1522 cy_en_bankmode_t Cy_Flashc_GetMainBankMode(void)
1523 {
1524 uint32_t bank_mode = _FLD2VAL(FLASHC_FLASH_CTL_MAIN_BANK_MODE, FLASHC_FLASH_CTL);
1525 if(bank_mode == 0UL)
1526 {
1527 return CY_FLASH_SINGLE_BANK_MODE;
1528 }
1529 else
1530 {
1531 return CY_FLASH_DUAL_BANK_MODE;
1532 }
1533 }
1534
1535
1536 #endif // defined(CY_IP_MXFLASHC_VERSION_ECT)
1537
1538 /* [] END OF FILE */
1539