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