1 /***********************************************************************************************************************
2 * Copyright [2015-2017] Renesas Electronics Corporation and/or its licensors. All Rights Reserved.
3 *
4 * This file is part of Renesas SynergyTM Software Package (SSP)
5 *
6 * The contents of this file (the "contents") are proprietary and confidential to Renesas Electronics Corporation
7 * and/or its licensors ("Renesas") and subject to statutory and contractual protections.
8 *
9 * This file is subject to a Renesas SSP license agreement. Unless otherwise agreed in an SSP license agreement with
10 * Renesas: 1) you may not use, copy, modify, distribute, display, or perform the contents; 2) you may not use any name
11 * or mark of Renesas for advertising or publicity purposes or in connection with your use of the contents; 3) RENESAS
12 * MAKES NO WARRANTY OR REPRESENTATIONS ABOUT THE SUITABILITY OF THE CONTENTS FOR ANY PURPOSE; THE CONTENTS ARE PROVIDED
13 * "AS IS" WITHOUT ANY EXPRESS OR IMPLIED WARRANTY, INCLUDING THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
14 * PARTICULAR PURPOSE, AND NON-INFRINGEMENT; AND 4) RENESAS SHALL NOT BE LIABLE FOR ANY DIRECT, INDIRECT, SPECIAL, OR
15 * CONSEQUENTIAL DAMAGES, INCLUDING DAMAGES RESULTING FROM LOSS OF USE, DATA, OR PROJECTS, WHETHER IN AN ACTION OF
16 * CONTRACT OR TORT, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THE CONTENTS. Third-party contents
17 * included in this file may be subject to different terms.
18 **********************************************************************************************************************/
19
20 /**********************************************************************************************************************
21 * File Name : hw_codeflash_extra.c
22 * Description : Flash Control Access window and swap control processing for Low Power Flash
23 **********************************************************************************************************************/
24
25 /******************************************************************************
26 * Includes <System Includes> , “Project Includes”
27 ******************************************************************************/
28 #include "bsp_api.h"
29 #include "r_flash_lp.h"
30 #include "../hw_flash_lp_private.h"
31 #include "r_flash_cfg.h"
32 #include "hw_flash_common.h"
33 #include "hw_dataflash.h"
34 #include "hw_codeflash.h"
35 #include "hw_codeflash_extra.h"
36
37 /*******************************************************************************************************************//**
38 * @addtogroup FLASH
39 * @{
40 **********************************************************************************************************************/
41 /*******************************************************************************************************************//**
42 * @} (end FLASH)
43 **********************************************************************************************************************/
44
45 /******************************************************************************
46 * Private global variables and functions
47 ******************************************************************************/
48
49 /*******************************************************************************************************************//**
50 * @brief Temporarily sets the startup area to use the DEFAULT or ALTERNATE area as requested.
51 * On the next subsequent reset, the startup area will be determined by the state of the BTFLG.
52 * This command does NOT modify the configuration via The Configuration Set command, hence these changes are
53 * only in effect until the next reset.
54 * @param[in] p_ctrl Pointer to the Flash control block
55 * @param[in] swap_type - specifies the startup area swap being requested.
56 *
57 * @retval SSP_SUCCESS StartUp area temporarily modified.
58 **********************************************************************************************************************/
HW_FLASH_LP_set_startup_area_temporary(flash_lp_instance_ctrl_t * const p_ctrl,flash_startup_area_swap_t swap_type)59 ssp_err_t HW_FLASH_LP_set_startup_area_temporary (flash_lp_instance_ctrl_t * const p_ctrl, flash_startup_area_swap_t swap_type)
60 {
61 ssp_err_t err = SSP_SUCCESS;
62 R_FACI_Type * p_faci_reg = (R_FACI_Type *) p_ctrl->p_reg;
63
64 /** Set the Flash initial setting startup area select bit as requested. */
65 if (FLASH_STARTUP_AREA_BLOCK0 == swap_type)
66 {
67 p_faci_reg->FISR_b.SAS = SAS_DEFAULT_AREA;
68 }
69 else if (FLASH_STARTUP_AREA_BLOCK1 == swap_type)
70 {
71 p_faci_reg->FISR_b.SAS = SAS_ALTERNATE_AREA;
72 }
73 else
74 {
75 p_faci_reg->FISR_b.SAS = (uint32_t)SAS_PER_BTFLG_AREA;
76 }
77
78 return err;
79 }
80
81 /*******************************************************************************************************************//**
82 * @brief Configure an access window for the Code Flash memory using the provided start and end address. An access
83 * window defines a contiguous area in Code Flash for which programming/erase is enabled. This area is
84 * on block boundaries.
85 * The block containing start_addr is the first block. The block containing end_addr is the last block.
86 * The access window then becomes first block - last block inclusive. Anything outside this range
87 * of Code Flash is then write protected.
88 * This command DOES modify the configuration via The Configuration Set command to update the FAWS and FAWE.
89 *
90 * @param[in] p_ctrl Pointer to the Flash control block
91 * @param[in] start_addr Determines the Starting block for the Code Flash access window.
92 * @param[in] end_addr Determines the Ending block for the Code Flash access window.
93 *
94 * @retval SSP_SUCCESS Access window successfully configured.
95 * @retval SSP_ERR_ERASE_FAILED Status is indicating an erase error. Possibly from a prior operation.
96 * @retval SSP_ERR_CMD_LOCKED FCU is in locked state, typically as a result of having received an illegal
97 * command.
98 * @retval SSP_ERR_WRITE_FAILED Status is indicating a Programming error for the requested operation.
99 * @retval SSP_ERR_TIMEOUT Timed out waiting for the FCU to become ready.
100 **********************************************************************************************************************/
HW_FLASH_LP_access_window_set(flash_lp_instance_ctrl_t * const p_ctrl,uint32_t const start_addr,uint32_t const end_addr)101 ssp_err_t HW_FLASH_LP_access_window_set (flash_lp_instance_ctrl_t * const p_ctrl, uint32_t const start_addr, uint32_t const end_addr)
102 {
103 ssp_err_t err = SSP_SUCCESS;
104 R_FACI_Type * p_faci_reg = (R_FACI_Type *) p_ctrl->p_reg;
105
106 uint32_t start_addr_idx;
107 uint32_t end_addr_idx;
108
109 start_addr_idx = start_addr;
110 end_addr_idx = end_addr;
111
112 /** Select The Extra Area */
113 p_faci_reg->FASR_b.EXS = 1U;
114
115 /** Set the access window. */
116 HW_FLASH_LP_extra_operation(p_ctrl, start_addr_idx, end_addr_idx, FLASH_COMMAND_ACCESSWINDOW);
117
118 /** Wait for the operation to complete or error. */
119 do
120 {
121 err = HW_FLASH_LP_extra_check(p_ctrl);
122 } while (SSP_ERR_IN_USE == err);
123
124 /** Select User Area */
125 p_faci_reg->FASR_b.EXS = 0U;
126
127 /** Return status. */
128 return err;
129 }
130
131 /*******************************************************************************************************************//**
132 * @brief Remove any access window that is currently configured in the Code Flash.
133 * This command DOES modify the configuration via The Configuration Set command to update the FAWS and FAWE.
134 * Subsequent to this call all Code Flash is writable.
135 *
136 * @retval SSP_SUCCESS Access window successfully removed.
137 * @retval SSP_ERR_ERASE_FAILED Status is indicating an erase error. Possibly from a prior operation.
138 * @retval SSP_ERR_CMD_LOCKED FCU is in locked state, typically as a result of having received an illegal
139 * command.
140 * @retval SSP_ERR_WRITE_FAILED Status is indicating a Programming error for the requested operation.
141 * @retval SSP_ERR_TIMEOUT Timed out waiting for the FCU to become ready.
142 * @param[in] p_ctrl Pointer to the Flash control block
143 **********************************************************************************************************************/
HW_FLASH_LP_access_window_clear(flash_lp_instance_ctrl_t * const p_ctrl)144 ssp_err_t HW_FLASH_LP_access_window_clear (flash_lp_instance_ctrl_t * const p_ctrl)
145 {
146 ssp_err_t err = SSP_SUCCESS;
147 R_FACI_Type * p_faci_reg = (R_FACI_Type *) p_ctrl->p_reg;
148
149 /** Select Extra Area */
150 p_faci_reg->FASR_b.EXS = 1U;
151
152 // Setting the accesswindow to 0,0 will clear any configured access window.
153 /** Call extra operation to clear the access window. */
154 HW_FLASH_LP_extra_operation(p_ctrl, 0, 0, FLASH_COMMAND_ACCESSWINDOW);
155
156 /** Wait until the operation is complete or an error. */
157 do
158 {
159 err = HW_FLASH_LP_extra_check(p_ctrl);
160 } while (SSP_ERR_IN_USE == err);
161
162 /** Select User Area */
163 p_faci_reg->FASR_b.EXS = 0U;
164
165 return err;
166 }
167
168 /*******************************************************************************************************************//**
169 * @brief Set the id code
170 *
171 * @param p_ctrl The p control
172 * @param p_id_code Pointer to the code to be written
173 * @param[in] mode The id code mode
174 *
175 * @retval SSP_SUCCESS The id code have been written.
176 * @retval SSP_ERR_WRITE_FAILED Status is indicating a Programming error for the requested operation.
177 * @retval SSP_ERR_TIMEOUT Timed out waiting for completion of extra command.
178 **********************************************************************************************************************/
HW_FLASH_LP_set_id_code(flash_lp_instance_ctrl_t * const p_ctrl,uint8_t const * const p_id_code,flash_id_code_mode_t mode)179 ssp_err_t HW_FLASH_LP_set_id_code (flash_lp_instance_ctrl_t * const p_ctrl,
180 uint8_t const * const p_id_code,
181 flash_id_code_mode_t mode)
182 {
183 ssp_err_t err = SSP_SUCCESS;
184 R_FACI_Type * p_faci_reg = (R_FACI_Type *) p_ctrl->p_reg;
185 uint32_t fexcr_command = FEXCR_OCDID1;
186
187 uint16_t mode_mask = 0U;
188
189 if(FLASH_ID_CODE_MODE_LOCKED_WITH_ALL_ERASE_SUPPORT == mode)
190 {
191 mode_mask = 0xC000U;
192 }
193
194 if(FLASH_ID_CODE_MODE_LOCKED == mode)
195 {
196 mode_mask = 0x8000U;
197 }
198
199 /* Timeout counter. */
200 volatile uint32_t wait_cnt = FLASH_FRDY_CMD_TIMEOUT;
201
202 /** For each ID byte register */
203 for(uint32_t i = 0U; i < 16U; i+=4U)
204 {
205 /** Select Extra Area */
206 p_faci_reg->FASR_b.EXS = 1U;
207
208 /** Write the ID Bytes. If mode is unlocked write all 0xFF. Write the mode mask to the MSB. */
209 if(FLASH_ID_CODE_MODE_UNLOCKED == mode)
210 {
211 p_faci_reg->FWBL0 = 0xFFFFU;
212 p_faci_reg->FWBH0 = 0xFFFFU;
213 }
214 else
215 {
216 /* The id code array may be unaligned. Do not attempt to optimize this code to prevent unaligned access. */
217 p_faci_reg->FWBL0 = (uint32_t)(p_id_code[i] | ((uint32_t)p_id_code[i+1] << 8));
218 if(12U == i)
219 {
220 p_faci_reg->FWBH0 = (uint32_t)(p_id_code[i+2] | ((uint32_t)p_id_code[i+3] << 8)) | mode_mask;
221 }
222 else
223 {
224 p_faci_reg->FWBH0 = (uint32_t)(p_id_code[i+2] | ((uint32_t)p_id_code[i+3] << 8));
225 }
226 }
227
228 /** Execute OCDID command */
229 p_faci_reg->FEXCR = fexcr_command;
230
231 /** Increment the command to write to the next OCDID bytes */
232 fexcr_command++;
233
234 /** Wait until the operation is complete or an error. */
235 do
236 {
237 err = HW_FLASH_LP_extra_check(p_ctrl);
238 wait_cnt--;
239 if(wait_cnt == 0U)
240 {
241 err = SSP_ERR_TIMEOUT;
242 }
243 } while (SSP_ERR_IN_USE == err);
244
245 /** Select User Area */
246 p_faci_reg->FASR_b.EXS = 0U;
247
248 /** If failure return error */
249 if(SSP_SUCCESS != err)
250 {
251 return err;
252 }
253 }
254
255 return err;
256 }
257
258 /*******************************************************************************************************************//**
259 * @brief Modifies the start-up program swap flag (BTFLG) based on the supplied parameters. These changes will
260 * take effect on the next reset. This command DOES modify the configuration via The Configuration
261 * Set command to update the BTFLG.
262 *
263 * @retval SSP_SUCCESS Access window successfully removed.
264 * @retval SSP_ERR_ERASE_FAILED Status is indicating an erase error. Possibly from a prior operation.
265 * @retval SSP_ERR_CMD_LOCKED FCU is in locked state, typically as a result of having received an illegal
266 * command.
267 * @retval SSP_ERR_WRITE_FAILED Status is indicating a Programming error for the requested operation.
268 * @retval SSP_ERR_TIMEOUT Timed out waiting for the FCU to become ready.
269 *
270 * @param[in] p_ctrl Pointer to the Flash control block
271 * @param[in] swap_type - specifies the startup area swap being requested.
272 **********************************************************************************************************************/
HW_FLASH_LP_set_startup_area_boot(flash_lp_instance_ctrl_t * const p_ctrl,flash_startup_area_swap_t swap_type)273 ssp_err_t HW_FLASH_LP_set_startup_area_boot (flash_lp_instance_ctrl_t * const p_ctrl, flash_startup_area_swap_t swap_type)
274 {
275 ssp_err_t err = SSP_SUCCESS;
276 R_FACI_Type * p_faci_reg = (R_FACI_Type *) p_ctrl->p_reg;
277 uint32_t startup_area_mask = (uint32_t)((uint32_t)swap_type << 8); // move selection to bit 8
278
279 /** Select Extra Area */
280 p_faci_reg->FASR_b.EXS = 1U;
281
282 /** Call extra operation to set the startup area. */
283 HW_FLASH_LP_extra_operation(p_ctrl, startup_area_mask, 0, FLASH_COMMAND_STARTUPAREA);
284
285 /** Wait until the operation is complete or an error occurs. */
286 do
287 {
288 err = HW_FLASH_LP_extra_check(p_ctrl);
289 } while (SSP_ERR_IN_USE == err);
290
291 /** Select User Area */
292 p_faci_reg->FASR_b.EXS = 0U;
293
294 return err;
295 }
296
297 /*******************************************************************************************************************//**
298 * @brief Command processing for the extra area.
299 *
300 * @param[in] p_ctrl Pointer to the Flash control block
301 * @param[in] start_addr_startup_value Determines the Starting block for the Code Flash access window.
302 * @param[in] end_addr Determines the Ending block for the Code Flash access window.
303 * @param[in] command Select from R_FLASH_ACCESSWINDOW or R_FLASH_STARTUPAREA.
304 *
305 **********************************************************************************************************************/
HW_FLASH_LP_extra_operation(flash_lp_instance_ctrl_t * const p_ctrl,const uint32_t start_addr_startup_value,const uint32_t end_addr,r_flash_command_t command)306 void HW_FLASH_LP_extra_operation (flash_lp_instance_ctrl_t * const p_ctrl, const uint32_t start_addr_startup_value,
307 const uint32_t end_addr,
308 r_flash_command_t command)
309 {
310 R_FACI_Type * p_faci_reg = (R_FACI_Type *) p_ctrl->p_reg;
311 /* Per the spec: */
312 /* Setting data to the FWBL0 register, this command is allowed to select the start-up area from the */
313 /* default area (blocks 0-3) to the alternative area (blocks 4-7) and set the security. */
314 /* Bit 8 of the FWBL0 register is 0: the alternative area (blocks 4-7) are selected as the start-up area. */
315 /* Bit 8 of the FWBL0 register is 1: the default area (blocks 0-3) are selected as the start-up area. */
316 /* Bit 14 of the FWBL0 register MUST be 1! Setting this bit to zero will clear the FSPR register and lock the */
317 /* FLASH!!! It is not be possible to unlock it. */
318
319 if (FLASH_COMMAND_ACCESSWINDOW == command)
320 {
321 /** Set the Access Window start and end addresses. */
322 /* FWBL0 reg sets the Start Block address. FWBH0 reg sets the end address. */
323 /* Convert the addresses to their respective block numbers */
324 p_faci_reg->FWBL0 = ((start_addr_startup_value >> 10) & 0xFFFFU);
325 p_faci_reg->FWBH0 = ((end_addr >> 10) & 0xFFFFU);
326
327 /** Execute Access Window command */
328 p_faci_reg->FEXCR = FEXCR_AW;
329 }
330 else
331 {
332 /* Startup Area Flag value setting */
333 p_faci_reg->FWBH0 = 0xFFFFU;
334
335 /* FSPR must be set. Unused bits write value should be 1. */
336 p_faci_reg->FWBL0 = (start_addr_startup_value | 0xFEFFU);
337
338 /** Execute Startup Area Flag command */
339 p_faci_reg->FEXCR = FEXCR_STARTUP;
340 }
341 }
342
343 /*******************************************************************************************************************//**
344 * @brief Verifying the execution result for the extra area.
345 * @param[in] p_ctrl Pointer to the Flash control block
346 * @retval SSP_SUCCESS The extra command has successfully completed.
347 * @retval SSP_ERR_WRITE_FAILED Status is indicating a Programming error for the requested operation.
348 * @retval SSP_ERR_TIMEOUT Timed out waiting for completion of extra command.
349 **********************************************************************************************************************/
HW_FLASH_LP_extra_check(flash_lp_instance_ctrl_t * const p_ctrl)350 ssp_err_t HW_FLASH_LP_extra_check (flash_lp_instance_ctrl_t * const p_ctrl)
351 {
352 R_FACI_Type * p_faci_reg = (R_FACI_Type *) p_ctrl->p_reg;
353
354 /* Timeout counter. */
355 volatile uint32_t wait_cnt = FLASH_FRDY_CMD_TIMEOUT;
356
357 /** If the software command of the FEXCR register is not terminated return in use. */
358 if (1U != p_faci_reg->FSTATR1_b.EXRDY)
359 {
360 return SSP_ERR_IN_USE;
361 }
362
363 /** Clear the Flash Extra Area Control Register. */
364 p_faci_reg->FEXCR = FEXCR_CLEAR;
365
366 /** Wait until the command has completed or a timeout occurs. If timeout return error. */
367 while (0U != p_faci_reg->FSTATR1_b.EXRDY)
368 {
369 /* Check that execute command is completed. */
370 /* Confirm that the written value can be read correctly. */
371 if (wait_cnt <= (uint32_t)0)
372 {
373 /* return timeout status*/
374 return SSP_ERR_TIMEOUT;
375 }
376 wait_cnt--;
377 }
378
379 /** If Extra Area Illegal Command Error Flag or Error during programming reset the flash and return error. */
380 if ((0U != p_faci_reg->FSTATR00_b.EILGLERR) || (0U != p_faci_reg->FSTATR00_b.PRGERR01))
381 {
382 HW_FLASH_LP_reset(p_ctrl);
383 return SSP_ERR_WRITE_FAILED;
384 }
385
386 /** Return success. */
387 return SSP_SUCCESS;
388 }
389
390