1 /**
2 ******************************************************************************
3 * @file stm32g0xx_hal_flash_ex.c
4 * @author MCD Application Team
5 * @brief Extended FLASH HAL module driver.
6 * This file provides firmware functions to manage the following
7 * functionalities of the FLASH extended peripheral:
8 * + Extended programming operations functions
9 *
10 @verbatim
11 ==============================================================================
12 ##### Flash Extended features #####
13 ==============================================================================
14
15 [..] Comparing to other previous devices, the FLASH interface for STM32G0xx
16 devices contains the following additional features
17
18 (+) Capacity up to 128 Kbytes with single bank architecture supporting read-while-write
19 capability (RWW)
20 (+) Single bank memory organization
21 (+) PCROP protection
22
23 ##### How to use this driver #####
24 ==============================================================================
25 [..] This driver provides functions to configure and program the FLASH memory
26 of all STM32G0xx devices. It includes
27 (#) Flash Memory Erase functions:
28 (++) Lock and Unlock the FLASH interface using HAL_FLASH_Unlock() and
29 HAL_FLASH_Lock() functions
30 (++) Erase function: Erase page, erase all sectors
31 (++) There are two modes of erase :
32 (+++) Polling Mode using HAL_FLASHEx_Erase()
33 (+++) Interrupt Mode using HAL_FLASHEx_Erase_IT()
34
35 (#) Option Bytes Programming function: Use HAL_FLASHEx_OBProgram() to :
36 (++) Set/Reset the write protection
37 (++) Set the Read protection Level
38 (++) Program the user Option Bytes
39 (++) Configure the PCROP protection
40 (++) Set Securable memory area and boot entry point
41
42 (#) Get Option Bytes Configuration function: Use HAL_FLASHEx_OBGetConfig() to :
43 (++) Get the value of a write protection area
44 (++) Know if the read protection is activated
45 (++) Get the value of the user Option Bytes
46 (++) Get Securable memory area and boot entry point information
47
48 (#) Enable or disable debugger usage using HAL_FLASHEx_EnableDebugger and
49 HAL_FLASHEx_DisableDebugger.
50
51 (#) Check is flash content is empty or not using HAL_FLASHEx_FlashEmptyCheck.
52 and modify this setting (for flash loader purpose e.g.) using
53 HAL_FLASHEx_ForceFlashEmpty.
54
55 (#) Enable securable memory area protectionusing HAL_FLASHEx_EnableSecMemProtection
56
57 @endverbatim
58 ******************************************************************************
59 * @attention
60 *
61 * Copyright (c) 2018 STMicroelectronics.
62 * All rights reserved.
63 *
64 * This software is licensed under terms that can be found in the LICENSE file in
65 * the root directory of this software component.
66 * If no LICENSE file comes with this software, it is provided AS-IS.
67 ******************************************************************************
68 */
69
70 /* Includes ------------------------------------------------------------------*/
71 #include "stm32g0xx_hal.h"
72
73 /** @addtogroup STM32G0xx_HAL_Driver
74 * @{
75 */
76
77 /** @defgroup FLASHEx FLASHEx
78 * @brief FLASH Extended HAL module driver
79 * @{
80 */
81
82 #ifdef HAL_FLASH_MODULE_ENABLED
83
84 /* Private typedef -----------------------------------------------------------*/
85 /* Private define ------------------------------------------------------------*/
86 /* Private macro -------------------------------------------------------------*/
87 /* Private variables ---------------------------------------------------------*/
88 /* Private function prototypes -----------------------------------------------*/
89 /** @defgroup FLASHEx_Private_Functions FLASHEx Private Functions
90 * @{
91 */
92 static void FLASH_MassErase(uint32_t Banks);
93 void FLASH_FlushCaches(void);
94 static void FLASH_OB_WRPConfig(uint32_t WRPArea, uint32_t WRPStartOffset, uint32_t WRDPEndOffset);
95 static void FLASH_OB_GetWRP(uint32_t WRPArea, uint32_t *WRPStartOffset, uint32_t *WRDPEndOffset);
96 static void FLASH_OB_OptrConfig(uint32_t UserType, uint32_t UserConfig, uint32_t RDPLevel);
97 static uint32_t FLASH_OB_GetRDP(void);
98 static uint32_t FLASH_OB_GetUser(void);
99 #if defined(FLASH_PCROP_SUPPORT)
100 static void FLASH_OB_PCROP1AConfig(uint32_t PCROPConfig, uint32_t PCROP1AStartAddr,
101 uint32_t PCROP1AEndAddr);
102 static void FLASH_OB_PCROP1BConfig(uint32_t PCROP1BStartAddr, uint32_t PCROP1BEndAddr);
103 static void FLASH_OB_GetPCROP1A(uint32_t *PCROPConfig, uint32_t *PCROP1AStartAddr,
104 uint32_t *PCROP1AEndAddr);
105 static void FLASH_OB_GetPCROP1B(uint32_t *PCROP1BStartAddr, uint32_t *PCROP1BEndAddr);
106 #if defined(FLASH_DBANK_SUPPORT)
107 static void FLASH_OB_PCROP2AConfig(uint32_t PCROP2AStartAddr, uint32_t PCROP2AEndAddr);
108 static void FLASH_OB_PCROP2BConfig(uint32_t PCROP2BStartAddr, uint32_t PCROP2BEndAddr);
109 static void FLASH_OB_GetPCROP2A(uint32_t *PCROP2AStartAddr, uint32_t *PCROP2AEndAddr);
110 static void FLASH_OB_GetPCROP2B(uint32_t *PCROP2BStartAddr, uint32_t *PCROP2BEndAddr);
111 #endif /* FLASH_DBANK_SUPPORT */
112 #endif /* FLASH_PCROP_SUPPORT */
113 #if defined(FLASH_SECURABLE_MEMORY_SUPPORT)
114 #if defined(FLASH_DBANK_SUPPORT)
115 static void FLASH_OB_SecMemConfig(uint32_t BootEntry, uint32_t SecSize, uint32_t SecSize2);
116 static void FLASH_OB_GetSecMem(uint32_t *BootEntry, uint32_t *SecSize, uint32_t *SecSize2);
117 #else
118 static void FLASH_OB_SecMemConfig(uint32_t BootEntry, uint32_t SecSize);
119 static void FLASH_OB_GetSecMem(uint32_t *BootEntry, uint32_t *SecSize);
120 #endif /* FLASH_DBANK_SUPPORT */
121 #endif /* FLASH_SECURABLE_MEMORY_SUPPORT */
122 /**
123 * @}
124 */
125
126 /* Exported functions -------------------------------------------------------*/
127 /** @defgroup FLASHEx_Exported_Functions FLASH Extended Exported Functions
128 * @{
129 */
130
131 /** @defgroup FLASHEx_Exported_Functions_Group1 Extended IO operation functions
132 * @brief Extended IO operation functions
133 *
134 @verbatim
135 ===============================================================================
136 ##### Extended programming operation functions #####
137 ===============================================================================
138 [..]
139 This subsection provides a set of functions allowing to manage the Extended FLASH
140 programming operations Operations.
141
142 @endverbatim
143 * @{
144 */
145 /**
146 * @brief Perform a mass erase or erase the specified FLASH memory pages.
147 * @param[in] pEraseInit Pointer to an @ref FLASH_EraseInitTypeDef structure that
148 * contains the configuration information for the erasing.
149 * @param[out] PageError Pointer to variable that contains the configuration
150 * information on faulty page in case of error (0xFFFFFFFF means that all
151 * the pages have been correctly erased)
152 * @retval HAL Status
153 */
HAL_FLASHEx_Erase(FLASH_EraseInitTypeDef * pEraseInit,uint32_t * PageError)154 HAL_StatusTypeDef HAL_FLASHEx_Erase(FLASH_EraseInitTypeDef *pEraseInit, uint32_t *PageError)
155 {
156 HAL_StatusTypeDef status;
157 uint32_t index;
158
159 /* Check the parameters */
160 assert_param(IS_FLASH_TYPEERASE(pEraseInit->TypeErase));
161
162 /* Process Locked */
163 __HAL_LOCK(&pFlash);
164
165 /* Reset error code */
166 pFlash.ErrorCode = HAL_FLASH_ERROR_NONE;
167
168 /* Wait for last operation to be completed */
169 status = FLASH_WaitForLastOperation(FLASH_TIMEOUT_VALUE);
170
171 if (status == HAL_OK)
172 {
173 #if !defined(FLASH_DBANK_SUPPORT)
174 /* For single bank product force Banks to Bank 1 */
175 pEraseInit->Banks = FLASH_BANK_1;
176 #endif /* FLASH_DBANK_SUPPORT */
177
178 if (pEraseInit->TypeErase == FLASH_TYPEERASE_MASS)
179 {
180 /* Proceed to Mass Erase */
181 FLASH_MassErase(pEraseInit->Banks);
182
183 /* Wait for last operation to be completed */
184 status = FLASH_WaitForLastOperation(FLASH_TIMEOUT_VALUE);
185 }
186 else
187 {
188 /*Initialization of PageError variable*/
189 *PageError = 0xFFFFFFFFU;
190
191 for (index = pEraseInit->Page; index < (pEraseInit->Page + pEraseInit->NbPages); index++)
192 {
193 /* Start erase page */
194 FLASH_PageErase(pEraseInit->Banks, index);
195
196 /* Wait for last operation to be completed */
197 status = FLASH_WaitForLastOperation(FLASH_TIMEOUT_VALUE);
198
199 if (status != HAL_OK)
200 {
201 /* In case of error, stop erase procedure and return the faulty address */
202 *PageError = index;
203 break;
204 }
205 }
206
207 /* If operation is completed or interrupted, disable the Page Erase Bit */
208 CLEAR_BIT(FLASH->CR, FLASH_CR_PER);
209 }
210 }
211
212 /* Process Unlocked */
213 __HAL_UNLOCK(&pFlash);
214
215 /* return status */
216 return status;
217 }
218
219
220 /**
221 * @brief Perform a mass erase or erase the specified FLASH memory pages with interrupt enabled.
222 * @param pEraseInit Pointer to an @ref FLASH_EraseInitTypeDef structure that
223 * contains the configuration information for the erasing.
224 * @retval HAL Status
225 */
HAL_FLASHEx_Erase_IT(FLASH_EraseInitTypeDef * pEraseInit)226 HAL_StatusTypeDef HAL_FLASHEx_Erase_IT(FLASH_EraseInitTypeDef *pEraseInit)
227 {
228 HAL_StatusTypeDef status;
229
230 /* Check the parameters */
231 assert_param(IS_FLASH_TYPEERASE(pEraseInit->TypeErase));
232
233 /* Process Locked */
234 __HAL_LOCK(&pFlash);
235
236 /* Reset error code */
237 pFlash.ErrorCode = HAL_FLASH_ERROR_NONE;
238
239 /* save procedure for interrupt treatment */
240 pFlash.ProcedureOnGoing = pEraseInit->TypeErase;
241
242 /* Wait for last operation to be completed */
243 status = FLASH_WaitForLastOperation(FLASH_TIMEOUT_VALUE);
244
245 if (status != HAL_OK)
246 {
247 /* Process Unlocked */
248 __HAL_UNLOCK(&pFlash);
249 }
250 else
251 {
252 #if !defined(FLASH_DBANK_SUPPORT)
253 /* For single bank product force Banks to Bank 1 */
254 pEraseInit->Banks = FLASH_BANK_1;
255 #endif /* FLASH_DBANK_SUPPORT */
256 /* Store Bank number */
257 pFlash.Banks = pEraseInit->Banks;
258
259 /* Enable End of Operation and Error interrupts */
260 FLASH->CR |= FLASH_CR_EOPIE | FLASH_CR_ERRIE;
261
262 if (pEraseInit->TypeErase == FLASH_TYPEERASE_MASS)
263 {
264 /* Set Page to 0 for Interrupt callback management */
265 pFlash.Page = 0;
266
267 /* Proceed to Mass Erase */
268 FLASH_MassErase(pEraseInit->Banks);
269 }
270 else
271 {
272 /* Erase by page to be done */
273 pFlash.NbPagesToErase = pEraseInit->NbPages;
274 pFlash.Page = pEraseInit->Page;
275
276 /*Erase 1st page and wait for IT */
277 FLASH_PageErase(pEraseInit->Banks, pEraseInit->Page);
278 }
279 }
280
281 /* return status */
282 return status;
283 }
284
285 /**
286 * @brief Program Option bytes.
287 * @param pOBInit Pointer to an @ref FLASH_OBProgramInitTypeDef structure that
288 * contains the configuration information for the programming.
289 * @note To configure any option bytes, the option lock bit OPTLOCK must be
290 * cleared with the call of @ref HAL_FLASH_OB_Unlock() function.
291 * @note New option bytes configuration will be taken into account only
292 * - after an option bytes launch through the call of @ref HAL_FLASH_OB_Launch()
293 * - a Power On Reset
294 * - an exit from Standby or Shutdown mode.
295 * @retval HAL Status
296 */
HAL_FLASHEx_OBProgram(FLASH_OBProgramInitTypeDef * pOBInit)297 HAL_StatusTypeDef HAL_FLASHEx_OBProgram(FLASH_OBProgramInitTypeDef *pOBInit)
298 {
299 uint32_t optr;
300 HAL_StatusTypeDef status;
301
302 /* Check the parameters */
303 assert_param(IS_OPTIONBYTE(pOBInit->OptionType));
304
305 /* Process Locked */
306 __HAL_LOCK(&pFlash);
307
308 pFlash.ErrorCode = HAL_FLASH_ERROR_NONE;
309
310 /* Write protection configuration */
311 if ((pOBInit->OptionType & OPTIONBYTE_WRP) != 0x00U)
312 {
313 /* Configure of Write protection on the selected area */
314 FLASH_OB_WRPConfig(pOBInit->WRPArea, pOBInit->WRPStartOffset, pOBInit->WRPEndOffset);
315 }
316
317 /* Option register */
318 if ((pOBInit->OptionType & (OPTIONBYTE_RDP | OPTIONBYTE_USER)) == (OPTIONBYTE_RDP | OPTIONBYTE_USER))
319 {
320 /* Fully modify OPTR register with RDP & user data */
321 FLASH_OB_OptrConfig(pOBInit->USERType, pOBInit->USERConfig, pOBInit->RDPLevel);
322 }
323 else if ((pOBInit->OptionType & OPTIONBYTE_RDP) != 0x00U)
324 {
325 /* Only modify RDP so get current user data */
326 optr = FLASH_OB_GetUser();
327 FLASH_OB_OptrConfig(optr, optr, pOBInit->RDPLevel);
328 }
329 else if ((pOBInit->OptionType & OPTIONBYTE_USER) != 0x00U)
330 {
331 /* Only modify user so get current RDP level */
332 optr = FLASH_OB_GetRDP();
333 FLASH_OB_OptrConfig(pOBInit->USERType, pOBInit->USERConfig, optr);
334 }
335 else
336 {
337 /* nothing to do */
338 }
339
340 #if defined(FLASH_PCROP_SUPPORT)
341 /* PCROP Configuration */
342 if ((pOBInit->OptionType & OPTIONBYTE_PCROP) != 0x00U)
343 {
344 /* Check the parameters */
345 assert_param(IS_OB_PCROP_CONFIG(pOBInit->PCROPConfig));
346
347 if ((pOBInit->PCROPConfig & (OB_PCROP_ZONE_A | OB_PCROP_RDP_ERASE)) != 0x00U)
348 {
349 /* Configure the 1A Proprietary code readout protection */
350 FLASH_OB_PCROP1AConfig(pOBInit->PCROPConfig, pOBInit->PCROP1AStartAddr, pOBInit->PCROP1AEndAddr);
351 }
352
353 if ((pOBInit->PCROPConfig & OB_PCROP_ZONE_B) != 0x00U)
354 {
355 /* Configure the 1B Proprietary code readout protection */
356 FLASH_OB_PCROP1BConfig(pOBInit->PCROP1BStartAddr, pOBInit->PCROP1BEndAddr);
357 }
358
359 #if defined(FLASH_DBANK_SUPPORT)
360 if ((pOBInit->PCROPConfig & OB_PCROP_ZONE2_A) != 0x00U)
361 {
362 /* Configure the 2A Proprietary code readout protection */
363 FLASH_OB_PCROP2AConfig(pOBInit->PCROP2AStartAddr, pOBInit->PCROP2AEndAddr);
364 }
365
366 if ((pOBInit->PCROPConfig & OB_PCROP_ZONE2_B) != 0x00U)
367 {
368 /* Configure the 2B Proprietary code readout protection */
369 FLASH_OB_PCROP2BConfig(pOBInit->PCROP2BStartAddr, pOBInit->PCROP2BEndAddr);
370 }
371 #endif /* FLASH_DBANK_SUPPORT */
372 }
373 #endif /* FLASH_PCROP_SUPPORT */
374
375 #if defined(FLASH_SECURABLE_MEMORY_SUPPORT)
376 /* Securable Memory Area Configuration */
377 if ((pOBInit->OptionType & OPTIONBYTE_SEC) != 0x00U)
378 {
379 #if defined(FLASH_DBANK_SUPPORT)
380 /* Configure the securable memory area protection */
381 FLASH_OB_SecMemConfig(pOBInit->BootEntryPoint, pOBInit->SecSize, pOBInit->SecSize2);
382 #else
383 /* Configure the securable memory area protection */
384 FLASH_OB_SecMemConfig(pOBInit->BootEntryPoint, pOBInit->SecSize);
385 #endif /* FLASH_DBANK_SUPPORT */
386 }
387 #endif /* FLASH_SECURABLE_MEMORY_SUPPORT */
388
389 /* Wait for last operation to be completed */
390 status = FLASH_WaitForLastOperation(FLASH_TIMEOUT_VALUE);
391
392 if (status == HAL_OK)
393 {
394 /* Set OPTSTRT Bit */
395 SET_BIT(FLASH->CR, FLASH_CR_OPTSTRT);
396
397 /* Wait for last operation to be completed */
398 status = FLASH_WaitForLastOperation(FLASH_TIMEOUT_VALUE);
399
400 /* If the option byte program operation is completed, disable the OPTSTRT Bit */
401 CLEAR_BIT(FLASH->CR, FLASH_CR_OPTSTRT);
402 }
403
404 /* Process Unlocked */
405 __HAL_UNLOCK(&pFlash);
406
407 /* return status */
408 return status;
409 }
410
411 /**
412 * @brief Get the Option bytes configuration.
413 * @note warning: this API only read flash register, it does not reflect any
414 * change that would have been programmed between previous Option byte
415 * loading and current call.
416 * @param pOBInit Pointer to an @ref FLASH_OBProgramInitTypeDef structure that contains the
417 * configuration information. The fields pOBInit->WRPArea should
418 * indicate which area is requested for the WRP.
419 * @retval None
420 */
HAL_FLASHEx_OBGetConfig(FLASH_OBProgramInitTypeDef * pOBInit)421 void HAL_FLASHEx_OBGetConfig(FLASH_OBProgramInitTypeDef *pOBInit)
422 {
423 pOBInit->OptionType = OPTIONBYTE_ALL;
424
425 /* Get write protection on the selected area */
426 FLASH_OB_GetWRP(pOBInit->WRPArea, &(pOBInit->WRPStartOffset), &(pOBInit->WRPEndOffset));
427
428 /* Get Read protection level */
429 pOBInit->RDPLevel = FLASH_OB_GetRDP();
430
431 /* Get the user option bytes */
432 pOBInit->USERConfig = FLASH_OB_GetUser();
433 pOBInit->USERType = OB_USER_ALL;
434
435 #if defined(FLASH_PCROP_SUPPORT)
436 /* Get the Proprietary code readout protection */
437 FLASH_OB_GetPCROP1A(&(pOBInit->PCROPConfig), &(pOBInit->PCROP1AStartAddr), &(pOBInit->PCROP1AEndAddr));
438 FLASH_OB_GetPCROP1B(&(pOBInit->PCROP1BStartAddr), &(pOBInit->PCROP1BEndAddr));
439 pOBInit->PCROPConfig |= (OB_PCROP_ZONE_A | OB_PCROP_ZONE_B);
440 #if defined(FLASH_DBANK_SUPPORT)
441 FLASH_OB_GetPCROP2A(&(pOBInit->PCROP2AStartAddr), &(pOBInit->PCROP2AEndAddr));
442 FLASH_OB_GetPCROP2B(&(pOBInit->PCROP2BStartAddr), &(pOBInit->PCROP2BEndAddr));
443 pOBInit->PCROPConfig |= (OB_PCROP_ZONE2_A | OB_PCROP_ZONE2_B);
444 #endif /* FLASH_DBANK_SUPPORT */
445 #endif /* FLASH_PCROP_SUPPORT */
446
447 #if defined(FLASH_SECURABLE_MEMORY_SUPPORT)
448 #if defined(FLASH_DBANK_SUPPORT)
449 /* Get the Securable Memory Area protection */
450 FLASH_OB_GetSecMem(&(pOBInit->BootEntryPoint), &(pOBInit->SecSize), &(pOBInit->SecSize2));
451 #else
452 /* Get the Securable Memory Area protection */
453 FLASH_OB_GetSecMem(&(pOBInit->BootEntryPoint), &(pOBInit->SecSize));
454 #endif /* FLASH_DBANK_SUPPORT */
455 #endif /* FLASH_SECURABLE_MEMORY_SUPPORT */
456 }
457
458 #if defined(FLASH_ACR_DBG_SWEN)
459 /**
460 * @brief Enable Debugger.
461 * @note After calling this API, flash interface allow debugger intrusion.
462 * @retval None
463 */
HAL_FLASHEx_EnableDebugger(void)464 void HAL_FLASHEx_EnableDebugger(void)
465 {
466 FLASH->ACR |= FLASH_ACR_DBG_SWEN;
467 }
468
469
470 /**
471 * @brief Disable Debugger.
472 * @note After calling this API, Debugger is disabled: it is no more possible to
473 * break, see CPU register, etc...
474 * @retval None
475 */
HAL_FLASHEx_DisableDebugger(void)476 void HAL_FLASHEx_DisableDebugger(void)
477 {
478 FLASH->ACR &= ~FLASH_ACR_DBG_SWEN;
479 }
480 #endif /* FLASH_ACR_DBG_SWEN */
481
482 /**
483 * @brief Flash Empty check
484 * @note This API checks if first location in Flash is programmed or not.
485 * This check is done once by Option Byte Loader.
486 * @retval 0 if 1st location is not programmed else
487 */
HAL_FLASHEx_FlashEmptyCheck(void)488 uint32_t HAL_FLASHEx_FlashEmptyCheck(void)
489 {
490 return ((FLASH->ACR & FLASH_ACR_PROGEMPTY));
491 }
492
493
494 /**
495 * @brief Force Empty check value.
496 * @note Allows to modify program empty check value in order to force this
497 * infrmation in Flash Interface, for all next reset that do not launch
498 * Option Byte Loader.
499 * @param FlashEmpty this parameter can be a value of @ref FLASHEx_Empty_Check
500 * @retval None
501 */
HAL_FLASHEx_ForceFlashEmpty(uint32_t FlashEmpty)502 void HAL_FLASHEx_ForceFlashEmpty(uint32_t FlashEmpty)
503 {
504 uint32_t acr;
505 assert_param(IS_FLASH_EMPTY_CHECK(FlashEmpty));
506
507 acr = (FLASH->ACR & ~FLASH_ACR_PROGEMPTY);
508 FLASH->ACR = (acr | FlashEmpty);
509 }
510
511
512 #if defined(FLASH_SECURABLE_MEMORY_SUPPORT)
513 /**
514 * @brief Securable memory area protection enable
515 * @param Banks Select Bank to be secured.
516 * This parameter can be a value of @ref FLASH_Banks
517 * @note On some devices, there is only 1 bank so parameter has to be set FLASH_BANK_1.
518 * @note This API locks Securable memory area which is defined in SEC_SIZE option byte
519 * (that can be retrieved calling HAL_FLASHEx_OBGetConfig API and checking
520 * Secsize).
521 * @note SEC_PROT bit can only be set, it will be reset by system reset.
522 * @retval None
523 */
HAL_FLASHEx_EnableSecMemProtection(uint32_t Banks)524 void HAL_FLASHEx_EnableSecMemProtection(uint32_t Banks)
525 {
526 #if defined(FLASH_DBANK_SUPPORT)
527 assert_param(IS_FLASH_BANK(Banks));
528
529 if (Banks == (FLASH_BANK_2 | FLASH_BANK_1))
530 {
531 FLASH->CR |= (FLASH_CR_SEC_PROT2 | FLASH_CR_SEC_PROT);
532 }
533 else if (Banks == FLASH_BANK_2)
534 {
535 FLASH->CR |= FLASH_CR_SEC_PROT2;
536 }
537 else
538 #else
539 UNUSED(Banks);
540 #endif /* FLASH_DBANK_SUPPORT */
541 {
542 FLASH->CR |= FLASH_CR_SEC_PROT;
543 }
544 }
545 #endif /* FLASH_SECURABLE_MEMORY_SUPPORT */
546 /**
547 * @}
548 */
549
550 /**
551 * @}
552 */
553
554 /* Private functions ---------------------------------------------------------*/
555 /** @addtogroup FLASHEx_Private_Functions
556 * @{
557 */
558
559 /**
560 * @brief Mass erase of FLASH memory.
561 * @param Banks: Banks to be erased
562 * This parameter can be a combination of the following values:
563 * @arg FLASH_BANK_1: Bank1 to be erased
564 * @arg FLASH_BANK_2: Bank2 to be erased*
565 * @note (*) availability depends on devices
566 * @retval None
567 */
FLASH_MassErase(uint32_t Banks)568 static void FLASH_MassErase(uint32_t Banks)
569 {
570 /* Check the parameters */
571 assert_param(IS_FLASH_BANK(Banks));
572
573 /* Set the Mass Erase Bit and start bit */
574 FLASH->CR |= (FLASH_CR_STRT | Banks);
575 }
576
577 /**
578 * @brief Erase the specified FLASH memory page.
579 * @param Banks: Banks to be erased
580 * This parameter can one of the following values:
581 * @arg FLASH_BANK_1: Bank1 to be erased
582 * @arg FLASH_BANK_2: Bank2 to be erased*
583 * @param Page FLASH page to erase
584 * This parameter must be a value between 0 and (max number of pages in Flash - 1)
585 * @note (*) availability depends on devices
586 * @retval None
587 */
FLASH_PageErase(uint32_t Banks,uint32_t Page)588 void FLASH_PageErase(uint32_t Banks, uint32_t Page)
589 {
590 uint32_t tmp;
591
592 /* Check the parameters */
593 assert_param(IS_FLASH_BANK(Banks));
594 assert_param(IS_FLASH_PAGE(Page));
595
596 /* Get configuration register, then clear page number */
597 tmp = (FLASH->CR & ~FLASH_CR_PNB);
598
599 #if defined(FLASH_DBANK_SUPPORT)
600 /* Check if page has to be erased in bank 1 or 2 */
601 if (Banks != FLASH_BANK_1)
602 {
603 tmp |= FLASH_CR_BKER;
604 }
605 else
606 {
607 tmp &= ~FLASH_CR_BKER;
608 }
609 #endif /* FLASH_DBANK_SUPPORT */
610
611 /* Set page number, Page Erase bit & Start bit */
612 FLASH->CR = (tmp | (FLASH_CR_STRT | (Page << FLASH_CR_PNB_Pos) | FLASH_CR_PER));
613 }
614
615 /**
616 * @brief Flush the instruction cache.
617 * @retval None
618 */
FLASH_FlushCaches(void)619 void FLASH_FlushCaches(void)
620 {
621 /* Flush instruction cache */
622 if (READ_BIT(FLASH->ACR, FLASH_ACR_ICEN) != 0U)
623 {
624 /* Disable instruction cache */
625 __HAL_FLASH_INSTRUCTION_CACHE_DISABLE();
626 /* Reset instruction cache */
627 __HAL_FLASH_INSTRUCTION_CACHE_RESET();
628 /* Enable instruction cache */
629 __HAL_FLASH_INSTRUCTION_CACHE_ENABLE();
630 }
631 }
632
633
634 /**
635 * @brief Configure the write protection of the desired pages.
636 * @note When WRP is active in a zone, it cannot be erased or programmed.
637 * Consequently, a software mass erase cannot be performed if one zone
638 * is write-protected.
639 * @note When the memory read protection level is selected (RDP level = 1),
640 * it is not possible to program or erase Flash memory if the CPU debug
641 * features are connected (JTAG or single wire) or boot code is being
642 * executed from RAM or System flash, even if WRP is not activated.
643 * @param WRPArea Specifies the area to be configured.
644 * This parameter can be one of the following values:
645 * @arg @ref OB_WRPAREA_ZONE_A Flash Zone A
646 * @arg @ref OB_WRPAREA_ZONE_B Flash Zone B
647 * @arg @ref OB_WRPAREA_ZONE2_A Flash Bank 2 Zone A (*)
648 * @arg @ref OB_WRPAREA_ZONE2_B Flash Bank 2 Zone B (*)
649 * @note (*) availability depends on devices
650 * @param WRPStartOffset Specifies the start page of the write protected area
651 * This parameter can be page number between 0 and (max number of pages in the Flash Bank - 1)
652 * @param WRDPEndOffset Specifies the end page of the write protected area
653 * This parameter can be page number between WRPStartOffset and (max number of pages in the Flash Bank - 1)
654 * @retval None
655 */
FLASH_OB_WRPConfig(uint32_t WRPArea,uint32_t WRPStartOffset,uint32_t WRDPEndOffset)656 static void FLASH_OB_WRPConfig(uint32_t WRPArea, uint32_t WRPStartOffset, uint32_t WRDPEndOffset)
657 {
658 /* Check the parameters */
659 assert_param(IS_OB_WRPAREA(WRPArea));
660 assert_param(IS_FLASH_PAGE(WRPStartOffset));
661 assert_param(IS_FLASH_PAGE(WRDPEndOffset));
662
663 /* Configure the write protected area */
664 if (WRPArea == OB_WRPAREA_ZONE_A)
665 {
666 FLASH->WRP1AR = ((WRDPEndOffset << FLASH_WRP1AR_WRP1A_END_Pos) | WRPStartOffset);
667 }
668 #if defined(FLASH_DBANK_SUPPORT)
669 else if (WRPArea == OB_WRPAREA_ZONE2_A)
670 {
671 FLASH->WRP2AR = ((WRDPEndOffset << FLASH_WRP2AR_WRP2A_END_Pos) | WRPStartOffset);
672 }
673 else if (WRPArea == OB_WRPAREA_ZONE2_B)
674 {
675 FLASH->WRP2BR = ((WRDPEndOffset << FLASH_WRP2BR_WRP2B_END_Pos) | WRPStartOffset);
676 }
677 #endif /* FLASH_DBANK_SUPPORT */
678 else
679 {
680 FLASH->WRP1BR = ((WRDPEndOffset << FLASH_WRP1BR_WRP1B_END_Pos) | WRPStartOffset);
681 }
682 }
683
684 /**
685 * @brief Return the FLASH Write Protection Option Bytes value.
686 * @param[in] WRPArea Specifies the area to be returned.
687 * This parameter can be one of the following values:
688 * @arg @ref OB_WRPAREA_ZONE_A Flash Zone A
689 * @arg @ref OB_WRPAREA_ZONE_B Flash Zone B
690 * @arg @ref OB_WRPAREA_ZONE2_A Flash Bank 2 Zone A (*)
691 * @arg @ref OB_WRPAREA_ZONE2_B Flash Bank 2 Zone B (*)
692 * @note (*) availability depends on devices
693 * @param[out] WRPStartOffset Specifies the address where to copied the start page
694 * of the write protected area
695 * @param[out] WRDPEndOffset Dpecifies the address where to copied the end page of
696 * the write protected area
697 * @retval None
698 */
FLASH_OB_GetWRP(uint32_t WRPArea,uint32_t * WRPStartOffset,uint32_t * WRDPEndOffset)699 static void FLASH_OB_GetWRP(uint32_t WRPArea, uint32_t *WRPStartOffset, uint32_t *WRDPEndOffset)
700 {
701 /* Check the parameters */
702 assert_param(IS_OB_WRPAREA(WRPArea));
703
704 /* Get the configuration of the write protected area */
705 if (WRPArea == OB_WRPAREA_ZONE_A)
706 {
707 *WRPStartOffset = READ_BIT(FLASH->WRP1AR, FLASH_WRP1AR_WRP1A_STRT);
708 *WRDPEndOffset = (READ_BIT(FLASH->WRP1AR, FLASH_WRP1AR_WRP1A_END) >> FLASH_WRP1AR_WRP1A_END_Pos);
709 }
710 #if defined(FLASH_DBANK_SUPPORT)
711 else if (WRPArea == OB_WRPAREA_ZONE2_A)
712 {
713 *WRPStartOffset = READ_BIT(FLASH->WRP2AR, FLASH_WRP2AR_WRP2A_STRT);
714 *WRDPEndOffset = (READ_BIT(FLASH->WRP2AR, FLASH_WRP2AR_WRP2A_END) >> FLASH_WRP2AR_WRP2A_END_Pos);
715 }
716 else if (WRPArea == OB_WRPAREA_ZONE2_B)
717 {
718 *WRPStartOffset = READ_BIT(FLASH->WRP2BR, FLASH_WRP2BR_WRP2B_STRT);
719 *WRDPEndOffset = (READ_BIT(FLASH->WRP2BR, FLASH_WRP2BR_WRP2B_END) >> FLASH_WRP2BR_WRP2B_END_Pos);
720 }
721 #endif /* FLASH_DBANK_SUPPORT */
722 else
723 {
724 *WRPStartOffset = READ_BIT(FLASH->WRP1BR, FLASH_WRP1BR_WRP1B_STRT);
725 *WRDPEndOffset = (READ_BIT(FLASH->WRP1BR, FLASH_WRP1BR_WRP1B_END) >> FLASH_WRP1BR_WRP1B_END_Pos);
726 }
727 }
728
729 /**
730 * @brief Set user & RDP configuration
731 * @note !!! Warning : When enabling OB_RDP level 2 it is no more possible
732 * to go back to level 1 or 0 !!!
733 * @param UserType The FLASH User Option Bytes to be modified.
734 * This parameter can be a combination of @ref FLASH_OB_USER_Type
735 * @param UserConfig The FLASH User Option Bytes values.
736 * This parameter can be a combination of:
737 * @arg @ref FLASH_OB_USER_BOR_ENABLE(*)
738 * @arg @ref FLASH_OB_USER_BOR_LEVEL(*)
739 * @arg @ref FLASH_OB_USER_RESET_CONFIG(*)
740 * @arg @ref FLASH_OB_USER_nRST_STOP
741 * @arg @ref FLASH_OB_USER_nRST_STANDBY
742 * @arg @ref FLASH_OB_USER_nRST_SHUTDOWN(*)
743 * @arg @ref FLASH_OB_USER_IWDG_SW
744 * @arg @ref FLASH_OB_USER_IWDG_STOP
745 * @arg @ref FLASH_OB_USER_IWDG_STANDBY
746 * @arg @ref FLASH_OB_USER_WWDG_SW
747 * @arg @ref FLASH_OB_USER_SRAM_PARITY
748 * @arg @ref FLASH_OB_USER_BANK_SWAP(*)
749 * @arg @ref FLASH_OB_USER_DUAL_BANK(*)
750 * @arg @ref FLASH_OB_USER_nBOOT_SEL
751 * @arg @ref FLASH_OB_USER_nBOOT1
752 * @arg @ref FLASH_OB_USER_nBOOT0
753 * @arg @ref FLASH_OB_USER_INPUT_RESET_HOLDER(*)
754 * @param RDPLevel specifies the read protection level.
755 * This parameter can be one of the following values:
756 * @arg @ref OB_RDP_LEVEL_0 No protection
757 * @arg @ref OB_RDP_LEVEL_1 Memory Read protection
758 * @arg @ref OB_RDP_LEVEL_2 Full chip protection
759 * @note (*) availability depends on devices
760 * @retval None
761 */
FLASH_OB_OptrConfig(uint32_t UserType,uint32_t UserConfig,uint32_t RDPLevel)762 static void FLASH_OB_OptrConfig(uint32_t UserType, uint32_t UserConfig, uint32_t RDPLevel)
763 {
764 uint32_t optr;
765
766 /* Check the parameters */
767 assert_param(IS_OB_USER_TYPE(UserType));
768 assert_param(IS_OB_USER_CONFIG(UserType, UserConfig));
769 assert_param(IS_OB_RDP_LEVEL(RDPLevel));
770
771 /* Configure the RDP level in the option bytes register */
772 optr = FLASH->OPTR;
773 optr &= ~(UserType | FLASH_OPTR_RDP);
774 FLASH->OPTR = (optr | UserConfig | RDPLevel);
775 }
776
777 /**
778 * @brief Return the FLASH Read Protection level.
779 * @retval FLASH ReadOut Protection Status:
780 * This return value can be one of the following values:
781 * @arg @ref OB_RDP_LEVEL_0 No protection
782 * @arg @ref OB_RDP_LEVEL_1 Read protection of the memory
783 * @arg @ref OB_RDP_LEVEL_2 Full chip protection
784 */
FLASH_OB_GetRDP(void)785 static uint32_t FLASH_OB_GetRDP(void)
786 {
787 uint32_t rdplvl = READ_BIT(FLASH->OPTR, FLASH_OPTR_RDP);
788
789 if ((rdplvl != OB_RDP_LEVEL_0) && (rdplvl != OB_RDP_LEVEL_2))
790 {
791 return (OB_RDP_LEVEL_1);
792 }
793 else
794 {
795 return rdplvl;
796 }
797 }
798
799 /**
800 * @brief Return the FLASH User Option Byte value.
801 * @retval The FLASH User Option Bytes values. It will be a combination of all the following values:
802 * @arg @ref FLASH_OB_USER_BOR_ENABLE(*)
803 * @arg @ref FLASH_OB_USER_BOR_LEVEL(*)
804 * @arg @ref FLASH_OB_USER_RESET_CONFIG(*)
805 * @arg @ref FLASH_OB_USER_nRST_STOP
806 * @arg @ref FLASH_OB_USER_nRST_STANDBY
807 * @arg @ref FLASH_OB_USER_nRST_SHUTDOWN(*)
808 * @arg @ref FLASH_OB_USER_IWDG_SW
809 * @arg @ref FLASH_OB_USER_IWDG_STOP
810 * @arg @ref FLASH_OB_USER_IWDG_STANDBY
811 * @arg @ref FLASH_OB_USER_WWDG_SW
812 * @arg @ref FLASH_OB_USER_SRAM_PARITY
813 * @arg @ref FLASH_OB_USER_BANK_SWAP(*)
814 * @arg @ref FLASH_OB_USER_DUAL_BANK(*)
815 * @arg @ref FLASH_OB_USER_nBOOT_SEL
816 * @arg @ref FLASH_OB_USER_nBOOT1
817 * @arg @ref FLASH_OB_USER_nBOOT0
818 * @arg @ref FLASH_OB_USER_INPUT_RESET_HOLDER(*)
819 * @note (*) availability depends on devices
820 */
FLASH_OB_GetUser(void)821 static uint32_t FLASH_OB_GetUser(void)
822 {
823 uint32_t user = ((FLASH->OPTR & ~FLASH_OPTR_RDP) & OB_USER_ALL);
824 return user;
825 }
826
827 #if defined(FLASH_PCROP_SUPPORT)
828 /**
829 * @brief Configure the 1A Proprietary code readout protection & erase configuration on RDP regression.
830 * @note It is recommended to align PCROP zone with page granularity when using PCROP_RDP or avoid
831 * having some executable code in a page where PCROP zone starts or ends.
832 * @note Minimum PCROP area size is 2 times the chosen granularity: PCROPA_STRT and PCROPA_END.
833 * So if the requirement is to be able to read-protect 1KB areas, the ROP granularity
834 * has to be set to 512 Bytes
835 * @param PCROPConfig specifies the erase configuration (OB_PCROP_RDP_NOT_ERASE or OB_PCROP_RDP_ERASE)
836 * on RDP level 1 regression.
837 * @param PCROP1AStartAddr Specifies the Zone 1A Start address of the Proprietary code readout protection
838 * This parameter can be an address between begin and end of the flash
839 * @param PCROP1AEndAddr Specifies the Zone 1A end address of the Proprietary code readout protection
840 * This parameter can be an address between PCROP1AStartAddr and end of the flash
841 * @retval None
842 */
FLASH_OB_PCROP1AConfig(uint32_t PCROPConfig,uint32_t PCROP1AStartAddr,uint32_t PCROP1AEndAddr)843 static void FLASH_OB_PCROP1AConfig(uint32_t PCROPConfig, uint32_t PCROP1AStartAddr, uint32_t PCROP1AEndAddr)
844 {
845 uint32_t startoffset;
846 uint32_t endoffset;
847 uint32_t pcrop1aend;
848 uint32_t ropbase;
849
850 /* Check the parameters */
851 assert_param(IS_OB_PCROP_CONFIG(PCROPConfig));
852
853 #if defined(FLASH_DBANK_SUPPORT)
854 /* Check if banks are swapped (valid if only one bank) */
855 if (((FLASH->OPTR & FLASH_OPTR_nSWAP_BANK) != FLASH_OPTR_nSWAP_BANK) && (FLASH_BANK_NB == 2U))
856 {
857 /* Check the parameters */
858 assert_param(IS_FLASH_MAIN_SECONDHALF_MEM_ADDRESS(PCROP1AStartAddr));
859 assert_param(IS_FLASH_MAIN_SECONDHALF_MEM_ADDRESS(PCROP1AEndAddr));
860
861 /* Bank swap, bank 1 read only protection is on second half of Flash */
862 ropbase = (FLASH_BASE + FLASH_BANK_SIZE);
863 }
864 else
865 #endif /* FLASH_DBANK_SUPPORT */
866 {
867 /* Check the parameters */
868 assert_param(IS_FLASH_MAIN_FIRSTHALF_MEM_ADDRESS(PCROP1AStartAddr));
869 assert_param(IS_FLASH_MAIN_FIRSTHALF_MEM_ADDRESS(PCROP1AEndAddr));
870
871 /* No Bank swap, bank 1 read only protection is on first half of Flash */
872 ropbase = FLASH_BASE;
873 }
874
875 /* get pcrop 1A end register */
876 pcrop1aend = FLASH->PCROP1AER;
877
878 /* Configure the Proprietary code readout protection offset */
879 if ((PCROPConfig & OB_PCROP_ZONE_A) != 0x00U)
880 {
881 /* Compute offset depending on pcrop granularity */
882 startoffset = ((PCROP1AStartAddr - ropbase) >> FLASH_PCROP_GRANULARITY_OFFSET);
883 endoffset = ((PCROP1AEndAddr - ropbase) >> FLASH_PCROP_GRANULARITY_OFFSET);
884
885 /* Set Zone A start offset */
886 FLASH->PCROP1ASR = startoffset;
887
888 /* Set Zone A end offset */
889 pcrop1aend &= ~FLASH_PCROP1AER_PCROP1A_END;
890 pcrop1aend |= endoffset;
891 }
892
893 /* Set RDP erase protection if needed. This bit is only set & will be reset by mass erase */
894 if ((PCROPConfig & OB_PCROP_RDP_ERASE) != 0x00U)
895 {
896 pcrop1aend |= FLASH_PCROP1AER_PCROP_RDP;
897 }
898
899 /* set 1A End register */
900 FLASH->PCROP1AER = pcrop1aend;
901 }
902
903 /**
904 * @brief Configure the 1B Proprietary code readout protection.
905 * @note It is recommended to align PCROP zone with page granularity when using PCROP_RDP or avoid
906 * having some executable code in a page where PCROP zone starts or ends.
907 * @note Minimum PCROP area size is 2 times the chosen granularity: PCROPB_STRT and PCROPB_END.
908 * So if the requirement is to be able to read-protect 1KB areas, the ROP granularity
909 * has to be set to 512 Bytes
910 * @param PCROP1BStartAddr Specifies the Zone 1B Start address of the Proprietary code readout protection
911 * This parameter can be an address between begin and end of the flash
912 * @param PCROP1BEndAddr Specifies the Zone 1B end address of the Proprietary code readout protection
913 * This parameter can be an address between PCROP1BStartAddr and end of the flash
914 * @retval None
915 */
FLASH_OB_PCROP1BConfig(uint32_t PCROP1BStartAddr,uint32_t PCROP1BEndAddr)916 static void FLASH_OB_PCROP1BConfig(uint32_t PCROP1BStartAddr, uint32_t PCROP1BEndAddr)
917 {
918 uint32_t startoffset;
919 uint32_t endoffset;
920 uint32_t ropbase;
921
922 #if defined(FLASH_DBANK_SUPPORT)
923 /* Check if banks are swapped (valid if only one bank) */
924 if (((FLASH->OPTR & FLASH_OPTR_nSWAP_BANK) != FLASH_OPTR_nSWAP_BANK) && (FLASH_BANK_NB == 2U))
925 {
926 /* Check the parameters */
927 assert_param(IS_FLASH_MAIN_SECONDHALF_MEM_ADDRESS(PCROP1BStartAddr));
928 assert_param(IS_FLASH_MAIN_SECONDHALF_MEM_ADDRESS(PCROP1BEndAddr));
929
930 /* Bank swap, bank 1 read only protection is on second half of Flash */
931 ropbase = (FLASH_BASE + FLASH_BANK_SIZE);
932 }
933 else
934 #endif /* FLASH_DBANK_SUPPORT */
935 {
936 /* Check the parameters */
937 assert_param(IS_FLASH_MAIN_FIRSTHALF_MEM_ADDRESS(PCROP1BStartAddr));
938 assert_param(IS_FLASH_MAIN_FIRSTHALF_MEM_ADDRESS(PCROP1BEndAddr));
939
940 /* No Bank swap, bank 1 read only protection is on first half of Flash */
941 ropbase = FLASH_BASE;
942 }
943
944 /* Configure the Proprietary code readout protection offset */
945 startoffset = ((PCROP1BStartAddr - ropbase) >> FLASH_PCROP_GRANULARITY_OFFSET);
946 endoffset = ((PCROP1BEndAddr - ropbase) >> FLASH_PCROP_GRANULARITY_OFFSET);
947
948 /* Set Zone B start offset */
949 FLASH->PCROP1BSR = startoffset;
950 /* Set Zone B end offset */
951 FLASH->PCROP1BER = endoffset;
952 }
953
954 /**
955 * @brief Return the FLASH PCROP Protection Option Bytes value.
956 * @param PCROPConfig [out] specifies the configuration of PCROP_RDP option.
957 * @param PCROP1AStartAddr [out] Specifies the address where to copied the start address
958 * of the 1A Proprietary code readout protection
959 * @param PCROP1AEndAddr [out] Specifies the address where to copied the end address of
960 * the 1A Proprietary code readout protection
961 * @retval None
962 */
FLASH_OB_GetPCROP1A(uint32_t * PCROPConfig,uint32_t * PCROP1AStartAddr,uint32_t * PCROP1AEndAddr)963 static void FLASH_OB_GetPCROP1A(uint32_t *PCROPConfig, uint32_t *PCROP1AStartAddr, uint32_t *PCROP1AEndAddr)
964 {
965 uint32_t pcrop;
966 uint32_t ropbase;
967
968 #if defined(FLASH_DBANK_SUPPORT)
969 /* Check if banks are swapped (valid if only one bank) */
970 if (((FLASH->OPTR & FLASH_OPTR_nSWAP_BANK) != FLASH_OPTR_nSWAP_BANK) && (FLASH_BANK_NB == 2U))
971 {
972 /* Bank swap, bank 1 read only protection is on second half of Flash */
973 ropbase = (FLASH_BASE + FLASH_BANK_SIZE);
974 }
975 else
976 #endif /* FLASH_DBANK_SUPPORT */
977 {
978 /* No Bank swap, bank 1 read only protection is on first half of Flash */
979 ropbase = FLASH_BASE;
980 }
981
982 pcrop = (FLASH->PCROP1ASR & FLASH_PCROP1ASR_PCROP1A_STRT);
983 *PCROP1AStartAddr = (pcrop << FLASH_PCROP_GRANULARITY_OFFSET);
984 *PCROP1AStartAddr += ropbase;
985
986 pcrop = FLASH->PCROP1AER;
987 *PCROP1AEndAddr = ((pcrop & FLASH_PCROP1AER_PCROP1A_END) << FLASH_PCROP_GRANULARITY_OFFSET);
988 *PCROP1AEndAddr += (ropbase + FLASH_PCROP_GRANULARITY - 1U);
989
990 *PCROPConfig &= ~OB_PCROP_RDP_ERASE;
991 *PCROPConfig |= (pcrop & FLASH_PCROP1AER_PCROP_RDP);
992 }
993
994 /**
995 * @brief Return the FLASH PCROP Protection Option Bytes value.
996 * @param PCROP1BStartAddr [out] Specifies the address where to copied the start address
997 * of the 1B Proprietary code readout protection
998 * @param PCROP1BEndAddr [out] Specifies the address where to copied the end address of
999 * the 1B Proprietary code readout protection
1000 * @retval None
1001 */
FLASH_OB_GetPCROP1B(uint32_t * PCROP1BStartAddr,uint32_t * PCROP1BEndAddr)1002 static void FLASH_OB_GetPCROP1B(uint32_t *PCROP1BStartAddr, uint32_t *PCROP1BEndAddr)
1003 {
1004 uint32_t pcrop;
1005 uint32_t ropbase;
1006
1007 #if defined(FLASH_DBANK_SUPPORT)
1008 /* Check if banks are swapped (valid if only one bank) */
1009 if (((FLASH->OPTR & FLASH_OPTR_nSWAP_BANK) != FLASH_OPTR_nSWAP_BANK) && (FLASH_BANK_NB == 2U))
1010 {
1011 /* Bank swap, bank 1 read only protection is on second half of Flash */
1012 ropbase = (FLASH_BASE + FLASH_BANK_SIZE);
1013 }
1014 else
1015 #endif /* FLASH_DBANK_SUPPORT */
1016 {
1017 /* No Bank swap, bank 1 read only protection is on first half of Flash */
1018 ropbase = FLASH_BASE;
1019 }
1020
1021 pcrop = (FLASH->PCROP1BSR & FLASH_PCROP1BSR_PCROP1B_STRT);
1022 *PCROP1BStartAddr = (pcrop << FLASH_PCROP_GRANULARITY_OFFSET);
1023 *PCROP1BStartAddr += ropbase;
1024
1025 pcrop = (FLASH->PCROP1BER & FLASH_PCROP1BER_PCROP1B_END);
1026 *PCROP1BEndAddr = (pcrop << FLASH_PCROP_GRANULARITY_OFFSET);
1027 *PCROP1BEndAddr += (ropbase + FLASH_PCROP_GRANULARITY - 1U);
1028 }
1029
1030 #if defined(FLASH_DBANK_SUPPORT)
1031 /**
1032 * @brief Configure the 2A Proprietary code readout protection.
1033 * @note It is recommended to align PCROP zone with page granularity when using PCROP_RDP or avoid
1034 * having some executable code in a page where PCROP zone starts or ends.
1035 * @note Minimum PCROP area size is 2 times the chosen granularity: PCROPA_STRT and PCROPA_END.
1036 * So if the requirement is to be able to read-protect 1KB areas, the ROP granularity
1037 * has to be set to 512 Bytes
1038 * @param PCROP2AStartAddr Specifies the Zone 2A Start address of the Proprietary code readout protection
1039 * This parameter can be an address between begin and end of the flash
1040 * @param PCROP2AEndAddr Specifies the Zone 2A end address of the Proprietary code readout protection
1041 * This parameter can be an address between PCROP2AStartAddr and end of the flash
1042 * @retval None
1043 */
FLASH_OB_PCROP2AConfig(uint32_t PCROP2AStartAddr,uint32_t PCROP2AEndAddr)1044 static void FLASH_OB_PCROP2AConfig(uint32_t PCROP2AStartAddr, uint32_t PCROP2AEndAddr)
1045 {
1046 uint32_t startoffset;
1047 uint32_t endoffset;
1048 uint32_t ropbase;
1049
1050 /* Check if banks are swapped */
1051 if ((FLASH->OPTR & FLASH_OPTR_nSWAP_BANK) != 0x00u)
1052 {
1053 /* Check the parameters */
1054 assert_param(IS_FLASH_MAIN_SECONDHALF_MEM_ADDRESS(PCROP2AStartAddr));
1055 assert_param(IS_FLASH_MAIN_SECONDHALF_MEM_ADDRESS(PCROP2AEndAddr));
1056
1057 /* No Bank swap, bank 2 read only protection is on second half of Flash */
1058 ropbase = (FLASH_BASE + FLASH_BANK_SIZE);
1059 }
1060 else
1061 {
1062 /* Check the parameters */
1063 assert_param(IS_FLASH_MAIN_FIRSTHALF_MEM_ADDRESS(PCROP2AStartAddr));
1064 assert_param(IS_FLASH_MAIN_FIRSTHALF_MEM_ADDRESS(PCROP2AEndAddr));
1065
1066 /* Bank swap, bank 2 read only protection is on first half of Flash */
1067 ropbase = FLASH_BASE;
1068 }
1069
1070 /* Configure the Proprietary code readout protection offset */
1071 startoffset = ((PCROP2AStartAddr - ropbase) >> FLASH_PCROP_GRANULARITY_OFFSET);
1072 endoffset = ((PCROP2AEndAddr - ropbase) >> FLASH_PCROP_GRANULARITY_OFFSET);
1073
1074 /* Set Zone A start offset */
1075 FLASH->PCROP2ASR = startoffset;
1076 /* Set Zone A end offset */
1077 FLASH->PCROP2AER = endoffset;
1078 }
1079
1080 /**
1081 * @brief Configure the 2B Proprietary code readout protection.
1082 * @note It is recommended to align PCROP zone with page granularity when using PCROP_RDP or avoid
1083 * having some executable code in a page where PCROP zone starts or ends.
1084 * @note Minimum PCROP area size is 2 times the chosen granularity: PCROP_STRT and PCROP_END.
1085 * So if the requirement is to be able to read-protect 1KB areas, the ROP granularity
1086 * has to be set to 512 Bytes
1087 * @param PCROP2BStartAddr Specifies the Zone 2B Start address of the Proprietary code readout protection
1088 * This parameter can be an address between begin and end of the flash
1089 * @param PCROP2BEndAddr Specifies the Zone 2B end address of the Proprietary code readout protection
1090 * This parameter can be an address between PCROP2BStartAddr and end of the flash
1091 * @retval None
1092 */
FLASH_OB_PCROP2BConfig(uint32_t PCROP2BStartAddr,uint32_t PCROP2BEndAddr)1093 static void FLASH_OB_PCROP2BConfig(uint32_t PCROP2BStartAddr, uint32_t PCROP2BEndAddr)
1094 {
1095 uint32_t startoffset;
1096 uint32_t endoffset;
1097 uint32_t ropbase;
1098
1099 /* Check if banks are swapped */
1100 if ((FLASH->OPTR & FLASH_OPTR_nSWAP_BANK) != 0x00u)
1101 {
1102 /* Check the parameters */
1103 assert_param(IS_FLASH_MAIN_SECONDHALF_MEM_ADDRESS(PCROP2BStartAddr));
1104 assert_param(IS_FLASH_MAIN_SECONDHALF_MEM_ADDRESS(PCROP2BEndAddr));
1105
1106 /* No Bank swap, bank 2 read only protection is on second half of Flash */
1107 ropbase = (FLASH_BASE + FLASH_BANK_SIZE);
1108 }
1109 else
1110 {
1111 /* Check the parameters */
1112 assert_param(IS_FLASH_MAIN_FIRSTHALF_MEM_ADDRESS(PCROP2BStartAddr));
1113 assert_param(IS_FLASH_MAIN_FIRSTHALF_MEM_ADDRESS(PCROP2BEndAddr));
1114
1115 /* Bank swap, bank 2 read only protection is on first half of Flash */
1116 ropbase = FLASH_BASE;
1117 }
1118
1119 /* Configure the Proprietary code readout protection offset */
1120 startoffset = ((PCROP2BStartAddr - ropbase) >> FLASH_PCROP_GRANULARITY_OFFSET);
1121 endoffset = ((PCROP2BEndAddr - ropbase) >> FLASH_PCROP_GRANULARITY_OFFSET);
1122
1123 /* Set Zone B start offset */
1124 FLASH->PCROP2BSR = startoffset;
1125 /* Set Zone B end offset */
1126 FLASH->PCROP2BER = endoffset;
1127 }
1128
1129 /**
1130 * @brief Return the FLASH PCROP Protection Option Bytes value.
1131 * @param PCROP2AStartAddr [out] Specifies the address where to copied the start address
1132 * of the 2A Proprietary code readout protection
1133 * @param PCROP2AEndAddr [out] Specifies the address where to copied the end address of
1134 * the 2A Proprietary code readout protection
1135 * @retval None
1136 */
FLASH_OB_GetPCROP2A(uint32_t * PCROP2AStartAddr,uint32_t * PCROP2AEndAddr)1137 static void FLASH_OB_GetPCROP2A(uint32_t *PCROP2AStartAddr, uint32_t *PCROP2AEndAddr)
1138 {
1139 uint32_t pcrop;
1140 uint32_t ropbase;
1141
1142 /* Check if banks are swapped */
1143 if ((FLASH->OPTR & FLASH_OPTR_nSWAP_BANK) != 0x00u)
1144 {
1145 /* No Bank swap, bank 2 read only protection is on second half of Flash */
1146 ropbase = (FLASH_BASE + FLASH_BANK_SIZE);
1147 }
1148 else
1149 {
1150 /* Bank swap, bank 2 read only protection is on first half of Flash */
1151 ropbase = FLASH_BASE;
1152 }
1153
1154 pcrop = (FLASH->PCROP2ASR & FLASH_PCROP2ASR_PCROP2A_STRT);
1155 *PCROP2AStartAddr = (pcrop << FLASH_PCROP_GRANULARITY_OFFSET);
1156 *PCROP2AStartAddr += ropbase;
1157
1158 pcrop = (FLASH->PCROP2AER & FLASH_PCROP2AER_PCROP2A_END);
1159 *PCROP2AEndAddr = (pcrop << FLASH_PCROP_GRANULARITY_OFFSET);
1160 *PCROP2AEndAddr += (ropbase + FLASH_PCROP_GRANULARITY - 1U);
1161 }
1162
1163 /**
1164 * @brief Return the FLASH PCROP Protection Option Bytes value.
1165 * @param PCROP2BStartAddr [out] Specifies the address where to copied the start address
1166 * of the 2B Proprietary code readout protection
1167 * @param PCROP2BEndAddr [out] Specifies the address where to copied the end address of
1168 * the 2B Proprietary code readout protection
1169 * @retval None
1170 */
FLASH_OB_GetPCROP2B(uint32_t * PCROP2BStartAddr,uint32_t * PCROP2BEndAddr)1171 static void FLASH_OB_GetPCROP2B(uint32_t *PCROP2BStartAddr, uint32_t *PCROP2BEndAddr)
1172 {
1173 uint32_t pcrop;
1174 uint32_t ropbase;
1175
1176 /* Check if banks are swapped */
1177 if ((FLASH->OPTR & FLASH_OPTR_nSWAP_BANK) != 0x00u)
1178 {
1179 /* No Bank swap, bank 2 read only protection is on second half of Flash */
1180 ropbase = (FLASH_BASE + FLASH_BANK_SIZE);
1181 }
1182 else
1183 {
1184 /* Bank swap, bank 2 read only protection is on first half of Flash */
1185 ropbase = FLASH_BASE;
1186 }
1187
1188 pcrop = (FLASH->PCROP2BSR & FLASH_PCROP2BSR_PCROP2B_STRT);
1189 *PCROP2BStartAddr = (pcrop << FLASH_PCROP_GRANULARITY_OFFSET);
1190 *PCROP2BStartAddr += ropbase;
1191
1192 pcrop = (FLASH->PCROP2BER & FLASH_PCROP2BER_PCROP2B_END);
1193 *PCROP2BEndAddr = (pcrop << FLASH_PCROP_GRANULARITY_OFFSET);
1194 *PCROP2BEndAddr += (ropbase + FLASH_PCROP_GRANULARITY - 1U);
1195 }
1196 #endif /* FLASH_DBANK_SUPPORT */
1197 #endif /* FLASH_PCROP_SUPPORT */
1198
1199 #if defined(FLASH_SECURABLE_MEMORY_SUPPORT)
1200 #if defined(FLASH_DBANK_SUPPORT)
1201 /**
1202 * @brief Configure Securable Memory area feature.
1203 * @param BootEntry specifies if boot scheme is forced to Flash (System or user) or not
1204 * This parameter can be one of the following values:
1205 * @arg @ref OB_BOOT_ENTRY_FORCED_NONE No boot entry forced
1206 * @arg @ref OB_BOOT_ENTRY_FORCED_FLASH Flash selected as unique entry boot
1207 * @param SecSize specifies number of pages to protect as securable memory area, starting from
1208 * beginning of Bank1 (page 0).
1209 * @param SecSize2 specifies number of pages to protect as securable memory area, starting from
1210 * beginning of Bank2 (page 0).
1211 * @retval None
1212 */
FLASH_OB_SecMemConfig(uint32_t BootEntry,uint32_t SecSize,uint32_t SecSize2)1213 static void FLASH_OB_SecMemConfig(uint32_t BootEntry, uint32_t SecSize, uint32_t SecSize2)
1214 {
1215 uint32_t secmem;
1216
1217 /* Check the parameters */
1218 assert_param(IS_OB_SEC_BOOT_LOCK(BootEntry));
1219 assert_param(IS_OB_SEC_SIZE(SecSize));
1220
1221 if ((FLASH_BANK_NB == 2U))
1222 {
1223 assert_param(IS_OB_SEC_SIZE(SecSize2));
1224 }
1225
1226 /* Set securable memory area configuration */
1227 secmem = (FLASH->SECR & ~(FLASH_SECR_BOOT_LOCK | FLASH_SECR_SEC_SIZE | FLASH_SECR_SEC_SIZE2));
1228 FLASH->SECR = (secmem | BootEntry | SecSize | (SecSize2 << FLASH_SECR_SEC_SIZE2_Pos));
1229 }
1230
1231 /**
1232 * @brief Return the FLASH Securable memory area protection Option Bytes value.
1233 * @param BootEntry specifies boot scheme configuration
1234 * @param SecSize specifies number of pages to protect as secure memory area, starting from
1235 * beginning of Bank1 (page 0).
1236 * @param SecSize2 specifies number of pages to protect as secure memory area, starting from
1237 * beginning of Bank2 (page 0).
1238 * @retval None
1239 */
FLASH_OB_GetSecMem(uint32_t * BootEntry,uint32_t * SecSize,uint32_t * SecSize2)1240 static void FLASH_OB_GetSecMem(uint32_t *BootEntry, uint32_t *SecSize, uint32_t *SecSize2)
1241 {
1242 uint32_t secmem = FLASH->SECR;
1243
1244 *BootEntry = (secmem & FLASH_SECR_BOOT_LOCK);
1245 *SecSize = (secmem & FLASH_SECR_SEC_SIZE);
1246 *SecSize2 = (secmem & FLASH_SECR_SEC_SIZE2) >> FLASH_SECR_SEC_SIZE2_Pos;
1247 }
1248
1249 #else
1250 /**
1251 * @brief Configure Securable Memory area feature.
1252 * @param BootEntry specifies if boot scheme is forced to Flash (System or user) or not
1253 * This parameter can be one of the following values:
1254 * @arg @ref OB_BOOT_ENTRY_FORCED_NONE No boot entry forced
1255 * @arg @ref OB_BOOT_ENTRY_FORCED_FLASH FLash selected as unique entry boot
1256 * @param SecSize specifies number of pages to protect as securable memory area, starting from
1257 * beginning of the Flash (page 0).
1258 * @retval None
1259 */
FLASH_OB_SecMemConfig(uint32_t BootEntry,uint32_t SecSize)1260 static void FLASH_OB_SecMemConfig(uint32_t BootEntry, uint32_t SecSize)
1261 {
1262 uint32_t secmem;
1263
1264 /* Check the parameters */
1265 assert_param(IS_OB_SEC_BOOT_LOCK(BootEntry));
1266 assert_param(IS_OB_SEC_SIZE(SecSize));
1267
1268 /* Set securable memory area configuration */
1269 secmem = (FLASH->SECR & ~(FLASH_SECR_BOOT_LOCK | FLASH_SECR_SEC_SIZE));
1270 FLASH->SECR = (secmem | BootEntry | SecSize);
1271 }
1272
1273 /**
1274 * @brief Return the FLASH Securable memory area protection Option Bytes value.
1275 * @param BootEntry specifies boot scheme configuration
1276 * @param SecSize specifies number of pages to protect as secure memory area, starting from
1277 * beginning of the Flash (page 0).
1278 * @retval None
1279 */
FLASH_OB_GetSecMem(uint32_t * BootEntry,uint32_t * SecSize)1280 static void FLASH_OB_GetSecMem(uint32_t *BootEntry, uint32_t *SecSize)
1281 {
1282 uint32_t secmem = FLASH->SECR;
1283
1284 *BootEntry = (secmem & FLASH_SECR_BOOT_LOCK);
1285 *SecSize = (secmem & FLASH_SECR_SEC_SIZE);
1286 }
1287 #endif /* FLASH_DBANK_SUPPORT */
1288 #endif /* FLASH_SECURABLE_MEMORY_SUPPORT */
1289
1290 /**
1291 * @}
1292 */
1293
1294 /**
1295 * @}
1296 */
1297
1298 #endif /* HAL_FLASH_MODULE_ENABLED */
1299
1300 /**
1301 * @}
1302 */
1303
1304 /**
1305 * @}
1306 */
1307
1308