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, &region))
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