stm32f1xx_hal_flash_ex.c 35 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121
  1. /**
  2. ******************************************************************************
  3. * @file stm32f1xx_hal_flash_ex.c
  4. * @author MCD Application Team
  5. * @brief Extended FLASH HAL module driver.
  6. *
  7. * This file provides firmware functions to manage the following
  8. * functionalities of the FLASH peripheral:
  9. * + Extended Initialization/de-initialization functions
  10. * + Extended I/O operation functions
  11. * + Extended Peripheral Control functions
  12. *
  13. @verbatim
  14. ==============================================================================
  15. ##### Flash peripheral extended features #####
  16. ==============================================================================
  17. ##### How to use this driver #####
  18. ==============================================================================
  19. [..] This driver provides functions to configure and program the FLASH memory
  20. of all STM32F1xxx devices. It includes
  21. (++) Set/Reset the write protection
  22. (++) Program the user Option Bytes
  23. (++) Get the Read protection Level
  24. @endverbatim
  25. ******************************************************************************
  26. * @attention
  27. *
  28. * Copyright (c) 2016 STMicroelectronics.
  29. * All rights reserved.
  30. *
  31. * This software is licensed under terms that can be found in the LICENSE file in
  32. * the root directory of this software component.
  33. * If no LICENSE file comes with this software, it is provided AS-IS.
  34. ******************************************************************************
  35. */
  36. /* Includes ------------------------------------------------------------------*/
  37. #include "stm32f1xx_hal.h"
  38. /** @addtogroup STM32F1xx_HAL_Driver
  39. * @{
  40. */
  41. #ifdef HAL_FLASH_MODULE_ENABLED
  42. /** @addtogroup FLASH
  43. * @{
  44. */
  45. /** @addtogroup FLASH_Private_Variables
  46. * @{
  47. */
  48. /* Variables used for Erase pages under interruption*/
  49. extern FLASH_ProcessTypeDef pFlash;
  50. /**
  51. * @}
  52. */
  53. /**
  54. * @}
  55. */
  56. /** @defgroup FLASHEx FLASHEx
  57. * @brief FLASH HAL Extension module driver
  58. * @{
  59. */
  60. /* Private typedef -----------------------------------------------------------*/
  61. /* Private define ------------------------------------------------------------*/
  62. /** @defgroup FLASHEx_Private_Constants FLASHEx Private Constants
  63. * @{
  64. */
  65. #define FLASH_POSITION_IWDGSW_BIT FLASH_OBR_IWDG_SW_Pos
  66. #define FLASH_POSITION_OB_USERDATA0_BIT FLASH_OBR_DATA0_Pos
  67. #define FLASH_POSITION_OB_USERDATA1_BIT FLASH_OBR_DATA1_Pos
  68. /**
  69. * @}
  70. */
  71. /* Private macro -------------------------------------------------------------*/
  72. /** @defgroup FLASHEx_Private_Macros FLASHEx Private Macros
  73. * @{
  74. */
  75. /**
  76. * @}
  77. */
  78. /* Private variables ---------------------------------------------------------*/
  79. /* Private function prototypes -----------------------------------------------*/
  80. /** @defgroup FLASHEx_Private_Functions FLASHEx Private Functions
  81. * @{
  82. */
  83. /* Erase operations */
  84. static void FLASH_MassErase(uint32_t Banks);
  85. void FLASH_PageErase(uint32_t PageAddress);
  86. /* Option bytes control */
  87. static HAL_StatusTypeDef FLASH_OB_EnableWRP(uint32_t WriteProtectPage);
  88. static HAL_StatusTypeDef FLASH_OB_DisableWRP(uint32_t WriteProtectPage);
  89. static HAL_StatusTypeDef FLASH_OB_RDP_LevelConfig(uint8_t ReadProtectLevel);
  90. static HAL_StatusTypeDef FLASH_OB_UserConfig(uint8_t UserConfig);
  91. static HAL_StatusTypeDef FLASH_OB_ProgramData(uint32_t Address, uint8_t Data);
  92. static uint32_t FLASH_OB_GetWRP(void);
  93. static uint32_t FLASH_OB_GetRDP(void);
  94. static uint8_t FLASH_OB_GetUser(void);
  95. /**
  96. * @}
  97. */
  98. /* Exported functions ---------------------------------------------------------*/
  99. /** @defgroup FLASHEx_Exported_Functions FLASHEx Exported Functions
  100. * @{
  101. */
  102. /** @defgroup FLASHEx_Exported_Functions_Group1 FLASHEx Memory Erasing functions
  103. * @brief FLASH Memory Erasing functions
  104. *
  105. @verbatim
  106. ==============================================================================
  107. ##### FLASH Erasing Programming functions #####
  108. ==============================================================================
  109. [..] The FLASH Memory Erasing functions, includes the following functions:
  110. (+) HAL_FLASHEx_Erase: return only when erase has been done
  111. (+) HAL_FLASHEx_Erase_IT: end of erase is done when HAL_FLASH_EndOfOperationCallback
  112. is called with parameter 0xFFFFFFFF
  113. [..] Any operation of erase should follow these steps:
  114. (#) Call the HAL_FLASH_Unlock() function to enable the flash control register and
  115. program memory access.
  116. (#) Call the desired function to erase page.
  117. (#) Call the HAL_FLASH_Lock() to disable the flash program memory access
  118. (recommended to protect the FLASH memory against possible unwanted operation).
  119. @endverbatim
  120. * @{
  121. */
  122. /**
  123. * @brief Perform a mass erase or erase the specified FLASH memory pages
  124. * @note To correctly run this function, the @ref HAL_FLASH_Unlock() function
  125. * must be called before.
  126. * Call the @ref HAL_FLASH_Lock() to disable the flash memory access
  127. * (recommended to protect the FLASH memory against possible unwanted operation)
  128. * @param[in] pEraseInit pointer to an FLASH_EraseInitTypeDef structure that
  129. * contains the configuration information for the erasing.
  130. *
  131. * @param[out] PageError pointer to variable that
  132. * contains the configuration information on faulty page in case of error
  133. * (0xFFFFFFFF means that all the pages have been correctly erased)
  134. *
  135. * @retval HAL_StatusTypeDef HAL Status
  136. */
  137. HAL_StatusTypeDef HAL_FLASHEx_Erase(FLASH_EraseInitTypeDef *pEraseInit, uint32_t *PageError)
  138. {
  139. HAL_StatusTypeDef status = HAL_ERROR;
  140. uint32_t address = 0U;
  141. /* Process Locked */
  142. __HAL_LOCK(&pFlash);
  143. /* Check the parameters */
  144. assert_param(IS_FLASH_TYPEERASE(pEraseInit->TypeErase));
  145. if (pEraseInit->TypeErase == FLASH_TYPEERASE_MASSERASE)
  146. {
  147. #if defined(FLASH_BANK2_END)
  148. if (pEraseInit->Banks == FLASH_BANK_BOTH)
  149. {
  150. /* Mass Erase requested for Bank1 and Bank2 */
  151. /* Wait for last operation to be completed */
  152. if ((FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE) == HAL_OK) && \
  153. (FLASH_WaitForLastOperationBank2((uint32_t)FLASH_TIMEOUT_VALUE) == HAL_OK))
  154. {
  155. /*Mass erase to be done*/
  156. FLASH_MassErase(FLASH_BANK_BOTH);
  157. /* Wait for last operation to be completed */
  158. if ((FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE) == HAL_OK) && \
  159. (FLASH_WaitForLastOperationBank2((uint32_t)FLASH_TIMEOUT_VALUE) == HAL_OK))
  160. {
  161. status = HAL_OK;
  162. }
  163. /* If the erase operation is completed, disable the MER Bit */
  164. CLEAR_BIT(FLASH->CR, FLASH_CR_MER);
  165. CLEAR_BIT(FLASH->CR2, FLASH_CR2_MER);
  166. }
  167. }
  168. else if (pEraseInit->Banks == FLASH_BANK_2)
  169. {
  170. /* Mass Erase requested for Bank2 */
  171. /* Wait for last operation to be completed */
  172. if (FLASH_WaitForLastOperationBank2((uint32_t)FLASH_TIMEOUT_VALUE) == HAL_OK)
  173. {
  174. /*Mass erase to be done*/
  175. FLASH_MassErase(FLASH_BANK_2);
  176. /* Wait for last operation to be completed */
  177. status = FLASH_WaitForLastOperationBank2((uint32_t)FLASH_TIMEOUT_VALUE);
  178. /* If the erase operation is completed, disable the MER Bit */
  179. CLEAR_BIT(FLASH->CR2, FLASH_CR2_MER);
  180. }
  181. }
  182. else
  183. #endif /* FLASH_BANK2_END */
  184. {
  185. /* Mass Erase requested for Bank1 */
  186. /* Wait for last operation to be completed */
  187. if (FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE) == HAL_OK)
  188. {
  189. /*Mass erase to be done*/
  190. FLASH_MassErase(FLASH_BANK_1);
  191. /* Wait for last operation to be completed */
  192. status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE);
  193. /* If the erase operation is completed, disable the MER Bit */
  194. CLEAR_BIT(FLASH->CR, FLASH_CR_MER);
  195. }
  196. }
  197. }
  198. else
  199. {
  200. /* Page Erase is requested */
  201. /* Check the parameters */
  202. assert_param(IS_FLASH_PROGRAM_ADDRESS(pEraseInit->PageAddress));
  203. assert_param(IS_FLASH_NB_PAGES(pEraseInit->PageAddress, pEraseInit->NbPages));
  204. #if defined(FLASH_BANK2_END)
  205. /* Page Erase requested on address located on bank2 */
  206. if(pEraseInit->PageAddress > FLASH_BANK1_END)
  207. {
  208. /* Wait for last operation to be completed */
  209. if (FLASH_WaitForLastOperationBank2((uint32_t)FLASH_TIMEOUT_VALUE) == HAL_OK)
  210. {
  211. /*Initialization of PageError variable*/
  212. *PageError = 0xFFFFFFFFU;
  213. /* Erase by page by page to be done*/
  214. for(address = pEraseInit->PageAddress;
  215. address < (pEraseInit->PageAddress + (pEraseInit->NbPages)*FLASH_PAGE_SIZE);
  216. address += FLASH_PAGE_SIZE)
  217. {
  218. FLASH_PageErase(address);
  219. /* Wait for last operation to be completed */
  220. status = FLASH_WaitForLastOperationBank2((uint32_t)FLASH_TIMEOUT_VALUE);
  221. /* If the erase operation is completed, disable the PER Bit */
  222. CLEAR_BIT(FLASH->CR2, FLASH_CR2_PER);
  223. if (status != HAL_OK)
  224. {
  225. /* In case of error, stop erase procedure and return the faulty address */
  226. *PageError = address;
  227. break;
  228. }
  229. }
  230. }
  231. }
  232. else
  233. #endif /* FLASH_BANK2_END */
  234. {
  235. /* Page Erase requested on address located on bank1 */
  236. /* Wait for last operation to be completed */
  237. if (FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE) == HAL_OK)
  238. {
  239. /*Initialization of PageError variable*/
  240. *PageError = 0xFFFFFFFFU;
  241. /* Erase page by page to be done*/
  242. for(address = pEraseInit->PageAddress;
  243. address < ((pEraseInit->NbPages * FLASH_PAGE_SIZE) + pEraseInit->PageAddress);
  244. address += FLASH_PAGE_SIZE)
  245. {
  246. FLASH_PageErase(address);
  247. /* Wait for last operation to be completed */
  248. status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE);
  249. /* If the erase operation is completed, disable the PER Bit */
  250. CLEAR_BIT(FLASH->CR, FLASH_CR_PER);
  251. if (status != HAL_OK)
  252. {
  253. /* In case of error, stop erase procedure and return the faulty address */
  254. *PageError = address;
  255. break;
  256. }
  257. }
  258. }
  259. }
  260. }
  261. /* Process Unlocked */
  262. __HAL_UNLOCK(&pFlash);
  263. return status;
  264. }
  265. /**
  266. * @brief Perform a mass erase or erase the specified FLASH memory pages with interrupt enabled
  267. * @note To correctly run this function, the @ref HAL_FLASH_Unlock() function
  268. * must be called before.
  269. * Call the @ref HAL_FLASH_Lock() to disable the flash memory access
  270. * (recommended to protect the FLASH memory against possible unwanted operation)
  271. * @param pEraseInit pointer to an FLASH_EraseInitTypeDef structure that
  272. * contains the configuration information for the erasing.
  273. *
  274. * @retval HAL_StatusTypeDef HAL Status
  275. */
  276. HAL_StatusTypeDef HAL_FLASHEx_Erase_IT(FLASH_EraseInitTypeDef *pEraseInit)
  277. {
  278. HAL_StatusTypeDef status = HAL_OK;
  279. /* If procedure already ongoing, reject the next one */
  280. if (pFlash.ProcedureOnGoing != FLASH_PROC_NONE)
  281. {
  282. return HAL_ERROR;
  283. }
  284. /* Check the parameters */
  285. assert_param(IS_FLASH_TYPEERASE(pEraseInit->TypeErase));
  286. /* Enable End of FLASH Operation and Error source interrupts */
  287. __HAL_FLASH_ENABLE_IT(FLASH_IT_EOP | FLASH_IT_ERR);
  288. #if defined(FLASH_BANK2_END)
  289. /* Enable End of FLASH Operation and Error source interrupts */
  290. __HAL_FLASH_ENABLE_IT(FLASH_IT_EOP_BANK2 | FLASH_IT_ERR_BANK2);
  291. #endif
  292. if (pEraseInit->TypeErase == FLASH_TYPEERASE_MASSERASE)
  293. {
  294. /*Mass erase to be done*/
  295. pFlash.ProcedureOnGoing = FLASH_PROC_MASSERASE;
  296. FLASH_MassErase(pEraseInit->Banks);
  297. }
  298. else
  299. {
  300. /* Erase by page to be done*/
  301. /* Check the parameters */
  302. assert_param(IS_FLASH_PROGRAM_ADDRESS(pEraseInit->PageAddress));
  303. assert_param(IS_FLASH_NB_PAGES(pEraseInit->PageAddress, pEraseInit->NbPages));
  304. pFlash.ProcedureOnGoing = FLASH_PROC_PAGEERASE;
  305. pFlash.DataRemaining = pEraseInit->NbPages;
  306. pFlash.Address = pEraseInit->PageAddress;
  307. /*Erase 1st page and wait for IT*/
  308. FLASH_PageErase(pEraseInit->PageAddress);
  309. }
  310. return status;
  311. }
  312. /**
  313. * @}
  314. */
  315. /** @defgroup FLASHEx_Exported_Functions_Group2 Option Bytes Programming functions
  316. * @brief Option Bytes Programming functions
  317. *
  318. @verbatim
  319. ==============================================================================
  320. ##### Option Bytes Programming functions #####
  321. ==============================================================================
  322. [..]
  323. This subsection provides a set of functions allowing to control the FLASH
  324. option bytes operations.
  325. @endverbatim
  326. * @{
  327. */
  328. /**
  329. * @brief Erases the FLASH option bytes.
  330. * @note This functions erases all option bytes except the Read protection (RDP).
  331. * The function @ref HAL_FLASH_Unlock() should be called before to unlock the FLASH interface
  332. * The function @ref HAL_FLASH_OB_Unlock() should be called before to unlock the options bytes
  333. * The function @ref HAL_FLASH_OB_Launch() should be called after to force the reload of the options bytes
  334. * (system reset will occur)
  335. * @retval HAL status
  336. */
  337. HAL_StatusTypeDef HAL_FLASHEx_OBErase(void)
  338. {
  339. uint8_t rdptmp = OB_RDP_LEVEL_0;
  340. HAL_StatusTypeDef status = HAL_ERROR;
  341. /* Get the actual read protection Option Byte value */
  342. rdptmp = FLASH_OB_GetRDP();
  343. /* Wait for last operation to be completed */
  344. status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE);
  345. if(status == HAL_OK)
  346. {
  347. /* Clean the error context */
  348. pFlash.ErrorCode = HAL_FLASH_ERROR_NONE;
  349. /* If the previous operation is completed, proceed to erase the option bytes */
  350. SET_BIT(FLASH->CR, FLASH_CR_OPTER);
  351. SET_BIT(FLASH->CR, FLASH_CR_STRT);
  352. /* Wait for last operation to be completed */
  353. status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE);
  354. /* If the erase operation is completed, disable the OPTER Bit */
  355. CLEAR_BIT(FLASH->CR, FLASH_CR_OPTER);
  356. if(status == HAL_OK)
  357. {
  358. /* Restore the last read protection Option Byte value */
  359. status = FLASH_OB_RDP_LevelConfig(rdptmp);
  360. }
  361. }
  362. /* Return the erase status */
  363. return status;
  364. }
  365. /**
  366. * @brief Program option bytes
  367. * @note The function @ref HAL_FLASH_Unlock() should be called before to unlock the FLASH interface
  368. * The function @ref HAL_FLASH_OB_Unlock() should be called before to unlock the options bytes
  369. * The function @ref HAL_FLASH_OB_Launch() should be called after to force the reload of the options bytes
  370. * (system reset will occur)
  371. *
  372. * @param pOBInit pointer to an FLASH_OBInitStruct structure that
  373. * contains the configuration information for the programming.
  374. *
  375. * @retval HAL_StatusTypeDef HAL Status
  376. */
  377. HAL_StatusTypeDef HAL_FLASHEx_OBProgram(FLASH_OBProgramInitTypeDef *pOBInit)
  378. {
  379. HAL_StatusTypeDef status = HAL_ERROR;
  380. /* Process Locked */
  381. __HAL_LOCK(&pFlash);
  382. /* Check the parameters */
  383. assert_param(IS_OPTIONBYTE(pOBInit->OptionType));
  384. /* Write protection configuration */
  385. if((pOBInit->OptionType & OPTIONBYTE_WRP) == OPTIONBYTE_WRP)
  386. {
  387. assert_param(IS_WRPSTATE(pOBInit->WRPState));
  388. if (pOBInit->WRPState == OB_WRPSTATE_ENABLE)
  389. {
  390. /* Enable of Write protection on the selected page */
  391. status = FLASH_OB_EnableWRP(pOBInit->WRPPage);
  392. }
  393. else
  394. {
  395. /* Disable of Write protection on the selected page */
  396. status = FLASH_OB_DisableWRP(pOBInit->WRPPage);
  397. }
  398. if (status != HAL_OK)
  399. {
  400. /* Process Unlocked */
  401. __HAL_UNLOCK(&pFlash);
  402. return status;
  403. }
  404. }
  405. /* Read protection configuration */
  406. if((pOBInit->OptionType & OPTIONBYTE_RDP) == OPTIONBYTE_RDP)
  407. {
  408. status = FLASH_OB_RDP_LevelConfig(pOBInit->RDPLevel);
  409. if (status != HAL_OK)
  410. {
  411. /* Process Unlocked */
  412. __HAL_UNLOCK(&pFlash);
  413. return status;
  414. }
  415. }
  416. /* USER configuration */
  417. if((pOBInit->OptionType & OPTIONBYTE_USER) == OPTIONBYTE_USER)
  418. {
  419. status = FLASH_OB_UserConfig(pOBInit->USERConfig);
  420. if (status != HAL_OK)
  421. {
  422. /* Process Unlocked */
  423. __HAL_UNLOCK(&pFlash);
  424. return status;
  425. }
  426. }
  427. /* DATA configuration*/
  428. if((pOBInit->OptionType & OPTIONBYTE_DATA) == OPTIONBYTE_DATA)
  429. {
  430. status = FLASH_OB_ProgramData(pOBInit->DATAAddress, pOBInit->DATAData);
  431. if (status != HAL_OK)
  432. {
  433. /* Process Unlocked */
  434. __HAL_UNLOCK(&pFlash);
  435. return status;
  436. }
  437. }
  438. /* Process Unlocked */
  439. __HAL_UNLOCK(&pFlash);
  440. return status;
  441. }
  442. /**
  443. * @brief Get the Option byte configuration
  444. * @param pOBInit pointer to an FLASH_OBInitStruct structure that
  445. * contains the configuration information for the programming.
  446. *
  447. * @retval None
  448. */
  449. void HAL_FLASHEx_OBGetConfig(FLASH_OBProgramInitTypeDef *pOBInit)
  450. {
  451. pOBInit->OptionType = OPTIONBYTE_WRP | OPTIONBYTE_RDP | OPTIONBYTE_USER;
  452. /*Get WRP*/
  453. pOBInit->WRPPage = FLASH_OB_GetWRP();
  454. /*Get RDP Level*/
  455. pOBInit->RDPLevel = FLASH_OB_GetRDP();
  456. /*Get USER*/
  457. pOBInit->USERConfig = FLASH_OB_GetUser();
  458. }
  459. /**
  460. * @brief Get the Option byte user data
  461. * @param DATAAdress Address of the option byte DATA
  462. * This parameter can be one of the following values:
  463. * @arg @ref OB_DATA_ADDRESS_DATA0
  464. * @arg @ref OB_DATA_ADDRESS_DATA1
  465. * @retval Value programmed in USER data
  466. */
  467. uint32_t HAL_FLASHEx_OBGetUserData(uint32_t DATAAdress)
  468. {
  469. uint32_t value = 0;
  470. if (DATAAdress == OB_DATA_ADDRESS_DATA0)
  471. {
  472. /* Get value programmed in OB USER Data0 */
  473. value = READ_BIT(FLASH->OBR, FLASH_OBR_DATA0) >> FLASH_POSITION_OB_USERDATA0_BIT;
  474. }
  475. else
  476. {
  477. /* Get value programmed in OB USER Data1 */
  478. value = READ_BIT(FLASH->OBR, FLASH_OBR_DATA1) >> FLASH_POSITION_OB_USERDATA1_BIT;
  479. }
  480. return value;
  481. }
  482. /**
  483. * @}
  484. */
  485. /**
  486. * @}
  487. */
  488. /** @addtogroup FLASHEx_Private_Functions
  489. * @{
  490. */
  491. /**
  492. * @brief Full erase of FLASH memory Bank
  493. * @param Banks Banks to be erased
  494. * This parameter can be one of the following values:
  495. * @arg @ref FLASH_BANK_1 Bank1 to be erased
  496. @if STM32F101xG
  497. * @arg @ref FLASH_BANK_2 Bank2 to be erased
  498. * @arg @ref FLASH_BANK_BOTH Bank1 and Bank2 to be erased
  499. @endif
  500. @if STM32F103xG
  501. * @arg @ref FLASH_BANK_2 Bank2 to be erased
  502. * @arg @ref FLASH_BANK_BOTH Bank1 and Bank2 to be erased
  503. @endif
  504. *
  505. * @retval None
  506. */
  507. static void FLASH_MassErase(uint32_t Banks)
  508. {
  509. /* Check the parameters */
  510. assert_param(IS_FLASH_BANK(Banks));
  511. /* Clean the error context */
  512. pFlash.ErrorCode = HAL_FLASH_ERROR_NONE;
  513. #if defined(FLASH_BANK2_END)
  514. if(Banks == FLASH_BANK_BOTH)
  515. {
  516. /* bank1 & bank2 will be erased*/
  517. SET_BIT(FLASH->CR, FLASH_CR_MER);
  518. SET_BIT(FLASH->CR2, FLASH_CR2_MER);
  519. SET_BIT(FLASH->CR, FLASH_CR_STRT);
  520. SET_BIT(FLASH->CR2, FLASH_CR2_STRT);
  521. }
  522. else if(Banks == FLASH_BANK_2)
  523. {
  524. /*Only bank2 will be erased*/
  525. SET_BIT(FLASH->CR2, FLASH_CR2_MER);
  526. SET_BIT(FLASH->CR2, FLASH_CR2_STRT);
  527. }
  528. else
  529. {
  530. #endif /* FLASH_BANK2_END */
  531. #if !defined(FLASH_BANK2_END)
  532. /* Prevent unused argument(s) compilation warning */
  533. UNUSED(Banks);
  534. #endif /* FLASH_BANK2_END */
  535. /* Only bank1 will be erased*/
  536. SET_BIT(FLASH->CR, FLASH_CR_MER);
  537. SET_BIT(FLASH->CR, FLASH_CR_STRT);
  538. #if defined(FLASH_BANK2_END)
  539. }
  540. #endif /* FLASH_BANK2_END */
  541. }
  542. /**
  543. * @brief Enable the write protection of the desired pages
  544. * @note An option byte erase is done automatically in this function.
  545. * @note When the memory read protection level is selected (RDP level = 1),
  546. * it is not possible to program or erase the flash page i if
  547. * debug features are connected or boot code is executed in RAM, even if nWRPi = 1
  548. *
  549. * @param WriteProtectPage specifies the page(s) to be write protected.
  550. * The value of this parameter depend on device used within the same series
  551. * @retval HAL status
  552. */
  553. static HAL_StatusTypeDef FLASH_OB_EnableWRP(uint32_t WriteProtectPage)
  554. {
  555. HAL_StatusTypeDef status = HAL_OK;
  556. uint16_t WRP0_Data = 0xFFFF;
  557. #if defined(FLASH_WRP1_WRP1)
  558. uint16_t WRP1_Data = 0xFFFF;
  559. #endif /* FLASH_WRP1_WRP1 */
  560. #if defined(FLASH_WRP2_WRP2)
  561. uint16_t WRP2_Data = 0xFFFF;
  562. #endif /* FLASH_WRP2_WRP2 */
  563. #if defined(FLASH_WRP3_WRP3)
  564. uint16_t WRP3_Data = 0xFFFF;
  565. #endif /* FLASH_WRP3_WRP3 */
  566. /* Check the parameters */
  567. assert_param(IS_OB_WRP(WriteProtectPage));
  568. /* Get current write protected pages and the new pages to be protected ******/
  569. WriteProtectPage = (uint32_t)(~((~FLASH_OB_GetWRP()) | WriteProtectPage));
  570. #if defined(OB_WRP_PAGES0TO15MASK)
  571. WRP0_Data = (uint16_t)(WriteProtectPage & OB_WRP_PAGES0TO15MASK);
  572. #elif defined(OB_WRP_PAGES0TO31MASK)
  573. WRP0_Data = (uint16_t)(WriteProtectPage & OB_WRP_PAGES0TO31MASK);
  574. #endif /* OB_WRP_PAGES0TO31MASK */
  575. #if defined(OB_WRP_PAGES16TO31MASK)
  576. WRP1_Data = (uint16_t)((WriteProtectPage & OB_WRP_PAGES16TO31MASK) >> 8U);
  577. #elif defined(OB_WRP_PAGES32TO63MASK)
  578. WRP1_Data = (uint16_t)((WriteProtectPage & OB_WRP_PAGES32TO63MASK) >> 8U);
  579. #endif /* OB_WRP_PAGES32TO63MASK */
  580. #if defined(OB_WRP_PAGES64TO95MASK)
  581. WRP2_Data = (uint16_t)((WriteProtectPage & OB_WRP_PAGES64TO95MASK) >> 16U);
  582. #endif /* OB_WRP_PAGES64TO95MASK */
  583. #if defined(OB_WRP_PAGES32TO47MASK)
  584. WRP2_Data = (uint16_t)((WriteProtectPage & OB_WRP_PAGES32TO47MASK) >> 16U);
  585. #endif /* OB_WRP_PAGES32TO47MASK */
  586. #if defined(OB_WRP_PAGES96TO127MASK)
  587. WRP3_Data = (uint16_t)((WriteProtectPage & OB_WRP_PAGES96TO127MASK) >> 24U);
  588. #elif defined(OB_WRP_PAGES48TO255MASK)
  589. WRP3_Data = (uint16_t)((WriteProtectPage & OB_WRP_PAGES48TO255MASK) >> 24U);
  590. #elif defined(OB_WRP_PAGES48TO511MASK)
  591. WRP3_Data = (uint16_t)((WriteProtectPage & OB_WRP_PAGES48TO511MASK) >> 24U);
  592. #elif defined(OB_WRP_PAGES48TO127MASK)
  593. WRP3_Data = (uint16_t)((WriteProtectPage & OB_WRP_PAGES48TO127MASK) >> 24U);
  594. #endif /* OB_WRP_PAGES96TO127MASK */
  595. /* Wait for last operation to be completed */
  596. status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE);
  597. if(status == HAL_OK)
  598. {
  599. /* Clean the error context */
  600. pFlash.ErrorCode = HAL_FLASH_ERROR_NONE;
  601. /* To be able to write again option byte, need to perform a option byte erase */
  602. status = HAL_FLASHEx_OBErase();
  603. if (status == HAL_OK)
  604. {
  605. /* Enable write protection */
  606. SET_BIT(FLASH->CR, FLASH_CR_OPTPG);
  607. #if defined(FLASH_WRP0_WRP0)
  608. if(WRP0_Data != 0xFFU)
  609. {
  610. OB->WRP0 &= WRP0_Data;
  611. /* Wait for last operation to be completed */
  612. status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE);
  613. }
  614. #endif /* FLASH_WRP0_WRP0 */
  615. #if defined(FLASH_WRP1_WRP1)
  616. if((status == HAL_OK) && (WRP1_Data != 0xFFU))
  617. {
  618. OB->WRP1 &= WRP1_Data;
  619. /* Wait for last operation to be completed */
  620. status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE);
  621. }
  622. #endif /* FLASH_WRP1_WRP1 */
  623. #if defined(FLASH_WRP2_WRP2)
  624. if((status == HAL_OK) && (WRP2_Data != 0xFFU))
  625. {
  626. OB->WRP2 &= WRP2_Data;
  627. /* Wait for last operation to be completed */
  628. status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE);
  629. }
  630. #endif /* FLASH_WRP2_WRP2 */
  631. #if defined(FLASH_WRP3_WRP3)
  632. if((status == HAL_OK) && (WRP3_Data != 0xFFU))
  633. {
  634. OB->WRP3 &= WRP3_Data;
  635. /* Wait for last operation to be completed */
  636. status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE);
  637. }
  638. #endif /* FLASH_WRP3_WRP3 */
  639. /* if the program operation is completed, disable the OPTPG Bit */
  640. CLEAR_BIT(FLASH->CR, FLASH_CR_OPTPG);
  641. }
  642. }
  643. return status;
  644. }
  645. /**
  646. * @brief Disable the write protection of the desired pages
  647. * @note An option byte erase is done automatically in this function.
  648. * @note When the memory read protection level is selected (RDP level = 1),
  649. * it is not possible to program or erase the flash page i if
  650. * debug features are connected or boot code is executed in RAM, even if nWRPi = 1
  651. *
  652. * @param WriteProtectPage specifies the page(s) to be write unprotected.
  653. * The value of this parameter depend on device used within the same series
  654. * @retval HAL status
  655. */
  656. static HAL_StatusTypeDef FLASH_OB_DisableWRP(uint32_t WriteProtectPage)
  657. {
  658. HAL_StatusTypeDef status = HAL_OK;
  659. uint16_t WRP0_Data = 0xFFFF;
  660. #if defined(FLASH_WRP1_WRP1)
  661. uint16_t WRP1_Data = 0xFFFF;
  662. #endif /* FLASH_WRP1_WRP1 */
  663. #if defined(FLASH_WRP2_WRP2)
  664. uint16_t WRP2_Data = 0xFFFF;
  665. #endif /* FLASH_WRP2_WRP2 */
  666. #if defined(FLASH_WRP3_WRP3)
  667. uint16_t WRP3_Data = 0xFFFF;
  668. #endif /* FLASH_WRP3_WRP3 */
  669. /* Check the parameters */
  670. assert_param(IS_OB_WRP(WriteProtectPage));
  671. /* Get current write protected pages and the new pages to be unprotected ******/
  672. WriteProtectPage = (FLASH_OB_GetWRP() | WriteProtectPage);
  673. #if defined(OB_WRP_PAGES0TO15MASK)
  674. WRP0_Data = (uint16_t)(WriteProtectPage & OB_WRP_PAGES0TO15MASK);
  675. #elif defined(OB_WRP_PAGES0TO31MASK)
  676. WRP0_Data = (uint16_t)(WriteProtectPage & OB_WRP_PAGES0TO31MASK);
  677. #endif /* OB_WRP_PAGES0TO31MASK */
  678. #if defined(OB_WRP_PAGES16TO31MASK)
  679. WRP1_Data = (uint16_t)((WriteProtectPage & OB_WRP_PAGES16TO31MASK) >> 8U);
  680. #elif defined(OB_WRP_PAGES32TO63MASK)
  681. WRP1_Data = (uint16_t)((WriteProtectPage & OB_WRP_PAGES32TO63MASK) >> 8U);
  682. #endif /* OB_WRP_PAGES32TO63MASK */
  683. #if defined(OB_WRP_PAGES64TO95MASK)
  684. WRP2_Data = (uint16_t)((WriteProtectPage & OB_WRP_PAGES64TO95MASK) >> 16U);
  685. #endif /* OB_WRP_PAGES64TO95MASK */
  686. #if defined(OB_WRP_PAGES32TO47MASK)
  687. WRP2_Data = (uint16_t)((WriteProtectPage & OB_WRP_PAGES32TO47MASK) >> 16U);
  688. #endif /* OB_WRP_PAGES32TO47MASK */
  689. #if defined(OB_WRP_PAGES96TO127MASK)
  690. WRP3_Data = (uint16_t)((WriteProtectPage & OB_WRP_PAGES96TO127MASK) >> 24U);
  691. #elif defined(OB_WRP_PAGES48TO255MASK)
  692. WRP3_Data = (uint16_t)((WriteProtectPage & OB_WRP_PAGES48TO255MASK) >> 24U);
  693. #elif defined(OB_WRP_PAGES48TO511MASK)
  694. WRP3_Data = (uint16_t)((WriteProtectPage & OB_WRP_PAGES48TO511MASK) >> 24U);
  695. #elif defined(OB_WRP_PAGES48TO127MASK)
  696. WRP3_Data = (uint16_t)((WriteProtectPage & OB_WRP_PAGES48TO127MASK) >> 24U);
  697. #endif /* OB_WRP_PAGES96TO127MASK */
  698. /* Wait for last operation to be completed */
  699. status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE);
  700. if(status == HAL_OK)
  701. {
  702. /* Clean the error context */
  703. pFlash.ErrorCode = HAL_FLASH_ERROR_NONE;
  704. /* To be able to write again option byte, need to perform a option byte erase */
  705. status = HAL_FLASHEx_OBErase();
  706. if (status == HAL_OK)
  707. {
  708. SET_BIT(FLASH->CR, FLASH_CR_OPTPG);
  709. #if defined(FLASH_WRP0_WRP0)
  710. if(WRP0_Data != 0xFFU)
  711. {
  712. OB->WRP0 |= WRP0_Data;
  713. /* Wait for last operation to be completed */
  714. status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE);
  715. }
  716. #endif /* FLASH_WRP0_WRP0 */
  717. #if defined(FLASH_WRP1_WRP1)
  718. if((status == HAL_OK) && (WRP1_Data != 0xFFU))
  719. {
  720. OB->WRP1 |= WRP1_Data;
  721. /* Wait for last operation to be completed */
  722. status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE);
  723. }
  724. #endif /* FLASH_WRP1_WRP1 */
  725. #if defined(FLASH_WRP2_WRP2)
  726. if((status == HAL_OK) && (WRP2_Data != 0xFFU))
  727. {
  728. OB->WRP2 |= WRP2_Data;
  729. /* Wait for last operation to be completed */
  730. status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE);
  731. }
  732. #endif /* FLASH_WRP2_WRP2 */
  733. #if defined(FLASH_WRP3_WRP3)
  734. if((status == HAL_OK) && (WRP3_Data != 0xFFU))
  735. {
  736. OB->WRP3 |= WRP3_Data;
  737. /* Wait for last operation to be completed */
  738. status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE);
  739. }
  740. #endif /* FLASH_WRP3_WRP3 */
  741. /* if the program operation is completed, disable the OPTPG Bit */
  742. CLEAR_BIT(FLASH->CR, FLASH_CR_OPTPG);
  743. }
  744. }
  745. return status;
  746. }
  747. /**
  748. * @brief Set the read protection level.
  749. * @param ReadProtectLevel specifies the read protection level.
  750. * This parameter can be one of the following values:
  751. * @arg @ref OB_RDP_LEVEL_0 No protection
  752. * @arg @ref OB_RDP_LEVEL_1 Read protection of the memory
  753. * @retval HAL status
  754. */
  755. static HAL_StatusTypeDef FLASH_OB_RDP_LevelConfig(uint8_t ReadProtectLevel)
  756. {
  757. HAL_StatusTypeDef status = HAL_OK;
  758. /* Check the parameters */
  759. assert_param(IS_OB_RDP_LEVEL(ReadProtectLevel));
  760. /* Wait for last operation to be completed */
  761. status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE);
  762. if(status == HAL_OK)
  763. {
  764. /* Clean the error context */
  765. pFlash.ErrorCode = HAL_FLASH_ERROR_NONE;
  766. /* If the previous operation is completed, proceed to erase the option bytes */
  767. SET_BIT(FLASH->CR, FLASH_CR_OPTER);
  768. SET_BIT(FLASH->CR, FLASH_CR_STRT);
  769. /* Wait for last operation to be completed */
  770. status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE);
  771. /* If the erase operation is completed, disable the OPTER Bit */
  772. CLEAR_BIT(FLASH->CR, FLASH_CR_OPTER);
  773. if(status == HAL_OK)
  774. {
  775. /* Enable the Option Bytes Programming operation */
  776. SET_BIT(FLASH->CR, FLASH_CR_OPTPG);
  777. WRITE_REG(OB->RDP, ReadProtectLevel);
  778. /* Wait for last operation to be completed */
  779. status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE);
  780. /* if the program operation is completed, disable the OPTPG Bit */
  781. CLEAR_BIT(FLASH->CR, FLASH_CR_OPTPG);
  782. }
  783. }
  784. return status;
  785. }
  786. /**
  787. * @brief Program the FLASH User Option Byte.
  788. * @note Programming of the OB should be performed only after an erase (otherwise PGERR occurs)
  789. * @param UserConfig The FLASH User Option Bytes values FLASH_OBR_IWDG_SW(Bit2),
  790. * FLASH_OBR_nRST_STOP(Bit3),FLASH_OBR_nRST_STDBY(Bit4).
  791. * And BFBF2(Bit5) for STM32F101xG and STM32F103xG .
  792. * @retval HAL status
  793. */
  794. static HAL_StatusTypeDef FLASH_OB_UserConfig(uint8_t UserConfig)
  795. {
  796. HAL_StatusTypeDef status = HAL_OK;
  797. /* Check the parameters */
  798. assert_param(IS_OB_IWDG_SOURCE((UserConfig&OB_IWDG_SW)));
  799. assert_param(IS_OB_STOP_SOURCE((UserConfig&OB_STOP_NO_RST)));
  800. assert_param(IS_OB_STDBY_SOURCE((UserConfig&OB_STDBY_NO_RST)));
  801. #if defined(FLASH_BANK2_END)
  802. assert_param(IS_OB_BOOT1((UserConfig&OB_BOOT1_SET)));
  803. #endif /* FLASH_BANK2_END */
  804. /* Wait for last operation to be completed */
  805. status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE);
  806. if(status == HAL_OK)
  807. {
  808. /* Clean the error context */
  809. pFlash.ErrorCode = HAL_FLASH_ERROR_NONE;
  810. /* Enable the Option Bytes Programming operation */
  811. SET_BIT(FLASH->CR, FLASH_CR_OPTPG);
  812. #if defined(FLASH_BANK2_END)
  813. OB->USER = (UserConfig | 0xF0U);
  814. #else
  815. OB->USER = (UserConfig | 0x88U);
  816. #endif /* FLASH_BANK2_END */
  817. /* Wait for last operation to be completed */
  818. status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE);
  819. /* if the program operation is completed, disable the OPTPG Bit */
  820. CLEAR_BIT(FLASH->CR, FLASH_CR_OPTPG);
  821. }
  822. return status;
  823. }
  824. /**
  825. * @brief Programs a half word at a specified Option Byte Data address.
  826. * @note The function @ref HAL_FLASH_Unlock() should be called before to unlock the FLASH interface
  827. * The function @ref HAL_FLASH_OB_Unlock() should be called before to unlock the options bytes
  828. * The function @ref HAL_FLASH_OB_Launch() should be called after to force the reload of the options bytes
  829. * (system reset will occur)
  830. * Programming of the OB should be performed only after an erase (otherwise PGERR occurs)
  831. * @param Address specifies the address to be programmed.
  832. * This parameter can be 0x1FFFF804 or 0x1FFFF806.
  833. * @param Data specifies the data to be programmed.
  834. * @retval HAL status
  835. */
  836. static HAL_StatusTypeDef FLASH_OB_ProgramData(uint32_t Address, uint8_t Data)
  837. {
  838. HAL_StatusTypeDef status = HAL_ERROR;
  839. /* Check the parameters */
  840. assert_param(IS_OB_DATA_ADDRESS(Address));
  841. /* Wait for last operation to be completed */
  842. status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE);
  843. if(status == HAL_OK)
  844. {
  845. /* Clean the error context */
  846. pFlash.ErrorCode = HAL_FLASH_ERROR_NONE;
  847. /* Enables the Option Bytes Programming operation */
  848. SET_BIT(FLASH->CR, FLASH_CR_OPTPG);
  849. *(__IO uint16_t*)Address = Data;
  850. /* Wait for last operation to be completed */
  851. status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE);
  852. /* If the program operation is completed, disable the OPTPG Bit */
  853. CLEAR_BIT(FLASH->CR, FLASH_CR_OPTPG);
  854. }
  855. /* Return the Option Byte Data Program Status */
  856. return status;
  857. }
  858. /**
  859. * @brief Return the FLASH Write Protection Option Bytes value.
  860. * @retval The FLASH Write Protection Option Bytes value
  861. */
  862. static uint32_t FLASH_OB_GetWRP(void)
  863. {
  864. /* Return the FLASH write protection Register value */
  865. return (uint32_t)(READ_REG(FLASH->WRPR));
  866. }
  867. /**
  868. * @brief Returns the FLASH Read Protection level.
  869. * @retval FLASH RDP level
  870. * This parameter can be one of the following values:
  871. * @arg @ref OB_RDP_LEVEL_0 No protection
  872. * @arg @ref OB_RDP_LEVEL_1 Read protection of the memory
  873. */
  874. static uint32_t FLASH_OB_GetRDP(void)
  875. {
  876. uint32_t readstatus = OB_RDP_LEVEL_0;
  877. uint32_t tmp_reg = 0U;
  878. /* Read RDP level bits */
  879. tmp_reg = READ_BIT(FLASH->OBR, FLASH_OBR_RDPRT);
  880. if (tmp_reg == FLASH_OBR_RDPRT)
  881. {
  882. readstatus = OB_RDP_LEVEL_1;
  883. }
  884. else
  885. {
  886. readstatus = OB_RDP_LEVEL_0;
  887. }
  888. return readstatus;
  889. }
  890. /**
  891. * @brief Return the FLASH User Option Byte value.
  892. * @retval The FLASH User Option Bytes values: FLASH_OBR_IWDG_SW(Bit2),
  893. * FLASH_OBR_nRST_STOP(Bit3),FLASH_OBR_nRST_STDBY(Bit4).
  894. * And FLASH_OBR_BFB2(Bit5) for STM32F101xG and STM32F103xG .
  895. */
  896. static uint8_t FLASH_OB_GetUser(void)
  897. {
  898. /* Return the User Option Byte */
  899. return (uint8_t)((READ_REG(FLASH->OBR) & FLASH_OBR_USER) >> FLASH_POSITION_IWDGSW_BIT);
  900. }
  901. /**
  902. * @}
  903. */
  904. /**
  905. * @}
  906. */
  907. /** @addtogroup FLASH
  908. * @{
  909. */
  910. /** @addtogroup FLASH_Private_Functions
  911. * @{
  912. */
  913. /**
  914. * @brief Erase the specified FLASH memory page
  915. * @param PageAddress FLASH page to erase
  916. * The value of this parameter depend on device used within the same series
  917. *
  918. * @retval None
  919. */
  920. void FLASH_PageErase(uint32_t PageAddress)
  921. {
  922. /* Clean the error context */
  923. pFlash.ErrorCode = HAL_FLASH_ERROR_NONE;
  924. #if defined(FLASH_BANK2_END)
  925. if(PageAddress > FLASH_BANK1_END)
  926. {
  927. /* Proceed to erase the page */
  928. SET_BIT(FLASH->CR2, FLASH_CR2_PER);
  929. WRITE_REG(FLASH->AR2, PageAddress);
  930. SET_BIT(FLASH->CR2, FLASH_CR2_STRT);
  931. }
  932. else
  933. {
  934. #endif /* FLASH_BANK2_END */
  935. /* Proceed to erase the page */
  936. SET_BIT(FLASH->CR, FLASH_CR_PER);
  937. WRITE_REG(FLASH->AR, PageAddress);
  938. SET_BIT(FLASH->CR, FLASH_CR_STRT);
  939. #if defined(FLASH_BANK2_END)
  940. }
  941. #endif /* FLASH_BANK2_END */
  942. }
  943. /**
  944. * @}
  945. */
  946. /**
  947. * @}
  948. */
  949. #endif /* HAL_FLASH_MODULE_ENABLED */
  950. /**
  951. * @}
  952. */