1 /**
2   ******************************************************************************
3   * @file    stm32u0xx_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 STM32U0xx
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        (+) Write protection
21        (+) Single bank memory organization
22        (+) Hide Protection areas
23 
24                         ##### How to use this driver #####
25  ==============================================================================
26   [..] This driver provides functions to configure and program the FLASH memory
27        of all STM32U0xx devices. It includes
28       (#) Flash Memory Erase functions:
29            (++) Lock and Unlock the FLASH interface using HAL_FLASH_Unlock() and
30                 HAL_FLASH_Lock() functions
31            (++) Erase function: Erase page, erase all sectors
32            (++) There are two modes of erase :
33              (+++) Polling Mode using HAL_FLASHEx_Erase()
34              (+++) Interrupt Mode using HAL_FLASHEx_Erase_IT()
35 
36       (#) Option Bytes Programming function: Use HAL_FLASHEx_OBProgram() to :
37         (++) Set/Reset the write protection
38         (++) Set the Read protection Level
39         (++) Program the user Option Bytes
40         (++) Set boot lock
41         (++) Configure the Hide protection areas
42 
43       (#) Get Option Bytes Configuration function: Use HAL_FLASHEx_OBGetConfig() to :
44         (++) Get the value of a write protection area
45         (++) Know if the read protection is activated
46         (++) Get the value of the user Option Bytes
47         (++) Get the boot lock information
48         (++) Get the configuration of Hide protection areas
49 
50       (#) Enable or disable debugger usage using HAL_FLASHEx_EnableDebugger and
51           HAL_FLASHEx_DisableDebugger.
52 
53       (#) Check is flash content is empty or not using HAL_FLASHEx_FlashEmptyCheck.
54           and modify this setting (for flash loader purpose e.g.) using
55           HAL_FLASHEx_ForceFlashEmpty.
56 
57       (#) Enable HDP area protection using HAL_FLASHEx_EnableHDPProtection
58 
59  @endverbatim
60   ******************************************************************************
61   * @attention
62   *
63   * Copyright (c) 2023 STMicroelectronics.
64   * All rights reserved.
65   *
66   * This software is licensed under terms that can be found in the LICENSE file
67   * in the root directory of this software component.
68   * If no LICENSE file comes with this software, it is provided AS-IS.
69   *
70   ******************************************************************************
71   */
72 
73 /* Includes ------------------------------------------------------------------*/
74 #include "stm32u0xx_hal.h"
75 
76 /** @addtogroup STM32U0xx_HAL_Driver
77   * @{
78   */
79 
80 /** @defgroup FLASHEx FLASHEx
81   * @brief FLASH Extended HAL module driver
82   * @{
83   */
84 
85 #ifdef HAL_FLASH_MODULE_ENABLED
86 
87 /* Private typedef -----------------------------------------------------------*/
88 /* Private define ------------------------------------------------------------*/
89 /* Private macro -------------------------------------------------------------*/
90 /* Private variables ---------------------------------------------------------*/
91 /* Private function prototypes -----------------------------------------------*/
92 /** @defgroup FLASHEx_Private_Functions FLASHEx Private Functions
93   * @{
94   */
95 static void               FLASH_MassErase(void);
96 static void               FLASH_OB_WRPConfig(uint32_t WRPArea, uint32_t WRPStartOffset, uint32_t WRDPEndOffset);
97 static void               FLASH_OB_GetWRP(uint32_t WRPArea, uint32_t *WRPStartOffset, uint32_t *WRDPEndOffset);
98 static void               FLASH_OB_OptrConfig(uint32_t UserType, uint32_t UserConfig, uint32_t RDPLevel);
99 static uint32_t           FLASH_OB_GetRDP(void);
100 static uint32_t           FLASH_OB_GetUser(void);
101 void                      FLASH_OB_GetOEMKeyCRC(uint32_t *OEM1KeyCRC, uint32_t *OEM2KEYCRC);
102 static void               FLASH_OB_HDPConfig(uint32_t BootEntry, uint32_t HDPEndPage, uint32_t HDPEn);
103 static void               FLASH_OB_GetHDPConfig(uint32_t *BootEntry, uint32_t *HDPEndPage, uint32_t *HDPEn);
104 static void               FLASH_OB_RDPKeyConfig(uint32_t RDPKeyType, uint32_t RDPKey0, uint32_t RDPKey1,
105                                                 uint32_t RDPKey2, uint32_t RDPKey3);
106 
107 /**
108   * @}
109   */
110 
111 /* Exported functions -------------------------------------------------------*/
112 /** @defgroup FLASHEx_Exported_Functions FLASH Extended Exported Functions
113   * @{
114   */
115 
116 /** @defgroup FLASHEx_Exported_Functions_Group1 Extended IO operation functions
117   *  @brief   Extended IO operation functions
118   *
119 @verbatim
120  ===============================================================================
121                 ##### Extended programming operation functions #####
122  ===============================================================================
123     [..]
124     This subsection provides a set of functions allowing to manage the Extended FLASH
125     programming operations Operations.
126 
127 @endverbatim
128   * @{
129   */
130 /**
131   * @brief  Perform a mass erase or erase the specified FLASH memory pages.
132   * @param[in]  pEraseInit Pointer to an @ref FLASH_EraseInitTypeDef structure that
133   *         contains the configuration information for the erasing.
134   * @param[out]  PageError Pointer to variable that contains the configuration
135   *         information on faulty page in case of error (0xFFFFFFFF means that all
136   *         the pages have been correctly erased)
137   * @retval HAL Status
138   */
HAL_FLASHEx_Erase(FLASH_EraseInitTypeDef * pEraseInit,uint32_t * PageError)139 HAL_StatusTypeDef HAL_FLASHEx_Erase(FLASH_EraseInitTypeDef *pEraseInit, uint32_t *PageError)
140 {
141   HAL_StatusTypeDef status;
142   uint32_t index;
143 
144   /* Check the parameters */
145   assert_param(IS_FLASH_TYPEERASE(pEraseInit->TypeErase));
146 
147   /* Process Locked */
148   __HAL_LOCK(&pFlash);
149 
150   /* Reset error code */
151   pFlash.ErrorCode = HAL_FLASH_ERROR_NONE;
152 
153   /* Wait for last operation to be completed */
154   status = FLASH_WaitForLastOperation(FLASH_TIMEOUT_VALUE);
155 
156   if (status == HAL_OK)
157   {
158     /* For single bank product force Banks to Bank 1 */
159     pEraseInit->Banks = FLASH_BANK_1;
160     if (pEraseInit->TypeErase == FLASH_TYPEERASE_MASS)
161     {
162       /* Proceed to Mass Erase */
163       FLASH_MassErase();
164 
165       /* Wait for last operation to be completed */
166       status = FLASH_WaitForLastOperation(FLASH_TIMEOUT_VALUE);
167     }
168     else
169     {
170       /*Initialization of PageError variable*/
171       *PageError = 0xFFFFFFFFU;
172 
173       for (index = pEraseInit->Page; index < (pEraseInit->Page + pEraseInit->NbPages); index++)
174       {
175         /* Start erase page */
176         FLASH_PageErase(index);
177 
178         /* Wait for last operation to be completed */
179         status = FLASH_WaitForLastOperation(FLASH_TIMEOUT_VALUE);
180 
181         if (status != HAL_OK)
182         {
183           /* In case of error, stop erase procedure and return the faulty address */
184           *PageError = index;
185           break;
186         }
187       }
188 
189       /* If operation is completed or interrupted, disable the Page Erase Bit */
190       CLEAR_BIT(FLASH->CR, FLASH_CR_PER);
191     }
192   }
193 
194   /* Process Unlocked */
195   __HAL_UNLOCK(&pFlash);
196 
197   /* return status */
198   return status;
199 }
200 
201 
202 /**
203   * @brief  Perform a mass erase or erase the specified FLASH memory pages with interrupt enabled.
204   * @param  pEraseInit Pointer to an @ref FLASH_EraseInitTypeDef structure that
205   *         contains the configuration information for the erasing.
206   * @retval HAL Status
207   */
HAL_FLASHEx_Erase_IT(FLASH_EraseInitTypeDef * pEraseInit)208 HAL_StatusTypeDef HAL_FLASHEx_Erase_IT(FLASH_EraseInitTypeDef *pEraseInit)
209 {
210   HAL_StatusTypeDef status;
211 
212   /* Check the parameters */
213   assert_param(IS_FLASH_TYPEERASE(pEraseInit->TypeErase));
214 
215   /* Process Locked */
216   __HAL_LOCK(&pFlash);
217 
218   /* Reset error code */
219   pFlash.ErrorCode = HAL_FLASH_ERROR_NONE;
220 
221   /* save procedure for interrupt treatment */
222   pFlash.ProcedureOnGoing = pEraseInit->TypeErase;
223 
224   /* Wait for last operation to be completed */
225   status = FLASH_WaitForLastOperation(FLASH_TIMEOUT_VALUE);
226 
227   if (status != HAL_OK)
228   {
229     /* Process Unlocked */
230     __HAL_UNLOCK(&pFlash);
231   }
232   else
233   {
234     /* For single bank product force Banks to Bank 1 */
235     pEraseInit->Banks = FLASH_BANK_1;
236     /* Store Bank number */
237     pFlash.Banks = pEraseInit->Banks;
238 
239     /* Enable End of Operation and Error interrupts */
240     FLASH->CR |= FLASH_CR_EOPIE | FLASH_CR_ERRIE;
241 
242     if (pEraseInit->TypeErase == FLASH_TYPEERASE_MASS)
243     {
244       /* Set Page to 0 for Interrupt callback management */
245       pFlash.Page = 0;
246 
247       /* Proceed to Mass Erase */
248       FLASH_MassErase();
249     }
250     else
251     {
252       /* Erase by page to be done */
253       pFlash.NbPagesToErase = pEraseInit->NbPages;
254       pFlash.Page = pEraseInit->Page;
255 
256       /*Erase 1st page and wait for IT */
257       FLASH_PageErase(pEraseInit->Page);
258     }
259   }
260 
261   /* return status */
262   return status;
263 }
264 
265 /**
266   * @brief  Program Option bytes.
267   * @param  pOBInit Pointer to an @ref FLASH_OBProgramInitTypeDef structure that
268   *         contains the configuration information for the programming.
269   * @note   To configure any option bytes, the option lock bit OPTLOCK must be
270   *         cleared with the call of @ref HAL_FLASH_OB_Unlock() function.
271   * @note   New option bytes configuration will be taken into account only
272   *         - after an option bytes launch through the call of @ref HAL_FLASH_OB_Launch()
273   *         - a Power On Reset
274   *         - an exit from Standby or Shutdown mode.
275   * @retval HAL Status
276   */
HAL_FLASHEx_OBProgram(FLASH_OBProgramInitTypeDef * pOBInit)277 HAL_StatusTypeDef HAL_FLASHEx_OBProgram(FLASH_OBProgramInitTypeDef *pOBInit)
278 {
279   uint32_t optr;
280   HAL_StatusTypeDef status;
281 
282   /* Check the parameters */
283   assert_param(IS_OPTIONBYTE(pOBInit->OptionType));
284 
285   /* Process Locked */
286   __HAL_LOCK(&pFlash);
287 
288   pFlash.ErrorCode = HAL_FLASH_ERROR_NONE;
289 
290   /* Write protection configuration */
291   if ((pOBInit->OptionType & OPTIONBYTE_WRP) != 0x00U)
292   {
293     /* Configure of Write protection on the selected area */
294     FLASH_OB_WRPConfig(pOBInit->WRPArea, pOBInit->WRPStartOffset, pOBInit->WRPEndOffset);
295   }
296 
297   /* Option register */
298   if ((pOBInit->OptionType & (OPTIONBYTE_RDP | OPTIONBYTE_USER)) == (OPTIONBYTE_RDP | OPTIONBYTE_USER))
299   {
300     /* Fully modify OPTR register with RDP & user data */
301     FLASH_OB_OptrConfig(pOBInit->USERType, pOBInit->USERConfig, pOBInit->RDPLevel);
302   }
303   else if ((pOBInit->OptionType & OPTIONBYTE_RDP) != 0x00U)
304   {
305     /* Only modify RDP so get current user data */
306     optr = FLASH_OB_GetUser();
307     FLASH_OB_OptrConfig(optr, optr, pOBInit->RDPLevel);
308   }
309   else if ((pOBInit->OptionType & OPTIONBYTE_USER) != 0x00U)
310   {
311     /* Only modify user so get current RDP level */
312     optr = FLASH_OB_GetRDP();
313     FLASH_OB_OptrConfig(pOBInit->USERType, pOBInit->USERConfig, optr);
314   }
315   else
316   {
317     /* nothing to do */
318   }
319 
320   /* HDP Area Configuration */
321   if ((pOBInit->OptionType & OPTIONBYTE_HDP) != 0x00U)
322   {
323     /* Configure the HDP area protection */
324     FLASH_OB_HDPConfig(pOBInit->BootLock, pOBInit->HDPEndPage, pOBInit->HDPState);
325   }
326 
327   /* RDP Keys OEM1/2 Configuration */
328   if ((pOBInit->OptionType & OPTIONBYTE_RDPKEY) != 0x00U)
329   {
330     /* Configure the RDP keys */
331     FLASH_OB_RDPKeyConfig(pOBInit->RDPKeyType, pOBInit->RDPKey1, pOBInit->RDPKey2, pOBInit->RDPKey3, pOBInit->RDPKey4);
332   }
333 
334   /* Wait for last operation to be completed */
335   status = FLASH_WaitForLastOperation(FLASH_TIMEOUT_VALUE);
336 
337   if (status == HAL_OK)
338   {
339     /* Set OPTSTRT Bit */
340     SET_BIT(FLASH->CR, FLASH_CR_OPTSTRT);
341 
342     /* Wait for last operation to be completed */
343     status = FLASH_WaitForLastOperation(FLASH_TIMEOUT_VALUE);
344 
345     /* If the option byte program operation is completed, disable the OPTSTRT Bit */
346     CLEAR_BIT(FLASH->CR, FLASH_CR_OPTSTRT);
347   }
348 
349   /* Process Unlocked */
350   __HAL_UNLOCK(&pFlash);
351 
352   /* return status */
353   return status;
354 }
355 
356 /**
357   * @brief  Get the Option bytes configuration.
358   * @note   warning: this API only read flash register, it does not reflect any
359   *         change that would have been programmed between previous Option byte
360   *         loading and current call.
361   * @param  pOBInit Pointer to an @ref FLASH_OBProgramInitTypeDef structure that contains the
362   *                  configuration information. The fields pOBInit->WRPArea should
363   *                  indicate which area is requested for the WRP.
364   * @retval None
365   */
HAL_FLASHEx_OBGetConfig(FLASH_OBProgramInitTypeDef * pOBInit)366 void HAL_FLASHEx_OBGetConfig(FLASH_OBProgramInitTypeDef *pOBInit)
367 {
368   pOBInit->OptionType = OPTIONBYTE_ALL;
369 
370   /* Get write protection on the selected area */
371   FLASH_OB_GetWRP(pOBInit->WRPArea, &(pOBInit->WRPStartOffset), &(pOBInit->WRPEndOffset));
372 
373   /* Get Read protection level */
374   pOBInit->RDPLevel = FLASH_OB_GetRDP();
375 
376   /* Get the user option bytes */
377   pOBInit->USERConfig = FLASH_OB_GetUser();
378   pOBInit->USERType = OB_USER_ALL;
379 
380   /* Get the Securable Memory Area protection */
381   FLASH_OB_GetHDPConfig(&(pOBInit->BootLock), &(pOBInit->HDPEndPage), &(pOBInit->HDPState));
382 }
383 
384 /**
385   * @brief  Enable Debugger.
386   * @note   After calling this API, flash interface allow debugger intrusion.
387   * @retval None
388   */
HAL_FLASHEx_EnableDebugger(void)389 void HAL_FLASHEx_EnableDebugger(void)
390 {
391   FLASH->ACR |= FLASH_ACR_DBG_SWEN;
392 }
393 
394 
395 /**
396   * @brief  Disable Debugger.
397   * @note   After calling this API, Debugger is disabled: it is no more possible to
398   *         break, see CPU register, etc...
399   * @retval None
400   */
HAL_FLASHEx_DisableDebugger(void)401 void HAL_FLASHEx_DisableDebugger(void)
402 {
403   FLASH->ACR &= ~FLASH_ACR_DBG_SWEN;
404 }
405 
406 /**
407   * @brief  Flash Empty check
408   * @note   This API checks if first location in Flash is programmed or not.
409   *         This check is done once by Option Byte Loader.
410   * @retval 0 if 1st location is not programmed else
411   */
HAL_FLASHEx_FlashEmptyCheck(void)412 uint32_t HAL_FLASHEx_FlashEmptyCheck(void)
413 {
414   return ((FLASH->ACR & FLASH_ACR_EMPTY));
415 }
416 
417 
418 /**
419   * @brief  Force Empty check value.
420   * @note   Allows to modify program empty check value in order to force this
421   *         infrmation in Flash Interface, for all next reset that do not launch
422   *         Option Byte Loader.
423   * @param  FlashEmpty this parameter can be a value of @ref FLASHEx_Empty_Check
424   * @retval None
425   */
HAL_FLASHEx_ForceFlashEmpty(uint32_t FlashEmpty)426 void HAL_FLASHEx_ForceFlashEmpty(uint32_t FlashEmpty)
427 {
428   uint32_t acr;
429   assert_param(IS_FLASH_EMPTY_CHECK(FlashEmpty));
430 
431   acr = (FLASH->ACR & ~FLASH_ACR_EMPTY);
432   FLASH->ACR = (acr | FlashEmpty);
433 }
434 
435 /**
436   * @}
437   */
438 
439 /**
440   * @}
441   */
442 
443 /* Private functions ---------------------------------------------------------*/
444 /** @addtogroup FLASHEx_Private_Functions
445   * @{
446   */
447 
448 /**
449   * @brief  Mass erase of FLASH memory.
450   * @retval None
451   */
FLASH_MassErase(void)452 static void FLASH_MassErase(void)
453 {
454   /* Set the Mass Erase Bit and start bit */
455   SET_BIT(FLASH->CR, (FLASH_CR_STRT | FLASH_CR_MER1));
456 }
457 
458 /**
459   * @brief  Erase the specified FLASH memory page.
460   * @param  Page FLASH page to erase
461   *         This parameter must be a value between 0 and (max number of pages in Flash - 1)
462   * @retval None
463   */
FLASH_PageErase(uint32_t Page)464 void FLASH_PageErase(uint32_t Page)
465 {
466   uint32_t tmp;
467 
468   /* Check the parameters */
469   assert_param(IS_FLASH_BANK(FLASH_BANK_1));
470   assert_param(IS_FLASH_PAGE(Page));
471 
472   /* Get configuration register, then clear page number */
473   tmp = (FLASH->CR & ~FLASH_CR_PNB);
474 
475   /* Set page number, Page Erase bit & Start bit */
476   FLASH->CR = (tmp | (FLASH_CR_STRT | (Page <<  FLASH_CR_PNB_Pos) | FLASH_CR_PER));
477 }
478 
479 /**
480   * @brief  Flush the instruction cache.
481   * @retval None
482   */
FLASH_FlushCaches(void)483 void FLASH_FlushCaches(void)
484 {
485   /* Flush instruction cache  */
486   if (READ_BIT(FLASH->ACR, FLASH_ACR_ICEN) != 0U)
487   {
488     /* Disable instruction cache */
489     __HAL_FLASH_INSTRUCTION_CACHE_DISABLE();
490     /* Reset instruction cache */
491     __HAL_FLASH_INSTRUCTION_CACHE_RESET();
492     /* Enable instruction cache */
493     __HAL_FLASH_INSTRUCTION_CACHE_ENABLE();
494   }
495 }
496 
497 
498 /**
499   * @brief  Configure the write protection of the desired pages.
500   * @note   When WRP is active in a zone, it cannot be erased or programmed.
501   *         Consequently, a software mass erase cannot be performed if one zone
502   *         is write-protected.
503   * @note   When the memory read protection level is selected (RDP level = 1),
504   *         it is not possible to program or erase Flash memory if the CPU debug
505   *         features are connected (JTAG or single wire) or boot code is being
506   *         executed from RAM or System flash, even if WRP is not activated.
507   * @param  WRPArea  Specifies the area to be configured.
508   *         This parameter can be one of the following values:
509   *           @arg @ref OB_WRPAREA_ZONE_A Flash Zone A
510   *           @arg @ref OB_WRPAREA_ZONE_B Flash Zone B
511   * @param  WRPStartOffset  Specifies the start page of the write protected area
512   *         This parameter can be page number between 0 and (max number of pages in the Flash Bank - 1)
513   * @param  WRDPEndOffset  Specifies the end page of the write protected area
514   *         This parameter can be page number between WRPStartOffset and (max number of pages in the Flash Bank - 1)
515   * @retval None
516   */
FLASH_OB_WRPConfig(uint32_t WRPArea,uint32_t WRPStartOffset,uint32_t WRDPEndOffset)517 static void FLASH_OB_WRPConfig(uint32_t WRPArea, uint32_t WRPStartOffset, uint32_t WRDPEndOffset)
518 {
519   /* Check the parameters */
520   assert_param(IS_OB_WRPAREA(WRPArea));
521   assert_param(IS_FLASH_PAGE(WRPStartOffset));
522   assert_param(IS_FLASH_PAGE(WRDPEndOffset));
523 
524   /* Configure the write protected area */
525   if (WRPArea == OB_WRPAREA_ZONE_A)
526   {
527     FLASH->WRP1AR = ((WRDPEndOffset << FLASH_WRP1AR_WRP1A_END_Pos) | WRPStartOffset);
528   }
529   else
530   {
531     FLASH->WRP1BR = ((WRDPEndOffset << FLASH_WRP1BR_WRP1B_END_Pos) | WRPStartOffset);
532   }
533 }
534 
535 /**
536   * @brief  Return the FLASH Write Protection Option Bytes value.
537   * @param[in]  WRPArea Specifies the area to be returned.
538   *             This parameter can be one of the following values:
539   *               @arg @ref OB_WRPAREA_ZONE_A Flash Zone A
540   *               @arg @ref OB_WRPAREA_ZONE_B Flash Zone B
541   * @param[out]  WRPStartOffset  Specifies the address where to copied the start page
542   *                         of the write protected area
543   * @param[out]  WRDPEndOffset  Dpecifies the address where to copied the end page of
544   *                        the write protected area
545   * @retval None
546   */
FLASH_OB_GetWRP(uint32_t WRPArea,uint32_t * WRPStartOffset,uint32_t * WRDPEndOffset)547 static void FLASH_OB_GetWRP(uint32_t WRPArea, uint32_t *WRPStartOffset, uint32_t *WRDPEndOffset)
548 {
549 
550   /* Get the configuration of the write protected area */
551   if (WRPArea == OB_WRPAREA_ZONE_A)
552   {
553     *WRPStartOffset = READ_BIT(FLASH->WRP1AR, FLASH_WRP1AR_WRP1A_STRT);
554     *WRDPEndOffset = (READ_BIT(FLASH->WRP1AR, FLASH_WRP1AR_WRP1A_END) >> FLASH_WRP1AR_WRP1A_END_Pos);
555   }
556   else if (WRPArea == OB_WRPAREA_ZONE_B)
557   {
558     *WRPStartOffset = READ_BIT(FLASH->WRP1BR, FLASH_WRP1BR_WRP1B_STRT);
559     *WRDPEndOffset = (READ_BIT(FLASH->WRP1BR, FLASH_WRP1BR_WRP1B_END) >> FLASH_WRP1BR_WRP1B_END_Pos);
560   }
561   else
562   {
563     /* Empty statement (to be compliant MISRA 15.7) */
564   }
565 }
566 
567 /**
568   * @brief  Set user & RDP configuration
569   * @note   !!! Warning : When enabling OB_RDP level 2 it is no more possible
570   *         to go back to level 1 or 0 !!!
571   * @param  UserType  The FLASH User Option Bytes to be modified.
572   *         This parameter can be a combination of @ref FLASH_OB_USER_Type
573   * @param  UserConfig  The FLASH User Option Bytes values.
574   *         This parameter can be a combination of:
575   *           @arg @ref FLASH_OB_USER_BOR_ENABLE
576   *           @arg @ref FLASH_OB_USER_BOR_LEVEL
577   *           @arg @ref FLASH_OB_USER_RESET_CONFIG
578   *           @arg @ref FLASH_OB_USER_NRST_STOP
579   *           @arg @ref FLASH_OB_USER_NRST_STANDBY
580   *           @arg @ref FLASH_OB_USER_NRST_SHUTDOWN
581   *           @arg @ref FLASH_OB_USER_IWDG_SW
582   *           @arg @ref FLASH_OB_USER_IWDG_STOP
583   *           @arg @ref FLASH_OB_USER_IWDG_STANDBY
584   *           @arg @ref FLASH_OB_USER_WWDG_SW
585   *           @arg @ref FLASH_OB_USER_SRAM_PARITY
586   *           @arg @ref FLASH_OB_USER_NBOOT_SEL
587   *           @arg @ref FLASH_OB_USER_NBOOT1
588   *           @arg @ref FLASH_OB_USER_NBOOT0
589   *           @arg @ref FLASH_OB_USER_INPUT_RESET_HOLDER
590   * @param  RDPLevel  specifies the read protection level.
591   *         This parameter can be one of the following values:
592   *           @arg @ref OB_RDP_LEVEL_0 No protection
593   *           @arg @ref OB_RDP_LEVEL_1 Memory Read protection
594   *           @arg @ref OB_RDP_LEVEL_2 Full chip protection
595   * @retval None
596   */
FLASH_OB_OptrConfig(uint32_t UserType,uint32_t UserConfig,uint32_t RDPLevel)597 static void FLASH_OB_OptrConfig(uint32_t UserType, uint32_t UserConfig, uint32_t RDPLevel)
598 {
599   uint32_t optr;
600 
601   /* Check the parameters */
602   assert_param(IS_OB_USER_TYPE(UserType));
603   assert_param(IS_OB_USER_CONFIG(UserType, UserConfig));
604   assert_param(IS_OB_RDP_LEVEL(RDPLevel));
605 
606   /* Configure the RDP level in the option bytes register */
607   optr = FLASH->OPTR;
608   optr &= ~(UserType | FLASH_OPTR_RDP);
609   FLASH->OPTR = (optr | UserConfig | RDPLevel);
610 }
611 
612 /**
613   * @brief  Return the FLASH Read Protection level.
614   * @retval FLASH ReadOut Protection Status:
615   *         This return value can be one of the following values:
616   *           @arg @ref OB_RDP_LEVEL_0 No protection
617   *           @arg @ref OB_RDP_LEVEL_1 Read protection of the memory
618   *           @arg @ref OB_RDP_LEVEL_2 Full chip protection
619   */
FLASH_OB_GetRDP(void)620 static uint32_t FLASH_OB_GetRDP(void)
621 {
622   uint32_t rdplvl = READ_BIT(FLASH->OPTR, FLASH_OPTR_RDP);
623 
624   if ((rdplvl != OB_RDP_LEVEL_0) && (rdplvl != OB_RDP_LEVEL_2))
625   {
626     return (OB_RDP_LEVEL_1);
627   }
628   else
629   {
630     return rdplvl;
631   }
632 }
633 
634 /**
635   * @brief  Return the FLASH User Option Byte value.
636   * @retval The FLASH User Option Bytes values. It will be a combination of all the following values:
637   *           @arg @ref FLASH_OB_USER_BOR_ENABLE
638   *           @arg @ref FLASH_OB_USER_BOR_LEVEL
639   *           @arg @ref FLASH_OB_USER_RESET_CONFIG
640   *           @arg @ref FLASH_OB_USER_NRST_STOP
641   *           @arg @ref FLASH_OB_USER_NRST_STANDBY
642   *           @arg @ref FLASH_OB_USER_NRST_SHUTDOWN
643   *           @arg @ref FLASH_OB_USER_IWDG_SW
644   *           @arg @ref FLASH_OB_USER_IWDG_STOP
645   *           @arg @ref FLASH_OB_USER_IWDG_STANDBY
646   *           @arg @ref FLASH_OB_USER_WWDG_SW
647   *           @arg @ref FLASH_OB_USER_SRAM_PARITY
648   *           @arg @ref FLASH_OB_USER_NBOOT_SEL
649   *           @arg @ref FLASH_OB_USER_NBOOT1
650   *           @arg @ref FLASH_OB_USER_NBOOT0
651   *           @arg @ref FLASH_OB_USER_INPUT_RESET_HOLDER
652   */
FLASH_OB_GetUser(void)653 static uint32_t FLASH_OB_GetUser(void)
654 {
655   uint32_t user = ((FLASH->OPTR & ~FLASH_OPTR_RDP) & OB_USER_ALL);
656   return user;
657 }
658 
659 /**
660   * @brief  Configure the HDP memory register.
661   * @param   BootEntry  specifies if boot scheme is forced to Flash (System or user) or not
662   *          This parameter can be one of the following values:
663   *           @arg @ref OB_BOOT_LOCK_DISABLE No boot entry
664   *           @arg @ref OB_BOOT_LOCK_ENABLE Flash selected as unique entry boot
665   * @param   HDPEndPage specifies the end page of the hide protection area
666   * @param   HDPEn     Enable and disable the HDP area
667   * @retval None
668   */
FLASH_OB_HDPConfig(uint32_t BootEntry,uint32_t HDPEndPage,uint32_t HDPEn)669 static void FLASH_OB_HDPConfig(uint32_t BootEntry, uint32_t HDPEndPage, uint32_t HDPEn)
670 {
671   uint32_t secmem;
672 
673   /* Check the parameters */
674   assert_param(IS_OB_BOOT_LOCK(BootEntry));
675   assert_param(IS_FLASH_PAGE(HDPEndPage));
676   /* Set securable memory area configuration */
677   secmem = (FLASH->SECR & ~(FLASH_SECR_BOOT_LOCK | FLASH_SECR_HDP1_PEND | FLASH_SECR_HDP1EN));
678   FLASH->SECR = (secmem | BootEntry | HDPEndPage | (HDPEn << FLASH_SECR_HDP1EN_Pos));
679 }
680 
681 /**
682   * @brief   Return the HDP memory register configuration.
683   * @param   BootEntry  specifies if boot scheme configuration.
684   * @param   HDPEndPage specifies the end page of the hide protection area
685   * @param   HDPEn      specifies the status of the hide protection area (Enabled(other) or disabled(0xB4))
686   * @retval None
687   */
FLASH_OB_GetHDPConfig(uint32_t * BootEntry,uint32_t * HDPEndPage,uint32_t * HDPEn)688 static void FLASH_OB_GetHDPConfig(uint32_t *BootEntry, uint32_t *HDPEndPage, uint32_t *HDPEn)
689 {
690   uint32_t secmem = FLASH->SECR;
691 
692   *BootEntry = (secmem & FLASH_SECR_BOOT_LOCK);
693   *HDPEndPage = (secmem & FLASH_SECR_HDP1_PEND);
694   *HDPEn = (secmem & FLASH_SECR_HDP1EN) >> FLASH_SECR_HDP1EN_Pos;
695 }
696 
697 /**
698   * @brief  Set the read protection key.
699   * @param  RDPKeyType specifies the read protection key type.
700   *         This parameter can be one of the following values:
701   *            @arg OB_RDP_KEY_OEM1: OEM1 key
702   *            @arg OB_RDP_KEY_OEM2: OEM2 key
703   * @param  RDPKey0 specifies the RDP key 0.
704   * @param  RDPKey1 specifies the RDP key 1.
705   * @param  RDPKey2 specifies the RDP key 2.
706   * @param  RDPKey3 specifies the RDP key 3.
707   * @retval None
708   */
FLASH_OB_RDPKeyConfig(uint32_t RDPKeyType,uint32_t RDPKey0,uint32_t RDPKey1,uint32_t RDPKey2,uint32_t RDPKey3)709 static void FLASH_OB_RDPKeyConfig(uint32_t RDPKeyType, uint32_t RDPKey0, uint32_t RDPKey1,
710                                   uint32_t RDPKey2, uint32_t RDPKey3)
711 {
712   /* Check the parameters */
713   assert_param(IS_OB_RDP_KEY_TYPE(RDPKeyType));
714 
715   /* Configure the RDP OEM1/2 key */
716   if (RDPKeyType == OB_RDP_KEY_OEM1)
717   {
718     WRITE_REG(FLASH->OEM1KEYW0R, RDPKey0);
719     WRITE_REG(FLASH->OEM1KEYW1R, RDPKey1);
720     WRITE_REG(FLASH->OEM1KEYW2R, RDPKey2);
721     WRITE_REG(FLASH->OEM1KEYW3R, RDPKey3);
722   }
723   else if (RDPKeyType == OB_RDP_KEY_OEM2)
724   {
725 
726     WRITE_REG(FLASH->OEM2KEYW0R, RDPKey0);
727     WRITE_REG(FLASH->OEM2KEYW1R, RDPKey1);
728     WRITE_REG(FLASH->OEM2KEYW2R, RDPKey2);
729     WRITE_REG(FLASH->OEM2KEYW3R, RDPKey3);
730   }
731   else
732   {
733     /* nothing to do */
734   }
735 }
736 
737 /**
738   * @brief  Get the OEM1/2 keys CRC.
739   * @param  RDPKeyType specifies the read protection key type.
740   *         This parameter can be one of the following values:
741   *            @arg OB_RDP_KEY_OEM1: OEM1 key
742   *            @arg OB_RDP_KEY_OEM2: OEM2 key
743   * @param  OEMKeyCRC specifies the OEM keys CRC.
744   * @retval None
745   */
HAL_FLASH_OB_GetOEMKeyCRC(uint32_t RDPKeyType,uint32_t * OEMKeyCRC)746 void HAL_FLASH_OB_GetOEMKeyCRC(uint32_t RDPKeyType, uint32_t *OEMKeyCRC)
747 {
748   uint32_t regvalue;
749 
750   regvalue = FLASH->OEMKEYSR;
751   if (RDPKeyType == OB_RDP_KEY_OEM1)
752   {
753     *OEMKeyCRC = (regvalue & FLASH_OEMKEYSR_OEM1KEYCRC);
754   }
755   else if (RDPKeyType == OB_RDP_KEY_OEM2)
756   {
757     *OEMKeyCRC = (regvalue & FLASH_OEMKEYSR_OEM2KEYCRC) >> FLASH_OEMKEYSR_OEM2KEYCRC_Pos;
758   }
759   else
760   {
761     /* Empty statement (to be compliant MISRA 15.7) */
762   }
763 }
764 
765 /**
766   * @brief  Enable the HDP Protection area .
767   * @param  Banks specifies the bank number
768   *         this parameter can be:
769   *         @arg @ref FLASH_BANK_1
770   * @retval None
771   */
HAL_FLASHEx_EnableHDPProtection(uint32_t Banks)772 void HAL_FLASHEx_EnableHDPProtection(uint32_t Banks)
773 {
774   assert_param(IS_FLASH_BANK(Banks));
775 
776   MODIFY_REG(FLASH->HDPCR, FLASH_HDPCR_HDP1_ACCDIS, FLASH_HDPCR_HDP1_ACCDIS);
777 }
778 
779 /**
780   * @brief  Check if the HDP area protection enabled.
781   * @retval returns 1 if the Protection is enabled
782   *                 0 if the protection is disabled
783   */
HAL_FLASHEx_IsEnabledHDPProtection(void)784 uint32_t HAL_FLASHEx_IsEnabledHDPProtection(void)
785 {
786   return ((READ_BIT(FLASH->HDPCR, FLASH_HDPCR_HDP1_ACCDIS) == FLASH_HDPCR_HDP1_ACCDIS) ? 0UL : 1UL);
787 }
788 /**
789   * @brief  HDP extension area configuration.
790   * @param  pHDPExtension pointer to an FLASH_HDPExtentionTypeDef structure that
791   *                       contains the configuration information.
792   * @retval None
793   */
HAL_FLASHEx_ConfigHDPExtension(const FLASH_HDPExtensionTypeDef * pHDPExtension)794 void HAL_FLASHEx_ConfigHDPExtension(const FLASH_HDPExtensionTypeDef *pHDPExtension)
795 {
796   assert_param(IS_FLASH_PAGE(pHDPExtension->NbPages));
797   assert_param(IS_OB_HDPEXT_CONFIG(pHDPExtension->Status));
798 
799   MODIFY_REG(FLASH->HDPEXTR, FLASH_HDPEXTR_HDP1_EXT, (pHDPExtension->NbPages));
800   MODIFY_REG(FLASH->HDPCR, FLASH_HDPCR_HDP1EXT_ACCDIS, (pHDPExtension->Status));
801 }
802 /**
803   * @brief  Get HDP extension configuration.
804   * @param  pHDPExtension pointer to an FLASH_HDPExtentionTypeDef structure that
805   *                       contains the configuration information.
806   * @retval None
807   */
HAL_FLASHEx_GetHDPExtensionConfig(FLASH_HDPExtensionTypeDef * pHDPExtension)808 void HAL_FLASHEx_GetHDPExtensionConfig(FLASH_HDPExtensionTypeDef *pHDPExtension)
809 {
810   uint32_t regvalue;
811 
812   regvalue = FLASH->HDPEXTR;
813   pHDPExtension->NbPages = regvalue & FLASH_HDPEXTR_HDP1_EXT;
814   regvalue = FLASH->HDPCR;
815   pHDPExtension->Status = regvalue & FLASH_HDPCR_HDP1EXT_ACCDIS;
816 }
817 
818 /**
819   * @}
820   */
821 
822 /**
823   * @}
824   */
825 
826 #endif /* HAL_FLASH_MODULE_ENABLED */
827 
828 /**
829   * @}
830   */
831 
832 /**
833   * @}
834   */
835