1 /***************************************************************************//**
2 * \file cy_flash.c
3 * \version 3.110
4 *
5 * \brief
6 * Provides the public functions for the API for the PSoC 6 Flash Driver.
7 *
8 ********************************************************************************
9 * \copyright
10 * Copyright 2016-2021 Cypress Semiconductor Corporation
11 * SPDX-License-Identifier: Apache-2.0
12 *
13 * Licensed under the Apache License, Version 2.0 (the "License");
14 * you may not use this file except in compliance with the License.
15 * You may obtain a copy of the License at
16 *
17 *     http://www.apache.org/licenses/LICENSE-2.0
18 *
19 * Unless required by applicable law or agreed to in writing, software
20 * distributed under the License is distributed on an "AS IS" BASIS,
21 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
22 * See the License for the specific language governing permissions and
23 * limitations under the License.
24 *******************************************************************************/
25 
26 #include "cy_device.h"
27 
28 #if ((defined (CY_IP_M4CPUSS) && !defined (CY_IP_MXFLASHC_VERSION_ECT)) || defined (CY_IP_MXS40FLASHC))
29 
30 #include "cy_flash.h"
31 #include "cy_sysclk.h"
32 #include "cy_sysint.h"
33 #include "cy_ipc_drv.h"
34 #include "cy_ipc_sema.h"
35 #include "cy_ipc_pipe.h"
36 #include "cy_syslib.h"
37 #if defined (CY_DEVICE_SECURE)
38     #include "cy_pra.h"
39 #endif /* defined (CY_DEVICE_SECURE) */
40 #if defined (CY_IP_MXS40FLASHC)
41 #include "cyboot_flash_list.h"
42 #endif
43 
44 CY_MISRA_DEVIATE_BLOCK_START('MISRA C-2012 Rule 11.3', 2, \
45 'IPC_STRUCT_Type will typecast to either IPC_STRUCT_V1_Type or IPC_STRUCT_V2_Type but not both on PDL initialization based on the target device at compile time.')
46 
47 /***************************************
48 * Data Structure definitions
49 ***************************************/
50 
51 /* Flash driver context */
52 typedef struct
53 {
54     uint32_t opcode;      /**< Specifies the code of flash operation */
55     uint32_t arg1;        /**< Specifies the configuration of flash operation */
56     uint32_t arg2;        /**< Specifies the configuration of flash operation */
57     uint32_t arg3;        /**< Specifies the configuration of flash operation */
58 } cy_stc_flash_context_t;
59 
60 
61 /***************************************
62 * Macro definitions
63 ***************************************/
64 
65 /** \cond INTERNAL */
66 /** Set SROM API in blocking mode */
67 #define CY_FLASH_BLOCKING_MODE             ((0x01UL) << 8UL)
68 /** Set SROM API in non blocking mode */
69 #define CY_FLASH_NON_BLOCKING_MODE         (0UL)
70 
71 /** SROM API flash region ID shift for flash row information */
72 #define CY_FLASH_REGION_ID_SHIFT           (16U)
73 #define CY_FLASH_REGION_ID_MASK            (3U)
74 #define CY_FLASH_ROW_ID_MASK               (0xFFFFU)
75 /** SROM API flash region IDs */
76 #define CY_FLASH_REGION_ID_MAIN            (0UL)
77 #define CY_FLASH_REGION_ID_EM_EEPROM       (1UL)
78 #define CY_FLASH_REGION_ID_SFLASH          (2UL)
79 
80 /** SROM API opcode mask */
81 #define CY_FLASH_OPCODE_Msk                ((0xFFUL) << 24UL)
82 /** SROM API opcode for flash write operation */
83 #define CY_FLASH_OPCODE_WRITE_ROW          ((0x05UL) << 24UL)
84 /** SROM API opcode for flash program operation */
85 #define CY_FLASH_OPCODE_PROGRAM_ROW        ((0x06UL) << 24UL)
86 /** SROM API opcode for row erase operation */
87 #define CY_FLASH_OPCODE_ERASE_ROW          ((0x1CUL) << 24UL)
88 /** SROM API opcode for sub sector erase operation */
89 #define CY_FLASH_OPCODE_ERASE_SUB_SECTOR   ((0x1DUL) << 24UL)
90 /** SROM API opcode for sector erase operation */
91 #define CY_FLASH_OPCODE_ERASE_SECTOR       ((0x14UL) << 24UL)
92 /** SROM API opcode for flash checksum operation */
93 #define CY_FLASH_OPCODE_CHECKSUM           ((0x0BUL) << 24UL)
94 /** SROM API opcode for flash hash operation */
95 #define CY_FLASH_OPCODE_HASH               ((0x0DUL) << 24UL)
96 /** SROM API flash row shift for flash checksum operation */
97 #define CY_FLASH_OPCODE_CHECKSUM_ROW_SHIFT (8UL)
98 /** SROM API flash row shift for flash checksum operation */
99 #define CY_FLASH_OPCODE_CHECKSUM_REGION_SHIFT (22UL)
100 /** Data to be programmed to flash is located in SRAM memory region */
101 #define CY_FLASH_DATA_LOC_SRAM             (0x100UL)
102 /** SROM API flash verification option for flash write operation */
103 #define CY_FLASH_CONFIG_VERIFICATION_EN    ((0x01UL) << 16u)
104 
105 /** Command completed with no errors */
106 #define CY_FLASH_ROMCODE_SUCCESS                   (0xA0000000UL)
107 /** Invalid device protection state */
108 #define CY_FLASH_ROMCODE_INVALID_PROTECTION        (0xF0000001UL)
109 /** Invalid flash page latch address */
110 #define CY_FLASH_ROMCODE_INVALID_FM_PL             (0xF0000003UL)
111 /** Invalid flash address */
112 #define CY_FLASH_ROMCODE_INVALID_FLASH_ADDR        (0xF0000004UL)
113 /** Row is write protected */
114 #define CY_FLASH_ROMCODE_ROW_PROTECTED             (0xF0000005UL)
115 /** Comparison between Page Latches and FM row failed */
116 #define CY_FLASH_ROMCODE_PL_ROW_COMP_FA            (0xF0000022UL)
117 /** Command in progress; no error */
118 #define CY_FLASH_ROMCODE_IN_PROGRESS_NO_ERROR      (0xA0000009UL)
119 /** Flash operation is successfully initiated */
120 #define CY_FLASH_IS_OPERATION_STARTED              (0x00000010UL)
121 /** Flash is under operation */
122 #define CY_FLASH_IS_BUSY                           (0x00000040UL)
123 /** IPC structure is already locked by another process */
124 #define CY_FLASH_IS_IPC_BUSY                       (0x00000080UL)
125 /** Input parameters passed to Flash API are not valid */
126 #define CY_FLASH_IS_INVALID_INPUT_PARAMETERS       (0x00000100UL)
127 
128 /** Result mask */
129 #define CY_FLASH_RESULT_MASK                       (0x0FFFFFFFUL)
130 /** Error shift */
131 #define CY_FLASH_ERROR_SHIFT                       (28UL)
132 /** No error */
133 #define CY_FLASH_ERROR_NO_ERROR                    (0xAUL)
134 
135 /** CM4 Flash Proxy address */
136 #define CY_FLASH_CM4_FLASH_PROXY_ADDR              (*(Cy_Flash_Proxy *)(0x00000D1CUL))
137 typedef cy_en_flashdrv_status_t (*Cy_Flash_Proxy)(cy_stc_flash_context_t *context);
138 
139 /** IPC notify bit for IPC0 structure (dedicated to flash operation) */
140 #define CY_FLASH_IPC_NOTIFY_STRUCT0                (0x1UL << CY_IPC_INTR_SYSCALL1)
141 
142 /** Disable delay */
143 #define CY_FLASH_NO_DELAY                          (0U)
144 
145 #if !defined (CY_FLASH_RWW_DRV_SUPPORT_DISABLED)
146     /** Number of ticks to wait 1 uS */
147     #define CY_FLASH_TICKS_FOR_1US                     (8U)
148     /** Define to set the IMO to perform a delay after the flash operation started */
149     #define CY_FLASH_TST_DDFT_SLOW_CTL_MASK            (0x00001F1EUL)
150     /** Fast control register */
151     #define CY_FLASH_TST_DDFT_FAST_CTL_MASK            (62U)
152     /** Slow output register - output disabled */
153     #define CY_FLASH_CLK_OUTPUT_DISABLED               (0U)
154 
155     /* The default delay time value */
156     #define CY_FLASH_DEFAULT_DELAY                     (150UL)
157     /* Calculates the time in microseconds to wait for the number of the CM0P ticks */
158     #define CY_FLASH_DELAY_CORRECTIVE(ticks)           (((ticks) * 1000UL) / (Cy_SysClk_ClkSlowGetFrequency() / 1000UL))
159 
160     /* Number of the CM0P ticks for StartProgram function delay corrective time */
161     #define CY_FLASH_START_PROGRAM_DELAY_TICKS         (6000UL)
162     /* Delay time for StartProgram function in us */
163     #define CY_FLASH_START_PROGRAM_DELAY_TIME          (900UL + CY_FLASH_DELAY_CORRECTIVE(CY_FLASH_START_PROGRAM_DELAY_TICKS))
164     /* Number of the CM0P ticks for StartErase functions delay corrective time */
165     #define CY_FLASH_START_ERASE_DELAY_TICKS           (9500UL)
166     /* Delay time for StartErase functions in us */
167     #define CY_FLASH_START_ERASE_DELAY_TIME            (2200UL + CY_FLASH_DELAY_CORRECTIVE(CY_FLASH_START_ERASE_DELAY_TICKS))
168     /* Number of the CM0P ticks for StartWrite function delay corrective time */
169     #define CY_FLASH_START_WRITE_DELAY_TICKS           (19000UL)
170     /* Delay time for StartWrite function in us */
171     #define CY_FLASH_START_WRITE_DELAY_TIME            (9800UL + CY_FLASH_DELAY_CORRECTIVE(CY_FLASH_START_WRITE_DELAY_TICKS))
172 
173     /** Delay time for Start Write function in us with corrective time */
174     #define CY_FLASH_START_WRITE_DELAY                 (CY_FLASH_START_WRITE_DELAY_TIME)
175     /** Delay time for Start Program function in us with corrective time */
176     #define CY_FLASH_START_PROGRAM_DELAY               (CY_FLASH_START_PROGRAM_DELAY_TIME)
177     /** Delay time for Start Erase function in uS with corrective time */
178     #define CY_FLASH_START_ERASE_DELAY                 (CY_FLASH_START_ERASE_DELAY_TIME)
179 
180     #define CY_FLASH_ENTER_WAIT_LOOP                   (0xFFU)
181     #define CY_FLASH_IPC_CLIENT_ID                     (2U)
182 
183     /** Semaphore number reserved for flash driver */
184     #define CY_FLASH_WAIT_SEMA                         (0UL)
185     /* Semaphore check timeout (in tries) */
186     #define CY_FLASH_SEMA_WAIT_MAX_TRIES               (150000UL)
187 #if !defined (CY_IP_MXS40FLASHC)
188     static void Cy_Flash_RAMDelay(uint32_t microseconds);
189 
190     #if (CY_CPU_CORTEX_M0P)
191         #define IS_CY_PIPE_FREE(...)       (!Cy_IPC_Drv_IsLockAcquired(Cy_IPC_Drv_GetIpcBaseAddress(CY_IPC_CHAN_CYPIPE_EP1)))
192         #define NOTIFY_PEER_CORE(a)         Cy_IPC_Pipe_SendMessage(CY_IPC_EP_CYPIPE_CM4_ADDR, CY_IPC_EP_CYPIPE_CM0_ADDR, (a), NULL)
193     #else
194         #define IS_CY_PIPE_FREE(...)       (!Cy_IPC_Drv_IsLockAcquired(Cy_IPC_Drv_GetIpcBaseAddress(CY_IPC_CHAN_CYPIPE_EP0)))
195         #define NOTIFY_PEER_CORE(a)         Cy_IPC_Pipe_SendMessage(CY_IPC_EP_CYPIPE_CM0_ADDR, CY_IPC_EP_CYPIPE_CM4_ADDR, (a), NULL)
196     #endif
197 
198     static void Cy_Flash_NotifyHandler(uint32_t * msgPtr);
199 
200     static cy_stc_flash_notify_t * ipcWaitMessage;
201 #endif /* !defined (CY_IP_MXS40FLASHC) */
202 #else
203     /** Delay time for Start Write function in us with corrective time */
204     #define CY_FLASH_START_WRITE_DELAY                 (CY_FLASH_NO_DELAY)
205     /** Delay time for Start Program function in us with corrective time */
206     #define CY_FLASH_START_PROGRAM_DELAY               (CY_FLASH_NO_DELAY)
207     /** Delay time for Start Erase function in uS with corrective time */
208     #define CY_FLASH_START_ERASE_DELAY                 (CY_FLASH_NO_DELAY)
209 
210 #endif /* !defined (CY_FLASH_RWW_DRV_SUPPORT_DISABLED) */
211 /** \endcond */
212 
213 /* Static functions */
214 static cy_en_flashdrv_status_t Cy_Flash_OperationStatus(void);
215 #if !defined (CY_IP_MXS40FLASHC)
216 static bool Cy_Flash_BoundsCheck(uint32_t flashAddr);
217 static cy_en_flashdrv_status_t Cy_Flash_ProcessOpcode(uint32_t opcode);
218 static uint32_t Cy_Flash_GetRowNum(uint32_t flashAddr);
219 static cy_en_flashdrv_status_t Cy_Flash_SendCmd(uint32_t mode, uint32_t microseconds);
220 static volatile cy_stc_flash_context_t flashContext;
221 #endif
222 
223 #if defined (CY_IP_MXS40FLASHC)
224 
225 #define CYBOOT_FLAGS_BLOCKING 0U
226 #define CYBOOT_FLAGS_NON_BLOCKING 1U
227 
228 static cyboot_flash_context_t boot_rom_context;
229 static cyboot_flash_refresh_t flash_refresh;
230 
231 #define HASH_CALC_DIVISOR 127U
232 #define HASH_CALC_DIVISOR_LEN 7U
233 #define REG8(addr)                      ( *( (volatile uint8_t  *)(addr) ) )
234 
235 static bool refresh_feature_enable;
236 
237 
238 /* To calculate hash */
239 static uint8_t Cy_Flash_GetHash(uint32_t startAddr,uint32_t numberOfBytes);
240 static void Cy_Flash_Callback_PreIRQ(cyboot_flash_context_t *ctx);
241 static void Cy_Flash_Callback_PostIRQ(cyboot_flash_context_t *ctx);
242 static void Cy_Flash_Callback_IRQComplete(cyboot_flash_context_t *ctx);
243 
244 #endif /* defined (CY_IP_MXS40FLASHC) */
245 
246 #if !defined (CY_IP_MXS40FLASHC)
247 #if !defined (CY_FLASH_RWW_DRV_SUPPORT_DISABLED)
248 /*******************************************************************************
249 * Function Name: Cy_Flash_InitExt
250 ****************************************************************************//**
251 *
252 * Initiates all needed prerequisites to support flash erase/write.
253 * Should be called from each core. Defines the address of the message structure.
254 *
255 * Requires a call to Cy_IPC_Sema_Init(), Cy_IPC_Pipe_Config() and
256 * Cy_IPC_Pipe_Init() functions before use.
257 *
258 * This function is called in the Cy_Flash_Init() function - see the
259 * Cy_Flash_Init usage considerations.
260 *
261 *******************************************************************************/
Cy_Flash_InitExt(cy_stc_flash_notify_t * ipcWaitMessageAddr)262 void Cy_Flash_InitExt(cy_stc_flash_notify_t *ipcWaitMessageAddr)
263 {
264     ipcWaitMessage = ipcWaitMessageAddr;
265 
266     if(ipcWaitMessage != NULL)
267     {
268         ipcWaitMessage->clientID = CY_FLASH_IPC_CLIENT_ID;
269         ipcWaitMessage->pktType = CY_FLASH_ENTER_WAIT_LOOP;
270         ipcWaitMessage->intrRelMask = 0U;
271     }
272 
273     if (cy_device->flashRwwRequired != 0U)
274     {
275         #if (CY_CPU_CORTEX_M4)
276             cy_stc_sysint_t flashIntConfig =
277             {
278                 (IRQn_Type)cy_device->cpussFmIrq,   /* .intrSrc */
279                 0U                                  /* .intrPriority */
280             };
281 
282             (void)Cy_SysInt_Init(&flashIntConfig, &Cy_Flash_ResumeIrqHandler);
283             NVIC_EnableIRQ(flashIntConfig.intrSrc);
284         #endif
285 
286             if (cy_device->flashPipeRequired != 0U)
287             {
288                 (void)Cy_IPC_Pipe_RegisterCallback(CY_IPC_EP_CYPIPE_ADDR, &Cy_Flash_NotifyHandler,
289                                                   (uint32_t)CY_FLASH_IPC_CLIENT_ID);
290             }
291     }
292 }
293 
294 
295 /*******************************************************************************
296 * Function Name: Cy_Flash_NotifyHandler
297 ****************************************************************************//**
298 *
299 * This is the interrupt service routine for the pipe notifications.
300 *
301 *******************************************************************************/
302 CY_SECTION_RAMFUNC_BEGIN
303 #if !defined (__ICCARM__)
304     CY_NOINLINE
305 #endif
Cy_Flash_NotifyHandler(uint32_t * msgPtr)306 static void Cy_Flash_NotifyHandler(uint32_t * msgPtr)
307 {
308 #if !((CY_CPU_CORTEX_M0P) && (defined (CY_DEVICE_SECURE)))
309     uint32_t intr;
310 #endif /* !((CY_CPU_CORTEX_M0P) && (defined (CY_DEVICE_SECURE))) */
311     static uint32_t semaIndex;
312     static uint32_t semaMask;
313     static volatile uint32_t *semaPtr;
314     static cy_stc_ipc_sema_t *semaStruct;
315 
316     cy_stc_flash_notify_t *ipcMsgPtr = (cy_stc_flash_notify_t *) (void *) msgPtr;
317 
318     if (CY_FLASH_ENTER_WAIT_LOOP == ipcMsgPtr->pktType)
319     {
320     #if !((CY_CPU_CORTEX_M0P) && (defined (CY_DEVICE_SECURE)))
321         intr = Cy_SysLib_EnterCriticalSection();
322     #endif /* !((CY_CPU_CORTEX_M0P) && (defined (CY_DEVICE_SECURE))) */
323 
324         /* Get pointer to structure */
325         semaStruct = (cy_stc_ipc_sema_t *)Cy_IPC_Drv_ReadDataValue(Cy_IPC_Drv_GetIpcBaseAddress(CY_IPC_CHAN_SEMA));
326 
327         /* Get the index into the semaphore array and calculate the mask */
328         semaIndex = CY_FLASH_WAIT_SEMA / CY_IPC_SEMA_PER_WORD;
329         semaMask = (uint32_t)(1UL << (CY_FLASH_WAIT_SEMA - (semaIndex * CY_IPC_SEMA_PER_WORD) ));
330         semaPtr = &semaStruct->arrayPtr[semaIndex];
331 
332         /* Notification to the Flash driver to start the current operation */
333         *semaPtr |= semaMask;
334 
335         /* Check a notification from other core to end of waiting */
336         while (((*semaPtr) & semaMask) != 0UL)
337         {
338         }
339 
340     #if !((CY_CPU_CORTEX_M0P) && (defined (CY_DEVICE_SECURE)))
341         Cy_SysLib_ExitCriticalSection(intr);
342     #endif /* !((CY_CPU_CORTEX_M0P) && (defined (CY_DEVICE_SECURE))) */
343     }
344 }
345 CY_SECTION_RAMFUNC_END
346 #endif /* !defined(CY_FLASH_RWW_DRV_SUPPORT_DISABLED) */
347 #endif /* !defined (CY_IP_MXS40FLASHC) */
348 
349 #if !defined (CY_IP_MXS40FLASHC)
350 /*******************************************************************************
351 * Function Name: Cy_Flash_Init
352 ****************************************************************************//**
353 *
354 * Initiates all needed prerequisites to support flash erase/write.
355 * Should be called from each core.
356 *
357 * Requires a call to Cy_IPC_Sema_Init(), Cy_IPC_Pipe_Config() and
358 * Cy_IPC_Pipe_Init() functions before use.
359 *
360 * This function is called in the SystemInit() function, for proper flash write
361 * and erase operations. If the default startup file is not used, or the function
362 * SystemInit() is not called in your project, ensure to perform the following steps
363 * before any flash or EmEEPROM write/erase operations:
364 *
365 *******************************************************************************/
Cy_Flash_Init(void)366 void Cy_Flash_Init(void)
367 {
368 
369     #if !defined (CY_FLASH_RWW_DRV_SUPPORT_DISABLED)
370         CY_SECTION_SHAREDMEM
371         static cy_stc_flash_notify_t ipcWaitMessageStc CY_ALIGN(4);
372 
373         Cy_Flash_InitExt(&ipcWaitMessageStc);
374     #endif /* !defined (CY_FLASH_RWW_DRV_SUPPORT_DISABLED) */
375 
376 }
377 
378 
379 /*******************************************************************************
380 * Function Name: Cy_Flash_SendCmd
381 ****************************************************************************//**
382 *
383 * Sends a command to the SROM via the IPC channel. The function is placed to the
384 * SRAM memory to guarantee successful operation. After an IPC message is sent,
385 * the function waits for a defined time before exiting the function.
386 *
387 *******************************************************************************/
388 CY_SECTION_RAMFUNC_BEGIN
389 #if !defined (__ICCARM__)
390     CY_NOINLINE
391 #endif
Cy_Flash_SendCmd(uint32_t mode,uint32_t microseconds)392 static cy_en_flashdrv_status_t Cy_Flash_SendCmd(uint32_t mode, uint32_t microseconds)
393 {
394     cy_en_flashdrv_status_t result = CY_FLASH_DRV_IPC_BUSY;
395     IPC_STRUCT_Type * locIpcBase = Cy_IPC_Drv_GetIpcBaseAddress(CY_IPC_CHAN_SYSCALL);
396     volatile uint32_t *ipcLockStatus = &REG_IPC_STRUCT_LOCK_STATUS(locIpcBase);
397 
398 #if !defined (CY_FLASH_RWW_DRV_SUPPORT_DISABLED)
399     uint32_t intr;
400     uint32_t semaTryCount = 0uL;
401 
402     if (cy_device->flashRwwRequired != 0U)
403     {
404         /* Check for active core is CM0+, or CM4 on single core device */
405     #if (CY_CPU_CORTEX_M0P)
406         bool isPeerCoreEnabled = (CY_SYS_CM4_STATUS_ENABLED == Cy_SysGetCM4Status());
407     #else
408         bool isPeerCoreEnabled = false;
409 
410         if (SFLASH_SINGLE_CORE == 0U)
411         {
412             isPeerCoreEnabled = true;
413         }
414     #endif
415 
416         if (!isPeerCoreEnabled)
417         {
418             result = CY_FLASH_DRV_SUCCESS;
419         }
420         else
421         {
422             if (IS_CY_PIPE_FREE())
423             {
424                 if (CY_IPC_SEMA_STATUS_LOCKED != Cy_IPC_Sema_Status(CY_FLASH_WAIT_SEMA))
425                 {
426                     if (CY_IPC_PIPE_SUCCESS == NOTIFY_PEER_CORE(ipcWaitMessage))
427                     {
428                         /* Wait for SEMA lock by peer core */
429                         while ((CY_IPC_SEMA_STATUS_LOCKED != Cy_IPC_Sema_Status(CY_FLASH_WAIT_SEMA)) && ((semaTryCount < CY_FLASH_SEMA_WAIT_MAX_TRIES)))
430                         {
431                             /* check for timeout (as maximum tries count) */
432                             ++semaTryCount;
433                         }
434 
435                         if (semaTryCount < CY_FLASH_SEMA_WAIT_MAX_TRIES)
436                         {
437                             result = CY_FLASH_DRV_SUCCESS;
438                         }
439                     }
440                 }
441             }
442         }
443 
444         if (CY_FLASH_DRV_SUCCESS == result)
445         {
446             /* Notifier is ready, start of the operation */
447             intr = Cy_SysLib_EnterCriticalSection();
448 
449             while (0UL == _FLD2VAL(SRSS_CLK_CAL_CNT1_CAL_COUNTER_DONE, SRSS_CLK_CAL_CNT1))
450             {
451                 /* wait here */
452             }
453 
454             if (0UL != _FLD2VAL(SRSS_CLK_CAL_CNT1_CAL_COUNTER_DONE, SRSS_CLK_CAL_CNT1))
455             {
456                /* Tries to acquire the IPC structure and pass the arguments to SROM API */
457                 if (Cy_IPC_Drv_SendMsgPtr(locIpcBase, CY_FLASH_IPC_NOTIFY_STRUCT0, (void*)&flashContext) == CY_IPC_DRV_SUCCESS)
458                 {
459                     Cy_Flash_RAMDelay(microseconds);
460 
461                     if (mode == CY_FLASH_NON_BLOCKING_MODE)
462                     {
463                         /* The Flash operation is successfully initiated */
464                         result = CY_FLASH_DRV_OPERATION_STARTED;
465                     }
466                     else
467                     {
468                         while (0U != _FLD2VAL(IPC_STRUCT_ACQUIRE_SUCCESS, *ipcLockStatus))
469                         {
470                             /* Polls whether the IPC is released and the Flash operation is performed */
471                         }
472                         result = Cy_Flash_OperationStatus();
473                     }
474                 }
475                 else
476                 {
477                     /* The IPC structure is already locked by another process */
478                     result = CY_FLASH_DRV_IPC_BUSY;
479                 }
480             }
481             else
482             {
483                 /* SysClk measurement counter is busy */
484                 result = CY_FLASH_DRV_IPC_BUSY;
485             }
486 
487             if (isPeerCoreEnabled)
488             {
489                 while (CY_IPC_SEMA_SUCCESS != Cy_IPC_Sema_Clear(CY_FLASH_WAIT_SEMA, true))
490                 {
491                     /* Clear SEMA lock */
492                 }
493             }
494 
495             Cy_SysLib_ExitCriticalSection(intr);
496             /* End of the flash operation */
497         }
498     }
499     else
500 #endif /* !defined (CY_FLASH_RWW_DRV_SUPPORT_DISABLED) */
501     {
502     #if !defined (CY_FLASH_RWW_DRV_SUPPORT_DISABLED)
503         intr = Cy_SysLib_EnterCriticalSection();
504     #endif /* !defined (CY_FLASH_RWW_DRV_SUPPORT_DISABLED) */
505         /* Tries to acquire the IPC structure and pass the arguments to SROM API */
506         if (Cy_IPC_Drv_SendMsgPtr(locIpcBase, CY_FLASH_IPC_NOTIFY_STRUCT0, (void*)&flashContext) == CY_IPC_DRV_SUCCESS)
507         {
508             if (mode == CY_FLASH_NON_BLOCKING_MODE)
509             {
510                 /* The Flash operation is successfully initiated */
511                 result = CY_FLASH_DRV_OPERATION_STARTED;
512             }
513             else
514             {
515                 while (0U != _FLD2VAL(IPC_STRUCT_ACQUIRE_SUCCESS, *ipcLockStatus))
516                 {
517                     /* Polls whether the IPC is released and the Flash operation is performed */
518                 }
519 
520                 result = Cy_Flash_OperationStatus();
521             }
522         }
523         else
524         {
525             /* The IPC structure is already locked by another process */
526             result = CY_FLASH_DRV_IPC_BUSY;
527         }
528     #if !defined (CY_FLASH_RWW_DRV_SUPPORT_DISABLED)
529         Cy_SysLib_ExitCriticalSection(intr);
530     #endif /* !defined (CY_FLASH_RWW_DRV_SUPPORT_DISABLED) */
531     }
532 
533     return (result);
534 }
535 CY_SECTION_RAMFUNC_END
536 
537 
538 #if !defined (CY_FLASH_RWW_DRV_SUPPORT_DISABLED)
539     /*******************************************************************************
540     * Function Name: Cy_Flash_RAMDelay
541     ****************************************************************************//**
542     *
543     * Wait for a defined time in the SRAM memory region.
544     *
545     *******************************************************************************/
546     CY_SECTION_RAMFUNC_BEGIN
547     #if !defined (__ICCARM__)
548         CY_NOINLINE
549     #endif
Cy_Flash_RAMDelay(uint32_t microseconds)550     static void Cy_Flash_RAMDelay(uint32_t microseconds)
551     {
552         uint32_t ticks = (microseconds & 0xFFFFUL) * CY_FLASH_TICKS_FOR_1US;
553         if (ticks != CY_FLASH_NO_DELAY)
554         {
555             /* Acquire the IPC to prevent changing of the shared resources at the same time */
556             while(0U == _FLD2VAL(IPC_STRUCT_ACQUIRE_SUCCESS, REG_IPC_STRUCT_ACQUIRE(CY_IPC_STRUCT_PTR(CY_IPC_CHAN_DDFT))))
557             {
558                 /* Wait until the IPC structure is released by another process */
559             }
560 
561             SRSS_TST_DDFT_FAST_CTL_REG  = SRSS_TST_DDFT_FAST_CTL_MASK;
562             SRSS_TST_DDFT_SLOW_CTL_REG  = SRSS_TST_DDFT_SLOW_CTL_MASK;
563 
564             SRSS_CLK_OUTPUT_SLOW = _VAL2FLD(SRSS_CLK_OUTPUT_SLOW_SLOW_SEL0, CY_SYSCLK_MEAS_CLK_IMO) |
565                                    _VAL2FLD(SRSS_CLK_OUTPUT_SLOW_SLOW_SEL1, CY_FLASH_CLK_OUTPUT_DISABLED);
566 
567             /* Load the down-counter without status bit value */
568             SRSS_CLK_CAL_CNT1 = _VAL2FLD(SRSS_CLK_CAL_CNT1_CAL_COUNTER1, ticks);
569 
570             /* Make sure that the counter is started */
571             ticks = _FLD2VAL(SRSS_CLK_CAL_CNT1_CAL_COUNTER_DONE, SRSS_CLK_CAL_CNT1);
572 
573             /* Release the IPC */
574             REG_IPC_STRUCT_RELEASE(CY_IPC_STRUCT_PTR(CY_IPC_CHAN_DDFT)) = 0U;
575 
576             while (0UL == _FLD2VAL(SRSS_CLK_CAL_CNT1_CAL_COUNTER_DONE, SRSS_CLK_CAL_CNT1))
577             {
578                 /* Wait until the counter stops counting */
579             }
580         }
581     }
582     CY_SECTION_RAMFUNC_END
583 
584     #if (CY_CPU_CORTEX_M4)
585 
586         /* Based on bookmark codes of mxs40srompsoc BROS,002-03298 */
587         #define CY_FLASH_PROGRAM_ROW_BOOKMARK        (0x00000001UL)
588         #define CY_FLASH_ERASE_ROW_BOOKMARK          (0x00000002UL)
589         #define CY_FLASH_WRITE_ROW_ERASE_BOOKMARK    (0x00000003UL)
590         #define CY_FLASH_WRITE_ROW_PROGRAM_BOOKMARK  (0x00000004UL)
591 
592         /* Number of the CM0P ticks for function delay corrective time at final stage */
593         #define CY_FLASH_FINAL_STAGE_DELAY_TICKS     (1000UL)
594         #define CY_FLASH_FINAL_STAGE_DELAY           (130UL + CY_FLASH_DELAY_CORRECTIVE(CY_FLASH_FINAL_STAGE_DELAY_TICKS))
595 
596 
597         /*******************************************************************************
598         * Function Name: Cy_Flash_ResumeIrqHandler
599         ****************************************************************************//**
600         *
601         * This is the interrupt service routine to make additional processing of the
602         * flash operations resume phase.
603         *
604         *******************************************************************************/
605         CY_SECTION_RAMFUNC_BEGIN
606         #if !defined (__ICCARM__)
607             CY_NOINLINE
608         #endif
Cy_Flash_ResumeIrqHandler(void)609         void Cy_Flash_ResumeIrqHandler(void)
610         {
611             IPC_STRUCT_Type * locIpcBase = Cy_IPC_Drv_GetIpcBaseAddress(CY_IPC_CHAN_CYPIPE_EP0);
612 
613             uint32_t bookmark;
614             #if ((CY_CPU_CORTEX_M4) && (defined (CY_DEVICE_SECURE)))
615                 bookmark = CY_PRA_REG32_GET(CY_PRA_INDX_FLASHC_FM_CTL_BOOKMARK) & 0xffffUL;
616             #else
617                 bookmark = FLASHC_FM_CTL_BOOKMARK & 0xffffUL;
618             #endif /* ((CY_CPU_CORTEX_M4) && (defined (CY_DEVICE_SECURE))) */
619 
620             uint32_t intr = Cy_SysLib_EnterCriticalSection();
621 
622             uint32_t cm0s = CPUSS_CM0_STATUS;
623             bool sflashSingleCore = (0U == SFLASH_SINGLE_CORE);
624 
625             if ((bookmark == CY_FLASH_PROGRAM_ROW_BOOKMARK) || (bookmark == CY_FLASH_ERASE_ROW_BOOKMARK) ||
626                 (bookmark == CY_FLASH_WRITE_ROW_ERASE_BOOKMARK) || (bookmark == CY_FLASH_WRITE_ROW_PROGRAM_BOOKMARK))
627             {
628                 if ((cm0s == (CPUSS_CM0_STATUS_SLEEPING_Msk | CPUSS_CM0_STATUS_SLEEPDEEP_Msk)) && sflashSingleCore)
629                 {
630                     REG_IPC_STRUCT_NOTIFY(locIpcBase) = _VAL2FLD(IPC_STRUCT_NOTIFY_INTR_NOTIFY, (1UL << CY_IPC_INTR_CYPIPE_EP0));
631                     while (CPUSS_CM0_STATUS == (CPUSS_CM0_STATUS_SLEEPING_Msk | CPUSS_CM0_STATUS_SLEEPDEEP_Msk))
632                     {
633                         /* Wait until the core is active */
634                     }
635                 }
636                 Cy_Flash_RAMDelay(CY_FLASH_FINAL_STAGE_DELAY);
637             }
638 
639             Cy_SysLib_ExitCriticalSection(intr);
640         }
641         CY_SECTION_RAMFUNC_END
642     #endif /* (CY_CPU_CORTEX_M4) */
643 #endif /* !defined (CY_FLASH_RWW_DRV_SUPPORT_DISABLED) */
644 
645 #else
646 
647 /*******************************************************************************
648 * Function Name: Cy_Flash_Process_BootRom_Error_Code
649 ****************************************************************************//**
650 *
651 * Converts Boot Rom Call returns to the Flash driver return defines.
652 *******************************************************************************/
653 static cy_en_flashdrv_status_t Cy_Flash_Process_BootRom_Error_Code(uint32_t error_code)
654 {
655     cy_en_flashdrv_status_t result;
656 
657     switch (error_code)
658     {
659         case CYBOOT_FLASH_SUCCESS:
660         {
661             result = CY_FLASH_DRV_SUCCESS;
662             break;
663         }
664         case CYBOOT_FLASH_INIT_FAILED:
665         {
666             result = CY_FLASH_DRV_INIT_FAILED;
667             break;
668         }
669         case CYBOOT_FLASH_ADDR_INVALID:
670         {
671             result = CY_FLASH_DRV_INVALID_FLASH_ADDR;
672             break;
673         }
674         case CYBOOT_FLASH_PARAM_INVALID:
675         {
676             result = CY_FLASH_DRV_INVALID_INPUT_PARAMETERS;
677             break;
678         }
679         case CYBOOT_FAULT_UNEXPECTED :
680         {
681             result = CY_FLASH_DRV_ERR_UNC;
682             break;
683         }
684         default:
685         {
686             result = CY_FLASH_DRV_ERR_UNC;
687             break;
688         }
689     }
690 
691     return (result);
692 }
693 
694 
695 /* These API's are call back functions from boot rom code.
696    These needs to be passed to the boot rom in the init function.
697    Current architecture in the PDL is not using the callback calls from boot rom.
698    PDL gets the status of the operation complete by calling cyboot_is_flash_ready().
699    cyboot_is_flash_ready is called from the existing function Cy_Flash_IsOperationComplete().
700 */
701 /*******************************************************************************
702 * Function Name: Cy_Flash_Callback_PreIRQ
703 ****************************************************************************//**
704 *
705 * Call back function from boot rom before the non blocking operation is started.
706 *
707 *******************************************************************************/
708 static void Cy_Flash_Callback_PreIRQ(cyboot_flash_context_t *ctx)
709 {
710     (void) ctx;
711 }
712 /*******************************************************************************
713 * Function Name: Cy_Flash_Callback_PostIRQ
714 ****************************************************************************//**
715 *
716 * Call back function from boot rom after the non blocking operation is started.
717 *
718 *******************************************************************************/
719 static void Cy_Flash_Callback_PostIRQ(cyboot_flash_context_t *ctx)
720 {
721     (void) ctx;
722 }
723 /*******************************************************************************
724 * Function Name: Cy_Flash_Callback_IRQComplete
725 ****************************************************************************//**
726 *
727 * Call back function from boot rom after the completion of non blocking operation.
728 *
729 *******************************************************************************/
730 static void Cy_Flash_Callback_IRQComplete(cyboot_flash_context_t *ctx)
731 {
732     (void) ctx;
733 }
734 
735 /*******************************************************************************
736 * Function Name: Cy_Flash_Init
737 ****************************************************************************//**
738 *
739 * Initiates all needed prerequisites to support flash erase/write.
740 * Should be once before starting any flash operations.
741 *
742 * param refresh_enable enable disable refresh feature
743 *
744 *******************************************************************************/
745 cy_en_flashdrv_status_t Cy_Flash_Init(bool refresh_enable)
746 {
747     cy_en_sysint_status_t sysStatus;
748     const cy_stc_sysint_t flash_isr_cfg =
749     {
750         .intrSrc = (IRQn_Type) cpuss_interrupt_fm_cbus_IRQn,
751         .intrPriority = 7,
752     };
753 
754     sysStatus = Cy_SysInt_Init(&flash_isr_cfg, ROM_FUNC->cyboot_flash_irq_handler);
755     if(CY_SYSINT_SUCCESS != sysStatus)
756     {
757         return CY_FLASH_DRV_ERR_UNC;
758     }
759     NVIC_EnableIRQ(flash_isr_cfg.intrSrc);
760 
761     __enable_irq();
762     boot_rom_context.callback_pre_irq  = (cyboot_flash_callback_t)Cy_Flash_Callback_PreIRQ;
763     boot_rom_context.callback_post_irq = (cyboot_flash_callback_t)Cy_Flash_Callback_PostIRQ;
764     boot_rom_context.callback_complete = (cyboot_flash_callback_t)Cy_Flash_Callback_IRQComplete;
765 
766     if(refresh_enable)
767     {
768         refresh_feature_enable = refresh_enable;
769         boot_rom_context.refresh = &flash_refresh;
770         /* Need to initialize boot_rom_context.refresh before working with flash */
771         ROM_FUNC->cyboot_flash_refresh_init_all(&flash_refresh);
772         /* To recover a previous failure, if any */
773         uint32_t ret = ROM_FUNC->cyboot_flash_refresh_recover_all(&flash_refresh);
774         return Cy_Flash_Process_BootRom_Error_Code(ret);
775     }
776     return CY_FLASH_DRV_SUCCESS;
777 }
778 
779 /*******************************************************************************
780 * Function Name: Cy_Flash_Is_Refresh_Required
781 ********************************************************************************
782 * Checks whether a flash refresh is needed for a sector.
783 * \param refresh    A pointer to a single refresh structure.
784 * \returns
785 * - TRUE, if a refresh is needed.
786 * - FALSE, if a refresh is not needed.
787 *******************************************************************************/
788 bool Cy_Flash_Is_Refresh_Required(void)
789 {
790     return ROM_FUNC->cyboot_flash_refresh_test(&flash_refresh);
791 }
792 #endif /* !defined (CY_IP_MXS40FLASHC) */
793 
794 /*******************************************************************************
795 * Function Name: Cy_Flash_EraseRow
796 ****************************************************************************//**
797 *
798 * This function erases a single row of flash. Reports success or
799 * a reason for failure. Does not return until the Write operation is
800 * complete. Returns immediately and reports a CY_FLASH_DRV_IPC_BUSY error in
801 * the case when another process is writing to flash or erasing the row.
802 * User firmware should not enter the Hibernate or Deep Sleep mode until flash Erase
803 * is complete. The Flash operation is allowed in Sleep mode.
804 * During the Flash operation, the device should not be reset, including the
805 * XRES pin, a software reset, and watchdog reset sources. Also, low-voltage
806 * detect circuits should be configured to generate an interrupt instead of a
807 * reset. Otherwise, portions of flash may undergo unexpected changes.
808 *
809 *******************************************************************************/
Cy_Flash_EraseRow(uint32_t rowAddr)810 cy_en_flashdrv_status_t Cy_Flash_EraseRow(uint32_t rowAddr)
811 {
812     cy_en_flashdrv_status_t result = CY_FLASH_DRV_INVALID_INPUT_PARAMETERS;
813 
814 #if !defined (CY_IP_MXS40FLASHC)
815     /* Prepares arguments to be passed to SROM API */
816     if (Cy_Flash_BoundsCheck(rowAddr) != false)
817     {
818         SystemCoreClockUpdate();
819         flashContext.opcode = CY_FLASH_OPCODE_ERASE_ROW | CY_FLASH_BLOCKING_MODE;
820         flashContext.arg1 = rowAddr;
821         flashContext.arg2 = 0UL;
822         flashContext.arg3 = 0UL;
823 
824         if (cy_device->flashEraseDelay != 0U)
825         {
826             result = Cy_Flash_SendCmd(CY_FLASH_BLOCKING_MODE, CY_FLASH_START_ERASE_DELAY);
827         }
828         else
829         {
830             result = Cy_Flash_SendCmd(CY_FLASH_BLOCKING_MODE, CY_FLASH_NO_DELAY);
831         }
832     }
833 #else
834         boot_rom_context.flags = CYBOOT_FLAGS_BLOCKING;
835         uint32_t status = ROM_FUNC->cyboot_flash_erase_row(rowAddr, &boot_rom_context);
836         result = Cy_Flash_Process_BootRom_Error_Code(status);
837 #endif /* !defined (CY_IP_MXS40FLASHC) */
838 
839 
840     return (result);
841 }
842 
843 
844 /*******************************************************************************
845 * Function Name: Cy_Flash_StartEraseRow
846 ****************************************************************************//**
847 *
848 * Starts erasing a single row of flash. Returns immediately
849 * and reports a successful start or reason for failure.
850 * Reports a CY_FLASH_DRV_IPC_BUSY error in the case when IPC structure is locked
851 * by another process. User firmware should not enter the Hibernate or Deep Sleep mode until
852 * flash Erase is complete. The Flash operation is allowed in Sleep mode.
853 * During the flash operation, the device should not be reset, including the
854 * XRES pin, a software reset, and watchdog reset sources. Also, the low-voltage
855 * detect circuits should be configured to generate an interrupt instead of a reset.
856 * Otherwise, portions of flash may undergo unexpected changes.
857 * To avoid situation of reading data from cache memory - before
858 * reading data from previously programmed/erased flash rows, the user must
859 * clear the flash cache with the Cy_SysLib_ClearFlashCacheAndBuffer()
860 * function.
861 *
862 *******************************************************************************/
Cy_Flash_StartEraseRow(uint32_t rowAddr)863 cy_en_flashdrv_status_t Cy_Flash_StartEraseRow(uint32_t rowAddr)
864 {
865     cy_en_flashdrv_status_t result = CY_FLASH_DRV_INVALID_INPUT_PARAMETERS;
866 #if !defined (CY_IP_MXS40FLASHC)
867     if (Cy_Flash_BoundsCheck(rowAddr) != false)
868     {
869         SystemCoreClockUpdate();
870 
871         /* Prepares arguments to be passed to SROM API */
872         flashContext.opcode = CY_FLASH_OPCODE_ERASE_ROW;
873         if (SFLASH_SINGLE_CORE != 0U)
874         {
875             flashContext.opcode |= CY_FLASH_BLOCKING_MODE;
876         }
877 
878         flashContext.arg1 = rowAddr;
879         flashContext.arg2 = 0UL;
880         flashContext.arg3 = 0UL;
881 
882         if (cy_device->flashEraseDelay != 0U)
883         {
884             result = Cy_Flash_SendCmd(CY_FLASH_NON_BLOCKING_MODE, CY_FLASH_START_ERASE_DELAY);
885         }
886         else
887         {
888             result = Cy_Flash_SendCmd(CY_FLASH_NON_BLOCKING_MODE, CY_FLASH_NO_DELAY);
889         }
890     }
891 #else
892         boot_rom_context.flags = CYBOOT_FLAGS_NON_BLOCKING;
893         uint32_t status = ROM_FUNC->cyboot_flash_erase_row_start(rowAddr, &boot_rom_context);
894         if(status == (uint32_t)CYBOOT_FLASH_SUCCESS)
895         {
896             result = CY_FLASH_DRV_OPERATION_STARTED;
897         }
898         else
899         {
900             result = Cy_Flash_Process_BootRom_Error_Code(status);
901         }
902 #endif /* !defined (CY_IP_MXS40FLASHC) */
903 
904     return (result);
905 }
906 
907 #if !defined (CY_IP_MXS40FLASHC)
908 /*******************************************************************************
909 * Function Name: Cy_Flash_EraseSector
910 ****************************************************************************//**
911 *
912 * This function erases a sector of flash. Reports success or
913 * a reason for failure. Does not return until the Erase operation is
914 * complete. Returns immediately and reports a CY_FLASH_DRV_IPC_BUSY error in
915 * the case when another process is writing to flash or erasing the row.
916 * User firmware should not enter the Hibernate or Deep Sleep mode until flash Erase
917 * is complete. The Flash operation is allowed in Sleep mode.
918 * During the Flash operation, the device should not be reset, including the
919 * XRES pin, a software reset, and watchdog reset sources. Also, low-voltage
920 * detect circuits should be configured to generate an interrupt instead of a
921 * reset. Otherwise, portions of flash may undergo unexpected changes.
922 *
923 *******************************************************************************/
Cy_Flash_EraseSector(uint32_t sectorAddr)924 cy_en_flashdrv_status_t Cy_Flash_EraseSector(uint32_t sectorAddr)
925 {
926     cy_en_flashdrv_status_t result = CY_FLASH_DRV_INVALID_INPUT_PARAMETERS;
927 
928     /* Prepares arguments to be passed to SROM API */
929     if (Cy_Flash_BoundsCheck(sectorAddr) != false)
930     {
931         SystemCoreClockUpdate();
932 
933         flashContext.opcode = CY_FLASH_OPCODE_ERASE_SECTOR | CY_FLASH_BLOCKING_MODE;
934         flashContext.arg1 = sectorAddr;
935         flashContext.arg2 = 0UL;
936         flashContext.arg3 = 0UL;
937 
938         if (cy_device->flashEraseDelay != 0U)
939         {
940             result = Cy_Flash_SendCmd(CY_FLASH_BLOCKING_MODE, CY_FLASH_START_ERASE_DELAY);
941         }
942         else
943         {
944             result = Cy_Flash_SendCmd(CY_FLASH_BLOCKING_MODE, CY_FLASH_NO_DELAY);
945         }
946     }
947 
948     return (result);
949 }
950 
951 /*******************************************************************************
952 * Function Name: Cy_Flash_StartEraseSector
953 ****************************************************************************//**
954 *
955 * Starts erasing a sector of flash. Returns immediately
956 * and reports a successful start or reason for failure.
957 * Reports a CY_FLASH_DRV_IPC_BUSY error in the case when IPC structure is locked
958 * by another process. User firmware should not enter the Hibernate or Deep Sleep mode until
959 * flash Erase is complete. The Flash operation is allowed in Sleep mode.
960 * During the flash operation, the device should not be reset, including the
961 * XRES pin, a software reset, and watchdog reset sources. Also, the low-voltage
962 * detect circuits should be configured to generate an interrupt instead of a reset.
963 * Otherwise, portions of flash may undergo unexpected changes.
964 * Before reading data from previously programmed/erased flash rows, the
965 * user must clear the flash cache with the Cy_SysLib_ClearFlashCacheAndBuffer()
966 * function.
967 *
968 *
969 *******************************************************************************/
Cy_Flash_StartEraseSector(uint32_t sectorAddr)970 cy_en_flashdrv_status_t Cy_Flash_StartEraseSector(uint32_t sectorAddr)
971 {
972     cy_en_flashdrv_status_t result = CY_FLASH_DRV_INVALID_INPUT_PARAMETERS;
973 
974     if (Cy_Flash_BoundsCheck(sectorAddr) != false)
975     {
976         SystemCoreClockUpdate();
977 
978         /* Prepares arguments to be passed to SROM API */
979         flashContext.opcode = CY_FLASH_OPCODE_ERASE_SECTOR;
980         if (SFLASH_SINGLE_CORE != 0U)
981         {
982             flashContext.opcode |= CY_FLASH_BLOCKING_MODE;
983         }
984 
985         flashContext.arg1 = sectorAddr;
986         flashContext.arg2 = 0UL;
987         flashContext.arg3 = 0UL;
988 
989         if (cy_device->flashEraseDelay != 0U)
990         {
991             result = Cy_Flash_SendCmd(CY_FLASH_NON_BLOCKING_MODE, CY_FLASH_START_ERASE_DELAY);
992         }
993         else
994         {
995             result = Cy_Flash_SendCmd(CY_FLASH_NON_BLOCKING_MODE, CY_FLASH_NO_DELAY);
996         }
997     }
998 
999     return (result);
1000 }
1001 
1002 /*******************************************************************************
1003 * Function Name: Cy_Flash_EraseSubsector
1004 ****************************************************************************//**
1005 *
1006 * This function erases an 8-row subsector of flash. Reports success or
1007 * a reason for failure. Does not return until the Write operation is
1008 * complete. Returns immediately and reports a CY_FLASH_DRV_IPC_BUSY error in
1009 * the case when another process is writing to flash or erasing the row.
1010 * User firmware should not enter the Hibernate or Deep-Sleep mode until flash Erase
1011 * is complete. The Flash operation is allowed in Sleep mode.
1012 * During the Flash operation, the device should not be reset, including the
1013 * XRES pin, a software reset, and watchdog reset sources. Also, low-voltage
1014 * detect circuits should be configured to generate an interrupt instead of a
1015 * reset. Otherwise, portions of flash may undergo unexpected changes.
1016 *******************************************************************************/
Cy_Flash_EraseSubsector(uint32_t subSectorAddr)1017 cy_en_flashdrv_status_t Cy_Flash_EraseSubsector(uint32_t subSectorAddr)
1018 {
1019     cy_en_flashdrv_status_t result = CY_FLASH_DRV_INVALID_INPUT_PARAMETERS;
1020 
1021     /* Prepares arguments to be passed to SROM API */
1022     if (Cy_Flash_BoundsCheck(subSectorAddr) != false)
1023     {
1024         SystemCoreClockUpdate();
1025 
1026         flashContext.opcode = CY_FLASH_OPCODE_ERASE_SUB_SECTOR | CY_FLASH_BLOCKING_MODE;
1027         flashContext.arg1 = subSectorAddr;
1028         flashContext.arg2 = 0UL;
1029         flashContext.arg3 = 0UL;
1030 
1031         if (cy_device->flashEraseDelay != 0U)
1032         {
1033             result = Cy_Flash_SendCmd(CY_FLASH_BLOCKING_MODE, CY_FLASH_START_ERASE_DELAY);
1034         }
1035         else
1036         {
1037             result = Cy_Flash_SendCmd(CY_FLASH_BLOCKING_MODE, CY_FLASH_NO_DELAY);
1038         }
1039     }
1040 
1041     return (result);
1042 }
1043 
1044 /*******************************************************************************
1045 * Function Name: Cy_Flash_StartEraseSubsector
1046 ****************************************************************************//**
1047 *
1048 * Starts erasing an 8-row subsector 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 *******************************************************************************/
Cy_Flash_StartEraseSubsector(uint32_t subSectorAddr)1061 cy_en_flashdrv_status_t Cy_Flash_StartEraseSubsector(uint32_t subSectorAddr)
1062 {
1063     cy_en_flashdrv_status_t result = CY_FLASH_DRV_INVALID_INPUT_PARAMETERS;
1064 
1065     if (Cy_Flash_BoundsCheck(subSectorAddr) != false)
1066     {
1067         SystemCoreClockUpdate();
1068 
1069         /* Prepares arguments to be passed to SROM API */
1070         flashContext.opcode = CY_FLASH_OPCODE_ERASE_SUB_SECTOR;
1071         if (SFLASH_SINGLE_CORE != 0U)
1072         {
1073             flashContext.opcode |= CY_FLASH_BLOCKING_MODE;
1074         }
1075 
1076         flashContext.arg1 = subSectorAddr;
1077         flashContext.arg2 = 0UL;
1078         flashContext.arg3 = 0UL;
1079 
1080         if (cy_device->flashEraseDelay != 0U)
1081         {
1082             result = Cy_Flash_SendCmd(CY_FLASH_NON_BLOCKING_MODE, CY_FLASH_START_ERASE_DELAY);
1083         }
1084         else
1085         {
1086             result = Cy_Flash_SendCmd(CY_FLASH_NON_BLOCKING_MODE, CY_FLASH_NO_DELAY);
1087         }
1088     }
1089 
1090     return (result);
1091 }
1092 #endif /* !defined (CY_IP_MXS40FLASHC) */
1093 
1094 /*******************************************************************************
1095 * Function Name: Cy_Flash_ProgramRow
1096 ****************************************************************************//**
1097 *
1098 * This function writes an array of data to a single row of flash. Reports
1099 * success or a reason for failure. Does not return until the Program operation
1100 * is complete.
1101 * Returns immediately and reports a CY_FLASH_DRV_IPC_BUSY error in the case
1102 * when another process is writing to flash. User firmware should not enter the
1103 * Hibernate or Deep-sleep mode until flash Write is complete. The Flash operation
1104 * is allowed in Sleep mode. During the Flash operation, the device should not be
1105 * reset, including the XRES pin, a software reset, and watchdog reset sources.
1106 * Also, low-voltage detect circuits should be configured to generate an interrupt
1107 * instead of a reset. Otherwise, portions of flash may undergo unexpected
1108 * changes.\n
1109 * Before calling this function, the target flash region must be erased by
1110 * the StartErase/EraseRow function.\n
1111 * Data to be programmed must be located in the SRAM memory region.
1112 * Before reading data from previously programmed/erased flash rows, the
1113 * user must clear the flash cache with the Cy_SysLib_ClearFlashCacheAndBuffer()
1114 * function.
1115 *
1116 *******************************************************************************/
Cy_Flash_ProgramRow(uint32_t rowAddr,const uint32_t * data)1117 cy_en_flashdrv_status_t Cy_Flash_ProgramRow(uint32_t rowAddr, const uint32_t* data)
1118 {
1119     cy_en_flashdrv_status_t result = CY_FLASH_DRV_INVALID_INPUT_PARAMETERS;
1120 
1121 #if !defined (CY_IP_MXS40FLASHC)
1122     /* Checks whether the input parameters are valid */
1123     if ((Cy_Flash_BoundsCheck(rowAddr) != false) && (NULL != data))
1124     {
1125         SystemCoreClockUpdate();
1126         /* Prepares arguments to be passed to SROM API */
1127         flashContext.opcode = CY_FLASH_OPCODE_PROGRAM_ROW | CY_FLASH_BLOCKING_MODE;
1128         flashContext.arg1   = CY_FLASH_DATA_LOC_SRAM;
1129         flashContext.arg2   = rowAddr;
1130         flashContext.arg3   = (uint32_t)data;
1131 
1132         if (cy_device->flashProgramDelay != 0U)
1133         {
1134             result = Cy_Flash_SendCmd(CY_FLASH_BLOCKING_MODE, CY_FLASH_START_PROGRAM_DELAY);
1135         }
1136         else
1137         {
1138             result = Cy_Flash_SendCmd(CY_FLASH_BLOCKING_MODE, CY_FLASH_NO_DELAY);
1139         }
1140     }
1141 #else
1142 
1143         boot_rom_context.flags = CYBOOT_FLAGS_BLOCKING;
1144         uint32_t status = ROM_FUNC->cyboot_flash_program_row(rowAddr, (void *)data, &boot_rom_context);
1145         result = Cy_Flash_Process_BootRom_Error_Code(status);
1146 #endif /* !defined (CY_IP_MXS40FLASHC) */
1147 
1148     return (result);
1149 }
1150 
1151 
1152 /*******************************************************************************
1153 * Function Name: Cy_Flash_WriteRow
1154 ****************************************************************************//**
1155 *
1156 * This function writes an array of data to a single row of flash. This is done
1157 * in three steps - pre-program, erase and then program flash row with the input
1158 * data. Reports success or a reason for failure. Does not return until the Write
1159 * operation is complete.
1160 * Returns immediately and reports a CY_FLASH_DRV_IPC_BUSY error in the case
1161 * when another process is writing to flash. User firmware should not enter the
1162 * Hibernate or Deep-sleep mode until flash Write is complete. The Flash operation
1163 * is allowed in Sleep mode. During the Flash operation, the
1164 * device should not be reset, including the XRES pin, a software
1165 * reset, and watchdog reset sources. Also, low-voltage detect
1166 * circuits should be configured to generate an interrupt
1167 * instead of a reset. Otherwise, portions of flash may undergo
1168 * unexpected changes.
1169 *
1170 *******************************************************************************/
Cy_Flash_WriteRow(uint32_t rowAddr,const uint32_t * data)1171 cy_en_flashdrv_status_t Cy_Flash_WriteRow(uint32_t rowAddr, const uint32_t* data)
1172 {
1173     cy_en_flashdrv_status_t result = CY_FLASH_DRV_INVALID_INPUT_PARAMETERS;
1174 
1175 #if !defined (CY_IP_MXS40FLASHC)
1176     /* Checks whether the input parameters are valid */
1177     if ((Cy_Flash_BoundsCheck(rowAddr) != false) && (NULL != data))
1178     {
1179         SystemCoreClockUpdate();
1180         /* Prepares arguments to be passed to SROM API */
1181         flashContext.opcode = CY_FLASH_OPCODE_WRITE_ROW | CY_FLASH_BLOCKING_MODE;
1182         flashContext.arg1   = 0UL;
1183         flashContext.arg2   = rowAddr;
1184         flashContext.arg3   = (uint32_t)data;
1185 
1186         if (cy_device->flashWriteDelay != 0U)
1187         {
1188             result = Cy_Flash_SendCmd(CY_FLASH_BLOCKING_MODE, CY_FLASH_START_WRITE_DELAY);
1189         }
1190         else
1191         {
1192             result = Cy_Flash_SendCmd(CY_FLASH_BLOCKING_MODE, CY_FLASH_NO_DELAY);
1193         }
1194     }
1195 #else
1196 
1197         boot_rom_context.flags = CYBOOT_FLAGS_BLOCKING;
1198         uint32_t status = ROM_FUNC->cyboot_flash_write_row(rowAddr, (void *)data, &boot_rom_context);
1199         result = Cy_Flash_Process_BootRom_Error_Code(status);
1200 #endif /* !defined (CY_IP_MXS40FLASHC) */
1201 
1202 
1203     return (result);
1204 }
1205 
1206 
1207 /*******************************************************************************
1208 * Function Name: Cy_Flash_StartWrite
1209 ****************************************************************************//**
1210 *
1211 * Performs pre-program, erase and then starts programming the flash row with
1212 * the input data. Returns immediately and reports a successful start
1213 * or reason for failure. Reports a CY_FLASH_DRV_IPC_BUSY error
1214 * in the case when another process is writing to flash. User
1215 * firmware should not enter the Hibernate or Deep-Sleep mode until
1216 * flash Write is complete. The Flash operation is allowed in Sleep mode.
1217 * During the flash operation, the device should not be reset, including the
1218 * XRES pin, a software reset, and watchdog reset sources. Also, the low-voltage
1219 * detect circuits should be configured to generate an interrupt instead of a reset.
1220 * Otherwise, portions of flash may undergo unexpected changes.
1221 * Before reading data from previously programmed/erased flash rows, the
1222 * user must clear the flash cache with the Cy_SysLib_ClearFlashCacheAndBuffer()
1223 * function.
1224 *
1225 *******************************************************************************/
Cy_Flash_StartWrite(uint32_t rowAddr,const uint32_t * data)1226 cy_en_flashdrv_status_t Cy_Flash_StartWrite(uint32_t rowAddr, const uint32_t* data)
1227 {
1228     cy_en_flashdrv_status_t result = CY_FLASH_DRV_INVALID_INPUT_PARAMETERS;
1229 #if !defined (CY_IP_MXS40FLASHC)
1230     /* Checks whether the input parameters are valid */
1231     if ((Cy_Flash_BoundsCheck(rowAddr) != false) && (NULL != data))
1232     {
1233         result = Cy_Flash_StartEraseRow(rowAddr);
1234 
1235         if (CY_FLASH_DRV_OPERATION_STARTED == result)
1236         {
1237             /* Polls whether the IPC is released and the Flash operation is performed */
1238             do
1239             {
1240                 result = Cy_Flash_OperationStatus();
1241             }
1242             while (result == CY_FLASH_DRV_OPCODE_BUSY);
1243 
1244             if (CY_FLASH_DRV_SUCCESS == result)
1245             {
1246                 result = Cy_Flash_StartProgram(rowAddr, data);
1247             }
1248         }
1249 
1250     }
1251 
1252 #else
1253         boot_rom_context.flags = CYBOOT_FLAGS_NON_BLOCKING;
1254         uint32_t status = ROM_FUNC->cyboot_flash_write_row_start(rowAddr, (void *)data, &boot_rom_context);
1255         if(status == (uint32_t)CYBOOT_FLASH_SUCCESS)
1256         {
1257             result = CY_FLASH_DRV_OPERATION_STARTED;
1258         }
1259         else
1260         {
1261             result = Cy_Flash_Process_BootRom_Error_Code(status);
1262         }
1263 #endif /* !defined (CY_IP_MXS40FLASHC) */
1264     return (result);
1265 }
1266 
1267 
1268 /*******************************************************************************
1269 * Function Name: Cy_Flash_IsOperationComplete
1270 ****************************************************************************//**
1271 *
1272 * Reports a successful operation result, reason of failure or busy status
1273 * ( CY_FLASH_DRV_OPCODE_BUSY ).
1274 *******************************************************************************/
Cy_Flash_IsOperationComplete(void)1275 cy_en_flashdrv_status_t Cy_Flash_IsOperationComplete(void)
1276 {
1277     return (Cy_Flash_OperationStatus());
1278 }
1279 
1280 
1281 /*******************************************************************************
1282 * Function Name: Cy_Flash_StartProgram
1283 ****************************************************************************//**
1284 *
1285 * Starts writing an array of data to a single row of flash. Returns immediately
1286 * and reports a successful start or reason for failure.
1287 * Reports a CY_FLASH_DRV_IPC_BUSY error if another process is writing
1288 * to flash. The user firmware should not enter Hibernate or Deep-Sleep mode until flash
1289 * Program is complete. The Flash operation is allowed in Sleep mode.
1290 * During the Flash operation, the device should not be reset, including the
1291 * XRES pin, a software reset, and watchdog reset sources. Also, the low-voltage
1292 * detect circuits should be configured to generate an interrupt instead of a reset.
1293 * Otherwise, portions of flash may undergo unexpected changes.\n
1294 * Before calling this function, the target flash region must be erased by
1295 * the StartEraseRow/EraseRow function.\n
1296 * Data to be programmed must be located in the SRAM memory region.
1297 * Before reading data from previously programmed/erased flash rows, the
1298 * user must clear the flash cache with the Cy_SysLib_ClearFlashCacheAndBuffer()
1299 * function.
1300 *******************************************************************************/
Cy_Flash_StartProgram(uint32_t rowAddr,const uint32_t * data)1301 cy_en_flashdrv_status_t Cy_Flash_StartProgram(uint32_t rowAddr, const uint32_t* data)
1302 {
1303     cy_en_flashdrv_status_t result = CY_FLASH_DRV_INVALID_INPUT_PARAMETERS;
1304 #if !defined (CY_IP_MXS40FLASHC)
1305     if ((Cy_Flash_BoundsCheck(rowAddr) != false) && (NULL != data))
1306     {
1307         SystemCoreClockUpdate();
1308         /* Prepares arguments to be passed to SROM API */
1309         flashContext.opcode = CY_FLASH_OPCODE_PROGRAM_ROW;
1310 
1311         if (SFLASH_SINGLE_CORE != 0U)
1312         {
1313             flashContext.opcode |= CY_FLASH_BLOCKING_MODE;
1314         }
1315 
1316         flashContext.arg1   = CY_FLASH_DATA_LOC_SRAM;
1317         flashContext.arg2   = rowAddr;
1318         flashContext.arg3   = (uint32_t)data;
1319 
1320         if (cy_device->flashProgramDelay != 0U)
1321         {
1322             result = Cy_Flash_SendCmd(CY_FLASH_NON_BLOCKING_MODE, CY_FLASH_START_PROGRAM_DELAY);
1323         }
1324         else
1325         {
1326             result = Cy_Flash_SendCmd(CY_FLASH_NON_BLOCKING_MODE, CY_FLASH_NO_DELAY);
1327         }
1328     }
1329 #else
1330         boot_rom_context.flags = CYBOOT_FLAGS_NON_BLOCKING;
1331         uint32_t status = ROM_FUNC->cyboot_flash_program_row_start(rowAddr, (void *)data, &boot_rom_context);
1332         if(status == (uint32_t)CYBOOT_FLASH_SUCCESS)
1333         {
1334             result = CY_FLASH_DRV_OPERATION_STARTED;
1335         }
1336         else
1337         {
1338             result = Cy_Flash_Process_BootRom_Error_Code(status);
1339         }
1340 #endif /* !defined (CY_IP_MXS40FLASHC) */
1341 
1342     return (result);
1343 }
1344 
1345 
1346 /*******************************************************************************
1347 * Function Name: Cy_Flash_RowChecksum
1348 ****************************************************************************//**
1349 *
1350 * Returns a checksum value of the specified flash row.
1351 *
1352 *******************************************************************************/
Cy_Flash_RowChecksum(uint32_t rowAddr,uint32_t * checksumPtr)1353 cy_en_flashdrv_status_t Cy_Flash_RowChecksum (uint32_t rowAddr, uint32_t* checksumPtr)
1354 {
1355     cy_en_flashdrv_status_t result = CY_FLASH_DRV_INVALID_INPUT_PARAMETERS;
1356 #if !defined (CY_IP_MXS40FLASHC)
1357     /* Checks whether the input parameters are valid */
1358     if ((Cy_Flash_BoundsCheck(rowAddr) != false) && (NULL != checksumPtr))
1359     {
1360 
1361         uint32_t resTmp;
1362         uint32_t rowID;
1363         rowID = Cy_Flash_GetRowNum(rowAddr);
1364 
1365         /* Prepares arguments to be passed to SROM API */
1366         flashContext.opcode = CY_FLASH_OPCODE_CHECKSUM |
1367                               (((rowID >> CY_FLASH_REGION_ID_SHIFT) & CY_FLASH_REGION_ID_MASK) << CY_FLASH_OPCODE_CHECKSUM_REGION_SHIFT) |
1368                               ((rowID & CY_FLASH_ROW_ID_MASK) << CY_FLASH_OPCODE_CHECKSUM_ROW_SHIFT);
1369 
1370         /* Tries to acquire the IPC structure and pass the arguments to SROM API */
1371         if (Cy_IPC_Drv_SendMsgPtr(Cy_IPC_Drv_GetIpcBaseAddress(CY_IPC_CHAN_SYSCALL), CY_FLASH_IPC_NOTIFY_STRUCT0,
1372                                   (void*)&flashContext) == CY_IPC_DRV_SUCCESS)
1373         {
1374             /* Polls whether IPC is released and the Flash operation is performed */
1375             while (Cy_IPC_Drv_IsLockAcquired(Cy_IPC_Drv_GetIpcBaseAddress(CY_IPC_CHAN_SYSCALL)) != false)
1376             {
1377                 /* Wait till IPC is released */
1378             }
1379 
1380             resTmp = flashContext.opcode >> CY_FLASH_ERROR_SHIFT;
1381 
1382             if (resTmp == CY_FLASH_ERROR_NO_ERROR)
1383             {
1384                 result = CY_FLASH_DRV_SUCCESS;
1385 
1386                 if (CY_IPC_V1)
1387                 {
1388                     *checksumPtr = flashContext.opcode & CY_FLASH_RESULT_MASK;
1389                 }
1390                 else
1391                 {
1392                     *checksumPtr = REG_IPC_STRUCT_DATA1(Cy_IPC_Drv_GetIpcBaseAddress(CY_IPC_CHAN_SYSCALL));
1393                 }
1394             }
1395             else
1396             {
1397                 result = Cy_Flash_ProcessOpcode(flashContext.opcode);
1398             }
1399 
1400         }
1401         else
1402         {
1403             /* The IPC structure is already locked by another process */
1404             result = CY_FLASH_DRV_IPC_BUSY;
1405         }
1406     }
1407 #else
1408         uint32_t startAddress, endAddress;
1409         volatile uint32_t i, j;
1410         uint32_t checksum_value=0U;
1411 
1412         startAddress = rowAddr;
1413         endAddress = startAddress + CY_FLASH_SIZEOF_ROW;
1414 
1415         i = startAddress;
1416         j = endAddress;
1417         do
1418         {
1419             checksum_value += REG8(i);
1420             i++;
1421             j--;
1422         }while(i<endAddress);
1423         *checksumPtr = checksum_value;
1424         result = CY_FLASH_DRV_SUCCESS;
1425 #endif /* !defined (CY_IP_MXS40FLASHC) */
1426 
1427     return (result);
1428 }
1429 
1430 
1431 /*******************************************************************************
1432 * Function Name: Cy_Flash_CalculateHash
1433 ****************************************************************************//**
1434 *
1435 * Returns a hash value of the specified region of flash.
1436 *******************************************************************************/
Cy_Flash_CalculateHash(const uint32_t * data,uint32_t numberOfBytes,uint32_t * hashPtr)1437 cy_en_flashdrv_status_t Cy_Flash_CalculateHash (const uint32_t* data, uint32_t numberOfBytes,  uint32_t* hashPtr)
1438 {
1439     cy_en_flashdrv_status_t result = CY_FLASH_DRV_INVALID_INPUT_PARAMETERS;
1440 
1441     /* Checks whether the input parameters are valid */
1442     if ((data != NULL) && (0UL != numberOfBytes))
1443     {
1444 #if !defined (CY_IP_MXS40FLASHC)
1445         volatile uint32_t resTmp;
1446         /* Prepares arguments to be passed to SROM API */
1447         flashContext.opcode = CY_FLASH_OPCODE_HASH;
1448         flashContext.arg1 = (uint32_t)data;
1449         flashContext.arg2 = numberOfBytes;
1450 
1451         /* Tries to acquire the IPC structure and pass the arguments to SROM API */
1452         if (Cy_IPC_Drv_SendMsgPtr(Cy_IPC_Drv_GetIpcBaseAddress(CY_IPC_CHAN_SYSCALL), CY_FLASH_IPC_NOTIFY_STRUCT0,
1453                                   (void*)&flashContext) == CY_IPC_DRV_SUCCESS)
1454         {
1455             /* Polls whether IPC is released and the Flash operation is performed */
1456             while (Cy_IPC_Drv_IsLockAcquired(Cy_IPC_Drv_GetIpcBaseAddress(CY_IPC_CHAN_SYSCALL)) != false)
1457             {
1458                 /* Wait till IPC is released */
1459             }
1460 
1461             resTmp = flashContext.opcode;
1462 
1463             if ((resTmp >> CY_FLASH_ERROR_SHIFT) == CY_FLASH_ERROR_NO_ERROR)
1464             {
1465                 result = CY_FLASH_DRV_SUCCESS;
1466                 *hashPtr = flashContext.opcode & CY_FLASH_RESULT_MASK;
1467             }
1468             else
1469             {
1470                 result = Cy_Flash_ProcessOpcode(flashContext.opcode);
1471             }
1472         }
1473         else
1474         {
1475             /* The IPC structure is already locked by another process */
1476             result = CY_FLASH_DRV_IPC_BUSY;
1477         }
1478 #else
1479         *hashPtr = (uint32_t)Cy_Flash_GetHash((uint32_t) data, numberOfBytes);
1480         result = CY_FLASH_DRV_SUCCESS;
1481 
1482 #endif /* !defined (CY_IP_MXS40FLASHC) */
1483     }
1484 
1485     return (result);
1486 }
1487 
1488 #if !defined (CY_IP_MXS40FLASHC)
1489 /*******************************************************************************
1490 * Function Name: Cy_Flash_GetRowNum
1491 ****************************************************************************//**
1492 *
1493 * Returns flash region ID and row number of the Flash address.
1494 *******************************************************************************/
Cy_Flash_GetRowNum(uint32_t flashAddr)1495 static uint32_t Cy_Flash_GetRowNum(uint32_t flashAddr)
1496 {
1497     uint32_t result;
1498 
1499 #if (CY_EM_EEPROM_SIZE>0)
1500     if ((flashAddr >= CY_EM_EEPROM_BASE) && (flashAddr < (CY_EM_EEPROM_BASE + CY_EM_EEPROM_SIZE)))
1501     {
1502         result = (CY_FLASH_REGION_ID_EM_EEPROM << CY_FLASH_REGION_ID_SHIFT) |
1503                  ((flashAddr - CY_EM_EEPROM_BASE) / CY_FLASH_SIZEOF_ROW);
1504     }
1505     else
1506 #endif
1507     if ((flashAddr >= SFLASH_BASE) && (flashAddr < (SFLASH_BASE + SFLASH_SECTION_SIZE)))
1508     {
1509         result = (CY_FLASH_REGION_ID_SFLASH << CY_FLASH_REGION_ID_SHIFT) |
1510                  ((flashAddr - SFLASH_BASE) / CY_FLASH_SIZEOF_ROW);
1511     }
1512     else
1513     {
1514         result = (CY_FLASH_REGION_ID_MAIN << CY_FLASH_REGION_ID_SHIFT) |
1515                  ((flashAddr - CY_FLASH_BASE) / CY_FLASH_SIZEOF_ROW);
1516     }
1517 
1518     return (result);
1519 }
1520 
1521 
1522 /*******************************************************************************
1523 * Function Name: Cy_Flash_BoundsCheck
1524 ****************************************************************************//**
1525 *
1526 * The function checks the following conditions:
1527 *  - if Flash address is equal to start address of the row
1528 *******************************************************************************/
Cy_Flash_BoundsCheck(uint32_t flashAddr)1529 static bool Cy_Flash_BoundsCheck(uint32_t flashAddr)
1530 {
1531     return ((flashAddr % CY_FLASH_SIZEOF_ROW) == 0UL);
1532 }
1533 
1534 
1535 /*******************************************************************************
1536 * Function Name: Cy_Flash_ProcessOpcode
1537 ****************************************************************************//**
1538 *
1539 * Converts System Call returns to the Flash driver return defines.
1540 *******************************************************************************/
Cy_Flash_ProcessOpcode(uint32_t opcode)1541 static cy_en_flashdrv_status_t Cy_Flash_ProcessOpcode(uint32_t opcode)
1542 {
1543     cy_en_flashdrv_status_t result;
1544 
1545     switch (opcode)
1546     {
1547         case 0UL:
1548         {
1549             result = CY_FLASH_DRV_SUCCESS;
1550             break;
1551         }
1552         case CY_FLASH_ROMCODE_SUCCESS:
1553         {
1554             result = CY_FLASH_DRV_SUCCESS;
1555             break;
1556         }
1557         case CY_FLASH_ROMCODE_INVALID_PROTECTION:
1558         {
1559             result = CY_FLASH_DRV_INV_PROT;
1560             break;
1561         }
1562         case CY_FLASH_ROMCODE_INVALID_FM_PL:
1563         {
1564             result = CY_FLASH_DRV_INVALID_FM_PL;
1565             break;
1566         }
1567         case CY_FLASH_ROMCODE_INVALID_FLASH_ADDR:
1568         {
1569             result = CY_FLASH_DRV_INVALID_FLASH_ADDR;
1570             break;
1571         }
1572         case CY_FLASH_ROMCODE_ROW_PROTECTED:
1573         {
1574             result = CY_FLASH_DRV_ROW_PROTECTED;
1575             break;
1576         }
1577         case CY_FLASH_ROMCODE_IN_PROGRESS_NO_ERROR:
1578         {
1579             result = CY_FLASH_DRV_PROGRESS_NO_ERROR;
1580             break;
1581         }
1582         case (uint32_t)CY_FLASH_DRV_INVALID_INPUT_PARAMETERS:
1583         {
1584             result = CY_FLASH_DRV_INVALID_INPUT_PARAMETERS;
1585             break;
1586         }
1587         case CY_FLASH_IS_OPERATION_STARTED :
1588         {
1589             result = CY_FLASH_DRV_OPERATION_STARTED;
1590             break;
1591         }
1592         case CY_FLASH_IS_BUSY :
1593         {
1594             result = CY_FLASH_DRV_OPCODE_BUSY;
1595             break;
1596         }
1597         case CY_FLASH_IS_IPC_BUSY :
1598         {
1599             result = CY_FLASH_DRV_IPC_BUSY;
1600             break;
1601         }
1602         case CY_FLASH_IS_INVALID_INPUT_PARAMETERS :
1603         {
1604             result = CY_FLASH_DRV_INVALID_INPUT_PARAMETERS;
1605             break;
1606         }
1607         default:
1608         {
1609             result = CY_FLASH_DRV_ERR_UNC;
1610             break;
1611         }
1612     }
1613 
1614     return (result);
1615 }
1616 #endif /* !defined (CY_IP_MXS40FLASHC) */
1617 
1618 /*******************************************************************************
1619 * Function Name: Cy_Flash_OperationStatus
1620 ****************************************************************************//**
1621 *
1622 * Checks the status of the Flash Operation, and returns it.
1623 *******************************************************************************/
Cy_Flash_OperationStatus(void)1624 static cy_en_flashdrv_status_t Cy_Flash_OperationStatus(void)
1625 {
1626     cy_en_flashdrv_status_t result = CY_FLASH_DRV_OPCODE_BUSY;
1627 #if !defined (CY_IP_MXS40FLASHC)
1628     /* Checks if the IPC structure is not locked */
1629     if (Cy_IPC_Drv_IsLockAcquired(Cy_IPC_Drv_GetIpcBaseAddress(CY_IPC_CHAN_SYSCALL)) == false)
1630     {
1631         /* The result of SROM API calling is returned to the driver context */
1632         result = Cy_Flash_ProcessOpcode(flashContext.opcode);
1633 
1634         /* Clear pre-fetch cache after flash operation */
1635         #if CY_CPU_CORTEX_M4 && defined (CY_DEVICE_SECURE)
1636             CY_PRA_REG32_SET(CY_PRA_INDX_FLASHC_FLASH_CMD, FLASHC_FLASH_CMD_INV_Msk);
1637             while (CY_PRA_REG32_GET(CY_PRA_INDX_FLASHC_FLASH_CMD) != 0U)
1638             {
1639             }
1640         #else
1641             FLASHC_FLASH_CMD = FLASHC_FLASH_CMD_INV_Msk;
1642             while (FLASHC_FLASH_CMD != 0U)
1643             {
1644             }
1645         #endif /* CY_CPU_CORTEX_M4 && defined (CY_DEVICE_SECURE) */
1646     }
1647 #else
1648     if(ROM_FUNC->cyboot_is_flash_ready(&boot_rom_context))
1649     {
1650         return CY_FLASH_DRV_SUCCESS;
1651     }
1652 #endif /* !defined (CY_IP_MXS40FLASHC) */
1653     return (result);
1654 }
1655 
1656 
1657 /*******************************************************************************
1658 * Function Name: Cy_Flash_GetExternalStatus
1659 ****************************************************************************//**
1660 *
1661 * This function handles the case where a module such as security image captures
1662 * a system call from this driver and reports its own status or error code,
1663 * for example protection violation. In that case, a function from this
1664 * driver returns an unknown error (see cy_en_flashdrv_status_t). After receipt
1665 * of an unknown error, the user may call this function to get the status
1666 * of the capturing module.
1667 *
1668 * The user is responsible for parsing the content of the returned value
1669 * and casting it to the appropriate enumeration.
1670 *******************************************************************************/
Cy_Flash_GetExternalStatus(void)1671 uint32_t Cy_Flash_GetExternalStatus(void)
1672 {
1673 #if !defined (CY_IP_MXS40FLASHC)
1674     return (flashContext.opcode);
1675 #else
1676     if(Cy_Flash_IsOperationComplete() == CY_FLASH_DRV_SUCCESS)
1677     {
1678         return (uint32_t)CY_FLASH_DRV_SUCCESS;
1679     }
1680     else
1681     {
1682         return (uint32_t)CY_FLASH_DRV_OPCODE_BUSY;
1683     }
1684 #endif /* !defined (CY_IP_MXS40FLASHC) */
1685 }
1686 
1687 
1688 #if defined (CY_IP_MXS40FLASHC)
1689 /*******************************************************************************
1690 * Function Name: Cy_Flash_Refresh
1691 ****************************************************************************//**
1692 *
1693 * Refreshes the flash rows which were not updated by the user code. This is a blocking call.
1694 * If there are only limited number of flash row writes for each flash sector then
1695 * the flash rows in this flash sector (which were not updated during this number of row writes) start to wear out.
1696 * This refresh feature will prevent the flash sector from wear out
1697 *
1698 * param address of the row that needs to be refreshed.
1699 *
1700 * return success if refresh is complete. will return err
1701 *
1702 * \note Refresh is not allowed on sector which has SFLASH. That sector must be left immutable.
1703 *       This is a blocking call.
1704 *******************************************************************************/
Cy_Flash_Refresh(uint32_t flashAddr)1705 cy_en_flashdrv_status_t Cy_Flash_Refresh(uint32_t flashAddr)
1706 {
1707     cy_en_flashdrv_status_t result = CY_FLASH_DRV_REFRESH_NOT_ENABLED;
1708     if(refresh_feature_enable)
1709     {
1710         uint32_t sector_Idx;
1711         uint32_t row_Idx;
1712         uint32_t status = ROM_FUNC->cyboot_flash_refresh_get_sector_idx(flashAddr, &sector_Idx, &row_Idx);
1713         if( status == CYBOOT_FLASH_SUCCESS)
1714         {
1715             status = ROM_FUNC->cyboot_flash_refresh_perform(sector_Idx, &flash_refresh);
1716         }
1717         (void)row_Idx;
1718         result = Cy_Flash_Process_BootRom_Error_Code(status);
1719     }
1720     return result;
1721 }
1722 
1723 /*******************************************************************************
1724 * Function Name: Cy_Flash_Refresh_Start
1725 ****************************************************************************//**
1726 *
1727 * Refreshes the flash rows which were not updated by the user code. This is a non-blocking call.
1728 * If there are only limited number of flash row writes for each flash sector then
1729 * the flash rows in this flash sector (which were not updated during this number of row writes) start to wear out.
1730 * This refresh feature will prevent the flash sector from wear out
1731 * This is not allowed on sector which has SFLASH
1732 *
1733 * \param address of the row that needs to be refreshed.
1734 *
1735 * \return success if refresh is started. Else will return err
1736 *
1737 *
1738 *******************************************************************************/
Cy_Flash_Refresh_Start(uint32_t flashAddr)1739 cy_en_flashdrv_status_t Cy_Flash_Refresh_Start(uint32_t flashAddr)
1740 {
1741     cy_en_flashdrv_status_t result = CY_FLASH_DRV_REFRESH_NOT_ENABLED;
1742     if(refresh_feature_enable)
1743     {
1744         uint32_t sector_Idx;
1745         uint32_t row_Idx;
1746         uint32_t status = ROM_FUNC->cyboot_flash_refresh_get_sector_idx(flashAddr, &sector_Idx, &row_Idx);
1747         if( status == CYBOOT_FLASH_SUCCESS)
1748         {
1749             status = ROM_FUNC->cyboot_flash_refresh_perform_start(sector_Idx, &flash_refresh, &boot_rom_context);
1750             if(status == (uint32_t)CYBOOT_FLASH_SUCCESS)
1751             {
1752                 return CY_FLASH_DRV_OPERATION_STARTED;
1753             }
1754         }
1755         (void)row_Idx;
1756         result = Cy_Flash_Process_BootRom_Error_Code(status);
1757     }
1758     return result;
1759 }
1760 /*****************************************************************************
1761 * Function Name: GetHash()
1762 ******************************************************************************
1763 * Summary:
1764 *  This function computes the hash based on formula
1765 *  H(n+1)=(H(n)*2+Byte)%127,where H(0)=0
1766 *
1767 * Parameters:
1768 *  uint32_t startAddr - 32 bit system address of  first byte of data chunk
1769 *  uint32_t numberOfBytes    - total number of bytes of data chunk on which hash needs
1770 *  to be computed
1771 
1772 * Return:
1773 *  uint8_t hash
1774 *
1775 * Calls:
1776 *  None
1777 *
1778 * Called by:
1779 *  Boot
1780 *
1781 * Note:
1782 *  cHash represents the calculated hash (H in the above formula).
1783 *  HASH_CALC_DIVISOR = 127 and HASH_CALC_DIVISOR_LEN = 7
1784 *  Mod 127 is calculated using the following method.
1785 *  Any number N (< 128*127 + 127 = 16383) can be represented in the form of
1786 *  N = 128*A + B = 127*A + A + B. Thus, N mod 127 can be calculated from A + B.
1787 *  If A + B == 254, then N mod 127 = 0
1788 *  Else if A + B >= 127, then N mod 127 = A + B - 127
1789 *  Else N mod 127 = A + B
1790 *  For the given implementation, N < 255*2 + 255 = 766. Hence, A + B < 254
1791 *  This method reduces the computational cost by avoiding divide operation.
1792 *****************************************************************************/
Cy_Flash_GetHash(uint32_t startAddr,uint32_t numberOfBytes)1793 static uint8_t Cy_Flash_GetHash(uint32_t startAddr,uint32_t numberOfBytes)
1794 {
1795     uint32_t i;
1796     uint8_t hash = 0U;
1797     uint32_t cHashSum;
1798 
1799      uint8_t cData, cHigherPart, cLowerPart;
1800     for (i = 0U; i < numberOfBytes; i++)
1801     {
1802         cData = REG8(startAddr + i);
1803         cHashSum = (((uint32_t) hash << 1U) + cData);
1804          /* PRQA S 2985 4 */ /* FIXMISRA */ /* MISRA C:2012 Rule 2.2 Required
1805             This operation is redundant. The value of the result is always that of the left-hand operand.
1806             The cHashSum equals cData, that is 8-bit value, shifted left by 7 bit (HASH_CALC_DIVISOR_LEN).
1807         */
1808         cHigherPart = (uint8_t)(cHashSum >> HASH_CALC_DIVISOR_LEN) & HASH_CALC_DIVISOR;
1809         cLowerPart = (uint8_t) (cHashSum & HASH_CALC_DIVISOR);
1810         hash = ( (cHigherPart + cLowerPart) >=  HASH_CALC_DIVISOR ) ? (cHigherPart + cLowerPart - HASH_CALC_DIVISOR) :
1811                  (cHigherPart + cLowerPart);
1812     }
1813     return hash;
1814 }
1815 
1816 /*******************************************************************************
1817 * Function Name: Cy_Flashc_ECCEnable
1818 ****************************************************************************//**
1819 *
1820 * \brief Enables ECC for flash
1821 * ECC checking/reporting on FLASH interface is enabled.
1822 * Correctable or non-correctable faults are reported by enabling ECC.
1823 *
1824 * \return none
1825 *
1826 *******************************************************************************/
Cy_Flashc_ECCEnable(void)1827 void Cy_Flashc_ECCEnable(void)
1828 {
1829     FLASHC_FLASH_CTL |= FLASHC_FLASH_CTL_ECC_EN_Msk;
1830 }
1831 
1832 /*******************************************************************************
1833 * Function Name: Cy_Flashc_ECCDisable
1834 ****************************************************************************//**
1835 *
1836 * \brief Disables ECC for flash
1837 * ECC checking/reporting on FLASH interface is disabled.
1838 * Correctable or non-correctable faults are not reported by disabling ECC.
1839 *
1840 * \return none
1841 *
1842 *******************************************************************************/
Cy_Flashc_ECCDisable(void)1843 void Cy_Flashc_ECCDisable(void)
1844 {
1845     FLASHC_FLASH_CTL &= (uint32_t) ~FLASHC_FLASH_CTL_ECC_EN_Msk;
1846 }
1847 
1848 /*******************************************************************************
1849 * Function Name: Cy_Flashc_INJ_ECCEnable
1850 ****************************************************************************//**
1851 *
1852 * This function enable ECC error injection for FLASH interface
1853 * And is applicable while ECC is enabled.
1854 *
1855 * \return none
1856 *
1857 *******************************************************************************/
Cy_Flashc_INJ_ECCEnable(void)1858 void Cy_Flashc_INJ_ECCEnable(void)
1859 {
1860     FLASHC_FLASH_ECC_INJ_EN |= (FLASHC_ECC_INJ_EN_ECC_INJ_ENABLE_Msk |
1861                                FLASHC_ECC_INJ_EN_ECC_ERROR_Msk);
1862 }
1863 
1864 /*******************************************************************************
1865 * Function Name: Cy_Flashc_INJ_ECCDisable
1866 ****************************************************************************//**
1867 *
1868 * This function disables ECC error injection for FLASH interface
1869 *
1870 * \return none
1871 *
1872 *******************************************************************************/
Cy_Flashc_INJ_ECCDisable(void)1873 void Cy_Flashc_INJ_ECCDisable(void)
1874 {
1875     FLASHC_FLASH_ECC_INJ_EN &= (uint32_t) ~(FLASHC_ECC_INJ_EN_ECC_INJ_ENABLE_Msk |
1876                                FLASHC_ECC_INJ_EN_ECC_ERROR_Msk);
1877 }
1878 
1879 
1880 /*******************************************************************************
1881 * Function Name: Cy_Flashc_InjectECC
1882 ****************************************************************************//**
1883 *
1884 * This function enables ECC injection and sets the address where a parity will be injected
1885 * and the parity value.
1886 * Reports success or a reason for failure.
1887 *
1888 * \address The address where ECC parity will be injected.
1889 *
1890 * \parity The parity value which will be injected.
1891 *
1892 * \returns none
1893 *
1894 *******************************************************************************/
Cy_Flashc_InjectECC(uint32_t address,uint8_t parity)1895 void Cy_Flashc_InjectECC(uint32_t address, uint8_t parity)
1896 {
1897     FLASHC_FLASH_ECC_INJ_CTL = (_VAL2FLD(FLASHC_ECC_INJ_CTL_WORD_ADDR, address) |
1898                                 _VAL2FLD(FLASHC_ECC_INJ_CTL_PARITY, parity ));
1899 }
1900 
1901 /*******************************************************************************
1902 * Function Name: Cy_Flashc_Get_ECC_Error
1903 ****************************************************************************//**
1904 *
1905 * \brief This function when ECC injection is enabled and error is injected will return no of errors generated.
1906 *
1907 * \returns no of errors generated with ECC error injection \ref cy_en_flash_ecc_inject_errors_t.
1908 *
1909 *******************************************************************************/
Cy_Flashc_Get_ECC_Error(void)1910 cy_en_flash_ecc_inject_errors_t Cy_Flashc_Get_ECC_Error(void)
1911 {
1912     if (0UL != _FLD2VAL(FLASHC_ECC_INJ_EN_ECC_ERROR, FLASHC_FLASH_ECC_INJ_EN))
1913     {
1914         return CY_FLASH_ECC_ERRORS_MORE_THAN_ONE;
1915     }
1916     return CY_FLASH_ECC_ERRORS_LESS_THAN_TWO;
1917 }
1918 
1919 
1920 /*******************************************************************************
1921 * Function Name: Cy_Flashc_Dual_Bank_Mode_Enable
1922 ****************************************************************************//**
1923 *
1924 * \brief Enables Dual bank Mode for flash
1925 *
1926 * \param mapping : Mapping for the main and work regions.
1927 *
1928 * \return none
1929 *
1930 *******************************************************************************/
Cy_Flashc_Dual_Bank_Mode_Enable(cy_en_flash_dual_bank_mapping_t mapping)1931 void Cy_Flashc_Dual_Bank_Mode_Enable(cy_en_flash_dual_bank_mapping_t mapping)
1932 {
1933     FLASHC_FLASH_CTL |= (_VAL2FLD(FLASHC_FLASH_CTL_BANK_MODE, 1U) |
1934                          _VAL2FLD(FLASHC_FLASH_CTL_BANK_MAPPING, mapping ));;
1935 }
1936 
1937 /*******************************************************************************
1938 * Function Name: Cy_Flashc_Dual_Bank_Mode_Disable
1939 ****************************************************************************//**
1940 *
1941 * \brief Disables Dual bank Mode for flash
1942 *
1943 * \return none
1944 *
1945 *******************************************************************************/
Cy_Flashc_Dual_Bank_Mode_Disable(void)1946 void Cy_Flashc_Dual_Bank_Mode_Disable(void)
1947 {
1948     FLASHC_FLASH_CTL &= (uint32_t) ~(FLASHC_FLASH_CTL_BANK_MODE_Msk |
1949                                      FLASHC_FLASH_CTL_BANK_MAPPING_Msk);
1950 }
1951 
1952 
1953 #endif /*defined (CY_IP_MXS40FLASHC)*/
1954 
1955 #if (defined (CY_IP_M4CPUSS) && (CY_IP_M4CPUSS_VERSION >=2))
1956 /*******************************************************************************
1957 * Function Name: Cy_Flashc_SetWorkBankMode
1958 ****************************************************************************//**
1959 *
1960 * Sets bank mode for work flash
1961 *
1962 * mode bank mode to be set
1963 *
1964 *******************************************************************************/
Cy_Flashc_SetWorkBankMode(cy_en_bankmode_t mode)1965 void Cy_Flashc_SetWorkBankMode(cy_en_bankmode_t mode)
1966 {
1967     if(CY_FLASH_DUAL_BANK_MODE == mode)
1968     {
1969         FLASHC_FLASH_CTL |= FLASHC_V2_FLASH_CTL_WORK_BANK_MODE_Msk;
1970     }
1971     else
1972     {
1973         FLASHC_FLASH_CTL &= (uint32_t) ~FLASHC_V2_FLASH_CTL_WORK_BANK_MODE_Msk;
1974     }
1975 }
1976 
1977 /*******************************************************************************
1978 * Function Name: Cy_Flashc_GetWorkBankMode
1979 ****************************************************************************//**
1980 *
1981 * Gets current bank mode for work flash
1982 *
1983 *******************************************************************************/
Cy_Flashc_GetWorkBankMode(void)1984 cy_en_bankmode_t Cy_Flashc_GetWorkBankMode(void)
1985 {
1986    uint32_t bank_mode = _FLD2VAL(FLASHC_V2_FLASH_CTL_WORK_BANK_MODE, FLASHC_FLASH_CTL);
1987    if(bank_mode == 0UL)
1988     {
1989         return CY_FLASH_SINGLE_BANK_MODE;
1990     }
1991     else
1992     {
1993         return CY_FLASH_DUAL_BANK_MODE;
1994     }
1995 }
1996 /*******************************************************************************
1997 * Function Name: Cy_Flashc_SetMainBankMode
1998 ****************************************************************************//**
1999 *
2000 *  Sets bank mode for main flash
2001 *
2002 *  mode bank mode to be set
2003 *
2004 *******************************************************************************/
Cy_Flashc_SetMainBankMode(cy_en_bankmode_t mode)2005 void Cy_Flashc_SetMainBankMode(cy_en_bankmode_t mode)
2006 {
2007    if(CY_FLASH_DUAL_BANK_MODE == mode)
2008     {
2009         FLASHC_FLASH_CTL |= FLASHC_V2_FLASH_CTL_MAIN_BANK_MODE_Msk;
2010     }
2011     else
2012     {
2013         FLASHC_FLASH_CTL &= (uint32_t) ~FLASHC_V2_FLASH_CTL_MAIN_BANK_MODE_Msk;
2014     }
2015 }
2016 
2017 /*******************************************************************************
2018 * Function Name: Cy_Flashc_GetMainBankMode
2019 ****************************************************************************//**
2020 *
2021 *  Gets current bank mode for main flash
2022 *
2023 *******************************************************************************/
Cy_Flashc_GetMainBankMode(void)2024 cy_en_bankmode_t Cy_Flashc_GetMainBankMode(void)
2025 {
2026     uint32_t bank_mode = _FLD2VAL(FLASHC_V2_FLASH_CTL_MAIN_BANK_MODE, FLASHC_FLASH_CTL);
2027     if(bank_mode == 0UL)
2028     {
2029         return CY_FLASH_SINGLE_BANK_MODE;
2030     }
2031     else
2032     {
2033         return CY_FLASH_DUAL_BANK_MODE;
2034     }
2035 }
2036 
2037 /*******************************************************************************
2038 * Function Name: Cy_Flashc_SetMain_Flash_Mapping
2039 ****************************************************************************//**
2040 *
2041 * \brief Sets mapping for main flash region. Applicable only in Dual Bank mode of Main flash region
2042 *
2043 * \param mapping mapping to be set
2044 *
2045 * \return none
2046 *******************************************************************************/
Cy_Flashc_SetMain_Flash_Mapping(cy_en_maptype_t mapping)2047 void Cy_Flashc_SetMain_Flash_Mapping(cy_en_maptype_t  mapping)
2048 {
2049     FLASHC_FLASH_CTL &= ~FLASHC_V2_FLASH_CTL_MAIN_MAP_Msk;
2050     FLASHC_FLASH_CTL |= _VAL2FLD(FLASHC_V2_FLASH_CTL_MAIN_MAP, mapping);
2051 }
2052 
2053 /*******************************************************************************
2054 * Function Name: Cy_Flashc_SetWork_Flash_Mapping
2055 ****************************************************************************//**
2056 *
2057 * \brief Sets mapping for work flash region. Applicable only in Dual Bank mode of Work flash region
2058 *
2059 * \param mapping mapping to be set
2060 *
2061 * \return none
2062 *******************************************************************************/
Cy_Flashc_SetWork_Flash_Mapping(cy_en_maptype_t mapping)2063 void Cy_Flashc_SetWork_Flash_Mapping(cy_en_maptype_t mapping)
2064 {
2065     FLASHC_FLASH_CTL &= ~FLASHC_V2_FLASH_CTL_WORK_MAP_Msk;
2066     FLASHC_FLASH_CTL |= _VAL2FLD(FLASHC_V2_FLASH_CTL_WORK_MAP, mapping);
2067 }
2068 
2069 #endif /* (defined (CY_IP_M4CPUSS) && (CY_IP_M4CPUSS_VERSION >=2)) */
2070 CY_MISRA_BLOCK_END('MISRA C-2012 Rule 11.3')
2071 #endif /* CY_IP_M4CPUSS */
2072 
2073 /* [] END OF FILE */
2074