1 /***************************************************************************//**
2 * \file cy_flash.c
3 * \version 3.50.1
4 *
5 * \brief
6 * Provides the public functions for the API for the PSoC 6 Flash Driver.
7 *
8 ********************************************************************************
9 * \copyright
10 * Copyright 2016-2020 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)
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
41 CY_MISRA_DEVIATE_BLOCK_START('MISRA C-2012 Rule 11.3', 2, \
42 '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.');
43
44 /***************************************
45 * Data Structure definitions
46 ***************************************/
47
48 /* Flash driver context */
49 typedef struct
50 {
51 uint32_t opcode; /**< Specifies the code of flash operation */
52 uint32_t arg1; /**< Specifies the configuration of flash operation */
53 uint32_t arg2; /**< Specifies the configuration of flash operation */
54 uint32_t arg3; /**< Specifies the configuration of flash operation */
55 } cy_stc_flash_context_t;
56
57
58 /***************************************
59 * Macro definitions
60 ***************************************/
61
62 /** \cond INTERNAL */
63 /** Set SROM API in blocking mode */
64 #define CY_FLASH_BLOCKING_MODE ((0x01UL) << 8UL)
65 /** Set SROM API in non blocking mode */
66 #define CY_FLASH_NON_BLOCKING_MODE (0UL)
67
68 /** SROM API flash region ID shift for flash row information */
69 #define CY_FLASH_REGION_ID_SHIFT (16U)
70 #define CY_FLASH_REGION_ID_MASK (3U)
71 #define CY_FLASH_ROW_ID_MASK (0xFFFFU)
72 /** SROM API flash region IDs */
73 #define CY_FLASH_REGION_ID_MAIN (0UL)
74 #define CY_FLASH_REGION_ID_EM_EEPROM (1UL)
75 #define CY_FLASH_REGION_ID_SFLASH (2UL)
76
77 /** SROM API opcode mask */
78 #define CY_FLASH_OPCODE_Msk ((0xFFUL) << 24UL)
79 /** SROM API opcode for flash write operation */
80 #define CY_FLASH_OPCODE_WRITE_ROW ((0x05UL) << 24UL)
81 /** SROM API opcode for flash program operation */
82 #define CY_FLASH_OPCODE_PROGRAM_ROW ((0x06UL) << 24UL)
83 /** SROM API opcode for row erase operation */
84 #define CY_FLASH_OPCODE_ERASE_ROW ((0x1CUL) << 24UL)
85 /** SROM API opcode for sub sector erase operation */
86 #define CY_FLASH_OPCODE_ERASE_SUB_SECTOR ((0x1DUL) << 24UL)
87 /** SROM API opcode for sector erase operation */
88 #define CY_FLASH_OPCODE_ERASE_SECTOR ((0x14UL) << 24UL)
89 /** SROM API opcode for flash checksum operation */
90 #define CY_FLASH_OPCODE_CHECKSUM ((0x0BUL) << 24UL)
91 /** SROM API opcode for flash hash operation */
92 #define CY_FLASH_OPCODE_HASH ((0x0DUL) << 24UL)
93 /** SROM API flash row shift for flash checksum operation */
94 #define CY_FLASH_OPCODE_CHECKSUM_ROW_SHIFT (8UL)
95 /** SROM API flash row shift for flash checksum operation */
96 #define CY_FLASH_OPCODE_CHECKSUM_REGION_SHIFT (22UL)
97 /** Data to be programmed to flash is located in SRAM memory region */
98 #define CY_FLASH_DATA_LOC_SRAM (0x100UL)
99 /** SROM API flash verification option for flash write operation */
100 #define CY_FLASH_CONFIG_VERIFICATION_EN ((0x01UL) << 16u)
101
102 /** Command completed with no errors */
103 #define CY_FLASH_ROMCODE_SUCCESS (0xA0000000UL)
104 /** Invalid device protection state */
105 #define CY_FLASH_ROMCODE_INVALID_PROTECTION (0xF0000001UL)
106 /** Invalid flash page latch address */
107 #define CY_FLASH_ROMCODE_INVALID_FM_PL (0xF0000003UL)
108 /** Invalid flash address */
109 #define CY_FLASH_ROMCODE_INVALID_FLASH_ADDR (0xF0000004UL)
110 /** Row is write protected */
111 #define CY_FLASH_ROMCODE_ROW_PROTECTED (0xF0000005UL)
112 /** Comparison between Page Latches and FM row failed */
113 #define CY_FLASH_ROMCODE_PL_ROW_COMP_FA (0xF0000022UL)
114 /** Command in progress; no error */
115 #define CY_FLASH_ROMCODE_IN_PROGRESS_NO_ERROR (0xA0000009UL)
116 /** Flash operation is successfully initiated */
117 #define CY_FLASH_IS_OPERATION_STARTED (0x00000010UL)
118 /** Flash is under operation */
119 #define CY_FLASH_IS_BUSY (0x00000040UL)
120 /** IPC structure is already locked by another process */
121 #define CY_FLASH_IS_IPC_BUSY (0x00000080UL)
122 /** Input parameters passed to Flash API are not valid */
123 #define CY_FLASH_IS_INVALID_INPUT_PARAMETERS (0x00000100UL)
124
125 /** Result mask */
126 #define CY_FLASH_RESULT_MASK (0x0FFFFFFFUL)
127 /** Error shift */
128 #define CY_FLASH_ERROR_SHIFT (28UL)
129 /** No error */
130 #define CY_FLASH_ERROR_NO_ERROR (0xAUL)
131
132 /** CM4 Flash Proxy address */
133 #define CY_FLASH_CM4_FLASH_PROXY_ADDR (*(Cy_Flash_Proxy *)(0x00000D1CUL))
134 typedef cy_en_flashdrv_status_t (*Cy_Flash_Proxy)(cy_stc_flash_context_t *context);
135
136 /** IPC notify bit for IPC0 structure (dedicated to flash operation) */
137 #define CY_FLASH_IPC_NOTIFY_STRUCT0 (0x1UL << CY_IPC_INTR_SYSCALL1)
138
139 /** Disable delay */
140 #define CY_FLASH_NO_DELAY (0U)
141
142 #if !defined (CY_FLASH_RWW_DRV_SUPPORT_DISABLED)
143 /** Number of ticks to wait 1 uS */
144 #define CY_FLASH_TICKS_FOR_1US (8U)
145 /** Define to set the IMO to perform a delay after the flash operation started */
146 #define CY_FLASH_TST_DDFT_SLOW_CTL_MASK (0x00001F1EUL)
147 /** Fast control register */
148 #define CY_FLASH_TST_DDFT_FAST_CTL_MASK (62U)
149 /** Slow output register - output disabled */
150 #define CY_FLASH_CLK_OUTPUT_DISABLED (0U)
151
152 /* The default delay time value */
153 #define CY_FLASH_DEFAULT_DELAY (150UL)
154 /* Calculates the time in microseconds to wait for the number of the CM0P ticks */
155 #define CY_FLASH_DELAY_CORRECTIVE(ticks) (((ticks) * 1000UL) / (Cy_SysClk_ClkSlowGetFrequency() / 1000UL))
156
157 /* Number of the CM0P ticks for StartProgram function delay corrective time */
158 #define CY_FLASH_START_PROGRAM_DELAY_TICKS (6000UL)
159 /* Delay time for StartProgram function in us */
160 #define CY_FLASH_START_PROGRAM_DELAY_TIME (900UL + CY_FLASH_DELAY_CORRECTIVE(CY_FLASH_START_PROGRAM_DELAY_TICKS))
161 /* Number of the CM0P ticks for StartErase functions delay corrective time */
162 #define CY_FLASH_START_ERASE_DELAY_TICKS (9500UL)
163 /* Delay time for StartErase functions in us */
164 #define CY_FLASH_START_ERASE_DELAY_TIME (2200UL + CY_FLASH_DELAY_CORRECTIVE(CY_FLASH_START_ERASE_DELAY_TICKS))
165 /* Number of the CM0P ticks for StartWrite function delay corrective time */
166 #define CY_FLASH_START_WRITE_DELAY_TICKS (19000UL)
167 /* Delay time for StartWrite function in us */
168 #define CY_FLASH_START_WRITE_DELAY_TIME (9800UL + CY_FLASH_DELAY_CORRECTIVE(CY_FLASH_START_WRITE_DELAY_TICKS))
169
170 /** Delay time for Start Write function in us with corrective time */
171 #define CY_FLASH_START_WRITE_DELAY (CY_FLASH_START_WRITE_DELAY_TIME)
172 /** Delay time for Start Program function in us with corrective time */
173 #define CY_FLASH_START_PROGRAM_DELAY (CY_FLASH_START_PROGRAM_DELAY_TIME)
174 /** Delay time for Start Erase function in uS with corrective time */
175 #define CY_FLASH_START_ERASE_DELAY (CY_FLASH_START_ERASE_DELAY_TIME)
176
177 #define CY_FLASH_ENTER_WAIT_LOOP (0xFFU)
178 #define CY_FLASH_IPC_CLIENT_ID (2U)
179
180 /** Semaphore number reserved for flash driver */
181 #define CY_FLASH_WAIT_SEMA (0UL)
182 /* Semaphore check timeout (in tries) */
183 #define CY_FLASH_SEMA_WAIT_MAX_TRIES (150000UL)
184
185 static void Cy_Flash_RAMDelay(uint32_t microseconds);
186
187 #if (CY_CPU_CORTEX_M0P)
188 #define IS_CY_PIPE_FREE(...) (!Cy_IPC_Drv_IsLockAcquired(Cy_IPC_Drv_GetIpcBaseAddress(CY_IPC_CHAN_CYPIPE_EP1)))
189 #define NOTIFY_PEER_CORE(a) Cy_IPC_Pipe_SendMessage(CY_IPC_EP_CYPIPE_CM4_ADDR, CY_IPC_EP_CYPIPE_CM0_ADDR, (a), NULL)
190 #else
191 #define IS_CY_PIPE_FREE(...) (!Cy_IPC_Drv_IsLockAcquired(Cy_IPC_Drv_GetIpcBaseAddress(CY_IPC_CHAN_CYPIPE_EP0)))
192 #define NOTIFY_PEER_CORE(a) Cy_IPC_Pipe_SendMessage(CY_IPC_EP_CYPIPE_CM0_ADDR, CY_IPC_EP_CYPIPE_CM4_ADDR, (a), NULL)
193 #endif
194
195 static void Cy_Flash_NotifyHandler(uint32_t * msgPtr);
196
197 static cy_stc_flash_notify_t * ipcWaitMessage;
198
199 #else
200 /** Delay time for Start Write function in us with corrective time */
201 #define CY_FLASH_START_WRITE_DELAY (CY_FLASH_NO_DELAY)
202 /** Delay time for Start Program function in us with corrective time */
203 #define CY_FLASH_START_PROGRAM_DELAY (CY_FLASH_NO_DELAY)
204 /** Delay time for Start Erase function in uS with corrective time */
205 #define CY_FLASH_START_ERASE_DELAY (CY_FLASH_NO_DELAY)
206
207 #endif /* !defined (CY_FLASH_RWW_DRV_SUPPORT_DISABLED) */
208 /** \endcond */
209
210 /* Static functions */
211 static bool Cy_Flash_BoundsCheck(uint32_t flashAddr);
212 static uint32_t Cy_Flash_GetRowNum(uint32_t flashAddr);
213 static cy_en_flashdrv_status_t Cy_Flash_ProcessOpcode(uint32_t opcode);
214 static cy_en_flashdrv_status_t Cy_Flash_OperationStatus(void);
215 static cy_en_flashdrv_status_t Cy_Flash_SendCmd(uint32_t mode, uint32_t microseconds);
216
217 static volatile cy_stc_flash_context_t flashContext;
218
219
220 #if !defined (CY_FLASH_RWW_DRV_SUPPORT_DISABLED)
221 /*******************************************************************************
222 * Function Name: Cy_Flash_InitExt
223 ****************************************************************************//**
224 *
225 * Initiates all needed prerequisites to support flash erase/write.
226 * Should be called from each core. Defines the address of the message structure.
227 *
228 * Requires a call to Cy_IPC_Sema_Init(), Cy_IPC_Pipe_Config() and
229 * Cy_IPC_Pipe_Init() functions before use.
230 *
231 * This function is called in the Cy_Flash_Init() function - see the
232 * \ref Cy_Flash_Init usage considerations.
233 *
234 *******************************************************************************/
Cy_Flash_InitExt(cy_stc_flash_notify_t * ipcWaitMessageAddr)235 void Cy_Flash_InitExt(cy_stc_flash_notify_t *ipcWaitMessageAddr)
236 {
237 ipcWaitMessage = ipcWaitMessageAddr;
238
239 if(ipcWaitMessage != NULL)
240 {
241 ipcWaitMessage->clientID = CY_FLASH_IPC_CLIENT_ID;
242 ipcWaitMessage->pktType = CY_FLASH_ENTER_WAIT_LOOP;
243 ipcWaitMessage->intrRelMask = 0U;
244 }
245
246 if (cy_device->flashRwwRequired != 0U)
247 {
248 #if (CY_CPU_CORTEX_M4)
249 cy_stc_sysint_t flashIntConfig =
250 {
251 (IRQn_Type)cy_device->cpussFmIrq, /* .intrSrc */
252 0U /* .intrPriority */
253 };
254
255 (void)Cy_SysInt_Init(&flashIntConfig, &Cy_Flash_ResumeIrqHandler);
256 NVIC_EnableIRQ(flashIntConfig.intrSrc);
257 #endif
258
259 if (cy_device->flashPipeRequired != 0U)
260 {
261 (void)Cy_IPC_Pipe_RegisterCallback(CY_IPC_EP_CYPIPE_ADDR, &Cy_Flash_NotifyHandler,
262 (uint32_t)CY_FLASH_IPC_CLIENT_ID);
263 }
264 }
265 }
266
267
268 /*******************************************************************************
269 * Function Name: Cy_Flash_NotifyHandler
270 ****************************************************************************//**
271 *
272 * This is the interrupt service routine for the pipe notifications.
273 *
274 *******************************************************************************/
275 CY_SECTION_RAMFUNC_BEGIN
276 #if !defined (__ICCARM__)
277 CY_NOINLINE
278 #endif
Cy_Flash_NotifyHandler(uint32_t * msgPtr)279 static void Cy_Flash_NotifyHandler(uint32_t * msgPtr)
280 {
281 #if !((CY_CPU_CORTEX_M0P) && (defined (CY_DEVICE_SECURE)))
282 uint32_t intr;
283 #endif /* !((CY_CPU_CORTEX_M0P) && (defined (CY_DEVICE_SECURE))) */
284 static uint32_t semaIndex;
285 static uint32_t semaMask;
286 static volatile uint32_t *semaPtr;
287 static cy_stc_ipc_sema_t *semaStruct;
288
289 cy_stc_flash_notify_t *ipcMsgPtr = (cy_stc_flash_notify_t *) (void *) msgPtr;
290
291 if (CY_FLASH_ENTER_WAIT_LOOP == ipcMsgPtr->pktType)
292 {
293 #if !((CY_CPU_CORTEX_M0P) && (defined (CY_DEVICE_SECURE)))
294 intr = Cy_SysLib_EnterCriticalSection();
295 #endif /* !((CY_CPU_CORTEX_M0P) && (defined (CY_DEVICE_SECURE))) */
296
297 /* Get pointer to structure */
298 semaStruct = (cy_stc_ipc_sema_t *)Cy_IPC_Drv_ReadDataValue(Cy_IPC_Drv_GetIpcBaseAddress(CY_IPC_CHAN_SEMA));
299
300 /* Get the index into the semaphore array and calculate the mask */
301 semaIndex = CY_FLASH_WAIT_SEMA / CY_IPC_SEMA_PER_WORD;
302 semaMask = (uint32_t)(1UL << (CY_FLASH_WAIT_SEMA - (semaIndex * CY_IPC_SEMA_PER_WORD) ));
303 semaPtr = &semaStruct->arrayPtr[semaIndex];
304
305 /* Notification to the Flash driver to start the current operation */
306 *semaPtr |= semaMask;
307
308 /* Check a notification from other core to end of waiting */
309 while (((*semaPtr) & semaMask) != 0UL)
310 {
311 }
312
313 #if !((CY_CPU_CORTEX_M0P) && (defined (CY_DEVICE_SECURE)))
314 Cy_SysLib_ExitCriticalSection(intr);
315 #endif /* !((CY_CPU_CORTEX_M0P) && (defined (CY_DEVICE_SECURE))) */
316 }
317 }
318 CY_SECTION_RAMFUNC_END
319 #endif /* !defined(CY_FLASH_RWW_DRV_SUPPORT_DISABLED) */
320
321
322 /*******************************************************************************
323 * Function Name: Cy_Flash_Init
324 ****************************************************************************//**
325 *
326 * Initiates all needed prerequisites to support flash erase/write.
327 * Should be called from each core.
328 *
329 * Requires a call to Cy_IPC_Sema_Init(), Cy_IPC_Pipe_Config() and
330 * Cy_IPC_Pipe_Init() functions before use.
331 *
332 * This function is called in the SystemInit() function, for proper flash write
333 * and erase operations. If the default startup file is not used, or the function
334 * SystemInit() is not called in your project, ensure to perform the following steps
335 * before any flash or EmEEPROM write/erase operations:
336 * \snippet flash/snippet/main.c Flash Initialization
337 *
338 *******************************************************************************/
Cy_Flash_Init(void)339 void Cy_Flash_Init(void)
340 {
341 #if !defined (CY_FLASH_RWW_DRV_SUPPORT_DISABLED)
342 CY_SECTION_SHAREDMEM
343 CY_ALIGN(4) static cy_stc_flash_notify_t ipcWaitMessageStc;
344
345 Cy_Flash_InitExt(&ipcWaitMessageStc);
346 #endif /* !defined (CY_FLASH_RWW_DRV_SUPPORT_DISABLED) */
347 }
348
349
350 /*******************************************************************************
351 * Function Name: Cy_Flash_SendCmd
352 ****************************************************************************//**
353 *
354 * Sends a command to the SROM via the IPC channel. The function is placed to the
355 * SRAM memory to guarantee successful operation. After an IPC message is sent,
356 * the function waits for a defined time before exiting the function.
357 *
358 * \param mode
359 * Sets the blocking or non-blocking Flash operation.
360 *
361 * \param microseconds
362 * The number of microseconds to wait before exiting the functions
363 * in range 0-65535 us.
364 *
365 * \return Returns the status of the Flash operation,
366 * see \ref cy_en_flashdrv_status_t.
367 *
368 *******************************************************************************/
369 CY_SECTION_RAMFUNC_BEGIN
370 #if !defined (__ICCARM__)
371 CY_NOINLINE
372 #endif
Cy_Flash_SendCmd(uint32_t mode,uint32_t microseconds)373 static cy_en_flashdrv_status_t Cy_Flash_SendCmd(uint32_t mode, uint32_t microseconds)
374 {
375 cy_en_flashdrv_status_t result = CY_FLASH_DRV_IPC_BUSY;
376 IPC_STRUCT_Type * locIpcBase = Cy_IPC_Drv_GetIpcBaseAddress(CY_IPC_CHAN_SYSCALL);
377 volatile uint32_t *ipcLockStatus = ®_IPC_STRUCT_LOCK_STATUS(locIpcBase);
378
379 #if !defined (CY_FLASH_RWW_DRV_SUPPORT_DISABLED)
380 uint32_t intr;
381 uint32_t semaTryCount = 0uL;
382
383 if (cy_device->flashRwwRequired != 0U)
384 {
385 /* Check for active core is CM0+, or CM4 on single core device */
386 #if (CY_CPU_CORTEX_M0P)
387 bool isPeerCoreEnabled = (CY_SYS_CM4_STATUS_ENABLED == Cy_SysGetCM4Status());
388 #else
389 bool isPeerCoreEnabled = false;
390
391 if (SFLASH_SINGLE_CORE == 0U)
392 {
393 isPeerCoreEnabled = true;
394 }
395 #endif
396
397 if (!isPeerCoreEnabled)
398 {
399 result = CY_FLASH_DRV_SUCCESS;
400 }
401 else
402 {
403 if (IS_CY_PIPE_FREE())
404 {
405 if (CY_IPC_SEMA_STATUS_LOCKED != Cy_IPC_Sema_Status(CY_FLASH_WAIT_SEMA))
406 {
407 if (CY_IPC_PIPE_SUCCESS == NOTIFY_PEER_CORE(ipcWaitMessage))
408 {
409 /* Wait for SEMA lock by peer core */
410 while ((CY_IPC_SEMA_STATUS_LOCKED != Cy_IPC_Sema_Status(CY_FLASH_WAIT_SEMA)) && ((semaTryCount < CY_FLASH_SEMA_WAIT_MAX_TRIES)))
411 {
412 /* check for timeout (as maximum tries count) */
413 ++semaTryCount;
414 }
415
416 if (semaTryCount < CY_FLASH_SEMA_WAIT_MAX_TRIES)
417 {
418 result = CY_FLASH_DRV_SUCCESS;
419 }
420 }
421 }
422 }
423 }
424
425 if (CY_FLASH_DRV_SUCCESS == result)
426 {
427 /* Notifier is ready, start of the operation */
428 intr = Cy_SysLib_EnterCriticalSection();
429
430 if (0UL != _FLD2VAL(SRSS_CLK_CAL_CNT1_CAL_COUNTER_DONE, SRSS_CLK_CAL_CNT1))
431 {
432 /* Tries to acquire the IPC structure and pass the arguments to SROM API */
433 if (Cy_IPC_Drv_SendMsgPtr(locIpcBase, CY_FLASH_IPC_NOTIFY_STRUCT0, (void*)&flashContext) == CY_IPC_DRV_SUCCESS)
434 {
435 Cy_Flash_RAMDelay(microseconds);
436
437 if (mode == CY_FLASH_NON_BLOCKING_MODE)
438 {
439 /* The Flash operation is successfully initiated */
440 result = CY_FLASH_DRV_OPERATION_STARTED;
441 }
442 else
443 {
444 while (0U != _FLD2VAL(IPC_STRUCT_ACQUIRE_SUCCESS, *ipcLockStatus))
445 {
446 /* Polls whether the IPC is released and the Flash operation is performed */
447 }
448 result = Cy_Flash_OperationStatus();
449 }
450 }
451 else
452 {
453 /* The IPC structure is already locked by another process */
454 result = CY_FLASH_DRV_IPC_BUSY;
455 }
456 }
457 else
458 {
459 /* SysClk measurement counter is busy */
460 result = CY_FLASH_DRV_IPC_BUSY;
461 }
462
463 if (isPeerCoreEnabled)
464 {
465 while (CY_IPC_SEMA_SUCCESS != Cy_IPC_Sema_Clear(CY_FLASH_WAIT_SEMA, true))
466 {
467 /* Clear SEMA lock */
468 }
469 }
470
471 Cy_SysLib_ExitCriticalSection(intr);
472 /* End of the flash operation */
473 }
474 }
475 else
476 #endif /* !defined (CY_FLASH_RWW_DRV_SUPPORT_DISABLED) */
477 {
478 #if !defined (CY_FLASH_RWW_DRV_SUPPORT_DISABLED)
479 intr = Cy_SysLib_EnterCriticalSection();
480 #endif /* !defined (CY_FLASH_RWW_DRV_SUPPORT_DISABLED) */
481 /* Tries to acquire the IPC structure and pass the arguments to SROM API */
482 if (Cy_IPC_Drv_SendMsgPtr(locIpcBase, CY_FLASH_IPC_NOTIFY_STRUCT0, (void*)&flashContext) == CY_IPC_DRV_SUCCESS)
483 {
484 if (mode == CY_FLASH_NON_BLOCKING_MODE)
485 {
486 /* The Flash operation is successfully initiated */
487 result = CY_FLASH_DRV_OPERATION_STARTED;
488 }
489 else
490 {
491 while (0U != _FLD2VAL(IPC_STRUCT_ACQUIRE_SUCCESS, *ipcLockStatus))
492 {
493 /* Polls whether the IPC is released and the Flash operation is performed */
494 }
495
496 result = Cy_Flash_OperationStatus();
497 }
498 }
499 else
500 {
501 /* The IPC structure is already locked by another process */
502 result = CY_FLASH_DRV_IPC_BUSY;
503 }
504 #if !defined (CY_FLASH_RWW_DRV_SUPPORT_DISABLED)
505 Cy_SysLib_ExitCriticalSection(intr);
506 #endif /* !defined (CY_FLASH_RWW_DRV_SUPPORT_DISABLED) */
507 }
508
509 return (result);
510 }
511 CY_SECTION_RAMFUNC_END
512
513
514 #if !defined (CY_FLASH_RWW_DRV_SUPPORT_DISABLED)
515 /*******************************************************************************
516 * Function Name: Cy_Flash_RAMDelay
517 ****************************************************************************//**
518 *
519 * Wait for a defined time in the SRAM memory region.
520 *
521 * \param microseconds
522 * Delay time in microseconds in range 0-65535 us.
523 *
524 *******************************************************************************/
525 CY_SECTION_RAMFUNC_BEGIN
526 #if !defined (__ICCARM__)
527 CY_NOINLINE
528 #endif
Cy_Flash_RAMDelay(uint32_t microseconds)529 static void Cy_Flash_RAMDelay(uint32_t microseconds)
530 {
531 uint32_t ticks = (microseconds & 0xFFFFUL) * CY_FLASH_TICKS_FOR_1US;
532 if (ticks != CY_FLASH_NO_DELAY)
533 {
534 /* Acquire the IPC to prevent changing of the shared resources at the same time */
535 while(0U == _FLD2VAL(IPC_STRUCT_ACQUIRE_SUCCESS, REG_IPC_STRUCT_ACQUIRE(CY_IPC_STRUCT_PTR(CY_IPC_CHAN_DDFT))))
536 {
537 /* Wait until the IPC structure is released by another process */
538 }
539
540 SRSS_TST_DDFT_FAST_CTL_REG = SRSS_TST_DDFT_FAST_CTL_MASK;
541 SRSS_TST_DDFT_SLOW_CTL_REG = SRSS_TST_DDFT_SLOW_CTL_MASK;
542
543 SRSS_CLK_OUTPUT_SLOW = _VAL2FLD(SRSS_CLK_OUTPUT_SLOW_SLOW_SEL0, CY_SYSCLK_MEAS_CLK_IMO) |
544 _VAL2FLD(SRSS_CLK_OUTPUT_SLOW_SLOW_SEL1, CY_FLASH_CLK_OUTPUT_DISABLED);
545
546 /* Load the down-counter without status bit value */
547 SRSS_CLK_CAL_CNT1 = _VAL2FLD(SRSS_CLK_CAL_CNT1_CAL_COUNTER1, ticks);
548
549 /* Make sure that the counter is started */
550 ticks = _FLD2VAL(SRSS_CLK_CAL_CNT1_CAL_COUNTER_DONE, SRSS_CLK_CAL_CNT1);
551
552 /* Release the IPC */
553 REG_IPC_STRUCT_RELEASE(CY_IPC_STRUCT_PTR(CY_IPC_CHAN_DDFT)) = 0U;
554
555 while (0UL == _FLD2VAL(SRSS_CLK_CAL_CNT1_CAL_COUNTER_DONE, SRSS_CLK_CAL_CNT1))
556 {
557 /* Wait until the counter stops counting */
558 }
559 }
560 }
561 CY_SECTION_RAMFUNC_END
562
563 #if (CY_CPU_CORTEX_M4)
564
565 /* Based on bookmark codes of mxs40srompsoc BROS,002-03298 */
566 #define CY_FLASH_PROGRAM_ROW_BOOKMARK (0x00000001UL)
567 #define CY_FLASH_ERASE_ROW_BOOKMARK (0x00000002UL)
568 #define CY_FLASH_WRITE_ROW_ERASE_BOOKMARK (0x00000003UL)
569 #define CY_FLASH_WRITE_ROW_PROGRAM_BOOKMARK (0x00000004UL)
570
571 /* Number of the CM0P ticks for function delay corrective time at final stage */
572 #define CY_FLASH_FINAL_STAGE_DELAY_TICKS (1000UL)
573 #define CY_FLASH_FINAL_STAGE_DELAY (130UL + CY_FLASH_DELAY_CORRECTIVE(CY_FLASH_FINAL_STAGE_DELAY_TICKS))
574
575
576 /*******************************************************************************
577 * Function Name: Cy_Flash_ResumeIrqHandler
578 ****************************************************************************//**
579 *
580 * This is the interrupt service routine to make additional processing of the
581 * flash operations resume phase.
582 *
583 *******************************************************************************/
584 CY_SECTION_RAMFUNC_BEGIN
585 #if !defined (__ICCARM__)
586 CY_NOINLINE
587 #endif
Cy_Flash_ResumeIrqHandler(void)588 void Cy_Flash_ResumeIrqHandler(void)
589 {
590 IPC_STRUCT_Type * locIpcBase = Cy_IPC_Drv_GetIpcBaseAddress(CY_IPC_CHAN_CYPIPE_EP0);
591
592 uint32_t bookmark;
593 #if ((CY_CPU_CORTEX_M4) && (defined (CY_DEVICE_SECURE)))
594 bookmark = CY_PRA_REG32_GET(CY_PRA_INDX_FLASHC_FM_CTL_BOOKMARK) & 0xffffUL;
595 #else
596 bookmark = FLASHC_FM_CTL_BOOKMARK & 0xffffUL;
597 #endif /* ((CY_CPU_CORTEX_M4) && (defined (CY_DEVICE_SECURE))) */
598
599 uint32_t intr = Cy_SysLib_EnterCriticalSection();
600
601 uint32_t cm0s = CPUSS_CM0_STATUS;
602 bool sflashSingleCore = (0U == SFLASH_SINGLE_CORE);
603
604 if ((bookmark == CY_FLASH_PROGRAM_ROW_BOOKMARK) || (bookmark == CY_FLASH_ERASE_ROW_BOOKMARK) ||
605 (bookmark == CY_FLASH_WRITE_ROW_ERASE_BOOKMARK) || (bookmark == CY_FLASH_WRITE_ROW_PROGRAM_BOOKMARK))
606 {
607 if ((cm0s == (CPUSS_CM0_STATUS_SLEEPING_Msk | CPUSS_CM0_STATUS_SLEEPDEEP_Msk)) && sflashSingleCore)
608 {
609 REG_IPC_STRUCT_NOTIFY(locIpcBase) = _VAL2FLD(IPC_STRUCT_NOTIFY_INTR_NOTIFY, (1UL << CY_IPC_INTR_CYPIPE_EP0));
610 while (CPUSS_CM0_STATUS == (CPUSS_CM0_STATUS_SLEEPING_Msk | CPUSS_CM0_STATUS_SLEEPDEEP_Msk))
611 {
612 /* Wait until the core is active */
613 }
614 }
615 Cy_Flash_RAMDelay(CY_FLASH_FINAL_STAGE_DELAY);
616 }
617
618 Cy_SysLib_ExitCriticalSection(intr);
619 }
620 CY_SECTION_RAMFUNC_END
621 #endif /* (CY_CPU_CORTEX_M4) */
622 #endif /* !defined (CY_FLASH_RWW_DRV_SUPPORT_DISABLED) */
623
624
625 /*******************************************************************************
626 * Function Name: Cy_Flash_EraseRow
627 ****************************************************************************//**
628 *
629 * This function erases a single row of flash. Reports success or
630 * a reason for failure. Does not return until the Write operation is
631 * complete. Returns immediately and reports a \ref CY_FLASH_DRV_IPC_BUSY error in
632 * the case when another process is writing to flash or erasing the row.
633 * User firmware should not enter the Hibernate or Deep Sleep mode until flash Erase
634 * is complete. The Flash operation is allowed in Sleep mode.
635 * During the Flash operation, the device should not be reset, including the
636 * XRES pin, a software reset, and watchdog reset sources. Also, low-voltage
637 * detect circuits should be configured to generate an interrupt instead of a
638 * reset. Otherwise, portions of flash may undergo unexpected changes.
639 * \note A Read while Write violation occurs when a flash Read operation is initiated
640 * in the same or neighboring flash sector where the flash Write, Erase, or
641 * Program operation is working. This violation may cause a HardFault exception.
642 * To avoid the Read while Write violation,
643 * use Cy_Flash_IsOperationComplete() to ensure flash operation is complete.
644 *
645 * \param rowAddr Address of the flash row number.
646 * The Read-while-Write violation occurs when the flash read operation is
647 * initiated in the same flash sector where the flash write operation is
648 * performing. Refer to the device datasheet for the details.
649 * Address must match row start address.
650 *
651 * \return Returns the status of the Flash operation,
652 * see \ref cy_en_flashdrv_status_t.
653 *
654 *******************************************************************************/
Cy_Flash_EraseRow(uint32_t rowAddr)655 cy_en_flashdrv_status_t Cy_Flash_EraseRow(uint32_t rowAddr)
656 {
657 cy_en_flashdrv_status_t result = CY_FLASH_DRV_INVALID_INPUT_PARAMETERS;
658
659 /* Prepares arguments to be passed to SROM API */
660 if (Cy_Flash_BoundsCheck(rowAddr) != false)
661 {
662 SystemCoreClockUpdate();
663
664 flashContext.opcode = CY_FLASH_OPCODE_ERASE_ROW | CY_FLASH_BLOCKING_MODE;
665 flashContext.arg1 = rowAddr;
666 flashContext.arg2 = 0UL;
667 flashContext.arg3 = 0UL;
668
669 if (cy_device->flashEraseDelay != 0U)
670 {
671 result = Cy_Flash_SendCmd(CY_FLASH_BLOCKING_MODE, CY_FLASH_START_ERASE_DELAY);
672 }
673 else
674 {
675 result = Cy_Flash_SendCmd(CY_FLASH_BLOCKING_MODE, CY_FLASH_NO_DELAY);
676 }
677 }
678
679 return (result);
680 }
681
682
683 /*******************************************************************************
684 * Function Name: Cy_Flash_StartEraseRow
685 ****************************************************************************//**
686 *
687 * Starts erasing a single row of flash. Returns immediately
688 * and reports a successful start or reason for failure.
689 * Reports a \ref CY_FLASH_DRV_IPC_BUSY error in the case when IPC structure is locked
690 * by another process. User firmware should not enter the Hibernate or Deep Sleep mode until
691 * flash Erase is complete. The Flash operation is allowed in Sleep mode.
692 * During the flash operation, the device should not be reset, including the
693 * XRES pin, a software reset, and watchdog reset sources. Also, the low-voltage
694 * detect circuits should be configured to generate an interrupt instead of a reset.
695 * Otherwise, portions of flash may undergo unexpected changes.
696 * \note To avoid situation of reading data from cache memory - before
697 * reading data from previously programmed/erased flash rows, the user must
698 * clear the flash cache with the Cy_SysLib_ClearFlashCacheAndBuffer()
699 * function.
700 * \note A Read while Write violation occurs when a flash Read operation is initiated
701 * in the same or neighboring flash sector where the flash Write, Erase, or
702 * Program operation is working. This violation may cause a HardFault exception.
703 * To avoid the Read while Write violation,
704 * use Cy_Flash_IsOperationComplete() to ensure flash operation is complete.
705 *
706 * \param rowAddr Address of the flash row number.
707 * The Read-while-Write violation occurs when the flash read operation is
708 * initiated in the same flash sector where the flash erase operation is
709 * performing. Refer to the device datasheet for the details.
710 * Address must match row start address.
711 *
712 * \return Returns the status of the Flash operation,
713 * see \ref cy_en_flashdrv_status_t.
714 *
715 *******************************************************************************/
Cy_Flash_StartEraseRow(uint32_t rowAddr)716 cy_en_flashdrv_status_t Cy_Flash_StartEraseRow(uint32_t rowAddr)
717 {
718 cy_en_flashdrv_status_t result = CY_FLASH_DRV_INVALID_INPUT_PARAMETERS;
719
720 if (Cy_Flash_BoundsCheck(rowAddr) != false)
721 {
722 SystemCoreClockUpdate();
723
724 /* Prepares arguments to be passed to SROM API */
725 flashContext.opcode = CY_FLASH_OPCODE_ERASE_ROW;
726 if (SFLASH_SINGLE_CORE != 0U)
727 {
728 flashContext.opcode |= CY_FLASH_BLOCKING_MODE;
729 }
730
731 flashContext.arg1 = rowAddr;
732 flashContext.arg2 = 0UL;
733 flashContext.arg3 = 0UL;
734
735 if (cy_device->flashEraseDelay != 0U)
736 {
737 result = Cy_Flash_SendCmd(CY_FLASH_NON_BLOCKING_MODE, CY_FLASH_START_ERASE_DELAY);
738 }
739 else
740 {
741 result = Cy_Flash_SendCmd(CY_FLASH_NON_BLOCKING_MODE, CY_FLASH_NO_DELAY);
742 }
743 }
744
745 return (result);
746 }
747
748
749 /*******************************************************************************
750 * Function Name: Cy_Flash_EraseSector
751 ****************************************************************************//**
752 *
753 * This function erases a sector of flash. Reports success or
754 * a reason for failure. Does not return until the Erase operation is
755 * complete. Returns immediately and reports a \ref CY_FLASH_DRV_IPC_BUSY error in
756 * the case when another process is writing to flash or erasing the row.
757 * User firmware should not enter the Hibernate or Deep Sleep mode until flash Erase
758 * is complete. The Flash operation is allowed in Sleep mode.
759 * During the Flash operation, the device should not be reset, including the
760 * XRES pin, a software reset, and watchdog reset sources. Also, low-voltage
761 * detect circuits should be configured to generate an interrupt instead of a
762 * reset. Otherwise, portions of flash may undergo unexpected changes.
763 * \note A Read while Write violation occurs when a flash Read operation is initiated
764 * in the same or neighboring flash sector where the flash Write, Erase, or
765 * Program operation is working. This violation may cause a HardFault exception.
766 * To avoid the Read while Write violation,
767 * use Cy_Flash_IsOperationComplete() to ensure flash operation is complete.
768 *
769 * \param sectorAddr Address of the flash row number.
770 * The Read-while-Write violation occurs when the flash read operation is
771 * initiated in the same flash sector where the flash write operation is
772 * performing. Refer to the device datasheet for the details.
773 * Address must match row start address.
774 *
775 * \return Returns the status of the Flash operation,
776 * see \ref cy_en_flashdrv_status_t.
777 *
778 *******************************************************************************/
Cy_Flash_EraseSector(uint32_t sectorAddr)779 cy_en_flashdrv_status_t Cy_Flash_EraseSector(uint32_t sectorAddr)
780 {
781 cy_en_flashdrv_status_t result = CY_FLASH_DRV_INVALID_INPUT_PARAMETERS;
782
783 /* Prepares arguments to be passed to SROM API */
784 if (Cy_Flash_BoundsCheck(sectorAddr) != false)
785 {
786 SystemCoreClockUpdate();
787
788 flashContext.opcode = CY_FLASH_OPCODE_ERASE_SECTOR | CY_FLASH_BLOCKING_MODE;
789 flashContext.arg1 = sectorAddr;
790 flashContext.arg2 = 0UL;
791 flashContext.arg3 = 0UL;
792
793 if (cy_device->flashEraseDelay != 0U)
794 {
795 result = Cy_Flash_SendCmd(CY_FLASH_BLOCKING_MODE, CY_FLASH_START_ERASE_DELAY);
796 }
797 else
798 {
799 result = Cy_Flash_SendCmd(CY_FLASH_BLOCKING_MODE, CY_FLASH_NO_DELAY);
800 }
801 }
802
803 return (result);
804 }
805
806
807 /*******************************************************************************
808 * Function Name: Cy_Flash_StartEraseSector
809 ****************************************************************************//**
810 *
811 * Starts erasing a sector of flash. Returns immediately
812 * and reports a successful start or reason for failure.
813 * Reports a \ref CY_FLASH_DRV_IPC_BUSY error in the case when IPC structure is locked
814 * by another process. User firmware should not enter the Hibernate or Deep Sleep mode until
815 * flash Erase is complete. The Flash operation is allowed in Sleep mode.
816 * During the flash operation, the device should not be reset, including the
817 * XRES pin, a software reset, and watchdog reset sources. Also, the low-voltage
818 * detect circuits should be configured to generate an interrupt instead of a reset.
819 * Otherwise, portions of flash may undergo unexpected changes.
820 * \note Before reading data from previously programmed/erased flash rows, the
821 * user must clear the flash cache with the Cy_SysLib_ClearFlashCacheAndBuffer()
822 * function.
823 * \note A Read while Write violation occurs when a flash Read operation is initiated
824 * in the same or neighboring flash sector where the flash Write, Erase, or
825 * Program operation is working. This violation may cause a HardFault exception.
826 * To avoid the Read while Write violation,
827 * use Cy_Flash_IsOperationComplete() to ensure flash operation is complete.
828 *
829 * \param sectorAddr Address of the flash row number.
830 * The Read-while-Write violation occurs when the flash read operation is
831 * initiated in the same flash sector where the flash erase operation is
832 * performing. Refer to the device datasheet for the details.
833 * Address must match row start address.
834 *
835 * \return Returns the status of the Flash operation,
836 * see \ref cy_en_flashdrv_status_t.
837 *
838 *******************************************************************************/
Cy_Flash_StartEraseSector(uint32_t sectorAddr)839 cy_en_flashdrv_status_t Cy_Flash_StartEraseSector(uint32_t sectorAddr)
840 {
841 cy_en_flashdrv_status_t result = CY_FLASH_DRV_INVALID_INPUT_PARAMETERS;
842
843 if (Cy_Flash_BoundsCheck(sectorAddr) != false)
844 {
845 SystemCoreClockUpdate();
846
847 /* Prepares arguments to be passed to SROM API */
848 flashContext.opcode = CY_FLASH_OPCODE_ERASE_SECTOR;
849 if (SFLASH_SINGLE_CORE != 0U)
850 {
851 flashContext.opcode |= CY_FLASH_BLOCKING_MODE;
852 }
853
854 flashContext.arg1 = sectorAddr;
855 flashContext.arg2 = 0UL;
856 flashContext.arg3 = 0UL;
857
858 if (cy_device->flashEraseDelay != 0U)
859 {
860 result = Cy_Flash_SendCmd(CY_FLASH_NON_BLOCKING_MODE, CY_FLASH_START_ERASE_DELAY);
861 }
862 else
863 {
864 result = Cy_Flash_SendCmd(CY_FLASH_NON_BLOCKING_MODE, CY_FLASH_NO_DELAY);
865 }
866 }
867
868 return (result);
869 }
870
871
872 /*******************************************************************************
873 * Function Name: Cy_Flash_EraseSubsector
874 ****************************************************************************//**
875 *
876 * This function erases an 8-row subsector of flash. Reports success or
877 * a reason for failure. Does not return until the Write operation is
878 * complete. Returns immediately and reports a \ref CY_FLASH_DRV_IPC_BUSY error in
879 * the case when another process is writing to flash or erasing the row.
880 * User firmware should not enter the Hibernate or Deep-Sleep mode until flash Erase
881 * is complete. The Flash operation is allowed in Sleep mode.
882 * During the Flash operation, the device should not be reset, including the
883 * XRES pin, a software reset, and watchdog reset sources. Also, low-voltage
884 * detect circuits should be configured to generate an interrupt instead of a
885 * reset. Otherwise, portions of flash may undergo unexpected changes.
886 * \note A Read while Write violation occurs when a flash Read operation is initiated
887 * in the same or neighboring flash sector where the flash Write, Erase, or
888 * Program operation is working. This violation may cause a HardFault exception.
889 * To avoid the Read while Write violation,
890 * use Cy_Flash_IsOperationComplete() to ensure flash operation is complete.
891 *
892 * \param subSectorAddr Address of the flash row number.
893 * The Read-while-Write violation occurs when the flash read operation is
894 * initiated in the same flash sector where the flash write operation is
895 * performing. Refer to the device datasheet for the details.
896 * Address must match row start address.
897 *
898 * \return Returns the status of the Flash operation,
899 * see \ref cy_en_flashdrv_status_t.
900 *
901 *******************************************************************************/
Cy_Flash_EraseSubsector(uint32_t subSectorAddr)902 cy_en_flashdrv_status_t Cy_Flash_EraseSubsector(uint32_t subSectorAddr)
903 {
904 cy_en_flashdrv_status_t result = CY_FLASH_DRV_INVALID_INPUT_PARAMETERS;
905
906 /* Prepares arguments to be passed to SROM API */
907 if (Cy_Flash_BoundsCheck(subSectorAddr) != false)
908 {
909 SystemCoreClockUpdate();
910
911 flashContext.opcode = CY_FLASH_OPCODE_ERASE_SUB_SECTOR | CY_FLASH_BLOCKING_MODE;
912 flashContext.arg1 = subSectorAddr;
913 flashContext.arg2 = 0UL;
914 flashContext.arg3 = 0UL;
915
916 if (cy_device->flashEraseDelay != 0U)
917 {
918 result = Cy_Flash_SendCmd(CY_FLASH_BLOCKING_MODE, CY_FLASH_START_ERASE_DELAY);
919 }
920 else
921 {
922 result = Cy_Flash_SendCmd(CY_FLASH_BLOCKING_MODE, CY_FLASH_NO_DELAY);
923 }
924 }
925
926 return (result);
927 }
928
929
930 /*******************************************************************************
931 * Function Name: Cy_Flash_StartEraseSubsector
932 ****************************************************************************//**
933 *
934 * Starts erasing an 8-row subsector of flash. Returns immediately
935 * and reports a successful start or reason for failure.
936 * Reports a \ref CY_FLASH_DRV_IPC_BUSY error in the case when IPC structure is locked
937 * by another process. User firmware should not enter the Hibernate or Deep-Sleep mode until
938 * flash Erase is complete. The Flash operation is allowed in Sleep mode.
939 * During the flash operation, the device should not be reset, including the
940 * XRES pin, a software reset, and watchdog reset sources. Also, the low-voltage
941 * detect circuits should be configured to generate an interrupt instead of a reset.
942 * Otherwise, portions of flash may undergo unexpected changes.
943 * \note Before reading data from previously programmed/erased flash rows, the
944 * user must clear the flash cache with the Cy_SysLib_ClearFlashCacheAndBuffer()
945 * function.
946 * \note A Read while Write violation occurs when a flash Read operation is initiated
947 * in the same or neighboring flash sector where the flash Write, Erase, or
948 * Program operation is working. This violation may cause a HardFault exception.
949 * To avoid the Read while Write violation,
950 * use Cy_Flash_IsOperationComplete() to ensure flash operation is complete.
951 *
952 * \param subSectorAddr Address of the flash row number.
953 * The Read-while-Write violation occurs when the flash read operation is
954 * initiated in the same flash sector where the flash erase operation is
955 * performing. Refer to the device datasheet for the details.
956 * Address must match row start address.
957 *
958 * \return Returns the status of the Flash operation,
959 * see \ref cy_en_flashdrv_status_t.
960 *
961 *******************************************************************************/
Cy_Flash_StartEraseSubsector(uint32_t subSectorAddr)962 cy_en_flashdrv_status_t Cy_Flash_StartEraseSubsector(uint32_t subSectorAddr)
963 {
964 cy_en_flashdrv_status_t result = CY_FLASH_DRV_INVALID_INPUT_PARAMETERS;
965
966 if (Cy_Flash_BoundsCheck(subSectorAddr) != false)
967 {
968 SystemCoreClockUpdate();
969
970 /* Prepares arguments to be passed to SROM API */
971 flashContext.opcode = CY_FLASH_OPCODE_ERASE_SUB_SECTOR;
972 if (SFLASH_SINGLE_CORE != 0U)
973 {
974 flashContext.opcode |= CY_FLASH_BLOCKING_MODE;
975 }
976
977 flashContext.arg1 = subSectorAddr;
978 flashContext.arg2 = 0UL;
979 flashContext.arg3 = 0UL;
980
981 if (cy_device->flashEraseDelay != 0U)
982 {
983 result = Cy_Flash_SendCmd(CY_FLASH_NON_BLOCKING_MODE, CY_FLASH_START_ERASE_DELAY);
984 }
985 else
986 {
987 result = Cy_Flash_SendCmd(CY_FLASH_NON_BLOCKING_MODE, CY_FLASH_NO_DELAY);
988 }
989 }
990
991 return (result);
992 }
993
994
995 /*******************************************************************************
996 * Function Name: Cy_Flash_ProgramRow
997 ****************************************************************************//**
998 *
999 * This function writes an array of data to a single row of flash. Reports
1000 * success or a reason for failure. Does not return until the Program operation
1001 * is complete.
1002 * Returns immediately and reports a \ref CY_FLASH_DRV_IPC_BUSY error in the case
1003 * when another process is writing to flash. User firmware should not enter the
1004 * Hibernate or Deep-sleep mode until flash Write is complete. The Flash operation
1005 * is allowed in Sleep mode. During the Flash operation, the device should not be
1006 * reset, including the XRES pin, a software reset, and watchdog reset sources.
1007 * Also, low-voltage detect circuits should be configured to generate an interrupt
1008 * instead of a reset. Otherwise, portions of flash may undergo unexpected
1009 * changes.\n
1010 * Before calling this function, the target flash region must be erased by
1011 * the StartErase/EraseRow function.\n
1012 * Data to be programmed must be located in the SRAM memory region.
1013 * \note Before reading data from previously programmed/erased flash rows, the
1014 * user must clear the flash cache with the Cy_SysLib_ClearFlashCacheAndBuffer()
1015 * function.
1016 * \note A Read while Write violation occurs when a flash Read operation is initiated
1017 * in the same or neighboring flash sector where the flash Write, Erase, or
1018 * Program operation is working. This violation may cause a HardFault exception.
1019 * To avoid the Read while Write violation,
1020 * use Cy_Flash_IsOperationComplete() to ensure flash operation is complete.
1021 *
1022 * \param rowAddr Address of the flash row number.
1023 * The Read-while-Write violation occurs when the flash read operation is
1024 * initiated in the same flash sector where the flash write operation is
1025 * performing. Refer to the device datasheet for the details.
1026 * Address must match row start address.
1027 *
1028 * \param data The pointer to the data which has to be written to flash. The size
1029 * of the data array must be equal to the flash row size. The flash row size for
1030 * the selected device is defined by the \ref CY_FLASH_SIZEOF_ROW macro. Refer to
1031 * the device datasheet for the details.
1032 *
1033 * \return Returns the status of the Flash operation,
1034 * see \ref cy_en_flashdrv_status_t.
1035 *
1036 *******************************************************************************/
Cy_Flash_ProgramRow(uint32_t rowAddr,const uint32_t * data)1037 cy_en_flashdrv_status_t Cy_Flash_ProgramRow(uint32_t rowAddr, const uint32_t* data)
1038 {
1039 cy_en_flashdrv_status_t result = CY_FLASH_DRV_INVALID_INPUT_PARAMETERS;
1040
1041 /* Checks whether the input parameters are valid */
1042 if ((Cy_Flash_BoundsCheck(rowAddr) != false) && (NULL != data))
1043 {
1044 SystemCoreClockUpdate();
1045
1046 /* Prepares arguments to be passed to SROM API */
1047 flashContext.opcode = CY_FLASH_OPCODE_PROGRAM_ROW | CY_FLASH_BLOCKING_MODE;
1048 flashContext.arg1 = CY_FLASH_DATA_LOC_SRAM;
1049 flashContext.arg2 = rowAddr;
1050 flashContext.arg3 = (uint32_t)data;
1051
1052 if (cy_device->flashProgramDelay != 0U)
1053 {
1054 result = Cy_Flash_SendCmd(CY_FLASH_BLOCKING_MODE, CY_FLASH_START_PROGRAM_DELAY);
1055 }
1056 else
1057 {
1058 result = Cy_Flash_SendCmd(CY_FLASH_BLOCKING_MODE, CY_FLASH_NO_DELAY);
1059 }
1060 }
1061
1062 return (result);
1063 }
1064
1065
1066 /*******************************************************************************
1067 * Function Name: Cy_Flash_WriteRow
1068 ****************************************************************************//**
1069 *
1070 * This function writes an array of data to a single row of flash. This is done
1071 * in three steps - pre-program, erase and then program flash row with the input
1072 * data. Reports success or a reason for failure. Does not return until the Write
1073 * operation is complete.
1074 * Returns immediately and reports a \ref CY_FLASH_DRV_IPC_BUSY error in the case
1075 * when another process is writing to flash. User firmware should not enter the
1076 * Hibernate or Deep-sleep mode until flash Write is complete. The Flash operation
1077 * is allowed in Sleep mode. During the Flash operation, the
1078 * device should not be reset, including the XRES pin, a software
1079 * reset, and watchdog reset sources. Also, low-voltage detect
1080 * circuits should be configured to generate an interrupt
1081 * instead of a reset. Otherwise, portions of flash may undergo
1082 * unexpected changes.
1083 * \note A Read while Write violation occurs when a flash Read operation is initiated
1084 * in the same or neighboring flash sector where the flash Write, Erase, or
1085 * Program operation is working. This violation may cause a HardFault exception.
1086 * To avoid the Read while Write violation,
1087 * use Cy_Flash_IsOperationComplete() to ensure flash operation is complete.
1088 *
1089 * \param rowAddr Address of the flash row number.
1090 * The Read-while-Write violation occurs when the flash read operation is
1091 * initiated in the same flash sector where the flash write operation is
1092 * performing. Refer to the device datasheet for the details.
1093 * Address must match row start address.
1094 *
1095 * \param data The pointer to the data which has to be written to flash. The size
1096 * of the data array must be equal to the flash row size. The flash row size for
1097 * the selected device is defined by the \ref CY_FLASH_SIZEOF_ROW macro. Refer to
1098 * the device datasheet for the details.
1099 *
1100 * \return Returns the status of the Flash operation,
1101 * see \ref cy_en_flashdrv_status_t.
1102 *
1103 *******************************************************************************/
Cy_Flash_WriteRow(uint32_t rowAddr,const uint32_t * data)1104 cy_en_flashdrv_status_t Cy_Flash_WriteRow(uint32_t rowAddr, const uint32_t* data)
1105 {
1106 cy_en_flashdrv_status_t result = CY_FLASH_DRV_INVALID_INPUT_PARAMETERS;
1107
1108 /* Checks whether the input parameters are valid */
1109 if ((Cy_Flash_BoundsCheck(rowAddr) != false) && (NULL != data))
1110 {
1111 SystemCoreClockUpdate();
1112
1113 /* Prepares arguments to be passed to SROM API */
1114 flashContext.opcode = CY_FLASH_OPCODE_WRITE_ROW | CY_FLASH_BLOCKING_MODE;
1115 flashContext.arg1 = 0UL;
1116 flashContext.arg2 = rowAddr;
1117 flashContext.arg3 = (uint32_t)data;
1118
1119 if (cy_device->flashWriteDelay != 0U)
1120 {
1121 result = Cy_Flash_SendCmd(CY_FLASH_BLOCKING_MODE, CY_FLASH_START_WRITE_DELAY);
1122 }
1123 else
1124 {
1125 result = Cy_Flash_SendCmd(CY_FLASH_BLOCKING_MODE, CY_FLASH_NO_DELAY);
1126 }
1127 }
1128
1129 return (result);
1130 }
1131
1132
1133 /*******************************************************************************
1134 * Function Name: Cy_Flash_StartWrite
1135 ****************************************************************************//**
1136 *
1137 * Performs pre-program, erase and then starts programming the flash row with
1138 * the input data. Returns immediately and reports a successful start
1139 * or reason for failure. Reports a \ref CY_FLASH_DRV_IPC_BUSY error
1140 * in the case when another process is writing to flash. User
1141 * firmware should not enter the Hibernate or Deep-Sleep mode until
1142 * flash Write is complete. The Flash operation is allowed in Sleep mode.
1143 * During the flash operation, the device should not be reset, including the
1144 * XRES pin, a software reset, and watchdog reset sources. Also, the low-voltage
1145 * detect circuits should be configured to generate an interrupt instead of a reset.
1146 * Otherwise, portions of flash may undergo unexpected changes.
1147 * \note Before reading data from previously programmed/erased flash rows, the
1148 * user must clear the flash cache with the Cy_SysLib_ClearFlashCacheAndBuffer()
1149 * function.
1150 * \note A Read while Write violation occurs when a flash Read operation is initiated
1151 * in the same or neighboring flash sector where the flash Write, Erase, or
1152 * Program operation is working. This violation may cause a HardFault exception.
1153 * To avoid the Read while Write violation,
1154 * use Cy_Flash_IsOperationComplete() to ensure flash operation is complete.
1155 *
1156 * \param rowAddr Address of the flash row number.
1157 * The Read-while-Write violation occurs when the flash read operation is
1158 * initiated in the same flash sector where the flash write operation is
1159 * performing. Refer to the device datasheet for the details.
1160 * Address must match row start address.
1161 *
1162 * \param data The pointer to the data to be written to flash. The size
1163 * of the data array must be equal to the flash row size. The flash row size for
1164 * the selected device is defined by the \ref CY_FLASH_SIZEOF_ROW macro. Refer to
1165 * the device datasheet for the details.
1166 *
1167 * \return Returns the status of the Flash operation,
1168 * see \ref cy_en_flashdrv_status_t.
1169 *
1170 *******************************************************************************/
Cy_Flash_StartWrite(uint32_t rowAddr,const uint32_t * data)1171 cy_en_flashdrv_status_t Cy_Flash_StartWrite(uint32_t rowAddr, const uint32_t* data)
1172 {
1173 cy_en_flashdrv_status_t result = CY_FLASH_DRV_INVALID_INPUT_PARAMETERS;
1174
1175 /* Checks whether the input parameters are valid */
1176 if ((Cy_Flash_BoundsCheck(rowAddr) != false) && (NULL != data))
1177 {
1178 result = Cy_Flash_StartEraseRow(rowAddr);
1179
1180 if (CY_FLASH_DRV_OPERATION_STARTED == result)
1181 {
1182 /* Polls whether the IPC is released and the Flash operation is performed */
1183 do
1184 {
1185 result = Cy_Flash_OperationStatus();
1186 }
1187 while (result == CY_FLASH_DRV_OPCODE_BUSY);
1188
1189 if (CY_FLASH_DRV_SUCCESS == result)
1190 {
1191 result = Cy_Flash_StartProgram(rowAddr, data);
1192 }
1193 }
1194 }
1195
1196 return (result);
1197 }
1198
1199
1200 /*******************************************************************************
1201 * Function Name: Cy_Flash_IsOperationComplete
1202 ****************************************************************************//**
1203 *
1204 * Reports a successful operation result, reason of failure or busy status
1205 * ( \ref CY_FLASH_DRV_OPCODE_BUSY ).
1206 *
1207 * \return Returns the status of the Flash operation (see \ref cy_en_flashdrv_status_t).
1208 *
1209 *******************************************************************************/
Cy_Flash_IsOperationComplete(void)1210 cy_en_flashdrv_status_t Cy_Flash_IsOperationComplete(void)
1211 {
1212 return (Cy_Flash_OperationStatus());
1213 }
1214
1215
1216 /*******************************************************************************
1217 * Function Name: Cy_Flash_StartProgram
1218 ****************************************************************************//**
1219 *
1220 * Starts writing an array of data to a single row of flash. Returns immediately
1221 * and reports a successful start or reason for failure.
1222 * Reports a \ref CY_FLASH_DRV_IPC_BUSY error if another process is writing
1223 * to flash. The user firmware should not enter Hibernate or Deep-Sleep mode until flash
1224 * Program is complete. The Flash operation is allowed in Sleep mode.
1225 * During the Flash operation, the device should not be reset, including the
1226 * XRES pin, a software reset, and watchdog reset sources. Also, the low-voltage
1227 * detect circuits should be configured to generate an interrupt instead of a reset.
1228 * Otherwise, portions of flash may undergo unexpected changes.\n
1229 * Before calling this function, the target flash region must be erased by
1230 * the StartEraseRow/EraseRow function.\n
1231 * Data to be programmed must be located in the SRAM memory region.
1232 * \note Before reading data from previously programmed/erased flash rows, the
1233 * user must clear the flash cache with the Cy_SysLib_ClearFlashCacheAndBuffer()
1234 * function.
1235 * \note A Read while Write violation occurs when a flash Read operation is initiated
1236 * in the same or neighboring flash sector where the flash Write, Erase, or
1237 * Program operation is working. This violation may cause a HardFault exception.
1238 * To avoid the Read while Write violation,
1239 * use Cy_Flash_IsOperationComplete() to ensure flash operation is complete.
1240 *
1241 * \param rowAddr The address of the flash row number.
1242 * The Read-while-Write violation occurs when the Flash Write operation is
1243 * performing. Refer to the device datasheet for the details.
1244 * The address must match the row start address.
1245 *
1246 * \param data The pointer to the data to be written to flash. The size
1247 * of the data array must be equal to the flash row size. The flash row size for
1248 * the selected device is defined by the \ref CY_FLASH_SIZEOF_ROW macro. Refer to
1249 * the device datasheet for the details.
1250 *
1251 * \return Returns the status of the Flash operation,
1252 * see \ref cy_en_flashdrv_status_t.
1253 *
1254 *******************************************************************************/
Cy_Flash_StartProgram(uint32_t rowAddr,const uint32_t * data)1255 cy_en_flashdrv_status_t Cy_Flash_StartProgram(uint32_t rowAddr, const uint32_t* data)
1256 {
1257 cy_en_flashdrv_status_t result = CY_FLASH_DRV_INVALID_INPUT_PARAMETERS;
1258
1259 if ((Cy_Flash_BoundsCheck(rowAddr) != false) && (NULL != data))
1260 {
1261 SystemCoreClockUpdate();
1262
1263 /* Prepares arguments to be passed to SROM API */
1264 flashContext.opcode = CY_FLASH_OPCODE_PROGRAM_ROW;
1265
1266 if (SFLASH_SINGLE_CORE != 0U)
1267 {
1268 flashContext.opcode |= CY_FLASH_BLOCKING_MODE;
1269 }
1270
1271 flashContext.arg1 = CY_FLASH_DATA_LOC_SRAM;
1272 flashContext.arg2 = rowAddr;
1273 flashContext.arg3 = (uint32_t)data;
1274
1275 if (cy_device->flashProgramDelay != 0U)
1276 {
1277 result = Cy_Flash_SendCmd(CY_FLASH_NON_BLOCKING_MODE, CY_FLASH_START_PROGRAM_DELAY);
1278 }
1279 else
1280 {
1281 result = Cy_Flash_SendCmd(CY_FLASH_NON_BLOCKING_MODE, CY_FLASH_NO_DELAY);
1282 }
1283 }
1284
1285 return (result);
1286 }
1287
1288
1289 /*******************************************************************************
1290 * Function Name: Cy_Flash_RowChecksum
1291 ****************************************************************************//**
1292 *
1293 * Returns a checksum value of the specified flash row.
1294 *
1295 * \note Now Cy_Flash_RowChecksum() requires the row <b>address</b> (rowAddr)
1296 * as a parameter. In previous versions of the driver, this function used
1297 * the row <b>number</b> (rowNum) for this parameter.
1298 *
1299 * \param rowAddr The address of the flash row.
1300 *
1301 * \param checksumPtr The pointer to the address where checksum is to be stored
1302 *
1303 * \return Returns the status of the Flash operation.
1304 *
1305 *******************************************************************************/
Cy_Flash_RowChecksum(uint32_t rowAddr,uint32_t * checksumPtr)1306 cy_en_flashdrv_status_t Cy_Flash_RowChecksum (uint32_t rowAddr, uint32_t* checksumPtr)
1307 {
1308 cy_en_flashdrv_status_t result = CY_FLASH_DRV_INVALID_INPUT_PARAMETERS;
1309 uint32_t resTmp;
1310 uint32_t rowID;
1311
1312 /* Checks whether the input parameters are valid */
1313 if ((Cy_Flash_BoundsCheck(rowAddr)) && (NULL != checksumPtr))
1314 {
1315 rowID = Cy_Flash_GetRowNum(rowAddr);
1316
1317 /* Prepares arguments to be passed to SROM API */
1318 flashContext.opcode = CY_FLASH_OPCODE_CHECKSUM |
1319 (((rowID >> CY_FLASH_REGION_ID_SHIFT) & CY_FLASH_REGION_ID_MASK) << CY_FLASH_OPCODE_CHECKSUM_REGION_SHIFT) |
1320 ((rowID & CY_FLASH_ROW_ID_MASK) << CY_FLASH_OPCODE_CHECKSUM_ROW_SHIFT);
1321
1322 /* Tries to acquire the IPC structure and pass the arguments to SROM API */
1323 if (Cy_IPC_Drv_SendMsgPtr(Cy_IPC_Drv_GetIpcBaseAddress(CY_IPC_CHAN_SYSCALL), CY_FLASH_IPC_NOTIFY_STRUCT0,
1324 (void*)&flashContext) == CY_IPC_DRV_SUCCESS)
1325 {
1326 /* Polls whether IPC is released and the Flash operation is performed */
1327 while (Cy_IPC_Drv_IsLockAcquired(Cy_IPC_Drv_GetIpcBaseAddress(CY_IPC_CHAN_SYSCALL)) != false)
1328 {
1329 /* Wait till IPC is released */
1330 }
1331
1332 resTmp = flashContext.opcode >> CY_FLASH_ERROR_SHIFT;
1333
1334 if (resTmp == CY_FLASH_ERROR_NO_ERROR)
1335 {
1336 result = CY_FLASH_DRV_SUCCESS;
1337
1338 if (CY_IPC_V1)
1339 {
1340 *checksumPtr = flashContext.opcode & CY_FLASH_RESULT_MASK;
1341 }
1342 else
1343 {
1344 *checksumPtr = REG_IPC_STRUCT_DATA1(Cy_IPC_Drv_GetIpcBaseAddress(CY_IPC_CHAN_SYSCALL));
1345 }
1346 }
1347 else
1348 {
1349 result = Cy_Flash_ProcessOpcode(flashContext.opcode);
1350 }
1351
1352 }
1353 else
1354 {
1355 /* The IPC structure is already locked by another process */
1356 result = CY_FLASH_DRV_IPC_BUSY;
1357 }
1358 }
1359
1360 return (result);
1361 }
1362
1363
1364 /*******************************************************************************
1365 * Function Name: Cy_Flash_CalculateHash
1366 ****************************************************************************//**
1367 *
1368 * Returns a hash value of the specified region of flash.
1369 *
1370 * \param data Start the data address.
1371 *
1372 * \param numberOfBytes The hash value is calculated for the number of bytes after the
1373 * start data address (0 - 1 byte, 1- 2 bytes etc).
1374 *
1375 * \param hashPtr The pointer to the address where hash is to be stored
1376 *
1377 * \return Returns the status of the Flash operation.
1378 *
1379 *******************************************************************************/
Cy_Flash_CalculateHash(const uint32_t * data,uint32_t numberOfBytes,uint32_t * hashPtr)1380 cy_en_flashdrv_status_t Cy_Flash_CalculateHash (const uint32_t* data, uint32_t numberOfBytes, uint32_t* hashPtr)
1381 {
1382 cy_en_flashdrv_status_t result = CY_FLASH_DRV_INVALID_INPUT_PARAMETERS;
1383 volatile uint32_t resTmp;
1384
1385 /* Checks whether the input parameters are valid */
1386 if ((data != NULL) && (0UL != numberOfBytes))
1387 {
1388 /* Prepares arguments to be passed to SROM API */
1389 flashContext.opcode = CY_FLASH_OPCODE_HASH;
1390 flashContext.arg1 = (uint32_t)data;
1391 flashContext.arg2 = numberOfBytes;
1392
1393 /* Tries to acquire the IPC structure and pass the arguments to SROM API */
1394 if (Cy_IPC_Drv_SendMsgPtr(Cy_IPC_Drv_GetIpcBaseAddress(CY_IPC_CHAN_SYSCALL), CY_FLASH_IPC_NOTIFY_STRUCT0,
1395 (void*)&flashContext) == CY_IPC_DRV_SUCCESS)
1396 {
1397 /* Polls whether IPC is released and the Flash operation is performed */
1398 while (Cy_IPC_Drv_IsLockAcquired(Cy_IPC_Drv_GetIpcBaseAddress(CY_IPC_CHAN_SYSCALL)) != false)
1399 {
1400 /* Wait till IPC is released */
1401 }
1402
1403 resTmp = flashContext.opcode;
1404
1405 if ((resTmp >> CY_FLASH_ERROR_SHIFT) == CY_FLASH_ERROR_NO_ERROR)
1406 {
1407 result = CY_FLASH_DRV_SUCCESS;
1408 *hashPtr = flashContext.opcode & CY_FLASH_RESULT_MASK;
1409 }
1410 else
1411 {
1412 result = Cy_Flash_ProcessOpcode(flashContext.opcode);
1413 }
1414 }
1415 else
1416 {
1417 /* The IPC structure is already locked by another process */
1418 result = CY_FLASH_DRV_IPC_BUSY;
1419 }
1420 }
1421
1422 return (result);
1423 }
1424
1425
1426 /*******************************************************************************
1427 * Function Name: Cy_Flash_GetRowNum
1428 ****************************************************************************//**
1429 *
1430 * Returns flash region ID and row number of the Flash address.
1431 *
1432 * \param flashAddr Address to be checked
1433 *
1434 * \return
1435 * The valid return value is encoded as follows
1436 * <table>
1437 * <tr><th>Field <th>Value
1438 * <tr><td>Flash row number <td>[15:0] bits
1439 * <tr><td>Flash region ID <td>[31:16] bits
1440 * </table>
1441 *
1442 *******************************************************************************/
Cy_Flash_GetRowNum(uint32_t flashAddr)1443 static uint32_t Cy_Flash_GetRowNum(uint32_t flashAddr)
1444 {
1445 uint32_t result;
1446
1447 #if (CY_EM_EEPROM_SIZE>0)
1448 if ((flashAddr >= CY_EM_EEPROM_BASE) && (flashAddr < (CY_EM_EEPROM_BASE + CY_EM_EEPROM_SIZE)))
1449 {
1450 result = (CY_FLASH_REGION_ID_EM_EEPROM << CY_FLASH_REGION_ID_SHIFT) |
1451 ((flashAddr - CY_EM_EEPROM_BASE) / CY_FLASH_SIZEOF_ROW);
1452 }
1453 else
1454 #endif
1455 if ((flashAddr >= SFLASH_BASE) && (flashAddr < (SFLASH_BASE + SFLASH_SECTION_SIZE)))
1456 {
1457 result = (CY_FLASH_REGION_ID_SFLASH << CY_FLASH_REGION_ID_SHIFT) |
1458 ((flashAddr - SFLASH_BASE) / CY_FLASH_SIZEOF_ROW);
1459 }
1460 else
1461 {
1462 result = (CY_FLASH_REGION_ID_MAIN << CY_FLASH_REGION_ID_SHIFT) |
1463 ((flashAddr - CY_FLASH_BASE) / CY_FLASH_SIZEOF_ROW);
1464 }
1465
1466 return (result);
1467 }
1468
1469
1470 /*******************************************************************************
1471 * Function Name: Cy_Flash_BoundsCheck
1472 ****************************************************************************//**
1473 *
1474 * The function checks the following conditions:
1475 * - if Flash address is equal to start address of the row
1476 *
1477 * \param flashAddr Address to be checked
1478 *
1479 * \return false - out of bound, true - in flash bounds
1480 *
1481 *******************************************************************************/
Cy_Flash_BoundsCheck(uint32_t flashAddr)1482 static bool Cy_Flash_BoundsCheck(uint32_t flashAddr)
1483 {
1484 return ((flashAddr % CY_FLASH_SIZEOF_ROW) == 0UL);
1485 }
1486
1487
1488 /*******************************************************************************
1489 * Function Name: Cy_Flash_ProcessOpcode
1490 ****************************************************************************//**
1491 *
1492 * Converts System Call returns to the Flash driver return defines.
1493 *
1494 * \param opcode The value returned by the System Call.
1495 *
1496 * \return Flash driver return.
1497 *
1498 *******************************************************************************/
Cy_Flash_ProcessOpcode(uint32_t opcode)1499 static cy_en_flashdrv_status_t Cy_Flash_ProcessOpcode(uint32_t opcode)
1500 {
1501 cy_en_flashdrv_status_t result;
1502
1503 switch (opcode)
1504 {
1505 case 0UL:
1506 {
1507 result = CY_FLASH_DRV_SUCCESS;
1508 break;
1509 }
1510 case CY_FLASH_ROMCODE_SUCCESS:
1511 {
1512 result = CY_FLASH_DRV_SUCCESS;
1513 break;
1514 }
1515 case CY_FLASH_ROMCODE_INVALID_PROTECTION:
1516 {
1517 result = CY_FLASH_DRV_INV_PROT;
1518 break;
1519 }
1520 case CY_FLASH_ROMCODE_INVALID_FM_PL:
1521 {
1522 result = CY_FLASH_DRV_INVALID_FM_PL;
1523 break;
1524 }
1525 case CY_FLASH_ROMCODE_INVALID_FLASH_ADDR:
1526 {
1527 result = CY_FLASH_DRV_INVALID_FLASH_ADDR;
1528 break;
1529 }
1530 case CY_FLASH_ROMCODE_ROW_PROTECTED:
1531 {
1532 result = CY_FLASH_DRV_ROW_PROTECTED;
1533 break;
1534 }
1535 case CY_FLASH_ROMCODE_IN_PROGRESS_NO_ERROR:
1536 {
1537 result = CY_FLASH_DRV_PROGRESS_NO_ERROR;
1538 break;
1539 }
1540 case (uint32_t)CY_FLASH_DRV_INVALID_INPUT_PARAMETERS:
1541 {
1542 result = CY_FLASH_DRV_INVALID_INPUT_PARAMETERS;
1543 break;
1544 }
1545 case CY_FLASH_IS_OPERATION_STARTED :
1546 {
1547 result = CY_FLASH_DRV_OPERATION_STARTED;
1548 break;
1549 }
1550 case CY_FLASH_IS_BUSY :
1551 {
1552 result = CY_FLASH_DRV_OPCODE_BUSY;
1553 break;
1554 }
1555 case CY_FLASH_IS_IPC_BUSY :
1556 {
1557 result = CY_FLASH_DRV_IPC_BUSY;
1558 break;
1559 }
1560 case CY_FLASH_IS_INVALID_INPUT_PARAMETERS :
1561 {
1562 result = CY_FLASH_DRV_INVALID_INPUT_PARAMETERS;
1563 break;
1564 }
1565 default:
1566 {
1567 result = CY_FLASH_DRV_ERR_UNC;
1568 break;
1569 }
1570 }
1571
1572 return (result);
1573 }
1574
1575
1576 /*******************************************************************************
1577 * Function Name: Cy_Flash_OperationStatus
1578 ****************************************************************************//**
1579 *
1580 * Checks the status of the Flash Operation, and returns it.
1581 *
1582 * \return Returns the status of the Flash operation
1583 * (see \ref cy_en_flashdrv_status_t).
1584 *
1585 *******************************************************************************/
Cy_Flash_OperationStatus(void)1586 static cy_en_flashdrv_status_t Cy_Flash_OperationStatus(void)
1587 {
1588 cy_en_flashdrv_status_t result = CY_FLASH_DRV_OPCODE_BUSY;
1589
1590 /* Checks if the IPC structure is not locked */
1591 if (Cy_IPC_Drv_IsLockAcquired(Cy_IPC_Drv_GetIpcBaseAddress(CY_IPC_CHAN_SYSCALL)) == false)
1592 {
1593 /* The result of SROM API calling is returned to the driver context */
1594 result = Cy_Flash_ProcessOpcode(flashContext.opcode);
1595
1596 /* Clear pre-fetch cache after flash operation */
1597 #if CY_CPU_CORTEX_M4 && defined (CY_DEVICE_SECURE)
1598 CY_PRA_REG32_SET(CY_PRA_INDX_FLASHC_FLASH_CMD, FLASHC_FLASH_CMD_INV_Msk);
1599 while (CY_PRA_REG32_GET(CY_PRA_INDX_FLASHC_FLASH_CMD) != 0U)
1600 {
1601 }
1602 #else
1603 FLASHC_FLASH_CMD = FLASHC_FLASH_CMD_INV_Msk;
1604 while (FLASHC_FLASH_CMD != 0U)
1605 {
1606 }
1607 #endif /* CY_CPU_CORTEX_M4 && defined (CY_DEVICE_SECURE) */
1608 }
1609
1610 return (result);
1611 }
1612
1613
1614 /*******************************************************************************
1615 * Function Name: Cy_Flash_GetExternalStatus
1616 ****************************************************************************//**
1617 *
1618 * This function handles the case where a module such as security image captures
1619 * a system call from this driver and reports its own status or error code,
1620 * for example protection violation. In that case, a function from this
1621 * driver returns an unknown error (see \ref cy_en_flashdrv_status_t). After receipt
1622 * of an unknown error, the user may call this function to get the status
1623 * of the capturing module.
1624 *
1625 * The user is responsible for parsing the content of the returned value
1626 * and casting it to the appropriate enumeration.
1627 *
1628 * \return
1629 * The error code that was stored in the opcode variable.
1630 *
1631 *******************************************************************************/
Cy_Flash_GetExternalStatus(void)1632 uint32_t Cy_Flash_GetExternalStatus(void)
1633 {
1634 return (flashContext.opcode);
1635 }
1636
1637 CY_MISRA_BLOCK_END('MISRA C-2012 Rule 11.3');
1638 #endif /* CY_IP_M4CPUSS */
1639
1640 /* [] END OF FILE */
1641