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