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 = ®_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, §or_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, §or_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