1 /***********************************************************************************************************************
2 * Copyright [2020-2022] Renesas Electronics Corporation and/or its affiliates. All Rights Reserved.
3 *
4 * This software and documentation are supplied by Renesas Electronics America Inc. and may only be used with products
5 * of Renesas Electronics Corp. and its affiliates ("Renesas"). No other uses are authorized. Renesas products are
6 * sold pursuant to Renesas terms and conditions of sale. Purchasers are solely responsible for the selection and use
7 * of Renesas products and Renesas assumes no liability. No license, express or implied, to any intellectual property
8 * right is granted by Renesas. This software is protected under all applicable laws, including copyright laws. Renesas
9 * reserves the right to change or discontinue this software and/or this documentation. THE SOFTWARE AND DOCUMENTATION
10 * IS DELIVERED TO YOU "AS IS," AND RENESAS MAKES NO REPRESENTATIONS OR WARRANTIES, AND TO THE FULLEST EXTENT
11 * PERMISSIBLE UNDER APPLICABLE LAW, DISCLAIMS ALL WARRANTIES, WHETHER EXPLICITLY OR IMPLICITLY, INCLUDING WARRANTIES
12 * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, AND NONINFRINGEMENT, WITH RESPECT TO THE SOFTWARE OR
13 * DOCUMENTATION. RENESAS SHALL HAVE NO LIABILITY ARISING OUT OF ANY SECURITY VULNERABILITY OR BREACH. TO THE MAXIMUM
14 * EXTENT PERMITTED BY LAW, IN NO EVENT WILL RENESAS BE LIABLE TO YOU IN CONNECTION WITH THE SOFTWARE OR DOCUMENTATION
15 * (OR ANY PERSON OR ENTITY CLAIMING RIGHTS DERIVED FROM YOU) FOR ANY LOSS, DAMAGES, OR CLAIMS WHATSOEVER, INCLUDING,
16 * WITHOUT LIMITATION, ANY DIRECT, CONSEQUENTIAL, SPECIAL, INDIRECT, PUNITIVE, OR INCIDENTAL DAMAGES; ANY LOST PROFITS,
17 * OTHER ECONOMIC DAMAGE, PROPERTY DAMAGE, OR PERSONAL INJURY; AND EVEN IF RENESAS HAS BEEN ADVISED OF THE POSSIBILITY
18 * OF SUCH LOSS, DAMAGES, CLAIMS OR COSTS.
19 **********************************************************************************************************************/
20
21 /***********************************************************************************************************************
22 * Includes
23 **********************************************************************************************************************/
24 #include "bsp_api.h"
25 #include <string.h>
26 #include "r_flash_hp.h"
27
28 /* Configuration for this package. */
29 #include "r_flash_hp_cfg.h"
30
31 /***********************************************************************************************************************
32 * Typedef definitions
33 **********************************************************************************************************************/
34
35 #if defined(__ARMCC_VERSION) || defined(__ICCARM__)
36 typedef void (BSP_CMSE_NONSECURE_CALL * flash_hp_prv_ns_callback)(flash_callback_args_t * p_args);
37 #elif defined(__GNUC__)
38 typedef BSP_CMSE_NONSECURE_CALL void (*volatile flash_hp_prv_ns_callback)(flash_callback_args_t * p_args);
39 #endif
40
41 /***********************************************************************************************************************
42 * Macro definitions
43 **********************************************************************************************************************/
44
45 #define FLASH_HP_FENTRYR_PE_MODE_BITS (0x0081U)
46 #define FLASH_HP_FSTATR_FLWEERR (1U << 6U)
47 #define FLASH_HP_FSTATR_PRGERR (1U << 12U)
48 #define FLASH_HP_FSTATR_ERSERR (1U << 13U)
49 #define FLASH_HP_FSTATR_ILGLERR (1U << 14U)
50 #define FLASH_HP_FSTATR_OTERR (1U << 20U)
51 #define FLASH_HP_FSTATR_SECERR (1U << 21U)
52 #define FLASH_HP_FSTATR_FESETERR (1U << 22U)
53 #define FLASH_HP_FSTATR_ILGCOMERR (1U << 23U)
54
55 #define FLASH_HP_FSTATR_ERROR_MASK (FLASH_HP_FSTATR_FLWEERR | FLASH_HP_FSTATR_PRGERR | \
56 FLASH_HP_FSTATR_ERSERR | \
57 FLASH_HP_FSTATR_ILGLERR | FLASH_HP_FSTATR_OTERR | \
58 FLASH_HP_FSTATR_SECERR | \
59 FLASH_HP_FSTATR_FESETERR | FLASH_HP_FSTATR_ILGCOMERR)
60
61 /** "OPEN" in ASCII, used to avoid multiple open. */
62 #define FLASH_HP_OPEN (0x4f50454eU)
63 #define FLASH_HP_CLOSE (0U)
64
65 /* Minimum FCLK for Flash Operations in Hz */
66 #define FLASH_HP_MINIMUM_SUPPORTED_FCLK_FREQ (4000000U)
67
68 /* Smallest Code Flash block size */
69 #define FLASH_HP_CODE_SMALL_BLOCK_SZ (8192U)
70
71 /* Largest Code Flash block size */
72 #define FLASH_HP_CODE_LARGE_BLOCK_SZ (32768U)
73
74 #define FLASH_HP_DATA_BLOCK_SIZE (64U)
75
76 /** The maximum timeout for commands is 100usec when FCLK is 16 MHz i.e. 1600 FCLK cycles.
77 * Assuming worst case of ICLK at 240 MHz and FCLK at 4 MHz, and optimization set to max such that
78 * each count decrement loop takes only 5 cycles, then ((240/4)*1600)/5 = 19200 */
79 #define FLASH_HP_FRDY_CMD_TIMEOUT (19200)
80
81 /** Time that it would take for the Data Buffer to be empty (DBFULL Flag) is 90 FCLK cycles.
82 * Assuming worst case of ICLK at 240 MHz and FCLK at 4 MHz, and optimization set to max such that
83 * each count decrement loop takes only 5 cycles, then ((240/4)*90)/5 = 1080 */
84 #define FLASH_HP_DBFULL_TIMEOUT (1080U)
85
86 /** R_FACI Commands */
87 #define FLASH_HP_FACI_CMD_PROGRAM (0xE8U)
88 #define FLASH_HP_FACI_CMD_PROGRAM_CF (0x80U)
89 #define FLASH_HP_FACI_CMD_PROGRAM_DF (0x02U)
90 #define FLASH_HP_FACI_CMD_BLOCK_ERASE (0x20U)
91 #define FLASH_HP_FACI_CMD_PE_SUSPEND (0xB0U)
92 #define FLASH_HP_FACI_CMD_PE_RESUME (0xD0U)
93 #define FLASH_HP_FACI_CMD_STATUS_CLEAR (0x50U)
94 #define FLASH_HP_FACI_CMD_FORCED_STOP (0xB3U)
95 #define FLASH_HP_FACI_CMD_BLANK_CHECK (0x71U)
96 #define FLASH_HP_FACI_CMD_CONFIG_SET_1 (0x40U)
97 #define FLASH_HP_FACI_CMD_CONFIG_SET_2 (0x08U)
98 #define FLASH_HP_FACI_CMD_LOCK_BIT_PGM (0x77U)
99 #define FLASH_HP_FACI_CMD_LOCK_BIT_READ (0x71U)
100 #define FLASH_HP_FACI_CMD_FINAL (0xD0U)
101
102 /** Configuration set Command offset*/
103 #define FLASH_HP_FCU_CONFIG_SET_ID_BYTE (0x0000A150U)
104 #if !(defined(BSP_MCU_GROUP_RA6M4) || defined(BSP_MCU_GROUP_RA4M3) || defined(BSP_MCU_GROUP_RA4M2) || \
105 defined(BSP_MCU_GROUP_RA6M5) || defined(BSP_MCU_GROUP_RA4E1) || defined(BSP_MCU_GROUP_RA6E1) || \
106 defined(BSP_MCU_GROUP_RA6T2))
107 #define FLASH_HP_FCU_CONFIG_SET_ACCESS_STARTUP (0x0000A160U)
108 #else
109 #define FLASH_HP_FCU_CONFIG_SET_DUAL_MODE (0x0100A110U)
110 #define FLASH_HP_FCU_CONFIG_SET_ACCESS_STARTUP (0x0100A130U)
111 #define FLASH_HP_FCU_CONFIG_SET_BANK_MODE (0x0100A190U)
112 #endif
113
114 /* Zero based offset into g_configuration_area_data[] for FAWS */
115 #define FLASH_HP_FCU_CONFIG_SET_FAWS_OFFSET (2U)
116
117 /* Zero based offset into g_configuration_area_data[] for FAWE and BTFLG */
118 #define FLASH_HP_FCU_CONFIG_SET_FAWE_BTFLG_OFFSET (3U)
119
120 /* These bits must always be set when writing to the configuration area. */
121 #define FLASH_HP_FCU_CONFIG_FAWE_BTFLG_UNUSED_BITS (0x7800U)
122 #define FLASH_HP_FCU_CONFIG_FAWS_UNUSED_BITS (0xF800U)
123
124 /* 8 words need to be written */
125 #define FLASH_HP_CONFIG_SET_ACCESS_WORD_CNT (8U)
126
127 #define FLASH_HP_FSUACR_KEY (0x6600U)
128
129 #define FLASH_HP_SAS_KEY (0x6600U)
130
131 /** Register masks */
132 #define FLASH_HP_FPESTAT_NON_LOCK_BIT_PGM_ERROR (0x0002U) // Bits indicating Non Lock Bit related Programming error.
133 #define FLASH_HP_FPESTAT_NON_LOCK_BIT_ERASE_ERROR (0x0012U) // Bits indicating Non Lock Bit related Erasure error.
134 #define FLASH_HP_FENTRYR_DF_PE_MODE (0x0080U) // Bits indicating that Data Flash is in P/E mode.
135 #define FLASH_HP_FENTRYR_CF_PE_MODE (0x0001U) // Bits indicating that CodeFlash is in P/E mode.
136 #define FLASH_HP_FENTRYR_TRANSITION_TO_CF_PE (0xAA01U) // Key Code to transition to CF P/E mode.
137 #define FLASH_HP_FENTRYR_TRANSITION_TO_DF_PE (0xAA80U) // Key Code to transition to DF P/E mode.
138
139 #define FLASH_HP_FREQUENCY_IN_HZ (1000000U)
140
141 #define FLASH_HP_FENTRYR_READ_MODE (0xAA00U)
142
143 #define FLASH_HP_FMEPROT_LOCK (0xD901)
144 #define FLASH_HP_FMEPROT_UNLOCK (0xD900)
145
146 #define FLASH_HP_OFS_SAS_MASK (0x7FFFU)
147
148 #define FLASH_HP_FAEINT_DFAEIE (0x08)
149 #define FLASH_HP_FAEINT_CMDLKIE (0x10)
150 #define FLASH_HP_FAEINT_CFAEIE (0x80)
151 #define FLASH_HP_ERROR_INTERRUPTS_ENABLE (FLASH_HP_FAEINT_DFAEIE | FLASH_HP_FAEINT_CMDLKIE | \
152 FLASH_HP_FAEINT_CFAEIE)
153
154 #define FLASH_HP_FPCKAR_KEY (0x1E00U)
155
156 #define FLASH_HP_MAX_WRITE_CF_US (15800)
157 #define FLASH_HP_MAX_WRITE_DF_US (3800)
158 #define FLASH_HP_MAX_DBFULL_US (2)
159 #define FLASH_HP_MAX_BLANK_CHECK_US (84)
160 #define FLASH_HP_MAX_WRITE_CONFIG_US (307000)
161 #define FLASH_HP_MAX_ERASE_DF_BLOCK_US (18000)
162 #define FLASH_HP_MAX_ERASE_CF_LARGE_BLOCK_US (1040000)
163 #define FLASH_HP_MAX_ERASE_CF_SMALL_BLOCK_US (260000)
164
165 #define FLASH_HP_FASTAT_DFAE (0x08)
166 #define FLASH_HP_FASTAT_CFAE (0x80)
167 #define FLASH_HP_FASTAT_CMDLK (0x10)
168
169 #if BSP_FEATURE_FLASH_HP_SUPPORTS_DUAL_BANK
170 #define FLASH_HP_PRV_DUALSEL_BANKMD_MASK (0x7U)
171 #define FLASH_HP_PRV_BANKSEL_BANKSWP_MASK (0x7U)
172 #define FLASH_HP_PRV_BANK1_MASK (~BSP_FEATURE_FLASH_HP_CF_DUAL_BANK_START)
173 #else
174 #define FLASH_HP_PRV_BANK1_MASK (UINT32_MAX)
175 #endif
176
177 /* The number of CPU cycles per each timeout loop. */
178 #ifndef R_FLASH_HP_CYCLES_MINIMUM_PER_TIMEOUT_LOOP
179 #if defined(__GNUC__)
180 #define R_FLASH_HP_CYCLES_MINIMUM_PER_TIMEOUT_LOOP (6U)
181 #elif defined(__ICCARM__)
182 #define R_FLASH_HP_CYCLES_MINIMUM_PER_TIMEOUT_LOOP (6U)
183 #endif
184 #endif
185
186 #define FLASH_HP_REGISTER_WAIT_TIMEOUT(val, reg, timeout, err) \
187 while (val != reg) \
188 { \
189 if (0 == timeout) \
190 { \
191 return err; \
192 } \
193 timeout--; \
194 }
195
196 /***********************************************************************************************************************
197 * Private global variables
198 **********************************************************************************************************************/
199
200 #if (FLASH_HP_CFG_CODE_FLASH_PROGRAMMING_ENABLE == 1)
201 static uint16_t g_configuration_area_data[FLASH_HP_CONFIG_SET_ACCESS_WORD_CNT] = {UINT16_MAX};
202 #endif
203
204 #define FLASH_HP_DF_START_ADDRESS (BSP_FEATURE_FLASH_DATA_FLASH_START)
205
206 static const flash_block_info_t g_code_flash_macro_info[] =
207 {
208 {
209 .block_section_st_addr = 0,
210 .block_section_end_addr = UINT16_MAX,
211 .block_size = FLASH_HP_CODE_SMALL_BLOCK_SZ,
212 .block_size_write = BSP_FEATURE_FLASH_HP_CF_WRITE_SIZE
213 },
214 {
215 .block_section_st_addr = BSP_FEATURE_FLASH_HP_CF_REGION0_SIZE,
216 .block_section_end_addr = BSP_ROM_SIZE_BYTES - 1,
217 .block_size = FLASH_HP_CODE_LARGE_BLOCK_SZ,
218 .block_size_write = BSP_FEATURE_FLASH_HP_CF_WRITE_SIZE
219 }
220 };
221
222 static const flash_regions_t g_flash_code_region =
223 {
224 .num_regions = 2,
225 .p_block_array = g_code_flash_macro_info
226 };
227
228 const flash_block_info_t g_data_flash_macro_info =
229 {
230 .block_section_st_addr = FLASH_HP_DF_START_ADDRESS,
231 .block_section_end_addr = FLASH_HP_DF_START_ADDRESS + BSP_DATA_FLASH_SIZE_BYTES - 1,
232 .block_size = FLASH_HP_DATA_BLOCK_SIZE,
233 .block_size_write = BSP_FEATURE_FLASH_HP_DF_WRITE_SIZE
234 };
235
236 static flash_regions_t g_flash_data_region =
237 {
238 .num_regions = 1,
239 .p_block_array = &g_data_flash_macro_info
240 };
241
242 #if (FLASH_HP_CFG_CODE_FLASH_PROGRAMMING_ENABLE == 1) && (BSP_FEATURE_FLASH_HP_SUPPORTS_DUAL_BANK == 1)
243 static volatile uint32_t * const flash_hp_banksel = (uint32_t *) FLASH_HP_FCU_CONFIG_SET_BANK_MODE;
244 #if (FLASH_HP_CFG_PARAM_CHECKING_ENABLE == 1)
245 static volatile uint32_t * const flash_hp_dualsel = (uint32_t *) FLASH_HP_FCU_CONFIG_SET_DUAL_MODE;
246 #endif
247 #endif
248
249 /***********************************************************************************************************************
250 * Private function prototypes
251 **********************************************************************************************************************/
252
253 void fcu_fiferr_isr(void);
254 void fcu_frdyi_isr(void);
255
256 /* Internal functions. */
257 static fsp_err_t flash_hp_init(flash_hp_instance_ctrl_t * p_ctrl);
258
259 static fsp_err_t flash_hp_enter_pe_df_mode(flash_hp_instance_ctrl_t * const p_ctrl);
260
261 static fsp_err_t flash_hp_pe_mode_exit() PLACE_IN_RAM_SECTION;
262
263 static fsp_err_t flash_hp_reset(flash_hp_instance_ctrl_t * p_ctrl) PLACE_IN_RAM_SECTION;
264
265 static fsp_err_t flash_hp_stop(void) PLACE_IN_RAM_SECTION;
266
267 static fsp_err_t flash_hp_status_clear() PLACE_IN_RAM_SECTION;
268
269 static fsp_err_t flash_hp_erase_block(flash_hp_instance_ctrl_t * const p_ctrl, uint32_t block_size,
270 uint32_t timeout) PLACE_IN_RAM_SECTION;
271
272 static fsp_err_t flash_hp_write_data(flash_hp_instance_ctrl_t * const p_ctrl, uint32_t write_size,
273 uint32_t timeout) PLACE_IN_RAM_SECTION;
274
275 static fsp_err_t flash_hp_check_errors(fsp_err_t previous_error, uint32_t error_bits,
276 fsp_err_t return_error) PLACE_IN_RAM_SECTION;
277
278 static void r_flash_hp_call_callback(flash_hp_instance_ctrl_t * p_ctrl, flash_event_t event);
279
280 #if (FLASH_HP_CFG_DATA_FLASH_PROGRAMMING_ENABLE == 1)
281
282 static fsp_err_t flash_hp_df_blank_check(flash_hp_instance_ctrl_t * const p_ctrl,
283 uint32_t const address,
284 uint32_t num_bytes,
285 flash_result_t * p_blank_check_result);
286
287 static fsp_err_t flash_hp_df_write(flash_hp_instance_ctrl_t * const p_ctrl);
288
289 static fsp_err_t flash_hp_df_erase(flash_hp_instance_ctrl_t * p_ctrl, uint32_t block_address, uint32_t num_blocks);
290
291 #endif
292
293 #if (FLASH_HP_CFG_CODE_FLASH_PROGRAMMING_ENABLE == 1)
294
295 static fsp_err_t flash_hp_configuration_area_write(flash_hp_instance_ctrl_t * p_ctrl,
296 uint32_t fsaddr) PLACE_IN_RAM_SECTION;
297
298 static void flash_hp_configuration_area_data_setup(uint32_t btflg_swap, uint32_t start_addr,
299 uint32_t end_addr) PLACE_IN_RAM_SECTION;
300
301 static fsp_err_t flash_hp_cf_write(flash_hp_instance_ctrl_t * const p_ctrl) PLACE_IN_RAM_SECTION;
302
303 #if (BSP_FEATURE_FLASH_HP_SUPPORTS_DUAL_BANK == 1)
304 static fsp_err_t flash_hp_bank_swap(flash_hp_instance_ctrl_t * const p_ctrl) PLACE_IN_RAM_SECTION;
305
306 #endif
307
308 static fsp_err_t flash_hp_cf_erase(flash_hp_instance_ctrl_t * p_ctrl, uint32_t block_address,
309 uint32_t num_blocks) PLACE_IN_RAM_SECTION;
310
311 static fsp_err_t flash_hp_enter_pe_cf_mode(flash_hp_instance_ctrl_t * const p_ctrl) PLACE_IN_RAM_SECTION;
312
313 static fsp_err_t flash_hp_access_window_set(flash_hp_instance_ctrl_t * p_ctrl,
314 uint32_t const start_addr,
315 uint32_t const end_addr) PLACE_IN_RAM_SECTION;
316
317 static fsp_err_t flash_hp_set_startup_area_boot(flash_hp_instance_ctrl_t * p_ctrl,
318 flash_startup_area_swap_t swap_type,
319 bool is_temporary) PLACE_IN_RAM_SECTION;
320
321 static fsp_err_t flash_hp_set_id_code(flash_hp_instance_ctrl_t * p_ctrl,
322 uint8_t const * const p_id_code,
323 flash_id_code_mode_t mode) PLACE_IN_RAM_SECTION;
324
325 #endif
326
327 #if (FLASH_HP_CFG_PARAM_CHECKING_ENABLE == 1)
328
329 static fsp_err_t r_flash_hp_common_parameter_checking(flash_hp_instance_ctrl_t * const p_ctrl);
330
331 static fsp_err_t r_flash_hp_write_bc_parameter_checking(flash_hp_instance_ctrl_t * const p_ctrl,
332 uint32_t flash_address,
333 uint32_t const num_bytes,
334 bool check_write);
335
336 #endif
337
338 /***********************************************************************************************************************
339 * Exported global variables
340 **********************************************************************************************************************/
341
342 const flash_api_t g_flash_on_flash_hp =
343 {
344 .open = R_FLASH_HP_Open,
345 .close = R_FLASH_HP_Close,
346 .write = R_FLASH_HP_Write,
347 .erase = R_FLASH_HP_Erase,
348 .blankCheck = R_FLASH_HP_BlankCheck,
349 .statusGet = R_FLASH_HP_StatusGet,
350 .infoGet = R_FLASH_HP_InfoGet,
351 .accessWindowSet = R_FLASH_HP_AccessWindowSet,
352 .accessWindowClear = R_FLASH_HP_AccessWindowClear,
353 .idCodeSet = R_FLASH_HP_IdCodeSet,
354 .reset = R_FLASH_HP_Reset,
355 .startupAreaSelect = R_FLASH_HP_StartUpAreaSelect,
356 .updateFlashClockFreq = R_FLASH_HP_UpdateFlashClockFreq,
357 .bankSwap = R_FLASH_HP_BankSwap,
358 .callbackSet = R_FLASH_HP_CallbackSet,
359 };
360
361 /*******************************************************************************************************************//**
362 * @addtogroup FLASH_HP
363 * @{
364 **********************************************************************************************************************/
365
366 /***********************************************************************************************************************
367 * Functions
368 **********************************************************************************************************************/
369
370 /*******************************************************************************************************************//**
371 * Initializes the high performance flash peripheral. Implements @ref flash_api_t::open.
372 *
373 * The Open function initializes the Flash.
374 *
375 * Example:
376 * @snippet r_flash_hp_example.c R_FLASH_HP_Open
377 *
378 * @retval FSP_SUCCESS Initialization was successful and timer has started.
379 * @retval FSP_ERR_ALREADY_OPEN The flash control block is already open.
380 * @retval FSP_ERR_ASSERTION NULL provided for p_ctrl or p_cfg.
381 * @retval FSP_ERR_IRQ_BSP_DISABLED Caller is requesting BGO but the Flash interrupts are not enabled.
382 * @retval FSP_ERR_FCLK FCLK must be a minimum of 4 MHz for Flash operations.
383 **********************************************************************************************************************/
R_FLASH_HP_Open(flash_ctrl_t * const p_api_ctrl,flash_cfg_t const * const p_cfg)384 fsp_err_t R_FLASH_HP_Open (flash_ctrl_t * const p_api_ctrl, flash_cfg_t const * const p_cfg)
385 {
386 flash_hp_instance_ctrl_t * p_ctrl = (flash_hp_instance_ctrl_t *) p_api_ctrl;
387 fsp_err_t err = FSP_SUCCESS;
388
389 #if (FLASH_HP_CFG_PARAM_CHECKING_ENABLE)
390
391 /* If null pointers return error. */
392 FSP_ASSERT(NULL != p_cfg);
393 FSP_ASSERT(NULL != p_ctrl);
394
395 /* If open return error. */
396 FSP_ERROR_RETURN((FLASH_HP_OPEN != p_ctrl->opened), FSP_ERR_ALREADY_OPEN);
397
398 /* Background operations for data flash are enabled but the flash interrupt is disabled. */
399 if (p_cfg->data_flash_bgo)
400 {
401 FSP_ERROR_RETURN(p_cfg->irq >= (IRQn_Type) 0, FSP_ERR_IRQ_BSP_DISABLED);
402 FSP_ERROR_RETURN(p_cfg->err_irq >= (IRQn_Type) 0, FSP_ERR_IRQ_BSP_DISABLED);
403 }
404 #endif
405
406 /* Set the parameters struct based on the user supplied settings */
407 p_ctrl->p_cfg = p_cfg;
408
409 if (true == p_cfg->data_flash_bgo)
410 {
411 p_ctrl->p_callback = p_cfg->p_callback;
412 p_ctrl->p_context = p_cfg->p_context;
413 p_ctrl->p_callback_memory = NULL;
414
415 /* Enable FCU interrupts. */
416 R_FACI_HP->FRDYIE = 1U;
417 R_BSP_IrqCfgEnable(p_cfg->irq, p_cfg->ipl, p_ctrl);
418
419 /* Enable Error interrupts. */
420 R_FACI_HP->FAEINT = FLASH_HP_ERROR_INTERRUPTS_ENABLE;
421 R_BSP_IrqCfgEnable(p_cfg->err_irq, p_cfg->err_ipl, p_ctrl);
422 }
423 else
424 {
425 /* Disable Flash Rdy interrupt in the FLASH peripheral. */
426 R_FACI_HP->FRDYIE = 0U;
427
428 /* Disable Flash Error interrupt in the FLASH peripheral */
429 R_FACI_HP->FAEINT = 0U;
430 }
431
432 /* Calculate timeout values. */
433 err = flash_hp_init(p_ctrl);
434 FSP_ERROR_RETURN(FSP_SUCCESS == err, err);
435
436 /* If successful mark the control block as open. Otherwise release the hardware lock. */
437 p_ctrl->opened = FLASH_HP_OPEN;
438
439 return err;
440 }
441
442 /*******************************************************************************************************************//**
443 * Writes to the specified Code or Data Flash memory area. Implements @ref flash_api_t::write.
444 *
445 * Example:
446 * @snippet r_flash_hp_example.c R_FLASH_HP_Write
447 *
448 * @retval FSP_SUCCESS Operation successful. If BGO is enabled this means the operation was started
449 * successfully.
450 * @retval FSP_ERR_IN_USE The Flash peripheral is busy with a prior on-going transaction.
451 * @retval FSP_ERR_NOT_OPEN The Flash API is not Open.
452 * @retval FSP_ERR_CMD_LOCKED FCU is in locked state, typically as a result of attempting to Write an area
453 * that is protected by an Access Window.
454 * @retval FSP_ERR_WRITE_FAILED Status is indicating a Programming error for the requested operation. This may
455 * be returned if the requested Flash area is not blank.
456 * @retval FSP_ERR_TIMEOUT Timed out waiting for FCU operation to complete.
457 * @retval FSP_ERR_INVALID_SIZE Number of bytes provided was not a multiple of the programming size or exceeded
458 * the maximum range.
459 * @retval FSP_ERR_INVALID_ADDRESS Invalid address was input or address not on programming boundary.
460 * @retval FSP_ERR_ASSERTION NULL provided for p_ctrl.
461 * @retval FSP_ERR_PE_FAILURE Failed to enter or exit P/E mode.
462 **********************************************************************************************************************/
R_FLASH_HP_Write(flash_ctrl_t * const p_api_ctrl,uint32_t const src_address,uint32_t flash_address,uint32_t const num_bytes)463 fsp_err_t R_FLASH_HP_Write (flash_ctrl_t * const p_api_ctrl,
464 uint32_t const src_address,
465 uint32_t flash_address,
466 uint32_t const num_bytes)
467 {
468 flash_hp_instance_ctrl_t * p_ctrl = (flash_hp_instance_ctrl_t *) p_api_ctrl;
469 fsp_err_t err = FSP_SUCCESS;
470
471 #if (FLASH_HP_CFG_PARAM_CHECKING_ENABLE == 1)
472
473 /* Verify write parameters. If failure return error. */
474 err = r_flash_hp_write_bc_parameter_checking(p_ctrl, flash_address, num_bytes, true);
475 FSP_ERROR_RETURN((err == FSP_SUCCESS), err);
476 #endif
477
478 p_ctrl->operations_remaining = (num_bytes) >> 1; // Since two bytes will be written at a time
479 p_ctrl->source_start_address = src_address;
480 p_ctrl->dest_end_address = flash_address;
481 p_ctrl->current_operation = FLASH_OPERATION_NON_BGO;
482
483 #if (FLASH_HP_CFG_CODE_FLASH_PROGRAMMING_ENABLE == 1)
484 if (flash_address < BSP_FEATURE_FLASH_DATA_FLASH_START)
485 {
486 #if (FLASH_HP_CFG_PARAM_CHECKING_ENABLE == 1)
487
488 /* Verify the source address is not in code flash. It will not be available in P/E mode. */
489 FSP_ASSERT(src_address > BSP_ROM_SIZE_BYTES);
490 #endif
491
492 /* Initiate the write operation, may return FSP_ERR_IN_USE via setup_for_pe_mode() */
493 err = flash_hp_cf_write(p_ctrl);
494 }
495 else
496 #endif
497 {
498 #if (FLASH_HP_CFG_DATA_FLASH_PROGRAMMING_ENABLE == 1)
499
500 /* Initiate the write operation, may return FSP_ERR_IN_USE via setup_for_pe_mode() */
501 err = flash_hp_df_write(p_ctrl);
502 #endif
503 }
504
505 return err;
506 }
507
508 /*******************************************************************************************************************//**
509 * Erases the specified Code or Data Flash blocks. Implements @ref flash_api_t::erase by the block_erase_address.
510 *
511 * @note Code flash may contain blocks of different sizes. When erasing code flash it is important to take this
512 * into consideration to prevent erasing a larger address space than desired.
513 *
514 * Example:
515 * @snippet r_flash_hp_example.c R_FLASH_HP_Erase
516 *
517 * @retval FSP_SUCCESS Successful open.
518 * @retval FSP_ERR_INVALID_BLOCKS Invalid number of blocks specified
519 * @retval FSP_ERR_INVALID_ADDRESS Invalid address specified. If the address is in code flash then code flash
520 * programming must be enabled.
521 * @retval FSP_ERR_IN_USE Other flash operation in progress, or API not initialized
522 * @retval FSP_ERR_CMD_LOCKED FCU is in locked state, typically as a result of attempting to Erase an area
523 * that is protected by an Access Window.
524 * @retval FSP_ERR_ASSERTION NULL provided for p_ctrl
525 * @retval FSP_ERR_NOT_OPEN The Flash API is not Open.
526 * @retval FSP_ERR_ERASE_FAILED Status is indicating a Erase error.
527 * @retval FSP_ERR_TIMEOUT Timed out waiting for the FCU to become ready.
528 * @retval FSP_ERR_PE_FAILURE Failed to enter or exit P/E mode.
529 **********************************************************************************************************************/
R_FLASH_HP_Erase(flash_ctrl_t * const p_api_ctrl,uint32_t const address,uint32_t const num_blocks)530 fsp_err_t R_FLASH_HP_Erase (flash_ctrl_t * const p_api_ctrl, uint32_t const address, uint32_t const num_blocks)
531 {
532 flash_hp_instance_ctrl_t * p_ctrl = (flash_hp_instance_ctrl_t *) p_api_ctrl;
533 fsp_err_t err = FSP_SUCCESS;
534
535 #if (FLASH_HP_CFG_PARAM_CHECKING_ENABLE == 1)
536
537 /* Verify the control block is not null and is opened. */
538 err = r_flash_hp_common_parameter_checking(p_ctrl);
539 FSP_ERROR_RETURN(FSP_SUCCESS == err, err);
540
541 if (true == p_ctrl->p_cfg->data_flash_bgo)
542 {
543 FSP_ASSERT(NULL != p_ctrl->p_callback);
544 }
545
546 /* If invalid number of blocks return error. */
547 FSP_ERROR_RETURN(num_blocks != 0U, FSP_ERR_INVALID_BLOCKS);
548 #endif
549
550 p_ctrl->current_operation = FLASH_OPERATION_NON_BGO;
551
552 #if (FLASH_HP_CFG_CODE_FLASH_PROGRAMMING_ENABLE == 1)
553 if (address < BSP_FEATURE_FLASH_DATA_FLASH_START)
554 {
555 uint32_t start_address = 0;
556 #if (FLASH_HP_CFG_PARAM_CHECKING_ENABLE == 1)
557 uint32_t region0_blocks = 0;
558 #endif
559
560 /* Configure the current parameters based on if the operation is for code flash or data flash. */
561 if ((address & FLASH_HP_PRV_BANK1_MASK) < BSP_FEATURE_FLASH_HP_CF_REGION0_SIZE)
562 {
563 start_address = address & ~(BSP_FEATURE_FLASH_HP_CF_REGION0_BLOCK_SIZE - 1);
564
565 #if (FLASH_HP_CFG_PARAM_CHECKING_ENABLE == 1)
566 region0_blocks = (BSP_FEATURE_FLASH_HP_CF_REGION0_SIZE - (start_address & FLASH_HP_PRV_BANK1_MASK)) /
567 BSP_FEATURE_FLASH_HP_CF_REGION0_BLOCK_SIZE;
568 #endif
569 }
570 else
571 {
572 start_address = address & ~(BSP_FEATURE_FLASH_HP_CF_REGION1_BLOCK_SIZE - 1);
573 }
574
575 #if (FLASH_HP_CFG_PARAM_CHECKING_ENABLE == 1)
576 uint32_t num_bytes = (region0_blocks * BSP_FEATURE_FLASH_HP_CF_REGION0_BLOCK_SIZE);
577 if (num_blocks > region0_blocks)
578 {
579 num_bytes += ((num_blocks - region0_blocks) * BSP_FEATURE_FLASH_HP_CF_REGION1_BLOCK_SIZE);
580 }
581
582 #if BSP_FEATURE_FLASH_HP_SUPPORTS_DUAL_BANK
583 uint32_t rom_end =
584 (FLASH_HP_PRV_DUALSEL_BANKMD_MASK ==
585 (*flash_hp_dualsel & FLASH_HP_PRV_DUALSEL_BANKMD_MASK)) ? BSP_ROM_SIZE_BYTES : BSP_ROM_SIZE_BYTES / 2;
586
587 FSP_ERROR_RETURN((start_address & FLASH_HP_PRV_BANK1_MASK) + num_bytes <= rom_end, FSP_ERR_INVALID_BLOCKS);
588 #else
589 FSP_ERROR_RETURN(start_address + num_bytes <= BSP_ROM_SIZE_BYTES, FSP_ERR_INVALID_BLOCKS);
590 #endif
591 #endif
592
593 err = flash_hp_cf_erase(p_ctrl, start_address, num_blocks);
594 }
595 else
596 #endif
597 {
598 #if (FLASH_HP_CFG_DATA_FLASH_PROGRAMMING_ENABLE == 1)
599 uint32_t start_address = address & ~(BSP_FEATURE_FLASH_HP_DF_BLOCK_SIZE - 1);
600
601 #if (FLASH_HP_CFG_PARAM_CHECKING_ENABLE == 1)
602 uint32_t num_bytes = num_blocks * BSP_FEATURE_FLASH_HP_DF_BLOCK_SIZE;
603
604 FSP_ERROR_RETURN((start_address >= (FLASH_HP_DF_START_ADDRESS)) &&
605 (start_address < (FLASH_HP_DF_START_ADDRESS + BSP_DATA_FLASH_SIZE_BYTES)),
606 FSP_ERR_INVALID_ADDRESS);
607
608 FSP_ERROR_RETURN(start_address + num_bytes <= (FLASH_HP_DF_START_ADDRESS + BSP_DATA_FLASH_SIZE_BYTES),
609 FSP_ERR_INVALID_BLOCKS);
610 #endif
611
612 /* Initiate the flash erase. */
613 err = flash_hp_df_erase(p_ctrl, start_address, num_blocks);
614 FSP_ERROR_RETURN(FSP_SUCCESS == err, err);
615 #else
616
617 return FSP_ERR_INVALID_ADDRESS;
618 #endif
619 }
620
621 return err;
622 }
623
624 /*******************************************************************************************************************//**
625 * Performs a blank check on the specified address area. Implements @ref flash_api_t::blankCheck.
626 *
627 * Example:
628 * @snippet r_flash_hp_example.c R_FLASH_HP_BlankCheck
629 *
630 * @retval FSP_SUCCESS Blank check operation completed with result in p_blank_check_result, or
631 * blank check started and in-progess (BGO mode).
632 * @retval FSP_ERR_INVALID_ADDRESS Invalid data flash address was input.
633 * @retval FSP_ERR_INVALID_SIZE 'num_bytes' was either too large or not aligned for the CF/DF boundary size.
634 * @retval FSP_ERR_IN_USE Other flash operation in progress or API not initialized.
635 * @retval FSP_ERR_ASSERTION NULL provided for p_ctrl.
636 * @retval FSP_ERR_CMD_LOCKED FCU is in locked state, typically as a result of attempting to Erase an area
637 * that is protected by an Access Window.
638 * @retval FSP_ERR_NOT_OPEN The Flash API is not Open.
639 * @retval FSP_ERR_TIMEOUT Timed out waiting for the FCU to become ready.
640 * @retval FSP_ERR_PE_FAILURE Failed to enter or exit P/E mode.
641 * @retval FSP_ERR_BLANK_CHECK_FAILED Blank check operation failed.
642 **********************************************************************************************************************/
R_FLASH_HP_BlankCheck(flash_ctrl_t * const p_api_ctrl,uint32_t const address,uint32_t num_bytes,flash_result_t * p_blank_check_result)643 fsp_err_t R_FLASH_HP_BlankCheck (flash_ctrl_t * const p_api_ctrl,
644 uint32_t const address,
645 uint32_t num_bytes,
646 flash_result_t * p_blank_check_result)
647 {
648 flash_hp_instance_ctrl_t * p_ctrl = (flash_hp_instance_ctrl_t *) p_api_ctrl;
649 fsp_err_t err = FSP_SUCCESS;
650
651 #if (FLASH_HP_CFG_PARAM_CHECKING_ENABLE == 1)
652
653 /* Check parameters. If failure return error */
654 err = r_flash_hp_write_bc_parameter_checking(p_ctrl, address, num_bytes, false);
655 FSP_ERROR_RETURN((err == FSP_SUCCESS), err);
656 #endif
657
658 #if (FLASH_HP_CFG_CODE_FLASH_PROGRAMMING_ENABLE == 1)
659
660 /* Is this a request to Blank check Code Flash? */
661 /* If the address is code flash check if the region is blank. If not blank return error. */
662 if (address < BSP_ROM_SIZE_BYTES)
663 {
664 /* Blank checking for Code Flash does not require any FCU operations. The specified address area
665 * can simply be checked for non 0xFF. */
666 p_ctrl->current_operation = FLASH_OPERATION_NON_BGO;
667 *p_blank_check_result = FLASH_RESULT_BLANK; // Assume blank until we know otherwise
668 uint8_t * p_address = (uint8_t *) address;
669 for (uint32_t index = 0U; index < num_bytes; index++)
670 {
671 if (p_address[index] != UINT8_MAX)
672 {
673 *p_blank_check_result = FLASH_RESULT_NOT_BLANK;
674 break;
675 }
676 }
677 }
678 /* Otherwise the address is data flash. Put the flash in the blank check state. Return status. */
679 else
680 #endif
681 {
682 #if (FLASH_HP_CFG_DATA_FLASH_PROGRAMMING_ENABLE == 1)
683 err = flash_hp_df_blank_check(p_ctrl, address, num_bytes, p_blank_check_result);
684 #endif
685 }
686
687 return err;
688 }
689
690 /*******************************************************************************************************************//**
691 * Query the FLASH peripheral for its status. Implements @ref flash_api_t::statusGet.
692 *
693 * Example:
694 * @snippet r_flash_hp_example.c R_FLASH_HP_StatusGet
695 *
696 * @retval FSP_SUCCESS FLASH peripheral is ready to use.
697 * @retval FSP_ERR_ASSERTION NULL provided for p_ctrl.
698 * @retval FSP_ERR_NOT_OPEN The Flash API is not Open.
699 **********************************************************************************************************************/
R_FLASH_HP_StatusGet(flash_ctrl_t * const p_api_ctrl,flash_status_t * const p_status)700 fsp_err_t R_FLASH_HP_StatusGet (flash_ctrl_t * const p_api_ctrl, flash_status_t * const p_status)
701 {
702 #if (FLASH_HP_CFG_PARAM_CHECKING_ENABLE == 1)
703 flash_hp_instance_ctrl_t * p_ctrl = (flash_hp_instance_ctrl_t *) p_api_ctrl;
704
705 /* If null pointer return error. */
706 FSP_ASSERT(NULL != p_ctrl);
707 FSP_ASSERT(NULL != p_status);
708
709 /* If control block is not open return error. */
710 FSP_ERROR_RETURN(!(FLASH_HP_OPEN != p_ctrl->opened), FSP_ERR_NOT_OPEN);
711 #else
712
713 /* Eliminate warning if parameter checking is disabled. */
714 FSP_PARAMETER_NOT_USED(p_api_ctrl);
715 #endif
716
717 /* If the flash is currently in program/erase mode notify the caller that the flash is busy. */
718 if ((R_FACI_HP->FENTRYR & FLASH_HP_FENTRYR_PE_MODE_BITS) == 0x0000U)
719 {
720 *p_status = FLASH_STATUS_IDLE;
721 }
722 else
723 {
724 *p_status = FLASH_STATUS_BUSY;
725 }
726
727 return FSP_SUCCESS;
728 }
729
730 /*******************************************************************************************************************//**
731 * Implements @ref flash_api_t::idCodeSet.
732 *
733 * @retval FSP_SUCCESS ID Code successfully configured.
734 * @retval FSP_ERR_IN_USE FLASH peripheral is busy with a prior operation.
735 * @retval FSP_ERR_ASSERTION NULL provided for p_ctrl.
736 * @retval FSP_ERR_UNSUPPORTED Code Flash Programming is not enabled.
737 * @retval FSP_ERR_NOT_OPEN Flash API has not yet been opened.
738 * @retval FSP_ERR_PE_FAILURE Failed to enter or exit Code Flash P/E mode.
739 * @retval FSP_ERR_TIMEOUT Timed out waiting for the FCU to become ready.
740 * @retval FSP_ERR_WRITE_FAILED Status is indicating a Programming error for the requested operation.
741 * @retval FSP_ERR_CMD_LOCKED FCU is in locked state, typically as a result of having received an illegal
742 * command.
743 **********************************************************************************************************************/
R_FLASH_HP_IdCodeSet(flash_ctrl_t * const p_api_ctrl,uint8_t const * const p_id_code,flash_id_code_mode_t mode)744 fsp_err_t R_FLASH_HP_IdCodeSet (flash_ctrl_t * const p_api_ctrl,
745 uint8_t const * const p_id_code,
746 flash_id_code_mode_t mode)
747 {
748 flash_hp_instance_ctrl_t * p_ctrl = (flash_hp_instance_ctrl_t *) p_api_ctrl;
749
750 fsp_err_t err = FSP_SUCCESS;
751
752 #if (FLASH_HP_CFG_CODE_FLASH_PROGRAMMING_ENABLE == 1) && (BSP_FEATURE_FLASH_SUPPORTS_ID_CODE == 1)
753 #if (FLASH_HP_CFG_PARAM_CHECKING_ENABLE)
754
755 /* Verify the id bytes are not in code flash. They will not be available in P/E mode. */
756 FSP_ASSERT(((uint32_t) p_id_code) > BSP_ROM_SIZE_BYTES);
757
758 /* Verify the control block is not null and is opened. */
759 err = r_flash_hp_common_parameter_checking(p_ctrl);
760 FSP_ERROR_RETURN(FSP_SUCCESS == err, err);
761 #endif
762
763 /* If successful set the id code. */
764 err = flash_hp_set_id_code(p_ctrl, p_id_code, mode);
765 #else
766
767 /* Eliminate warning if code flash programming is disabled. */
768 FSP_PARAMETER_NOT_USED(p_ctrl);
769 FSP_PARAMETER_NOT_USED(p_id_code);
770 FSP_PARAMETER_NOT_USED(mode);
771
772 err = FSP_ERR_UNSUPPORTED; // For consistency with _LP API we return error if Code Flash not enabled
773 #endif
774
775 /* Return status. */
776 return err;
777 }
778
779 /*******************************************************************************************************************//**
780 * Configure an access window for the Code Flash memory using the provided start and end address. An access window
781 * defines a contiguous area in Code Flash for which programming/erase is enabled. This area is on block boundaries. The
782 * block containing start_addr is the first block. The block containing end_addr is the last block. The access window
783 * then becomes first block --> last block inclusive. Anything outside this range of Code Flash is then write protected.
784 * @note If the start address and end address are set to the same value, then the access window is effectively
785 * removed. This accomplishes the same functionality as R_FLASH_HP_AccessWindowClear().
786 *
787 * Implements @ref flash_api_t::accessWindowSet.
788 *
789 * @retval FSP_SUCCESS Access window successfully configured.
790 * @retval FSP_ERR_INVALID_ADDRESS Invalid settings for start_addr and/or end_addr.
791 * @retval FSP_ERR_IN_USE FLASH peripheral is busy with a prior operation.
792 * @retval FSP_ERR_ASSERTION NULL provided for p_ctrl.
793 * @retval FSP_ERR_UNSUPPORTED Code Flash Programming is not enabled.
794 * @retval FSP_ERR_NOT_OPEN Flash API has not yet been opened.
795 * @retval FSP_ERR_PE_FAILURE Failed to enter or exit Code Flash P/E mode.
796 * @retval FSP_ERR_TIMEOUT Timed out waiting for the FCU to become ready.
797 * @retval FSP_ERR_WRITE_FAILED Status is indicating a Programming error for the requested operation.
798 * @retval FSP_ERR_CMD_LOCKED FCU is in locked state, typically as a result of having received an illegal
799 * command.
800 **********************************************************************************************************************/
R_FLASH_HP_AccessWindowSet(flash_ctrl_t * const p_api_ctrl,uint32_t const start_addr,uint32_t const end_addr)801 fsp_err_t R_FLASH_HP_AccessWindowSet (flash_ctrl_t * const p_api_ctrl,
802 uint32_t const start_addr,
803 uint32_t const end_addr)
804 {
805 flash_hp_instance_ctrl_t * p_ctrl = (flash_hp_instance_ctrl_t *) p_api_ctrl;
806
807 fsp_err_t err = FSP_SUCCESS;
808
809 #if (FLASH_HP_CFG_CODE_FLASH_PROGRAMMING_ENABLE == 1) && (BSP_FEATURE_FLASH_SUPPORTS_ACCESS_WINDOW == 1)
810 #if (FLASH_HP_CFG_PARAM_CHECKING_ENABLE)
811
812 /* Verify the control block is not null and is opened. */
813 err = r_flash_hp_common_parameter_checking(p_ctrl);
814 FSP_ERROR_RETURN(FSP_SUCCESS == err, err);
815
816 /* Note that the end_addr indicates the address up to, but not including the block that contains that address. */
817 /* Therefore to allow the very last Block to be included in the access window we must allow for FLASH_CF_BLOCK_END+1 */
818 /* If the start or end addresses are invalid return error. */
819 FSP_ERROR_RETURN(start_addr <= end_addr, FSP_ERR_INVALID_ADDRESS);
820 FSP_ERROR_RETURN(end_addr <= BSP_ROM_SIZE_BYTES, FSP_ERR_INVALID_ADDRESS);
821 #endif
822
823 /* Set the access window. */
824 err = flash_hp_access_window_set(p_ctrl, start_addr, end_addr);
825 #else
826
827 /* Eliminate warning if code flash programming is disabled. */
828 FSP_PARAMETER_NOT_USED(p_ctrl);
829
830 FSP_PARAMETER_NOT_USED(start_addr);
831 FSP_PARAMETER_NOT_USED(end_addr);
832
833 err = FSP_ERR_UNSUPPORTED; ///< For consistency with _LP API we return error if Code Flash not enabled
834 #endif
835
836 /* Return status. */
837 return err;
838 }
839
840 /*******************************************************************************************************************//**
841 * Remove any access window that is currently configured in the Code Flash. Subsequent to this call all Code Flash is
842 * writable. Implements @ref flash_api_t::accessWindowClear.
843 *
844 * @retval FSP_SUCCESS Access window successfully removed.
845 * @retval FSP_ERR_IN_USE FLASH peripheral is busy with a prior operation.
846 * @retval FSP_ERR_ASSERTION NULL provided for p_ctrl.
847 * @retval FSP_ERR_UNSUPPORTED Code Flash Programming is not enabled.
848 * @retval FSP_ERR_NOT_OPEN Flash API has not yet been opened.
849 * @retval FSP_ERR_PE_FAILURE Failed to enter or exit Code Flash P/E mode.
850 * @retval FSP_ERR_TIMEOUT Timed out waiting for the FCU to become ready.
851 * @retval FSP_ERR_WRITE_FAILED Status is indicating a Programming error for the requested operation.
852 * @retval FSP_ERR_CMD_LOCKED FCU is in locked state, typically as a result of having received an illegal
853 * command.
854 **********************************************************************************************************************/
R_FLASH_HP_AccessWindowClear(flash_ctrl_t * const p_api_ctrl)855 fsp_err_t R_FLASH_HP_AccessWindowClear (flash_ctrl_t * const p_api_ctrl)
856 {
857 flash_hp_instance_ctrl_t * p_ctrl = (flash_hp_instance_ctrl_t *) p_api_ctrl;
858
859 fsp_err_t err = FSP_SUCCESS;
860
861 #if (FLASH_HP_CFG_CODE_FLASH_PROGRAMMING_ENABLE == 1) && (BSP_FEATURE_FLASH_SUPPORTS_ACCESS_WINDOW == 1)
862 #if (FLASH_HP_CFG_PARAM_CHECKING_ENABLE)
863
864 /* Verify the control block is not null and is opened. */
865 err = r_flash_hp_common_parameter_checking(p_ctrl);
866 FSP_ERROR_RETURN(FSP_SUCCESS == err, err);
867 #endif
868
869 /* Clear the access window. When the start address and end address are set to the same value, then the access
870 * window is effectively removed. */
871 err = flash_hp_access_window_set(p_ctrl, 0, 0);
872 #else
873
874 /* Eliminate warning if code flash programming is disabled. */
875 FSP_PARAMETER_NOT_USED(p_ctrl);
876
877 err = FSP_ERR_UNSUPPORTED; ///< For consistency with _LP API we return error if Code Flash not enabled
878 #endif
879
880 return err;
881 }
882
883 /*******************************************************************************************************************//**
884 * Reset the FLASH peripheral. Implements @ref flash_api_t::reset.
885 *
886 * No attempt is made to check if the flash is busy before executing the reset since the assumption is that a reset will
887 * terminate any existing operation.
888 *
889 * @retval FSP_SUCCESS Flash circuit successfully reset.
890 * @retval FSP_ERR_ASSERTION NULL provided for p_ctrl.
891 * @retval FSP_ERR_NOT_OPEN The control block is not open.
892 * @retval FSP_ERR_PE_FAILURE Failed to enter or exit P/E mode.
893 * @retval FSP_ERR_TIMEOUT Timed out waiting for the FCU to become ready.
894 * @retval FSP_ERR_CMD_LOCKED FCU is in locked state, typically as a result of having received an illegal command.
895 **********************************************************************************************************************/
R_FLASH_HP_Reset(flash_ctrl_t * const p_api_ctrl)896 fsp_err_t R_FLASH_HP_Reset (flash_ctrl_t * const p_api_ctrl)
897 {
898 flash_hp_instance_ctrl_t * p_ctrl = (flash_hp_instance_ctrl_t *) p_api_ctrl;
899
900 /* Eliminate warning if parameter checking is disabled. */
901 FSP_PARAMETER_NOT_USED(p_ctrl);
902
903 #if (FLASH_HP_CFG_PARAM_CHECKING_ENABLE)
904
905 /* If null pointer return error. */
906 FSP_ASSERT(NULL != p_ctrl);
907
908 /* If control block not open return error. */
909 FSP_ERROR_RETURN(FLASH_HP_OPEN == p_ctrl->opened, FSP_ERR_NOT_OPEN);
910 #endif
911
912 /* Reset the flash. */
913 return flash_hp_reset(p_ctrl);
914 }
915
916 /*******************************************************************************************************************//**
917 * Selects which block, Default (Block 0) or Alternate (Block 1), is used as the startup area block. The provided
918 * parameters determine which block will become the active startup block and whether that action will be immediate (but
919 * temporary), or permanent subsequent to the next reset. Doing a temporary switch might appear to have limited
920 * usefulness. If there is an access window in place such that Block 0 is write protected, then one could do a temporary
921 * switch, update the block and switch them back without having to touch the access window. Implements
922 * @ref flash_api_t::startupAreaSelect.
923 *
924 * @retval FSP_SUCCESS Start-up area successfully toggled.
925 * @retval FSP_ERR_IN_USE FLASH peripheral is busy with a prior operation.
926 * @retval FSP_ERR_ASSERTION NULL provided for p_ctrl.
927 * @retval FSP_ERR_NOT_OPEN The control block is not open.
928 * @retval FSP_ERR_UNSUPPORTED Code Flash Programming is not enabled.
929 * @retval FSP_ERR_PE_FAILURE Failed to enter or exit Code Flash P/E mode.
930 * @retval FSP_ERR_TIMEOUT Timed out waiting for the FCU to become ready.
931 * @retval FSP_ERR_WRITE_FAILED Status is indicating a Programming error for the requested operation.
932 * @retval FSP_ERR_CMD_LOCKED FCU is in locked state, typically as a result of having received an illegal
933 * command.
934 **********************************************************************************************************************/
R_FLASH_HP_StartUpAreaSelect(flash_ctrl_t * const p_api_ctrl,flash_startup_area_swap_t swap_type,bool is_temporary)935 fsp_err_t R_FLASH_HP_StartUpAreaSelect (flash_ctrl_t * const p_api_ctrl,
936 flash_startup_area_swap_t swap_type,
937 bool is_temporary)
938 {
939 flash_hp_instance_ctrl_t * p_ctrl = (flash_hp_instance_ctrl_t *) p_api_ctrl;
940
941 /* Eliminate warning if parameter checking is disabled. */
942 FSP_PARAMETER_NOT_USED(p_ctrl);
943
944 fsp_err_t err = FSP_SUCCESS;
945
946 #if (FLASH_HP_CFG_CODE_FLASH_PROGRAMMING_ENABLE == 1)
947 #if (FLASH_HP_CFG_PARAM_CHECKING_ENABLE)
948
949 /* Verify the control block is not null and is opened. */
950 err = r_flash_hp_common_parameter_checking(p_ctrl);
951 FSP_ERROR_RETURN(FSP_SUCCESS == err, err);
952
953 /* If the swap type is BTFLG and the operation is temporary there's nothing to do. */
954 FSP_ASSERT(!((swap_type == FLASH_STARTUP_AREA_BTFLG) && (is_temporary == false)));
955 #endif
956
957 err = flash_hp_set_startup_area_boot(p_ctrl, swap_type, is_temporary);
958 #else
959
960 /* Eliminate warning if code flash programming is disabled. */
961 FSP_PARAMETER_NOT_USED(p_ctrl);
962 FSP_PARAMETER_NOT_USED(swap_type);
963 FSP_PARAMETER_NOT_USED(is_temporary);
964
965 err = FSP_ERR_UNSUPPORTED; ///< For consistency with _LP API we return error if Code Flash not enabled
966 #endif
967
968 return err;
969 }
970
971 /*******************************************************************************************************************//**
972 * Swaps the flash bank located at address 0x00000000 and address 0x00200000. This can only be done when in dual bank
973 * mode. Dual bank mode can be enabled in the FSP Configuration Tool under BSP Properties. After a bank swap is done
974 * the MCU will need to be reset for the changes to take place.
975 * @ref flash_api_t::bankSwap.
976 *
977 * @retval FSP_SUCCESS Start-up area successfully toggled.
978 * @retval FSP_ERR_IN_USE FLASH peripheral is busy with a prior operation.
979 * @retval FSP_ERR_ASSERTION NULL provided for p_ctrl.
980 * @retval FSP_ERR_NOT_OPEN The control block is not open.
981 * @retval FSP_ERR_UNSUPPORTED Code Flash Programming is not enabled.
982 * @retval FSP_ERR_PE_FAILURE Failed to enter or exit Code Flash P/E mode.
983 * @retval FSP_ERR_TIMEOUT Timed out waiting for the FCU to become ready.
984 * @retval FSP_ERR_INVALID_MODE Cannot switch banks while flash is in Linear mode.
985 * @retval FSP_ERR_WRITE_FAILED Flash write operation failed.
986 * @retval FSP_ERR_CMD_LOCKED FCU is in locked state, typically as a result of having received an illegal
987 * command.
988 **********************************************************************************************************************/
R_FLASH_HP_BankSwap(flash_ctrl_t * const p_api_ctrl)989 fsp_err_t R_FLASH_HP_BankSwap (flash_ctrl_t * const p_api_ctrl)
990 {
991 flash_hp_instance_ctrl_t * p_ctrl = (flash_hp_instance_ctrl_t *) p_api_ctrl;
992
993 /* Eliminate warning if parameter checking is disabled. */
994 FSP_PARAMETER_NOT_USED(p_ctrl);
995
996 fsp_err_t err = FSP_SUCCESS;
997
998 #if (FLASH_HP_CFG_CODE_FLASH_PROGRAMMING_ENABLE == 1) && (BSP_FEATURE_FLASH_HP_SUPPORTS_DUAL_BANK == 1)
999 #if (FLASH_HP_CFG_PARAM_CHECKING_ENABLE)
1000
1001 /* Verify the control block is not null and is opened. */
1002 err = r_flash_hp_common_parameter_checking(p_ctrl);
1003 FSP_ERROR_RETURN(FSP_SUCCESS == err, err);
1004
1005 FSP_ERROR_RETURN(0 == (*flash_hp_dualsel & FLASH_HP_PRV_DUALSEL_BANKMD_MASK), FSP_ERR_INVALID_MODE)
1006 #endif
1007
1008 flash_hp_bank_swap(p_ctrl);
1009 #else
1010
1011 /* Eliminate warning if code flash programming is disabled. */
1012 FSP_PARAMETER_NOT_USED(p_ctrl);
1013
1014 err = FSP_ERR_UNSUPPORTED; ///< For consistency with _LP API we return error if Code Flash not enabled
1015 #endif
1016
1017 return err;
1018 }
1019
1020 /*******************************************************************************************************************//**
1021 * Indicate to the already open Flash API that the FCLK has changed. Implements @ref flash_api_t::updateFlashClockFreq.
1022 *
1023 * This could be the case if the application has changed the system clock, and therefore the FCLK. Failure to call this
1024 * function subsequent to changing the FCLK could result in damage to the flash macro.
1025 *
1026 * @retval FSP_SUCCESS Start-up area successfully toggled.
1027 * @retval FSP_ERR_IN_USE Flash is busy with an on-going operation.
1028 * @retval FSP_ERR_ASSERTION NULL provided for p_ctrl
1029 * @retval FSP_ERR_NOT_OPEN Flash API has not yet been opened.
1030 * @retval FSP_ERR_FCLK FCLK is not within the acceptable range.
1031 **********************************************************************************************************************/
R_FLASH_HP_UpdateFlashClockFreq(flash_ctrl_t * const p_api_ctrl)1032 fsp_err_t R_FLASH_HP_UpdateFlashClockFreq (flash_ctrl_t * const p_api_ctrl)
1033 {
1034 flash_hp_instance_ctrl_t * p_ctrl = (flash_hp_instance_ctrl_t *) p_api_ctrl;
1035
1036 #if (FLASH_HP_CFG_PARAM_CHECKING_ENABLE)
1037
1038 /* Verify the control block is not null and is opened. */
1039 fsp_err_t err = r_flash_hp_common_parameter_checking(p_ctrl);
1040 FSP_ERROR_RETURN(FSP_SUCCESS == err, err);
1041 #endif
1042
1043 /* Calculate timeout values */
1044 return flash_hp_init(p_ctrl);
1045 }
1046
1047 /*******************************************************************************************************************//**
1048 * Returns the information about the flash regions. Implements @ref flash_api_t::infoGet.
1049 *
1050 * @retval FSP_SUCCESS Successful retrieved the request information.
1051 * @retval FSP_ERR_NOT_OPEN The control block is not open.
1052 * @retval FSP_ERR_ASSERTION NULL provided for p_ctrl or p_info.
1053 **********************************************************************************************************************/
R_FLASH_HP_InfoGet(flash_ctrl_t * const p_api_ctrl,flash_info_t * const p_info)1054 fsp_err_t R_FLASH_HP_InfoGet (flash_ctrl_t * const p_api_ctrl, flash_info_t * const p_info)
1055 {
1056 #if FLASH_HP_CFG_PARAM_CHECKING_ENABLE
1057
1058 /* If null pointers return error. */
1059 FSP_ASSERT(NULL != p_api_ctrl);
1060 FSP_ASSERT(NULL != p_info);
1061
1062 flash_hp_instance_ctrl_t * p_ctrl = (flash_hp_instance_ctrl_t *) p_api_ctrl;
1063
1064 /* If the flash api is not open return an error. */
1065 FSP_ERROR_RETURN(FLASH_HP_OPEN == p_ctrl->opened, FSP_ERR_NOT_OPEN);
1066 #else
1067
1068 /* Eliminate warning if parameter checking is disabled. */
1069 FSP_PARAMETER_NOT_USED(p_api_ctrl);
1070 #endif
1071
1072 /* Copy information about the code and data flash to the user structure. */
1073 p_info->code_flash = g_flash_code_region;
1074 p_info->data_flash = g_flash_data_region;
1075
1076 return FSP_SUCCESS;
1077 }
1078
1079 /*******************************************************************************************************************//**
1080 * Releases any resources that were allocated by the Open() or any subsequent Flash operations. Implements
1081 * @ref flash_api_t::close.
1082 *
1083 * @retval FSP_SUCCESS Successful close.
1084 * @retval FSP_ERR_NOT_OPEN The control block is not open.
1085 * @retval FSP_ERR_ASSERTION NULL provided for p_ctrl or p_cfg.
1086 **********************************************************************************************************************/
R_FLASH_HP_Close(flash_ctrl_t * const p_api_ctrl)1087 fsp_err_t R_FLASH_HP_Close (flash_ctrl_t * const p_api_ctrl)
1088 {
1089 flash_hp_instance_ctrl_t * p_ctrl = (flash_hp_instance_ctrl_t *) p_api_ctrl;
1090
1091 /* Eliminate warning if parameter checking is disabled. */
1092 FSP_PARAMETER_NOT_USED(p_ctrl);
1093
1094 fsp_err_t err = FSP_SUCCESS;
1095
1096 #if FLASH_HP_CFG_PARAM_CHECKING_ENABLE
1097
1098 /* If null pointer return error. */
1099 FSP_ASSERT(NULL != p_ctrl);
1100
1101 /* If the flash api is not open return an error. */
1102 FSP_ERROR_RETURN(FLASH_HP_OPEN == p_ctrl->opened, FSP_ERR_NOT_OPEN);
1103 #endif
1104
1105 /* Close the API */
1106 p_ctrl->opened = FLASH_HP_CLOSE;
1107
1108 if (p_ctrl->p_cfg->irq >= 0)
1109 {
1110 /* Disable interrupt in ICU */
1111 R_BSP_IrqDisable(p_ctrl->p_cfg->irq);
1112 }
1113
1114 /* Disable Flash Rdy interrupt in the FLASH peripheral */
1115 R_FACI_HP->FRDYIE = 0x00U;
1116
1117 if (p_ctrl->p_cfg->err_irq >= 0)
1118 {
1119 /* Disable interrupt in ICU */
1120 R_BSP_IrqDisable(p_ctrl->p_cfg->err_irq);
1121 }
1122
1123 /* Disable Flash Error interrupt in the FLASH peripheral */
1124 R_FACI_HP->FAEINT = 0x00U;
1125
1126 return err;
1127 }
1128
1129 /*******************************************************************************************************************//**
1130 * Updates the user callback with the option to provide memory for the callback argument structure.
1131 * Implements @ref flash_api_t::callbackSet.
1132 *
1133 * @retval FSP_SUCCESS Callback updated successfully.
1134 * @retval FSP_ERR_ASSERTION A required pointer is NULL.
1135 * @retval FSP_ERR_NOT_OPEN The control block has not been opened.
1136 * @retval FSP_ERR_NO_CALLBACK_MEMORY p_callback is non-secure and p_callback_memory is either secure or NULL.
1137 **********************************************************************************************************************/
R_FLASH_HP_CallbackSet(flash_ctrl_t * const p_api_ctrl,void (* p_callback)(flash_callback_args_t *),void const * const p_context,flash_callback_args_t * const p_callback_memory)1138 fsp_err_t R_FLASH_HP_CallbackSet (flash_ctrl_t * const p_api_ctrl,
1139 void ( * p_callback)(flash_callback_args_t *),
1140 void const * const p_context,
1141 flash_callback_args_t * const p_callback_memory)
1142 {
1143 flash_hp_instance_ctrl_t * p_ctrl = (flash_hp_instance_ctrl_t *) p_api_ctrl;
1144
1145 #if FLASH_HP_CFG_PARAM_CHECKING_ENABLE
1146 FSP_ASSERT(p_ctrl);
1147 FSP_ASSERT(p_callback);
1148 FSP_ERROR_RETURN(FLASH_HP_OPEN == p_ctrl->opened, FSP_ERR_NOT_OPEN);
1149 #endif
1150
1151 #if BSP_TZ_SECURE_BUILD
1152
1153 /* Get security state of p_callback */
1154 bool callback_is_secure =
1155 (NULL == cmse_check_address_range((void *) p_callback, sizeof(void *), CMSE_AU_NONSECURE));
1156
1157 #if FLASH_HP_CFG_PARAM_CHECKING_ENABLE
1158
1159 /* In secure projects, p_callback_memory must be provided in non-secure space if p_callback is non-secure */
1160 flash_callback_args_t * const p_callback_memory_checked = cmse_check_pointed_object(p_callback_memory,
1161 CMSE_AU_NONSECURE);
1162 FSP_ERROR_RETURN(callback_is_secure || (NULL != p_callback_memory_checked), FSP_ERR_NO_CALLBACK_MEMORY);
1163 #endif
1164 #endif
1165
1166 /* Store callback and context */
1167 #if BSP_TZ_SECURE_BUILD
1168 p_ctrl->p_callback = callback_is_secure ? p_callback :
1169 (void (*)(flash_callback_args_t *))cmse_nsfptr_create(p_callback);
1170 #else
1171 p_ctrl->p_callback = p_callback;
1172 #endif
1173 p_ctrl->p_context = p_context;
1174 p_ctrl->p_callback_memory = p_callback_memory;
1175
1176 return FSP_SUCCESS;
1177 }
1178
1179 /*******************************************************************************************************************//**
1180 * @} (end addtogroup FLASH_HP)
1181 **********************************************************************************************************************/
1182
1183 /*******************************************************************************************************************//**
1184 * Write data to the flash.
1185 *
1186 * @param p_ctrl Pointer to the control block
1187 * @param[in] write_size The write size
1188 * @param[in] timeout The timeout
1189 *
1190 * @retval FSP_SUCCESS Write completed succesfully
1191 * @retval FSP_ERR_TIMEOUT Flash timed out during write operation.
1192 **********************************************************************************************************************/
flash_hp_write_data(flash_hp_instance_ctrl_t * const p_ctrl,uint32_t write_size,uint32_t timeout)1193 static fsp_err_t flash_hp_write_data (flash_hp_instance_ctrl_t * const p_ctrl, uint32_t write_size, uint32_t timeout)
1194 {
1195 volatile uint32_t wait_count;
1196
1197 /* Set block start address */
1198 R_FACI_HP->FSADDR = p_ctrl->dest_end_address;
1199
1200 /* Issue two part Write commands */
1201 R_FACI_HP_CMD->FACI_CMD8 = FLASH_HP_FACI_CMD_PROGRAM;
1202 R_FACI_HP_CMD->FACI_CMD8 = (uint8_t) (write_size / 2U);
1203
1204 /* Write one line. If timeout stop the flash and return error. */
1205 for (uint32_t i = 0U; i < (write_size / 2U); i++)
1206 {
1207 wait_count = p_ctrl->timeout_dbfull;
1208
1209 /* Copy data from source address to destination area */
1210 R_FACI_HP_CMD->FACI_CMD16 = *(uint16_t *) p_ctrl->source_start_address;
1211
1212 while (R_FACI_HP->FSTATR_b.DBFULL == 1U)
1213 {
1214 /* Wait until DBFULL is 0 unless timeout occurs. */
1215 if (wait_count-- == 0U)
1216 {
1217
1218 /* If DBFULL is not set to 0 return timeout. */
1219 return FSP_ERR_TIMEOUT;
1220 }
1221 }
1222
1223 /* Each write handles 2 bytes of data. */
1224 p_ctrl->source_start_address += 2U;
1225 p_ctrl->dest_end_address += 2U;
1226 p_ctrl->operations_remaining--;
1227 }
1228
1229 /* Issue write end command */
1230 R_FACI_HP_CMD->FACI_CMD8 = FLASH_HP_FACI_CMD_FINAL;
1231
1232 /* If a timeout has been supplied wait for the flash to become ready. Otherwise return immediately. */
1233 if (timeout)
1234 {
1235 /* Read FRDY bit until it has been set to 1 indicating that the current operation is complete.*/
1236 /* Wait until operation has completed or timeout occurs. If timeout stop the module and return error. */
1237 while (1U != R_FACI_HP->FSTATR_b.FRDY)
1238 {
1239 /* Wait until FRDY is 1 unless timeout occurs. */
1240 if (timeout == 0U)
1241 {
1242 return FSP_ERR_TIMEOUT;
1243 }
1244
1245 timeout--;
1246 }
1247 }
1248
1249 return FSP_SUCCESS;
1250 }
1251
1252 /*******************************************************************************************************************//**
1253 * Check for errors after a flash operation
1254 *
1255 * @param[in] previous_error The previous error
1256 * @param[in] error_bits The error bits
1257 * @param[in] return_error The return error
1258 *
1259 * @retval FSP_SUCCESS Command completed succesfully
1260 * @retval FSP_ERR_CMD_LOCKED Flash entered command locked state
1261 **********************************************************************************************************************/
flash_hp_check_errors(fsp_err_t previous_error,uint32_t error_bits,fsp_err_t return_error)1262 static fsp_err_t flash_hp_check_errors (fsp_err_t previous_error, uint32_t error_bits, fsp_err_t return_error)
1263 {
1264 /* See "Recovery from the Command-Locked State": Section 47.9.3.6 of the RA6M4 manual R01UH0890EJ0100.*/
1265 fsp_err_t err = FSP_SUCCESS;
1266 if (1U == R_FACI_HP->FASTAT_b.CMDLK)
1267 {
1268 /* If an illegal error occurred read and clear CFAE and DFAE in FASTAT. */
1269 if (1U == R_FACI_HP->FSTATR_b.ILGLERR)
1270 {
1271 R_FACI_HP->FASTAT;
1272 R_FACI_HP->FASTAT = 0;
1273 }
1274
1275 err = FSP_ERR_CMD_LOCKED;
1276 }
1277
1278 /* Check if status is indicating a Programming error */
1279 /* If a programming error occurred return error. */
1280 if (R_FACI_HP->FSTATR & error_bits)
1281 {
1282 err = return_error;
1283 }
1284
1285 /* Return the first error code that was encountered. */
1286 if (FSP_SUCCESS != previous_error)
1287 {
1288 err = previous_error;
1289 }
1290
1291 if (FSP_SUCCESS != err)
1292 {
1293 /* Stop the flash and return the previous error. */
1294 (void) flash_hp_stop();
1295 }
1296
1297 return err;
1298 }
1299
1300 #if (FLASH_HP_CFG_CODE_FLASH_PROGRAMMING_ENABLE == 1)
1301
1302 /*******************************************************************************************************************//**
1303 * This function initiates the write sequence for the R_FLASH_HP_Write() function.
1304 * @param[in] p_ctrl Flash control block
1305 * @retval FSP_SUCCESS The write started successfully.
1306 * @retval FSP_ERR_PE_FAILURE Failed to enter or exit Code Flash P/E mode.
1307 * @retval FSP_ERR_CMD_LOCKED Flash entered command locked state.
1308 * @retval FSP_ERR_TIMEOUT Flash timed out during write operation.
1309 * @retval FSP_ERR_WRITE_FAILED Flash write operation failed.
1310 **********************************************************************************************************************/
flash_hp_cf_write(flash_hp_instance_ctrl_t * const p_ctrl)1311 static fsp_err_t flash_hp_cf_write (flash_hp_instance_ctrl_t * const p_ctrl)
1312 {
1313 fsp_err_t err = FSP_SUCCESS;
1314
1315 /* Update Flash state and enter the respective Code or Data Flash P/E mode. If failure return error */
1316 err = flash_hp_enter_pe_cf_mode(p_ctrl);
1317 FSP_ERROR_RETURN(FSP_SUCCESS == err, err);
1318
1319 /* Iterate through the number of data bytes */
1320 while (p_ctrl->operations_remaining && (err == FSP_SUCCESS))
1321 {
1322 err = flash_hp_write_data(p_ctrl, BSP_FEATURE_FLASH_HP_CF_WRITE_SIZE, p_ctrl->timeout_write_cf);
1323
1324 err = flash_hp_check_errors(err, FLASH_HP_FSTATR_PRGERR | FLASH_HP_FSTATR_ILGLERR, FSP_ERR_WRITE_FAILED);
1325 }
1326
1327 /* Return to read mode*/
1328 fsp_err_t pe_exit_err = flash_hp_pe_mode_exit();
1329
1330 if (FSP_SUCCESS == err)
1331 {
1332 err = pe_exit_err;
1333 }
1334
1335 /* Return status. */
1336 return err;
1337 }
1338
1339 #if (BSP_FEATURE_FLASH_HP_SUPPORTS_DUAL_BANK == 1)
1340
1341 /*******************************************************************************************************************//**
1342 * This function swaps which flash bank will be used to boot from after the next reset.
1343 * @param[in] p_ctrl Flash control block
1344 * @retval FSP_SUCCESS The write started successfully.
1345 * @retval FSP_ERR_PE_FAILURE Failed to enter or exit Code Flash P/E mode.
1346 * @retval FSP_ERR_CMD_LOCKED Flash entered command locked state.
1347 * @retval FSP_ERR_TIMEOUT Flash timed out during write operation.
1348 * @retval FSP_ERR_WRITE_FAILED Flash write operation failed.
1349 **********************************************************************************************************************/
flash_hp_bank_swap(flash_hp_instance_ctrl_t * const p_ctrl)1350 static fsp_err_t flash_hp_bank_swap (flash_hp_instance_ctrl_t * const p_ctrl)
1351 {
1352 fsp_err_t err = FSP_SUCCESS;
1353
1354 /* Unused bits should be written as 1. */
1355 g_configuration_area_data[0] =
1356 (uint16_t) ((~FLASH_HP_PRV_BANKSEL_BANKSWP_MASK) | (~(FLASH_HP_PRV_BANKSEL_BANKSWP_MASK & *flash_hp_banksel)));
1357
1358 memset(&g_configuration_area_data[1], UINT8_MAX, 7 * sizeof(uint16_t));
1359
1360 flash_hp_enter_pe_cf_mode(p_ctrl);
1361
1362 /* Write the configuration area to the access/startup region. */
1363 err = flash_hp_configuration_area_write(p_ctrl, FLASH_HP_FCU_CONFIG_SET_BANK_MODE);
1364
1365 err = flash_hp_check_errors(err, 0, FSP_ERR_WRITE_FAILED);
1366
1367 /* Return to read mode*/
1368 fsp_err_t pe_exit_err = flash_hp_pe_mode_exit();
1369
1370 if (FSP_SUCCESS == err)
1371 {
1372 err = pe_exit_err;
1373 }
1374
1375 /* Return status. */
1376 return err;
1377 }
1378
1379 #endif
1380 #endif
1381
1382 #if (FLASH_HP_CFG_DATA_FLASH_PROGRAMMING_ENABLE == 1)
1383
1384 /*******************************************************************************************************************//**
1385 * This function initiates the write sequence for the R_FLASH_HP_Write() function.
1386 * @param[in] p_ctrl Flash control block
1387 * @retval FSP_SUCCESS The write started successfully.
1388 * @retval FSP_ERR_PE_FAILURE Failed to enter or exit P/E mode.
1389 * @retval FSP_ERR_CMD_LOCKED Flash entered command locked state.
1390 * @retval FSP_ERR_TIMEOUT Flash timed out during write operation.
1391 * @retval FSP_ERR_WRITE_FAILED Flash write operation failed.
1392 **********************************************************************************************************************/
flash_hp_df_write(flash_hp_instance_ctrl_t * const p_ctrl)1393 static fsp_err_t flash_hp_df_write (flash_hp_instance_ctrl_t * const p_ctrl)
1394 {
1395 fsp_err_t err = FSP_SUCCESS;
1396
1397 /* Update Flash state and enter the respective Code or Data Flash P/E mode. If failure return error */
1398 err = flash_hp_enter_pe_df_mode(p_ctrl);
1399 FSP_ERROR_RETURN(FSP_SUCCESS == err, err);
1400
1401 uint32_t wait_count;
1402
1403 /* If in BGO mode, exit here; remaining processing if any will be done in ISR */
1404 if (p_ctrl->p_cfg->data_flash_bgo == true)
1405 {
1406 p_ctrl->current_operation = FLASH_OPERATION_DF_BGO_WRITE;
1407 wait_count = 0;
1408 }
1409 else
1410 {
1411 wait_count = p_ctrl->timeout_write_df;
1412 }
1413
1414 do
1415 {
1416 err = flash_hp_write_data(p_ctrl, BSP_FEATURE_FLASH_HP_DF_WRITE_SIZE, wait_count);
1417
1418 if (p_ctrl->p_cfg->data_flash_bgo)
1419 {
1420
1421 /* Errors will be handled in the error interrupt when using BGO. */
1422 return err;
1423 }
1424
1425 err = flash_hp_check_errors(err, FLASH_HP_FSTATR_PRGERR, FSP_ERR_WRITE_FAILED);
1426 } while (p_ctrl->operations_remaining && (err == FSP_SUCCESS));
1427
1428 /* Return to read mode*/
1429 fsp_err_t pe_exit_err = flash_hp_pe_mode_exit();
1430
1431 if (FSP_SUCCESS == err)
1432 {
1433 err = pe_exit_err;
1434 }
1435
1436 return err;
1437 }
1438
1439 #endif
1440
1441 #if (FLASH_HP_CFG_PARAM_CHECKING_ENABLE == 1)
1442
1443 /*******************************************************************************************************************//**
1444 * This function performs the parameter checking required by the write, read and blank check functions.
1445 *
1446 * @param[in] p_ctrl Flash control block
1447 * @param[in] flash_address The flash address to be written to
1448 * @param[in] num_bytes The number bytes
1449 * @param[in] check_write Check that the parameters are valid for a write.
1450 *
1451 * @retval FSP_SUCCESS Parameter checking completed without error.
1452 * @retval FSP_ERR_IN_USE The Flash peripheral is busy with a prior on-going transaction.
1453 * @retval FSP_ERR_NOT_OPEN The Flash API is not Open.
1454 * @retval FSP_ERR_ASSERTION Null pointer
1455 * @retval FSP_ERR_INVALID_SIZE Number of bytes provided was not a multiple of the programming size or exceeded
1456 * the maximum range.
1457 * @retval FSP_ERR_INVALID_ADDRESS Invalid address was input or address not on programming boundary.
1458 **********************************************************************************************************************/
r_flash_hp_write_bc_parameter_checking(flash_hp_instance_ctrl_t * const p_ctrl,uint32_t flash_address,uint32_t const num_bytes,bool check_write)1459 static fsp_err_t r_flash_hp_write_bc_parameter_checking (flash_hp_instance_ctrl_t * const p_ctrl,
1460 uint32_t flash_address,
1461 uint32_t const num_bytes,
1462 bool check_write)
1463 {
1464 /* Verify the control block is not null and is opened. Verify the flash isn't in use. */
1465 fsp_err_t err = r_flash_hp_common_parameter_checking(p_ctrl);
1466 FSP_ERROR_RETURN(FSP_SUCCESS == err, err);
1467
1468 uint32_t write_size;
1469
1470 if (p_ctrl->p_cfg->data_flash_bgo == true)
1471 {
1472 FSP_ASSERT(NULL != p_ctrl->p_callback);
1473 }
1474
1475 /* If invalid address or number of bytes return error. */
1476 #if (FLASH_HP_CFG_CODE_FLASH_PROGRAMMING_ENABLE == 1)
1477 if (flash_address < BSP_FEATURE_FLASH_DATA_FLASH_START)
1478 {
1479 uint32_t rom_end = BSP_ROM_SIZE_BYTES;
1480 #if BSP_FEATURE_FLASH_HP_SUPPORTS_DUAL_BANK
1481 if (0 == (FLASH_HP_PRV_DUALSEL_BANKMD_MASK & *flash_hp_dualsel))
1482 {
1483 flash_address = flash_address % BSP_FEATURE_FLASH_HP_CF_DUAL_BANK_START;
1484 rom_end = BSP_ROM_SIZE_BYTES / 2;
1485 }
1486 #endif
1487
1488 FSP_ERROR_RETURN(flash_address + num_bytes <= rom_end, FSP_ERR_INVALID_SIZE);
1489 write_size = BSP_FEATURE_FLASH_HP_CF_WRITE_SIZE;
1490 }
1491 else
1492 #endif
1493 {
1494 #if (FLASH_HP_CFG_DATA_FLASH_PROGRAMMING_ENABLE == 1)
1495 FSP_ERROR_RETURN((flash_address >= (FLASH_HP_DF_START_ADDRESS)) &&
1496 (flash_address < (FLASH_HP_DF_START_ADDRESS + BSP_DATA_FLASH_SIZE_BYTES)),
1497 FSP_ERR_INVALID_ADDRESS);
1498 FSP_ERROR_RETURN((flash_address + num_bytes <= (FLASH_HP_DF_START_ADDRESS + BSP_DATA_FLASH_SIZE_BYTES)),
1499 FSP_ERR_INVALID_SIZE);
1500 write_size = BSP_FEATURE_FLASH_HP_DF_WRITE_SIZE;
1501 #else
1502
1503 return FSP_ERR_INVALID_ADDRESS;
1504 #endif
1505 }
1506
1507 if (check_write)
1508 {
1509 FSP_ERROR_RETURN(!(flash_address & (write_size - 1U)), FSP_ERR_INVALID_ADDRESS);
1510 FSP_ERROR_RETURN(!(num_bytes & (write_size - 1U)), FSP_ERR_INVALID_SIZE);
1511 }
1512
1513 /* If invalid number of bytes return error. */
1514 FSP_ERROR_RETURN((0 != num_bytes), FSP_ERR_INVALID_SIZE);
1515
1516 /* If control block is not open return error. */
1517 FSP_ERROR_RETURN((FLASH_HP_OPEN == p_ctrl->opened), FSP_ERR_NOT_OPEN);
1518
1519 return FSP_SUCCESS;
1520 }
1521
1522 #endif
1523
1524 #if (FLASH_HP_CFG_PARAM_CHECKING_ENABLE == 1)
1525
1526 /*******************************************************************************************************************//**
1527 * This function performs the common parameter checking required by top level API functions.
1528 * @param p_ctrl Pointer to the control block
1529 * @retval FSP_SUCCESS Parameter checking completed without error.
1530 * @retval FSP_ERR_ASSERTION Null pointer
1531 * @retval FSP_ERR_NOT_OPEN The flash module is not open.
1532 * @retval FSP_ERR_IN_USE The Flash peripheral is busy with a prior on-going transaction.
1533 **********************************************************************************************************************/
r_flash_hp_common_parameter_checking(flash_hp_instance_ctrl_t * const p_ctrl)1534 static fsp_err_t r_flash_hp_common_parameter_checking (flash_hp_instance_ctrl_t * const p_ctrl)
1535 {
1536 /* If null control block return error. */
1537 FSP_ASSERT(p_ctrl);
1538
1539 /* If control block is not open return error. */
1540 FSP_ERROR_RETURN((FLASH_HP_OPEN == p_ctrl->opened), FSP_ERR_NOT_OPEN);
1541
1542 /* If the flash is currently in program/erase mode return an error. */
1543 FSP_ERROR_RETURN((R_FACI_HP->FENTRYR & FLASH_HP_FENTRYR_PE_MODE_BITS) == 0x0000U, FSP_ERR_IN_USE);
1544
1545 return FSP_SUCCESS;
1546 }
1547
1548 #endif
1549
1550 #if (FLASH_HP_CFG_DATA_FLASH_PROGRAMMING_ENABLE == 1)
1551
1552 /*******************************************************************************************************************//**
1553 * This function performs the Blank check phase required by the R_FLASH_HP_BlankCheck() function.
1554 *
1555 * @param[in] p_ctrl Flash control block
1556 * @param[in] address The start address of the range to blank check
1557 * @param[in] num_bytes The number bytes
1558 * @param[out] p_blank_check_result The blank check result
1559 *
1560 * @retval FSP_SUCCESS Setup completed completed without error.
1561 * @retval FSP_ERR_PE_FAILURE Failed to enter P/E mode
1562 * @retval FSP_ERR_CMD_LOCKED Peripheral in command locked state.
1563 * @retval FSP_ERR_TIMEOUT Timed out waiting for the FCU to become ready.
1564 * @retval FSP_ERR_BLANK_CHECK_FAILED Blank check operation failed.
1565 **********************************************************************************************************************/
flash_hp_df_blank_check(flash_hp_instance_ctrl_t * const p_ctrl,uint32_t const address,uint32_t num_bytes,flash_result_t * p_blank_check_result)1566 static fsp_err_t flash_hp_df_blank_check (flash_hp_instance_ctrl_t * const p_ctrl,
1567 uint32_t const address,
1568 uint32_t num_bytes,
1569 flash_result_t * p_blank_check_result)
1570 {
1571 fsp_err_t err;
1572
1573 /* This is a request to Blank check Data Flash */
1574 err = flash_hp_enter_pe_df_mode(p_ctrl);
1575 FSP_ERROR_RETURN(FSP_SUCCESS == err, err);
1576
1577 /* Start the Blank check operation. If BGO is enabled then the result of the Blank check will be
1578 * available when the interrupt occurs and p_blank_check_result will contain FLASH_RESULT_BGO_ACTIVE */
1579
1580 /* Call blank check. If successful and not DF BGO operation then enter read mode. */
1581 /* Set the mode to incremental*/
1582 R_FACI_HP->FBCCNT = 0x00U;
1583
1584 /* Set the start address for blank checking*/
1585 R_FACI_HP->FSADDR = address;
1586
1587 /* Set the end address for blank checking*/
1588 R_FACI_HP->FEADDR = (address + num_bytes) - 1U;
1589
1590 /* Issue two part Blank Check command*/
1591 R_FACI_HP_CMD->FACI_CMD8 = FLASH_HP_FACI_CMD_BLANK_CHECK;
1592 R_FACI_HP_CMD->FACI_CMD8 = FLASH_HP_FACI_CMD_FINAL;
1593
1594 /* If in DF BGO mode, exit here; remaining processing if any will be done in ISR */
1595 if (p_ctrl->p_cfg->data_flash_bgo == true)
1596 {
1597 p_ctrl->current_operation = FLASH_OPERATION_DF_BGO_BLANKCHECK;
1598 *p_blank_check_result = FLASH_RESULT_BGO_ACTIVE;
1599
1600 return FSP_SUCCESS;
1601 }
1602
1603 /* timeout_blank_check specifies the wait time for a 4 byte blank check,
1604 * num_bytes is divided by 4 and then multiplied to calculate the wait time for the entire operation*/
1605
1606 /* Configure the timeout value. */
1607 uint32_t wait_count = (p_ctrl->timeout_blank_check * ((num_bytes >> 2) + 1));
1608
1609 /* Wait for the operation to complete or timeout. If timeout stop the module and return error. */
1610
1611 /* Read FRDY bit until it has been set to 1 indicating that the current
1612 * operation is complete. */
1613 while (1U != R_FACI_HP->FSTATR_b.FRDY)
1614 {
1615 /* Wait until FRDY is 1 unless timeout occurs. */
1616 if (wait_count == 0U)
1617 {
1618 err = FSP_ERR_TIMEOUT;
1619 break;
1620 }
1621
1622 wait_count--;
1623 }
1624
1625 /* Check the status of the Blank Check operation. */
1626 err = flash_hp_check_errors(err, 0, FSP_ERR_BLANK_CHECK_FAILED);
1627
1628 /* Set the result to blank or not blank. */
1629 if (R_FACI_HP->FBCSTAT == 0x01U)
1630 {
1631 *p_blank_check_result = FLASH_RESULT_NOT_BLANK;
1632 }
1633 else
1634 {
1635 *p_blank_check_result = FLASH_RESULT_BLANK;
1636 }
1637
1638 /* Return to read mode*/
1639 fsp_err_t pe_exit_err = flash_hp_pe_mode_exit();
1640
1641 if (FSP_SUCCESS == err)
1642 {
1643 err = pe_exit_err;
1644 }
1645
1646 /* Return status. */
1647 return err;
1648 }
1649
1650 #endif
1651
1652 /*******************************************************************************************************************//**
1653 * This function will initialize the FCU and set the FCU Clock based on the current FCLK frequency.
1654 * @param p_ctrl Pointer to the instance control block
1655 * @retval FSP_SUCCESS Clock and timeouts configured succesfully.
1656 * @retval FSP_ERR_FCLK FCLK is not within the acceptable range.
1657 **********************************************************************************************************************/
flash_hp_init(flash_hp_instance_ctrl_t * p_ctrl)1658 static fsp_err_t flash_hp_init (flash_hp_instance_ctrl_t * p_ctrl)
1659 {
1660 p_ctrl->current_operation = FLASH_OPERATION_NON_BGO;
1661
1662 /*Allow Access to the Flash registers*/
1663 R_SYSTEM->FWEPROR = 0x01U;
1664
1665 uint32_t flash_clock_freq_hz = R_FSP_SystemClockHzGet(FSP_PRIV_CLOCK_FCLK);
1666 uint32_t system_clock_freq_hz = R_FSP_SystemClockHzGet(FSP_PRIV_CLOCK_ICLK);
1667
1668 FSP_ERROR_RETURN(flash_clock_freq_hz >= FLASH_HP_MINIMUM_SUPPORTED_FCLK_FREQ, FSP_ERR_FCLK);
1669
1670 /* Round up the frequency to a whole number */
1671 uint32_t flash_clock_freq_mhz = (flash_clock_freq_hz + (FLASH_HP_FREQUENCY_IN_HZ - 1)) /
1672 FLASH_HP_FREQUENCY_IN_HZ;
1673
1674 /* Round up the frequency to a whole number */
1675 uint32_t system_clock_freq_mhz = (system_clock_freq_hz + (FLASH_HP_FREQUENCY_IN_HZ - 1)) /
1676 FLASH_HP_FREQUENCY_IN_HZ;
1677
1678 /* Set the Clock */
1679 R_FACI_HP->FPCKAR = (uint16_t) (FLASH_HP_FPCKAR_KEY + flash_clock_freq_mhz);
1680
1681 /* According to HW Manual the Max Programming Time for 256 bytes (ROM)
1682 * is 15.8ms. This is with a FCLK of 4MHz. The calculation below
1683 * calculates the number of ICLK ticks needed for the timeout delay.
1684 */
1685 p_ctrl->timeout_write_cf = (uint32_t) (FLASH_HP_MAX_WRITE_CF_US * system_clock_freq_mhz) /
1686 R_FLASH_HP_CYCLES_MINIMUM_PER_TIMEOUT_LOOP;
1687
1688 /* According to HW Manual the Max Programming Time for 4 bytes
1689 * (Data Flash) is 3.8ms. This is with a FCLK of 4MHz. The calculation
1690 * below calculates the number of ICLK ticks needed for the timeout delay.
1691 */
1692 p_ctrl->timeout_write_df = (uint32_t) (FLASH_HP_MAX_WRITE_DF_US * system_clock_freq_mhz) /
1693 R_FLASH_HP_CYCLES_MINIMUM_PER_TIMEOUT_LOOP;
1694
1695 /* According to HW Manual the Data Buffer Full time for 2 bytes
1696 * is 2 usec. This is with a FCLK of 4MHz. The calculation
1697 * below calculates the number of ICLK ticks needed for the timeout delay.
1698 */
1699 p_ctrl->timeout_dbfull = (uint32_t) (FLASH_HP_MAX_DBFULL_US * system_clock_freq_mhz) /
1700 R_FLASH_HP_CYCLES_MINIMUM_PER_TIMEOUT_LOOP;
1701
1702 /* According to HW Manual the Max Blank Check time for 4 bytes
1703 * (Data Flash) is 84 usec. This is with a FCLK of 4MHz. The calculation
1704 * below calculates the number of ICLK ticks needed for the timeout delay.
1705 */
1706 p_ctrl->timeout_blank_check = (uint32_t) (FLASH_HP_MAX_BLANK_CHECK_US * system_clock_freq_mhz) /
1707 R_FLASH_HP_CYCLES_MINIMUM_PER_TIMEOUT_LOOP;
1708
1709 /* According to HW Manual the max timeout value when using the configuration set
1710 * command is 307 ms. This is with a FCLK of 4MHz. The
1711 * calculation below calculates the number of ICLK ticks needed for the
1712 * timeout delay.
1713 */
1714 p_ctrl->timeout_write_config = (uint32_t) (FLASH_HP_MAX_WRITE_CONFIG_US * system_clock_freq_mhz) /
1715 R_FLASH_HP_CYCLES_MINIMUM_PER_TIMEOUT_LOOP;
1716
1717 /* According to HW Manual the Max Erasure Time for a 64 byte Data Flash block is
1718 * around 18ms. This is with a FCLK of 4MHz. The calculation below
1719 * calculates the number of ICLK ticks needed for the timeout delay.
1720 */
1721 p_ctrl->timeout_erase_df_block = (uint32_t) (FLASH_HP_MAX_ERASE_DF_BLOCK_US * system_clock_freq_mhz) /
1722 R_FLASH_HP_CYCLES_MINIMUM_PER_TIMEOUT_LOOP;
1723
1724 /* According to HW Manual the Max Erasure Time for a 32KB block is
1725 * around 1040ms. This is with a FCLK of 4MHz. The calculation below
1726 * calculates the number of ICLK ticks needed for the timeout delay.
1727 */
1728 p_ctrl->timeout_erase_cf_large_block =
1729 (uint32_t) (FLASH_HP_MAX_ERASE_CF_LARGE_BLOCK_US * system_clock_freq_mhz) /
1730 R_FLASH_HP_CYCLES_MINIMUM_PER_TIMEOUT_LOOP;
1731
1732 /* According to HW Manual the Max Erasure Time for a 8KB block is
1733 * around 260ms. This is with a FCLK of 4MHz. The calculation below
1734 * calculates the number of ICLK ticks needed for the timeout delay.
1735 */
1736 p_ctrl->timeout_erase_cf_small_block =
1737 (uint32_t) (FLASH_HP_MAX_ERASE_CF_SMALL_BLOCK_US * system_clock_freq_mhz) /
1738 R_FLASH_HP_CYCLES_MINIMUM_PER_TIMEOUT_LOOP;
1739
1740 return FSP_SUCCESS;
1741 }
1742
1743 /*******************************************************************************************************************//**
1744 * Erase the block at the start address in the control block.
1745 *
1746 * @param p_ctrl Pointer to the instance control block
1747 * @param[in] block_size The block size
1748 * @param[in] timeout The timeout for the block erase
1749 *
1750 * @retval FSP_SUCCESS The erase completed successfully.
1751 * @retval FSP_ERR_TIMEOUT The erase operation timed out.
1752 **********************************************************************************************************************/
flash_hp_erase_block(flash_hp_instance_ctrl_t * const p_ctrl,uint32_t block_size,uint32_t timeout)1753 static fsp_err_t flash_hp_erase_block (flash_hp_instance_ctrl_t * const p_ctrl, uint32_t block_size, uint32_t timeout)
1754 {
1755 /* Set block start address*/
1756 R_FACI_HP->FSADDR = p_ctrl->source_start_address;
1757
1758 /* Issue two part Block Erase commands */
1759 R_FACI_HP_CMD->FACI_CMD8 = FLASH_HP_FACI_CMD_BLOCK_ERASE;
1760 R_FACI_HP_CMD->FACI_CMD8 = FLASH_HP_FACI_CMD_FINAL;
1761
1762 p_ctrl->source_start_address += block_size;
1763
1764 p_ctrl->operations_remaining--;
1765
1766 /* Wait until the operation has completed or timeout. If timeout stop the flash and return error. */
1767
1768 /* Read FRDY bit until it has been set to 1 indicating that the current
1769 * operation is complete.*/
1770 if (timeout)
1771 {
1772 while (1U != R_FACI_HP->FSTATR_b.FRDY)
1773 {
1774 /* Wait until FRDY is 1 unless timeout occurs. */
1775 if (timeout == 0U)
1776 {
1777 return FSP_ERR_TIMEOUT;
1778 }
1779
1780 timeout--;
1781 }
1782 }
1783
1784 return FSP_SUCCESS;
1785 }
1786
1787 #if (FLASH_HP_CFG_CODE_FLASH_PROGRAMMING_ENABLE == 1)
1788
1789 /*******************************************************************************************************************//**
1790 * This function erases a specified number of Code Flash blocks
1791 *
1792 * @param p_ctrl Pointer to the control block
1793 * @param[in] block_address The starting address of the first block to erase.
1794 * @param[in] num_blocks The number of blocks to erase.
1795 *
1796 * @retval FSP_SUCCESS Successfully erased (non-BGO) mode or operation successfully started (BGO).
1797 * @retval FSP_ERR_ERASE_FAILED Status is indicating a Erase error.
1798 * @retval FSP_ERR_CMD_LOCKED FCU is in locked state, typically as a result of attempting to Write or Erase an
1799 * area that is protected by an Access Window.
1800 * @retval FSP_ERR_TIMEOUT Timed out waiting for the FCU to become ready.
1801 * @retval FSP_ERR_PE_FAILURE Failed to enter or exit Code Flash P/E mode.
1802 **********************************************************************************************************************/
flash_hp_cf_erase(flash_hp_instance_ctrl_t * p_ctrl,uint32_t block_address,uint32_t num_blocks)1803 static fsp_err_t flash_hp_cf_erase (flash_hp_instance_ctrl_t * p_ctrl, uint32_t block_address, uint32_t num_blocks)
1804 {
1805 fsp_err_t err = FSP_SUCCESS;
1806
1807 /* Set current operation parameters */
1808 p_ctrl->source_start_address = block_address;
1809 p_ctrl->operations_remaining = num_blocks;
1810 uint32_t wait_count;
1811 uint32_t block_size;
1812
1813 err = flash_hp_enter_pe_cf_mode(p_ctrl);
1814 FSP_ERROR_RETURN(FSP_SUCCESS == err, err);
1815
1816 /* Set Erasure Priority Mode*/
1817 R_FACI_HP->FCPSR = 1U;
1818
1819 while (p_ctrl->operations_remaining && (FSP_SUCCESS == err))
1820 {
1821 if ((p_ctrl->source_start_address & FLASH_HP_PRV_BANK1_MASK) < BSP_FEATURE_FLASH_HP_CF_REGION0_SIZE)
1822 {
1823 wait_count = p_ctrl->timeout_erase_cf_small_block;
1824 block_size = BSP_FEATURE_FLASH_HP_CF_REGION0_BLOCK_SIZE;
1825 }
1826 else
1827 {
1828 wait_count = p_ctrl->timeout_erase_cf_large_block;
1829 block_size = BSP_FEATURE_FLASH_HP_CF_REGION1_BLOCK_SIZE;
1830 }
1831
1832 err = flash_hp_erase_block(p_ctrl, block_size, wait_count);
1833
1834 /* Check the status of the erase operation. */
1835 err = flash_hp_check_errors(err, FLASH_HP_FSTATR_ERSERR | FLASH_HP_FSTATR_ILGLERR, FSP_ERR_ERASE_FAILED);
1836 }
1837
1838 /* Return to read mode*/
1839 fsp_err_t pe_exit_err = flash_hp_pe_mode_exit();
1840
1841 if (FSP_SUCCESS == err)
1842 {
1843 err = pe_exit_err;
1844 }
1845
1846 return err;
1847 }
1848
1849 #endif
1850
1851 #if (FLASH_HP_CFG_DATA_FLASH_PROGRAMMING_ENABLE == 1)
1852
1853 /*******************************************************************************************************************//**
1854 * This function erases a specified number of Code or Data Flash blocks
1855 *
1856 * @param p_ctrl Pointer to the control block
1857 * @param[in] block_address The starting address of the first block to erase.
1858 * @param[in] num_blocks The number of blocks to erase.
1859 *
1860 * @retval FSP_SUCCESS Successfully erased (non-BGO) mode or operation successfully started (BGO).
1861 * @retval FSP_ERR_ERASE_FAILED Status is indicating a Erase error.
1862 * @retval FSP_ERR_CMD_LOCKED FCU is in locked state, typically as a result of attempting to Write or Erase an
1863 * area that is protected by an Access Window.
1864 * @retval FSP_ERR_TIMEOUT Timed out waiting for the FCU to become ready.
1865 * @retval FSP_ERR_PE_FAILURE Failed to enter or exit P/E mode.
1866 **********************************************************************************************************************/
flash_hp_df_erase(flash_hp_instance_ctrl_t * p_ctrl,uint32_t block_address,uint32_t num_blocks)1867 static fsp_err_t flash_hp_df_erase (flash_hp_instance_ctrl_t * p_ctrl, uint32_t block_address, uint32_t num_blocks)
1868 {
1869 fsp_err_t err = FSP_SUCCESS;
1870
1871 /* Set current operation parameters */
1872 p_ctrl->source_start_address = block_address;
1873 p_ctrl->operations_remaining = num_blocks;
1874 uint32_t wait_count;
1875
1876 err = flash_hp_enter_pe_df_mode(p_ctrl);
1877 FSP_ERROR_RETURN(FSP_SUCCESS == err, FSP_ERR_PE_FAILURE);
1878
1879 /* If in BGO mode, exit here; remaining processing if any will be done in ISR */
1880 if (p_ctrl->p_cfg->data_flash_bgo)
1881 {
1882 p_ctrl->current_operation = FLASH_OPERATION_DF_BGO_ERASE;
1883 wait_count = 0;
1884 }
1885 else
1886 {
1887 wait_count = p_ctrl->timeout_write_df;
1888 }
1889
1890 /* Set Erasure Priority Mode*/
1891 R_FACI_HP->FCPSR = 1U;
1892
1893 do
1894 {
1895 err = flash_hp_erase_block(p_ctrl, BSP_FEATURE_FLASH_HP_DF_BLOCK_SIZE, wait_count);
1896
1897 if (p_ctrl->p_cfg->data_flash_bgo)
1898 {
1899 return err;
1900 }
1901
1902 err = flash_hp_check_errors(err, FLASH_HP_FSTATR_ERSERR, FSP_ERR_ERASE_FAILED);
1903 } while (p_ctrl->operations_remaining && (err == FSP_SUCCESS));
1904
1905 /* Return to read mode*/
1906 fsp_err_t pe_exit_err = flash_hp_pe_mode_exit();
1907
1908 if (FSP_SUCCESS == err)
1909 {
1910 err = pe_exit_err;
1911 }
1912
1913 return err;
1914 }
1915
1916 #endif
1917
1918 /*******************************************************************************************************************//**
1919 * This function switches the peripheral from P/E mode for Code Flash or Data Flash to Read mode.
1920 *
1921 * @retval FSP_SUCCESS Successfully entered P/E mode.
1922 * @retval FSP_ERR_PE_FAILURE Failed to exited P/E mode
1923 * @retval FSP_ERR_CMD_LOCKED Flash entered command locked state.
1924 **********************************************************************************************************************/
flash_hp_pe_mode_exit(void)1925 static fsp_err_t flash_hp_pe_mode_exit (void)
1926 {
1927 /* See "Transition to Read Mode": Section 47.9.3.5 of the RA6M4 manual R01UH0890EJ0100. */
1928 /* FRDY and CMDLK are checked after the previous commands complete and do not need to be checked again. */
1929 fsp_err_t err = FSP_SUCCESS;
1930 fsp_err_t temp_err = FSP_SUCCESS;
1931 uint32_t pe_mode = R_FACI_HP->FENTRYR;
1932
1933 uint32_t wait_count = FLASH_HP_FRDY_CMD_TIMEOUT;
1934
1935 /* Transition to Read mode */
1936 R_FACI_HP->FENTRYR = FLASH_HP_FENTRYR_READ_MODE;
1937
1938 /* Wait until the flash is in read mode or timeout. If timeout return error. */
1939 /* Read FENTRYR until it has been set to 0x0000 indicating that we have successfully exited P/E mode.*/
1940 while (0U != R_FACI_HP->FENTRYR)
1941 {
1942 /* Wait until FENTRYR is 0x0000 unless timeout occurs. */
1943 if (wait_count == 0U)
1944 {
1945 /* If FENTRYR is not set after max timeout, FSP_ERR_PE_FAILURE*/
1946 err = FSP_ERR_PE_FAILURE;
1947 }
1948
1949 wait_count--;
1950 }
1951
1952 /* If the device is coming out of code flash p/e mode restore the flash cache state. */
1953 if (FLASH_HP_FENTRYR_CF_PE_MODE == pe_mode)
1954 {
1955 #if BSP_FEATURE_FLASH_HP_HAS_FMEPROT
1956 R_FACI_HP->FMEPROT = FLASH_HP_FMEPROT_LOCK;
1957 #endif
1958
1959 R_BSP_FlashCacheEnable();
1960 }
1961
1962 #if BSP_FEATURE_BSP_HAS_CODE_SYSTEM_CACHE
1963 else if (FLASH_HP_FENTRYR_DF_PE_MODE == pe_mode)
1964 {
1965 /* Flush the C-CACHE. */
1966 R_CACHE->CCAFCT = 1U;
1967 FSP_HARDWARE_REGISTER_WAIT(R_CACHE->CCAFCT, 0U);
1968 }
1969 else
1970 {
1971 /* Do nothing. */
1972 }
1973 #endif
1974
1975 /* If a command locked state was detected earlier, then return that error. */
1976 if (FSP_ERR_CMD_LOCKED == temp_err)
1977 {
1978 err = temp_err;
1979 }
1980
1981 return err;
1982 }
1983
1984 /*******************************************************************************************************************//**
1985 * This function resets the Flash peripheral.
1986 * @param[in] p_ctrl Pointer to the Flash HP instance control block.
1987 * @retval FSP_SUCCESS Reset completed
1988 * @retval FSP_ERR_PE_FAILURE Failed to enter or exit P/E mode.
1989 * @retval FSP_ERR_TIMEOUT Timed out waiting for the FCU to become ready.
1990 * @retval FSP_ERR_CMD_LOCKED FCU is in locked state, typically as a result of having received an illegal command.
1991 **********************************************************************************************************************/
flash_hp_reset(flash_hp_instance_ctrl_t * p_ctrl)1992 static fsp_err_t flash_hp_reset (flash_hp_instance_ctrl_t * p_ctrl)
1993 {
1994 /* Disable the FACI interrupts, we don't want the reset itself to generate an interrupt */
1995 if (p_ctrl->p_cfg->data_flash_bgo)
1996 {
1997 R_BSP_IrqDisable(p_ctrl->p_cfg->irq);
1998 R_BSP_IrqDisable(p_ctrl->p_cfg->err_irq);
1999 }
2000
2001 /* If not in PE mode enter PE mode. */
2002 if (R_FACI_HP->FENTRYR == 0x0000U)
2003 {
2004 /* Enter P/E mode so that we can execute some FACI commands. Either Code or Data Flash P/E mode would work
2005 * but Code Flash P/E mode requires FLASH_HP_CFG_CODE_FLASH_PROGRAMMING_ENABLE == 1, which may not be true */
2006 flash_hp_enter_pe_df_mode(p_ctrl);
2007 }
2008
2009 /* Issue a Flash Stop to stop any ongoing operation*/
2010 fsp_err_t err = flash_hp_stop();
2011
2012 /* Issue a status clear to clear the locked-command state*/
2013 fsp_err_t temp_err = flash_hp_status_clear();
2014
2015 /* Keep track of and return the first error encountered. */
2016 if (FSP_SUCCESS == err)
2017 {
2018 err = temp_err;
2019 }
2020
2021 /* Transition back to Read mode*/
2022 temp_err = flash_hp_pe_mode_exit();
2023
2024 if (FSP_SUCCESS == err)
2025 {
2026 err = temp_err;
2027 }
2028
2029 /* Cancel any in progress background operation. */
2030 p_ctrl->current_operation = FLASH_OPERATION_NON_BGO;
2031
2032 return err;
2033 }
2034
2035 /*******************************************************************************************************************//**
2036 * This function is used to force stop the flash during an ongoing operation.
2037 *
2038 * @retval FSP_SUCCESS Successful stop.
2039 * @retval FSP_ERR_TIMEOUT Timeout executing flash_stop.
2040 * @retval FSP_ERR_CMD_LOCKED Peripheral in command locked state.
2041 **********************************************************************************************************************/
flash_hp_stop(void)2042 static fsp_err_t flash_hp_stop (void)
2043 {
2044 /* See "Forced Stop Command": Section 47.9.3.13 of the RA6M4 manual R01UH0890EJ0100. If the CMDLK bit
2045 * is still set after issuing the force stop command return an error. */
2046 volatile uint32_t wait_count = FLASH_HP_FRDY_CMD_TIMEOUT;
2047
2048 R_FACI_HP_CMD->FACI_CMD8 = (uint8_t) FLASH_HP_FACI_CMD_FORCED_STOP;
2049
2050 while (1U != R_FACI_HP->FSTATR_b.FRDY)
2051 {
2052 if (wait_count == 0U)
2053 {
2054 return FSP_ERR_TIMEOUT;
2055 }
2056
2057 wait_count--;
2058 }
2059
2060 if (0U != R_FACI_HP->FASTAT_b.CMDLK)
2061 {
2062 return FSP_ERR_CMD_LOCKED;
2063 }
2064
2065 return FSP_SUCCESS;
2066 }
2067
2068 /*******************************************************************************************************************//**
2069 * This function is used to clear the command-locked state .
2070 * @retval FSP_SUCCESS Successful stop.
2071 * @retval FSP_ERR_TIMEOUT Timeout executing flash_stop.Failed to exited P/E mode
2072 * @retval FSP_ERR_CMD_LOCKED Peripheral in command locked state
2073 **********************************************************************************************************************/
flash_hp_status_clear(void)2074 static fsp_err_t flash_hp_status_clear (void)
2075 {
2076 /* See "Status Clear Command": Section 47.9.3.12 of the RA6M4 manual R01UH0890EJ0100. */
2077 /* Timeout counter. */
2078 volatile uint32_t wait_count = FLASH_HP_FRDY_CMD_TIMEOUT;
2079
2080 /*Issue stop command to flash command area*/
2081 R_FACI_HP_CMD->FACI_CMD8 = (uint8_t) FLASH_HP_FACI_CMD_STATUS_CLEAR;
2082
2083 /* Read FRDY bit until it has been set to 1 indicating that the current
2084 * operation is complete.*/
2085 while (1U != R_FACI_HP->FSTATR_b.FRDY)
2086 {
2087 /* Wait until FRDY is 1 unless timeout occurs. */
2088 if (wait_count == 0U)
2089 {
2090
2091 /* This should not happen normally.
2092 * FRDY should get set in 15-20 ICLK cycles on STOP command*/
2093 return FSP_ERR_TIMEOUT;
2094 }
2095
2096 wait_count--;
2097 }
2098
2099 /*Check that Command Lock bit is cleared*/
2100 if (0U != R_FACI_HP->FASTAT_b.CMDLK)
2101 {
2102 return FSP_ERR_CMD_LOCKED;
2103 }
2104
2105 return FSP_SUCCESS;
2106 }
2107
2108 #if (FLASH_HP_CFG_CODE_FLASH_PROGRAMMING_ENABLE == 1)
2109
2110 /*******************************************************************************************************************//**
2111 * Set up the g_configuration_area_data for writing to the access/startup region of option setting memory.
2112 *
2113 * @param[in] btflg_swap The btflg swap
2114 * @param[in] start_addr The access window start address
2115 * @param[in] end_addr The access window end address
2116 **********************************************************************************************************************/
flash_hp_configuration_area_data_setup(uint32_t btflg_swap,uint32_t start_addr,uint32_t end_addr)2117 static void flash_hp_configuration_area_data_setup (uint32_t btflg_swap, uint32_t start_addr, uint32_t end_addr)
2118 {
2119 /* Unused bits should be written as 1. */
2120 g_configuration_area_data[0] = UINT16_MAX;
2121 g_configuration_area_data[1] = UINT16_MAX;
2122
2123 /* Prepare the configuration data. */
2124
2125 /* Bit 15 is BTFLG(Startup Area Select Flag) */
2126 /* Bits 10:0 are FAWE(Flash Access Window End Block). */
2127 /* Unused bits should be written as 1. */
2128 g_configuration_area_data[FLASH_HP_FCU_CONFIG_SET_FAWE_BTFLG_OFFSET] =
2129 (uint16_t) (FLASH_HP_FCU_CONFIG_FAWE_BTFLG_UNUSED_BITS | end_addr | (btflg_swap << 15U));
2130
2131 /* Bits 10:0 are FAWS(Flash Access Window Start Block). */
2132 /* Unused bits should be written as 1. */
2133 g_configuration_area_data[FLASH_HP_FCU_CONFIG_SET_FAWS_OFFSET] =
2134 (uint16_t) (FLASH_HP_FCU_CONFIG_FAWS_UNUSED_BITS | start_addr);
2135
2136 g_configuration_area_data[4] = UINT16_MAX;
2137 g_configuration_area_data[5] = UINT16_MAX;
2138 g_configuration_area_data[6] = UINT16_MAX;
2139 g_configuration_area_data[7] = UINT16_MAX;
2140 }
2141
2142 #endif
2143
2144 #if (FLASH_HP_CFG_CODE_FLASH_PROGRAMMING_ENABLE == 1)
2145
2146 /*******************************************************************************************************************//**
2147 * Configure an access window for the Code Flash memory using the provided start and end address. An access window
2148 * defines a contiguous area in Code Flash for which programming/erase is enabled. This area is on block boundaries. The
2149 * block containing start_addr is the first block. The block containing end_addr is the last block. The access window
2150 * then becomes first block - last block inclusive. Anything outside this range of Code Flash is then write protected.
2151 * This command DOES modify the configuration via The Configuration Set command to update the FAWS and FAWE.
2152 *
2153 * @param p_ctrl Pointer to the control block
2154 * @param[in] start_addr Determines the Starting block for the Code Flash access window.
2155 * @param[in] end_addr Determines the Ending block for the Code Flash access window.
2156 *
2157 * @retval FSP_SUCCESS Access window successfully configured.
2158 * @retval FSP_ERR_CMD_LOCKED FCU is in locked state, typically as a result of having received an illegal
2159 * command.
2160 * @retval FSP_ERR_WRITE_FAILED Status is indicating a Programming error for the requested operation.
2161 * @retval FSP_ERR_TIMEOUT Timed out waiting for the FCU to become ready.
2162 * @retval FSP_ERR_PE_FAILURE Failed to enter or exit Code Flash P/E mode.
2163 **********************************************************************************************************************/
flash_hp_access_window_set(flash_hp_instance_ctrl_t * p_ctrl,uint32_t const start_addr,uint32_t const end_addr)2164 static fsp_err_t flash_hp_access_window_set (flash_hp_instance_ctrl_t * p_ctrl,
2165 uint32_t const start_addr,
2166 uint32_t const end_addr)
2167 {
2168 uint32_t btflg = R_FACI_HP->FAWMON_b.BTFLG;
2169
2170 /* Update Flash state and enter Code Flash P/E mode */
2171 fsp_err_t err = flash_hp_enter_pe_cf_mode(p_ctrl);
2172 FSP_ERROR_RETURN(FSP_SUCCESS == err, err);
2173
2174 /* Configure the configuration area to be written. */
2175 flash_hp_configuration_area_data_setup(btflg, start_addr >> 13U, end_addr >> 13U);
2176
2177 /* Write the configuration area to the access/startup region. */
2178 err = flash_hp_configuration_area_write(p_ctrl, FLASH_HP_FCU_CONFIG_SET_ACCESS_STARTUP);
2179
2180 err = flash_hp_check_errors(err, 0, FSP_ERR_WRITE_FAILED);
2181
2182 /* Return to read mode*/
2183 fsp_err_t pe_exit_err = flash_hp_pe_mode_exit();
2184
2185 if (FSP_SUCCESS == err)
2186 {
2187 err = pe_exit_err;
2188 }
2189
2190 return err;
2191 }
2192
2193 #endif
2194
2195 #if (FLASH_HP_CFG_CODE_FLASH_PROGRAMMING_ENABLE == 1)
2196
2197 /*******************************************************************************************************************//**
2198 * Modifies the start-up program swap flag (BTFLG) based on the supplied parameters. These changes will take effect on
2199 * the next reset. This command DOES modify the configuration via The Configuration Set command to update the BTFLG.
2200 *
2201 * @param p_ctrl Pointer to the instance control block.
2202 * @param[in] swap_type The swap type Alternate or Default.
2203 * @param[in] is_temporary Indicates if the swap should be temporary or permanent.
2204 *
2205 * @retval FSP_SUCCESS Access window successfully removed.
2206 * @retval FSP_ERR_CMD_LOCKED FCU is in locked state, typically as a result of having received an illegal
2207 * command.
2208 * @retval FSP_ERR_WRITE_FAILED Status is indicating a Programming error for the requested operation.
2209 * @retval FSP_ERR_TIMEOUT Timed out waiting for the FCU to become ready.
2210 * @retval FSP_ERR_PE_FAILURE Failed to enter or exit Code Flash P/E mode.
2211 **********************************************************************************************************************/
flash_hp_set_startup_area_boot(flash_hp_instance_ctrl_t * p_ctrl,flash_startup_area_swap_t swap_type,bool is_temporary)2212 static fsp_err_t flash_hp_set_startup_area_boot (flash_hp_instance_ctrl_t * p_ctrl,
2213 flash_startup_area_swap_t swap_type,
2214 bool is_temporary)
2215 {
2216 /* Update Flash state and enter Code Flash P/E mode */
2217 fsp_err_t err = flash_hp_enter_pe_cf_mode(p_ctrl);
2218 FSP_ERROR_RETURN(FSP_SUCCESS == err, err);
2219
2220 if (is_temporary)
2221 {
2222 R_FACI_HP->FSUACR = (uint16_t) (FLASH_HP_FSUACR_KEY | swap_type);
2223 }
2224 else
2225 {
2226 #if BSP_FEATURE_FLASH_SUPPORTS_ACCESS_WINDOW
2227
2228 /* Do not call functions with multiple volatile parameters. */
2229 uint32_t faws = R_FACI_HP->FAWMON_b.FAWS;
2230 uint32_t fawe = R_FACI_HP->FAWMON_b.FAWE;
2231
2232 /* Configure the configuration area to be written. */
2233 flash_hp_configuration_area_data_setup(~swap_type & 0x1, faws, fawe);
2234 #else
2235 memset(g_configuration_area_data, UINT8_MAX, sizeof(g_configuration_area_data));
2236
2237 g_configuration_area_data[FLASH_HP_FCU_CONFIG_SET_FAWE_BTFLG_OFFSET] =
2238 (uint16_t) (((((uint16_t) ~swap_type) & 0x1U) << 15U) | FLASH_HP_OFS_SAS_MASK);
2239 #endif
2240
2241 /* Write the configuration area to the access/startup region. */
2242 err = flash_hp_configuration_area_write(p_ctrl, FLASH_HP_FCU_CONFIG_SET_ACCESS_STARTUP);
2243
2244 err = flash_hp_check_errors(err, 0, FSP_ERR_WRITE_FAILED);
2245 }
2246
2247 /* Return to read mode*/
2248 fsp_err_t pe_exit_err = flash_hp_pe_mode_exit();
2249
2250 if (FSP_SUCCESS == err)
2251 {
2252 err = pe_exit_err;
2253 }
2254
2255 return err;
2256 }
2257
2258 #endif
2259
2260 #if (FLASH_HP_CFG_CODE_FLASH_PROGRAMMING_ENABLE == 1)
2261
2262 /*******************************************************************************************************************//**
2263 * Set the ID code.
2264 *
2265 * @param p_ctrl Pointer to the control block
2266 * @param p_id_code The identifier code
2267 * @param[in] mode ID code mode
2268 *
2269 * @retval FSP_SUCCESS Set Configuration successful
2270 * @retval FSP_ERR_PE_FAILURE Failed to enter or exit Code Flash P/E mode.
2271 * @retval FSP_ERR_TIMEOUT Timed out waiting for the FCU to become ready.
2272 * @retval FSP_ERR_WRITE_FAILED Status is indicating a Programming error for the requested operation.
2273 * @retval FSP_ERR_CMD_LOCKED FCU is in locked state, typically as a result of having received an illegal
2274 * command.
2275 **********************************************************************************************************************/
flash_hp_set_id_code(flash_hp_instance_ctrl_t * p_ctrl,uint8_t const * const p_id_code,flash_id_code_mode_t mode)2276 static fsp_err_t flash_hp_set_id_code (flash_hp_instance_ctrl_t * p_ctrl,
2277 uint8_t const * const p_id_code,
2278 flash_id_code_mode_t mode)
2279 {
2280 uint32_t * temp = (uint32_t *) p_id_code;
2281 uint32_t * temp_area = (uint32_t *) g_configuration_area_data;
2282
2283 /* Update Flash state and enter the required P/E mode specified by the hardware manual. */
2284 fsp_err_t err = flash_hp_enter_pe_cf_mode(p_ctrl);
2285 FSP_ERROR_RETURN(FSP_SUCCESS == err, err);
2286
2287 /* Configure the configuration area to be written. If the mode is unlocked write all 0xFF. */
2288 for (uint32_t index = 0U; index < 4U; index++)
2289 {
2290 if (FLASH_ID_CODE_MODE_UNLOCKED == mode)
2291 {
2292 temp_area[index] = UINT32_MAX;
2293 }
2294 else
2295 {
2296 temp_area[index] = temp[index];
2297 }
2298 }
2299
2300 /* If the mode is not unlocked set bits 126 and 127 accordingly. */
2301 if (FLASH_ID_CODE_MODE_UNLOCKED != mode)
2302 {
2303 g_configuration_area_data[FLASH_HP_CONFIG_SET_ACCESS_WORD_CNT - 1U] |= (uint16_t) mode;
2304 }
2305
2306 /* Write the configuration area to the access/startup region. */
2307 err = flash_hp_configuration_area_write(p_ctrl, FLASH_HP_FCU_CONFIG_SET_ID_BYTE);
2308
2309 err = flash_hp_check_errors(err, 0, FSP_ERR_WRITE_FAILED);
2310
2311 /* Return to read mode*/
2312 fsp_err_t pe_exit_err = flash_hp_pe_mode_exit();
2313
2314 if (FSP_SUCCESS == err)
2315 {
2316 err = pe_exit_err;
2317 }
2318
2319 return err;
2320 }
2321
2322 #endif
2323
2324 #if (FLASH_HP_CFG_CODE_FLASH_PROGRAMMING_ENABLE == 1)
2325
2326 /*******************************************************************************************************************//**
2327 * Execute the Set Configuration sequence using the g_configuration_area_data structure set up the caller.
2328 *
2329 * @param p_ctrl Pointer to the control block
2330 * @param[in] fsaddr Flash address to be written to.
2331 *
2332 * @retval FSP_SUCCESS Set Configuration successful
2333 * @retval FSP_ERR_TIMEOUT Timed out waiting for the FCU to become ready.
2334 **********************************************************************************************************************/
flash_hp_configuration_area_write(flash_hp_instance_ctrl_t * p_ctrl,uint32_t fsaddr)2335 static fsp_err_t flash_hp_configuration_area_write (flash_hp_instance_ctrl_t * p_ctrl, uint32_t fsaddr)
2336 {
2337 volatile uint32_t timeout = p_ctrl->timeout_write_config;
2338
2339 /* See "Configuration Set Command": Section 47.9.3.15 of the RA6M4 manual R01UH0890EJ0100. */
2340 R_FACI_HP->FSADDR = fsaddr;
2341 R_FACI_HP_CMD->FACI_CMD8 = FLASH_HP_FACI_CMD_CONFIG_SET_1;
2342 R_FACI_HP_CMD->FACI_CMD8 = FLASH_HP_FACI_CMD_CONFIG_SET_2;
2343
2344 /* Write the configuration data. */
2345 for (uint32_t index = 0U; index < FLASH_HP_CONFIG_SET_ACCESS_WORD_CNT; index++)
2346 {
2347 /* There are 8 16 bit words that must be written to accomplish a configuration set */
2348 R_FACI_HP_CMD->FACI_CMD16 = g_configuration_area_data[index];
2349 }
2350
2351 R_FACI_HP_CMD->FACI_CMD8 = FLASH_HP_FACI_CMD_FINAL;
2352
2353 while (1U != R_FACI_HP->FSTATR_b.FRDY)
2354 {
2355 if (timeout <= 0U)
2356 {
2357 return FSP_ERR_TIMEOUT;
2358 }
2359
2360 timeout--;
2361 }
2362
2363 return FSP_SUCCESS;
2364 }
2365
2366 #endif
2367
2368 /** If BGO is being used then we require both interrupts to be enabled (RDY and ERR). If either one
2369 * is not enabled then don't generate any ISR routines */
2370
2371 /*******************************************************************************************************************//**
2372 * FLASH error interrupt routine.
2373 *
2374 * This function implements the FLASH error isr. The function clears the interrupt request source on entry populates the
2375 * callback structure with the FLASH_IRQ_EVENT_ERR_ECC event, and providing a callback routine has been provided, calls
2376 * the callback function with the event.
2377 **********************************************************************************************************************/
fcu_fiferr_isr(void)2378 void fcu_fiferr_isr (void)
2379 {
2380 /* Save context if RTOS is used */
2381 FSP_CONTEXT_SAVE
2382 flash_event_t event;
2383 IRQn_Type irq = R_FSP_CurrentIrqGet();
2384
2385 flash_hp_instance_ctrl_t * p_ctrl = (flash_hp_instance_ctrl_t *) R_FSP_IsrContextGet(irq);
2386
2387 uint32_t fastat = R_FACI_HP->FASTAT;
2388 uint32_t fstatr_errors = R_FACI_HP->FSTATR & FLASH_HP_FSTATR_ERROR_MASK;
2389
2390 /* The flash access error interrupt register has fired. */
2391 /* Check for the data flash memory access violation flag. */
2392 if (fastat & FLASH_HP_FASTAT_DFAE)
2393 {
2394 event = FLASH_EVENT_ERR_DF_ACCESS;
2395 }
2396 /* Check for the code flash memory access violation flag. */
2397 else if (fastat & FLASH_HP_FASTAT_CFAE)
2398 {
2399 event = FLASH_EVENT_ERR_CF_ACCESS;
2400 }
2401 /* Check if the command Lock bit is set. */
2402 else if (fastat & FLASH_HP_FASTAT_CMDLK)
2403 {
2404 if (fstatr_errors & (FLASH_HP_FSTATR_PRGERR | FLASH_HP_FSTATR_ERSERR))
2405 {
2406 event = FLASH_EVENT_ERR_FAILURE;
2407 }
2408 else
2409 {
2410 event = FLASH_EVENT_ERR_CMD_LOCKED;
2411 }
2412 }
2413 else
2414 {
2415 event = FLASH_EVENT_ERR_FAILURE;
2416 }
2417
2418 /* Reset the FCU: This will stop any existing processes and exit PE mode*/
2419 flash_hp_reset(p_ctrl);
2420
2421 /* Clear the Error Interrupt. */
2422 R_BSP_IrqStatusClear(irq);
2423
2424 /* Call the user callback. */
2425 r_flash_hp_call_callback(p_ctrl, event);
2426
2427 /* Restore context if RTOS is used */
2428 FSP_CONTEXT_RESTORE
2429 }
2430
2431 /*******************************************************************************************************************//**
2432 * FLASH ready interrupt routine.
2433 *
2434 * This function implements the FLASH ready isr. The function clears the interrupt request source on entry populates the
2435 * callback structure with the relevant event, and providing a callback routine has been provided, calls the callback
2436 * function with the event.
2437 **********************************************************************************************************************/
fcu_frdyi_isr(void)2438 void fcu_frdyi_isr (void)
2439 {
2440 FSP_CONTEXT_SAVE
2441 bool operation_completed = false;
2442
2443 /*Wait counter used for DBFULL flag*/
2444 flash_event_t event;
2445
2446 IRQn_Type irq = R_FSP_CurrentIrqGet();
2447
2448 flash_hp_instance_ctrl_t * p_ctrl = (flash_hp_instance_ctrl_t *) R_FSP_IsrContextGet(irq);
2449
2450 /* Clear the Interrupt Request*/
2451 R_BSP_IrqStatusClear(irq);
2452
2453 /* A reset of the FACI with a BGO operation in progress may still generate a single interrupt
2454 * subsequent to the reset. We want to ignore that */
2455
2456 /* Continue the current operation. If unknown operation set callback event to failure. */
2457 if (FLASH_OPERATION_DF_BGO_WRITE == p_ctrl->current_operation)
2458 {
2459 /* If there are still bytes to write */
2460 if (p_ctrl->operations_remaining)
2461 {
2462 fsp_err_t err = flash_hp_write_data(p_ctrl, BSP_FEATURE_FLASH_HP_DF_WRITE_SIZE, 0);
2463
2464 if (FSP_SUCCESS != err)
2465 {
2466 flash_hp_reset(p_ctrl);
2467 event = FLASH_EVENT_ERR_FAILURE;
2468 }
2469 }
2470 /*Done writing all bytes*/
2471 else
2472 {
2473 event = FLASH_EVENT_WRITE_COMPLETE;
2474 operation_completed = true;
2475 }
2476 }
2477 else if ((FLASH_OPERATION_DF_BGO_ERASE == p_ctrl->current_operation))
2478 {
2479 if (p_ctrl->operations_remaining)
2480 {
2481 flash_hp_erase_block(p_ctrl, BSP_FEATURE_FLASH_HP_DF_BLOCK_SIZE, 0);
2482 }
2483 /* If all blocks are erased*/
2484 else
2485 {
2486 event = FLASH_EVENT_ERASE_COMPLETE;
2487 operation_completed = true;
2488 }
2489 }
2490 else
2491 {
2492 /* Blank check is a single operation */
2493 operation_completed = true;
2494 if (R_FACI_HP->FBCSTAT == 0x01U)
2495 {
2496 event = FLASH_EVENT_NOT_BLANK;
2497 }
2498 else
2499 {
2500 event = FLASH_EVENT_BLANK;
2501 }
2502 }
2503
2504 /* If the current operation has completed exit pe mode, release the software lock and call the user callback if used. */
2505 if (operation_completed == true)
2506 {
2507 /* finished current operation. Exit P/E mode*/
2508 flash_hp_pe_mode_exit();
2509
2510 /* Release lock and Set current state to Idle*/
2511 p_ctrl->current_operation = FLASH_OPERATION_NON_BGO;
2512
2513 /* Set data to identify callback to user, then call user callback. */
2514 r_flash_hp_call_callback(p_ctrl, event);
2515 }
2516
2517 FSP_CONTEXT_RESTORE
2518 }
2519
2520 /*******************************************************************************************************************//**
2521 * Calls user callback.
2522 *
2523 * @param[in] p_ctrl Pointer to FLASH_HP instance control block
2524 * @param[in] event Event code
2525 **********************************************************************************************************************/
r_flash_hp_call_callback(flash_hp_instance_ctrl_t * p_ctrl,flash_event_t event)2526 static void r_flash_hp_call_callback (flash_hp_instance_ctrl_t * p_ctrl, flash_event_t event)
2527 {
2528 flash_callback_args_t args;
2529
2530 /* Store callback arguments in memory provided by user if available. This allows callback arguments to be
2531 * stored in non-secure memory so they can be accessed by a non-secure callback function. */
2532 flash_callback_args_t * p_args = p_ctrl->p_callback_memory;
2533 if (NULL == p_args)
2534 {
2535 /* Store on stack */
2536 p_args = &args;
2537 }
2538 else
2539 {
2540 /* Save current arguments on the stack in case this is a nested interrupt. */
2541 args = *p_args;
2542 }
2543
2544 p_args->event = event;
2545 p_args->p_context = p_ctrl->p_context;
2546
2547 #if BSP_TZ_SECURE_BUILD
2548
2549 /* p_callback can point to a secure function or a non-secure function. */
2550 if (!cmse_is_nsfptr(p_ctrl->p_callback))
2551 {
2552 /* If p_callback is secure, then the project does not need to change security state. */
2553 p_ctrl->p_callback(p_args);
2554 }
2555 else
2556 {
2557 /* If p_callback is Non-secure, then the project must change to Non-secure state in order to call the callback. */
2558 flash_hp_prv_ns_callback p_callback = (flash_hp_prv_ns_callback) (p_ctrl->p_callback);
2559 p_callback(p_args);
2560 }
2561
2562 #else
2563
2564 /* If the project is not Trustzone Secure, then it will never need to change security state in order to call the callback. */
2565 p_ctrl->p_callback(p_args);
2566 #endif
2567 if (NULL != p_ctrl->p_callback_memory)
2568 {
2569 /* Restore callback memory in case this is a nested interrupt. */
2570 *p_ctrl->p_callback_memory = args;
2571 }
2572 }
2573
2574 /*******************************************************************************************************************//**
2575 * This function switches the peripheral to P/E mode for Data Flash.
2576 * @param[in] p_ctrl Pointer to the Flash control block.
2577 * @retval FSP_SUCCESS Successfully entered Data Flash P/E mode.
2578 * @retval FSP_ERR_PE_FAILURE Failed to enter Data Flash P/E mode.
2579 **********************************************************************************************************************/
flash_hp_enter_pe_df_mode(flash_hp_instance_ctrl_t * const p_ctrl)2580 static fsp_err_t flash_hp_enter_pe_df_mode (flash_hp_instance_ctrl_t * const p_ctrl)
2581 {
2582 fsp_err_t err = FSP_SUCCESS;
2583
2584 /* See "Transition to Data Flash P/E Mode": Section 47.9.3.4 of the RA6M4 manual R01UH0890EJ0100. */
2585 /* Timeout counter. */
2586 volatile uint32_t wait_count = FLASH_HP_FRDY_CMD_TIMEOUT;
2587
2588 /* If BGO mode is enabled and interrupts are being used then enable interrupts. */
2589 if (p_ctrl->p_cfg->data_flash_bgo == true)
2590 {
2591 /* We are supporting Flash Rdy interrupts for Data Flash operations. */
2592 R_BSP_IrqEnable(p_ctrl->p_cfg->irq);
2593
2594 /* We are supporting Flash Err interrupts for Data Flash operations. */
2595 R_BSP_IrqEnable(p_ctrl->p_cfg->err_irq);
2596 }
2597
2598 /* Enter Data Flash PE mode. */
2599 R_FACI_HP->FENTRYR = FLASH_HP_FENTRYR_TRANSITION_TO_DF_PE;
2600
2601 /* Wait for the operation to complete or timeout. If timeout return error. */
2602 /* Read FENTRYR until it has been set to 0x0080 indicating that we have successfully entered P/E mode.*/
2603 while (FLASH_HP_FENTRYR_DF_PE_MODE != R_FACI_HP->FENTRYR)
2604 {
2605 /* Wait until FENTRYR is 0x0080 unless timeout occurs. */
2606 if (wait_count == 0U)
2607 {
2608
2609 /* if FENTRYR is not set after max timeout return an error. */
2610 return FSP_ERR_PE_FAILURE;
2611 }
2612
2613 wait_count--;
2614 }
2615
2616 return err;
2617 }
2618
2619 #if (FLASH_HP_CFG_CODE_FLASH_PROGRAMMING_ENABLE == 1)
2620
2621 /*******************************************************************************************************************//**
2622 * This function switches the peripheral to P/E mode for Code Flash.
2623 * @param[in] p_ctrl Pointer to the Flash control block.
2624 * @retval FSP_SUCCESS Successfully entered Code Flash P/E mode.
2625 * @retval FSP_ERR_PE_FAILURE Failed to enter Code Flash P/E mode.
2626 **********************************************************************************************************************/
flash_hp_enter_pe_cf_mode(flash_hp_instance_ctrl_t * const p_ctrl)2627 static fsp_err_t flash_hp_enter_pe_cf_mode (flash_hp_instance_ctrl_t * const p_ctrl)
2628 {
2629 fsp_err_t err = FSP_SUCCESS;
2630
2631 /* See "Transition to Code Flash P/E Mode": Section 47.9.3.3 of the RA6M4 manual R01UH0890EJ0100. */
2632 /* Timeout counter. */
2633 volatile uint32_t wait_count = FLASH_HP_FRDY_CMD_TIMEOUT;
2634
2635 /* While the Flash API is in use we will disable the flash cache. */
2636 #if BSP_FEATURE_BSP_FLASH_CACHE_DISABLE_OPM
2637 R_BSP_FlashCacheDisable();
2638 #elif BSP_FEATURE_BSP_HAS_CODE_SYSTEM_CACHE
2639
2640 /* Disable the C-Cache. */
2641 R_CACHE->CCACTL = 0U;
2642 #endif
2643
2644 /* If interrupts are being used then disable interrupts. */
2645 if (p_ctrl->p_cfg->data_flash_bgo == true)
2646 {
2647 /* We are not supporting Flash Rdy interrupts for Code Flash operations */
2648 R_BSP_IrqDisable(p_ctrl->p_cfg->irq);
2649
2650 /* We are not supporting Flash Err interrupts for Code Flash operations */
2651 R_BSP_IrqDisable(p_ctrl->p_cfg->err_irq);
2652 }
2653
2654 #if BSP_FEATURE_FLASH_HP_HAS_FMEPROT
2655 R_FACI_HP->FMEPROT = FLASH_HP_FMEPROT_UNLOCK;
2656 #endif
2657
2658 /* Enter code flash PE mode */
2659 R_FACI_HP->FENTRYR = FLASH_HP_FENTRYR_TRANSITION_TO_CF_PE;
2660
2661 /* Wait for the operation to complete or timeout. If timeout return error. */
2662 /* Read FENTRYR until it has been set to 0x0001 indicating that we have successfully entered CF P/E mode.*/
2663 while (FLASH_HP_FENTRYR_CF_PE_MODE != R_FACI_HP->FENTRYR)
2664 {
2665 /* Wait until FENTRYR is 0x0001UL unless timeout occurs. */
2666 if (wait_count == 0U)
2667 {
2668
2669 /* if FENTRYR is not set after max timeout, FSP_ERR_PE_FAILURE*/
2670 return FSP_ERR_PE_FAILURE;
2671 }
2672
2673 wait_count--;
2674 }
2675
2676 return err;
2677 }
2678
2679 #endif
2680