diff --git a/firmware/hw_layer/ports/stm32/stm32h7/stm32h7xx_hal_def.h b/firmware/hw_layer/ports/stm32/stm32h7/stm32h7xx_hal_def.h
new file mode 100644
index 0000000000..d59c8c12bb
--- /dev/null
+++ b/firmware/hw_layer/ports/stm32/stm32h7/stm32h7xx_hal_def.h
@@ -0,0 +1,188 @@
+/**
+ ******************************************************************************
+ * @file stm32h7xx_hal_def.h
+ * @author MCD Application Team
+ * @brief This file contains HAL common defines, enumeration, macros and
+ * structures definitions.
+ ******************************************************************************
+ * @attention
+ *
+ *
© Copyright (c) 2017 STMicroelectronics.
+ * All rights reserved.
+ *
+ * This software component is licensed by ST under BSD 3-Clause license,
+ * the "License"; You may not use this file except in compliance with the
+ * License. You may obtain a copy of the License at:
+ * opensource.org/licenses/BSD-3-Clause
+ *
+ ******************************************************************************
+ */
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef STM32H7xx_HAL_DEF
+#define STM32H7xx_HAL_DEF
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+/* Includes ------------------------------------------------------------------*/
+#include "stm32h7xx.h"
+#include "Legacy/stm32_hal_legacy.h"
+#include
+#include
+
+/* Exported types ------------------------------------------------------------*/
+
+/**
+ * @brief HAL Status structures definition
+ */
+typedef enum
+{
+ HAL_OK = 0x00,
+ HAL_ERROR = 0x01,
+ HAL_BUSY = 0x02,
+ HAL_TIMEOUT = 0x03
+} HAL_StatusTypeDef;
+
+/**
+ * @brief HAL Lock structures definition
+ */
+typedef enum
+{
+ HAL_UNLOCKED = 0x00,
+ HAL_LOCKED = 0x01
+} HAL_LockTypeDef;
+
+/* Exported macro ------------------------------------------------------------*/
+
+#define HAL_MAX_DELAY 0xFFFFFFFFU
+
+#define HAL_IS_BIT_SET(REG, BIT) (((REG) & (BIT)) == (BIT))
+#define HAL_IS_BIT_CLR(REG, BIT) (((REG) & (BIT)) == 0U)
+
+#define __HAL_LINKDMA(__HANDLE__, __PPP_DMA_FIELD__, __DMA_HANDLE__) \
+ do{ \
+ (__HANDLE__)->__PPP_DMA_FIELD__ = &(__DMA_HANDLE__); \
+ (__DMA_HANDLE__).Parent = (__HANDLE__); \
+ } while(0)
+
+#define UNUSED(x) ((void)(x))
+
+/** @brief Reset the Handle's State field.
+ * @param __HANDLE__: specifies the Peripheral Handle.
+ * @note This macro can be used for the following purpose:
+ * - When the Handle is declared as local variable; before passing it as parameter
+ * to HAL_PPP_Init() for the first time, it is mandatory to use this macro
+ * to set to 0 the Handle's "State" field.
+ * Otherwise, "State" field may have any random value and the first time the function
+ * HAL_PPP_Init() is called, the low level hardware initialization will be missed
+ * (i.e. HAL_PPP_MspInit() will not be executed).
+ * - When there is a need to reconfigure the low level hardware: instead of calling
+ * HAL_PPP_DeInit() then HAL_PPP_Init(), user can make a call to this macro then HAL_PPP_Init().
+ * In this later function, when the Handle's "State" field is set to 0, it will execute the function
+ * HAL_PPP_MspInit() which will reconfigure the low level hardware.
+ * @retval None
+ */
+#define __HAL_RESET_HANDLE_STATE(__HANDLE__) ((__HANDLE__)->State = 0)
+
+#if (USE_RTOS == 1)
+ #error " USE_RTOS should be 0 in the current HAL release "
+#else
+ #define __HAL_LOCK(__HANDLE__) \
+ do{ \
+ if((__HANDLE__)->Lock == HAL_LOCKED) \
+ { \
+ return HAL_BUSY; \
+ } \
+ else \
+ { \
+ (__HANDLE__)->Lock = HAL_LOCKED; \
+ } \
+ }while (0)
+
+ #define __HAL_UNLOCK(__HANDLE__) \
+ do{ \
+ (__HANDLE__)->Lock = HAL_UNLOCKED; \
+ }while (0)
+#endif /* USE_RTOS */
+
+#if defined ( __GNUC__ )
+ #ifndef __weak
+ #define __weak __attribute__((weak))
+ #endif /* __weak */
+ #ifndef __packed
+ #define __packed __attribute__((__packed__))
+ #endif /* __packed */
+#endif /* __GNUC__ */
+
+
+/* Macro to get variable aligned on 4-bytes, for __ICCARM__ the directive "#pragma data_alignment=4" must be used instead */
+#if defined (__GNUC__) /* GNU Compiler */
+ #ifndef __ALIGN_END
+ #define __ALIGN_END __attribute__ ((aligned (4)))
+ #endif /* __ALIGN_END */
+ #ifndef __ALIGN_BEGIN
+ #define __ALIGN_BEGIN
+ #endif /* __ALIGN_BEGIN */
+#else
+ #ifndef __ALIGN_END
+ #define __ALIGN_END
+ #endif /* __ALIGN_END */
+ #ifndef __ALIGN_BEGIN
+ #if defined (__CC_ARM) /* ARM Compiler */
+ #define __ALIGN_BEGIN __align(4)
+ #elif defined (__ICCARM__) /* IAR Compiler */
+ #define __ALIGN_BEGIN
+ #endif /* __CC_ARM */
+ #endif /* __ALIGN_BEGIN */
+#endif /* __GNUC__ */
+
+/* Macro to get variable aligned on 32-bytes,needed for cache maintenance purpose */
+#if defined (__GNUC__) /* GNU Compiler */
+ #define ALIGN_32BYTES(buf) buf __attribute__ ((aligned (32)))
+#elif defined (__ICCARM__) /* IAR Compiler */
+ #define ALIGN_32BYTES(buf) _Pragma("data_alignment=32") buf
+#elif defined (__CC_ARM) /* ARM Compiler */
+ #define ALIGN_32BYTES(buf) __align(32) buf
+#endif
+
+/**
+ * @brief __RAM_FUNC definition
+ */
+#if defined ( __CC_ARM )
+/* ARM Compiler
+ ------------
+ RAM functions are defined using the toolchain options.
+ Functions that are executed in RAM should reside in a separate source module.
+ Using the 'Options for File' dialog you can simply change the 'Code / Const'
+ area of a module to a memory space in physical RAM.
+ Available memory areas are declared in the 'Target' tab of the 'Options for Target'
+ dialog.
+*/
+#define __RAM_FUNC
+
+#elif defined ( __ICCARM__ )
+/* ICCARM Compiler
+ ---------------
+ RAM functions are defined using a specific toolchain keyword "__ramfunc".
+*/
+#define __RAM_FUNC __ramfunc
+
+#elif defined ( __GNUC__ )
+/* GNU Compiler
+ ------------
+ RAM functions are defined using a specific toolchain attribute
+ "__attribute__((section(".RamFunc")))".
+*/
+#define __RAM_FUNC __attribute__((section(".RamFunc")))
+
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* STM32H7xx_HAL_DEF */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/firmware/hw_layer/ports/stm32/stm32h7/stm32h7xx_hal_flash.c b/firmware/hw_layer/ports/stm32/stm32h7/stm32h7xx_hal_flash.c
new file mode 100644
index 0000000000..6383da56e1
--- /dev/null
+++ b/firmware/hw_layer/ports/stm32/stm32h7/stm32h7xx_hal_flash.c
@@ -0,0 +1,1177 @@
+/**
+ ******************************************************************************
+ * @file stm32h7xx_hal_flash.c
+ * @author MCD Application Team
+ * @brief FLASH HAL module driver.
+ * This file provides firmware functions to manage the following
+ * functionalities of the internal FLASH memory:
+ * + Program operations functions
+ * + Memory Control functions
+ * + Peripheral Errors functions
+ *
+ @verbatim
+ ==============================================================================
+ ##### FLASH peripheral features #####
+ ==============================================================================
+
+ [..] The Flash memory interface manages CPU AXI I-Code and D-Code accesses
+ to the Flash memory. It implements the erase and program Flash memory operations
+ and the read and write protection mechanisms.
+
+ [..] The FLASH main features are:
+ (+) Flash memory read operations
+ (+) Flash memory program/erase operations
+ (+) Read / write protections
+ (+) Option bytes programming
+ (+) Error code correction (ECC) : Data in flash are 266-bits word
+ (10 bits added per flash word)
+
+ ##### How to use this driver #####
+ ==============================================================================
+ [..]
+ This driver provides functions and macros to configure and program the FLASH
+ memory of all STM32H7xx devices.
+
+ (#) FLASH Memory IO Programming functions:
+ (++) Lock and Unlock the FLASH interface using HAL_FLASH_Unlock() and
+ HAL_FLASH_Lock() functions
+ (++) Program functions: 256-bit word only
+ (++) There Two modes of programming :
+ (+++) Polling mode using HAL_FLASH_Program() function
+ (+++) Interrupt mode using HAL_FLASH_Program_IT() function
+
+ (#) Interrupts and flags management functions :
+ (++) Handle FLASH interrupts by calling HAL_FLASH_IRQHandler()
+ (++) Callback functions are called when the flash operations are finished :
+ HAL_FLASH_EndOfOperationCallback() when everything is ok, otherwise
+ HAL_FLASH_OperationErrorCallback()
+ (++) Get error flag status by calling HAL_FLASH_GetError()
+
+ (#) Option bytes management functions :
+ (++) Lock and Unlock the option bytes using HAL_FLASH_OB_Unlock() and
+ HAL_FLASH_OB_Lock() functions
+ (++) Launch the reload of the option bytes using HAL_FLASH_OB_Launch() function.
+ In this case, a reset is generated
+ [..]
+ In addition to these functions, this driver includes a set of macros allowing
+ to handle the following operations:
+ (+) Set the latency
+ (+) Enable/Disable the FLASH interrupts
+ (+) Monitor the FLASH flags status
+ [..]
+ (@) For any Flash memory program operation (erase or program), the CPU clock frequency
+ (HCLK) must be at least 1MHz.
+ (@) The contents of the Flash memory are not guaranteed if a device reset occurs during
+ a Flash memory operation.
+ (@) The application can simultaneously request a read and a write operation through each AXI
+ interface.
+ As the Flash memory is divided into two independent banks, the embedded Flash
+ memory interface can drive different operations at the same time on each bank. For
+ example a read, write or erase operation can be executed on bank 1 while another read,
+ write or erase operation is executed on bank 2.
+
+ @endverbatim
+ ******************************************************************************
+ * @attention
+ *
+ * © COPYRIGHT(c) 2017 STMicroelectronics.
+ * All rights reserved.
+ *
+ * This software component is licensed by ST under BSD 3-Clause license,
+ * the "License"; You may not use this file except in compliance with the
+ * License. You may obtain a copy of the License at:
+ * opensource.org/licenses/BSD-3-Clause
+ *
+ ******************************************************************************
+ */
+
+/* Includes ------------------------------------------------------------------*/
+#include "stm32h7xx_hal.h"
+
+/** @addtogroup STM32H7xx_HAL_Driver
+ * @{
+ */
+
+/** @defgroup FLASH FLASH
+ * @brief FLASH HAL module driver
+ * @{
+ */
+
+#ifdef HAL_FLASH_MODULE_ENABLED
+
+/* Private typedef -----------------------------------------------------------*/
+/* Private define ------------------------------------------------------------*/
+/** @addtogroup FLASH_Private_Constants
+ * @{
+ */
+#define FLASH_TIMEOUT_VALUE 50000U /* 50 s */
+/**
+ * @}
+ */
+/* Private macro -------------------------------------------------------------*/
+/* Private variables ---------------------------------------------------------*/
+FLASH_ProcessTypeDef pFlash;
+/* Private function prototypes -----------------------------------------------*/
+/* Exported functions ---------------------------------------------------------*/
+
+/** @defgroup FLASH_Exported_Functions FLASH Exported functions
+ * @{
+ */
+
+/** @defgroup FLASH_Exported_Functions_Group1 Programming operation functions
+ * @brief Programming operation functions
+ *
+@verbatim
+ ===============================================================================
+ ##### Programming operation functions #####
+ ===============================================================================
+ [..]
+ This subsection provides a set of functions allowing to manage the FLASH
+ program operations.
+
+@endverbatim
+ * @{
+ */
+
+/**
+ * @brief Program flash word at a specified address
+ * @param TypeProgram Indicate the way to program at a specified address.
+ * This parameter can be a value of @ref FLASH_Type_Program
+ * @param FlashAddress specifies the address to be programmed.
+ * @param DataAddress specifies the address of data to be programmed
+ *
+ * @retval HAL_StatusTypeDef HAL Status
+ */
+HAL_StatusTypeDef HAL_FLASH_Program(uint32_t TypeProgram, uint32_t FlashAddress, uint32_t DataAddress)
+{
+ HAL_StatusTypeDef status;
+ __IO uint32_t *dest_addr = (__IO uint32_t *)FlashAddress;
+ __IO uint32_t *src_addr = (__IO uint32_t*)DataAddress;
+ uint32_t bank;
+ uint8_t row_index = FLASH_NB_32BITWORD_IN_FLASHWORD;
+
+ /* Check the parameters */
+ assert_param(IS_FLASH_TYPEPROGRAM(TypeProgram));
+ assert_param(IS_FLASH_PROGRAM_ADDRESS(FlashAddress));
+
+ /* Process Locked */
+ __HAL_LOCK(&pFlash);
+
+#if defined (FLASH_OPTCR_PG_OTP)
+ if((IS_FLASH_PROGRAM_ADDRESS_BANK1(FlashAddress)) || (IS_FLASH_PROGRAM_ADDRESS_OTP(FlashAddress)))
+#else
+ if(IS_FLASH_PROGRAM_ADDRESS_BANK1(FlashAddress))
+#endif /* FLASH_OPTCR_PG_OTP */
+ {
+ bank = FLASH_BANK_1;
+ }
+#if defined (DUAL_BANK)
+ else if(IS_FLASH_PROGRAM_ADDRESS_BANK2(FlashAddress))
+ {
+ bank = FLASH_BANK_2;
+ }
+#endif /* DUAL_BANK */
+ else
+ {
+ return HAL_ERROR;
+ }
+
+ /* Reset error code */
+ pFlash.ErrorCode = HAL_FLASH_ERROR_NONE;
+
+ /* Wait for last operation to be completed */
+ status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE, bank);
+
+ if(status == HAL_OK)
+ {
+#if defined (DUAL_BANK)
+ if(bank == FLASH_BANK_1)
+ {
+#if defined (FLASH_OPTCR_PG_OTP)
+ if (TypeProgram == FLASH_TYPEPROGRAM_OTPWORD)
+ {
+ /* Set OTP_PG bit */
+ SET_BIT(FLASH->OPTCR, FLASH_OPTCR_PG_OTP);
+ }
+ else
+#endif /* FLASH_OPTCR_PG_OTP */
+ {
+ /* Set PG bit */
+ SET_BIT(FLASH->CR1, FLASH_CR_PG);
+ }
+ }
+ else
+ {
+ /* Set PG bit */
+ SET_BIT(FLASH->CR2, FLASH_CR_PG);
+ }
+#else /* Single Bank */
+#if defined (FLASH_OPTCR_PG_OTP)
+ if (TypeProgram == FLASH_TYPEPROGRAM_OTPWORD)
+ {
+ /* Set OTP_PG bit */
+ SET_BIT(FLASH->OPTCR, FLASH_OPTCR_PG_OTP);
+ }
+ else
+#endif /* FLASH_OPTCR_PG_OTP */
+ {
+ /* Set PG bit */
+ SET_BIT(FLASH->CR1, FLASH_CR_PG);
+ }
+#endif /* DUAL_BANK */
+
+ __ISB();
+ __DSB();
+
+#if defined (FLASH_OPTCR_PG_OTP)
+ if (TypeProgram == FLASH_TYPEPROGRAM_OTPWORD)
+ {
+ /* Program an OTP word (16 bits) */
+ *(__IO uint16_t *)FlashAddress = *(__IO uint16_t*)DataAddress;
+ }
+ else
+#endif /* FLASH_OPTCR_PG_OTP */
+ {
+ /* Program the flash word */
+ do
+ {
+ *dest_addr = *src_addr;
+ dest_addr++;
+ src_addr++;
+ row_index--;
+ } while (row_index != 0U);
+ }
+
+ __ISB();
+ __DSB();
+
+ /* Wait for last operation to be completed */
+ status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE, bank);
+
+#if defined (DUAL_BANK)
+#if defined (FLASH_OPTCR_PG_OTP)
+ if (TypeProgram == FLASH_TYPEPROGRAM_OTPWORD)
+ {
+ /* If the program operation is completed, disable the OTP_PG */
+ CLEAR_BIT(FLASH->OPTCR, FLASH_OPTCR_PG_OTP);
+ }
+ else
+#endif /* FLASH_OPTCR_PG_OTP */
+ {
+ if(bank == FLASH_BANK_1)
+ {
+ /* If the program operation is completed, disable the PG */
+ CLEAR_BIT(FLASH->CR1, FLASH_CR_PG);
+ }
+ else
+ {
+ /* If the program operation is completed, disable the PG */
+ CLEAR_BIT(FLASH->CR2, FLASH_CR_PG);
+ }
+ }
+#else /* Single Bank */
+#if defined (FLASH_OPTCR_PG_OTP)
+ if (TypeProgram == FLASH_TYPEPROGRAM_OTPWORD)
+ {
+ /* If the program operation is completed, disable the OTP_PG */
+ CLEAR_BIT(FLASH->OPTCR, FLASH_OPTCR_PG_OTP);
+ }
+ else
+#endif /* FLASH_OPTCR_PG_OTP */
+ {
+ /* If the program operation is completed, disable the PG */
+ CLEAR_BIT(FLASH->CR1, FLASH_CR_PG);
+ }
+#endif /* DUAL_BANK */
+ }
+
+ /* Process Unlocked */
+ __HAL_UNLOCK(&pFlash);
+
+ return status;
+}
+
+/**
+ * @brief Program flash words of 256 bits at a specified address with interrupt enabled.
+ * @param TypeProgram Indicate the way to program at a specified address.
+ * This parameter can be a value of @ref FLASH_Type_Program
+ * @param FlashAddress specifies the address to be programmed.
+ * @param DataAddress specifies the address of data (256 bits) to be programmed
+ *
+ * @retval HAL Status
+ */
+HAL_StatusTypeDef HAL_FLASH_Program_IT(uint32_t TypeProgram, uint32_t FlashAddress, uint32_t DataAddress)
+{
+ HAL_StatusTypeDef status;
+ __IO uint32_t *dest_addr = (__IO uint32_t*)FlashAddress;
+ __IO uint32_t *src_addr = (__IO uint32_t*)DataAddress;
+ uint32_t bank;
+ uint8_t row_index = FLASH_NB_32BITWORD_IN_FLASHWORD;
+
+ /* Check the parameters */
+ assert_param(IS_FLASH_TYPEPROGRAM(TypeProgram));
+ assert_param(IS_FLASH_PROGRAM_ADDRESS(FlashAddress));
+
+ /* Process Locked */
+ __HAL_LOCK(&pFlash);
+
+ /* Reset error code */
+ pFlash.ErrorCode = HAL_FLASH_ERROR_NONE;
+
+#if defined (FLASH_OPTCR_PG_OTP)
+ if((IS_FLASH_PROGRAM_ADDRESS_BANK1(FlashAddress)) || (IS_FLASH_PROGRAM_ADDRESS_OTP(FlashAddress)))
+#else
+ if(IS_FLASH_PROGRAM_ADDRESS_BANK1(FlashAddress))
+#endif /* FLASH_OPTCR_PG_OTP */
+ {
+ bank = FLASH_BANK_1;
+ }
+#if defined (DUAL_BANK)
+ else if(IS_FLASH_PROGRAM_ADDRESS_BANK2(FlashAddress))
+ {
+ bank = FLASH_BANK_2;
+ }
+#endif /* DUAL_BANK */
+ else
+ {
+ return HAL_ERROR;
+ }
+
+ /* Wait for last operation to be completed */
+ status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE, bank);
+
+ if (status != HAL_OK)
+ {
+ /* Process Unlocked */
+ __HAL_UNLOCK(&pFlash);
+ }
+ else
+ {
+ pFlash.Address = FlashAddress;
+
+#if defined (DUAL_BANK)
+ if(bank == FLASH_BANK_1)
+ {
+ /* Set internal variables used by the IRQ handler */
+ pFlash.ProcedureOnGoing = FLASH_PROC_PROGRAM_BANK1;
+
+#if defined (FLASH_OPTCR_PG_OTP)
+ if (TypeProgram == FLASH_TYPEPROGRAM_OTPWORD)
+ {
+ /* Set OTP_PG bit */
+ SET_BIT(FLASH->OPTCR, FLASH_OPTCR_PG_OTP);
+ }
+ else
+#endif /* FLASH_OPTCR_PG_OTP */
+ {
+ /* Set PG bit */
+ SET_BIT(FLASH->CR1, FLASH_CR_PG);
+ }
+
+ /* Enable End of Operation and Error interrupts for Bank 1 */
+#if defined (FLASH_CR_OPERRIE)
+ __HAL_FLASH_ENABLE_IT_BANK1(FLASH_IT_EOP_BANK1 | FLASH_IT_WRPERR_BANK1 | FLASH_IT_PGSERR_BANK1 | \
+ FLASH_IT_STRBERR_BANK1 | FLASH_IT_INCERR_BANK1 | FLASH_IT_OPERR_BANK1);
+#else
+ __HAL_FLASH_ENABLE_IT_BANK1(FLASH_IT_EOP_BANK1 | FLASH_IT_WRPERR_BANK1 | FLASH_IT_PGSERR_BANK1 | \
+ FLASH_IT_STRBERR_BANK1 | FLASH_IT_INCERR_BANK1);
+#endif /* FLASH_CR_OPERRIE */
+ }
+ else
+ {
+ /* Set internal variables used by the IRQ handler */
+ pFlash.ProcedureOnGoing = FLASH_PROC_PROGRAM_BANK2;
+
+ /* Set PG bit */
+ SET_BIT(FLASH->CR2, FLASH_CR_PG);
+
+ /* Enable End of Operation and Error interrupts for Bank2 */
+#if defined (FLASH_CR_OPERRIE)
+ __HAL_FLASH_ENABLE_IT_BANK2(FLASH_IT_EOP_BANK2 | FLASH_IT_WRPERR_BANK2 | FLASH_IT_PGSERR_BANK2 | \
+ FLASH_IT_STRBERR_BANK2 | FLASH_IT_INCERR_BANK2 | FLASH_IT_OPERR_BANK2);
+#else
+ __HAL_FLASH_ENABLE_IT_BANK2(FLASH_IT_EOP_BANK2 | FLASH_IT_WRPERR_BANK2 | FLASH_IT_PGSERR_BANK2 | \
+ FLASH_IT_STRBERR_BANK2 | FLASH_IT_INCERR_BANK2);
+#endif /* FLASH_CR_OPERRIE */
+ }
+#else /* Single Bank */
+ /* Set internal variables used by the IRQ handler */
+ pFlash.ProcedureOnGoing = FLASH_PROC_PROGRAM_BANK1;
+
+#if defined (FLASH_OPTCR_PG_OTP)
+ if (TypeProgram == FLASH_TYPEPROGRAM_OTPWORD)
+ {
+ /* Set OTP_PG bit */
+ SET_BIT(FLASH->OPTCR, FLASH_OPTCR_PG_OTP);
+ }
+ else
+#endif /* FLASH_OPTCR_PG_OTP */
+ {
+ /* Set PG bit */
+ SET_BIT(FLASH->CR1, FLASH_CR_PG);
+ }
+
+ /* Enable End of Operation and Error interrupts for Bank 1 */
+#if defined (FLASH_CR_OPERRIE)
+ __HAL_FLASH_ENABLE_IT_BANK1(FLASH_IT_EOP_BANK1 | FLASH_IT_WRPERR_BANK1 | FLASH_IT_PGSERR_BANK1 | \
+ FLASH_IT_STRBERR_BANK1 | FLASH_IT_INCERR_BANK1 | FLASH_IT_OPERR_BANK1);
+#else
+ __HAL_FLASH_ENABLE_IT_BANK1(FLASH_IT_EOP_BANK1 | FLASH_IT_WRPERR_BANK1 | FLASH_IT_PGSERR_BANK1 | \
+ FLASH_IT_STRBERR_BANK1 | FLASH_IT_INCERR_BANK1);
+#endif /* FLASH_CR_OPERRIE */
+#endif /* DUAL_BANK */
+
+ __ISB();
+ __DSB();
+
+#if defined (FLASH_OPTCR_PG_OTP)
+ if (TypeProgram == FLASH_TYPEPROGRAM_OTPWORD)
+ {
+ /* Program an OTP word (16 bits) */
+ *(__IO uint16_t *)FlashAddress = *(__IO uint16_t*)DataAddress;
+ }
+ else
+#endif /* FLASH_OPTCR_PG_OTP */
+ {
+ /* Program the flash word */
+ do
+ {
+ *dest_addr = *src_addr;
+ dest_addr++;
+ src_addr++;
+ row_index--;
+ } while (row_index != 0U);
+ }
+
+ __ISB();
+ __DSB();
+ }
+
+ return status;
+}
+
+/**
+ * @brief This function handles FLASH interrupt request.
+ * @retval None
+ */
+void HAL_FLASH_IRQHandler(void)
+{
+ uint32_t temp;
+ uint32_t errorflag;
+ FLASH_ProcedureTypeDef procedure;
+
+ /* Check FLASH Bank1 End of Operation flag */
+ if(__HAL_FLASH_GET_FLAG_BANK1(FLASH_SR_EOP) != RESET)
+ {
+ if(pFlash.ProcedureOnGoing == FLASH_PROC_SECTERASE_BANK1)
+ {
+ /* Nb of sector to erased can be decreased */
+ pFlash.NbSectorsToErase--;
+
+ /* Check if there are still sectors to erase */
+ if(pFlash.NbSectorsToErase != 0U)
+ {
+ /* Indicate user which sector has been erased */
+ HAL_FLASH_EndOfOperationCallback(pFlash.Sector);
+
+ /* Clear bank 1 End of Operation pending bit */
+ __HAL_FLASH_CLEAR_FLAG_BANK1(FLASH_FLAG_EOP_BANK1);
+
+ /* Increment sector number */
+ pFlash.Sector++;
+ temp = pFlash.Sector;
+ FLASH_Erase_Sector(temp, FLASH_BANK_1, pFlash.VoltageForErase);
+ }
+ else
+ {
+ /* No more sectors to Erase, user callback can be called */
+ /* Reset Sector and stop Erase sectors procedure */
+ pFlash.Sector = 0xFFFFFFFFU;
+ pFlash.ProcedureOnGoing = FLASH_PROC_NONE;
+
+ /* FLASH EOP interrupt user callback */
+ HAL_FLASH_EndOfOperationCallback(pFlash.Sector);
+
+ /* Clear FLASH End of Operation pending bit */
+ __HAL_FLASH_CLEAR_FLAG_BANK1(FLASH_FLAG_EOP_BANK1);
+ }
+ }
+ else
+ {
+ procedure = pFlash.ProcedureOnGoing;
+
+ if((procedure == FLASH_PROC_MASSERASE_BANK1) || (procedure == FLASH_PROC_ALLBANK_MASSERASE))
+ {
+ /* MassErase ended. Return the selected bank */
+ /* FLASH EOP interrupt user callback */
+ HAL_FLASH_EndOfOperationCallback(FLASH_BANK_1);
+ }
+ else if(procedure == FLASH_PROC_PROGRAM_BANK1)
+ {
+ /* Program ended. Return the selected address */
+ /* FLASH EOP interrupt user callback */
+ HAL_FLASH_EndOfOperationCallback(pFlash.Address);
+ }
+ else
+ {
+ /* Nothing to do */
+ }
+
+ if((procedure != FLASH_PROC_SECTERASE_BANK2) && \
+ (procedure != FLASH_PROC_MASSERASE_BANK2) && \
+ (procedure != FLASH_PROC_PROGRAM_BANK2))
+ {
+ pFlash.ProcedureOnGoing = FLASH_PROC_NONE;
+ /* Clear FLASH End of Operation pending bit */
+ __HAL_FLASH_CLEAR_FLAG_BANK1(FLASH_FLAG_EOP_BANK1);
+ }
+ }
+ }
+
+#if defined (DUAL_BANK)
+ /* Check FLASH Bank2 End of Operation flag */
+ if(__HAL_FLASH_GET_FLAG_BANK2(FLASH_SR_EOP) != RESET)
+ {
+ if(pFlash.ProcedureOnGoing == FLASH_PROC_SECTERASE_BANK2)
+ {
+ /*Nb of sector to erased can be decreased*/
+ pFlash.NbSectorsToErase--;
+
+ /* Check if there are still sectors to erase*/
+ if(pFlash.NbSectorsToErase != 0U)
+ {
+ /*Indicate user which sector has been erased*/
+ HAL_FLASH_EndOfOperationCallback(pFlash.Sector);
+
+ /* Clear bank 2 End of Operation pending bit */
+ __HAL_FLASH_CLEAR_FLAG_BANK2(FLASH_FLAG_EOP_BANK2);
+
+ /*Increment sector number*/
+ pFlash.Sector++;
+ temp = pFlash.Sector;
+ FLASH_Erase_Sector(temp, FLASH_BANK_2, pFlash.VoltageForErase);
+ }
+ else
+ {
+ /* No more sectors to Erase, user callback can be called */
+ /* Reset Sector and stop Erase sectors procedure */
+ pFlash.Sector = 0xFFFFFFFFU;
+ pFlash.ProcedureOnGoing = FLASH_PROC_NONE;
+
+ /* FLASH EOP interrupt user callback */
+ HAL_FLASH_EndOfOperationCallback(pFlash.Sector);
+
+ /* Clear FLASH End of Operation pending bit */
+ __HAL_FLASH_CLEAR_FLAG_BANK2(FLASH_FLAG_EOP_BANK2);
+ }
+ }
+ else
+ {
+ procedure = pFlash.ProcedureOnGoing;
+
+ if((procedure == FLASH_PROC_MASSERASE_BANK2) || (procedure == FLASH_PROC_ALLBANK_MASSERASE))
+ {
+ /*MassErase ended. Return the selected bank*/
+ /* FLASH EOP interrupt user callback */
+ HAL_FLASH_EndOfOperationCallback(FLASH_BANK_2);
+ }
+ else if(procedure == FLASH_PROC_PROGRAM_BANK2)
+ {
+ /* Program ended. Return the selected address */
+ /* FLASH EOP interrupt user callback */
+ HAL_FLASH_EndOfOperationCallback(pFlash.Address);
+ }
+ else
+ {
+ /* Nothing to do */
+ }
+
+ if((procedure != FLASH_PROC_SECTERASE_BANK1) && \
+ (procedure != FLASH_PROC_MASSERASE_BANK1) && \
+ (procedure != FLASH_PROC_PROGRAM_BANK1))
+ {
+ pFlash.ProcedureOnGoing = FLASH_PROC_NONE;
+ /* Clear FLASH End of Operation pending bit */
+ __HAL_FLASH_CLEAR_FLAG_BANK2(FLASH_FLAG_EOP_BANK2);
+ }
+ }
+ }
+#endif /* DUAL_BANK */
+
+ /* Check FLASH Bank1 operation error flags */
+#if defined (FLASH_SR_OPERR)
+ errorflag = FLASH->SR1 & (FLASH_FLAG_WRPERR_BANK1 | FLASH_FLAG_PGSERR_BANK1 | FLASH_FLAG_STRBERR_BANK1 | \
+ FLASH_FLAG_INCERR_BANK1 | FLASH_FLAG_OPERR_BANK1);
+#else
+ errorflag = FLASH->SR1 & (FLASH_FLAG_WRPERR_BANK1 | FLASH_FLAG_PGSERR_BANK1 | FLASH_FLAG_STRBERR_BANK1 | \
+ FLASH_FLAG_INCERR_BANK1);
+#endif /* FLASH_SR_OPERR */
+
+ if(errorflag != 0U)
+ {
+ /* Save the error code */
+ pFlash.ErrorCode |= errorflag;
+
+ /* Clear error programming flags */
+ __HAL_FLASH_CLEAR_FLAG_BANK1(errorflag);
+
+ procedure = pFlash.ProcedureOnGoing;
+
+ if(procedure == FLASH_PROC_SECTERASE_BANK1)
+ {
+ /* Return the faulty sector */
+ temp = pFlash.Sector;
+ pFlash.Sector = 0xFFFFFFFFU;
+ }
+ else if((procedure == FLASH_PROC_MASSERASE_BANK1) || (procedure == FLASH_PROC_ALLBANK_MASSERASE))
+ {
+ /* Return the faulty bank */
+ temp = FLASH_BANK_1;
+ }
+ else
+ {
+ /* Return the faulty address */
+ temp = pFlash.Address;
+ }
+
+ /* Stop the procedure ongoing*/
+ pFlash.ProcedureOnGoing = FLASH_PROC_NONE;
+
+ /* FLASH error interrupt user callback */
+ HAL_FLASH_OperationErrorCallback(temp);
+ }
+
+#if defined (DUAL_BANK)
+ /* Check FLASH Bank2 operation error flags */
+#if defined (FLASH_SR_OPERR)
+ errorflag = FLASH->SR2 & ((FLASH_FLAG_WRPERR_BANK2 | FLASH_FLAG_PGSERR_BANK2 | FLASH_FLAG_STRBERR_BANK2 | \
+ FLASH_FLAG_INCERR_BANK2 | FLASH_FLAG_OPERR_BANK2) & 0x7FFFFFFFU);
+#else
+ errorflag = FLASH->SR2 & ((FLASH_FLAG_WRPERR_BANK2 | FLASH_FLAG_PGSERR_BANK2 | FLASH_FLAG_STRBERR_BANK2 | \
+ FLASH_FLAG_INCERR_BANK2) & 0x7FFFFFFFU);
+#endif /* FLASH_SR_OPERR */
+
+ if(errorflag != 0U)
+ {
+ /* Save the error code */
+ pFlash.ErrorCode |= (errorflag | 0x80000000U);
+
+ /* Clear error programming flags */
+ __HAL_FLASH_CLEAR_FLAG_BANK2(errorflag);
+
+ procedure = pFlash.ProcedureOnGoing;
+
+ if(procedure== FLASH_PROC_SECTERASE_BANK2)
+ {
+ /*return the faulty sector*/
+ temp = pFlash.Sector;
+ pFlash.Sector = 0xFFFFFFFFU;
+ }
+ else if((procedure == FLASH_PROC_MASSERASE_BANK2) || (procedure == FLASH_PROC_ALLBANK_MASSERASE))
+ {
+ /*return the faulty bank*/
+ temp = FLASH_BANK_2;
+ }
+ else
+ {
+ /*return the faulty address*/
+ temp = pFlash.Address;
+ }
+
+ /*Stop the procedure ongoing*/
+ pFlash.ProcedureOnGoing = FLASH_PROC_NONE;
+
+ /* FLASH error interrupt user callback */
+ HAL_FLASH_OperationErrorCallback(temp);
+ }
+#endif /* DUAL_BANK */
+
+ if(pFlash.ProcedureOnGoing == FLASH_PROC_NONE)
+ {
+#if defined (FLASH_CR_OPERRIE)
+ /* Disable Bank1 Operation and Error source interrupt */
+ __HAL_FLASH_DISABLE_IT_BANK1(FLASH_IT_EOP_BANK1 | FLASH_IT_WRPERR_BANK1 | FLASH_IT_PGSERR_BANK1 | \
+ FLASH_IT_STRBERR_BANK1 | FLASH_IT_INCERR_BANK1 | FLASH_IT_OPERR_BANK1);
+
+#if defined (DUAL_BANK)
+ /* Disable Bank2 Operation and Error source interrupt */
+ __HAL_FLASH_DISABLE_IT_BANK2(FLASH_IT_EOP_BANK2 | FLASH_IT_WRPERR_BANK2 | FLASH_IT_PGSERR_BANK2 | \
+ FLASH_IT_STRBERR_BANK2 | FLASH_IT_INCERR_BANK2 | FLASH_IT_OPERR_BANK2);
+#endif /* DUAL_BANK */
+#else
+ /* Disable Bank1 Operation and Error source interrupt */
+ __HAL_FLASH_DISABLE_IT_BANK1(FLASH_IT_EOP_BANK1 | FLASH_IT_WRPERR_BANK1 | FLASH_IT_PGSERR_BANK1 | \
+ FLASH_IT_STRBERR_BANK1 | FLASH_IT_INCERR_BANK1);
+
+#if defined (DUAL_BANK)
+ /* Disable Bank2 Operation and Error source interrupt */
+ __HAL_FLASH_DISABLE_IT_BANK2(FLASH_IT_EOP_BANK2 | FLASH_IT_WRPERR_BANK2 | FLASH_IT_PGSERR_BANK2 | \
+ FLASH_IT_STRBERR_BANK2 | FLASH_IT_INCERR_BANK2);
+#endif /* DUAL_BANK */
+#endif /* FLASH_CR_OPERRIE */
+
+ /* Process Unlocked */
+ __HAL_UNLOCK(&pFlash);
+ }
+}
+
+/**
+ * @brief FLASH end of operation interrupt callback
+ * @param ReturnValue The value saved in this parameter depends on the ongoing procedure
+ * Mass Erase: Bank number which has been requested to erase
+ * Sectors Erase: Sector which has been erased
+ * (if 0xFFFFFFFF, it means that all the selected sectors have been erased)
+ * Program: Address which was selected for data program
+ * @retval None
+ */
+__weak void HAL_FLASH_EndOfOperationCallback(uint32_t ReturnValue)
+{
+ /* Prevent unused argument(s) compilation warning */
+ UNUSED(ReturnValue);
+
+ /* NOTE : This function Should not be modified, when the callback is needed,
+ the HAL_FLASH_EndOfOperationCallback could be implemented in the user file
+ */
+}
+
+/**
+ * @brief FLASH operation error interrupt callback
+ * @param ReturnValue The value saved in this parameter depends on the ongoing procedure
+ * Mass Erase: Bank number which has been requested to erase
+ * Sectors Erase: Sector number which returned an error
+ * Program: Address which was selected for data program
+ * @retval None
+ */
+__weak void HAL_FLASH_OperationErrorCallback(uint32_t ReturnValue)
+{
+ /* Prevent unused argument(s) compilation warning */
+ UNUSED(ReturnValue);
+
+ /* NOTE : This function Should not be modified, when the callback is needed,
+ the HAL_FLASH_OperationErrorCallback could be implemented in the user file
+ */
+}
+
+/**
+ * @}
+ */
+
+/** @defgroup FLASH_Exported_Functions_Group2 Peripheral Control functions
+ * @brief Management functions
+ *
+@verbatim
+ ===============================================================================
+ ##### Peripheral Control functions #####
+ ===============================================================================
+ [..]
+ This subsection provides a set of functions allowing to control the FLASH
+ memory operations.
+
+@endverbatim
+ * @{
+ */
+
+/**
+ * @brief Unlock the FLASH control registers access
+ * @retval HAL Status
+ */
+HAL_StatusTypeDef HAL_FLASH_Unlock(void)
+{
+ if(READ_BIT(FLASH->CR1, FLASH_CR_LOCK) != 0U)
+ {
+ /* Authorize the FLASH Bank1 Registers access */
+ WRITE_REG(FLASH->KEYR1, FLASH_KEY1);
+ WRITE_REG(FLASH->KEYR1, FLASH_KEY2);
+
+ /* Verify Flash Bank1 is unlocked */
+ if (READ_BIT(FLASH->CR1, FLASH_CR_LOCK) != 0U)
+ {
+ return HAL_ERROR;
+ }
+ }
+
+#if defined (DUAL_BANK)
+ if(READ_BIT(FLASH->CR2, FLASH_CR_LOCK) != 0U)
+ {
+ /* Authorize the FLASH Bank2 Registers access */
+ WRITE_REG(FLASH->KEYR2, FLASH_KEY1);
+ WRITE_REG(FLASH->KEYR2, FLASH_KEY2);
+
+ /* Verify Flash Bank2 is unlocked */
+ if (READ_BIT(FLASH->CR2, FLASH_CR_LOCK) != 0U)
+ {
+ return HAL_ERROR;
+ }
+ }
+#endif /* DUAL_BANK */
+
+ return HAL_OK;
+}
+
+/**
+ * @brief Locks the FLASH control registers access
+ * @retval HAL Status
+ */
+HAL_StatusTypeDef HAL_FLASH_Lock(void)
+{
+ /* Set the LOCK Bit to lock the FLASH Bank1 Control Register access */
+ SET_BIT(FLASH->CR1, FLASH_CR_LOCK);
+
+ /* Verify Flash Bank1 is locked */
+ if (READ_BIT(FLASH->CR1, FLASH_CR_LOCK) == 0U)
+ {
+ return HAL_ERROR;
+ }
+
+#if defined (DUAL_BANK)
+ /* Set the LOCK Bit to lock the FLASH Bank2 Control Register access */
+ SET_BIT(FLASH->CR2, FLASH_CR_LOCK);
+
+ /* Verify Flash Bank2 is locked */
+ if (READ_BIT(FLASH->CR2, FLASH_CR_LOCK) == 0U)
+ {
+ return HAL_ERROR;
+ }
+#endif /* DUAL_BANK */
+
+ return HAL_OK;
+}
+
+/**
+ * @brief Unlock the FLASH Option Control Registers access.
+ * @retval HAL Status
+ */
+HAL_StatusTypeDef HAL_FLASH_OB_Unlock(void)
+{
+ if(READ_BIT(FLASH->OPTCR, FLASH_OPTCR_OPTLOCK) != 0U)
+ {
+ /* Authorizes the Option Byte registers programming */
+ WRITE_REG(FLASH->OPTKEYR, FLASH_OPT_KEY1);
+ WRITE_REG(FLASH->OPTKEYR, FLASH_OPT_KEY2);
+
+ /* Verify that the Option Bytes are unlocked */
+ if (READ_BIT(FLASH->OPTCR, FLASH_OPTCR_OPTLOCK) != 0U)
+ {
+ return HAL_ERROR;
+ }
+ }
+
+ return HAL_OK;
+}
+
+/**
+ * @brief Lock the FLASH Option Control Registers access.
+ * @retval HAL Status
+ */
+HAL_StatusTypeDef HAL_FLASH_OB_Lock(void)
+{
+ /* Set the OPTLOCK Bit to lock the FLASH Option Byte Registers access */
+ SET_BIT(FLASH->OPTCR, FLASH_OPTCR_OPTLOCK);
+
+ /* Verify that the Option Bytes are locked */
+ if (READ_BIT(FLASH->OPTCR, FLASH_OPTCR_OPTLOCK) == 0U)
+ {
+ return HAL_ERROR;
+ }
+
+ return HAL_OK;
+}
+
+/**
+ * @brief Launch the option bytes loading.
+ * @retval HAL Status
+ */
+HAL_StatusTypeDef HAL_FLASH_OB_Launch(void)
+{
+ HAL_StatusTypeDef status;
+
+ /* Wait for CRC computation to be completed */
+ if (FLASH_CRC_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE, FLASH_BANK_1) != HAL_OK)
+ {
+ status = HAL_ERROR;
+ }
+#if defined (DUAL_BANK)
+ else if (FLASH_CRC_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE, FLASH_BANK_2) != HAL_OK)
+ {
+ status = HAL_ERROR;
+ }
+#endif /* DUAL_BANK */
+ else
+ {
+ status = HAL_OK;
+ }
+
+ if (status == HAL_OK)
+ {
+ /* Set OPTSTRT Bit */
+ SET_BIT(FLASH->OPTCR, FLASH_OPTCR_OPTSTART);
+
+ /* Wait for OB change operation to be completed */
+ status = FLASH_OB_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE);
+ }
+
+ return status;
+}
+
+/**
+ * @}
+ */
+
+/** @defgroup FLASH_Exported_Functions_Group3 Peripheral State and Errors functions
+ * @brief Peripheral Errors functions
+ *
+@verbatim
+ ===============================================================================
+ ##### Peripheral Errors functions #####
+ ===============================================================================
+ [..]
+ This subsection permits to get in run-time Errors of the FLASH peripheral.
+
+@endverbatim
+ * @{
+ */
+
+/**
+ * @brief Get the specific FLASH error flag.
+ * @retval HAL_FLASH_ERRORCode The returned value can be:
+ * @arg HAL_FLASH_ERROR_NONE : No error set
+ *
+ * @arg HAL_FLASH_ERROR_WRP_BANK1 : Write Protection Error on Bank 1
+ * @arg HAL_FLASH_ERROR_PGS_BANK1 : Program Sequence Error on Bank 1
+ * @arg HAL_FLASH_ERROR_STRB_BANK1 : Strobe Error on Bank 1
+ * @arg HAL_FLASH_ERROR_INC_BANK1 : Inconsistency Error on Bank 1
+ * @arg HAL_FLASH_ERROR_OPE_BANK1 : Operation Error on Bank 1
+ * @arg HAL_FLASH_ERROR_RDP_BANK1 : Read Protection Error on Bank 1
+ * @arg HAL_FLASH_ERROR_RDS_BANK1 : Read Secured Error on Bank 1
+ * @arg HAL_FLASH_ERROR_SNECC_BANK1: ECC Single Correction Error on Bank 1
+ * @arg HAL_FLASH_ERROR_DBECC_BANK1: ECC Double Detection Error on Bank 1
+ * @arg HAL_FLASH_ERROR_CRCRD_BANK1: CRC Read Error on Bank 1
+ *
+ * @arg HAL_FLASH_ERROR_WRP_BANK2 : Write Protection Error on Bank 2
+ * @arg HAL_FLASH_ERROR_PGS_BANK2 : Program Sequence Error on Bank 2
+ * @arg HAL_FLASH_ERROR_STRB_BANK2 : Strobe Error on Bank 2
+ * @arg HAL_FLASH_ERROR_INC_BANK2 : Inconsistency Error on Bank 2
+ * @arg HAL_FLASH_ERROR_OPE_BANK2 : Operation Error on Bank 2
+ * @arg HAL_FLASH_ERROR_RDP_BANK2 : Read Protection Error on Bank 2
+ * @arg HAL_FLASH_ERROR_RDS_BANK2 : Read Secured Error on Bank 2
+ * @arg HAL_FLASH_ERROR_SNECC_BANK2: SNECC Error on Bank 2
+ * @arg HAL_FLASH_ERROR_DBECC_BANK2: Double Detection ECC on Bank 2
+ * @arg HAL_FLASH_ERROR_CRCRD_BANK2: CRC Read Error on Bank 2
+*/
+
+uint32_t HAL_FLASH_GetError(void)
+{
+ return pFlash.ErrorCode;
+}
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/* Private functions ---------------------------------------------------------*/
+
+/** @addtogroup FLASH_Private_Functions
+ * @{
+ */
+
+/**
+ * @brief Wait for a FLASH operation to complete.
+ * @param Timeout maximum flash operation timeout
+ * @param Bank flash FLASH_BANK_1 or FLASH_BANK_2
+ * @retval HAL_StatusTypeDef HAL Status
+ */
+HAL_StatusTypeDef FLASH_WaitForLastOperation(uint32_t Timeout, uint32_t Bank)
+{
+ /* Wait for the FLASH operation to complete by polling on QW flag to be reset.
+ Even if the FLASH operation fails, the QW flag will be reset and an error
+ flag will be set */
+
+ uint32_t bsyflag = FLASH_FLAG_QW_BANK1;
+ uint32_t errorflag = FLASH->SR1 & FLASH_FLAG_ALL_ERRORS_BANK1;
+ uint32_t tickstart = HAL_GetTick();
+
+ assert_param(IS_FLASH_BANK_EXCLUSIVE(Bank));
+
+#if defined (DUAL_BANK)
+
+ if (Bank == FLASH_BANK_2)
+ {
+ /* Get Error Flags */
+ errorflag = (FLASH->SR2 & FLASH_FLAG_ALL_ERRORS_BANK2) | 0x80000000U;
+ /* Select bsyflag depending on Bank */
+ bsyflag = FLASH_FLAG_QW_BANK2;
+ }
+#endif /* DUAL_BANK */
+
+ while(__HAL_FLASH_GET_FLAG(bsyflag))
+ {
+ if(Timeout != HAL_MAX_DELAY)
+ {
+ if(((HAL_GetTick() - tickstart) > Timeout) || (Timeout == 0U))
+ {
+ return HAL_TIMEOUT;
+ }
+ }
+ }
+
+ /* In case of error reported in Flash SR1 or SR2 register */
+ if((errorflag & 0x7FFFFFFFU) != 0U)
+ {
+ /*Save the error code*/
+ pFlash.ErrorCode |= errorflag;
+
+ /* Clear error programming flags */
+ __HAL_FLASH_CLEAR_FLAG(errorflag);
+
+ return HAL_ERROR;
+ }
+
+ /* Check FLASH End of Operation flag */
+ if(Bank == FLASH_BANK_1)
+ {
+ if (__HAL_FLASH_GET_FLAG_BANK1(FLASH_FLAG_EOP_BANK1))
+ {
+ /* Clear FLASH End of Operation pending bit */
+ __HAL_FLASH_CLEAR_FLAG_BANK1(FLASH_FLAG_EOP_BANK1);
+ }
+ }
+#if defined (DUAL_BANK)
+ else
+ {
+ if (__HAL_FLASH_GET_FLAG_BANK2(FLASH_FLAG_EOP_BANK2))
+ {
+ /* Clear FLASH End of Operation pending bit */
+ __HAL_FLASH_CLEAR_FLAG_BANK2(FLASH_FLAG_EOP_BANK2);
+ }
+ }
+#endif /* DUAL_BANK */
+
+ return HAL_OK;
+}
+
+/**
+ * @brief Wait for a FLASH Option Bytes change operation to complete.
+ * @param Timeout maximum flash operation timeout
+ * @retval HAL_StatusTypeDef HAL Status
+ */
+HAL_StatusTypeDef FLASH_OB_WaitForLastOperation(uint32_t Timeout)
+{
+ /* Get timeout */
+ uint32_t tickstart = HAL_GetTick();
+
+ /* Wait for the FLASH Option Bytes change operation to complete by polling on OPT_BUSY flag to be reset */
+ while(READ_BIT(FLASH->OPTSR_CUR, FLASH_OPTSR_OPT_BUSY) != 0U)
+ {
+ if(Timeout != HAL_MAX_DELAY)
+ {
+ if(((HAL_GetTick() - tickstart) > Timeout) || (Timeout == 0U))
+ {
+ return HAL_TIMEOUT;
+ }
+ }
+ }
+
+ /* Check option byte change error */
+ if(READ_BIT(FLASH->OPTSR_CUR, FLASH_OPTSR_OPTCHANGEERR) != 0U)
+ {
+ /* Save the error code */
+ pFlash.ErrorCode |= HAL_FLASH_ERROR_OB_CHANGE;
+
+ /* Clear the OB error flag */
+ FLASH->OPTCCR |= FLASH_OPTCCR_CLR_OPTCHANGEERR;
+
+ return HAL_ERROR;
+ }
+
+ /* If there is no error flag set */
+ return HAL_OK;
+}
+
+/**
+ * @brief Wait for a FLASH CRC computation to complete.
+ * @param Timeout maximum flash operation timeout
+ * @param Bank flash FLASH_BANK_1 or FLASH_BANK_2
+ * @retval HAL_StatusTypeDef HAL Status
+ */
+HAL_StatusTypeDef FLASH_CRC_WaitForLastOperation(uint32_t Timeout, uint32_t Bank)
+{
+ uint32_t bsyflag;
+ uint32_t tickstart = HAL_GetTick();
+
+ assert_param(IS_FLASH_BANK_EXCLUSIVE(Bank));
+
+ /* Select bsyflag depending on Bank */
+ if(Bank == FLASH_BANK_1)
+ {
+ bsyflag = FLASH_FLAG_CRC_BUSY_BANK1;
+ }
+ else
+ {
+ bsyflag = FLASH_FLAG_CRC_BUSY_BANK2;
+ }
+
+ /* Wait for the FLASH CRC computation to complete by polling on CRC_BUSY flag to be reset */
+ while(__HAL_FLASH_GET_FLAG(bsyflag))
+ {
+ if(Timeout != HAL_MAX_DELAY)
+ {
+ if(((HAL_GetTick() - tickstart) > Timeout) || (Timeout == 0U))
+ {
+ return HAL_TIMEOUT;
+ }
+ }
+ }
+
+ /* Check FLASH CRC read error flag */
+ if(Bank == FLASH_BANK_1)
+ {
+ if (__HAL_FLASH_GET_FLAG_BANK1(FLASH_FLAG_CRCRDERR_BANK1))
+ {
+ /* Save the error code */
+ pFlash.ErrorCode |= HAL_FLASH_ERROR_CRCRD_BANK1;
+
+ /* Clear FLASH CRC read error pending bit */
+ __HAL_FLASH_CLEAR_FLAG_BANK1(FLASH_FLAG_CRCRDERR_BANK1);
+
+ return HAL_ERROR;
+ }
+ }
+#if defined (DUAL_BANK)
+ else
+ {
+ if (__HAL_FLASH_GET_FLAG_BANK2(FLASH_FLAG_CRCRDERR_BANK2))
+ {
+ /* Save the error code */
+ pFlash.ErrorCode |= HAL_FLASH_ERROR_CRCRD_BANK2;
+
+ /* Clear FLASH CRC read error pending bit */
+ __HAL_FLASH_CLEAR_FLAG_BANK2(FLASH_FLAG_CRCRDERR_BANK2);
+
+ return HAL_ERROR;
+ }
+ }
+#endif /* DUAL_BANK */
+
+ /* If there is no error flag set */
+ return HAL_OK;
+}
+
+/**
+ * @}
+ */
+
+#endif /* HAL_FLASH_MODULE_ENABLED */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/firmware/hw_layer/ports/stm32/stm32h7/stm32h7xx_hal_flash.h b/firmware/hw_layer/ports/stm32/stm32h7/stm32h7xx_hal_flash.h
new file mode 100644
index 0000000000..8a47e0b0b9
--- /dev/null
+++ b/firmware/hw_layer/ports/stm32/stm32h7/stm32h7xx_hal_flash.h
@@ -0,0 +1,864 @@
+/**
+ ******************************************************************************
+ * @file stm32h7xx_hal_flash.h
+ * @author MCD Application Team
+ * @brief Header file of FLASH HAL module.
+ ******************************************************************************
+ * @attention
+ *
+ * © COPYRIGHT(c) 2017 STMicroelectronics.
+ * All rights reserved.
+ *
+ * This software component is licensed by ST under BSD 3-Clause license,
+ * the "License"; You may not use this file except in compliance with the
+ * License. You may obtain a copy of the License at:
+ * opensource.org/licenses/BSD-3-Clause
+ *
+ ******************************************************************************
+ */
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef STM32H7xx_HAL_FLASH_H
+#define STM32H7xx_HAL_FLASH_H
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+/* Includes ------------------------------------------------------------------*/
+#include "stm32h7xx_hal_def.h"
+
+/** @addtogroup STM32H7xx_HAL_Driver
+ * @{
+ */
+
+/** @addtogroup FLASH
+ * @{
+ */
+
+/* Exported types ------------------------------------------------------------*/
+/** @defgroup FLASH_Exported_Types FLASH Exported Types
+ * @{
+ */
+
+/**
+ * @brief FLASH Procedure structure definition
+ */
+typedef enum
+{
+ FLASH_PROC_NONE = 0U,
+ FLASH_PROC_SECTERASE_BANK1,
+ FLASH_PROC_MASSERASE_BANK1,
+ FLASH_PROC_PROGRAM_BANK1,
+ FLASH_PROC_SECTERASE_BANK2,
+ FLASH_PROC_MASSERASE_BANK2,
+ FLASH_PROC_PROGRAM_BANK2,
+ FLASH_PROC_ALLBANK_MASSERASE
+} FLASH_ProcedureTypeDef;
+
+
+/**
+ * @brief FLASH handle Structure definition
+ */
+typedef struct
+{
+ __IO FLASH_ProcedureTypeDef ProcedureOnGoing; /*!< Internal variable to indicate which procedure is ongoing or not in IT context */
+
+ __IO uint32_t NbSectorsToErase; /*!< Internal variable to save the remaining sectors to erase in IT context */
+
+ __IO uint32_t VoltageForErase; /*!< Internal variable to provide voltage range selected by user in IT context */
+
+ __IO uint32_t Sector; /*!< Internal variable to define the current sector which is erasing */
+
+ __IO uint32_t Address; /*!< Internal variable to save address selected for program */
+
+ HAL_LockTypeDef Lock; /*!< FLASH locking object */
+
+ __IO uint32_t ErrorCode; /*!< FLASH error code */
+
+}FLASH_ProcessTypeDef;
+
+/**
+ * @}
+ */
+
+/* Exported constants --------------------------------------------------------*/
+/** @defgroup FLASH_Exported_Constants FLASH Exported Constants
+ * @{
+ */
+
+/** @defgroup FLASH_Error_Code FLASH Error Code
+ * @brief FLASH Error Code
+ * @{
+ */
+#define HAL_FLASH_ERROR_NONE 0x00000000U /*!< No error */
+
+#define HAL_FLASH_ERROR_WRP FLASH_FLAG_WRPERR /*!< Write Protection Error */
+#define HAL_FLASH_ERROR_PGS FLASH_FLAG_PGSERR /*!< Program Sequence Error */
+#define HAL_FLASH_ERROR_STRB FLASH_FLAG_STRBERR /*!< Strobe Error */
+#define HAL_FLASH_ERROR_INC FLASH_FLAG_INCERR /*!< Inconsistency Error */
+#if defined (FLASH_SR_OPERR)
+#define HAL_FLASH_ERROR_OPE FLASH_FLAG_OPERR /*!< Operation Error */
+#endif /* FLASH_SR_OPERR */
+#define HAL_FLASH_ERROR_RDP FLASH_FLAG_RDPERR /*!< Read Protection Error */
+#define HAL_FLASH_ERROR_RDS FLASH_FLAG_RDSERR /*!< Read Secured Error */
+#define HAL_FLASH_ERROR_SNECC FLASH_FLAG_SNECCERR /*!< ECC Single Correction Error */
+#define HAL_FLASH_ERROR_DBECC FLASH_FLAG_DBECCERR /*!< ECC Double Detection Error */
+#define HAL_FLASH_ERROR_CRCRD FLASH_FLAG_CRCRDERR /*!< CRC Read Error */
+
+#define HAL_FLASH_ERROR_WRP_BANK1 FLASH_FLAG_WRPERR_BANK1 /*!< Write Protection Error on Bank 1 */
+#define HAL_FLASH_ERROR_PGS_BANK1 FLASH_FLAG_PGSERR_BANK1 /*!< Program Sequence Error on Bank 1 */
+#define HAL_FLASH_ERROR_STRB_BANK1 FLASH_FLAG_STRBERR_BANK1 /*!< Strobe Error on Bank 1 */
+#define HAL_FLASH_ERROR_INC_BANK1 FLASH_FLAG_INCERR_BANK1 /*!< Inconsistency Error on Bank 1 */
+#if defined (FLASH_SR_OPERR)
+#define HAL_FLASH_ERROR_OPE_BANK1 FLASH_FLAG_OPERR_BANK1 /*!< Operation Error on Bank 1 */
+#endif /* FLASH_SR_OPERR */
+#define HAL_FLASH_ERROR_RDP_BANK1 FLASH_FLAG_RDPERR_BANK1 /*!< Read Protection Error on Bank 1 */
+#define HAL_FLASH_ERROR_RDS_BANK1 FLASH_FLAG_RDSERR_BANK1 /*!< Read Secured Error on Bank 1 */
+#define HAL_FLASH_ERROR_SNECC_BANK1 FLASH_FLAG_SNECCERR_BANK1 /*!< ECC Single Correction Error on Bank 1 */
+#define HAL_FLASH_ERROR_DBECC_BANK1 FLASH_FLAG_DBECCERR_BANK1 /*!< ECC Double Detection Error on Bank 1 */
+#define HAL_FLASH_ERROR_CRCRD_BANK1 FLASH_FLAG_CRCRDERR_BANK1 /*!< CRC Read Error on Bank1 */
+
+#define HAL_FLASH_ERROR_WRP_BANK2 FLASH_FLAG_WRPERR_BANK2 /*!< Write Protection Error on Bank 2 */
+#define HAL_FLASH_ERROR_PGS_BANK2 FLASH_FLAG_PGSERR_BANK2 /*!< Program Sequence Error on Bank 2 */
+#define HAL_FLASH_ERROR_STRB_BANK2 FLASH_FLAG_STRBERR_BANK2 /*!< Strobe Error on Bank 2 */
+#define HAL_FLASH_ERROR_INC_BANK2 FLASH_FLAG_INCERR_BANK2 /*!< Inconsistency Error on Bank 2 */
+#if defined (FLASH_SR_OPERR)
+#define HAL_FLASH_ERROR_OPE_BANK2 FLASH_FLAG_OPERR_BANK2 /*!< Operation Error on Bank 2 */
+#endif /* FLASH_SR_OPERR */
+#define HAL_FLASH_ERROR_RDP_BANK2 FLASH_FLAG_RDPERR_BANK2 /*!< Read Protection Error on Bank 2 */
+#define HAL_FLASH_ERROR_RDS_BANK2 FLASH_FLAG_RDSERR_BANK2 /*!< Read Secured Error on Bank 2 */
+#define HAL_FLASH_ERROR_SNECC_BANK2 FLASH_FLAG_SNECCERR_BANK2 /*!< ECC Single Correction Error on Bank 2 */
+#define HAL_FLASH_ERROR_DBECC_BANK2 FLASH_FLAG_DBECCERR_BANK2 /*!< ECC Double Detection Error on Bank 2 */
+#define HAL_FLASH_ERROR_CRCRD_BANK2 FLASH_FLAG_CRCRDERR_BANK2 /*!< CRC Read Error on Bank2 */
+
+#define HAL_FLASH_ERROR_OB_CHANGE FLASH_OPTSR_OPTCHANGEERR /*!< Option Byte Change Error */
+/**
+ * @}
+ */
+
+/** @defgroup FLASH_Type_Program FLASH Type Program
+ * @{
+ */
+#define FLASH_TYPEPROGRAM_FLASHWORD 0x01U /*!< Program a flash word at a specified address */
+#if defined (FLASH_OPTCR_PG_OTP)
+#define FLASH_TYPEPROGRAM_OTPWORD 0x02U /*!< Program an OTP word at a specified address */
+#endif /* FLASH_OPTCR_PG_OTP */
+/**
+ * @}
+ */
+
+/** @defgroup FLASH_Flag_definition FLASH Flag definition
+ * @brief Flag definition
+ * @{
+ */
+#define FLASH_FLAG_BSY FLASH_SR_BSY /*!< FLASH Busy flag */
+#define FLASH_FLAG_WBNE FLASH_SR_WBNE /*!< Write Buffer Not Empty flag */
+#define FLASH_FLAG_QW FLASH_SR_QW /*!< Wait Queue on flag */
+#define FLASH_FLAG_CRC_BUSY FLASH_SR_CRC_BUSY /*!< CRC Busy flag */
+#define FLASH_FLAG_EOP FLASH_SR_EOP /*!< End Of Program on flag */
+#define FLASH_FLAG_WRPERR FLASH_SR_WRPERR /*!< Write Protection Error on flag */
+#define FLASH_FLAG_PGSERR FLASH_SR_PGSERR /*!< Program Sequence Error on flag */
+#define FLASH_FLAG_STRBERR FLASH_SR_STRBERR /*!< Strobe Error flag */
+#define FLASH_FLAG_INCERR FLASH_SR_INCERR /*!< Inconsistency Error on flag */
+#if defined (FLASH_SR_OPERR)
+#define FLASH_FLAG_OPERR FLASH_SR_OPERR /*!< Operation Error on flag */
+#endif /* FLASH_SR_OPERR */
+#define FLASH_FLAG_RDPERR FLASH_SR_RDPERR /*!< Read Protection Error on flag */
+#define FLASH_FLAG_RDSERR FLASH_SR_RDSERR /*!< Read Secured Error on flag */
+#define FLASH_FLAG_SNECCERR FLASH_SR_SNECCERR /*!< Single ECC Error Correction on flag */
+#define FLASH_FLAG_DBECCERR FLASH_SR_DBECCERR /*!< Double Detection ECC Error on flag */
+#define FLASH_FLAG_CRCEND FLASH_SR_CRCEND /*!< CRC End of Calculation flag */
+#define FLASH_FLAG_CRCRDERR FLASH_SR_CRCRDERR /*!< CRC Read Error on bank flag */
+
+#define FLASH_FLAG_BSY_BANK1 FLASH_SR_BSY /*!< FLASH Bank 1 Busy flag */
+#define FLASH_FLAG_WBNE_BANK1 FLASH_SR_WBNE /*!< Write Buffer Not Empty on Bank 1 flag */
+#define FLASH_FLAG_QW_BANK1 FLASH_SR_QW /*!< Wait Queue on Bank 1 flag */
+#define FLASH_FLAG_CRC_BUSY_BANK1 FLASH_SR_CRC_BUSY /*!< CRC Busy on Bank 1 flag */
+#define FLASH_FLAG_EOP_BANK1 FLASH_SR_EOP /*!< End Of Program on Bank 1 flag */
+#define FLASH_FLAG_WRPERR_BANK1 FLASH_SR_WRPERR /*!< Write Protection Error on Bank 1 flag */
+#define FLASH_FLAG_PGSERR_BANK1 FLASH_SR_PGSERR /*!< Program Sequence Error on Bank 1 flag */
+#define FLASH_FLAG_STRBERR_BANK1 FLASH_SR_STRBERR /*!< Strobe Error on Bank 1 flag */
+#define FLASH_FLAG_INCERR_BANK1 FLASH_SR_INCERR /*!< Inconsistency Error on Bank 1 flag */
+#if defined (FLASH_SR_OPERR)
+#define FLASH_FLAG_OPERR_BANK1 FLASH_SR_OPERR /*!< Operation Error on Bank 1 flag */
+#endif /* FLASH_SR_OPERR */
+#define FLASH_FLAG_RDPERR_BANK1 FLASH_SR_RDPERR /*!< Read Protection Error on Bank 1 flag */
+#define FLASH_FLAG_RDSERR_BANK1 FLASH_SR_RDSERR /*!< Read Secured Error on Bank 1 flag */
+#define FLASH_FLAG_SNECCERR_BANK1 FLASH_SR_SNECCERR /*!< Single ECC Error Correction on Bank 1 flag */
+#define FLASH_FLAG_DBECCERR_BANK1 FLASH_SR_DBECCERR /*!< Double Detection ECC Error on Bank 1 flag */
+#define FLASH_FLAG_CRCEND_BANK1 FLASH_SR_CRCEND /*!< CRC End of Calculation on Bank 1 flag */
+#define FLASH_FLAG_CRCRDERR_BANK1 FLASH_SR_CRCRDERR /*!< CRC Read error on Bank 1 flag */
+
+#if defined (FLASH_SR_OPERR)
+#define FLASH_FLAG_ALL_ERRORS_BANK1 (FLASH_FLAG_WRPERR_BANK1 | FLASH_FLAG_PGSERR_BANK1 | \
+ FLASH_FLAG_STRBERR_BANK1 | FLASH_FLAG_INCERR_BANK1 | \
+ FLASH_FLAG_OPERR_BANK1 | FLASH_FLAG_RDPERR_BANK1 | \
+ FLASH_FLAG_RDSERR_BANK1 | FLASH_FLAG_SNECCERR_BANK1 | \
+ FLASH_FLAG_DBECCERR_BANK1 | FLASH_FLAG_CRCRDERR_BANK1) /*!< All Bank 1 error flags */
+#else
+#define FLASH_FLAG_ALL_ERRORS_BANK1 (FLASH_FLAG_WRPERR_BANK1 | FLASH_FLAG_PGSERR_BANK1 | \
+ FLASH_FLAG_STRBERR_BANK1 | FLASH_FLAG_INCERR_BANK1 | \
+ FLASH_FLAG_RDPERR_BANK1 | FLASH_FLAG_RDSERR_BANK1 | \
+ FLASH_FLAG_SNECCERR_BANK1 | FLASH_FLAG_DBECCERR_BANK1 | \
+ FLASH_FLAG_CRCRDERR_BANK1) /*!< All Bank 1 error flags */
+#endif /* FLASH_SR_OPERR */
+
+#define FLASH_FLAG_ALL_BANK1 (FLASH_FLAG_BSY_BANK1 | FLASH_FLAG_WBNE_BANK1 | \
+ FLASH_FLAG_QW_BANK1 | FLASH_FLAG_CRC_BUSY_BANK1 | \
+ FLASH_FLAG_EOP_BANK1 | FLASH_FLAG_CRCEND_BANK1 | \
+ FLASH_FLAG_ALL_ERRORS_BANK1) /*!< All Bank 1 flags */
+
+#define FLASH_FLAG_BSY_BANK2 (FLASH_SR_BSY | 0x80000000U) /*!< FLASH Bank 2 Busy flag */
+#define FLASH_FLAG_WBNE_BANK2 (FLASH_SR_WBNE | 0x80000000U) /*!< Write Buffer Not Empty on Bank 2 flag */
+#define FLASH_FLAG_QW_BANK2 (FLASH_SR_QW | 0x80000000U) /*!< Wait Queue on Bank 2 flag */
+#define FLASH_FLAG_CRC_BUSY_BANK2 (FLASH_SR_CRC_BUSY | 0x80000000U) /*!< CRC Busy on Bank 2 flag */
+#define FLASH_FLAG_EOP_BANK2 (FLASH_SR_EOP | 0x80000000U) /*!< End Of Program on Bank 2 flag */
+#define FLASH_FLAG_WRPERR_BANK2 (FLASH_SR_WRPERR | 0x80000000U) /*!< Write Protection Error on Bank 2 flag */
+#define FLASH_FLAG_PGSERR_BANK2 (FLASH_SR_PGSERR | 0x80000000U) /*!< Program Sequence Error on Bank 2 flag */
+#define FLASH_FLAG_STRBERR_BANK2 (FLASH_SR_STRBERR | 0x80000000U) /*!< Strobe Error on Bank 2 flag */
+#define FLASH_FLAG_INCERR_BANK2 (FLASH_SR_INCERR | 0x80000000U) /*!< Inconsistency Error on Bank 2 flag */
+#if defined (FLASH_SR_OPERR)
+#define FLASH_FLAG_OPERR_BANK2 (FLASH_SR_OPERR | 0x80000000U) /*!< Operation Error on Bank 2 flag */
+#endif /* FLASH_SR_OPERR */
+#define FLASH_FLAG_RDPERR_BANK2 (FLASH_SR_RDPERR | 0x80000000U) /*!< Read Protection Error on Bank 2 flag */
+#define FLASH_FLAG_RDSERR_BANK2 (FLASH_SR_RDSERR | 0x80000000U) /*!< Read Secured Error on Bank 2 flag */
+#define FLASH_FLAG_SNECCERR_BANK2 (FLASH_SR_SNECCERR | 0x80000000U) /*!< Single ECC Error Correction on Bank 2 flag */
+#define FLASH_FLAG_DBECCERR_BANK2 (FLASH_SR_DBECCERR | 0x80000000U) /*!< Double Detection ECC Error on Bank 2 flag */
+#define FLASH_FLAG_CRCEND_BANK2 (FLASH_SR_CRCEND | 0x80000000U) /*!< CRC End of Calculation on Bank 2 flag */
+#define FLASH_FLAG_CRCRDERR_BANK2 (FLASH_SR_CRCRDERR | 0x80000000U) /*!< CRC Read error on Bank 2 flag */
+
+#if defined (FLASH_SR_OPERR)
+#define FLASH_FLAG_ALL_ERRORS_BANK2 (FLASH_FLAG_WRPERR_BANK2 | FLASH_FLAG_PGSERR_BANK2 | \
+ FLASH_FLAG_STRBERR_BANK2 | FLASH_FLAG_INCERR_BANK2 | \
+ FLASH_FLAG_OPERR_BANK2 | FLASH_FLAG_RDPERR_BANK2 | \
+ FLASH_FLAG_RDSERR_BANK2 | FLASH_FLAG_SNECCERR_BANK2 | \
+ FLASH_FLAG_DBECCERR_BANK2 | FLASH_FLAG_CRCRDERR_BANK2) /*!< All Bank 2 error flags */
+#else
+#define FLASH_FLAG_ALL_ERRORS_BANK2 (FLASH_FLAG_WRPERR_BANK2 | FLASH_FLAG_PGSERR_BANK2 | \
+ FLASH_FLAG_STRBERR_BANK2 | FLASH_FLAG_INCERR_BANK2 | \
+ FLASH_FLAG_RDPERR_BANK2 | FLASH_FLAG_RDSERR_BANK2 | \
+ FLASH_FLAG_SNECCERR_BANK2 | FLASH_FLAG_DBECCERR_BANK2 | \
+ FLASH_FLAG_CRCRDERR_BANK2) /*!< All Bank 2 error flags */
+#endif /* FLASH_SR_OPERR */
+
+#define FLASH_FLAG_ALL_BANK2 (FLASH_FLAG_BSY_BANK2 | FLASH_FLAG_WBNE_BANK2 | \
+ FLASH_FLAG_QW_BANK2 | FLASH_FLAG_CRC_BUSY_BANK2 | \
+ FLASH_FLAG_EOP_BANK2 | FLASH_FLAG_CRCEND_BANK2 | \
+ FLASH_FLAG_ALL_ERRORS_BANK2) /*!< All Bank 2 flags */
+/**
+ * @}
+ */
+
+/** @defgroup FLASH_Interrupt_definition FLASH Interrupt definition
+ * @brief FLASH Interrupt definition
+ * @{
+ */
+#define FLASH_IT_EOP_BANK1 FLASH_CR_EOPIE /*!< End of FLASH Bank 1 Operation Interrupt source */
+#define FLASH_IT_WRPERR_BANK1 FLASH_CR_WRPERRIE /*!< Write Protection Error on Bank 1 Interrupt source */
+#define FLASH_IT_PGSERR_BANK1 FLASH_CR_PGSERRIE /*!< Program Sequence Error on Bank 1 Interrupt source */
+#define FLASH_IT_STRBERR_BANK1 FLASH_CR_STRBERRIE /*!< Strobe Error on Bank 1 Interrupt source */
+#define FLASH_IT_INCERR_BANK1 FLASH_CR_INCERRIE /*!< Inconsistency Error on Bank 1 Interrupt source */
+#if defined (FLASH_CR_OPERRIE)
+#define FLASH_IT_OPERR_BANK1 FLASH_CR_OPERRIE /*!< Operation Error on Bank 1 Interrupt source */
+#endif /* FLASH_CR_OPERRIE */
+#define FLASH_IT_RDPERR_BANK1 FLASH_CR_RDPERRIE /*!< Read protection Error on Bank 1 Interrupt source */
+#define FLASH_IT_RDSERR_BANK1 FLASH_CR_RDSERRIE /*!< Read Secured Error on Bank 1 Interrupt source */
+#define FLASH_IT_SNECCERR_BANK1 FLASH_CR_SNECCERRIE /*!< Single ECC Error Correction on Bank 1 Interrupt source */
+#define FLASH_IT_DBECCERR_BANK1 FLASH_CR_DBECCERRIE /*!< Double Detection ECC Error on Bank 1 Interrupt source */
+#define FLASH_IT_CRCEND_BANK1 FLASH_CR_CRCENDIE /*!< CRC End on Bank 1 Interrupt source */
+#define FLASH_IT_CRCRDERR_BANK1 FLASH_CR_CRCRDERRIE /*!< CRC Read error on Bank 1 Interrupt source */
+
+#if defined (FLASH_CR_OPERRIE)
+#define FLASH_IT_ALL_BANK1 (FLASH_IT_EOP_BANK1 | FLASH_IT_WRPERR_BANK1 | \
+ FLASH_IT_PGSERR_BANK1 | FLASH_IT_STRBERR_BANK1 | \
+ FLASH_IT_INCERR_BANK1 | FLASH_IT_OPERR_BANK1 | \
+ FLASH_IT_RDPERR_BANK1 | FLASH_IT_RDSERR_BANK1 | \
+ FLASH_IT_SNECCERR_BANK1 | FLASH_IT_DBECCERR_BANK1 | \
+ FLASH_IT_CRCEND_BANK1 | FLASH_IT_CRCRDERR_BANK1) /*!< All Bank 1 Interrupt sources */
+#else
+#define FLASH_IT_ALL_BANK1 (FLASH_IT_EOP_BANK1 | FLASH_IT_WRPERR_BANK1 | \
+ FLASH_IT_PGSERR_BANK1 | FLASH_IT_STRBERR_BANK1 | \
+ FLASH_IT_INCERR_BANK1 | FLASH_IT_RDPERR_BANK1 | \
+ FLASH_IT_RDSERR_BANK1 | FLASH_IT_SNECCERR_BANK1 | \
+ FLASH_IT_DBECCERR_BANK1 | FLASH_IT_CRCEND_BANK1 | \
+ FLASH_IT_CRCRDERR_BANK1) /*!< All Bank 1 Interrupt sources */
+#endif /* FLASH_CR_OPERRIE */
+
+#define FLASH_IT_EOP_BANK2 (FLASH_CR_EOPIE | 0x80000000U) /*!< End of FLASH Bank 2 Operation Interrupt source */
+#define FLASH_IT_WRPERR_BANK2 (FLASH_CR_WRPERRIE | 0x80000000U) /*!< Write Protection Error on Bank 2 Interrupt source */
+#define FLASH_IT_PGSERR_BANK2 (FLASH_CR_PGSERRIE | 0x80000000U) /*!< Program Sequence Error on Bank 2 Interrupt source */
+#define FLASH_IT_STRBERR_BANK2 (FLASH_CR_STRBERRIE | 0x80000000U) /*!< Strobe Error on Bank 2 Interrupt source */
+#define FLASH_IT_INCERR_BANK2 (FLASH_CR_INCERRIE | 0x80000000U) /*!< Inconsistency Error on Bank 2 Interrupt source */
+#if defined (FLASH_CR_OPERRIE)
+#define FLASH_IT_OPERR_BANK2 (FLASH_CR_OPERRIE | 0x80000000U) /*!< Operation Error on Bank 2 Interrupt source */
+#endif /* FLASH_CR_OPERRIE */
+#define FLASH_IT_RDPERR_BANK2 (FLASH_CR_RDPERRIE | 0x80000000U) /*!< Read protection Error on Bank 2 Interrupt source */
+#define FLASH_IT_RDSERR_BANK2 (FLASH_CR_RDSERRIE | 0x80000000U) /*!< Read Secured Error on Bank 2 Interrupt source */
+#define FLASH_IT_SNECCERR_BANK2 (FLASH_CR_SNECCERRIE | 0x80000000U) /*!< Single ECC Error Correction on Bank 2 Interrupt source */
+#define FLASH_IT_DBECCERR_BANK2 (FLASH_CR_DBECCERRIE | 0x80000000U) /*!< Double Detection ECC Error on Bank 2 Interrupt source */
+#define FLASH_IT_CRCEND_BANK2 (FLASH_CR_CRCENDIE | 0x80000000U) /*!< CRC End on Bank 2 Interrupt source */
+#define FLASH_IT_CRCRDERR_BANK2 (FLASH_CR_CRCRDERRIE | 0x80000000U) /*!< CRC Read Error on Bank 2 Interrupt source */
+
+#if defined (FLASH_CR_OPERRIE)
+#define FLASH_IT_ALL_BANK2 (FLASH_IT_EOP_BANK2 | FLASH_IT_WRPERR_BANK2 | \
+ FLASH_IT_PGSERR_BANK2 | FLASH_IT_STRBERR_BANK2 | \
+ FLASH_IT_INCERR_BANK2 | FLASH_IT_OPERR_BANK2 | \
+ FLASH_IT_RDPERR_BANK2 | FLASH_IT_RDSERR_BANK2 | \
+ FLASH_IT_SNECCERR_BANK2 | FLASH_IT_DBECCERR_BANK2 | \
+ FLASH_IT_CRCEND_BANK2 | FLASH_IT_CRCRDERR_BANK2) /*!< All Bank 2 Interrupt sources */
+#else
+#define FLASH_IT_ALL_BANK2 (FLASH_IT_EOP_BANK2 | FLASH_IT_WRPERR_BANK2 | \
+ FLASH_IT_PGSERR_BANK2 | FLASH_IT_STRBERR_BANK2 | \
+ FLASH_IT_INCERR_BANK2 | FLASH_IT_RDPERR_BANK2 | \
+ FLASH_IT_RDSERR_BANK2 | FLASH_IT_SNECCERR_BANK2 | \
+ FLASH_IT_DBECCERR_BANK2 | FLASH_IT_CRCEND_BANK2 | \
+ FLASH_IT_CRCRDERR_BANK2) /*!< All Bank 2 Interrupt sources */
+#endif /* FLASH_CR_OPERRIE */
+/**
+ * @}
+ */
+
+#if defined (FLASH_CR_PSIZE)
+/** @defgroup FLASH_Program_Parallelism FLASH Program Parallelism
+ * @{
+ */
+#define FLASH_PSIZE_BYTE 0x00000000U /*!< Flash program/erase by 8 bits */
+#define FLASH_PSIZE_HALF_WORD FLASH_CR_PSIZE_0 /*!< Flash program/erase by 16 bits */
+#define FLASH_PSIZE_WORD FLASH_CR_PSIZE_1 /*!< Flash program/erase by 32 bits */
+#define FLASH_PSIZE_DOUBLE_WORD FLASH_CR_PSIZE /*!< Flash program/erase by 64 bits */
+/**
+ * @}
+ */
+#endif /* FLASH_CR_PSIZE */
+
+
+/** @defgroup FLASH_Keys FLASH Keys
+ * @{
+ */
+#define FLASH_KEY1 0x45670123U
+#define FLASH_KEY2 0xCDEF89ABU
+#define FLASH_OPT_KEY1 0x08192A3BU
+#define FLASH_OPT_KEY2 0x4C5D6E7FU
+/**
+ * @}
+ */
+
+/** @defgroup FLASH_Sectors FLASH Sectors
+ * @{
+ */
+#define FLASH_SECTOR_0 0U /*!< Sector Number 0 */
+#define FLASH_SECTOR_1 1U /*!< Sector Number 1 */
+#define FLASH_SECTOR_2 2U /*!< Sector Number 2 */
+#define FLASH_SECTOR_3 3U /*!< Sector Number 3 */
+#define FLASH_SECTOR_4 4U /*!< Sector Number 4 */
+#define FLASH_SECTOR_5 5U /*!< Sector Number 5 */
+#define FLASH_SECTOR_6 6U /*!< Sector Number 6 */
+#define FLASH_SECTOR_7 7U /*!< Sector Number 7 */
+#if (FLASH_SECTOR_TOTAL == 128)
+#define FLASH_SECTOR_8 8U /*!< Sector Number 8 */
+#define FLASH_SECTOR_9 9U /*!< Sector Number 9 */
+#define FLASH_SECTOR_10 10U /*!< Sector Number 10 */
+#define FLASH_SECTOR_11 11U /*!< Sector Number 11 */
+#define FLASH_SECTOR_12 12U /*!< Sector Number 12 */
+#define FLASH_SECTOR_13 13U /*!< Sector Number 13 */
+#define FLASH_SECTOR_14 14U /*!< Sector Number 14 */
+#define FLASH_SECTOR_15 15U /*!< Sector Number 15 */
+#define FLASH_SECTOR_16 16U /*!< Sector Number 16 */
+#define FLASH_SECTOR_17 17U /*!< Sector Number 17 */
+#define FLASH_SECTOR_18 18U /*!< Sector Number 18 */
+#define FLASH_SECTOR_19 19U /*!< Sector Number 19 */
+#define FLASH_SECTOR_20 20U /*!< Sector Number 20 */
+#define FLASH_SECTOR_21 21U /*!< Sector Number 21 */
+#define FLASH_SECTOR_22 22U /*!< Sector Number 22 */
+#define FLASH_SECTOR_23 23U /*!< Sector Number 23 */
+#define FLASH_SECTOR_24 24U /*!< Sector Number 24 */
+#define FLASH_SECTOR_25 25U /*!< Sector Number 25 */
+#define FLASH_SECTOR_26 26U /*!< Sector Number 26 */
+#define FLASH_SECTOR_27 27U /*!< Sector Number 27 */
+#define FLASH_SECTOR_28 28U /*!< Sector Number 28 */
+#define FLASH_SECTOR_29 29U /*!< Sector Number 29 */
+#define FLASH_SECTOR_30 30U /*!< Sector Number 30 */
+#define FLASH_SECTOR_31 31U /*!< Sector Number 31 */
+#define FLASH_SECTOR_32 32U /*!< Sector Number 32 */
+#define FLASH_SECTOR_33 33U /*!< Sector Number 33 */
+#define FLASH_SECTOR_34 34U /*!< Sector Number 34 */
+#define FLASH_SECTOR_35 35U /*!< Sector Number 35 */
+#define FLASH_SECTOR_36 36U /*!< Sector Number 36 */
+#define FLASH_SECTOR_37 37U /*!< Sector Number 37 */
+#define FLASH_SECTOR_38 38U /*!< Sector Number 38 */
+#define FLASH_SECTOR_39 39U /*!< Sector Number 39 */
+#define FLASH_SECTOR_40 40U /*!< Sector Number 40 */
+#define FLASH_SECTOR_41 41U /*!< Sector Number 41 */
+#define FLASH_SECTOR_42 42U /*!< Sector Number 42 */
+#define FLASH_SECTOR_43 43U /*!< Sector Number 43 */
+#define FLASH_SECTOR_44 44U /*!< Sector Number 44 */
+#define FLASH_SECTOR_45 45U /*!< Sector Number 45 */
+#define FLASH_SECTOR_46 46U /*!< Sector Number 46 */
+#define FLASH_SECTOR_47 47U /*!< Sector Number 47 */
+#define FLASH_SECTOR_48 48U /*!< Sector Number 48 */
+#define FLASH_SECTOR_49 49U /*!< Sector Number 49 */
+#define FLASH_SECTOR_50 50U /*!< Sector Number 50 */
+#define FLASH_SECTOR_51 51U /*!< Sector Number 51 */
+#define FLASH_SECTOR_52 52U /*!< Sector Number 52 */
+#define FLASH_SECTOR_53 53U /*!< Sector Number 53 */
+#define FLASH_SECTOR_54 54U /*!< Sector Number 54 */
+#define FLASH_SECTOR_55 55U /*!< Sector Number 55 */
+#define FLASH_SECTOR_56 56U /*!< Sector Number 56 */
+#define FLASH_SECTOR_57 57U /*!< Sector Number 57 */
+#define FLASH_SECTOR_58 58U /*!< Sector Number 58 */
+#define FLASH_SECTOR_59 59U /*!< Sector Number 59 */
+#define FLASH_SECTOR_60 60U /*!< Sector Number 60 */
+#define FLASH_SECTOR_61 61U /*!< Sector Number 61 */
+#define FLASH_SECTOR_62 62U /*!< Sector Number 62 */
+#define FLASH_SECTOR_63 63U /*!< Sector Number 63 */
+#define FLASH_SECTOR_64 64U /*!< Sector Number 64 */
+#define FLASH_SECTOR_65 65U /*!< Sector Number 65 */
+#define FLASH_SECTOR_66 66U /*!< Sector Number 66 */
+#define FLASH_SECTOR_67 67U /*!< Sector Number 67 */
+#define FLASH_SECTOR_68 68U /*!< Sector Number 68 */
+#define FLASH_SECTOR_69 69U /*!< Sector Number 69 */
+#define FLASH_SECTOR_70 70U /*!< Sector Number 70 */
+#define FLASH_SECTOR_71 71U /*!< Sector Number 71 */
+#define FLASH_SECTOR_72 72U /*!< Sector Number 72 */
+#define FLASH_SECTOR_73 73U /*!< Sector Number 73 */
+#define FLASH_SECTOR_74 74U /*!< Sector Number 74 */
+#define FLASH_SECTOR_75 75U /*!< Sector Number 75 */
+#define FLASH_SECTOR_76 76U /*!< Sector Number 76 */
+#define FLASH_SECTOR_77 77U /*!< Sector Number 77 */
+#define FLASH_SECTOR_78 78U /*!< Sector Number 78 */
+#define FLASH_SECTOR_79 79U /*!< Sector Number 79 */
+#define FLASH_SECTOR_80 80U /*!< Sector Number 80 */
+#define FLASH_SECTOR_81 81U /*!< Sector Number 81 */
+#define FLASH_SECTOR_82 82U /*!< Sector Number 82 */
+#define FLASH_SECTOR_83 83U /*!< Sector Number 83 */
+#define FLASH_SECTOR_84 84U /*!< Sector Number 84 */
+#define FLASH_SECTOR_85 85U /*!< Sector Number 85 */
+#define FLASH_SECTOR_86 86U /*!< Sector Number 86 */
+#define FLASH_SECTOR_87 87U /*!< Sector Number 87 */
+#define FLASH_SECTOR_88 88U /*!< Sector Number 88 */
+#define FLASH_SECTOR_89 89U /*!< Sector Number 89 */
+#define FLASH_SECTOR_90 90U /*!< Sector Number 90 */
+#define FLASH_SECTOR_91 91U /*!< Sector Number 91 */
+#define FLASH_SECTOR_92 92U /*!< Sector Number 92 */
+#define FLASH_SECTOR_93 93U /*!< Sector Number 93 */
+#define FLASH_SECTOR_94 94U /*!< Sector Number 94 */
+#define FLASH_SECTOR_95 95U /*!< Sector Number 95 */
+#define FLASH_SECTOR_96 96U /*!< Sector Number 96 */
+#define FLASH_SECTOR_97 97U /*!< Sector Number 97 */
+#define FLASH_SECTOR_98 98U /*!< Sector Number 98 */
+#define FLASH_SECTOR_99 99U /*!< Sector Number 99 */
+#define FLASH_SECTOR_100 100U /*!< Sector Number 100 */
+#define FLASH_SECTOR_101 101U /*!< Sector Number 101 */
+#define FLASH_SECTOR_102 102U /*!< Sector Number 102 */
+#define FLASH_SECTOR_103 103U /*!< Sector Number 103 */
+#define FLASH_SECTOR_104 104U /*!< Sector Number 104 */
+#define FLASH_SECTOR_105 105U /*!< Sector Number 105 */
+#define FLASH_SECTOR_106 106U /*!< Sector Number 106 */
+#define FLASH_SECTOR_107 107U /*!< Sector Number 107 */
+#define FLASH_SECTOR_108 108U /*!< Sector Number 108 */
+#define FLASH_SECTOR_109 109U /*!< Sector Number 109 */
+#define FLASH_SECTOR_110 110U /*!< Sector Number 110 */
+#define FLASH_SECTOR_111 111U /*!< Sector Number 111 */
+#define FLASH_SECTOR_112 112U /*!< Sector Number 112 */
+#define FLASH_SECTOR_113 113U /*!< Sector Number 113 */
+#define FLASH_SECTOR_114 114U /*!< Sector Number 114 */
+#define FLASH_SECTOR_115 115U /*!< Sector Number 115 */
+#define FLASH_SECTOR_116 116U /*!< Sector Number 116 */
+#define FLASH_SECTOR_117 117U /*!< Sector Number 117 */
+#define FLASH_SECTOR_118 118U /*!< Sector Number 118 */
+#define FLASH_SECTOR_119 119U /*!< Sector Number 119 */
+#define FLASH_SECTOR_120 120U /*!< Sector Number 120 */
+#define FLASH_SECTOR_121 121U /*!< Sector Number 121 */
+#define FLASH_SECTOR_122 122U /*!< Sector Number 122 */
+#define FLASH_SECTOR_123 123U /*!< Sector Number 123 */
+#define FLASH_SECTOR_124 124U /*!< Sector Number 124 */
+#define FLASH_SECTOR_125 125U /*!< Sector Number 125 */
+#define FLASH_SECTOR_126 126U /*!< Sector Number 126 */
+#define FLASH_SECTOR_127 127U /*!< Sector Number 127 */
+#endif /* FLASH_SECTOR_TOTAL == 128 */
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/* Exported macro ------------------------------------------------------------*/
+/** @defgroup FLASH_Exported_Macros FLASH Exported Macros
+ * @{
+ */
+/**
+ * @brief Set the FLASH Latency.
+ * @param __LATENCY__: FLASH Latency
+ * The value of this parameter depend on device used within the same series
+ * @retval none
+ */
+#define __HAL_FLASH_SET_LATENCY(__LATENCY__) \
+ MODIFY_REG(FLASH->ACR, FLASH_ACR_LATENCY, (uint32_t)(__LATENCY__))
+
+/**
+ * @brief Get the FLASH Latency.
+ * @retval FLASH Latency
+ * The value of this parameter depend on device used within the same series
+ */
+#define __HAL_FLASH_GET_LATENCY() (READ_BIT((FLASH->ACR), FLASH_ACR_LATENCY))
+
+/**
+ * @brief Enable the specified FLASH interrupt.
+ * @param __INTERRUPT__ : FLASH interrupt
+ * In case of Bank 1 This parameter can be any combination of the following values:
+ * @arg FLASH_IT_EOP_BANK1 : End of FLASH Bank 1 Operation Interrupt source
+ * @arg FLASH_IT_WRPERR_BANK1 : Write Protection Error on Bank 1 Interrupt source
+ * @arg FLASH_IT_PGSERR_BANK1 : Program Sequence Error on Bank 1 Interrupt source
+ * @arg FLASH_IT_STRBERR_BANK1 : Strobe Error on Bank 1 Interrupt source
+ * @arg FLASH_IT_INCERR_BANK1 : Inconsistency Error on Bank 1 Interrupt source
+ * @arg FLASH_IT_OPERR_BANK1 : Operation Error on Bank 1 Interrupt source
+ * @arg FLASH_IT_RDPERR_BANK1 : Read protection Error on Bank 1 Interrupt source
+ * @arg FLASH_IT_RDSERR_BANK1 : Read secure Error on Bank 1 Interrupt source
+ * @arg FLASH_IT_SNECCERR_BANK1 : Single ECC Error Correction on Bank 1 Interrupt source
+ * @arg FLASH_IT_DBECCERR_BANK1 : Double Detection ECC Error on Bank 1 Interrupt source
+ * @arg FLASH_IT_CRCEND_BANK1 : CRC End on Bank 1 Interrupt source
+ * @arg FLASH_IT_CRCRDERR_BANK1 : CRC Read error on Bank 1 Interrupt source
+ * @arg FLASH_IT_ALL_BANK1 : All Bank 1 Interrupt sources
+ *
+ * In case of Bank 2, this parameter can be any combination of the following values:
+ * @arg FLASH_IT_EOP_BANK2 : End of FLASH Bank 2 Operation Interrupt source
+ * @arg FLASH_IT_WRPERR_BANK2 : Write Protection Error on Bank 2 Interrupt source
+ * @arg FLASH_IT_PGSERR_BANK2 : Program Sequence Error on Bank 2 Interrupt source
+ * @arg FLASH_IT_STRBERR_BANK2 : Strobe Error on Bank 2 Interrupt source
+ * @arg FLASH_IT_INCERR_BANK2 : Inconsistency Error on Bank 2 Interrupt source
+ * @arg FLASH_IT_OPERR_BANK2 : Operation Error on Bank 2 Interrupt source
+ * @arg FLASH_IT_RDPERR_BANK2 : Read protection Error on Bank 2 Interrupt source
+ * @arg FLASH_IT_RDSERR_BANK2 : Read secure Error on Bank 2 Interrupt source
+ * @arg FLASH_IT_SNECCERR_BANK2 : Single ECC Error Correction on Bank 2 Interrupt source
+ * @arg FLASH_IT_DBECCERR_BANK2 : Double Detection ECC Error on Bank 2 Interrupt source
+ * @arg FLASH_IT_CRCEND_BANK2 : CRC End on Bank 2 Interrupt source
+ * @arg FLASH_IT_CRCRDERR_BANK2 : CRC Read error on Bank 2 Interrupt source
+ * @arg FLASH_IT_ALL_BANK2 : All Bank 2 Interrupt sources
+ * @retval none
+ */
+
+#define __HAL_FLASH_ENABLE_IT_BANK1(__INTERRUPT__) (FLASH->CR1 |= (__INTERRUPT__))
+
+#define __HAL_FLASH_ENABLE_IT_BANK2(__INTERRUPT__) (FLASH->CR2 |= ((__INTERRUPT__) & 0x7FFFFFFFU))
+
+#if defined (DUAL_BANK)
+#define __HAL_FLASH_ENABLE_IT(__INTERRUPT__) (IS_FLASH_IT_BANK1(__INTERRUPT__) ? \
+ __HAL_FLASH_ENABLE_IT_BANK1(__INTERRUPT__) : \
+ __HAL_FLASH_ENABLE_IT_BANK2(__INTERRUPT__))
+#else
+#define __HAL_FLASH_ENABLE_IT(__INTERRUPT__) __HAL_FLASH_ENABLE_IT_BANK1(__INTERRUPT__)
+#endif /* DUAL_BANK */
+
+
+/**
+ * @brief Disable the specified FLASH interrupt.
+ * @param __INTERRUPT__ : FLASH interrupt
+ * In case of Bank 1 This parameter can be any combination of the following values:
+ * @arg FLASH_IT_EOP_BANK1 : End of FLASH Bank 1 Operation Interrupt source
+ * @arg FLASH_IT_WRPERR_BANK1 : Write Protection Error on Bank 1 Interrupt source
+ * @arg FLASH_IT_PGSERR_BANK1 : Program Sequence Error on Bank 1 Interrupt source
+ * @arg FLASH_IT_STRBERR_BANK1 : Strobe Error on Bank 1 Interrupt source
+ * @arg FLASH_IT_INCERR_BANK1 : Inconsistency Error on Bank 1 Interrupt source
+ * @arg FLASH_IT_OPERR_BANK1 : Operation Error on Bank 1 Interrupt source
+ * @arg FLASH_IT_RDPERR_BANK1 : Read protection Error on Bank 1 Interrupt source
+ * @arg FLASH_IT_RDSERR_BANK1 : Read secure Error on Bank 1 Interrupt source
+ * @arg FLASH_IT_SNECCERR_BANK1 : Single ECC Error Correction on Bank 1 Interrupt source
+ * @arg FLASH_IT_DBECCERR_BANK1 : Double Detection ECC Error on Bank 1 Interrupt source
+ * @arg FLASH_IT_CRCEND_BANK1 : CRC End on Bank 1 Interrupt source
+ * @arg FLASH_IT_CRCRDERR_BANK1 : CRC Read error on Bank 1 Interrupt source
+ * @arg FLASH_IT_ALL_BANK1 : All Bank 1 Interrupt sources
+ *
+ * In case of Bank 2, this parameter can be any combination of the following values:
+ * @arg FLASH_IT_EOP_BANK2 : End of FLASH Bank 2 Operation Interrupt source
+ * @arg FLASH_IT_WRPERR_BANK2 : Write Protection Error on Bank 2 Interrupt source
+ * @arg FLASH_IT_PGSERR_BANK2 : Program Sequence Error on Bank 2 Interrupt source
+ * @arg FLASH_IT_STRBERR_BANK2 : Strobe Error on Bank 2 Interrupt source
+ * @arg FLASH_IT_INCERR_BANK2 : Inconsistency Error on Bank 2 Interrupt source
+ * @arg FLASH_IT_OPERR_BANK2 : Operation Error on Bank 2 Interrupt source
+ * @arg FLASH_IT_RDPERR_BANK2 : Read protection Error on Bank 2 Interrupt source
+ * @arg FLASH_IT_RDSERR_BANK2 : Read secure Error on Bank 2 Interrupt source
+ * @arg FLASH_IT_SNECCERR_BANK2 : Single ECC Error Correction on Bank 2 Interrupt source
+ * @arg FLASH_IT_DBECCERR_BANK2 : Double Detection ECC Error on Bank 2 Interrupt source
+ * @arg FLASH_IT_CRCEND_BANK2 : CRC End on Bank 2 Interrupt source
+ * @arg FLASH_IT_CRCRDERR_BANK2 : CRC Read error on Bank 2 Interrupt source
+ * @arg FLASH_IT_ALL_BANK2 : All Bank 2 Interrupt sources
+ * @retval none
+ */
+
+#define __HAL_FLASH_DISABLE_IT_BANK1(__INTERRUPT__) (FLASH->CR1 &= ~(uint32_t)(__INTERRUPT__))
+
+#define __HAL_FLASH_DISABLE_IT_BANK2(__INTERRUPT__) (FLASH->CR2 &= ~(uint32_t)((__INTERRUPT__) & 0x7FFFFFFFU))
+
+#if defined (DUAL_BANK)
+#define __HAL_FLASH_DISABLE_IT(__INTERRUPT__) (IS_FLASH_IT_BANK1(__INTERRUPT__) ? \
+ __HAL_FLASH_DISABLE_IT_BANK1(__INTERRUPT__) : \
+ __HAL_FLASH_DISABLE_IT_BANK2(__INTERRUPT__))
+#else
+#define __HAL_FLASH_DISABLE_IT(__INTERRUPT__) __HAL_FLASH_DISABLE_IT_BANK1(__INTERRUPT__)
+#endif /* DUAL_BANK */
+
+
+/**
+ * @brief Checks whether the specified FLASH flag is set or not.
+ * @param __FLAG__: specifies the FLASH flag to check.
+ * In case of Bank 1 This parameter can be one of the following values :
+ * @arg FLASH_FLAG_BSY_BANK1 : FLASH Bank 1 Busy flag
+ * @arg FLASH_FLAG_WBNE_BANK1 : Write Buffer Not Empty on Bank 1 flag
+ * @arg FLASH_FLAG_QW_BANK1 : Wait Queue on Bank 1 flag
+ * @arg FLASH_FLAG_CRC_BUSY_BANK1 : CRC module is working on Bank 1 flag
+ * @arg FLASH_FLAG_EOP_BANK1 : End Of Program on Bank 1 flag
+ * @arg FLASH_FLAG_WRPERR_BANK1 : Write Protection Error on Bank 1 flag
+ * @arg FLASH_FLAG_PGSERR_BANK1 : Program Sequence Error on Bank 1 flag
+ * @arg FLASH_FLAG_STRBER_BANK1 : Program Alignment Error on Bank 1 flag
+ * @arg FLASH_FLAG_INCERR_BANK1 : Inconsistency Error on Bank 1 flag
+ * @arg FLASH_FLAG_OPERR_BANK1 : Operation Error on Bank 1 flag
+ * @arg FLASH_FLAG_RDPERR_BANK1 : Read Protection Error on Bank 1 flag
+ * @arg FLASH_FLAG_RDSERR_BANK1 : Read secure Error on Bank 1 flag
+ * @arg FLASH_FLAG_SNECCE_BANK1 : Single ECC Error Correction on Bank 1 flag
+ * @arg FLASH_FLAG_DBECCE_BANK1 : Double Detection ECC Error on Bank 1 flag
+ * @arg FLASH_FLAG_CRCEND_BANK1 : CRC End on Bank 1 flag
+ * @arg FLASH_FLAG_CRCRDERR_BANK1 : CRC Read error on Bank 1 flag
+ *
+ * In case of Bank 2 This parameter can be one of the following values :
+ * @arg FLASH_FLAG_BSY_BANK2 : FLASH Bank 2 Busy flag
+ * @arg FLASH_FLAG_WBNE_BANK2 : Write Buffer Not Empty on Bank 2 flag
+ * @arg FLASH_FLAG_QW_BANK2 : Wait Queue on Bank 2 flag
+ * @arg FLASH_FLAG_CRC_BUSY_BANK2 : CRC module is working on Bank 2 flag
+ * @arg FLASH_FLAG_EOP_BANK2 : End Of Program on Bank 2 flag
+ * @arg FLASH_FLAG_WRPERR_BANK2 : Write Protection Error on Bank 2 flag
+ * @arg FLASH_FLAG_PGSERR_BANK2 : Program Sequence Error on Bank 2 flag
+ * @arg FLASH_FLAG_STRBER_BANK2 : Program Alignment Error on Bank 2 flag
+ * @arg FLASH_FLAG_INCERR_BANK2 : Inconsistency Error on Bank 2 flag
+ * @arg FLASH_FLAG_OPERR_BANK2 : Operation Error on Bank 2 flag
+ * @arg FLASH_FLAG_RDPERR_BANK2 : Read Protection Error on Bank 2 flag
+ * @arg FLASH_FLAG_RDSERR_BANK2 : Read secure Error on Bank 2 flag
+ * @arg FLASH_FLAG_SNECCE_BANK2 : Single ECC Error Correction on Bank 2 flag
+ * @arg FLASH_FLAG_DBECCE_BANK2 : Double Detection ECC Error on Bank 2 flag
+ * @arg FLASH_FLAG_CRCEND_BANK2 : CRC End on Bank 2 flag
+ * @arg FLASH_FLAG_CRCRDERR_BANK2 : CRC Read error on Bank 2 flag
+ * @retval The new state of FLASH_FLAG (SET or RESET).
+ */
+#define __HAL_FLASH_GET_FLAG_BANK1(__FLAG__) (READ_BIT(FLASH->SR1, (__FLAG__)) == (__FLAG__))
+
+#define __HAL_FLASH_GET_FLAG_BANK2(__FLAG__) (READ_BIT(FLASH->SR2, ((__FLAG__) & 0x7FFFFFFFU)) == (((__FLAG__) & 0x7FFFFFFFU)))
+
+#if defined (DUAL_BANK)
+#define __HAL_FLASH_GET_FLAG(__FLAG__) (IS_FLASH_FLAG_BANK1(__FLAG__) ? __HAL_FLASH_GET_FLAG_BANK1(__FLAG__) : \
+ __HAL_FLASH_GET_FLAG_BANK2(__FLAG__))
+#else
+#define __HAL_FLASH_GET_FLAG(__FLAG__) __HAL_FLASH_GET_FLAG_BANK1(__FLAG__)
+#endif /* DUAL_BANK */
+
+
+/**
+ * @brief Clear the specified FLASH flag.
+ * @param __FLAG__: specifies the FLASH flags to clear.
+ * In case of Bank 1, this parameter can be any combination of the following values:
+ * @arg FLASH_FLAG_EOP_BANK1 : End Of Program on Bank 1 flag
+ * @arg FLASH_FLAG_WRPERR_BANK1 : Write Protection Error on Bank 1 flag
+ * @arg FLASH_FLAG_PGSERR_BANK1 : Program Sequence Error on Bank 1 flag
+ * @arg FLASH_FLAG_STRBER_BANK1 : Program Alignment Error on Bank 1 flag
+ * @arg FLASH_FLAG_INCERR_BANK1 : Inconsistency Error on Bank 1 flag
+ * @arg FLASH_FLAG_OPERR_BANK1 : Operation Error on Bank 1 flag
+ * @arg FLASH_FLAG_RDPERR_BANK1 : Read Protection Error on Bank 1 flag
+ * @arg FLASH_FLAG_RDSERR_BANK1 : Read secure Error on Bank 1 flag
+ * @arg FLASH_FLAG_SNECCE_BANK1 : Single ECC Error Correction on Bank 1 flag
+ * @arg FLASH_FLAG_DBECCE_BANK1 : Double Detection ECC Error on Bank 1 flag
+ * @arg FLASH_FLAG_CRCEND_BANK1 : CRC End on Bank 1 flag
+ * @arg FLASH_FLAG_CRCRDERR_BANK1 : CRC Read error on Bank 1 flag
+ * @arg FLASH_FLAG_ALL_ERRORS_BANK1 : All Bank 1 error flags
+ * @arg FLASH_FLAG_ALL_BANK1 : All Bank 1 flags
+ *
+ * In case of Bank 2, this parameter can be any combination of the following values :
+ * @arg FLASH_FLAG_EOP_BANK2 : End Of Program on Bank 2 flag
+ * @arg FLASH_FLAG_WRPERR_BANK2 : Write Protection Error on Bank 2 flag
+ * @arg FLASH_FLAG_PGSERR_BANK2 : Program Sequence Error on Bank 2 flag
+ * @arg FLASH_FLAG_STRBER_BANK2 : Program Alignment Error on Bank 2 flag
+ * @arg FLASH_FLAG_INCERR_BANK2 : Inconsistency Error on Bank 2 flag
+ * @arg FLASH_FLAG_OPERR_BANK2 : Operation Error on Bank 2 flag
+ * @arg FLASH_FLAG_RDPERR_BANK2 : Read Protection Error on Bank 2 flag
+ * @arg FLASH_FLAG_RDSERR_BANK2 : Read secure Error on Bank 2 flag
+ * @arg FLASH_FLAG_SNECCE_BANK2 : Single ECC Error Correction on Bank 2 flag
+ * @arg FLASH_FLAG_DBECCE_BANK2 : Double Detection ECC Error on Bank 2 flag
+ * @arg FLASH_FLAG_CRCEND_BANK2 : CRC End on Bank 2 flag
+ * @arg FLASH_FLAG_CRCRDERR_BANK2 : CRC Read error on Bank 2 flag
+ * @arg FLASH_FLAG_ALL_ERRORS_BANK2 : All Bank 2 error flags
+ * @arg FLASH_FLAG_ALL_BANK2 : All Bank 2 flags
+ * @retval none
+ */
+
+#define __HAL_FLASH_CLEAR_FLAG_BANK1(__FLAG__) WRITE_REG(FLASH->CCR1, (__FLAG__))
+
+#define __HAL_FLASH_CLEAR_FLAG_BANK2(__FLAG__) WRITE_REG(FLASH->CCR2, ((__FLAG__) & 0x7FFFFFFFU))
+
+#if defined (DUAL_BANK)
+#define __HAL_FLASH_CLEAR_FLAG(__FLAG__) (IS_FLASH_FLAG_BANK1(__FLAG__) ? __HAL_FLASH_CLEAR_FLAG_BANK1(__FLAG__) : \
+ __HAL_FLASH_CLEAR_FLAG_BANK2(__FLAG__))
+#else
+#define __HAL_FLASH_CLEAR_FLAG(__FLAG__) __HAL_FLASH_CLEAR_FLAG_BANK1(__FLAG__)
+#endif /* DUAL_BANK */
+
+/**
+ * @}
+ */
+
+/* Include FLASH HAL Extension module */
+#include "stm32h7xx_hal_flash_ex.h"
+
+/* Exported functions --------------------------------------------------------*/
+/** @addtogroup FLASH_Exported_Functions
+ * @{
+ */
+/** @addtogroup FLASH_Exported_Functions_Group1
+ * @{
+ */
+/* Program operation functions ***********************************************/
+HAL_StatusTypeDef HAL_FLASH_Program(uint32_t TypeProgram, uint32_t FlashAddress, uint32_t DataAddress);
+HAL_StatusTypeDef HAL_FLASH_Program_IT(uint32_t TypeProgram, uint32_t FlashAddress, uint32_t DataAddress);
+/* FLASH IRQ handler method */
+void HAL_FLASH_IRQHandler(void);
+/* Callbacks in non blocking modes */
+void HAL_FLASH_EndOfOperationCallback(uint32_t ReturnValue);
+void HAL_FLASH_OperationErrorCallback(uint32_t ReturnValue);
+/**
+ * @}
+ */
+
+/** @addtogroup FLASH_Exported_Functions_Group2
+ * @{
+ */
+/* Peripheral Control functions **********************************************/
+HAL_StatusTypeDef HAL_FLASH_Unlock(void);
+HAL_StatusTypeDef HAL_FLASH_Lock(void);
+HAL_StatusTypeDef HAL_FLASH_OB_Unlock(void);
+HAL_StatusTypeDef HAL_FLASH_OB_Lock(void);
+/* Option bytes control */
+HAL_StatusTypeDef HAL_FLASH_OB_Launch(void);
+/**
+ * @}
+ */
+
+/** @addtogroup FLASH_Exported_Functions_Group3
+ * @{
+ */
+/* Peripheral State functions ************************************************/
+uint32_t HAL_FLASH_GetError(void);
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+/* Private types -------------------------------------------------------------*/
+/* Private variables ---------------------------------------------------------*/
+/** @defgroup FLASH_Private_Variables FLASH Private Variables
+ * @{
+ */
+extern FLASH_ProcessTypeDef pFlash;
+/**
+ * @}
+ */
+/* Private constants ---------------------------------------------------------*/
+/** @defgroup FLASH_Private_Constants FLASH Private Constants
+ * @{
+ */
+
+/**
+ * @}
+ */
+
+/* Private macros ------------------------------------------------------------*/
+/** @defgroup FLASH_Private_Macros FLASH Private Macros
+ * @{
+ */
+
+#if defined (FLASH_OPTCR_PG_OTP)
+#define IS_FLASH_TYPEPROGRAM(VALUE) (((VALUE) == FLASH_TYPEPROGRAM_FLASHWORD) || \
+ ((VALUE) == FLASH_TYPEPROGRAM_OTPWORD))
+#else
+#define IS_FLASH_TYPEPROGRAM(VALUE) ((VALUE) == FLASH_TYPEPROGRAM_FLASHWORD)
+#endif /* FLASH_OPTCR_PG_OTP */
+
+#define IS_FLASH_IT_BANK1(IT) (((IT) & FLASH_IT_ALL_BANK1) == (IT))
+#if defined (DUAL_BANK)
+#define IS_FLASH_IT_BANK2(IT) (((IT) & FLASH_IT_ALL_BANK2) == (IT))
+#endif /* DUAL_BANK */
+
+#define IS_FLASH_FLAG_BANK1(FLAG) (((FLAG) & FLASH_FLAG_ALL_BANK1) == (FLAG))
+#if defined (DUAL_BANK)
+#define IS_FLASH_FLAG_BANK2(FLAG) (((FLAG) & FLASH_FLAG_ALL_BANK2) == (FLAG))
+#endif /* DUAL_BANK */
+
+#if defined (DUAL_BANK)
+#define IS_FLASH_PROGRAM_ADDRESS_BANK1(ADDRESS) (((ADDRESS) >= FLASH_BANK1_BASE) && ((ADDRESS) < FLASH_BANK2_BASE))
+#define IS_FLASH_PROGRAM_ADDRESS_BANK2(ADDRESS) (((ADDRESS) >= FLASH_BANK2_BASE ) && ((ADDRESS) <= FLASH_END))
+#else
+#define IS_FLASH_PROGRAM_ADDRESS_BANK1(ADDRESS) (((ADDRESS) >= FLASH_BANK1_BASE) && ((ADDRESS) <= FLASH_END))
+#endif /* DUAL_BANK */
+
+#if defined (DUAL_BANK)
+#if defined (FLASH_OPTCR_PG_OTP)
+#define IS_FLASH_PROGRAM_ADDRESS_OTP(ADDRESS) (((ADDRESS) >= 0x08FFF000U) && ((ADDRESS) <= 0x08FFF3FFU))
+#define IS_FLASH_PROGRAM_ADDRESS(ADDRESS) (IS_FLASH_PROGRAM_ADDRESS_BANK1(ADDRESS) || \
+ IS_FLASH_PROGRAM_ADDRESS_BANK2(ADDRESS) || \
+ IS_FLASH_PROGRAM_ADDRESS_OTP(ADDRESS))
+#else
+#define IS_FLASH_PROGRAM_ADDRESS(ADDRESS) (IS_FLASH_PROGRAM_ADDRESS_BANK1(ADDRESS) || \
+ IS_FLASH_PROGRAM_ADDRESS_BANK2(ADDRESS))
+#endif /* FLASH_OPTCR_PG_OTP */
+#else
+#if defined (FLASH_OPTCR_PG_OTP)
+#define IS_FLASH_PROGRAM_ADDRESS_OTP(ADDRESS) (((ADDRESS) >= 0x08FFF000U) && ((ADDRESS) <= 0x08FFF3FFU))
+#define IS_FLASH_PROGRAM_ADDRESS(ADDRESS) (IS_FLASH_PROGRAM_ADDRESS_BANK1(ADDRESS) || \
+ IS_FLASH_PROGRAM_ADDRESS_OTP(ADDRESS))
+#else
+#define IS_FLASH_PROGRAM_ADDRESS(ADDRESS) (IS_FLASH_PROGRAM_ADDRESS_BANK1(ADDRESS))
+#endif /* FLASH_OPTCR_PG_OTP */
+#endif /* DUAL_BANK */
+
+#define IS_BOOT_ADDRESS(ADDRESS) ((ADDRESS) <= (0x3FFF0000U))
+
+#if defined (DUAL_BANK)
+#define IS_FLASH_BANK(BANK) (((BANK) == FLASH_BANK_1) || \
+ ((BANK) == FLASH_BANK_2) || \
+ ((BANK) == FLASH_BANK_BOTH))
+#define IS_FLASH_BANK_EXCLUSIVE(BANK) (((BANK) == FLASH_BANK_1) || \
+ ((BANK) == FLASH_BANK_2))
+#else
+#define IS_FLASH_BANK(BANK) ((BANK) == FLASH_BANK_1)
+#define IS_FLASH_BANK_EXCLUSIVE(BANK) ((BANK) == FLASH_BANK_1)
+#endif /* DUAL_BANK */
+
+/**
+ * @}
+ */
+/* Private functions ---------------------------------------------------------*/
+/** @defgroup FLASH_Private_Functions FLASH Private functions
+ * @{
+ */
+HAL_StatusTypeDef FLASH_WaitForLastOperation(uint32_t Timeout, uint32_t Bank);
+HAL_StatusTypeDef FLASH_OB_WaitForLastOperation(uint32_t Timeout);
+HAL_StatusTypeDef FLASH_CRC_WaitForLastOperation(uint32_t Timeout, uint32_t Bank);
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* STM32H7xx_HAL_FLASH_H */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/firmware/hw_layer/ports/stm32/stm32h7/stm32h7xx_hal_flash_ex.c b/firmware/hw_layer/ports/stm32/stm32h7/stm32h7xx_hal_flash_ex.c
new file mode 100644
index 0000000000..dc45d4a190
--- /dev/null
+++ b/firmware/hw_layer/ports/stm32/stm32h7/stm32h7xx_hal_flash_ex.c
@@ -0,0 +1,1863 @@
+/**
+ ******************************************************************************
+ * @file stm32h7xx_hal_flash_ex.c
+ * @author MCD Application Team
+ * @brief Extended FLASH HAL module driver.
+ * This file provides firmware functions to manage the following
+ * functionalities of the FLASH extension peripheral:
+ * + Extended programming operations functions
+ *
+ @verbatim
+ ==============================================================================
+ ##### Flash Extension features #####
+ ==============================================================================
+
+ [..] Comparing to other previous devices, the FLASH interface for STM32H7xx
+ devices contains the following additional features
+
+ (+) Capacity up to 2 Mbyte with dual bank architecture supporting read-while-write
+ capability (RWW)
+ (+) Dual bank memory organization
+ (+) PCROP protection for all banks
+ (+) Global readout protection (RDP)
+ (+) Write protection
+ (+) Secure access only protection
+ (+) Bank / register swapping
+ (+) Cyclic Redundancy Check (CRC)
+
+ ##### How to use this driver #####
+ ==============================================================================
+ [..] This driver provides functions to configure and program the FLASH memory
+ of all STM32H7xx devices. It includes
+ (#) FLASH Memory Erase functions:
+ (++) Lock and Unlock the FLASH interface using HAL_FLASH_Unlock() and
+ HAL_FLASH_Lock() functions
+ (++) Erase function: Sector erase, bank erase and dual-bank mass erase
+ (++) There are two modes of erase :
+ (+++) Polling Mode using HAL_FLASHEx_Erase()
+ (+++) Interrupt Mode using HAL_FLASHEx_Erase_IT()
+
+ (#) Option Bytes Programming functions: Use HAL_FLASHEx_OBProgram() to:
+ (++) Set/Reset the write protection per bank
+ (++) Set the Read protection Level
+ (++) Set the BOR level
+ (++) Program the user Option Bytes
+ (++) PCROP protection configuration and control per bank
+ (++) Secure area configuration and control per bank
+ (++) Core Boot address configuration
+ (++) TCM / AXI shared RAM configuration
+ (++) CPU Frequency Boost configuration
+
+ (#) FLASH Memory Lock and unlock per Bank: HAL_FLASHEx_Lock_Bank1(), HAL_FLASHEx_Unlock_Bank1(),
+ HAL_FLASHEx_Lock_Bank2() and HAL_FLASHEx_Unlock_Bank2() functions
+
+ (#) FLASH CRC computation function: Use HAL_FLASHEx_ComputeCRC() to:
+ (++) Enable CRC feature
+ (++) Program the desired burst size
+ (++) Define the user Flash Area on which the CRC has be computed
+ (++) Perform the CRC computation
+ (++) Disable CRC feature
+
+ @endverbatim
+ ******************************************************************************
+ * @attention
+ *
+ * © COPYRIGHT(c) 2017 STMicroelectronics.
+ * All rights reserved.
+ *
+ * This software component is licensed by ST under BSD 3-Clause license,
+ * the "License"; You may not use this file except in compliance with the
+ * License. You may obtain a copy of the License at:
+ * opensource.org/licenses/BSD-3-Clause
+ *
+ ******************************************************************************
+ */
+
+/* Includes ------------------------------------------------------------------*/
+#include "stm32h7xx_hal.h"
+
+/** @addtogroup STM32H7xx_HAL_Driver
+ * @{
+ */
+
+/** @defgroup FLASHEx FLASHEx
+ * @brief FLASH HAL Extension module driver
+ * @{
+ */
+
+#ifdef HAL_FLASH_MODULE_ENABLED
+
+/* Private typedef -----------------------------------------------------------*/
+/* Private define ------------------------------------------------------------*/
+/** @addtogroup FLASHEx_Private_Constants
+ * @{
+ */
+#define FLASH_TIMEOUT_VALUE 50000U /* 50 s */
+
+/**
+ * @}
+ */
+/* Private macro -------------------------------------------------------------*/
+/* Private variables ---------------------------------------------------------*/
+/* Private function prototypes -----------------------------------------------*/
+/** @defgroup FLASHEx_Private_Functions FLASHEx Private Functions
+ * @{
+ */
+static void FLASH_MassErase(uint32_t VoltageRange, uint32_t Banks);
+static void FLASH_OB_EnableWRP(uint32_t WRPSector, uint32_t Banks);
+static void FLASH_OB_DisableWRP(uint32_t WRPSector, uint32_t Bank);
+static void FLASH_OB_GetWRP(uint32_t *WRPState, uint32_t *WRPSector, uint32_t Bank);
+static void FLASH_OB_RDPConfig(uint32_t RDPLevel);
+static uint32_t FLASH_OB_GetRDP(void);
+static void FLASH_OB_PCROPConfig(uint32_t PCROConfigRDP, uint32_t PCROPStartAddr, uint32_t PCROPEndAddr, uint32_t Banks);
+static void FLASH_OB_GetPCROP(uint32_t *PCROPConfig, uint32_t *PCROPStartAddr,uint32_t *PCROPEndAddr, uint32_t Bank);
+static void FLASH_OB_BOR_LevelConfig(uint32_t Level);
+static uint32_t FLASH_OB_GetBOR(void);
+static void FLASH_OB_UserConfig(uint32_t UserType, uint32_t UserConfig);
+static uint32_t FLASH_OB_GetUser(void);
+static void FLASH_OB_BootAddConfig(uint32_t BootOption, uint32_t BootAddress0, uint32_t BootAddress1);
+static void FLASH_OB_GetBootAdd(uint32_t *BootAddress0, uint32_t *BootAddress1);
+static void FLASH_OB_SecureAreaConfig(uint32_t SecureAreaConfig, uint32_t SecureAreaStartAddr, uint32_t SecureAreaEndAddr, uint32_t Banks);
+static void FLASH_OB_GetSecureArea(uint32_t *SecureAreaConfig, uint32_t *SecureAreaStartAddr, uint32_t *SecureAreaEndAddr, uint32_t Bank);
+static void FLASH_CRC_AddSector(uint32_t Sector, uint32_t Bank);
+static void FLASH_CRC_SelectAddress(uint32_t CRCStartAddr, uint32_t CRCEndAddr, uint32_t Bank);
+
+#if defined (DUAL_CORE)
+static void FLASH_OB_CM4BootAddConfig(uint32_t BootOption, uint32_t BootAddress0, uint32_t BootAddress1);
+static void FLASH_OB_GetCM4BootAdd(uint32_t *BootAddress0, uint32_t *BootAddress1);
+#endif /*DUAL_CORE*/
+
+#if defined (FLASH_OTPBL_LOCKBL)
+static void FLASH_OB_OTP_LockConfig(uint32_t OTP_Block);
+static uint32_t FLASH_OB_OTP_GetLock(void);
+#endif /* FLASH_OTPBL_LOCKBL */
+
+#if defined (FLASH_OPTSR2_TCM_AXI_SHARED)
+static void FLASH_OB_SharedRAM_Config(uint32_t SharedRamConfig);
+static uint32_t FLASH_OB_SharedRAM_GetConfig(void);
+#endif /* FLASH_OPTSR2_TCM_AXI_SHARED */
+
+#if defined (FLASH_OPTSR2_CPUFREQ_BOOST)
+static void FLASH_OB_CPUFreq_BoostConfig(uint32_t FreqBoost);
+static uint32_t FLASH_OB_CPUFreq_GetBoost(void);
+#endif /* FLASH_OPTSR2_CPUFREQ_BOOST */
+/**
+ * @}
+ */
+
+/* Exported functions ---------------------------------------------------------*/
+/** @defgroup FLASHEx_Exported_Functions FLASHEx Exported Functions
+ * @{
+ */
+
+/** @defgroup FLASHEx_Exported_Functions_Group1 Extended IO operation functions
+ * @brief Extended IO operation functions
+ *
+@verbatim
+ ===============================================================================
+ ##### Extended programming operation functions #####
+ ===============================================================================
+ [..]
+ This subsection provides a set of functions allowing to manage the Extension FLASH
+ programming operations Operations.
+
+@endverbatim
+ * @{
+ */
+/**
+ * @brief Perform a mass erase or erase the specified FLASH memory sectors
+ * @param[in] pEraseInit pointer to an FLASH_EraseInitTypeDef structure that
+ * contains the configuration information for the erasing.
+ *
+ * @param[out] SectorError pointer to variable that contains the configuration
+ * information on faulty sector in case of error (0xFFFFFFFF means that all
+ * the sectors have been correctly erased)
+ *
+ * @retval HAL Status
+ */
+HAL_StatusTypeDef HAL_FLASHEx_Erase(FLASH_EraseInitTypeDef *pEraseInit, uint32_t *SectorError)
+{
+ HAL_StatusTypeDef status = HAL_OK;
+ uint32_t sector_index;
+
+ /* Check the parameters */
+ assert_param(IS_FLASH_TYPEERASE(pEraseInit->TypeErase));
+ assert_param(IS_FLASH_BANK(pEraseInit->Banks));
+
+ /* Process Locked */
+ __HAL_LOCK(&pFlash);
+
+ /* Reset error code */
+ pFlash.ErrorCode = HAL_FLASH_ERROR_NONE;
+
+ /* Wait for last operation to be completed on Bank1 */
+ if((pEraseInit->Banks & FLASH_BANK_1) == FLASH_BANK_1)
+ {
+ if(FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE, FLASH_BANK_1) != HAL_OK)
+ {
+ status = HAL_ERROR;
+ }
+ }
+
+#if defined (DUAL_BANK)
+ /* Wait for last operation to be completed on Bank2 */
+ if((pEraseInit->Banks & FLASH_BANK_2) == FLASH_BANK_2)
+ {
+ if(FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE, FLASH_BANK_2) != HAL_OK)
+ {
+ status = HAL_ERROR;
+ }
+ }
+#endif /* DUAL_BANK */
+
+ if(status == HAL_OK)
+ {
+ if(pEraseInit->TypeErase == FLASH_TYPEERASE_MASSERASE)
+ {
+ /* Mass erase to be done */
+ FLASH_MassErase(pEraseInit->VoltageRange, pEraseInit->Banks);
+
+ /* Wait for last operation to be completed on Bank 1 */
+ if((pEraseInit->Banks & FLASH_BANK_1) == FLASH_BANK_1)
+ {
+ if(FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE, FLASH_BANK_1) != HAL_OK)
+ {
+ status = HAL_ERROR;
+ }
+ /* if the erase operation is completed, disable the Bank1 BER Bit */
+ FLASH->CR1 &= (~FLASH_CR_BER);
+ }
+#if defined (DUAL_BANK)
+ /* Wait for last operation to be completed on Bank 2 */
+ if((pEraseInit->Banks & FLASH_BANK_2) == FLASH_BANK_2)
+ {
+ if(FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE, FLASH_BANK_2) != HAL_OK)
+ {
+ status = HAL_ERROR;
+ }
+ /* if the erase operation is completed, disable the Bank2 BER Bit */
+ FLASH->CR2 &= (~FLASH_CR_BER);
+ }
+#endif /* DUAL_BANK */
+ }
+ else
+ {
+ /*Initialization of SectorError variable*/
+ *SectorError = 0xFFFFFFFFU;
+
+ /* Erase by sector by sector to be done*/
+ for(sector_index = pEraseInit->Sector; sector_index < (pEraseInit->NbSectors + pEraseInit->Sector); sector_index++)
+ {
+ FLASH_Erase_Sector(sector_index, pEraseInit->Banks, pEraseInit->VoltageRange);
+
+ if((pEraseInit->Banks & FLASH_BANK_1) == FLASH_BANK_1)
+ {
+ /* Wait for last operation to be completed */
+ status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE, FLASH_BANK_1);
+
+ /* If the erase operation is completed, disable the SER Bit */
+ FLASH->CR1 &= (~(FLASH_CR_SER | FLASH_CR_SNB));
+ }
+#if defined (DUAL_BANK)
+ if((pEraseInit->Banks & FLASH_BANK_2) == FLASH_BANK_2)
+ {
+ /* Wait for last operation to be completed */
+ status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE, FLASH_BANK_2);
+
+ /* If the erase operation is completed, disable the SER Bit */
+ FLASH->CR2 &= (~(FLASH_CR_SER | FLASH_CR_SNB));
+ }
+#endif /* DUAL_BANK */
+
+ if(status != HAL_OK)
+ {
+ /* In case of error, stop erase procedure and return the faulty sector */
+ *SectorError = sector_index;
+ break;
+ }
+ }
+ }
+ }
+
+ /* Process Unlocked */
+ __HAL_UNLOCK(&pFlash);
+
+ return status;
+}
+
+/**
+ * @brief Perform a mass erase or erase the specified FLASH memory sectors with interrupt enabled
+ * @param pEraseInit pointer to an FLASH_EraseInitTypeDef structure that
+ * contains the configuration information for the erasing.
+ *
+ * @retval HAL Status
+ */
+HAL_StatusTypeDef HAL_FLASHEx_Erase_IT(FLASH_EraseInitTypeDef *pEraseInit)
+{
+ HAL_StatusTypeDef status = HAL_OK;
+
+ /* Check the parameters */
+ assert_param(IS_FLASH_TYPEERASE(pEraseInit->TypeErase));
+ assert_param(IS_FLASH_BANK(pEraseInit->Banks));
+
+ /* Process Locked */
+ __HAL_LOCK(&pFlash);
+
+ /* Reset error code */
+ pFlash.ErrorCode = HAL_FLASH_ERROR_NONE;
+
+ /* Wait for last operation to be completed on Bank 1 */
+ if((pEraseInit->Banks & FLASH_BANK_1) == FLASH_BANK_1)
+ {
+ if(FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE, FLASH_BANK_1) != HAL_OK)
+ {
+ status = HAL_ERROR;
+ }
+ }
+
+#if defined (DUAL_BANK)
+ /* Wait for last operation to be completed on Bank 2 */
+ if((pEraseInit->Banks & FLASH_BANK_2) == FLASH_BANK_2)
+ {
+ if(FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE, FLASH_BANK_2) != HAL_OK)
+ {
+ status = HAL_ERROR;
+ }
+ }
+#endif /* DUAL_BANK */
+
+ if (status != HAL_OK)
+ {
+ /* Process Unlocked */
+ __HAL_UNLOCK(&pFlash);
+ }
+ else
+ {
+ if((pEraseInit->Banks & FLASH_BANK_1) == FLASH_BANK_1)
+ {
+ /* Enable End of Operation and Error interrupts for Bank 1 */
+#if defined (FLASH_CR_OPERRIE)
+ __HAL_FLASH_ENABLE_IT_BANK1(FLASH_IT_EOP_BANK1 | FLASH_IT_WRPERR_BANK1 | FLASH_IT_PGSERR_BANK1 | \
+ FLASH_IT_STRBERR_BANK1 | FLASH_IT_INCERR_BANK1 | FLASH_IT_OPERR_BANK1);
+#else
+ __HAL_FLASH_ENABLE_IT_BANK1(FLASH_IT_EOP_BANK1 | FLASH_IT_WRPERR_BANK1 | FLASH_IT_PGSERR_BANK1 | \
+ FLASH_IT_STRBERR_BANK1 | FLASH_IT_INCERR_BANK1);
+#endif /* FLASH_CR_OPERRIE */
+ }
+#if defined (DUAL_BANK)
+ if((pEraseInit->Banks & FLASH_BANK_2) == FLASH_BANK_2)
+ {
+ /* Enable End of Operation and Error interrupts for Bank 2 */
+#if defined (FLASH_CR_OPERRIE)
+ __HAL_FLASH_ENABLE_IT_BANK2(FLASH_IT_EOP_BANK2 | FLASH_IT_WRPERR_BANK2 | FLASH_IT_PGSERR_BANK2 | \
+ FLASH_IT_STRBERR_BANK2 | FLASH_IT_INCERR_BANK2 | FLASH_IT_OPERR_BANK2);
+#else
+ __HAL_FLASH_ENABLE_IT_BANK2(FLASH_IT_EOP_BANK2 | FLASH_IT_WRPERR_BANK2 | FLASH_IT_PGSERR_BANK2 | \
+ FLASH_IT_STRBERR_BANK2 | FLASH_IT_INCERR_BANK2);
+#endif /* FLASH_CR_OPERRIE */
+ }
+#endif /* DUAL_BANK */
+
+ if(pEraseInit->TypeErase == FLASH_TYPEERASE_MASSERASE)
+ {
+ /*Mass erase to be done*/
+ if(pEraseInit->Banks == FLASH_BANK_1)
+ {
+ pFlash.ProcedureOnGoing = FLASH_PROC_MASSERASE_BANK1;
+ }
+#if defined (DUAL_BANK)
+ else if(pEraseInit->Banks == FLASH_BANK_2)
+ {
+ pFlash.ProcedureOnGoing = FLASH_PROC_MASSERASE_BANK2;
+ }
+#endif /* DUAL_BANK */
+ else
+ {
+ pFlash.ProcedureOnGoing = FLASH_PROC_ALLBANK_MASSERASE;
+ }
+
+ FLASH_MassErase(pEraseInit->VoltageRange, pEraseInit->Banks);
+ }
+ else
+ {
+ /* Erase by sector to be done */
+#if defined (DUAL_BANK)
+ if(pEraseInit->Banks == FLASH_BANK_1)
+ {
+ pFlash.ProcedureOnGoing = FLASH_PROC_SECTERASE_BANK1;
+ }
+ else
+ {
+ pFlash.ProcedureOnGoing = FLASH_PROC_SECTERASE_BANK2;
+ }
+#else
+ pFlash.ProcedureOnGoing = FLASH_PROC_SECTERASE_BANK1;
+#endif /* DUAL_BANK */
+
+ pFlash.NbSectorsToErase = pEraseInit->NbSectors;
+ pFlash.Sector = pEraseInit->Sector;
+ pFlash.VoltageForErase = pEraseInit->VoltageRange;
+
+ /* Erase first sector and wait for IT */
+ FLASH_Erase_Sector(pEraseInit->Sector, pEraseInit->Banks, pEraseInit->VoltageRange);
+ }
+ }
+
+ return status;
+}
+
+/**
+ * @brief Program option bytes
+ * @param pOBInit pointer to an FLASH_OBInitStruct structure that
+ * contains the configuration information for the programming.
+ *
+ * @retval HAL Status
+ */
+HAL_StatusTypeDef HAL_FLASHEx_OBProgram(FLASH_OBProgramInitTypeDef *pOBInit)
+{
+ HAL_StatusTypeDef status;
+
+ /* Check the parameters */
+ assert_param(IS_OPTIONBYTE(pOBInit->OptionType));
+
+ /* Process Locked */
+ __HAL_LOCK(&pFlash);
+
+ /* Reset Error Code */
+ pFlash.ErrorCode = HAL_FLASH_ERROR_NONE;
+
+ /* Wait for last operation to be completed */
+ if(FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE, FLASH_BANK_1) != HAL_OK)
+ {
+ status = HAL_ERROR;
+ }
+#if defined (DUAL_BANK)
+ else if(FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE, FLASH_BANK_2) != HAL_OK)
+ {
+ status = HAL_ERROR;
+ }
+#endif /* DUAL_BANK */
+ else
+ {
+ status = HAL_OK;
+ }
+
+ if(status == HAL_OK)
+ {
+ /*Write protection configuration*/
+ if((pOBInit->OptionType & OPTIONBYTE_WRP) == OPTIONBYTE_WRP)
+ {
+ assert_param(IS_WRPSTATE(pOBInit->WRPState));
+
+ if(pOBInit->WRPState == OB_WRPSTATE_ENABLE)
+ {
+ /*Enable of Write protection on the selected Sector*/
+ FLASH_OB_EnableWRP(pOBInit->WRPSector,pOBInit->Banks);
+ }
+ else
+ {
+ /*Disable of Write protection on the selected Sector*/
+ FLASH_OB_DisableWRP(pOBInit->WRPSector, pOBInit->Banks);
+ }
+ }
+
+ /* Read protection configuration */
+ if((pOBInit->OptionType & OPTIONBYTE_RDP) != 0U)
+ {
+ /* Configure the Read protection level */
+ FLASH_OB_RDPConfig(pOBInit->RDPLevel);
+ }
+
+ /* User Configuration */
+ if((pOBInit->OptionType & OPTIONBYTE_USER) != 0U)
+ {
+ /* Configure the user option bytes */
+ FLASH_OB_UserConfig(pOBInit->USERType, pOBInit->USERConfig);
+ }
+
+ /* PCROP Configuration */
+ if((pOBInit->OptionType & OPTIONBYTE_PCROP) != 0U)
+ {
+ assert_param(IS_FLASH_BANK(pOBInit->Banks));
+
+ /*Configure the Proprietary code readout protection */
+ FLASH_OB_PCROPConfig(pOBInit->PCROPConfig, pOBInit->PCROPStartAddr, pOBInit->PCROPEndAddr, pOBInit->Banks);
+ }
+
+ /* BOR Level configuration */
+ if((pOBInit->OptionType & OPTIONBYTE_BOR) == OPTIONBYTE_BOR)
+ {
+ FLASH_OB_BOR_LevelConfig(pOBInit->BORLevel);
+ }
+
+#if defined(DUAL_CORE)
+ /* CM7 Boot Address configuration */
+ if((pOBInit->OptionType & OPTIONBYTE_CM7_BOOTADD) == OPTIONBYTE_CM7_BOOTADD)
+ {
+ FLASH_OB_BootAddConfig(pOBInit->BootConfig, pOBInit->BootAddr0, pOBInit->BootAddr1);
+ }
+
+ /* CM4 Boot Address configuration */
+ if((pOBInit->OptionType & OPTIONBYTE_CM4_BOOTADD) == OPTIONBYTE_CM4_BOOTADD)
+ {
+ FLASH_OB_CM4BootAddConfig(pOBInit->CM4BootConfig, pOBInit->CM4BootAddr0, pOBInit->CM4BootAddr1);
+ }
+#else /* Single Core*/
+ /* Boot Address configuration */
+ if((pOBInit->OptionType & OPTIONBYTE_BOOTADD) == OPTIONBYTE_BOOTADD)
+ {
+ FLASH_OB_BootAddConfig(pOBInit->BootConfig, pOBInit->BootAddr0, pOBInit->BootAddr1);
+ }
+#endif /*DUAL_CORE*/
+
+ /* Secure area configuration */
+ if((pOBInit->OptionType & OPTIONBYTE_SECURE_AREA) == OPTIONBYTE_SECURE_AREA)
+ {
+ FLASH_OB_SecureAreaConfig(pOBInit->SecureAreaConfig, pOBInit->SecureAreaStartAddr, pOBInit->SecureAreaEndAddr,pOBInit->Banks);
+ }
+
+#if defined(FLASH_OTPBL_LOCKBL)
+ /* OTP Block Lock configuration */
+ if((pOBInit->OptionType & OPTIONBYTE_OTP_LOCK) == OPTIONBYTE_OTP_LOCK)
+ {
+ FLASH_OB_OTP_LockConfig(pOBInit->OTPBlockLock);
+ }
+#endif /* FLASH_OTPBL_LOCKBL */
+
+#if defined(FLASH_OPTSR2_TCM_AXI_SHARED)
+ /* TCM / AXI Shared RAM configuration */
+ if((pOBInit->OptionType & OPTIONBYTE_SHARED_RAM) == OPTIONBYTE_SHARED_RAM)
+ {
+ FLASH_OB_SharedRAM_Config(pOBInit->SharedRamConfig);
+ }
+#endif /* FLASH_OPTSR2_TCM_AXI_SHARED */
+
+#if defined(FLASH_OPTSR2_CPUFREQ_BOOST)
+ /* CPU Frequency Boost configuration */
+ if((pOBInit->OptionType & OPTIONBYTE_FREQ_BOOST) == OPTIONBYTE_FREQ_BOOST)
+ {
+ FLASH_OB_CPUFreq_BoostConfig(pOBInit->FreqBoostState);
+ }
+#endif /* FLASH_OPTSR2_CPUFREQ_BOOST */
+ }
+
+ /* Process Unlocked */
+ __HAL_UNLOCK(&pFlash);
+
+ return status;
+}
+
+/**
+ * @brief Get the Option byte configuration
+ * @param pOBInit pointer to an FLASH_OBInitStruct structure that
+ * contains the configuration information for the programming.
+ * @note The parameter Banks of the pOBInit structure must be set exclusively to FLASH_BANK_1 or FLASH_BANK_2,
+ * as this parameter is use to get the given Bank WRP, PCROP and secured area configuration.
+ *
+ * @retval None
+ */
+void HAL_FLASHEx_OBGetConfig(FLASH_OBProgramInitTypeDef *pOBInit)
+{
+ pOBInit->OptionType = (OPTIONBYTE_USER | OPTIONBYTE_RDP | OPTIONBYTE_BOR);
+
+ /* Get Read protection level */
+ pOBInit->RDPLevel = FLASH_OB_GetRDP();
+
+ /* Get the user option bytes */
+ pOBInit->USERConfig = FLASH_OB_GetUser();
+
+ /*Get BOR Level*/
+ pOBInit->BORLevel = FLASH_OB_GetBOR();
+
+#if defined (DUAL_BANK)
+ if ((pOBInit->Banks == FLASH_BANK_1) || (pOBInit->Banks == FLASH_BANK_2))
+#else
+ if (pOBInit->Banks == FLASH_BANK_1)
+#endif /* DUAL_BANK */
+ {
+ pOBInit->OptionType |= (OPTIONBYTE_WRP | OPTIONBYTE_PCROP | OPTIONBYTE_SECURE_AREA);
+
+ /* Get write protection on the selected area */
+ FLASH_OB_GetWRP(&(pOBInit->WRPState), &(pOBInit->WRPSector), pOBInit->Banks);
+
+ /* Get the Proprietary code readout protection */
+ FLASH_OB_GetPCROP(&(pOBInit->PCROPConfig), &(pOBInit->PCROPStartAddr), &(pOBInit->PCROPEndAddr), pOBInit->Banks);
+
+ /*Get Bank Secure area*/
+ FLASH_OB_GetSecureArea(&(pOBInit->SecureAreaConfig), &(pOBInit->SecureAreaStartAddr), &(pOBInit->SecureAreaEndAddr), pOBInit->Banks);
+ }
+
+ /*Get Boot Address*/
+ FLASH_OB_GetBootAdd(&(pOBInit->BootAddr0), &(pOBInit->BootAddr1));
+#if defined(DUAL_CORE)
+ pOBInit->OptionType |= OPTIONBYTE_CM7_BOOTADD | OPTIONBYTE_CM4_BOOTADD;
+
+ /*Get CM4 Boot Address*/
+ FLASH_OB_GetCM4BootAdd(&(pOBInit->CM4BootAddr0), &(pOBInit->CM4BootAddr1));
+#else
+ pOBInit->OptionType |= OPTIONBYTE_BOOTADD;
+#endif /*DUAL_CORE*/
+
+#if defined (FLASH_OTPBL_LOCKBL)
+ pOBInit->OptionType |= OPTIONBYTE_OTP_LOCK;
+
+ /* Get OTP Block Lock */
+ pOBInit->OTPBlockLock = FLASH_OB_OTP_GetLock();
+#endif /* FLASH_OTPBL_LOCKBL */
+
+#if defined (FLASH_OPTSR2_TCM_AXI_SHARED)
+ pOBInit->OptionType |= OPTIONBYTE_SHARED_RAM;
+
+ /* Get TCM / AXI Shared RAM */
+ pOBInit->SharedRamConfig = FLASH_OB_SharedRAM_GetConfig();
+#endif /* FLASH_OPTSR2_TCM_AXI_SHARED */
+
+#if defined (FLASH_OPTSR2_CPUFREQ_BOOST)
+ pOBInit->OptionType |= OPTIONBYTE_FREQ_BOOST;
+
+ /* Get CPU Frequency Boost */
+ pOBInit->FreqBoostState = FLASH_OB_CPUFreq_GetBoost();
+#endif /* FLASH_OPTSR2_CPUFREQ_BOOST */
+}
+
+/**
+ * @brief Unlock the FLASH Bank1 control registers access
+ * @retval HAL Status
+ */
+HAL_StatusTypeDef HAL_FLASHEx_Unlock_Bank1(void)
+{
+ if(READ_BIT(FLASH->CR1, FLASH_CR_LOCK) != 0U)
+ {
+ /* Authorize the FLASH Bank1 Registers access */
+ WRITE_REG(FLASH->KEYR1, FLASH_KEY1);
+ WRITE_REG(FLASH->KEYR1, FLASH_KEY2);
+
+ /* Verify Flash Bank1 is unlocked */
+ if (READ_BIT(FLASH->CR1, FLASH_CR_LOCK) != 0U)
+ {
+ return HAL_ERROR;
+ }
+ }
+
+ return HAL_OK;
+}
+
+/**
+ * @brief Locks the FLASH Bank1 control registers access
+ * @retval HAL Status
+ */
+HAL_StatusTypeDef HAL_FLASHEx_Lock_Bank1(void)
+{
+ /* Set the LOCK Bit to lock the FLASH Bank1 Registers access */
+ SET_BIT(FLASH->CR1, FLASH_CR_LOCK);
+ return HAL_OK;
+}
+
+#if defined (DUAL_BANK)
+/**
+ * @brief Unlock the FLASH Bank2 control registers access
+ * @retval HAL Status
+ */
+HAL_StatusTypeDef HAL_FLASHEx_Unlock_Bank2(void)
+{
+ if(READ_BIT(FLASH->CR2, FLASH_CR_LOCK) != 0U)
+ {
+ /* Authorize the FLASH Bank2 Registers access */
+ WRITE_REG(FLASH->KEYR2, FLASH_KEY1);
+ WRITE_REG(FLASH->KEYR2, FLASH_KEY2);
+
+ /* Verify Flash Bank1 is unlocked */
+ if (READ_BIT(FLASH->CR2, FLASH_CR_LOCK) != 0U)
+ {
+ return HAL_ERROR;
+ }
+ }
+
+ return HAL_OK;
+}
+
+/**
+ * @brief Locks the FLASH Bank2 control registers access
+ * @retval HAL Status
+ */
+HAL_StatusTypeDef HAL_FLASHEx_Lock_Bank2(void)
+{
+ /* Set the LOCK Bit to lock the FLASH Bank2 Registers access */
+ SET_BIT(FLASH->CR2, FLASH_CR_LOCK);
+ return HAL_OK;
+}
+#endif /* DUAL_BANK */
+
+/*
+ * @brief Perform a CRC computation on the specified FLASH memory area
+ * @param pCRCInit pointer to an FLASH_CRCInitTypeDef structure that
+ * contains the configuration information for the CRC computation.
+ * @note CRC computation uses CRC-32 (Ethernet) polynomial 0x4C11DB7
+ * @note The application should avoid running a CRC on PCROP or secure-only
+ * user Flash memory area since it may alter the expected CRC value.
+ * A special error flag (CRC read error: CRCRDERR) can be used to
+ * detect such a case.
+ * @retval HAL Status
+*/
+HAL_StatusTypeDef HAL_FLASHEx_ComputeCRC(FLASH_CRCInitTypeDef *pCRCInit, uint32_t *CRC_Result)
+{
+ HAL_StatusTypeDef status;
+ uint32_t sector_index;
+
+ /* Check the parameters */
+ assert_param(IS_FLASH_BANK_EXCLUSIVE(pCRCInit->Bank));
+ assert_param(IS_FLASH_TYPECRC(pCRCInit->TypeCRC));
+
+ /* Wait for OB change operation to be completed */
+ status = FLASH_OB_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE);
+
+ if (status == HAL_OK)
+ {
+ if (pCRCInit->Bank == FLASH_BANK_1)
+ {
+ /* Enable CRC feature */
+ FLASH->CR1 |= FLASH_CR_CRC_EN;
+
+ /* Clear CRC flags in Status Register: CRC end of calculation and CRC read error */
+ FLASH->CCR1 |= (FLASH_CCR_CLR_CRCEND | FLASH_CCR_CLR_CRCRDERR);
+
+ /* Clear current CRC result, program burst size and define memory area on which CRC has to be computed */
+ FLASH->CRCCR1 |= FLASH_CRCCR_CLEAN_CRC | pCRCInit->BurstSize | pCRCInit->TypeCRC;
+
+ if (pCRCInit->TypeCRC == FLASH_CRC_SECTORS)
+ {
+ /* Clear sectors list */
+ FLASH->CRCCR1 |= FLASH_CRCCR_CLEAN_SECT;
+
+ /* Select CRC sectors */
+ for(sector_index = pCRCInit->Sector; sector_index < (pCRCInit->NbSectors + pCRCInit->Sector); sector_index++)
+ {
+ FLASH_CRC_AddSector(sector_index, FLASH_BANK_1);
+ }
+ }
+ else if (pCRCInit->TypeCRC == FLASH_CRC_BANK)
+ {
+ /* Enable Bank 1 CRC select bit */
+ FLASH->CRCCR1 |= FLASH_CRCCR_ALL_BANK;
+ }
+ else
+ {
+ /* Select CRC start and end addresses */
+ FLASH_CRC_SelectAddress(pCRCInit->CRCStartAddr, pCRCInit->CRCEndAddr, FLASH_BANK_1);
+ }
+
+ /* Start the CRC calculation */
+ FLASH->CRCCR1 |= FLASH_CRCCR_START_CRC;
+
+ /* Wait on CRC busy flag */
+ status = FLASH_CRC_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE, FLASH_BANK_1);
+
+ /* Return CRC result */
+ (*CRC_Result) = FLASH->CRCDATA;
+
+ /* Disable CRC feature */
+ FLASH->CR1 &= (~FLASH_CR_CRC_EN);
+
+ /* Clear CRC flags */
+ __HAL_FLASH_CLEAR_FLAG_BANK1(FLASH_FLAG_CRCEND_BANK1 | FLASH_FLAG_CRCRDERR_BANK1);
+ }
+#if defined (DUAL_BANK)
+ else
+ {
+ /* Enable CRC feature */
+ FLASH->CR2 |= FLASH_CR_CRC_EN;
+
+ /* Clear CRC flags in Status Register: CRC end of calculation and CRC read error */
+ FLASH->CCR2 |= (FLASH_CCR_CLR_CRCEND | FLASH_CCR_CLR_CRCRDERR);
+
+ /* Clear current CRC result, program burst size and define memory area on which CRC has to be computed */
+ FLASH->CRCCR2 |= FLASH_CRCCR_CLEAN_CRC | pCRCInit->BurstSize | pCRCInit->TypeCRC;
+
+ if (pCRCInit->TypeCRC == FLASH_CRC_SECTORS)
+ {
+ /* Clear sectors list */
+ FLASH->CRCCR2 |= FLASH_CRCCR_CLEAN_SECT;
+
+ /* Add CRC sectors */
+ for(sector_index = pCRCInit->Sector; sector_index < (pCRCInit->NbSectors + pCRCInit->Sector); sector_index++)
+ {
+ FLASH_CRC_AddSector(sector_index, FLASH_BANK_2);
+ }
+ }
+ else if (pCRCInit->TypeCRC == FLASH_CRC_BANK)
+ {
+ /* Enable Bank 2 CRC select bit */
+ FLASH->CRCCR2 |= FLASH_CRCCR_ALL_BANK;
+ }
+ else
+ {
+ /* Select CRC start and end addresses */
+ FLASH_CRC_SelectAddress(pCRCInit->CRCStartAddr, pCRCInit->CRCEndAddr, FLASH_BANK_2);
+ }
+
+ /* Start the CRC calculation */
+ FLASH->CRCCR2 |= FLASH_CRCCR_START_CRC;
+
+ /* Wait on CRC busy flag */
+ status = FLASH_CRC_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE, FLASH_BANK_2);
+
+ /* Return CRC result */
+ (*CRC_Result) = FLASH->CRCDATA;
+
+ /* Disable CRC feature */
+ FLASH->CR2 &= (~FLASH_CR_CRC_EN);
+
+ /* Clear CRC flags */
+ __HAL_FLASH_CLEAR_FLAG_BANK2(FLASH_FLAG_CRCEND_BANK2 | FLASH_FLAG_CRCRDERR_BANK2);
+ }
+#endif /* DUAL_BANK */
+ }
+
+ return status;
+}
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/* Private functions ---------------------------------------------------------*/
+
+/** @addtogroup FLASHEx_Private_Functions
+ * @{
+ */
+
+/**
+ * @brief Mass erase of FLASH memory
+ * @param VoltageRange The device program/erase parallelism.
+ * This parameter can be one of the following values:
+ * @arg FLASH_VOLTAGE_RANGE_1 : Flash program/erase by 8 bits
+ * @arg FLASH_VOLTAGE_RANGE_2 : Flash program/erase by 16 bits
+ * @arg FLASH_VOLTAGE_RANGE_3 : Flash program/erase by 32 bits
+ * @arg FLASH_VOLTAGE_RANGE_4 : Flash program/erase by 64 bits
+ *
+ * @param Banks Banks to be erased
+ * This parameter can be one of the following values:
+ * @arg FLASH_BANK_1: Bank1 to be erased
+ * @arg FLASH_BANK_2: Bank2 to be erased
+ * @arg FLASH_BANK_BOTH: Bank1 and Bank2 to be erased
+ *
+ * @retval HAL Status
+ */
+static void FLASH_MassErase(uint32_t VoltageRange, uint32_t Banks)
+{
+ /* Check the parameters */
+#if defined (FLASH_CR_PSIZE)
+ assert_param(IS_VOLTAGERANGE(VoltageRange));
+#else
+ UNUSED(VoltageRange);
+#endif /* FLASH_CR_PSIZE */
+ assert_param(IS_FLASH_BANK(Banks));
+
+#if defined (DUAL_BANK)
+ /* Flash Mass Erase */
+ if((Banks & FLASH_BANK_BOTH) == FLASH_BANK_BOTH)
+ {
+#if defined (FLASH_CR_PSIZE)
+ /* Reset Program/erase VoltageRange for Bank1 and Bank2 */
+ FLASH->CR1 &= (~FLASH_CR_PSIZE);
+ FLASH->CR2 &= (~FLASH_CR_PSIZE);
+
+ /* Set voltage range */
+ FLASH->CR1 |= VoltageRange;
+ FLASH->CR2 |= VoltageRange;
+#endif /* FLASH_CR_PSIZE */
+
+ /* Set Mass Erase Bit */
+ FLASH->OPTCR |= FLASH_OPTCR_MER;
+ }
+ else
+#endif /* DUAL_BANK */
+ {
+ /* Proceed to erase Flash Bank */
+ if((Banks & FLASH_BANK_1) == FLASH_BANK_1)
+ {
+#if defined (FLASH_CR_PSIZE)
+ /* Set Program/erase VoltageRange for Bank1 */
+ FLASH->CR1 &= (~FLASH_CR_PSIZE);
+ FLASH->CR1 |= VoltageRange;
+#endif /* FLASH_CR_PSIZE */
+
+ /* Erase Bank1 */
+ FLASH->CR1 |= (FLASH_CR_BER | FLASH_CR_START);
+ }
+
+#if defined (DUAL_BANK)
+ if((Banks & FLASH_BANK_2) == FLASH_BANK_2)
+ {
+#if defined (FLASH_CR_PSIZE)
+ /* Set Program/erase VoltageRange for Bank2 */
+ FLASH->CR2 &= (~FLASH_CR_PSIZE);
+ FLASH->CR2 |= VoltageRange;
+#endif /* FLASH_CR_PSIZE */
+
+ /* Erase Bank2 */
+ FLASH->CR2 |= (FLASH_CR_BER | FLASH_CR_START);
+ }
+#endif /* DUAL_BANK */
+ }
+}
+
+/**
+ * @brief Erase the specified FLASH memory sector
+ * @param Sector FLASH sector to erase
+ * This parameter can be a value of @ref FLASH_Sectors
+ * @param Banks Banks to be erased
+ * This parameter can be one of the following values:
+ * @arg FLASH_BANK_1: Bank1 to be erased
+ * @arg FLASH_BANK_2: Bank2 to be erased
+ * @arg FLASH_BANK_BOTH: Bank1 and Bank2 to be erased
+ * @param VoltageRange The device program/erase parallelism.
+ * This parameter can be one of the following values:
+ * @arg FLASH_VOLTAGE_RANGE_1 : Flash program/erase by 8 bits
+ * @arg FLASH_VOLTAGE_RANGE_2 : Flash program/erase by 16 bits
+ * @arg FLASH_VOLTAGE_RANGE_3 : Flash program/erase by 32 bits
+ * @arg FLASH_VOLTAGE_RANGE_4 : Flash program/erase by 64 bits
+ *
+ * @retval None
+ */
+void FLASH_Erase_Sector(uint32_t Sector, uint32_t Banks, uint32_t VoltageRange)
+{
+ assert_param(IS_FLASH_SECTOR(Sector));
+ assert_param(IS_FLASH_BANK_EXCLUSIVE(Banks));
+#if defined (FLASH_CR_PSIZE)
+ assert_param(IS_VOLTAGERANGE(VoltageRange));
+#else
+ UNUSED(VoltageRange);
+#endif /* FLASH_CR_PSIZE */
+
+ if((Banks & FLASH_BANK_1) == FLASH_BANK_1)
+ {
+#if defined (FLASH_CR_PSIZE)
+ /* Reset Program/erase VoltageRange and Sector Number for Bank1 */
+ FLASH->CR1 &= ~(FLASH_CR_PSIZE | FLASH_CR_SNB);
+
+ FLASH->CR1 |= (FLASH_CR_SER | VoltageRange | (Sector << FLASH_CR_SNB_Pos) | FLASH_CR_START);
+#else
+ /* Reset Sector Number for Bank1 */
+ FLASH->CR1 &= ~(FLASH_CR_SNB);
+
+ FLASH->CR1 |= (FLASH_CR_SER | (Sector << FLASH_CR_SNB_Pos) | FLASH_CR_START);
+#endif /* FLASH_CR_PSIZE */
+ }
+
+#if defined (DUAL_BANK)
+ if((Banks & FLASH_BANK_2) == FLASH_BANK_2)
+ {
+#if defined (FLASH_CR_PSIZE)
+ /* Reset Program/erase VoltageRange and Sector Number for Bank2 */
+ FLASH->CR2 &= ~(FLASH_CR_PSIZE | FLASH_CR_SNB);
+
+ FLASH->CR2 |= (FLASH_CR_SER | VoltageRange | (Sector << FLASH_CR_SNB_Pos) | FLASH_CR_START);
+#else
+ /* Reset Sector Number for Bank2 */
+ FLASH->CR2 &= ~(FLASH_CR_SNB);
+
+ FLASH->CR2 |= (FLASH_CR_SER | (Sector << FLASH_CR_SNB_Pos) | FLASH_CR_START);
+#endif /* FLASH_CR_PSIZE */
+ }
+#endif /* DUAL_BANK */
+}
+
+/**
+ * @brief Enable the write protection of the desired bank1 or bank 2 sectors
+ * @param WRPSector specifies the sector(s) to be write protected.
+ * This parameter can be one of the following values:
+ * @arg WRPSector: A combination of OB_WRP_SECTOR_0 to OB_WRP_SECTOR_7 or OB_WRP_SECTOR_All
+ *
+ * @param Banks the specific bank to apply WRP sectors
+ * This parameter can be one of the following values:
+ * @arg FLASH_BANK_1: enable WRP on specified bank1 sectors
+ * @arg FLASH_BANK_2: enable WRP on specified bank2 sectors
+ * @arg FLASH_BANK_BOTH: enable WRP on both bank1 and bank2 specified sectors
+ *
+ * @retval HAL FLASH State
+ */
+static void FLASH_OB_EnableWRP(uint32_t WRPSector, uint32_t Banks)
+{
+ /* Check the parameters */
+ assert_param(IS_OB_WRP_SECTOR(WRPSector));
+ assert_param(IS_FLASH_BANK(Banks));
+
+ if((Banks & FLASH_BANK_1) == FLASH_BANK_1)
+ {
+ /* Enable Write Protection for bank 1 */
+ FLASH->WPSN_PRG1 &= (~(WRPSector & FLASH_WPSN_WRPSN));
+ }
+
+#if defined (DUAL_BANK)
+ if((Banks & FLASH_BANK_2) == FLASH_BANK_2)
+ {
+ /* Enable Write Protection for bank 2 */
+ FLASH->WPSN_PRG2 &= (~(WRPSector & FLASH_WPSN_WRPSN));
+ }
+#endif /* DUAL_BANK */
+}
+
+/**
+ * @brief Disable the write protection of the desired bank1 or bank 2 sectors
+ * @param WRPSector specifies the sector(s) to disable write protection.
+ * This parameter can be one of the following values:
+ * @arg WRPSector: A combination of FLASH_OB_WRP_SECTOR_0 to FLASH_OB_WRP_SECTOR_7 or FLASH_OB_WRP_SECTOR_All
+ *
+ * @param Banks the specific bank to apply WRP sectors
+ * This parameter can be one of the following values:
+ * @arg FLASH_BANK_1: disable WRP on specified bank1 sectors
+ * @arg FLASH_BANK_2: disable WRP on specified bank2 sectors
+ * @arg FLASH_BANK_BOTH: disable WRP on both bank1 and bank2 specified sectors
+ *
+ * @retval HAL FLASH State
+ */
+static void FLASH_OB_DisableWRP(uint32_t WRPSector, uint32_t Banks)
+{
+ /* Check the parameters */
+ assert_param(IS_OB_WRP_SECTOR(WRPSector));
+ assert_param(IS_FLASH_BANK(Banks));
+
+ if((Banks & FLASH_BANK_1) == FLASH_BANK_1)
+ {
+ /* Disable Write Protection for bank 1 */
+ FLASH->WPSN_PRG1 |= (WRPSector & FLASH_WPSN_WRPSN);
+ }
+
+#if defined (DUAL_BANK)
+ if((Banks & FLASH_BANK_2) == FLASH_BANK_2)
+ {
+ /* Disable Write Protection for bank 2 */
+ FLASH->WPSN_PRG2 |= (WRPSector & FLASH_WPSN_WRPSN);
+ }
+#endif /* DUAL_BANK */
+}
+
+/**
+ * @brief Get the write protection of the given bank 1 or bank 2 sectors
+ * @param WRPState gives the write protection state on the given bank.
+ * This parameter can be one of the following values:
+ * @arg WRPState: OB_WRPSTATE_DISABLE or OB_WRPSTATE_ENABLE
+
+ * @param WRPSector gives the write protected sector(s) on the given bank .
+ * This parameter can be one of the following values:
+ * @arg WRPSector: A combination of FLASH_OB_WRP_SECTOR_0 to FLASH_OB_WRP_SECTOR_7 or FLASH_OB_WRP_SECTOR_All
+ *
+ * @param Bank the specific bank to apply WRP sectors
+ * This parameter can be exclusively one of the following values:
+ * @arg FLASH_BANK_1: Get bank1 WRP sectors
+ * @arg FLASH_BANK_2: Get bank2 WRP sectors
+ * @arg FLASH_BANK_BOTH: note allowed in this functions
+ *
+ * @retval HAL FLASH State
+ */
+static void FLASH_OB_GetWRP(uint32_t *WRPState, uint32_t *WRPSector, uint32_t Bank)
+{
+ uint32_t regvalue = 0U;
+
+ if(Bank == FLASH_BANK_1)
+ {
+ regvalue = FLASH->WPSN_CUR1;
+ }
+
+#if defined (DUAL_BANK)
+ if(Bank == FLASH_BANK_2)
+ {
+ regvalue = FLASH->WPSN_CUR2;
+ }
+#endif /* DUAL_BANK */
+
+ (*WRPSector) = (~regvalue) & FLASH_WPSN_WRPSN;
+
+ if(*WRPSector == 0U)
+ {
+ (*WRPState) = OB_WRPSTATE_DISABLE;
+ }
+ else
+ {
+ (*WRPState) = OB_WRPSTATE_ENABLE;
+ }
+}
+
+/**
+ * @brief Set the read protection level.
+ *
+ * @note To configure the RDP level, the option lock bit OPTLOCK must be
+ * cleared with the call of the HAL_FLASH_OB_Unlock() function.
+ * @note To validate the RDP level, the option bytes must be reloaded
+ * through the call of the HAL_FLASH_OB_Launch() function.
+ * @note !!! Warning : When enabling OB_RDP level 2 it's no more possible
+ * to go back to level 1 or 0 !!!
+ *
+ * @param RDPLevel specifies the read protection level.
+ * This parameter can be one of the following values:
+ * @arg OB_RDP_LEVEL_0: No protection
+ * @arg OB_RDP_LEVEL_1: Read protection of the memory
+ * @arg OB_RDP_LEVEL_2: Full chip protection
+ *
+ * @retval HAL status
+ */
+static void FLASH_OB_RDPConfig(uint32_t RDPLevel)
+{
+ /* Check the parameters */
+ assert_param(IS_OB_RDP_LEVEL(RDPLevel));
+
+ /* Configure the RDP level in the option bytes register */
+ MODIFY_REG(FLASH->OPTSR_PRG, FLASH_OPTSR_RDP, RDPLevel);
+}
+
+/**
+ * @brief Get the read protection level.
+ * @retval RDPLevel specifies the read protection level.
+ * This return value can be one of the following values:
+ * @arg OB_RDP_LEVEL_0: No protection
+ * @arg OB_RDP_LEVEL_1: Read protection of the memory
+ * @arg OB_RDP_LEVEL_2: Full chip protection
+ */
+static uint32_t FLASH_OB_GetRDP(void)
+{
+ uint32_t rdp_level = READ_BIT(FLASH->OPTSR_CUR, FLASH_OPTSR_RDP);
+
+ if ((rdp_level != OB_RDP_LEVEL_0) && (rdp_level != OB_RDP_LEVEL_2))
+ {
+ return (OB_RDP_LEVEL_1);
+ }
+ else
+ {
+ return rdp_level;
+ }
+}
+
+#if defined(DUAL_CORE)
+/**
+ * @brief Program the FLASH User Option Byte.
+ *
+ * @note To configure the user option bytes, the option lock bit OPTLOCK must
+ * be cleared with the call of the HAL_FLASH_OB_Unlock() function.
+ *
+ * @note To validate the user option bytes, the option bytes must be reloaded
+ * through the call of the HAL_FLASH_OB_Launch() function.
+ *
+ * @param UserType The FLASH User Option Bytes to be modified :
+ * a combination of @ref FLASHEx_OB_USER_Type
+ *
+ * @param UserConfig The FLASH User Option Bytes values:
+ * IWDG1_SW(Bit4), IWDG2_SW(Bit 5), nRST_STOP_D1(Bit 6), nRST_STDY_D1(Bit 7),
+ * FZ_IWDG_STOP(Bit 17), FZ_IWDG_SDBY(Bit 18), ST_RAM_SIZE(Bit[19:20]),
+ * SECURITY(Bit 21), BCM4(Bit 22), BCM7(Bit 23), nRST_STOP_D2(Bit 24),
+ * nRST_STDY_D2(Bit 25), IO_HSLV (Bit 29) and SWAP_BANK_OPT(Bit 31).
+ *
+ * @retval HAL status
+ */
+#else
+/**
+ * @brief Program the FLASH User Option Byte.
+ *
+ * @note To configure the user option bytes, the option lock bit OPTLOCK must
+ * be cleared with the call of the HAL_FLASH_OB_Unlock() function.
+ *
+ * @note To validate the user option bytes, the option bytes must be reloaded
+ * through the call of the HAL_FLASH_OB_Launch() function.
+ *
+ * @param UserType The FLASH User Option Bytes to be modified :
+ * a combination of @arg FLASHEx_OB_USER_Type
+ *
+ * @param UserConfig The FLASH User Option Bytes values:
+ * IWDG_SW(Bit4), nRST_STOP_D1(Bit 6), nRST_STDY_D1(Bit 7),
+ * FZ_IWDG_STOP(Bit 17), FZ_IWDG_SDBY(Bit 18), ST_RAM_SIZE(Bit[19:20]),
+ * SECURITY(Bit 21), IO_HSLV (Bit 29) and SWAP_BANK_OPT(Bit 31).
+ *
+ * @retval HAL status
+ */
+#endif /*DUAL_CORE*/
+static void FLASH_OB_UserConfig(uint32_t UserType, uint32_t UserConfig)
+{
+ uint32_t optr_reg_val = 0;
+ uint32_t optr_reg_mask = 0;
+
+ /* Check the parameters */
+ assert_param(IS_OB_USER_TYPE(UserType));
+
+ if((UserType & OB_USER_IWDG1_SW) != 0U)
+ {
+ /* IWDG_HW option byte should be modified */
+ assert_param(IS_OB_IWDG1_SOURCE(UserConfig & FLASH_OPTSR_IWDG1_SW));
+
+ /* Set value and mask for IWDG_HW option byte */
+ optr_reg_val |= (UserConfig & FLASH_OPTSR_IWDG1_SW);
+ optr_reg_mask |= FLASH_OPTSR_IWDG1_SW;
+ }
+#if defined(DUAL_CORE)
+ if((UserType & OB_USER_IWDG2_SW) != 0U)
+ {
+ /* IWDG2_SW option byte should be modified */
+ assert_param(IS_OB_IWDG2_SOURCE(UserConfig & FLASH_OPTSR_IWDG2_SW));
+
+ /* Set value and mask for IWDG2_SW option byte */
+ optr_reg_val |= (UserConfig & FLASH_OPTSR_IWDG2_SW);
+ optr_reg_mask |= FLASH_OPTSR_IWDG2_SW;
+ }
+#endif /*DUAL_CORE*/
+ if((UserType & OB_USER_NRST_STOP_D1) != 0U)
+ {
+ /* NRST_STOP option byte should be modified */
+ assert_param(IS_OB_STOP_D1_RESET(UserConfig & FLASH_OPTSR_NRST_STOP_D1));
+
+ /* Set value and mask for NRST_STOP option byte */
+ optr_reg_val |= (UserConfig & FLASH_OPTSR_NRST_STOP_D1);
+ optr_reg_mask |= FLASH_OPTSR_NRST_STOP_D1;
+ }
+
+ if((UserType & OB_USER_NRST_STDBY_D1) != 0U)
+ {
+ /* NRST_STDBY option byte should be modified */
+ assert_param(IS_OB_STDBY_D1_RESET(UserConfig & FLASH_OPTSR_NRST_STBY_D1));
+
+ /* Set value and mask for NRST_STDBY option byte */
+ optr_reg_val |= (UserConfig & FLASH_OPTSR_NRST_STBY_D1);
+ optr_reg_mask |= FLASH_OPTSR_NRST_STBY_D1;
+ }
+
+ if((UserType & OB_USER_IWDG_STOP) != 0U)
+ {
+ /* IWDG_STOP option byte should be modified */
+ assert_param(IS_OB_USER_IWDG_STOP(UserConfig & FLASH_OPTSR_FZ_IWDG_STOP));
+
+ /* Set value and mask for IWDG_STOP option byte */
+ optr_reg_val |= (UserConfig & FLASH_OPTSR_FZ_IWDG_STOP);
+ optr_reg_mask |= FLASH_OPTSR_FZ_IWDG_STOP;
+ }
+
+ if((UserType & OB_USER_IWDG_STDBY) != 0U)
+ {
+ /* IWDG_STDBY option byte should be modified */
+ assert_param(IS_OB_USER_IWDG_STDBY(UserConfig & FLASH_OPTSR_FZ_IWDG_SDBY));
+
+ /* Set value and mask for IWDG_STDBY option byte */
+ optr_reg_val |= (UserConfig & FLASH_OPTSR_FZ_IWDG_SDBY);
+ optr_reg_mask |= FLASH_OPTSR_FZ_IWDG_SDBY;
+ }
+
+ if((UserType & OB_USER_ST_RAM_SIZE) != 0U)
+ {
+ /* ST_RAM_SIZE option byte should be modified */
+ assert_param(IS_OB_USER_ST_RAM_SIZE(UserConfig & FLASH_OPTSR_ST_RAM_SIZE));
+
+ /* Set value and mask for ST_RAM_SIZE option byte */
+ optr_reg_val |= (UserConfig & FLASH_OPTSR_ST_RAM_SIZE);
+ optr_reg_mask |= FLASH_OPTSR_ST_RAM_SIZE;
+ }
+
+ if((UserType & OB_USER_SECURITY) != 0U)
+ {
+ /* SECURITY option byte should be modified */
+ assert_param(IS_OB_USER_SECURITY(UserConfig & FLASH_OPTSR_SECURITY));
+
+ /* Set value and mask for SECURITY option byte */
+ optr_reg_val |= (UserConfig & FLASH_OPTSR_SECURITY);
+ optr_reg_mask |= FLASH_OPTSR_SECURITY;
+ }
+
+#if defined(DUAL_CORE)
+ if((UserType & OB_USER_BCM4) != 0U)
+ {
+ /* BCM4 option byte should be modified */
+ assert_param(IS_OB_USER_BCM4(UserConfig & FLASH_OPTSR_BCM4));
+
+ /* Set value and mask for BCM4 option byte */
+ optr_reg_val |= (UserConfig & FLASH_OPTSR_BCM4);
+ optr_reg_mask |= FLASH_OPTSR_BCM4;
+ }
+
+ if((UserType & OB_USER_BCM7) != 0U)
+ {
+ /* BCM7 option byte should be modified */
+ assert_param(IS_OB_USER_BCM7(UserConfig & FLASH_OPTSR_BCM7));
+
+ /* Set value and mask for BCM7 option byte */
+ optr_reg_val |= (UserConfig & FLASH_OPTSR_BCM7);
+ optr_reg_mask |= FLASH_OPTSR_BCM7;
+ }
+#endif /* DUAL_CORE */
+
+#if defined (FLASH_OPTSR_NRST_STOP_D2)
+ if((UserType & OB_USER_NRST_STOP_D2) != 0U)
+ {
+ /* NRST_STOP option byte should be modified */
+ assert_param(IS_OB_STOP_D2_RESET(UserConfig & FLASH_OPTSR_NRST_STOP_D2));
+
+ /* Set value and mask for NRST_STOP option byte */
+ optr_reg_val |= (UserConfig & FLASH_OPTSR_NRST_STOP_D2);
+ optr_reg_mask |= FLASH_OPTSR_NRST_STOP_D2;
+ }
+
+ if((UserType & OB_USER_NRST_STDBY_D2) != 0U)
+ {
+ /* NRST_STDBY option byte should be modified */
+ assert_param(IS_OB_STDBY_D2_RESET(UserConfig & FLASH_OPTSR_NRST_STBY_D2));
+
+ /* Set value and mask for NRST_STDBY option byte */
+ optr_reg_val |= (UserConfig & FLASH_OPTSR_NRST_STBY_D2);
+ optr_reg_mask |= FLASH_OPTSR_NRST_STBY_D2;
+ }
+#endif /* FLASH_OPTSR_NRST_STOP_D2 */
+
+#if defined (DUAL_BANK)
+ if((UserType & OB_USER_SWAP_BANK) != 0U)
+ {
+ /* SWAP_BANK_OPT option byte should be modified */
+ assert_param(IS_OB_USER_SWAP_BANK(UserConfig & FLASH_OPTSR_SWAP_BANK_OPT));
+
+ /* Set value and mask for SWAP_BANK_OPT option byte */
+ optr_reg_val |= (UserConfig & FLASH_OPTSR_SWAP_BANK_OPT);
+ optr_reg_mask |= FLASH_OPTSR_SWAP_BANK_OPT;
+ }
+#endif /* DUAL_BANK */
+
+ if((UserType & OB_USER_IOHSLV) != 0U)
+ {
+ /* IOHSLV_OPT option byte should be modified */
+ assert_param(IS_OB_USER_IOHSLV(UserConfig & FLASH_OPTSR_IO_HSLV));
+
+ /* Set value and mask for IOHSLV_OPT option byte */
+ optr_reg_val |= (UserConfig & FLASH_OPTSR_IO_HSLV);
+ optr_reg_mask |= FLASH_OPTSR_IO_HSLV;
+ }
+
+#if defined (FLASH_OPTSR_VDDMMC_HSLV)
+ if((UserType & OB_USER_VDDMMC_HSLV) != 0U)
+ {
+ /* VDDMMC_HSLV option byte should be modified */
+ assert_param(IS_OB_USER_VDDMMC_HSLV(UserConfig & FLASH_OPTSR_VDDMMC_HSLV));
+
+ /* Set value and mask for VDDMMC_HSLV option byte */
+ optr_reg_val |= (UserConfig & FLASH_OPTSR_VDDMMC_HSLV);
+ optr_reg_mask |= FLASH_OPTSR_VDDMMC_HSLV;
+ }
+#endif /* FLASH_OPTSR_VDDMMC_HSLV */
+
+ /* Configure the option bytes register */
+ MODIFY_REG(FLASH->OPTSR_PRG, optr_reg_mask, optr_reg_val);
+}
+
+#if defined(DUAL_CORE)
+/**
+ * @brief Return the FLASH User Option Byte value.
+ * @retval The FLASH User Option Bytes values
+ * IWDG1_SW(Bit4), IWDG2_SW(Bit 5), nRST_STOP_D1(Bit 6), nRST_STDY_D1(Bit 7),
+ * FZ_IWDG_STOP(Bit 17), FZ_IWDG_SDBY(Bit 18), ST_RAM_SIZE(Bit[19:20]),
+ * SECURITY(Bit 21), BCM4(Bit 22), BCM7(Bit 23), nRST_STOP_D2(Bit 24),
+ * nRST_STDY_D2(Bit 25), IO_HSLV (Bit 29) and SWAP_BANK_OPT(Bit 31).
+ */
+#else
+/**
+ * @brief Return the FLASH User Option Byte value.
+ * @retval The FLASH User Option Bytes values
+ * IWDG_SW(Bit4), nRST_STOP_D1(Bit 6), nRST_STDY_D1(Bit 7),
+ * FZ_IWDG_STOP(Bit 17), FZ_IWDG_SDBY(Bit 18), ST_RAM_SIZE(Bit[19:20]),
+ * SECURITY(Bit 21), IO_HSLV (Bit 29) and SWAP_BANK_OPT(Bit 31).
+ */
+#endif /*DUAL_CORE*/
+static uint32_t FLASH_OB_GetUser(void)
+{
+ uint32_t userConfig = READ_REG(FLASH->OPTSR_CUR);
+ userConfig &= (~(FLASH_OPTSR_BOR_LEV | FLASH_OPTSR_RDP));
+
+ return userConfig;
+}
+
+/**
+ * @brief Configure the Proprietary code readout protection of the desired addresses
+ *
+ * @note To configure the PCROP options, the option lock bit OPTLOCK must be
+ * cleared with the call of the HAL_FLASH_OB_Unlock() function.
+ * @note To validate the PCROP options, the option bytes must be reloaded
+ * through the call of the HAL_FLASH_OB_Launch() function.
+ *
+ * @param PCROPConfig specifies if the PCROP area for the given Bank shall be erased or not
+ * when RDP level decreased from Level 1 to Level 0, or after a bank erase with protection removal
+ * This parameter must be a value of @arg FLASHEx_OB_PCROP_RDP enumeration
+ *
+ * @param PCROPStartAddr specifies the start address of the Proprietary code readout protection
+ * This parameter can be an address between begin and end of the bank
+ *
+ * @param PCROPEndAddr specifies the end address of the Proprietary code readout protection
+ * This parameter can be an address between PCROPStartAddr and end of the bank
+ *
+ * @param Banks the specific bank to apply PCROP protection
+ * This parameter can be one of the following values:
+ * @arg FLASH_BANK_1: PCROP on specified bank1 area
+ * @arg FLASH_BANK_2: PCROP on specified bank2 area
+ * @arg FLASH_BANK_BOTH: PCROP on specified bank1 and bank2 area (same config will be applied on both banks)
+ *
+ * @retval None
+ */
+static void FLASH_OB_PCROPConfig(uint32_t PCROPConfig, uint32_t PCROPStartAddr, uint32_t PCROPEndAddr, uint32_t Banks)
+{
+ /* Check the parameters */
+ assert_param(IS_FLASH_BANK(Banks));
+ assert_param(IS_OB_PCROP_RDP(PCROPConfig));
+
+ if((Banks & FLASH_BANK_1) == FLASH_BANK_1)
+ {
+ assert_param(IS_FLASH_PROGRAM_ADDRESS_BANK1(PCROPStartAddr));
+ assert_param(IS_FLASH_PROGRAM_ADDRESS_BANK1(PCROPEndAddr));
+
+ /* Configure the Proprietary code readout protection */
+ FLASH->PRAR_PRG1 = ((PCROPStartAddr - FLASH_BANK1_BASE) >> 8) | \
+ (((PCROPEndAddr - FLASH_BANK1_BASE) >> 8) << FLASH_PRAR_PROT_AREA_END_Pos) | \
+ PCROPConfig;
+ }
+
+#if defined (DUAL_BANK)
+ if((Banks & FLASH_BANK_2) == FLASH_BANK_2)
+ {
+ assert_param(IS_FLASH_PROGRAM_ADDRESS_BANK2(PCROPStartAddr));
+ assert_param(IS_FLASH_PROGRAM_ADDRESS_BANK2(PCROPEndAddr));
+
+ /* Configure the Proprietary code readout protection */
+ FLASH->PRAR_PRG2 = ((PCROPStartAddr - FLASH_BANK2_BASE) >> 8) | \
+ (((PCROPEndAddr - FLASH_BANK2_BASE) >> 8) << FLASH_PRAR_PROT_AREA_END_Pos) | \
+ PCROPConfig;
+ }
+#endif /* DUAL_BANK */
+}
+
+/**
+ * @brief Get the Proprietary code readout protection configuration on a given Bank
+ *
+ * @param PCROPConfig indicates if the PCROP area for the given Bank shall be erased or not
+ * when RDP level decreased from Level 1 to Level 0 or after a bank erase with protection removal
+ *
+ * @param PCROPStartAddr gives the start address of the Proprietary code readout protection of the bank
+ *
+ * @param PCROPEndAddr gives the end address of the Proprietary code readout protection of the bank
+ *
+ * @param Bank the specific bank to apply PCROP protection
+ * This parameter can be exclusively one of the following values:
+ * @arg FLASH_BANK_1: PCROP on specified bank1 area
+ * @arg FLASH_BANK_2: PCROP on specified bank2 area
+ * @arg FLASH_BANK_BOTH: is not allowed here
+ *
+ * @retval None
+ */
+static void FLASH_OB_GetPCROP(uint32_t *PCROPConfig, uint32_t *PCROPStartAddr, uint32_t *PCROPEndAddr, uint32_t Bank)
+{
+ uint32_t regvalue = 0;
+ uint32_t bankBase = 0;
+
+ if(Bank == FLASH_BANK_1)
+ {
+ regvalue = FLASH->PRAR_CUR1;
+ bankBase = FLASH_BANK1_BASE;
+ }
+
+#if defined (DUAL_BANK)
+ if(Bank == FLASH_BANK_2)
+ {
+ regvalue = FLASH->PRAR_CUR2;
+ bankBase = FLASH_BANK2_BASE;
+ }
+#endif /* DUAL_BANK */
+
+ (*PCROPConfig) = (regvalue & FLASH_PRAR_DMEP);
+
+ (*PCROPStartAddr) = ((regvalue & FLASH_PRAR_PROT_AREA_START) << 8) + bankBase;
+ (*PCROPEndAddr) = (regvalue & FLASH_PRAR_PROT_AREA_END) >> FLASH_PRAR_PROT_AREA_END_Pos;
+ (*PCROPEndAddr) = ((*PCROPEndAddr) << 8) + bankBase;
+}
+
+/**
+ * @brief Set the BOR Level.
+ * @param Level specifies the Option Bytes BOR Reset Level.
+ * This parameter can be one of the following values:
+ * @arg OB_BOR_LEVEL0: Reset level threshold is set to 1.6V
+ * @arg OB_BOR_LEVEL1: Reset level threshold is set to 2.1V
+ * @arg OB_BOR_LEVEL2: Reset level threshold is set to 2.4V
+ * @arg OB_BOR_LEVEL3: Reset level threshold is set to 2.7V
+ * @retval None
+ */
+static void FLASH_OB_BOR_LevelConfig(uint32_t Level)
+{
+ assert_param(IS_OB_BOR_LEVEL(Level));
+
+ /* Configure BOR_LEV option byte */
+ MODIFY_REG(FLASH->OPTSR_PRG, FLASH_OPTSR_BOR_LEV, Level);
+}
+
+/**
+ * @brief Get the BOR Level.
+ * @retval The Option Bytes BOR Reset Level.
+ * This parameter can be one of the following values:
+ * @arg OB_BOR_LEVEL0: Reset level threshold is set to 1.6V
+ * @arg OB_BOR_LEVEL1: Reset level threshold is set to 2.1V
+ * @arg OB_BOR_LEVEL2: Reset level threshold is set to 2.4V
+ * @arg OB_BOR_LEVEL3: Reset level threshold is set to 2.7V
+ */
+static uint32_t FLASH_OB_GetBOR(void)
+{
+ return (FLASH->OPTSR_CUR & FLASH_OPTSR_BOR_LEV);
+}
+
+/**
+ * @brief Set Boot address
+ * @param BootOption Boot address option byte to be programmed,
+ * This parameter must be a value of @ref FLASHEx_OB_BOOT_OPTION
+ (OB_BOOT_ADD0, OB_BOOT_ADD1 or OB_BOOT_ADD_BOTH)
+ *
+ * @param BootAddress0 Specifies the Boot Address 0
+ * @param BootAddress1 Specifies the Boot Address 1
+ * @retval HAL Status
+ */
+static void FLASH_OB_BootAddConfig(uint32_t BootOption, uint32_t BootAddress0, uint32_t BootAddress1)
+{
+ /* Check the parameters */
+ assert_param(IS_OB_BOOT_ADD_OPTION(BootOption));
+
+ if((BootOption & OB_BOOT_ADD0) == OB_BOOT_ADD0)
+ {
+ /* Check the parameters */
+ assert_param(IS_BOOT_ADDRESS(BootAddress0));
+
+ /* Configure CM7 BOOT ADD0 */
+#if defined(DUAL_CORE)
+ MODIFY_REG(FLASH->BOOT7_PRG, FLASH_BOOT7_BCM7_ADD0, (BootAddress0 >> 16));
+#else /* Single Core*/
+ MODIFY_REG(FLASH->BOOT_PRG, FLASH_BOOT_ADD0, (BootAddress0 >> 16));
+#endif /* DUAL_CORE */
+ }
+
+ if((BootOption & OB_BOOT_ADD1) == OB_BOOT_ADD1)
+ {
+ /* Check the parameters */
+ assert_param(IS_BOOT_ADDRESS(BootAddress1));
+
+ /* Configure CM7 BOOT ADD1 */
+#if defined(DUAL_CORE)
+ MODIFY_REG(FLASH->BOOT7_PRG, FLASH_BOOT7_BCM7_ADD1, BootAddress1);
+#else /* Single Core*/
+ MODIFY_REG(FLASH->BOOT_PRG, FLASH_BOOT_ADD1, BootAddress1);
+#endif /* DUAL_CORE */
+ }
+}
+
+/**
+ * @brief Get Boot address
+ * @param BootAddress0 Specifies the Boot Address 0.
+ * @param BootAddress1 Specifies the Boot Address 1.
+ * @retval HAL Status
+ */
+static void FLASH_OB_GetBootAdd(uint32_t *BootAddress0, uint32_t *BootAddress1)
+{
+ uint32_t regvalue;
+
+#if defined(DUAL_CORE)
+ regvalue = FLASH->BOOT7_CUR;
+
+ (*BootAddress0) = (regvalue & FLASH_BOOT7_BCM7_ADD0) << 16;
+ (*BootAddress1) = (regvalue & FLASH_BOOT7_BCM7_ADD1);
+#else /* Single Core */
+ regvalue = FLASH->BOOT_CUR;
+
+ (*BootAddress0) = (regvalue & FLASH_BOOT_ADD0) << 16;
+ (*BootAddress1) = (regvalue & FLASH_BOOT_ADD1);
+#endif /* DUAL_CORE */
+}
+
+#if defined(DUAL_CORE)
+/**
+ * @brief Set CM4 Boot address
+ * @param BootOption Boot address option byte to be programmed,
+ * This parameter must be a value of @ref FLASHEx_OB_BOOT_OPTION
+ (OB_BOOT_ADD0, OB_BOOT_ADD1 or OB_BOOT_ADD_BOTH)
+ *
+ * @param BootAddress0 Specifies the CM4 Boot Address 0.
+ * @param BootAddress1 Specifies the CM4 Boot Address 1.
+ * @retval HAL Status
+ */
+static void FLASH_OB_CM4BootAddConfig(uint32_t BootOption, uint32_t BootAddress0, uint32_t BootAddress1)
+{
+ /* Check the parameters */
+ assert_param(IS_OB_BOOT_ADD_OPTION(BootOption));
+
+ if((BootOption & OB_BOOT_ADD0) == OB_BOOT_ADD0)
+ {
+ /* Check the parameters */
+ assert_param(IS_BOOT_ADDRESS(BootAddress0));
+
+ /* Configure CM4 BOOT ADD0 */
+ MODIFY_REG(FLASH->BOOT4_PRG, FLASH_BOOT4_BCM4_ADD0, (BootAddress0 >> 16));
+
+ }
+
+ if((BootOption & OB_BOOT_ADD1) == OB_BOOT_ADD1)
+ {
+ /* Check the parameters */
+ assert_param(IS_BOOT_ADDRESS(BootAddress1));
+
+ /* Configure CM4 BOOT ADD1 */
+ MODIFY_REG(FLASH->BOOT4_PRG, FLASH_BOOT4_BCM4_ADD1, BootAddress1);
+ }
+}
+
+/**
+ * @brief Get CM4 Boot address
+ * @param BootAddress0 Specifies the CM4 Boot Address 0.
+ * @param BootAddress1 Specifies the CM4 Boot Address 1.
+ * @retval HAL Status
+ */
+static void FLASH_OB_GetCM4BootAdd(uint32_t *BootAddress0, uint32_t *BootAddress1)
+{
+ uint32_t regvalue;
+
+ regvalue = FLASH->BOOT4_CUR;
+
+ (*BootAddress0) = (regvalue & FLASH_BOOT4_BCM4_ADD0) << 16;
+ (*BootAddress1) = (regvalue & FLASH_BOOT4_BCM4_ADD1);
+}
+#endif /*DUAL_CORE*/
+
+/**
+ * @brief Set secure area configuration
+ * @param SecureAreaConfig specify if the secure area will be deleted or not
+ * when RDP level decreased from Level 1 to Level 0 or during a mass erase.
+ *
+ * @param SecureAreaStartAddr Specifies the secure area start address
+ * @param SecureAreaEndAddr Specifies the secure area end address
+ * @param Banks the specific bank to apply Security protection
+ * This parameter can be one of the following values:
+ * @arg FLASH_BANK_1: Secure area on specified bank1 area
+ * @arg FLASH_BANK_2: Secure area on specified bank2 area
+ * @arg FLASH_BANK_BOTH: Secure area on specified bank1 and bank2 area (same config will be applied on both banks)
+ * @retval None
+ */
+static void FLASH_OB_SecureAreaConfig(uint32_t SecureAreaConfig, uint32_t SecureAreaStartAddr, uint32_t SecureAreaEndAddr, uint32_t Banks)
+{
+ /* Check the parameters */
+ assert_param(IS_FLASH_BANK(Banks));
+ assert_param(IS_OB_SECURE_RDP(SecureAreaConfig));
+
+ if((Banks & FLASH_BANK_1) == FLASH_BANK_1)
+ {
+ /* Check the parameters */
+ assert_param(IS_FLASH_PROGRAM_ADDRESS_BANK1(SecureAreaStartAddr));
+ assert_param(IS_FLASH_PROGRAM_ADDRESS_BANK1(SecureAreaEndAddr));
+
+ /* Configure the secure area */
+ FLASH->SCAR_PRG1 = ((SecureAreaStartAddr - FLASH_BANK1_BASE) >> 8) | \
+ (((SecureAreaEndAddr - FLASH_BANK1_BASE) >> 8) << FLASH_SCAR_SEC_AREA_END_Pos) | \
+ (SecureAreaConfig & FLASH_SCAR_DMES);
+ }
+
+#if defined (DUAL_BANK)
+ if((Banks & FLASH_BANK_2) == FLASH_BANK_2)
+ {
+ /* Check the parameters */
+ assert_param(IS_FLASH_PROGRAM_ADDRESS_BANK2(SecureAreaStartAddr));
+ assert_param(IS_FLASH_PROGRAM_ADDRESS_BANK2(SecureAreaEndAddr));
+
+ /* Configure the secure area */
+ FLASH->SCAR_PRG2 = ((SecureAreaStartAddr - FLASH_BANK2_BASE) >> 8) | \
+ (((SecureAreaEndAddr - FLASH_BANK2_BASE) >> 8) << FLASH_SCAR_SEC_AREA_END_Pos) | \
+ (SecureAreaConfig & FLASH_SCAR_DMES);
+ }
+#endif /* DUAL_BANK */
+}
+
+/**
+ * @brief Get secure area configuration
+ * @param SecureAreaConfig indicates if the secure area will be deleted or not
+ * when RDP level decreased from Level 1 to Level 0 or during a mass erase.
+ * @param SecureAreaStartAddr gives the secure area start address
+ * @param SecureAreaEndAddr gives the secure area end address
+ * @param Bank Specifies the Bank
+ * @retval None
+ */
+static void FLASH_OB_GetSecureArea(uint32_t *SecureAreaConfig, uint32_t *SecureAreaStartAddr, uint32_t *SecureAreaEndAddr, uint32_t Bank)
+{
+ uint32_t regvalue = 0;
+ uint32_t bankBase = 0;
+
+ /* Check Bank parameter value */
+ if(Bank == FLASH_BANK_1)
+ {
+ regvalue = FLASH->SCAR_CUR1;
+ bankBase = FLASH_BANK1_BASE;
+ }
+
+#if defined (DUAL_BANK)
+ if(Bank == FLASH_BANK_2)
+ {
+ regvalue = FLASH->SCAR_CUR2;
+ bankBase = FLASH_BANK2_BASE;
+ }
+#endif /* DUAL_BANK */
+
+ /* Get the secure area settings */
+ (*SecureAreaConfig) = (regvalue & FLASH_SCAR_DMES);
+ (*SecureAreaStartAddr) = ((regvalue & FLASH_SCAR_SEC_AREA_START) << 8) + bankBase;
+ (*SecureAreaEndAddr) = (regvalue & FLASH_SCAR_SEC_AREA_END) >> FLASH_SCAR_SEC_AREA_END_Pos;
+ (*SecureAreaEndAddr) = ((*SecureAreaEndAddr) << 8) + bankBase;
+}
+
+/**
+ * @brief Add a CRC sector to the list of sectors on which the CRC will be calculated
+ * @param Sector Specifies the CRC sector number
+ * @param Bank Specifies the Bank
+ * @retval None
+ */
+static void FLASH_CRC_AddSector(uint32_t Sector, uint32_t Bank)
+{
+ /* Check the parameters */
+ assert_param(IS_FLASH_SECTOR(Sector));
+
+ if (Bank == FLASH_BANK_1)
+ {
+ /* Clear CRC sector */
+ FLASH->CRCCR1 &= (~FLASH_CRCCR_CRC_SECT);
+
+ /* Select CRC Sector and activate ADD_SECT bit */
+ FLASH->CRCCR1 |= Sector | FLASH_CRCCR_ADD_SECT;
+ }
+#if defined (DUAL_BANK)
+ else
+ {
+ /* Clear CRC sector */
+ FLASH->CRCCR2 &= (~FLASH_CRCCR_CRC_SECT);
+
+ /* Select CRC Sector and activate ADD_SECT bit */
+ FLASH->CRCCR2 |= Sector | FLASH_CRCCR_ADD_SECT;
+ }
+#endif /* DUAL_BANK */
+}
+
+/**
+ * @brief Select CRC start and end memory addresses on which the CRC will be calculated
+ * @param CRCStartAddr Specifies the CRC start address
+ * @param CRCEndAddr Specifies the CRC end address
+ * @param Bank Specifies the Bank
+ * @retval None
+ */
+static void FLASH_CRC_SelectAddress(uint32_t CRCStartAddr, uint32_t CRCEndAddr, uint32_t Bank)
+{
+ if (Bank == FLASH_BANK_1)
+ {
+ assert_param(IS_FLASH_PROGRAM_ADDRESS_BANK1(CRCStartAddr));
+ assert_param(IS_FLASH_PROGRAM_ADDRESS_BANK1(CRCEndAddr));
+
+ /* Write CRC Start and End addresses */
+ FLASH->CRCSADD1 = CRCStartAddr;
+ FLASH->CRCEADD1 = CRCEndAddr;
+ }
+#if defined (DUAL_BANK)
+ else
+ {
+ assert_param(IS_FLASH_PROGRAM_ADDRESS_BANK2(CRCStartAddr));
+ assert_param(IS_FLASH_PROGRAM_ADDRESS_BANK2(CRCEndAddr));
+
+ /* Write CRC Start and End addresses */
+ FLASH->CRCSADD2 = CRCStartAddr;
+ FLASH->CRCEADD2 = CRCEndAddr;
+ }
+#endif /* DUAL_BANK */
+}
+/**
+ * @}
+ */
+
+#if defined (FLASH_OTPBL_LOCKBL)
+/**
+ * @brief Configure the OTP Block Lock.
+ * @param OTP_Block specifies the OTP Block to lock.
+ * This parameter can be a value of @ref FLASHEx_OTP_Blocks
+ * @retval None
+ */
+static void FLASH_OB_OTP_LockConfig(uint32_t OTP_Block)
+{
+ /* Check the parameters */
+ assert_param(IS_OTP_BLOCK(OTP_Block));
+
+ /* Configure the OTP Block lock in the option bytes register */
+ FLASH->OTPBL_PRG |= (OTP_Block & FLASH_OTPBL_LOCKBL);
+}
+
+/**
+ * @brief Get the OTP Block Lock.
+ * @retval OTP_Block specifies the OTP Block to lock.
+ * This return value can be a value of @ref FLASHEx_OTP_Blocks
+ */
+static uint32_t FLASH_OB_OTP_GetLock(void)
+{
+ return (FLASH->OTPBL_CUR);
+}
+#endif /* FLASH_OTPBL_LOCKBL */
+
+#if defined (FLASH_OPTSR2_TCM_AXI_SHARED)
+/**
+ * @brief Configure the TCM / AXI Shared RAM.
+ * @param SharedRamConfig specifies the Shared RAM configuration.
+ * This parameter can be a value of @ref FLASHEx_OB_TCM_AXI_SHARED
+ * @retval None
+ */
+static void FLASH_OB_SharedRAM_Config(uint32_t SharedRamConfig)
+{
+ /* Check the parameters */
+ assert_param(IS_OB_USER_TCM_AXI_SHARED(SharedRamConfig));
+
+ /* Configure the TCM / AXI Shared RAM in the option bytes register */
+ MODIFY_REG(FLASH->OPTSR2_PRG, FLASH_OPTSR2_TCM_AXI_SHARED, SharedRamConfig);
+}
+
+/**
+ * @brief Get the TCM / AXI Shared RAM configurtion.
+ * @retval SharedRamConfig returns the TCM / AXI Shared RAM configuration.
+ * This return value can be a value of @ref FLASHEx_OB_TCM_AXI_SHARED
+ */
+static uint32_t FLASH_OB_SharedRAM_GetConfig(void)
+{
+ return (FLASH->OPTSR2_CUR & FLASH_OPTSR2_TCM_AXI_SHARED);;
+}
+#endif /* FLASH_OPTSR2_TCM_AXI_SHARED */
+
+#if defined (FLASH_OPTSR2_CPUFREQ_BOOST)
+/**
+ * @brief Configure the CPU Frequency Boost.
+ * @param FreqBoost specifies the CPU Frequency Boost state.
+ * This parameter can be a value of @ref FLASHEx_OB_CPUFREQ_BOOST
+ * @retval None
+ */
+static void FLASH_OB_CPUFreq_BoostConfig(uint32_t FreqBoost)
+{
+ /* Check the parameters */
+ assert_param(IS_OB_USER_CPUFREQ_BOOST(FreqBoost));
+
+ /* Configure the CPU Frequency Boost in the option bytes register */
+ MODIFY_REG(FLASH->OPTSR2_PRG, FLASH_OPTSR2_CPUFREQ_BOOST, FreqBoost);
+}
+
+/**
+ * @brief Get the CPU Frequency Boost state.
+ * @retval FreqBoost returns the CPU Frequency Boost state.
+ * This return value can be a value of @ref FLASHEx_OB_CPUFREQ_BOOST
+ */
+static uint32_t FLASH_OB_CPUFreq_GetBoost(void)
+{
+ return (FLASH->OPTSR2_CUR & FLASH_OPTSR2_CPUFREQ_BOOST);;
+}
+#endif /* FLASH_OPTSR2_CPUFREQ_BOOST */
+
+#endif /* HAL_FLASH_MODULE_ENABLED */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/firmware/hw_layer/ports/stm32/stm32h7/stm32h7xx_hal_flash_ex.h b/firmware/hw_layer/ports/stm32/stm32h7/stm32h7xx_hal_flash_ex.h
new file mode 100644
index 0000000000..3c4c81a575
--- /dev/null
+++ b/firmware/hw_layer/ports/stm32/stm32h7/stm32h7xx_hal_flash_ex.h
@@ -0,0 +1,1010 @@
+/**
+ ******************************************************************************
+ * @file stm32H7xx_hal_flash_ex.h
+ * @author MCD Application Team
+ * @brief Header file of FLASH HAL module.
+ ******************************************************************************
+ * @attention
+ *
+ * © COPYRIGHT(c) 2017 STMicroelectronics.
+ * All rights reserved.
+ *
+ * This software component is licensed by ST under BSD 3-Clause license,
+ * the "License"; You may not use this file except in compliance with the
+ * License. You may obtain a copy of the License at:
+ * opensource.org/licenses/BSD-3-Clause
+ *
+ ******************************************************************************
+ */
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef STM32H7xx_HAL_FLASH_EX_H
+#define STM32H7xx_HAL_FLASH_EX_H
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+/* Includes ------------------------------------------------------------------*/
+#include "stm32h7xx_hal_def.h"
+
+/** @addtogroup STM32H7xx_HAL_Driver
+ * @{
+ */
+
+/** @addtogroup FLASHEx
+ * @{
+ */
+
+/* Exported types ------------------------------------------------------------*/
+/** @defgroup FLASHEx_Exported_Types FLASH Exported Types
+ * @{
+ */
+
+/**
+ * @brief FLASH Erase structure definition
+ */
+typedef struct
+{
+ uint32_t TypeErase; /*!< Mass erase or sector Erase.
+ This parameter can be a value of @ref FLASHEx_Type_Erase */
+
+ uint32_t Banks; /*!< Select banks to erase when Mass erase is enabled.
+ This parameter must be a value of @ref FLASHEx_Banks */
+
+ uint32_t Sector; /*!< Initial FLASH sector to erase when Mass erase is disabled
+ This parameter must be a value of @ref FLASH_Sectors */
+
+ uint32_t NbSectors; /*!< Number of sectors to be erased.
+ This parameter must be a value between 1 and (max number of sectors - value of Initial sector)*/
+
+ uint32_t VoltageRange;/*!< The device voltage range which defines the erase parallelism
+ This parameter must be a value of @ref FLASHEx_Voltage_Range */
+
+} FLASH_EraseInitTypeDef;
+
+
+/**
+ * @brief FLASH Option Bytes Program structure definition
+ */
+typedef struct
+{
+ uint32_t OptionType; /*!< Option byte to be configured.
+ This parameter can be a value of @ref FLASHEx_Option_Type */
+
+ uint32_t WRPState; /*!< Write protection activation or deactivation.
+ This parameter can be a value of @ref FLASHEx_WRP_State */
+
+ uint32_t WRPSector; /*!< Specifies the sector(s) to be write protected.
+ The value of this parameter depend on device used within the same series */
+
+ uint32_t RDPLevel; /*!< Set the read protection level.
+ This parameter can be a value of @ref FLASHEx_Option_Bytes_Read_Protection */
+
+ uint32_t BORLevel; /*!< Set the BOR Level.
+ This parameter can be a value of @ref FLASHEx_BOR_Reset_Level */
+
+ uint32_t USERType; /*!< User option byte(s) to be configured (used for OPTIONBYTE_USER).
+ This parameter can be a combination of @ref FLASHEx_OB_USER_Type */
+
+ uint32_t USERConfig; /*!< Program the FLASH User Option Byte: IWDG_SW / RST_STOP / RST_STDBY /
+ IWDG_FREEZE_STOP / IWDG_FREEZE_SANDBY / IO_HSLV / SWAP_BANK_OPT */
+
+ uint32_t Banks; /*!< Select banks for WRP , PCROP and secure area config .
+ This parameter must be a value of @ref FLASHEx_Banks */
+
+ uint32_t PCROPConfig; /*!< specifies if the PCROP area shall be erased or not
+ when RDP level decreased from Level 1 to Level 0 or during a mass erase.
+ This parameter must be a value of @ref FLASHEx_OB_PCROP_RDP enumeration */
+
+ uint32_t PCROPStartAddr; /*!< PCROP Start address (used for OPTIONBYTE_PCROP).
+ This parameter must be a value between begin and end of a bank */
+
+ uint32_t PCROPEndAddr; /*!< PCROP End address (used for OPTIONBYTE_PCROP).
+ This parameter must be a value between PCROP Start address and end of a bank */
+
+ uint32_t BootConfig; /*!< Specifies if the Boot Address to be configured BOOT_ADD0, BOOT_ADD1
+ or both. This parameter must be a value of @ref FLASHEx_OB_BOOT_OPTION enumeration */
+
+ uint32_t BootAddr0; /*!< Boot Address 0.
+ This parameter must be a value between begin and end of a bank */
+
+ uint32_t BootAddr1; /*!< Boot Address 1.
+ This parameter must be a value between begin and end of a bank */
+#if defined(DUAL_CORE)
+ uint32_t CM4BootConfig; /*!< specifies if the CM4 boot Address to be configured BOOT_ADD0, BOOT_ADD1
+ or both.
+ This parameter must be a value of @ref FLASHEx_OB_BOOT_OPTION enumeration */
+
+ uint32_t CM4BootAddr0; /*!< CM4 Boot Address 0.
+ This parameter must be a value between begin and end of a bank */
+
+ uint32_t CM4BootAddr1; /*!< CM4 Boot Address 1.
+ This parameter must be a value between begin and end of a bank */
+#endif /*DUAL_CORE*/
+
+ uint32_t SecureAreaConfig; /*!< specifies if the bank secured area shall be erased or not
+ when RDP level decreased from Level 1 to Level 0 or during a mass erase.
+ This parameter must be a value of @ref FLASHEx_OB_SECURE_RDP enumeration */
+
+ uint32_t SecureAreaStartAddr; /*!< Bank Secure area Start address.
+ This parameter must be a value between begin address and end address of bank1 */
+
+ uint32_t SecureAreaEndAddr; /*!< Bank Secure area End address.
+ This parameter must be a value between Secure Area Start address and end address of a bank1 */
+
+#if defined (FLASH_OTPBL_LOCKBL)
+ uint32_t OTPBlockLock; /*!< Specifies the OTP block(s) to be locked.
+ This parameter must be a value of @ref FLASHEx_OTP_Blocks */
+#endif /* FLASH_OTPBL_LOCKBL */
+
+#if defined (FLASH_OPTSR2_TCM_AXI_SHARED)
+ uint32_t SharedRamConfig; /*!< Specifies the configuration of TCM / AXI shared RAM.
+ This parameter must be a value of @ref FLASHEx_OB_TCM_AXI_SHARED */
+#endif /* FLASH_OPTSR2_TCM_AXI_SHARED */
+
+#if defined (FLASH_OPTSR2_CPUFREQ_BOOST)
+ uint32_t FreqBoostState; /*!< Specifies the state of CPU Frequency Boost.
+ This parameter must be a value of @ref FLASHEx_OB_CPUFREQ_BOOST */
+#endif /* FLASH_OPTSR2_CPUFREQ_BOOST */
+
+} FLASH_OBProgramInitTypeDef;
+
+/**
+ * @brief FLASH Erase structure definition
+ */
+typedef struct
+{
+ uint32_t TypeCRC; /*!< CRC Selection Type.
+ This parameter can be a value of @ref FLASHEx_CRC_Selection_Type */
+
+ uint32_t BurstSize; /*!< CRC Burst Size.
+ This parameter can be a value of @ref FLASHEx_CRC_Burst_Size */
+
+ uint32_t Bank; /*!< Select bank where CRC computation is enabled.
+ This parameter must be FLASH_BANK_1 or FLASH_BANK_2 */
+
+ uint32_t Sector; /*!< Initial FLASH sector from which starts the CRC computation
+ This parameter must be a value of @ref FLASH_Sectors */
+
+ uint32_t NbSectors; /*!< Number of sectors to be computed.
+ This parameter must be a value between 1 and (max number of sectors - value of Initial sector)*/
+
+ uint32_t CRCStartAddr; /*!< CRC Start address.
+ This parameter must be a value between begin address and end address of a bank */
+
+ uint32_t CRCEndAddr; /*!< CRC End address.
+ This parameter must be a value between CRC Start address and end address of a bank */
+
+} FLASH_CRCInitTypeDef;
+
+/**
+ * @}
+ */
+/* Exported constants --------------------------------------------------------*/
+
+/** @defgroup FLASHEx_Exported_Constants FLASH Exported Constants
+ * @{
+ */
+
+/** @defgroup FLASHEx_Type_Erase FLASH Type Erase
+ * @{
+ */
+#define FLASH_TYPEERASE_SECTORS 0x00U /*!< Sectors erase only */
+#define FLASH_TYPEERASE_MASSERASE 0x01U /*!< Flash Mass erase activation */
+/**
+ * @}
+ */
+
+#if defined (FLASH_CR_PSIZE)
+/** @defgroup FLASHEx_Voltage_Range FLASH Voltage Range
+ * @{
+ */
+#define FLASH_VOLTAGE_RANGE_1 0x00000000U /*!< Flash program/erase by 8 bits */
+#define FLASH_VOLTAGE_RANGE_2 FLASH_CR_PSIZE_0 /*!< Flash program/erase by 16 bits */
+#define FLASH_VOLTAGE_RANGE_3 FLASH_CR_PSIZE_1 /*!< Flash program/erase by 32 bits */
+#define FLASH_VOLTAGE_RANGE_4 FLASH_CR_PSIZE /*!< Flash program/erase by 64 bits */
+/**
+ * @}
+ */
+#endif /* FLASH_CR_PSIZE */
+
+/** @defgroup FLASHEx_WRP_State FLASH WRP State
+ * @{
+ */
+#define OB_WRPSTATE_DISABLE 0x00000000U /*!< Disable the write protection of the desired bank 1 sectors */
+#define OB_WRPSTATE_ENABLE 0x00000001U /*!< Enable the write protection of the desired bank 1 sectors */
+/**
+ * @}
+ */
+
+/** @defgroup FLASHEx_Option_Type FLASH Option Type
+ * @{
+ */
+#define OPTIONBYTE_WRP 0x01U /*!< WRP option byte configuration */
+#define OPTIONBYTE_RDP 0x02U /*!< RDP option byte configuration */
+#define OPTIONBYTE_USER 0x04U /*!< USER option byte configuration */
+#define OPTIONBYTE_PCROP 0x08U /*!< PCROP option byte configuration */
+#define OPTIONBYTE_BOR 0x10U /*!< BOR option byte configuration */
+#define OPTIONBYTE_SECURE_AREA 0x20U /*!< secure area option byte configuration */
+#if defined (DUAL_CORE)
+#define OPTIONBYTE_CM7_BOOTADD 0x40U /*!< CM7 BOOT ADD option byte configuration */
+#define OPTIONBYTE_CM4_BOOTADD 0x80U /*!< CM4 BOOT ADD option byte configuration */
+#define OPTIONBYTE_BOOTADD OPTIONBYTE_CM7_BOOTADD /*!< BOOT ADD option byte configuration */
+#else /* Single core */
+#define OPTIONBYTE_BOOTADD 0x40U /*!< BOOT ADD option byte configuration */
+#endif /*DUAL_CORE*/
+#if defined (FLASH_OTPBL_LOCKBL)
+#define OPTIONBYTE_OTP_LOCK 0x80U /*!< OTP Lock option byte configuration */
+#endif /* FLASH_OTPBL_LOCKBL */
+#if defined (FLASH_OPTSR2_TCM_AXI_SHARED)
+#define OPTIONBYTE_SHARED_RAM 0x100U /*!< TCM / AXI Shared RAM option byte configuration */
+#endif /* FLASH_OPTSR2_TCM_AXI_SHARED */
+#if defined (FLASH_OPTSR2_CPUFREQ_BOOST)
+#define OPTIONBYTE_FREQ_BOOST 0x200U /*!< CPU Frequency Boost option byte configuration */
+#endif /* FLASH_OPTSR2_CPUFREQ_BOOST */
+
+#if defined (DUAL_CORE)
+#define OPTIONBYTE_ALL (OPTIONBYTE_WRP | OPTIONBYTE_RDP | OPTIONBYTE_USER |\
+ OPTIONBYTE_PCROP | OPTIONBYTE_BOR | OPTIONBYTE_SECURE_AREA |\
+ OPTIONBYTE_CM7_BOOTADD | OPTIONBYTE_CM4_BOOTADD) /*!< All option byte configuration */
+#elif defined (FLASH_OTPBL_LOCKBL)
+#define OPTIONBYTE_ALL (OPTIONBYTE_WRP | OPTIONBYTE_RDP | OPTIONBYTE_USER |\
+ OPTIONBYTE_PCROP | OPTIONBYTE_BOR | OPTIONBYTE_SECURE_AREA |\
+ OPTIONBYTE_BOOTADD | OPTIONBYTE_OTP_LOCK) /*!< All option byte configuration */
+#elif defined (FLASH_OPTSR2_TCM_AXI_SHARED)
+#define OPTIONBYTE_ALL (OPTIONBYTE_WRP | OPTIONBYTE_RDP | OPTIONBYTE_USER |\
+ OPTIONBYTE_PCROP | OPTIONBYTE_BOR | OPTIONBYTE_SECURE_AREA |\
+ OPTIONBYTE_BOOTADD | OPTIONBYTE_SHARED_RAM | OPTIONBYTE_FREQ_BOOST) /*!< All option byte configuration */
+#else
+#define OPTIONBYTE_ALL (OPTIONBYTE_WRP | OPTIONBYTE_RDP | OPTIONBYTE_USER |\
+ OPTIONBYTE_PCROP | OPTIONBYTE_BOR | OPTIONBYTE_SECURE_AREA |\
+ OPTIONBYTE_BOOTADD) /*!< All option byte configuration */
+#endif /* DUAL_CORE */
+/**
+ * @}
+ */
+
+/** @defgroup FLASHEx_Option_Bytes_Read_Protection FLASH Option Bytes Read Protection
+ * @{
+ */
+#define OB_RDP_LEVEL_0 0xAA00U
+#define OB_RDP_LEVEL_1 0x5500U
+#define OB_RDP_LEVEL_2 0xCC00U /*!< Warning: When enabling read protection level 2
+ it s no more possible to go back to level 1 or 0 */
+/**
+ * @}
+ */
+
+/** @defgroup FLASHEx_Option_Bytes_WWatchdog FLASH Option Bytes WWatchdog
+ * @{
+ */
+#define OB_WWDG_SW 0x10U /*!< Software WWDG selected */
+#define OB_WWDG_HW 0x00U /*!< Hardware WWDG selected */
+/**
+ * @}
+ */
+
+
+/** @defgroup FLASHEx_Option_Bytes_IWatchdog FLASH Option Bytes IWatchdog
+ * @{
+ */
+#define OB_IWDG_SW OB_IWDG1_SW /*!< Software IWDG selected */
+#define OB_IWDG_HW OB_IWDG1_HW /*!< Hardware IWDG selected */
+/**
+ * @}
+ */
+
+/** @defgroup FLASHEx_Option_Bytes_nRST_STOP FLASH Option Bytes nRST_STOP
+ * @{
+ */
+#define OB_STOP_NO_RST 0x40U /*!< No reset generated when entering in STOP */
+#define OB_STOP_RST 0x00U /*!< Reset generated when entering in STOP */
+/**
+ * @}
+ */
+
+/** @defgroup FLASHEx_Option_Bytes_nRST_STDBY FLASH Option Bytes nRST_STDBY
+ * @{
+ */
+#define OB_STDBY_NO_RST 0x80U /*!< No reset generated when entering in STANDBY */
+#define OB_STDBY_RST 0x00U /*!< Reset generated when entering in STANDBY */
+/**
+ * @}
+ */
+
+/** @defgroup FLASHEx_Option_Bytes_IWDG_FREEZE_STOP FLASH IWDG Counter Freeze in STOP
+ * @{
+ */
+#define OB_IWDG_STOP_FREEZE 0x00000000U /*!< Freeze IWDG counter in STOP mode */
+#define OB_IWDG_STOP_ACTIVE FLASH_OPTSR_FZ_IWDG_STOP /*!< IWDG counter active in STOP mode */
+/**
+ * @}
+ */
+
+/** @defgroup FLASHEx_Option_Bytes_IWDG_FREEZE_SANDBY FLASH IWDG Counter Freeze in STANDBY
+ * @{
+ */
+#define OB_IWDG_STDBY_FREEZE 0x00000000U /*!< Freeze IWDG counter in STANDBY mode */
+#define OB_IWDG_STDBY_ACTIVE FLASH_OPTSR_FZ_IWDG_SDBY /*!< IWDG counter active in STANDBY mode */
+/**
+ * @}
+ */
+
+/** @defgroup FLASHEx_BOR_Reset_Level FLASH BOR Reset Level
+ * @{
+ */
+#define OB_BOR_LEVEL0 0x00000000U /*!< Reset level threshold is set to 1.6V */
+#define OB_BOR_LEVEL1 FLASH_OPTSR_BOR_LEV_0 /*!< Reset level threshold is set to 2.1V */
+#define OB_BOR_LEVEL2 FLASH_OPTSR_BOR_LEV_1 /*!< Reset level threshold is set to 2.4V */
+#define OB_BOR_LEVEL3 (FLASH_OPTSR_BOR_LEV_1 | FLASH_OPTSR_BOR_LEV_0) /*!< Reset level threshold is set to 2.7V */
+/**
+ * @}
+ */
+
+
+
+/** @defgroup FLASHEx_Boot_Address FLASH Boot Address
+ * @{
+ */
+#define OB_BOOTADDR_ITCM_RAM 0x0000U /*!< Boot from ITCM RAM (0x00000000) */
+#define OB_BOOTADDR_SYSTEM 0x0040U /*!< Boot from System memory bootloader (0x00100000) */
+#define OB_BOOTADDR_ITCM_FLASH 0x0080U /*!< Boot from Flash on ITCM interface (0x00200000) */
+#define OB_BOOTADDR_AXIM_FLASH 0x2000U /*!< Boot from Flash on AXIM interface (0x08000000) */
+#define OB_BOOTADDR_DTCM_RAM 0x8000U /*!< Boot from DTCM RAM (0x20000000) */
+#define OB_BOOTADDR_SRAM1 0x8004U /*!< Boot from SRAM1 (0x20010000) */
+#define OB_BOOTADDR_SRAM2 0x8013U /*!< Boot from SRAM2 (0x2004C000) */
+/**
+ * @}
+ */
+
+/** @defgroup FLASH_Latency FLASH Latency
+ * @{
+ */
+#define FLASH_LATENCY_0 FLASH_ACR_LATENCY_0WS /*!< FLASH Zero Latency cycle */
+#define FLASH_LATENCY_1 FLASH_ACR_LATENCY_1WS /*!< FLASH One Latency cycle */
+#define FLASH_LATENCY_2 FLASH_ACR_LATENCY_2WS /*!< FLASH Two Latency cycles */
+#define FLASH_LATENCY_3 FLASH_ACR_LATENCY_3WS /*!< FLASH Three Latency cycles */
+#define FLASH_LATENCY_4 FLASH_ACR_LATENCY_4WS /*!< FLASH Four Latency cycles */
+#define FLASH_LATENCY_5 FLASH_ACR_LATENCY_5WS /*!< FLASH Five Latency cycles */
+#define FLASH_LATENCY_6 FLASH_ACR_LATENCY_6WS /*!< FLASH Six Latency cycles */
+#define FLASH_LATENCY_7 FLASH_ACR_LATENCY_7WS /*!< FLASH Seven Latency cycles */
+#define FLASH_LATENCY_8 FLASH_ACR_LATENCY_8WS /*!< FLASH Eight Latency cycle */
+#define FLASH_LATENCY_9 FLASH_ACR_LATENCY_9WS /*!< FLASH Nine Latency cycle */
+#define FLASH_LATENCY_10 FLASH_ACR_LATENCY_10WS /*!< FLASH Ten Latency cycles */
+#define FLASH_LATENCY_11 FLASH_ACR_LATENCY_11WS /*!< FLASH Eleven Latency cycles */
+#define FLASH_LATENCY_12 FLASH_ACR_LATENCY_12WS /*!< FLASH Twelve Latency cycles */
+#define FLASH_LATENCY_13 FLASH_ACR_LATENCY_13WS /*!< FLASH Thirteen Latency cycles */
+#define FLASH_LATENCY_14 FLASH_ACR_LATENCY_14WS /*!< FLASH Fourteen Latency cycles */
+#define FLASH_LATENCY_15 FLASH_ACR_LATENCY_15WS /*!< FLASH Fifteen Latency cycles */
+/**
+ * @}
+ */
+
+/** @defgroup FLASHEx_Banks FLASH Banks
+ * @{
+ */
+#define FLASH_BANK_1 0x01U /*!< Bank 1 */
+#if defined (DUAL_BANK)
+#define FLASH_BANK_2 0x02U /*!< Bank 2 */
+#define FLASH_BANK_BOTH (FLASH_BANK_1 | FLASH_BANK_2) /*!< Bank1 and Bank2 */
+#endif /* DUAL_BANK */
+/**
+ * @}
+ */
+
+/** @defgroup FLASHEx_OB_PCROP_RDP FLASHEx OB PCROP RDP
+ * @{
+ */
+#define OB_PCROP_RDP_NOT_ERASE 0x00000000U /*!< PCROP area is not erased when the RDP level
+ is decreased from Level 1 to Level 0 or during a mass erase */
+#define OB_PCROP_RDP_ERASE FLASH_PRAR_DMEP /*!< PCROP area is erased when the RDP level is
+ decreased from Level 1 to Level 0 (full mass erase) */
+
+/**
+ * @}
+ */
+
+/** @defgroup FLASHEx_Option_Bytes_Write_Protection FLASH Option Bytes Write Protection
+ * @{
+ */
+#if (FLASH_SECTOR_TOTAL == 128)
+#define OB_WRP_SECTOR_0TO3 0x00000001U /*!< Write protection of Sector0 to Sector3 */
+#define OB_WRP_SECTOR_4TO7 0x00000002U /*!< Write protection of Sector4 to Sector7 */
+#define OB_WRP_SECTOR_8TO11 0x00000004U /*!< Write protection of Sector8 to Sector11 */
+#define OB_WRP_SECTOR_12TO15 0x00000008U /*!< Write protection of Sector12 to Sector15 */
+#define OB_WRP_SECTOR_16TO19 0x00000010U /*!< Write protection of Sector16 to Sector19 */
+#define OB_WRP_SECTOR_20TO23 0x00000020U /*!< Write protection of Sector20 to Sector23 */
+#define OB_WRP_SECTOR_24TO27 0x00000040U /*!< Write protection of Sector24 to Sector27 */
+#define OB_WRP_SECTOR_28TO31 0x00000080U /*!< Write protection of Sector28 to Sector31 */
+#define OB_WRP_SECTOR_32TO35 0x00000100U /*!< Write protection of Sector32 to Sector35 */
+#define OB_WRP_SECTOR_36TO39 0x00000200U /*!< Write protection of Sector36 to Sector39 */
+#define OB_WRP_SECTOR_40TO43 0x00000400U /*!< Write protection of Sector40 to Sector43 */
+#define OB_WRP_SECTOR_44TO47 0x00000800U /*!< Write protection of Sector44 to Sector47 */
+#define OB_WRP_SECTOR_48TO51 0x00001000U /*!< Write protection of Sector48 to Sector51 */
+#define OB_WRP_SECTOR_52TO55 0x00002000U /*!< Write protection of Sector52 to Sector55 */
+#define OB_WRP_SECTOR_56TO59 0x00004000U /*!< Write protection of Sector56 to Sector59 */
+#define OB_WRP_SECTOR_60TO63 0x00008000U /*!< Write protection of Sector60 to Sector63 */
+#define OB_WRP_SECTOR_64TO67 0x00010000U /*!< Write protection of Sector64 to Sector67 */
+#define OB_WRP_SECTOR_68TO71 0x00020000U /*!< Write protection of Sector68 to Sector71 */
+#define OB_WRP_SECTOR_72TO75 0x00040000U /*!< Write protection of Sector72 to Sector75 */
+#define OB_WRP_SECTOR_76TO79 0x00080000U /*!< Write protection of Sector76 to Sector79 */
+#define OB_WRP_SECTOR_80TO83 0x00100000U /*!< Write protection of Sector80 to Sector83 */
+#define OB_WRP_SECTOR_84TO87 0x00200000U /*!< Write protection of Sector84 to Sector87 */
+#define OB_WRP_SECTOR_88TO91 0x00400000U /*!< Write protection of Sector88 to Sector91 */
+#define OB_WRP_SECTOR_92TO95 0x00800000U /*!< Write protection of Sector92 to Sector95 */
+#define OB_WRP_SECTOR_96TO99 0x01000000U /*!< Write protection of Sector96 to Sector99 */
+#define OB_WRP_SECTOR_100TO103 0x02000000U /*!< Write protection of Sector100 to Sector103 */
+#define OB_WRP_SECTOR_104TO107 0x04000000U /*!< Write protection of Sector104 to Sector107 */
+#define OB_WRP_SECTOR_108TO111 0x08000000U /*!< Write protection of Sector108 to Sector111 */
+#define OB_WRP_SECTOR_112TO115 0x10000000U /*!< Write protection of Sector112 to Sector115 */
+#define OB_WRP_SECTOR_116TO119 0x20000000U /*!< Write protection of Sector116 to Sector119 */
+#define OB_WRP_SECTOR_120TO123 0x40000000U /*!< Write protection of Sector120 to Sector123 */
+#define OB_WRP_SECTOR_124TO127 0x80000000U /*!< Write protection of Sector124 to Sector127 */
+#define OB_WRP_SECTOR_ALL 0xFFFFFFFFU /*!< Write protection of all Sectors */
+#else
+#define OB_WRP_SECTOR_0 0x00000001U /*!< Write protection of Sector0 */
+#define OB_WRP_SECTOR_1 0x00000002U /*!< Write protection of Sector1 */
+#define OB_WRP_SECTOR_2 0x00000004U /*!< Write protection of Sector2 */
+#define OB_WRP_SECTOR_3 0x00000008U /*!< Write protection of Sector3 */
+#define OB_WRP_SECTOR_4 0x00000010U /*!< Write protection of Sector4 */
+#define OB_WRP_SECTOR_5 0x00000020U /*!< Write protection of Sector5 */
+#define OB_WRP_SECTOR_6 0x00000040U /*!< Write protection of Sector6 */
+#define OB_WRP_SECTOR_7 0x00000080U /*!< Write protection of Sector7 */
+#define OB_WRP_SECTOR_ALL 0x000000FFU /*!< Write protection of all Sectors */
+#endif /* FLASH_SECTOR_TOTAL == 128 */
+/**
+ * @}
+ */
+
+/** @defgroup FLASHEx_OB_SECURITY FLASHEx OB SECURITY
+ * @{
+ */
+#define OB_SECURITY_DISABLE 0x00000000U /*!< security enabled */
+#define OB_SECURITY_ENABLE FLASH_OPTSR_SECURITY /*!< security disabled */
+/**
+ * @}
+ */
+
+/** @defgroup FLASHEx_OB_ST_RAM_SIZE FLASHEx OB ST RAM SIZE
+ * @{
+ */
+#define OB_ST_RAM_SIZE_2KB 0x00000000U /*!< 2 Kbytes reserved to ST code */
+#define OB_ST_RAM_SIZE_4KB FLASH_OPTSR_ST_RAM_SIZE_0 /*!< 4 Kbytes reserved to ST code */
+#define OB_ST_RAM_SIZE_8KB FLASH_OPTSR_ST_RAM_SIZE_1 /*!< 8 Kbytes reserved to ST code */
+#define OB_ST_RAM_SIZE_16KB FLASH_OPTSR_ST_RAM_SIZE /*!< 16 Kbytes reserved to ST code */
+/**
+ * @}
+ */
+
+#if defined(DUAL_CORE)
+/** @defgroup FLASHEx_OB_BCM7 FLASHEx OB BCM7
+ * @{
+ */
+#define OB_BCM7_DISABLE 0x00000000U /*!< CM7 Boot disabled */
+#define OB_BCM7_ENABLE FLASH_OPTSR_BCM7 /*!< CM7 Boot enabled */
+
+/**
+ * @}
+ */
+
+/** @defgroup FLASHEx_OB_BCM4 FLASHEx OB BCM4
+ * @{
+ */
+#define OB_BCM4_DISABLE 0x00000000U /*!< CM4 Boot disabled */
+#define OB_BCM4_ENABLE FLASH_OPTSR_BCM4 /*!< CM4 Boot enabled */
+/**
+ * @}
+ */
+#endif /* DUAL_CORE */
+
+/** @defgroup FLASHEx_OB_IWDG1_SW FLASHEx OB IWDG1 SW
+ * @{
+ */
+#define OB_IWDG1_SW FLASH_OPTSR_IWDG1_SW /*!< Hardware independent watchdog 1 */
+#define OB_IWDG1_HW 0x00000000U /*!< Software independent watchdog 1 */
+/**
+ * @}
+ */
+
+#if defined(DUAL_CORE)
+/** @defgroup FLASHEx_OB_IWDG2_SW FLASHEx OB IWDG2 SW
+ * @{
+ */
+#define OB_IWDG2_SW FLASH_OPTSR_IWDG2_SW /*!< Hardware independent watchdog 2*/
+#define OB_IWDG2_HW 0x00000000U /*!< Software independent watchdog 2*/
+/**
+ * @}
+ */
+#endif
+
+/** @defgroup FLASHEx_OB_NRST_STOP_D1 FLASHEx OB NRST STOP D1
+ * @{
+ */
+#define OB_STOP_RST_D1 0x00000000U /*!< Reset generated when entering the D1 to stop mode */
+#define OB_STOP_NO_RST_D1 FLASH_OPTSR_NRST_STOP_D1 /*!< No reset generated when entering the D1 to stop mode */
+/**
+ * @}
+ */
+
+/** @defgroup FLASHEx_OB_NRST_STDBY_D1 FLASHEx OB NRST STDBY D1
+ * @{
+ */
+#define OB_STDBY_RST_D1 0x00000000U /*!< Reset generated when entering the D1 to standby mode */
+#define OB_STDBY_NO_RST_D1 FLASH_OPTSR_NRST_STBY_D1 /*!< No reset generated when entering the D1 to standby mode */
+/**
+ * @}
+ */
+
+#if defined (FLASH_OPTSR_NRST_STOP_D2)
+/** @defgroup FLASHEx_OB_NRST_STOP_D2 FLASHEx OB NRST STOP D2
+ * @{
+ */
+#define OB_STOP_RST_D2 0x00000000U /*!< Reset generated when entering the D2 to stop mode */
+#define OB_STOP_NO_RST_D2 FLASH_OPTSR_NRST_STOP_D2 /*!< No reset generated when entering the D2 to stop mode */
+/**
+ * @}
+ */
+
+/** @defgroup FLASHEx_OB_NRST_STDBY_D2 FLASHEx OB NRST STDBY D2
+ * @{
+ */
+#define OB_STDBY_RST_D2 0x00000000U /*!< Reset generated when entering the D2 to standby mode */
+#define OB_STDBY_NO_RST_D2 FLASH_OPTSR_NRST_STBY_D2 /*!< No reset generated when entering the D2 to standby mode */
+/**
+ * @}
+ */
+#endif /* FLASH_OPTSR_NRST_STOP_D2 */
+
+/** @defgroup FLASHEx_OB_SWAP_BANK FLASHEx OB SWAP BANK
+ * @{
+ */
+#define OB_SWAP_BANK_DISABLE 0x00000000U /*!< Bank swap disabled */
+#define OB_SWAP_BANK_ENABLE FLASH_OPTSR_SWAP_BANK_OPT /*!< Bank swap enabled */
+/**
+ * @}
+ */
+
+/** @defgroup FLASHEx_OB_IOHSLV FLASHEx OB IOHSLV
+ * @{
+ */
+#define OB_IOHSLV_DISABLE 0x00000000U /*!< IOHSLV disabled */
+#define OB_IOHSLV_ENABLE FLASH_OPTSR_IO_HSLV /*!< IOHSLV enabled */
+/**
+ * @}
+ */
+
+#if defined (FLASH_OPTSR_VDDMMC_HSLV)
+/** @defgroup FLASHEx_OB_VDDMMC_HSLV FLASHEx OB VDDMMC HSLV
+ * @{
+ */
+#define OB_VDDMMC_HSLV_DISABLE 0x00000000U /*!< VDDMMC HSLV disabled */
+#define OB_VDDMMC_HSLV_ENABLE FLASH_OPTSR_VDDMMC_HSLV /*!< VDDMMC HSLV enabled */
+/**
+ * @}
+ */
+#endif /* FLASH_OPTSR_VDDMMC_HSLV */
+
+#if defined (FLASH_OPTSR2_CPUFREQ_BOOST)
+/** @defgroup FLASHEx_OB_CPUFREQ_BOOST FLASHEx OB CPUFREQ BOOST
+ * @{
+ */
+#define OB_CPUFREQ_BOOST_DISABLE 0x00000000U /*!< CPUFREQ BOOST disabled */
+#define OB_CPUFREQ_BOOST_ENABLE FLASH_OPTSR2_CPUFREQ_BOOST /*!< CPUFREQ BOOST enabled */
+/**
+ * @}
+ */
+#endif /* FLASH_OPTSR2_CPUFREQ_BOOST */
+
+#if defined (FLASH_OPTSR2_TCM_AXI_SHARED)
+/** @defgroup FLASHEx_OB_TCM_AXI_SHARED FLASHEx OB TCM AXI SHARED
+ * @{
+ */
+#define OB_TCM_AXI_SHARED_ITCM64KB 0x00000000U /*!< 64KB ITCM / 320KB system AXI */
+#define OB_TCM_AXI_SHARED_ITCM128KB FLASH_OPTSR2_TCM_AXI_SHARED_0 /*!< 128KB ITCM / 256KB system AXI */
+#define OB_TCM_AXI_SHARED_ITCM192KB FLASH_OPTSR2_TCM_AXI_SHARED_1 /*!< 192KB ITCM / 192KB system AXI */
+#define OB_TCM_AXI_SHARED_ITCM256KB FLASH_OPTSR2_TCM_AXI_SHARED /*!< 256KB ITCM / 128KB system AXI */
+/**
+ * @}
+ */
+#endif /* FLASH_OPTSR2_TCM_AXI_SHARED */
+
+ /** @defgroup FLASHEx_OB_USER_Type FLASHEx OB USER Type
+ * @{
+ */
+#define OB_USER_IWDG1_SW 0x0001U /*!< Independent watchdog selection */
+#define OB_USER_NRST_STOP_D1 0x0002U /*!< Reset when entering Stop mode selection*/
+#define OB_USER_NRST_STDBY_D1 0x0004U /*!< Reset when entering standby mode selection*/
+#define OB_USER_IWDG_STOP 0x0008U /*!< Independent watchdog counter freeze in stop mode */
+#define OB_USER_IWDG_STDBY 0x0010U /*!< Independent watchdog counter freeze in standby mode */
+#define OB_USER_ST_RAM_SIZE 0x0020U /*!< dedicated DTCM Ram size selection */
+#define OB_USER_SECURITY 0x0040U /*!< security selection */
+#define OB_USER_IOHSLV 0x0080U /*!< IO HSLV selection */
+#if defined (DUAL_BANK)
+#define OB_USER_SWAP_BANK 0x0100U /*!< Bank swap selection */
+#endif /* DUAL_BANK */
+#if defined (FLASH_OPTSR_VDDMMC_HSLV)
+#define OB_USER_VDDMMC_HSLV 0x0200U /*!< VDDMMC HSLV selection */
+#endif /* FLASH_OPTSR_VDDMMC_HSLV */
+#if defined (DUAL_CORE)
+#define OB_USER_IWDG2_SW 0x0200U /*!< Window watchdog selection */
+#define OB_USER_BCM4 0x0400U /*!< CM4 boot selection */
+#define OB_USER_BCM7 0x0800U /*!< CM7 boot selection */
+#endif /*DUAL_CORE*/
+#if defined (FLASH_OPTSR_NRST_STOP_D2)
+#define OB_USER_NRST_STOP_D2 0x1000U /*!< Reset when entering Stop mode selection */
+#define OB_USER_NRST_STDBY_D2 0x2000U /*!< Reset when entering standby mode selection */
+#endif /* FLASH_OPTSR_NRST_STOP_D2 */
+
+#if defined (DUAL_CORE)
+#define OB_USER_ALL (OB_USER_IWDG1_SW | OB_USER_NRST_STOP_D1 | OB_USER_NRST_STDBY_D1 |\
+ OB_USER_IWDG_STOP | OB_USER_IWDG_STDBY | OB_USER_ST_RAM_SIZE |\
+ OB_USER_SECURITY | OB_USER_IOHSLV | OB_USER_SWAP_BANK |\
+ OB_USER_IWDG2_SW | OB_USER_BCM4 | OB_USER_BCM7 |\
+ OB_USER_NRST_STOP_D2 | OB_USER_NRST_STDBY_D2)
+#elif defined (FLASH_OPTSR_VDDMMC_HSLV)
+#define OB_USER_ALL (OB_USER_IWDG1_SW | OB_USER_NRST_STOP_D1 | OB_USER_NRST_STDBY_D1 |\
+ OB_USER_IWDG_STOP | OB_USER_IWDG_STDBY | OB_USER_ST_RAM_SIZE |\
+ OB_USER_SECURITY | OB_USER_IOHSLV | OB_USER_SWAP_BANK |\
+ OB_USER_VDDMMC_HSLV)
+#elif defined (FLASH_OPTSR2_TCM_AXI_SHARED)
+#define OB_USER_ALL (OB_USER_IWDG1_SW | OB_USER_NRST_STOP_D1 | OB_USER_NRST_STDBY_D1 |\
+ OB_USER_IWDG_STOP | OB_USER_IWDG_STDBY | OB_USER_ST_RAM_SIZE |\
+ OB_USER_SECURITY | OB_USER_IOHSLV |\
+ OB_USER_NRST_STOP_D2 | OB_USER_NRST_STDBY_D2)
+#else
+#define OB_USER_ALL (OB_USER_IWDG1_SW | OB_USER_NRST_STOP_D1 | OB_USER_NRST_STDBY_D1 |\
+ OB_USER_IWDG_STOP | OB_USER_IWDG_STDBY | OB_USER_ST_RAM_SIZE |\
+ OB_USER_SECURITY | OB_USER_IOHSLV | OB_USER_SWAP_BANK )
+#endif /* DUAL_CORE */
+/**
+ * @}
+ */
+
+/** @defgroup FLASHEx_OB_BOOT_OPTION FLASHEx OB BOOT OPTION
+ * @{
+ */
+#define OB_BOOT_ADD0 0x01U /*!< Select Boot Address 0 */
+#define OB_BOOT_ADD1 0x02U /*!< Select Boot Address 1 */
+#define OB_BOOT_ADD_BOTH 0x03U /*!< Select Boot Address 0 and 1 */
+/**
+ * @}
+ */
+
+/** @defgroup FLASHEx_OB_SECURE_RDP FLASHEx OB SECURE RDP
+ * @{
+ */
+#define OB_SECURE_RDP_NOT_ERASE 0x00000000U /*!< Secure area is not erased when the RDP level
+ is decreased from Level 1 to Level 0 or during a mass erase */
+#define OB_SECURE_RDP_ERASE FLASH_SCAR_DMES /*!< Secure area is erased when the RDP level is
+ decreased from Level 1 to Level 0 (full mass erase) */
+/**
+ * @}
+ */
+
+/** @defgroup FLASHEx_CRC_Selection_Type FLASH CRC Selection Type
+ * @{
+ */
+#define FLASH_CRC_ADDR 0x00000000U /*!< CRC selection type by address */
+#define FLASH_CRC_SECTORS FLASH_CRCCR_CRC_BY_SECT /*!< CRC selection type by sectors */
+#define FLASH_CRC_BANK (FLASH_CRCCR_ALL_BANK | FLASH_CRCCR_CRC_BY_SECT) /*!< CRC selection type by bank */
+/**
+ * @}
+ */
+
+/** @defgroup FLASHEx_CRC_Burst_Size FLASH CRC Burst Size
+ * @{
+ */
+#define FLASH_CRC_BURST_SIZE_4 0x00000000U /*!< Every burst has a size of 4 Flash words (256-bit) */
+#define FLASH_CRC_BURST_SIZE_16 FLASH_CRCCR_CRC_BURST_0 /*!< Every burst has a size of 16 Flash words (256-bit) */
+#define FLASH_CRC_BURST_SIZE_64 FLASH_CRCCR_CRC_BURST_1 /*!< Every burst has a size of 64 Flash words (256-bit) */
+#define FLASH_CRC_BURST_SIZE_256 FLASH_CRCCR_CRC_BURST /*!< Every burst has a size of 256 Flash words (256-bit) */
+/**
+ * @}
+ */
+
+/** @defgroup FLASHEx_Programming_Delay FLASH Programming Delay
+ * @{
+ */
+#define FLASH_PROGRAMMING_DELAY_0 0x00000000U /*!< programming delay set for Flash running at 70 MHz or below */
+#define FLASH_PROGRAMMING_DELAY_1 FLASH_ACR_WRHIGHFREQ_0 /*!< programming delay set for Flash running between 70 MHz and 185 MHz */
+#define FLASH_PROGRAMMING_DELAY_2 FLASH_ACR_WRHIGHFREQ_1 /*!< programming delay set for Flash running between 185 MHz and 225 MHz */
+#define FLASH_PROGRAMMING_DELAY_3 FLASH_ACR_WRHIGHFREQ /*!< programming delay set for Flash at startup */
+/**
+ * @}
+ */
+
+#if defined (FLASH_OTPBL_LOCKBL)
+/** @defgroup FLASHEx_OTP_Blocks FLASH OTP blocks
+ * @{
+ */
+#define FLASH_OTP_BLOCK_0 0x00000001U /*!< OTP Block0 */
+#define FLASH_OTP_BLOCK_1 0x00000002U /*!< OTP Block1 */
+#define FLASH_OTP_BLOCK_2 0x00000004U /*!< OTP Block2 */
+#define FLASH_OTP_BLOCK_3 0x00000008U /*!< OTP Block3 */
+#define FLASH_OTP_BLOCK_4 0x00000010U /*!< OTP Block4 */
+#define FLASH_OTP_BLOCK_5 0x00000020U /*!< OTP Block5 */
+#define FLASH_OTP_BLOCK_6 0x00000040U /*!< OTP Block6 */
+#define FLASH_OTP_BLOCK_7 0x00000080U /*!< OTP Block7 */
+#define FLASH_OTP_BLOCK_8 0x00000100U /*!< OTP Block8 */
+#define FLASH_OTP_BLOCK_9 0x00000200U /*!< OTP Block9 */
+#define FLASH_OTP_BLOCK_10 0x00000400U /*!< OTP Block10 */
+#define FLASH_OTP_BLOCK_11 0x00000800U /*!< OTP Block11 */
+#define FLASH_OTP_BLOCK_12 0x00001000U /*!< OTP Block12 */
+#define FLASH_OTP_BLOCK_13 0x00002000U /*!< OTP Block13 */
+#define FLASH_OTP_BLOCK_14 0x00004000U /*!< OTP Block14 */
+#define FLASH_OTP_BLOCK_15 0x00008000U /*!< OTP Block15 */
+#define FLASH_OTP_BLOCK_ALL 0x0000FFFFU /*!< OTP All Blocks */
+/**
+ * @}
+ */
+#endif /* FLASH_OTPBL_LOCKBL */
+
+/* Exported macro ------------------------------------------------------------*/
+/** @defgroup FLASHEx_Exported_Macros FLASH Exported Macros
+ * @{
+ */
+/**
+ * @brief Calculate the FLASH Boot Base Adress (BOOT_ADD0 or BOOT_ADD1)
+ * @note Returned value BOOT_ADDx[15:0] corresponds to boot address [29:14].
+ * @param __ADDRESS__: FLASH Boot Address (in the range 0x0000 0000 to 0x2004 FFFF with a granularity of 16KB)
+ * @retval The FLASH Boot Base Adress
+ */
+#define __HAL_FLASH_CALC_BOOT_BASE_ADR(__ADDRESS__) ((__ADDRESS__) >> 14U)
+ /**
+ * @}
+ */
+
+#if defined (FLASH_CR_PSIZE)
+/**
+ * @brief Set the FLASH Program/Erase parallelism.
+ * @param __PSIZE__ FLASH Program/Erase parallelism
+ * This parameter can be a value of @ref FLASH_Program_Parallelism
+ * @param __BANK__: Flash bank (FLASH_BANK_1 or FLASH_BANK_2)
+ * @retval none
+ */
+#if defined (DUAL_BANK)
+#define __HAL_FLASH_SET_PSIZE(__PSIZE__, __BANK__) (((__BANK__) == FLASH_BANK_1) ? \
+ MODIFY_REG(FLASH->CR1, FLASH_CR_PSIZE, (__PSIZE__)) : \
+ MODIFY_REG(FLASH->CR2, FLASH_CR_PSIZE, (__PSIZE__)))
+#else
+#define __HAL_FLASH_SET_PSIZE(__PSIZE__, __BANK__) MODIFY_REG(FLASH->CR1, FLASH_CR_PSIZE, (__PSIZE__))
+#endif /* DUAL_BANK */
+
+/**
+ * @brief Get the FLASH Program/Erase parallelism.
+ * @param __BANK__ Flash bank (FLASH_BANK_1 or FLASH_BANK_2)
+ * @retval FLASH Program/Erase parallelism
+ * This return value can be a value of @ref FLASH_Program_Parallelism
+ */
+#if defined (DUAL_BANK)
+#define __HAL_FLASH_GET_PSIZE(__BANK__) (((__BANK__) == FLASH_BANK_1) ? \
+ READ_BIT((FLASH->CR1), FLASH_CR_PSIZE) : \
+ READ_BIT((FLASH->CR2), FLASH_CR_PSIZE))
+#else
+#define __HAL_FLASH_GET_PSIZE(__BANK__) READ_BIT((FLASH->CR1), FLASH_CR_PSIZE)
+#endif /* DUAL_BANK */
+
+#endif /* FLASH_CR_PSIZE */
+
+/**
+ * @brief Set the FLASH Programming Delay.
+ * @param __DELAY__ FLASH Programming Delay
+ * This parameter can be a value of @ref FLASHEx_Programming_Delay
+ * @retval none
+ */
+#define __HAL_FLASH_SET_PROGRAM_DELAY(__DELAY__) MODIFY_REG(FLASH->ACR, FLASH_ACR_WRHIGHFREQ, (__DELAY__))
+
+/**
+ * @brief Get the FLASH Programming Delay.
+ * @retval FLASH Programming Delay
+ * This return value can be a value of @ref FLASHEx_Programming_Delay
+ */
+#define __HAL_FLASH_GET_PROGRAM_DELAY() READ_BIT(FLASH->ACR, FLASH_ACR_WRHIGHFREQ)
+
+/* Exported functions --------------------------------------------------------*/
+/** @addtogroup FLASHEx_Exported_Functions
+ * @{
+ */
+
+/** @addtogroup FLASHEx_Exported_Functions_Group1
+ * @{
+ */
+/* Extension Program operation functions *************************************/
+HAL_StatusTypeDef HAL_FLASHEx_Erase(FLASH_EraseInitTypeDef *pEraseInit, uint32_t *SectorError);
+HAL_StatusTypeDef HAL_FLASHEx_Erase_IT(FLASH_EraseInitTypeDef *pEraseInit);
+HAL_StatusTypeDef HAL_FLASHEx_OBProgram(FLASH_OBProgramInitTypeDef *pOBInit);
+void HAL_FLASHEx_OBGetConfig(FLASH_OBProgramInitTypeDef *pOBInit);
+
+HAL_StatusTypeDef HAL_FLASHEx_Unlock_Bank1(void);
+HAL_StatusTypeDef HAL_FLASHEx_Lock_Bank1(void);
+#if defined (DUAL_BANK)
+HAL_StatusTypeDef HAL_FLASHEx_Unlock_Bank2(void);
+HAL_StatusTypeDef HAL_FLASHEx_Lock_Bank2(void);
+#endif /* DUAL_BANK */
+
+HAL_StatusTypeDef HAL_FLASHEx_ComputeCRC(FLASH_CRCInitTypeDef *pCRCInit, uint32_t *CRC_Result);
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+/* Private types -------------------------------------------------------------*/
+/* Private variables ---------------------------------------------------------*/
+/* Private constants ---------------------------------------------------------*/
+/* Private macros ------------------------------------------------------------*/
+/** @defgroup FLASHEx_Private_Macros FLASHEx Private Macros
+ * @{
+ */
+
+/** @defgroup FLASHEx_IS_FLASH_Definitions FLASHEx Private macros to check input parameters
+ * @{
+ */
+
+#define IS_FLASH_TYPEERASE(VALUE) (((VALUE) == FLASH_TYPEERASE_SECTORS) || \
+ ((VALUE) == FLASH_TYPEERASE_MASSERASE))
+
+#if defined (FLASH_CR_PSIZE)
+#define IS_VOLTAGERANGE(RANGE) (((RANGE) == FLASH_VOLTAGE_RANGE_1) || \
+ ((RANGE) == FLASH_VOLTAGE_RANGE_2) || \
+ ((RANGE) == FLASH_VOLTAGE_RANGE_3) || \
+ ((RANGE) == FLASH_VOLTAGE_RANGE_4))
+#endif /* FLASH_CR_PSIZE */
+
+#define IS_WRPSTATE(VALUE) (((VALUE) == OB_WRPSTATE_DISABLE) || \
+ ((VALUE) == OB_WRPSTATE_ENABLE))
+
+#define IS_OPTIONBYTE(VALUE) ((((VALUE) & OPTIONBYTE_ALL) != 0U) && \
+ (((VALUE) & ~OPTIONBYTE_ALL) == 0U))
+
+#define IS_OB_BOOT_ADDRESS(ADDRESS) ((ADDRESS) <= 0x8013U)
+
+#define IS_OB_RDP_LEVEL(LEVEL) (((LEVEL) == OB_RDP_LEVEL_0) ||\
+ ((LEVEL) == OB_RDP_LEVEL_1) ||\
+ ((LEVEL) == OB_RDP_LEVEL_2))
+
+#define IS_OB_WWDG_SOURCE(SOURCE) (((SOURCE) == OB_WWDG_SW) || ((SOURCE) == OB_WWDG_HW))
+
+#define IS_OB_IWDG_SOURCE(SOURCE) (((SOURCE) == OB_IWDG_SW) || ((SOURCE) == OB_IWDG_HW))
+
+#define IS_OB_STOP_SOURCE(SOURCE) (((SOURCE) == OB_STOP_NO_RST) || ((SOURCE) == OB_STOP_RST))
+
+#define IS_OB_STDBY_SOURCE(SOURCE) (((SOURCE) == OB_STDBY_NO_RST) || ((SOURCE) == OB_STDBY_RST))
+
+#define IS_OB_IWDG_STOP_FREEZE(FREEZE) (((FREEZE) == OB_IWDG_STOP_FREEZE) || ((FREEZE) == OB_IWDG_STOP_ACTIVE))
+
+#define IS_OB_IWDG_STDBY_FREEZE(FREEZE) (((FREEZE) == OB_IWDG_STDBY_FREEZE) || ((FREEZE) == OB_IWDG_STDBY_ACTIVE))
+
+#define IS_OB_BOR_LEVEL(LEVEL) (((LEVEL) == OB_BOR_LEVEL0) || ((LEVEL) == OB_BOR_LEVEL1) || \
+ ((LEVEL) == OB_BOR_LEVEL2) || ((LEVEL) == OB_BOR_LEVEL3))
+
+#define IS_FLASH_LATENCY(LATENCY) (((LATENCY) == FLASH_LATENCY_0) || \
+ ((LATENCY) == FLASH_LATENCY_1) || \
+ ((LATENCY) == FLASH_LATENCY_2) || \
+ ((LATENCY) == FLASH_LATENCY_3) || \
+ ((LATENCY) == FLASH_LATENCY_4) || \
+ ((LATENCY) == FLASH_LATENCY_5) || \
+ ((LATENCY) == FLASH_LATENCY_6) || \
+ ((LATENCY) == FLASH_LATENCY_7) || \
+ ((LATENCY) == FLASH_LATENCY_8) || \
+ ((LATENCY) == FLASH_LATENCY_9) || \
+ ((LATENCY) == FLASH_LATENCY_10) || \
+ ((LATENCY) == FLASH_LATENCY_11) || \
+ ((LATENCY) == FLASH_LATENCY_12) || \
+ ((LATENCY) == FLASH_LATENCY_13) || \
+ ((LATENCY) == FLASH_LATENCY_14) || \
+ ((LATENCY) == FLASH_LATENCY_15))
+
+#define IS_FLASH_SECTOR(SECTOR) ((SECTOR) < FLASH_SECTOR_TOTAL)
+
+#if (FLASH_SECTOR_TOTAL == 8U)
+#define IS_OB_WRP_SECTOR(SECTOR) ((((SECTOR) & 0xFFFFFF00U) == 0x00000000U) && ((SECTOR) != 0x00000000U))
+#else
+#define IS_OB_WRP_SECTOR(SECTOR) ((SECTOR) != 0x00000000U)
+#endif /* FLASH_SECTOR_TOTAL == 8U */
+
+#define IS_OB_PCROP_RDP(CONFIG) (((CONFIG) == OB_PCROP_RDP_NOT_ERASE) || \
+ ((CONFIG) == OB_PCROP_RDP_ERASE))
+
+#define IS_OB_SECURE_RDP(CONFIG) (((CONFIG) == OB_SECURE_RDP_NOT_ERASE) || \
+ ((CONFIG) == OB_SECURE_RDP_ERASE))
+
+#define IS_OB_USER_SWAP_BANK(VALUE) (((VALUE) == OB_SWAP_BANK_DISABLE) || ((VALUE) == OB_SWAP_BANK_ENABLE))
+
+#define IS_OB_USER_IOHSLV(VALUE) (((VALUE) == OB_IOHSLV_DISABLE) || ((VALUE) == OB_IOHSLV_ENABLE))
+
+#if defined (FLASH_OPTSR_VDDMMC_HSLV)
+#define IS_OB_USER_VDDMMC_HSLV(VALUE) (((VALUE) == OB_VDDMMC_HSLV_DISABLE) || ((VALUE) == OB_VDDMMC_HSLV_ENABLE))
+#endif /* FLASH_OPTSR_VDDMMC_HSLV */
+
+#define IS_OB_IWDG1_SOURCE(SOURCE) (((SOURCE) == OB_IWDG1_SW) || ((SOURCE) == OB_IWDG1_HW))
+#if defined (DUAL_CORE)
+#define IS_OB_IWDG2_SOURCE(SOURCE) (((SOURCE) == OB_IWDG2_SW) || ((SOURCE) == OB_IWDG2_HW))
+#endif /* DUAL_CORE */
+#define IS_OB_STOP_D1_RESET(VALUE) (((VALUE) == OB_STOP_NO_RST_D1) || ((VALUE) == OB_STOP_RST_D1))
+
+#define IS_OB_STDBY_D1_RESET(VALUE) (((VALUE) == OB_STDBY_NO_RST_D1) || ((VALUE) == OB_STDBY_RST_D1))
+
+#define IS_OB_USER_IWDG_STOP(VALUE) (((VALUE) == OB_IWDG_STOP_FREEZE) || ((VALUE) == OB_IWDG_STOP_ACTIVE))
+
+#define IS_OB_USER_IWDG_STDBY(VALUE) (((VALUE) == OB_IWDG_STDBY_FREEZE) || ((VALUE) == OB_IWDG_STDBY_ACTIVE))
+
+#define IS_OB_USER_ST_RAM_SIZE(VALUE) (((VALUE) == OB_ST_RAM_SIZE_2KB) || ((VALUE) == OB_ST_RAM_SIZE_4KB) || \
+ ((VALUE) == OB_ST_RAM_SIZE_8KB) || ((VALUE) == OB_ST_RAM_SIZE_16KB))
+
+#define IS_OB_USER_SECURITY(VALUE) (((VALUE) == OB_SECURITY_ENABLE) || ((VALUE) == OB_SECURITY_DISABLE))
+
+#if defined (DUAL_CORE)
+#define IS_OB_USER_BCM4(VALUE) (((VALUE) == OB_BCM4_DISABLE) || ((VALUE) == OB_BCM4_ENABLE))
+
+#define IS_OB_USER_BCM7(VALUE) (((VALUE) == OB_BCM7_DISABLE) || ((VALUE) == OB_BCM7_ENABLE))
+#endif /* DUAL_CORE */
+
+#if defined (FLASH_OPTSR_NRST_STOP_D2)
+#define IS_OB_STOP_D2_RESET(VALUE) (((VALUE) == OB_STOP_NO_RST_D2) || ((VALUE) == OB_STOP_RST_D2))
+
+#define IS_OB_STDBY_D2_RESET(VALUE) (((VALUE) == OB_STDBY_NO_RST_D2) || ((VALUE) == OB_STDBY_RST_D2))
+#endif /* FLASH_OPTSR_NRST_STOP_D2 */
+
+#if defined (FLASH_OPTSR2_TCM_AXI_SHARED)
+#define IS_OB_USER_TCM_AXI_SHARED(VALUE) (((VALUE) == OB_TCM_AXI_SHARED_ITCM64KB) || ((VALUE) == OB_TCM_AXI_SHARED_ITCM128KB) || \
+ ((VALUE) == OB_TCM_AXI_SHARED_ITCM192KB) || ((VALUE) == OB_TCM_AXI_SHARED_ITCM256KB))
+#endif /* FLASH_OPTSR2_TCM_AXI_SHARED */
+
+#if defined (FLASH_OPTSR2_CPUFREQ_BOOST)
+#define IS_OB_USER_CPUFREQ_BOOST(VALUE) (((VALUE) == OB_CPUFREQ_BOOST_DISABLE) || ((VALUE) == OB_CPUFREQ_BOOST_ENABLE))
+#endif /* FLASH_OPTSR2_CPUFREQ_BOOST */
+
+#define IS_OB_USER_TYPE(TYPE) ((((TYPE) & OB_USER_ALL) != 0U) && \
+ (((TYPE) & ~OB_USER_ALL) == 0U))
+
+#define IS_OB_BOOT_ADD_OPTION(VALUE) (((VALUE) == OB_BOOT_ADD0) || \
+ ((VALUE) == OB_BOOT_ADD1) || \
+ ((VALUE) == OB_BOOT_ADD_BOTH))
+
+#define IS_FLASH_TYPECRC(VALUE) (((VALUE) == FLASH_CRC_ADDR) || \
+ ((VALUE) == FLASH_CRC_SECTORS) || \
+ ((VALUE) == FLASH_CRC_BANK))
+
+#if defined (FLASH_OTPBL_LOCKBL)
+#define IS_OTP_BLOCK(VALUE) ((((VALUE) & 0xFFFF0000U) == 0x00000000U) && ((VALUE) != 0x00000000U))
+#endif /* FLASH_OTPBL_LOCKBL */
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/* Private functions ---------------------------------------------------------*/
+/** @defgroup FLASHEx_Private_Functions FLASHEx Private Functions
+ * @{
+ */
+void FLASH_Erase_Sector(uint32_t Sector, uint32_t Banks, uint32_t VoltageRange);
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* STM32H7xx_HAL_FLASH_EX_H */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/