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