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