You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

1039 lines
38 KiB

  1. /**
  2. ******************************************************************************
  3. * @file stm32f7xx_hal_flash_ex.c
  4. * @author MCD Application Team
  5. * @version V1.1.2
  6. * @date 23-September-2016
  7. * @brief Extended FLASH HAL module driver.
  8. * This file provides firmware functions to manage the following
  9. * functionalities of the FLASH extension peripheral:
  10. * + Extended programming operations functions
  11. *
  12. @verbatim
  13. ==============================================================================
  14. ##### Flash Extension features #####
  15. ==============================================================================
  16. [..] Comparing to other previous devices, the FLASH interface for STM32F76xx/STM32F77xx
  17. devices contains the following additional features
  18. (+) Capacity up to 2 Mbyte with dual bank architecture supporting read-while-write
  19. capability (RWW)
  20. (+) Dual bank memory organization
  21. (+) Dual boot mode
  22. ##### How to use this driver #####
  23. ==============================================================================
  24. [..] This driver provides functions to configure and program the FLASH memory
  25. of all STM32F7xx devices. It includes
  26. (#) FLASH Memory Erase functions:
  27. (++) Lock and Unlock the FLASH interface using HAL_FLASH_Unlock() and
  28. HAL_FLASH_Lock() functions
  29. (++) Erase function: Erase sector, erase all sectors
  30. (++) There are two modes of erase :
  31. (+++) Polling Mode using HAL_FLASHEx_Erase()
  32. (+++) Interrupt Mode using HAL_FLASHEx_Erase_IT()
  33. (#) Option Bytes Programming functions: Use HAL_FLASHEx_OBProgram() to :
  34. (++) Set/Reset the write protection
  35. (++) Set the Read protection Level
  36. (++) Set the BOR level
  37. (++) Program the user Option Bytes
  38. @endverbatim
  39. ******************************************************************************
  40. * @attention
  41. *
  42. * <h2><center>&copy; COPYRIGHT(c) 2016 STMicroelectronics</center></h2>
  43. *
  44. * Redistribution and use in source and binary forms, with or without modification,
  45. * are permitted provided that the following conditions are met:
  46. * 1. Redistributions of source code must retain the above copyright notice,
  47. * this list of conditions and the following disclaimer.
  48. * 2. Redistributions in binary form must reproduce the above copyright notice,
  49. * this list of conditions and the following disclaimer in the documentation
  50. * and/or other materials provided with the distribution.
  51. * 3. Neither the name of STMicroelectronics nor the names of its contributors
  52. * may be used to endorse or promote products derived from this software
  53. * without specific prior written permission.
  54. *
  55. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
  56. * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  57. * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  58. * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
  59. * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  60. * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
  61. * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
  62. * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
  63. * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  64. * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  65. *
  66. ******************************************************************************
  67. */
  68. /* Includes ------------------------------------------------------------------*/
  69. #include "stm32f7xx_hal.h"
  70. /** @addtogroup STM32F7xx_HAL_Driver
  71. * @{
  72. */
  73. /** @defgroup FLASHEx FLASHEx
  74. * @brief FLASH HAL Extension module driver
  75. * @{
  76. */
  77. #ifdef HAL_FLASH_MODULE_ENABLED
  78. /* Private typedef -----------------------------------------------------------*/
  79. /* Private define ------------------------------------------------------------*/
  80. /** @addtogroup FLASHEx_Private_Constants
  81. * @{
  82. */
  83. #define SECTOR_MASK 0xFFFFFF07U
  84. #define FLASH_TIMEOUT_VALUE 50000U/* 50 s */
  85. /**
  86. * @}
  87. */
  88. /* Private macro -------------------------------------------------------------*/
  89. /* Private variables ---------------------------------------------------------*/
  90. /** @addtogroup FLASHEx_Private_Variables
  91. * @{
  92. */
  93. extern FLASH_ProcessTypeDef pFlash;
  94. /**
  95. * @}
  96. */
  97. /* Private function prototypes -----------------------------------------------*/
  98. /** @addtogroup FLASHEx_Private_Functions
  99. * @{
  100. */
  101. /* Option bytes control */
  102. static HAL_StatusTypeDef FLASH_OB_EnableWRP(uint32_t WRPSector);
  103. static HAL_StatusTypeDef FLASH_OB_DisableWRP(uint32_t WRPSector);
  104. static HAL_StatusTypeDef FLASH_OB_RDP_LevelConfig(uint8_t Level);
  105. static HAL_StatusTypeDef FLASH_OB_BOR_LevelConfig(uint8_t Level);
  106. static HAL_StatusTypeDef FLASH_OB_BootAddressConfig(uint32_t BootOption, uint32_t Address);
  107. static uint32_t FLASH_OB_GetUser(void);
  108. static uint32_t FLASH_OB_GetWRP(void);
  109. static uint8_t FLASH_OB_GetRDP(void);
  110. static uint32_t FLASH_OB_GetBOR(void);
  111. static uint32_t FLASH_OB_GetBootAddress(uint32_t BootOption);
  112. #if defined (FLASH_OPTCR_nDBANK)
  113. static void FLASH_MassErase(uint8_t VoltageRange, uint32_t Banks);
  114. static HAL_StatusTypeDef FLASH_OB_UserConfig(uint32_t Wwdg, uint32_t Iwdg, uint32_t Stop, uint32_t Stdby, uint32_t Iwdgstop, \
  115. uint32_t Iwdgstdby, uint32_t NDBank, uint32_t NDBoot);
  116. #else
  117. static void FLASH_MassErase(uint8_t VoltageRange);
  118. static HAL_StatusTypeDef FLASH_OB_UserConfig(uint32_t Wwdg, uint32_t Iwdg, uint32_t Stop, uint32_t Stdby, uint32_t Iwdgstop, uint32_t Iwdgstdby);
  119. #endif /* FLASH_OPTCR_nDBANK */
  120. extern HAL_StatusTypeDef FLASH_WaitForLastOperation(uint32_t Timeout);
  121. /**
  122. * @}
  123. */
  124. /* Exported functions --------------------------------------------------------*/
  125. /** @defgroup FLASHEx_Exported_Functions FLASHEx Exported Functions
  126. * @{
  127. */
  128. /** @defgroup FLASHEx_Exported_Functions_Group1 Extended IO operation functions
  129. * @brief Extended IO operation functions
  130. *
  131. @verbatim
  132. ===============================================================================
  133. ##### Extended programming operation functions #####
  134. ===============================================================================
  135. [..]
  136. This subsection provides a set of functions allowing to manage the Extension FLASH
  137. programming operations Operations.
  138. @endverbatim
  139. * @{
  140. */
  141. /**
  142. * @brief Perform a mass erase or erase the specified FLASH memory sectors
  143. * @param[in] pEraseInit: pointer to an FLASH_EraseInitTypeDef structure that
  144. * contains the configuration information for the erasing.
  145. *
  146. * @param[out] SectorError: pointer to variable that
  147. * contains the configuration information on faulty sector in case of error
  148. * (0xFFFFFFFF means that all the sectors have been correctly erased)
  149. *
  150. * @retval HAL Status
  151. */
  152. HAL_StatusTypeDef HAL_FLASHEx_Erase(FLASH_EraseInitTypeDef *pEraseInit, uint32_t *SectorError)
  153. {
  154. HAL_StatusTypeDef status = HAL_ERROR;
  155. uint32_t index = 0;
  156. /* Process Locked */
  157. __HAL_LOCK(&pFlash);
  158. /* Check the parameters */
  159. assert_param(IS_FLASH_TYPEERASE(pEraseInit->TypeErase));
  160. /* Wait for last operation to be completed */
  161. status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE);
  162. if(status == HAL_OK)
  163. {
  164. /*Initialization of SectorError variable*/
  165. *SectorError = 0xFFFFFFFFU;
  166. if(pEraseInit->TypeErase == FLASH_TYPEERASE_MASSERASE)
  167. {
  168. /*Mass erase to be done*/
  169. #if defined (FLASH_OPTCR_nDBANK)
  170. FLASH_MassErase((uint8_t) pEraseInit->VoltageRange, pEraseInit->Banks);
  171. #else
  172. FLASH_MassErase((uint8_t) pEraseInit->VoltageRange);
  173. #endif /* FLASH_OPTCR_nDBANK */
  174. /* Wait for last operation to be completed */
  175. status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE);
  176. /* if the erase operation is completed, disable the MER Bit */
  177. FLASH->CR &= (~FLASH_MER_BIT);
  178. }
  179. else
  180. {
  181. /* Check the parameters */
  182. assert_param(IS_FLASH_NBSECTORS(pEraseInit->NbSectors + pEraseInit->Sector));
  183. /* Erase by sector by sector to be done*/
  184. for(index = pEraseInit->Sector; index < (pEraseInit->NbSectors + pEraseInit->Sector); index++)
  185. {
  186. FLASH_Erase_Sector(index, (uint8_t) pEraseInit->VoltageRange);
  187. /* Wait for last operation to be completed */
  188. status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE);
  189. /* If the erase operation is completed, disable the SER Bit and SNB Bits */
  190. CLEAR_BIT(FLASH->CR, (FLASH_CR_SER | FLASH_CR_SNB));
  191. if(status != HAL_OK)
  192. {
  193. /* In case of error, stop erase procedure and return the faulty sector*/
  194. *SectorError = index;
  195. break;
  196. }
  197. }
  198. }
  199. }
  200. /* Process Unlocked */
  201. __HAL_UNLOCK(&pFlash);
  202. return status;
  203. }
  204. /**
  205. * @brief Perform a mass erase or erase the specified FLASH memory sectors with interrupt enabled
  206. * @param pEraseInit: pointer to an FLASH_EraseInitTypeDef structure that
  207. * contains the configuration information for the erasing.
  208. *
  209. * @retval HAL Status
  210. */
  211. HAL_StatusTypeDef HAL_FLASHEx_Erase_IT(FLASH_EraseInitTypeDef *pEraseInit)
  212. {
  213. HAL_StatusTypeDef status = HAL_OK;
  214. /* Process Locked */
  215. __HAL_LOCK(&pFlash);
  216. /* Check the parameters */
  217. assert_param(IS_FLASH_TYPEERASE(pEraseInit->TypeErase));
  218. /* Enable End of FLASH Operation interrupt */
  219. __HAL_FLASH_ENABLE_IT(FLASH_IT_EOP);
  220. /* Enable Error source interrupt */
  221. __HAL_FLASH_ENABLE_IT(FLASH_IT_ERR);
  222. /* Clear pending flags (if any) */
  223. __HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_EOP | FLASH_FLAG_OPERR | FLASH_FLAG_WRPERR |\
  224. FLASH_FLAG_PGAERR | FLASH_FLAG_PGPERR| FLASH_FLAG_ERSERR);
  225. if(pEraseInit->TypeErase == FLASH_TYPEERASE_MASSERASE)
  226. {
  227. /*Mass erase to be done*/
  228. pFlash.ProcedureOnGoing = FLASH_PROC_MASSERASE;
  229. #if defined (FLASH_OPTCR_nDBANK)
  230. FLASH_MassErase((uint8_t) pEraseInit->VoltageRange, pEraseInit->Banks);
  231. #else
  232. FLASH_MassErase((uint8_t) pEraseInit->VoltageRange);
  233. #endif /* FLASH_OPTCR_nDBANK */
  234. }
  235. else
  236. {
  237. /* Erase by sector to be done*/
  238. /* Check the parameters */
  239. assert_param(IS_FLASH_NBSECTORS(pEraseInit->NbSectors + pEraseInit->Sector));
  240. pFlash.ProcedureOnGoing = FLASH_PROC_SECTERASE;
  241. pFlash.NbSectorsToErase = pEraseInit->NbSectors;
  242. pFlash.Sector = pEraseInit->Sector;
  243. pFlash.VoltageForErase = (uint8_t)pEraseInit->VoltageRange;
  244. /*Erase 1st sector and wait for IT*/
  245. FLASH_Erase_Sector(pEraseInit->Sector, pEraseInit->VoltageRange);
  246. }
  247. return status;
  248. }
  249. /**
  250. * @brief Program option bytes
  251. * @param pOBInit: pointer to an FLASH_OBInitStruct structure that
  252. * contains the configuration information for the programming.
  253. *
  254. * @retval HAL Status
  255. */
  256. HAL_StatusTypeDef HAL_FLASHEx_OBProgram(FLASH_OBProgramInitTypeDef *pOBInit)
  257. {
  258. HAL_StatusTypeDef status = HAL_ERROR;
  259. /* Process Locked */
  260. __HAL_LOCK(&pFlash);
  261. /* Check the parameters */
  262. assert_param(IS_OPTIONBYTE(pOBInit->OptionType));
  263. /* Write protection configuration */
  264. if((pOBInit->OptionType & OPTIONBYTE_WRP) == OPTIONBYTE_WRP)
  265. {
  266. assert_param(IS_WRPSTATE(pOBInit->WRPState));
  267. if(pOBInit->WRPState == OB_WRPSTATE_ENABLE)
  268. {
  269. /*Enable of Write protection on the selected Sector*/
  270. status = FLASH_OB_EnableWRP(pOBInit->WRPSector);
  271. }
  272. else
  273. {
  274. /*Disable of Write protection on the selected Sector*/
  275. status = FLASH_OB_DisableWRP(pOBInit->WRPSector);
  276. }
  277. }
  278. /* Read protection configuration */
  279. if((pOBInit->OptionType & OPTIONBYTE_RDP) == OPTIONBYTE_RDP)
  280. {
  281. status = FLASH_OB_RDP_LevelConfig(pOBInit->RDPLevel);
  282. }
  283. /* USER configuration */
  284. if((pOBInit->OptionType & OPTIONBYTE_USER) == OPTIONBYTE_USER)
  285. {
  286. #if defined (FLASH_OPTCR_nDBANK)
  287. status = FLASH_OB_UserConfig(pOBInit->USERConfig & OB_WWDG_SW,
  288. pOBInit->USERConfig & OB_IWDG_SW,
  289. pOBInit->USERConfig & OB_STOP_NO_RST,
  290. pOBInit->USERConfig & OB_STDBY_NO_RST,
  291. pOBInit->USERConfig & OB_IWDG_STOP_ACTIVE,
  292. pOBInit->USERConfig & OB_IWDG_STDBY_ACTIVE,
  293. pOBInit->USERConfig & OB_NDBANK_SINGLE_BANK,
  294. pOBInit->USERConfig & OB_DUAL_BOOT_DISABLE);
  295. #else
  296. status = FLASH_OB_UserConfig(pOBInit->USERConfig & OB_WWDG_SW,
  297. pOBInit->USERConfig & OB_IWDG_SW,
  298. pOBInit->USERConfig & OB_STOP_NO_RST,
  299. pOBInit->USERConfig & OB_STDBY_NO_RST,
  300. pOBInit->USERConfig & OB_IWDG_STOP_ACTIVE,
  301. pOBInit->USERConfig & OB_IWDG_STDBY_ACTIVE);
  302. #endif /* FLASH_OPTCR_nDBANK */
  303. }
  304. /* BOR Level configuration */
  305. if((pOBInit->OptionType & OPTIONBYTE_BOR) == OPTIONBYTE_BOR)
  306. {
  307. status = FLASH_OB_BOR_LevelConfig(pOBInit->BORLevel);
  308. }
  309. /* Boot 0 Address configuration */
  310. if((pOBInit->OptionType & OPTIONBYTE_BOOTADDR_0) == OPTIONBYTE_BOOTADDR_0)
  311. {
  312. status = FLASH_OB_BootAddressConfig(OPTIONBYTE_BOOTADDR_0, pOBInit->BootAddr0);
  313. }
  314. /* Boot 1 Address configuration */
  315. if((pOBInit->OptionType & OPTIONBYTE_BOOTADDR_1) == OPTIONBYTE_BOOTADDR_1)
  316. {
  317. status = FLASH_OB_BootAddressConfig(OPTIONBYTE_BOOTADDR_1, pOBInit->BootAddr1);
  318. }
  319. /* Process Unlocked */
  320. __HAL_UNLOCK(&pFlash);
  321. return status;
  322. }
  323. /**
  324. * @brief Get the Option byte configuration
  325. * @param pOBInit: pointer to an FLASH_OBInitStruct structure that
  326. * contains the configuration information for the programming.
  327. *
  328. * @retval None
  329. */
  330. void HAL_FLASHEx_OBGetConfig(FLASH_OBProgramInitTypeDef *pOBInit)
  331. {
  332. pOBInit->OptionType = OPTIONBYTE_WRP | OPTIONBYTE_RDP | OPTIONBYTE_USER |\
  333. OPTIONBYTE_BOR | OPTIONBYTE_BOOTADDR_0 | OPTIONBYTE_BOOTADDR_1;
  334. /*Get WRP*/
  335. pOBInit->WRPSector = FLASH_OB_GetWRP();
  336. /*Get RDP Level*/
  337. pOBInit->RDPLevel = FLASH_OB_GetRDP();
  338. /*Get USER*/
  339. pOBInit->USERConfig = FLASH_OB_GetUser();
  340. /*Get BOR Level*/
  341. pOBInit->BORLevel = FLASH_OB_GetBOR();
  342. /*Get Boot Address when Boot pin = 0 */
  343. pOBInit->BootAddr0 = FLASH_OB_GetBootAddress(OPTIONBYTE_BOOTADDR_0);
  344. /*Get Boot Address when Boot pin = 1 */
  345. pOBInit->BootAddr1 = FLASH_OB_GetBootAddress(OPTIONBYTE_BOOTADDR_1);
  346. }
  347. /**
  348. * @}
  349. */
  350. #if defined (FLASH_OPTCR_nDBANK)
  351. /**
  352. * @brief Full erase of FLASH memory sectors
  353. * @param VoltageRange: The device voltage range which defines the erase parallelism.
  354. * This parameter can be one of the following values:
  355. * @arg VOLTAGE_RANGE_1: when the device voltage range is 1.8V to 2.1V,
  356. * the operation will be done by byte (8-bit)
  357. * @arg VOLTAGE_RANGE_2: when the device voltage range is 2.1V to 2.7V,
  358. * the operation will be done by half word (16-bit)
  359. * @arg VOLTAGE_RANGE_3: when the device voltage range is 2.7V to 3.6V,
  360. * the operation will be done by word (32-bit)
  361. * @arg VOLTAGE_RANGE_4: when the device voltage range is 2.7V to 3.6V + External Vpp,
  362. * the operation will be done by double word (64-bit)
  363. * @param Banks: Banks to be erased
  364. * This parameter can be one of the following values:
  365. * @arg FLASH_BANK_1: Bank1 to be erased
  366. * @arg FLASH_BANK_2: Bank2 to be erased
  367. * @arg FLASH_BANK_BOTH: Bank1 and Bank2 to be erased
  368. *
  369. * @retval HAL Status
  370. */
  371. static void FLASH_MassErase(uint8_t VoltageRange, uint32_t Banks)
  372. {
  373. /* Check the parameters */
  374. assert_param(IS_VOLTAGERANGE(VoltageRange));
  375. assert_param(IS_FLASH_BANK(Banks));
  376. /* if the previous operation is completed, proceed to erase all sectors */
  377. FLASH->CR &= CR_PSIZE_MASK;
  378. if(Banks == FLASH_BANK_BOTH)
  379. {
  380. /* bank1 & bank2 will be erased*/
  381. FLASH->CR |= FLASH_MER_BIT;
  382. }
  383. else if(Banks == FLASH_BANK_2)
  384. {
  385. /*Only bank2 will be erased*/
  386. FLASH->CR |= FLASH_CR_MER2;
  387. }
  388. else
  389. {
  390. /*Only bank1 will be erased*/
  391. FLASH->CR |= FLASH_CR_MER1;
  392. }
  393. FLASH->CR |= FLASH_CR_STRT | ((uint32_t)VoltageRange <<8);
  394. /* Data synchronous Barrier (DSB) Just after the write operation
  395. This will force the CPU to respect the sequence of instruction (no optimization).*/
  396. __DSB();
  397. }
  398. /**
  399. * @brief Erase the specified FLASH memory sector
  400. * @param Sector: FLASH sector to erase
  401. * The value of this parameter depend on device used within the same series
  402. * @param VoltageRange: The device voltage range which defines the erase parallelism.
  403. * This parameter can be one of the following values:
  404. * @arg FLASH_VOLTAGE_RANGE_1: when the device voltage range is 1.8V to 2.1V,
  405. * the operation will be done by byte (8-bit)
  406. * @arg FLASH_VOLTAGE_RANGE_2: when the device voltage range is 2.1V to 2.7V,
  407. * the operation will be done by half word (16-bit)
  408. * @arg FLASH_VOLTAGE_RANGE_3: when the device voltage range is 2.7V to 3.6V,
  409. * the operation will be done by word (32-bit)
  410. * @arg FLASH_VOLTAGE_RANGE_4: when the device voltage range is 2.7V to 3.6V + External Vpp,
  411. * the operation will be done by double word (64-bit)
  412. *
  413. * @retval None
  414. */
  415. void FLASH_Erase_Sector(uint32_t Sector, uint8_t VoltageRange)
  416. {
  417. uint32_t tmp_psize = 0;
  418. /* Check the parameters */
  419. assert_param(IS_FLASH_SECTOR(Sector));
  420. assert_param(IS_VOLTAGERANGE(VoltageRange));
  421. if(VoltageRange == FLASH_VOLTAGE_RANGE_1)
  422. {
  423. tmp_psize = FLASH_PSIZE_BYTE;
  424. }
  425. else if(VoltageRange == FLASH_VOLTAGE_RANGE_2)
  426. {
  427. tmp_psize = FLASH_PSIZE_HALF_WORD;
  428. }
  429. else if(VoltageRange == FLASH_VOLTAGE_RANGE_3)
  430. {
  431. tmp_psize = FLASH_PSIZE_WORD;
  432. }
  433. else
  434. {
  435. tmp_psize = FLASH_PSIZE_DOUBLE_WORD;
  436. }
  437. /* Need to add offset of 4 when sector higher than FLASH_SECTOR_11 */
  438. if(Sector > FLASH_SECTOR_11)
  439. {
  440. Sector += 4;
  441. }
  442. /* If the previous operation is completed, proceed to erase the sector */
  443. FLASH->CR &= CR_PSIZE_MASK;
  444. FLASH->CR |= tmp_psize;
  445. CLEAR_BIT(FLASH->CR, FLASH_CR_SNB);
  446. FLASH->CR |= FLASH_CR_SER | (Sector << POSITION_VAL(FLASH_CR_SNB));
  447. FLASH->CR |= FLASH_CR_STRT;
  448. /* Data synchronous Barrier (DSB) Just after the write operation
  449. This will force the CPU to respect the sequence of instruction (no optimization).*/
  450. __DSB();
  451. }
  452. /**
  453. * @brief Return the FLASH Write Protection Option Bytes value.
  454. * @retval uint32_t FLASH Write Protection Option Bytes value
  455. */
  456. static uint32_t FLASH_OB_GetWRP(void)
  457. {
  458. /* Return the FLASH write protection Register value */
  459. return ((uint32_t)(FLASH->OPTCR & 0x0FFF0000));
  460. }
  461. /**
  462. * @brief Program the FLASH User Option Byte: IWDG_SW / RST_STOP / RST_STDBY.
  463. * @param Wwdg: Selects the IWDG mode
  464. * This parameter can be one of the following values:
  465. * @arg OB_WWDG_SW: Software WWDG selected
  466. * @arg OB_WWDG_HW: Hardware WWDG selected
  467. * @param Iwdg: Selects the WWDG mode
  468. * This parameter can be one of the following values:
  469. * @arg OB_IWDG_SW: Software IWDG selected
  470. * @arg OB_IWDG_HW: Hardware IWDG selected
  471. * @param Stop: Reset event when entering STOP mode.
  472. * This parameter can be one of the following values:
  473. * @arg OB_STOP_NO_RST: No reset generated when entering in STOP
  474. * @arg OB_STOP_RST: Reset generated when entering in STOP
  475. * @param Stdby: Reset event when entering Standby mode.
  476. * This parameter can be one of the following values:
  477. * @arg OB_STDBY_NO_RST: No reset generated when entering in STANDBY
  478. * @arg OB_STDBY_RST: Reset generated when entering in STANDBY
  479. * @param Iwdgstop: Independent watchdog counter freeze in Stop mode.
  480. * This parameter can be one of the following values:
  481. * @arg OB_IWDG_STOP_FREEZE: Freeze IWDG counter in STOP
  482. * @arg OB_IWDG_STOP_ACTIVE: IWDG counter active in STOP
  483. * @param Iwdgstdby: Independent watchdog counter freeze in standby mode.
  484. * This parameter can be one of the following values:
  485. * @arg OB_IWDG_STDBY_FREEZE: Freeze IWDG counter in STANDBY
  486. * @arg OB_IWDG_STDBY_ACTIVE: IWDG counter active in STANDBY
  487. * @param NDBank: Flash Single Bank mode enabled.
  488. * This parameter can be one of the following values:
  489. * @arg OB_NDBANK_SINGLE_BANK: enable 256 bits mode (Flash is a single bank)
  490. * @arg OB_NDBANK_DUAL_BANK: disable 256 bits mode (Flash is a dual bank in 128 bits mode)
  491. * @param NDBoot: Flash Dual boot mode disable.
  492. * This parameter can be one of the following values:
  493. * @arg OB_DUAL_BOOT_DISABLE: Disable Dual Boot
  494. * @arg OB_DUAL_BOOT_ENABLE: Enable Dual Boot
  495. * @retval HAL Status
  496. */
  497. static HAL_StatusTypeDef FLASH_OB_UserConfig(uint32_t Wwdg, uint32_t Iwdg, uint32_t Stop, uint32_t Stdby, uint32_t Iwdgstop, \
  498. uint32_t Iwdgstdby, uint32_t NDBank, uint32_t NDBoot)
  499. {
  500. uint32_t useroptionmask = 0x00;
  501. uint32_t useroptionvalue = 0x00;
  502. HAL_StatusTypeDef status = HAL_OK;
  503. /* Check the parameters */
  504. assert_param(IS_OB_WWDG_SOURCE(Wwdg));
  505. assert_param(IS_OB_IWDG_SOURCE(Iwdg));
  506. assert_param(IS_OB_STOP_SOURCE(Stop));
  507. assert_param(IS_OB_STDBY_SOURCE(Stdby));
  508. assert_param(IS_OB_IWDG_STOP_FREEZE(Iwdgstop));
  509. assert_param(IS_OB_IWDG_STDBY_FREEZE(Iwdgstdby));
  510. assert_param(IS_OB_NDBANK(NDBank));
  511. assert_param(IS_OB_NDBOOT(NDBoot));
  512. /* Wait for last operation to be completed */
  513. status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE);
  514. if(status == HAL_OK)
  515. {
  516. useroptionmask = (FLASH_OPTCR_WWDG_SW | FLASH_OPTCR_IWDG_SW | FLASH_OPTCR_nRST_STOP | \
  517. FLASH_OPTCR_nRST_STDBY | FLASH_OPTCR_IWDG_STOP | FLASH_OPTCR_IWDG_STDBY | \
  518. FLASH_OPTCR_nDBOOT | FLASH_OPTCR_nDBANK);
  519. useroptionvalue = (Iwdg | Wwdg | Stop | Stdby | Iwdgstop | Iwdgstdby | NDBoot | NDBank);
  520. /* Update User Option Byte */
  521. MODIFY_REG(FLASH->OPTCR, useroptionmask, useroptionvalue);
  522. }
  523. return status;
  524. }
  525. /**
  526. * @brief Return the FLASH User Option Byte value.
  527. * @retval uint32_t FLASH User Option Bytes values: WWDG_SW(Bit4), IWDG_SW(Bit5), nRST_STOP(Bit6),
  528. * nRST_STDBY(Bit7), nDBOOT(Bit28), nDBANK(Bit29), IWDG_STDBY(Bit30) and IWDG_STOP(Bit31).
  529. */
  530. static uint32_t FLASH_OB_GetUser(void)
  531. {
  532. /* Return the User Option Byte */
  533. return ((uint32_t)(FLASH->OPTCR & 0xF00000F0U));
  534. }
  535. #else
  536. /**
  537. * @brief Full erase of FLASH memory sectors
  538. * @param VoltageRange: The device voltage range which defines the erase parallelism.
  539. * This parameter can be one of the following values:
  540. * @arg VOLTAGE_RANGE_1: when the device voltage range is 1.8V to 2.1V,
  541. * the operation will be done by byte (8-bit)
  542. * @arg VOLTAGE_RANGE_2: when the device voltage range is 2.1V to 2.7V,
  543. * the operation will be done by half word (16-bit)
  544. * @arg VOLTAGE_RANGE_3: when the device voltage range is 2.7V to 3.6V,
  545. * the operation will be done by word (32-bit)
  546. * @arg VOLTAGE_RANGE_4: when the device voltage range is 2.7V to 3.6V + External Vpp,
  547. * the operation will be done by double word (64-bit)
  548. *
  549. * @retval HAL Status
  550. */
  551. static void FLASH_MassErase(uint8_t VoltageRange)
  552. {
  553. /* Check the parameters */
  554. assert_param(IS_VOLTAGERANGE(VoltageRange));
  555. /* if the previous operation is completed, proceed to erase all sectors */
  556. FLASH->CR &= CR_PSIZE_MASK;
  557. FLASH->CR |= FLASH_CR_MER;
  558. FLASH->CR |= FLASH_CR_STRT | ((uint32_t)VoltageRange <<8);
  559. /* Data synchronous Barrier (DSB) Just after the write operation
  560. This will force the CPU to respect the sequence of instruction (no optimization).*/
  561. __DSB();
  562. }
  563. /**
  564. * @brief Erase the specified FLASH memory sector
  565. * @param Sector: FLASH sector to erase
  566. * The value of this parameter depend on device used within the same series
  567. * @param VoltageRange: The device voltage range which defines the erase parallelism.
  568. * This parameter can be one of the following values:
  569. * @arg FLASH_VOLTAGE_RANGE_1: when the device voltage range is 1.8V to 2.1V,
  570. * the operation will be done by byte (8-bit)
  571. * @arg FLASH_VOLTAGE_RANGE_2: when the device voltage range is 2.1V to 2.7V,
  572. * the operation will be done by half word (16-bit)
  573. * @arg FLASH_VOLTAGE_RANGE_3: when the device voltage range is 2.7V to 3.6V,
  574. * the operation will be done by word (32-bit)
  575. * @arg FLASH_VOLTAGE_RANGE_4: when the device voltage range is 2.7V to 3.6V + External Vpp,
  576. * the operation will be done by double word (64-bit)
  577. *
  578. * @retval None
  579. */
  580. void FLASH_Erase_Sector(uint32_t Sector, uint8_t VoltageRange)
  581. {
  582. uint32_t tmp_psize = 0;
  583. /* Check the parameters */
  584. assert_param(IS_FLASH_SECTOR(Sector));
  585. assert_param(IS_VOLTAGERANGE(VoltageRange));
  586. if(VoltageRange == FLASH_VOLTAGE_RANGE_1)
  587. {
  588. tmp_psize = FLASH_PSIZE_BYTE;
  589. }
  590. else if(VoltageRange == FLASH_VOLTAGE_RANGE_2)
  591. {
  592. tmp_psize = FLASH_PSIZE_HALF_WORD;
  593. }
  594. else if(VoltageRange == FLASH_VOLTAGE_RANGE_3)
  595. {
  596. tmp_psize = FLASH_PSIZE_WORD;
  597. }
  598. else
  599. {
  600. tmp_psize = FLASH_PSIZE_DOUBLE_WORD;
  601. }
  602. /* If the previous operation is completed, proceed to erase the sector */
  603. FLASH->CR &= CR_PSIZE_MASK;
  604. FLASH->CR |= tmp_psize;
  605. FLASH->CR &= SECTOR_MASK;
  606. FLASH->CR |= FLASH_CR_SER | (Sector << POSITION_VAL(FLASH_CR_SNB));
  607. FLASH->CR |= FLASH_CR_STRT;
  608. /* Data synchronous Barrier (DSB) Just after the write operation
  609. This will force the CPU to respect the sequence of instruction (no optimization).*/
  610. __DSB();
  611. }
  612. /**
  613. * @brief Return the FLASH Write Protection Option Bytes value.
  614. * @retval uint32_t FLASH Write Protection Option Bytes value
  615. */
  616. static uint32_t FLASH_OB_GetWRP(void)
  617. {
  618. /* Return the FLASH write protection Register value */
  619. return ((uint32_t)(FLASH->OPTCR & 0x00FF0000));
  620. }
  621. /**
  622. * @brief Program the FLASH User Option Byte: IWDG_SW / RST_STOP / RST_STDBY.
  623. * @param Wwdg: Selects the IWDG mode
  624. * This parameter can be one of the following values:
  625. * @arg OB_WWDG_SW: Software WWDG selected
  626. * @arg OB_WWDG_HW: Hardware WWDG selected
  627. * @param Iwdg: Selects the WWDG mode
  628. * This parameter can be one of the following values:
  629. * @arg OB_IWDG_SW: Software IWDG selected
  630. * @arg OB_IWDG_HW: Hardware IWDG selected
  631. * @param Stop: Reset event when entering STOP mode.
  632. * This parameter can be one of the following values:
  633. * @arg OB_STOP_NO_RST: No reset generated when entering in STOP
  634. * @arg OB_STOP_RST: Reset generated when entering in STOP
  635. * @param Stdby: Reset event when entering Standby mode.
  636. * This parameter can be one of the following values:
  637. * @arg OB_STDBY_NO_RST: No reset generated when entering in STANDBY
  638. * @arg OB_STDBY_RST: Reset generated when entering in STANDBY
  639. * @param Iwdgstop: Independent watchdog counter freeze in Stop mode.
  640. * This parameter can be one of the following values:
  641. * @arg OB_IWDG_STOP_FREEZE: Freeze IWDG counter in STOP
  642. * @arg OB_IWDG_STOP_ACTIVE: IWDG counter active in STOP
  643. * @param Iwdgstdby: Independent watchdog counter freeze in standby mode.
  644. * This parameter can be one of the following values:
  645. * @arg OB_IWDG_STDBY_FREEZE: Freeze IWDG counter in STANDBY
  646. * @arg OB_IWDG_STDBY_ACTIVE: IWDG counter active in STANDBY
  647. * @retval HAL Status
  648. */
  649. static HAL_StatusTypeDef FLASH_OB_UserConfig(uint32_t Wwdg, uint32_t Iwdg, uint32_t Stop, uint32_t Stdby, uint32_t Iwdgstop, uint32_t Iwdgstdby)
  650. {
  651. uint32_t useroptionmask = 0x00;
  652. uint32_t useroptionvalue = 0x00;
  653. HAL_StatusTypeDef status = HAL_OK;
  654. /* Check the parameters */
  655. assert_param(IS_OB_WWDG_SOURCE(Wwdg));
  656. assert_param(IS_OB_IWDG_SOURCE(Iwdg));
  657. assert_param(IS_OB_STOP_SOURCE(Stop));
  658. assert_param(IS_OB_STDBY_SOURCE(Stdby));
  659. assert_param(IS_OB_IWDG_STOP_FREEZE(Iwdgstop));
  660. assert_param(IS_OB_IWDG_STDBY_FREEZE(Iwdgstdby));
  661. /* Wait for last operation to be completed */
  662. status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE);
  663. if(status == HAL_OK)
  664. {
  665. useroptionmask = (FLASH_OPTCR_WWDG_SW | FLASH_OPTCR_IWDG_SW | FLASH_OPTCR_nRST_STOP | \
  666. FLASH_OPTCR_nRST_STDBY | FLASH_OPTCR_IWDG_STOP | FLASH_OPTCR_IWDG_STDBY);
  667. useroptionvalue = (Iwdg | Wwdg | Stop | Stdby | Iwdgstop | Iwdgstdby);
  668. /* Update User Option Byte */
  669. MODIFY_REG(FLASH->OPTCR, useroptionmask, useroptionvalue);
  670. }
  671. return status;
  672. }
  673. /**
  674. * @brief Return the FLASH User Option Byte value.
  675. * @retval uint32_t FLASH User Option Bytes values: WWDG_SW(Bit4), IWDG_SW(Bit5), nRST_STOP(Bit6),
  676. * nRST_STDBY(Bit7), IWDG_STDBY(Bit30) and IWDG_STOP(Bit31).
  677. */
  678. static uint32_t FLASH_OB_GetUser(void)
  679. {
  680. /* Return the User Option Byte */
  681. return ((uint32_t)(FLASH->OPTCR & 0xC00000F0U));
  682. }
  683. #endif /* FLASH_OPTCR_nDBANK */
  684. /**
  685. * @brief Enable the write protection of the desired bank1 or bank2 sectors
  686. *
  687. * @note When the memory read protection level is selected (RDP level = 1),
  688. * it is not possible to program or erase the flash sector i if CortexM7
  689. * debug features are connected or boot code is executed in RAM, even if nWRPi = 1
  690. *
  691. * @param WRPSector: specifies the sector(s) to be write protected.
  692. * This parameter can be one of the following values:
  693. * @arg WRPSector: A value between OB_WRP_SECTOR_0 and OB_WRP_SECTOR_7 (for STM32F74xxx/STM32F75xxx devices)
  694. * or a value between OB_WRP_SECTOR_0 and OB_WRP_SECTOR_11 (in Single Bank mode for STM32F76xxx/STM32F77xxx devices)
  695. * or a value between OB_WRP_DB_SECTOR_0 and OB_WRP_DB_SECTOR_23 (in Dual Bank mode for STM32F76xxx/STM32F77xxx devices)
  696. * @arg OB_WRP_SECTOR_All
  697. *
  698. * @retval HAL FLASH State
  699. */
  700. static HAL_StatusTypeDef FLASH_OB_EnableWRP(uint32_t WRPSector)
  701. {
  702. HAL_StatusTypeDef status = HAL_OK;
  703. /* Check the parameters */
  704. assert_param(IS_OB_WRP_SECTOR(WRPSector));
  705. /* Wait for last operation to be completed */
  706. status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE);
  707. if(status == HAL_OK)
  708. {
  709. /*Write protection enabled on sectors */
  710. FLASH->OPTCR &= (~WRPSector);
  711. }
  712. return status;
  713. }
  714. /**
  715. * @brief Disable the write protection of the desired bank1 or bank 2 sectors
  716. *
  717. * @note When the memory read protection level is selected (RDP level = 1),
  718. * it is not possible to program or erase the flash sector i if CortexM4
  719. * debug features are connected or boot code is executed in RAM, even if nWRPi = 1
  720. *
  721. * @param WRPSector: specifies the sector(s) to be write protected.
  722. * This parameter can be one of the following values:
  723. * @arg WRPSector: A value between OB_WRP_SECTOR_0 and OB_WRP_SECTOR_7 (for STM32F74xxx/STM32F75xxx devices)
  724. * or a value between OB_WRP_SECTOR_0 and OB_WRP_SECTOR_11 (in Single Bank mode for STM32F76xxx/STM32F77xxx devices)
  725. * or a value between OB_WRP_DB_SECTOR_0 and OB_WRP_DB_SECTOR_23 (in Dual Bank mode for STM32F76xxx/STM32F77xxx devices)
  726. * @arg OB_WRP_Sector_All
  727. *
  728. *
  729. * @retval HAL Status
  730. */
  731. static HAL_StatusTypeDef FLASH_OB_DisableWRP(uint32_t WRPSector)
  732. {
  733. HAL_StatusTypeDef status = HAL_OK;
  734. /* Check the parameters */
  735. assert_param(IS_OB_WRP_SECTOR(WRPSector));
  736. /* Wait for last operation to be completed */
  737. status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE);
  738. if(status == HAL_OK)
  739. {
  740. /* Write protection disabled on sectors */
  741. FLASH->OPTCR |= (WRPSector);
  742. }
  743. return status;
  744. }
  745. /**
  746. * @brief Set the read protection level.
  747. * @param Level: specifies the read protection level.
  748. * This parameter can be one of the following values:
  749. * @arg OB_RDP_LEVEL_0: No protection
  750. * @arg OB_RDP_LEVEL_1: Read protection of the memory
  751. * @arg OB_RDP_LEVEL_2: Full chip protection
  752. *
  753. * @note WARNING: When enabling OB_RDP level 2 it's no more possible to go back to level 1 or 0
  754. *
  755. * @retval HAL Status
  756. */
  757. static HAL_StatusTypeDef FLASH_OB_RDP_LevelConfig(uint8_t Level)
  758. {
  759. HAL_StatusTypeDef status = HAL_OK;
  760. /* Check the parameters */
  761. assert_param(IS_OB_RDP_LEVEL(Level));
  762. /* Wait for last operation to be completed */
  763. status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE);
  764. if(status == HAL_OK)
  765. {
  766. *(__IO uint8_t*)OPTCR_BYTE1_ADDRESS = Level;
  767. }
  768. return status;
  769. }
  770. /**
  771. * @brief Set the BOR Level.
  772. * @param Level: specifies the Option Bytes BOR Reset Level.
  773. * This parameter can be one of the following values:
  774. * @arg OB_BOR_LEVEL3: Supply voltage ranges from 2.7 to 3.6 V
  775. * @arg OB_BOR_LEVEL2: Supply voltage ranges from 2.4 to 2.7 V
  776. * @arg OB_BOR_LEVEL1: Supply voltage ranges from 2.1 to 2.4 V
  777. * @arg OB_BOR_OFF: Supply voltage ranges from 1.62 to 2.1 V
  778. * @retval HAL Status
  779. */
  780. static HAL_StatusTypeDef FLASH_OB_BOR_LevelConfig(uint8_t Level)
  781. {
  782. /* Check the parameters */
  783. assert_param(IS_OB_BOR_LEVEL(Level));
  784. /* Set the BOR Level */
  785. MODIFY_REG(FLASH->OPTCR, FLASH_OPTCR_BOR_LEV, Level);
  786. return HAL_OK;
  787. }
  788. /**
  789. * @brief Configure Boot base address.
  790. *
  791. * @param BootOption : specifies Boot base address depending from Boot pin = 0 or pin = 1
  792. * This parameter can be one of the following values:
  793. * @arg OPTIONBYTE_BOOTADDR_0 : Boot address based when Boot pin = 0
  794. * @arg OPTIONBYTE_BOOTADDR_1 : Boot address based when Boot pin = 1
  795. * @param Address: specifies Boot base address
  796. * This parameter can be one of the following values:
  797. * @arg OB_BOOTADDR_ITCM_RAM : Boot from ITCM RAM (0x00000000)
  798. * @arg OB_BOOTADDR_SYSTEM : Boot from System memory bootloader (0x00100000)
  799. * @arg OB_BOOTADDR_ITCM_FLASH : Boot from Flash on ITCM interface (0x00200000)
  800. * @arg OB_BOOTADDR_AXIM_FLASH : Boot from Flash on AXIM interface (0x08000000)
  801. * @arg OB_BOOTADDR_DTCM_RAM : Boot from DTCM RAM (0x20000000)
  802. * @arg OB_BOOTADDR_SRAM1 : Boot from SRAM1 (0x20010000)
  803. * @arg OB_BOOTADDR_SRAM2 : Boot from SRAM2 (0x2004C000)
  804. *
  805. * @retval HAL Status
  806. */
  807. static HAL_StatusTypeDef FLASH_OB_BootAddressConfig(uint32_t BootOption, uint32_t Address)
  808. {
  809. HAL_StatusTypeDef status = HAL_OK;
  810. /* Check the parameters */
  811. assert_param(IS_OB_BOOT_ADDRESS(Address));
  812. /* Wait for last operation to be completed */
  813. status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE);
  814. if(status == HAL_OK)
  815. {
  816. if(BootOption == OPTIONBYTE_BOOTADDR_0)
  817. {
  818. MODIFY_REG(FLASH->OPTCR1, FLASH_OPTCR1_BOOT_ADD0, Address);
  819. }
  820. else
  821. {
  822. MODIFY_REG(FLASH->OPTCR1, FLASH_OPTCR1_BOOT_ADD1, (Address << 16));
  823. }
  824. }
  825. return status;
  826. }
  827. /**
  828. * @brief Returns the FLASH Read Protection level.
  829. * @retval FlagStatus FLASH ReadOut Protection Status:
  830. * This parameter can be one of the following values:
  831. * @arg OB_RDP_LEVEL_0: No protection
  832. * @arg OB_RDP_LEVEL_1: Read protection of the memory
  833. * @arg OB_RDP_LEVEL_2: Full chip protection
  834. */
  835. static uint8_t FLASH_OB_GetRDP(void)
  836. {
  837. uint8_t readstatus = OB_RDP_LEVEL_0;
  838. if ((*(__IO uint8_t*)(OPTCR_BYTE1_ADDRESS)) == OB_RDP_LEVEL_0)
  839. {
  840. readstatus = OB_RDP_LEVEL_0;
  841. }
  842. else if ((*(__IO uint8_t*)(OPTCR_BYTE1_ADDRESS)) == OB_RDP_LEVEL_2)
  843. {
  844. readstatus = OB_RDP_LEVEL_2;
  845. }
  846. else
  847. {
  848. readstatus = OB_RDP_LEVEL_1;
  849. }
  850. return readstatus;
  851. }
  852. /**
  853. * @brief Returns the FLASH BOR level.
  854. * @retval uint32_t The FLASH BOR level:
  855. * - OB_BOR_LEVEL3: Supply voltage ranges from 2.7 to 3.6 V
  856. * - OB_BOR_LEVEL2: Supply voltage ranges from 2.4 to 2.7 V
  857. * - OB_BOR_LEVEL1: Supply voltage ranges from 2.1 to 2.4 V
  858. * - OB_BOR_OFF : Supply voltage ranges from 1.62 to 2.1 V
  859. */
  860. static uint32_t FLASH_OB_GetBOR(void)
  861. {
  862. /* Return the FLASH BOR level */
  863. return ((uint32_t)(FLASH->OPTCR & 0x0C));
  864. }
  865. /**
  866. * @brief Configure Boot base address.
  867. *
  868. * @param BootOption : specifies Boot base address depending from Boot pin = 0 or pin = 1
  869. * This parameter can be one of the following values:
  870. * @arg OPTIONBYTE_BOOTADDR_0 : Boot address based when Boot pin = 0
  871. * @arg OPTIONBYTE_BOOTADDR_1 : Boot address based when Boot pin = 1
  872. *
  873. * @retval uint32_t Boot Base Address:
  874. * - OB_BOOTADDR_ITCM_RAM : Boot from ITCM RAM (0x00000000)
  875. * - OB_BOOTADDR_SYSTEM : Boot from System memory bootloader (0x00100000)
  876. * - OB_BOOTADDR_ITCM_FLASH : Boot from Flash on ITCM interface (0x00200000)
  877. * - OB_BOOTADDR_AXIM_FLASH : Boot from Flash on AXIM interface (0x08000000)
  878. * - OB_BOOTADDR_DTCM_RAM : Boot from DTCM RAM (0x20000000)
  879. * - OB_BOOTADDR_SRAM1 : Boot from SRAM1 (0x20010000)
  880. * - OB_BOOTADDR_SRAM2 : Boot from SRAM2 (0x2004C000)
  881. */
  882. static uint32_t FLASH_OB_GetBootAddress(uint32_t BootOption)
  883. {
  884. uint32_t Address = 0;
  885. /* Return the Boot base Address */
  886. if(BootOption == OPTIONBYTE_BOOTADDR_0)
  887. {
  888. Address = FLASH->OPTCR1 & FLASH_OPTCR1_BOOT_ADD0;
  889. }
  890. else
  891. {
  892. Address = ((FLASH->OPTCR1 & FLASH_OPTCR1_BOOT_ADD1) >> 16);
  893. }
  894. return Address;
  895. }
  896. /**
  897. * @}
  898. */
  899. #endif /* HAL_FLASH_MODULE_ENABLED */
  900. /**
  901. * @}
  902. */
  903. /**
  904. * @}
  905. */
  906. /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/