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.
 
 
 

981 lines
34 KiB

  1. /**
  2. ******************************************************************************
  3. * @file stm32l4xx_hal_flash_ex.c
  4. * @author MCD Application Team
  5. * @version V1.3.0
  6. * @date 29-January-2016
  7. * @brief Extended FLASH HAL module driver.
  8. * This file provides firmware functions to manage the following
  9. * functionalities of the FLASH extended peripheral:
  10. * + Extended programming operations functions
  11. *
  12. @verbatim
  13. ==============================================================================
  14. ##### Flash Extended features #####
  15. ==============================================================================
  16. [..] Comparing to other previous devices, the FLASH interface for STM32L4xx
  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. (+) PCROP protection for all banks
  22. ##### How to use this driver #####
  23. ==============================================================================
  24. [..] This driver provides functions to configure and program the FLASH memory
  25. of all STM32L4xx 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 page, 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 function: Use HAL_FLASHEx_OBProgram() to :
  34. (++) Set/Reset the write protection
  35. (++) Set the Read protection Level
  36. (++) Program the user Option Bytes
  37. (++) Configure the PCROP protection
  38. (#) Get Option Bytes Configuration function: Use HAL_FLASHEx_OBGetConfig() to :
  39. (++) Get the value of a write protection area
  40. (++) Know if the read protection is activated
  41. (++) Get the value of the user Option Bytes
  42. (++) Get the value of a PCROP area
  43. @endverbatim
  44. ******************************************************************************
  45. * @attention
  46. *
  47. * <h2><center>&copy; COPYRIGHT(c) 2016 STMicroelectronics</center></h2>
  48. *
  49. * Redistribution and use in source and binary forms, with or without modification,
  50. * are permitted provided that the following conditions are met:
  51. * 1. Redistributions of source code must retain the above copyright notice,
  52. * this list of conditions and the following disclaimer.
  53. * 2. Redistributions in binary form must reproduce the above copyright notice,
  54. * this list of conditions and the following disclaimer in the documentation
  55. * and/or other materials provided with the distribution.
  56. * 3. Neither the name of STMicroelectronics nor the names of its contributors
  57. * may be used to endorse or promote products derived from this software
  58. * without specific prior written permission.
  59. *
  60. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
  61. * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  62. * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  63. * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
  64. * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  65. * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
  66. * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
  67. * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
  68. * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  69. * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  70. *
  71. ******************************************************************************
  72. */
  73. /* Includes ------------------------------------------------------------------*/
  74. #include "stm32l4xx_hal.h"
  75. /** @addtogroup STM32L4xx_HAL_Driver
  76. * @{
  77. */
  78. /** @defgroup FLASHEx FLASHEx
  79. * @brief FALSH Extended HAL module driver
  80. * @{
  81. */
  82. #ifdef HAL_FLASH_MODULE_ENABLED
  83. /* Private typedef -----------------------------------------------------------*/
  84. /* Private define ------------------------------------------------------------*/
  85. /* Private macro -------------------------------------------------------------*/
  86. /* Private variables ---------------------------------------------------------*/
  87. /** @defgroup FLASHEx_Private_Variables FLASHEx Private Variables
  88. * @{
  89. */
  90. extern FLASH_ProcessTypeDef pFlash;
  91. /**
  92. * @}
  93. */
  94. /* Private function prototypes -----------------------------------------------*/
  95. /** @defgroup FLASHEx_Private_Functions FLASHEx Private Functions
  96. * @{
  97. */
  98. extern HAL_StatusTypeDef FLASH_WaitForLastOperation(uint32_t Timeout);
  99. void FLASH_PageErase(uint32_t Page, uint32_t Banks);
  100. static void FLASH_MassErase(uint32_t Banks);
  101. void FLASH_FlushCaches(void);
  102. static HAL_StatusTypeDef FLASH_OB_WRPConfig(uint32_t WRPArea, uint32_t WRPStartOffset, uint32_t WRDPEndOffset);
  103. static HAL_StatusTypeDef FLASH_OB_RDPConfig(uint32_t RDPLevel);
  104. static HAL_StatusTypeDef FLASH_OB_UserConfig(uint32_t UserType, uint32_t UserConfig);
  105. static HAL_StatusTypeDef FLASH_OB_PCROPConfig(uint32_t PCROPConfig, uint32_t PCROPStartAddr, uint32_t PCROPEndAddr);
  106. static void FLASH_OB_GetWRP(uint32_t WRPArea, uint32_t * WRPStartOffset, uint32_t * WRDPEndOffset);
  107. static uint32_t FLASH_OB_GetRDP(void);
  108. static uint32_t FLASH_OB_GetUser(void);
  109. static void FLASH_OB_GetPCROP(uint32_t * PCROPConfig, uint32_t * PCROPStartAddr, uint32_t * PCROPEndAddr);
  110. /**
  111. * @}
  112. */
  113. /* Exported functions -------------------------------------------------------*/
  114. /** @defgroup FLASHEx_Exported_Functions FLASH Extended Exported Functions
  115. * @{
  116. */
  117. /** @defgroup FLASHEx_Exported_Functions_Group1 Extended IO operation functions
  118. * @brief Extended IO operation functions
  119. *
  120. @verbatim
  121. ===============================================================================
  122. ##### Extended programming operation functions #####
  123. ===============================================================================
  124. [..]
  125. This subsection provides a set of functions allowing to manage the Extended FLASH
  126. programming operations Operations.
  127. @endverbatim
  128. * @{
  129. */
  130. /**
  131. * @brief Perform a mass erase or erase the specified FLASH memory pages.
  132. * @param[in] pEraseInit: pointer to an FLASH_EraseInitTypeDef structure that
  133. * contains the configuration information for the erasing.
  134. *
  135. * @param[out] PageError : pointer to variable that contains the configuration
  136. * information on faulty page in case of error (0xFFFFFFFF means that all
  137. * the pages have been correctly erased)
  138. *
  139. * @retval HAL Status
  140. */
  141. HAL_StatusTypeDef HAL_FLASHEx_Erase(FLASH_EraseInitTypeDef *pEraseInit, uint32_t *PageError)
  142. {
  143. HAL_StatusTypeDef status = HAL_ERROR;
  144. uint32_t page_index = 0;
  145. /* Process Locked */
  146. __HAL_LOCK(&pFlash);
  147. /* Check the parameters */
  148. assert_param(IS_FLASH_TYPEERASE(pEraseInit->TypeErase));
  149. /* Wait for last operation to be completed */
  150. status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE);
  151. if (status == HAL_OK)
  152. {
  153. pFlash.ErrorCode = HAL_FLASH_ERROR_NONE;
  154. if (pEraseInit->TypeErase == FLASH_TYPEERASE_MASSERASE)
  155. {
  156. /* Mass erase to be done */
  157. FLASH_MassErase(pEraseInit->Banks);
  158. /* Wait for last operation to be completed */
  159. status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE);
  160. /* If the erase operation is completed, disable the MER1 and MER2 Bits */
  161. CLEAR_BIT(FLASH->CR, (FLASH_CR_MER1 | FLASH_CR_MER2));
  162. }
  163. else
  164. {
  165. /*Initialization of PageError variable*/
  166. *PageError = 0xFFFFFFFF;
  167. for(page_index = pEraseInit->Page; page_index < (pEraseInit->Page + pEraseInit->NbPages); page_index++)
  168. {
  169. FLASH_PageErase(page_index, pEraseInit->Banks);
  170. /* Wait for last operation to be completed */
  171. status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE);
  172. /* If the erase operation is completed, disable the PER Bit */
  173. CLEAR_BIT(FLASH->CR, (FLASH_CR_PER | FLASH_CR_PNB));
  174. if (status != HAL_OK)
  175. {
  176. /* In case of error, stop erase procedure and return the faulty address */
  177. *PageError = page_index;
  178. break;
  179. }
  180. }
  181. }
  182. /* Flush the caches to be sure of the data consistency */
  183. FLASH_FlushCaches();
  184. }
  185. /* Process Unlocked */
  186. __HAL_UNLOCK(&pFlash);
  187. return status;
  188. }
  189. /**
  190. * @brief Perform a mass erase or erase the specified FLASH memory pages with interrupt enabled.
  191. * @param pEraseInit: pointer to an FLASH_EraseInitTypeDef structure that
  192. * contains the configuration information for the erasing.
  193. *
  194. * @retval HAL Status
  195. */
  196. HAL_StatusTypeDef HAL_FLASHEx_Erase_IT(FLASH_EraseInitTypeDef *pEraseInit)
  197. {
  198. HAL_StatusTypeDef status = HAL_OK;
  199. /* Process Locked */
  200. __HAL_LOCK(&pFlash);
  201. /* Check the parameters */
  202. assert_param(IS_FLASH_TYPEERASE(pEraseInit->TypeErase));
  203. pFlash.ErrorCode = HAL_FLASH_ERROR_NONE;
  204. /* Enable End of Operation and Error interrupts */
  205. __HAL_FLASH_ENABLE_IT(FLASH_IT_EOP | FLASH_IT_OPERR);
  206. pFlash.Bank = pEraseInit->Banks;
  207. if (pEraseInit->TypeErase == FLASH_TYPEERASE_MASSERASE)
  208. {
  209. /* Mass erase to be done */
  210. pFlash.ProcedureOnGoing = FLASH_PROC_MASS_ERASE;
  211. FLASH_MassErase(pEraseInit->Banks);
  212. }
  213. else
  214. {
  215. /* Erase by page to be done */
  216. pFlash.ProcedureOnGoing = FLASH_PROC_PAGE_ERASE;
  217. pFlash.NbPagesToErase = pEraseInit->NbPages;
  218. pFlash.Page = pEraseInit->Page;
  219. /*Erase 1st page and wait for IT */
  220. FLASH_PageErase(pEraseInit->Page, pEraseInit->Banks);
  221. }
  222. return status;
  223. }
  224. /**
  225. * @brief Program Option bytes.
  226. * @param pOBInit: pointer to an FLASH_OBInitStruct structure that
  227. * contains the configuration information for the programming.
  228. *
  229. * @retval HAL Status
  230. */
  231. HAL_StatusTypeDef HAL_FLASHEx_OBProgram(FLASH_OBProgramInitTypeDef *pOBInit)
  232. {
  233. HAL_StatusTypeDef status = HAL_ERROR;
  234. /* Process Locked */
  235. __HAL_LOCK(&pFlash);
  236. /* Check the parameters */
  237. assert_param(IS_OPTIONBYTE(pOBInit->OptionType));
  238. pFlash.ErrorCode = HAL_FLASH_ERROR_NONE;
  239. /* Write protection configuration */
  240. if((pOBInit->OptionType & OPTIONBYTE_WRP) != RESET)
  241. {
  242. /* Configure of Write protection on the selected area */
  243. status = FLASH_OB_WRPConfig(pOBInit->WRPArea, pOBInit->WRPStartOffset, pOBInit->WRPEndOffset);
  244. }
  245. /* Read protection configuration */
  246. if((pOBInit->OptionType & OPTIONBYTE_RDP) != RESET)
  247. {
  248. /* Configure the Read protection level */
  249. status = FLASH_OB_RDPConfig(pOBInit->RDPLevel);
  250. }
  251. /* User Configuration */
  252. if((pOBInit->OptionType & OPTIONBYTE_USER) != RESET)
  253. {
  254. /* Configure the user option bytes */
  255. status = FLASH_OB_UserConfig(pOBInit->USERType, pOBInit->USERConfig);
  256. }
  257. /* PCROP Configuration */
  258. if((pOBInit->OptionType & OPTIONBYTE_PCROP) != RESET)
  259. {
  260. /* Configure the Proprietary code readout protection */
  261. status = FLASH_OB_PCROPConfig(pOBInit->PCROPConfig, pOBInit->PCROPStartAddr, pOBInit->PCROPEndAddr);
  262. }
  263. /* Process Unlocked */
  264. __HAL_UNLOCK(&pFlash);
  265. return status;
  266. }
  267. /**
  268. * @brief Get the Option bytes configuration.
  269. * @param pOBInit: pointer to an FLASH_OBInitStruct structure that contains the
  270. * configuration information. The fields pOBInit->WRPArea and
  271. * pOBInit->PCROPConfig should indicate which area is requested
  272. * for the WRP and PCROP
  273. *
  274. * @retval None
  275. */
  276. void HAL_FLASHEx_OBGetConfig(FLASH_OBProgramInitTypeDef *pOBInit)
  277. {
  278. pOBInit->OptionType = (OPTIONBYTE_WRP | OPTIONBYTE_RDP | OPTIONBYTE_USER | OPTIONBYTE_PCROP);
  279. /* Get write protection on the selected area */
  280. FLASH_OB_GetWRP(pOBInit->WRPArea, &(pOBInit->WRPStartOffset), &(pOBInit->WRPEndOffset));
  281. /* Get Read protection level */
  282. pOBInit->RDPLevel = FLASH_OB_GetRDP();
  283. /* Get the user option bytes */
  284. pOBInit->USERConfig = FLASH_OB_GetUser();
  285. /* Get the Proprietary code readout protection */
  286. FLASH_OB_GetPCROP(&(pOBInit->PCROPConfig), &(pOBInit->PCROPStartAddr), &(pOBInit->PCROPEndAddr));
  287. }
  288. /**
  289. * @}
  290. */
  291. /**
  292. * @}
  293. */
  294. /* Private functions ---------------------------------------------------------*/
  295. /** @addtogroup FLASHEx_Private_Functions
  296. * @{
  297. */
  298. /**
  299. * @brief Mass erase of FLASH memory.
  300. * @param Banks: Banks to be erased
  301. * This parameter can be one of the following values:
  302. * @arg FLASH_BANK_1: Bank1 to be erased
  303. * @arg FLASH_BANK_2: Bank2 to be erased
  304. * @arg FLASH_BANK_BOTH: Bank1 and Bank2 to be erased
  305. * @retval None
  306. */
  307. static void FLASH_MassErase(uint32_t Banks)
  308. {
  309. /* Check the parameters */
  310. assert_param(IS_FLASH_BANK(Banks));
  311. /* Set the Mass Erase Bit for the bank 1 if requested */
  312. if((Banks & FLASH_BANK_1) != RESET)
  313. {
  314. SET_BIT(FLASH->CR, FLASH_CR_MER1);
  315. }
  316. /* Set the Mass Erase Bit for the bank 2 if requested */
  317. if((Banks & FLASH_BANK_2) != RESET)
  318. {
  319. SET_BIT(FLASH->CR, FLASH_CR_MER2);
  320. }
  321. /* Proceed to erase all sectors */
  322. SET_BIT(FLASH->CR, FLASH_CR_STRT);
  323. }
  324. /**
  325. * @brief Erase the specified FLASH memory page.
  326. * @param Page: FLASH page to erase
  327. * This parameter must be a value between 0 and (max number of pages in the bank - 1)
  328. * @param Banks: Bank(s) where the page will be erased
  329. * This parameter can be one or a combination of the following values:
  330. * @arg FLASH_BANK_1: Page in bank 1 to be erased
  331. * @arg FLASH_BANK_2: Page in bank 2 to be erased
  332. * @retval None
  333. */
  334. void FLASH_PageErase(uint32_t Page, uint32_t Banks)
  335. {
  336. /* Check the parameters */
  337. assert_param(IS_FLASH_PAGE(Page));
  338. assert_param(IS_FLASH_BANK_EXCLUSIVE(Banks));
  339. if((Banks & FLASH_BANK_1) != RESET)
  340. {
  341. CLEAR_BIT(FLASH->CR, FLASH_CR_BKER);
  342. }
  343. else
  344. {
  345. SET_BIT(FLASH->CR, FLASH_CR_BKER);
  346. }
  347. /* Proceed to erase the page */
  348. MODIFY_REG(FLASH->CR, FLASH_CR_PNB, (Page << 3));
  349. SET_BIT(FLASH->CR, FLASH_CR_PER);
  350. SET_BIT(FLASH->CR, FLASH_CR_STRT);
  351. }
  352. /**
  353. * @brief Flush the instruction and data caches.
  354. * @retval None
  355. */
  356. void FLASH_FlushCaches(void)
  357. {
  358. /* Flush instruction cache */
  359. if(READ_BIT(FLASH->ACR, FLASH_ACR_ICEN) != RESET)
  360. {
  361. /* Disable instruction cache */
  362. __HAL_FLASH_INSTRUCTION_CACHE_DISABLE();
  363. /* Reset instruction cache */
  364. __HAL_FLASH_INSTRUCTION_CACHE_RESET();
  365. /* Enable instruction cache */
  366. __HAL_FLASH_INSTRUCTION_CACHE_ENABLE();
  367. }
  368. /* Flush data cache */
  369. if(READ_BIT(FLASH->ACR, FLASH_ACR_DCEN) != RESET)
  370. {
  371. /* Disable data cache */
  372. __HAL_FLASH_DATA_CACHE_DISABLE();
  373. /* Reset data cache */
  374. __HAL_FLASH_DATA_CACHE_RESET();
  375. /* Enable data cache */
  376. __HAL_FLASH_DATA_CACHE_ENABLE();
  377. }
  378. }
  379. /**
  380. * @brief Configure the write protection of the desired pages.
  381. *
  382. * @note When the memory read protection level is selected (RDP level = 1),
  383. * it is not possible to program or erase Flash memory if the CPU debug
  384. * features are connected (JTAG or single wire) or boot code is being
  385. * executed from RAM or System flash, even if WRP is not activated.
  386. * @note To configure the WRP options, the option lock bit OPTLOCK must be
  387. * cleared with the call of the HAL_FLASH_OB_Unlock() function.
  388. * @note To validate the WRP options, the option bytes must be reloaded
  389. * through the call of the HAL_FLASH_OB_Launch() function.
  390. *
  391. * @param WRPArea: specifies the area to be configured.
  392. * This parameter can be one of the following values:
  393. * @arg OB_WRPAREA_BANK1_AREAA: Flash Bank 1 Area A
  394. * @arg OB_WRPAREA_BANK1_AREAB: Flash Bank 1 Area B
  395. * @arg OB_WRPAREA_BANK2_AREAA: Flash Bank 2 Area A
  396. * @arg OB_WRPAREA_BANK2_AREAB: Flash Bank 2 Area B
  397. *
  398. * @param WRPStartOffset: specifies the start page of the write protected area
  399. * This parameter can be page number between 0 and (max number of pages in the bank - 1)
  400. *
  401. * @param WRDPEndOffset: specifies the end page of the write protected area
  402. * This parameter can be page number between WRPStartOffset and (max number of pages in the bank - 1)
  403. *
  404. * @retval HAL Status
  405. */
  406. static HAL_StatusTypeDef FLASH_OB_WRPConfig(uint32_t WRPArea, uint32_t WRPStartOffset, uint32_t WRDPEndOffset)
  407. {
  408. HAL_StatusTypeDef status = HAL_OK;
  409. /* Check the parameters */
  410. assert_param(IS_OB_WRPAREA(WRPArea));
  411. assert_param(IS_FLASH_PAGE(WRPStartOffset));
  412. assert_param(IS_FLASH_PAGE(WRDPEndOffset));
  413. /* Wait for last operation to be completed */
  414. status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE);
  415. if(status == HAL_OK)
  416. {
  417. /* Configure the write protected area */
  418. if(WRPArea == OB_WRPAREA_BANK1_AREAA)
  419. {
  420. MODIFY_REG(FLASH->WRP1AR, (FLASH_WRP1AR_WRP1A_STRT | FLASH_WRP1AR_WRP1A_END),
  421. (WRPStartOffset | (WRDPEndOffset << 16)));
  422. }
  423. else if(WRPArea == OB_WRPAREA_BANK1_AREAB)
  424. {
  425. MODIFY_REG(FLASH->WRP1BR, (FLASH_WRP1BR_WRP1B_STRT | FLASH_WRP1BR_WRP1B_END),
  426. (WRPStartOffset | (WRDPEndOffset << 16)));
  427. }
  428. else if(WRPArea == OB_WRPAREA_BANK2_AREAA)
  429. {
  430. MODIFY_REG(FLASH->WRP2AR, (FLASH_WRP2AR_WRP2A_STRT | FLASH_WRP2AR_WRP2A_END),
  431. (WRPStartOffset | (WRDPEndOffset << 16)));
  432. }
  433. else if(WRPArea == OB_WRPAREA_BANK2_AREAB)
  434. {
  435. MODIFY_REG(FLASH->WRP2BR, (FLASH_WRP2BR_WRP2B_STRT | FLASH_WRP2BR_WRP2B_END),
  436. (WRPStartOffset | (WRDPEndOffset << 16)));
  437. }
  438. /* Set OPTSTRT Bit */
  439. SET_BIT(FLASH->CR, FLASH_CR_OPTSTRT);
  440. /* Wait for last operation to be completed */
  441. status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE);
  442. /* If the option byte program operation is completed, disable the OPTSTRT Bit */
  443. CLEAR_BIT(FLASH->CR, FLASH_CR_OPTSTRT);
  444. }
  445. return status;
  446. }
  447. /**
  448. * @brief Set the read protection level.
  449. *
  450. * @note To configure the RDP level, the option lock bit OPTLOCK must be
  451. * cleared with the call of the HAL_FLASH_OB_Unlock() function.
  452. * @note To validate the RDP level, the option bytes must be reloaded
  453. * through the call of the HAL_FLASH_OB_Launch() function.
  454. * @note !!! Warning : When enabling OB_RDP level 2 it's no more possible
  455. * to go back to level 1 or 0 !!!
  456. *
  457. * @param RDPLevel: specifies the read protection level.
  458. * This parameter can be one of the following values:
  459. * @arg OB_RDP_LEVEL_0: No protection
  460. * @arg OB_RDP_LEVEL_1: Read protection of the memory
  461. * @arg OB_RDP_LEVEL_2: Full chip protection
  462. *
  463. * @retval HAL status
  464. */
  465. static HAL_StatusTypeDef FLASH_OB_RDPConfig(uint32_t RDPLevel)
  466. {
  467. HAL_StatusTypeDef status = HAL_OK;
  468. /* Check the parameters */
  469. assert_param(IS_OB_RDP_LEVEL(RDPLevel));
  470. /* Wait for last operation to be completed */
  471. status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE);
  472. if(status == HAL_OK)
  473. {
  474. /* Configure the RDP level in the option bytes register */
  475. MODIFY_REG(FLASH->OPTR, FLASH_OPTR_RDP, RDPLevel);
  476. /* Set OPTSTRT Bit */
  477. SET_BIT(FLASH->CR, FLASH_CR_OPTSTRT);
  478. /* Wait for last operation to be completed */
  479. status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE);
  480. /* If the option byte program operation is completed, disable the OPTSTRT Bit */
  481. CLEAR_BIT(FLASH->CR, FLASH_CR_OPTSTRT);
  482. }
  483. return status;
  484. }
  485. /**
  486. * @brief Program the FLASH User Option Byte.
  487. *
  488. * @note To configure the user option bytes, the option lock bit OPTLOCK must
  489. * be cleared with the call of the HAL_FLASH_OB_Unlock() function.
  490. * @note To validate the user option bytes, the option bytes must be reloaded
  491. * through the call of the HAL_FLASH_OB_Launch() function.
  492. *
  493. * @param UserType: The FLASH User Option Bytes to be modified
  494. * @param UserConfig: The FLASH User Option Bytes values:
  495. * BOR_LEV(Bit8-10), nRST_STOP(Bit12), nRST_STDBY(Bit13), IWDG_SW(Bit16),
  496. * IWDG_STOP(Bit17), IWDG_STDBY(Bit18), WWDG_SW(Bit19), BFB2(Bit20),
  497. * DUALBANK(Bit21), nBOOT1(Bit23), SRAM2_PE(Bit24) and SRAM2_RST(Bit25).
  498. *
  499. * @retval HAL status
  500. */
  501. static HAL_StatusTypeDef FLASH_OB_UserConfig(uint32_t UserType, uint32_t UserConfig)
  502. {
  503. uint32_t optr_reg_val = 0;
  504. uint32_t optr_reg_mask = 0;
  505. HAL_StatusTypeDef status = HAL_OK;
  506. /* Check the parameters */
  507. assert_param(IS_OB_USER_TYPE(UserType));
  508. /* Wait for last operation to be completed */
  509. status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE);
  510. if(status == HAL_OK)
  511. {
  512. if((UserType & OB_USER_BOR_LEV) != RESET)
  513. {
  514. /* BOR level option byte should be modified */
  515. assert_param(IS_OB_USER_BOR_LEVEL(UserConfig & FLASH_OPTR_BOR_LEV));
  516. /* Set value and mask for BOR level option byte */
  517. optr_reg_val |= (UserConfig & FLASH_OPTR_BOR_LEV);
  518. optr_reg_mask |= FLASH_OPTR_BOR_LEV;
  519. }
  520. if((UserType & OB_USER_nRST_STOP) != RESET)
  521. {
  522. /* nRST_STOP option byte should be modified */
  523. assert_param(IS_OB_USER_STOP(UserConfig & FLASH_OPTR_nRST_STOP));
  524. /* Set value and mask for nRST_STOP option byte */
  525. optr_reg_val |= (UserConfig & FLASH_OPTR_nRST_STOP);
  526. optr_reg_mask |= FLASH_OPTR_nRST_STOP;
  527. }
  528. if((UserType & OB_USER_nRST_STDBY) != RESET)
  529. {
  530. /* nRST_STDBY option byte should be modified */
  531. assert_param(IS_OB_USER_STANDBY(UserConfig & FLASH_OPTR_nRST_STDBY));
  532. /* Set value and mask for nRST_STDBY option byte */
  533. optr_reg_val |= (UserConfig & FLASH_OPTR_nRST_STDBY);
  534. optr_reg_mask |= FLASH_OPTR_nRST_STDBY;
  535. }
  536. if((UserType & OB_USER_nRST_SHDW) != RESET)
  537. {
  538. /* nRST_SHDW option byte should be modified */
  539. assert_param(IS_OB_USER_SHUTDOWN(UserConfig & FLASH_OPTR_nRST_SHDW));
  540. /* Set value and mask for nRST_SHDW option byte */
  541. optr_reg_val |= (UserConfig & FLASH_OPTR_nRST_SHDW);
  542. optr_reg_mask |= FLASH_OPTR_nRST_SHDW;
  543. }
  544. if((UserType & OB_USER_IWDG_SW) != RESET)
  545. {
  546. /* IWDG_SW option byte should be modified */
  547. assert_param(IS_OB_USER_IWDG(UserConfig & FLASH_OPTR_IWDG_SW));
  548. /* Set value and mask for IWDG_SW option byte */
  549. optr_reg_val |= (UserConfig & FLASH_OPTR_IWDG_SW);
  550. optr_reg_mask |= FLASH_OPTR_IWDG_SW;
  551. }
  552. if((UserType & OB_USER_IWDG_STOP) != RESET)
  553. {
  554. /* IWDG_STOP option byte should be modified */
  555. assert_param(IS_OB_USER_IWDG_STOP(UserConfig & FLASH_OPTR_IWDG_STOP));
  556. /* Set value and mask for IWDG_STOP option byte */
  557. optr_reg_val |= (UserConfig & FLASH_OPTR_IWDG_STOP);
  558. optr_reg_mask |= FLASH_OPTR_IWDG_STOP;
  559. }
  560. if((UserType & OB_USER_IWDG_STDBY) != RESET)
  561. {
  562. /* IWDG_STDBY option byte should be modified */
  563. assert_param(IS_OB_USER_IWDG_STDBY(UserConfig & FLASH_OPTR_IWDG_STDBY));
  564. /* Set value and mask for IWDG_STDBY option byte */
  565. optr_reg_val |= (UserConfig & FLASH_OPTR_IWDG_STDBY);
  566. optr_reg_mask |= FLASH_OPTR_IWDG_STDBY;
  567. }
  568. if((UserType & OB_USER_WWDG_SW) != RESET)
  569. {
  570. /* WWDG_SW option byte should be modified */
  571. assert_param(IS_OB_USER_WWDG(UserConfig & FLASH_OPTR_WWDG_SW));
  572. /* Set value and mask for WWDG_SW option byte */
  573. optr_reg_val |= (UserConfig & FLASH_OPTR_WWDG_SW);
  574. optr_reg_mask |= FLASH_OPTR_WWDG_SW;
  575. }
  576. if((UserType & OB_USER_BFB2) != RESET)
  577. {
  578. /* BFB2 option byte should be modified */
  579. assert_param(IS_OB_USER_BFB2(UserConfig & FLASH_OPTR_BFB2));
  580. /* Set value and mask for BFB2 option byte */
  581. optr_reg_val |= (UserConfig & FLASH_OPTR_BFB2);
  582. optr_reg_mask |= FLASH_OPTR_BFB2;
  583. }
  584. if((UserType & OB_USER_DUALBANK) != RESET)
  585. {
  586. /* DUALBANK option byte should be modified */
  587. assert_param(IS_OB_USER_DUALBANK(UserConfig & FLASH_OPTR_DUALBANK));
  588. /* Set value and mask for DUALBANK option byte */
  589. optr_reg_val |= (UserConfig & FLASH_OPTR_DUALBANK);
  590. optr_reg_mask |= FLASH_OPTR_DUALBANK;
  591. }
  592. if((UserType & OB_USER_nBOOT1) != RESET)
  593. {
  594. /* nBOOT1 option byte should be modified */
  595. assert_param(IS_OB_USER_BOOT1(UserConfig & FLASH_OPTR_nBOOT1));
  596. /* Set value and mask for nBOOT1 option byte */
  597. optr_reg_val |= (UserConfig & FLASH_OPTR_nBOOT1);
  598. optr_reg_mask |= FLASH_OPTR_nBOOT1;
  599. }
  600. if((UserType & OB_USER_SRAM2_PE) != RESET)
  601. {
  602. /* SRAM2_PE option byte should be modified */
  603. assert_param(IS_OB_USER_SRAM2_PARITY(UserConfig & FLASH_OPTR_SRAM2_PE));
  604. /* Set value and mask for SRAM2_PE option byte */
  605. optr_reg_val |= (UserConfig & FLASH_OPTR_SRAM2_PE);
  606. optr_reg_mask |= FLASH_OPTR_SRAM2_PE;
  607. }
  608. if((UserType & OB_USER_SRAM2_RST) != RESET)
  609. {
  610. /* SRAM2_RST option byte should be modified */
  611. assert_param(IS_OB_USER_SRAM2_RST(UserConfig & FLASH_OPTR_SRAM2_RST));
  612. /* Set value and mask for SRAM2_RST option byte */
  613. optr_reg_val |= (UserConfig & FLASH_OPTR_SRAM2_RST);
  614. optr_reg_mask |= FLASH_OPTR_SRAM2_RST;
  615. }
  616. /* Configure the option bytes register */
  617. MODIFY_REG(FLASH->OPTR, optr_reg_mask, optr_reg_val);
  618. /* Set OPTSTRT Bit */
  619. SET_BIT(FLASH->CR, FLASH_CR_OPTSTRT);
  620. /* Wait for last operation to be completed */
  621. status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE);
  622. /* If the option byte program operation is completed, disable the OPTSTRT Bit */
  623. CLEAR_BIT(FLASH->CR, FLASH_CR_OPTSTRT);
  624. }
  625. return status;
  626. }
  627. /**
  628. * @brief Configure the Proprietary code readout protection of the desired addresses.
  629. *
  630. * @note To configure the PCROP options, the option lock bit OPTLOCK must be
  631. * cleared with the call of the HAL_FLASH_OB_Unlock() function.
  632. * @note To validate the PCROP options, the option bytes must be reloaded
  633. * through the call of the HAL_FLASH_OB_Launch() function.
  634. *
  635. * @param PCROPConfig: specifies the configuration (Bank to be configured and PCROP_RDP option).
  636. * This parameter must be a combination of FLASH_BANK_1 or FLASH_BANK_2
  637. * with OB_PCROP_RDP_NOT_ERASE or OB_PCROP_RDP_ERASE
  638. *
  639. * @param PCROPStartAddr: specifies the start address of the Proprietary code readout protection
  640. * This parameter can be an address between begin and end of the bank
  641. *
  642. * @param PCROPEndAddr: specifies the end address of the Proprietary code readout protection
  643. * This parameter can be an address between PCROPStartAddr and end of the bank
  644. *
  645. * @retval HAL Status
  646. */
  647. static HAL_StatusTypeDef FLASH_OB_PCROPConfig(uint32_t PCROPConfig, uint32_t PCROPStartAddr, uint32_t PCROPEndAddr)
  648. {
  649. HAL_StatusTypeDef status = HAL_OK;
  650. uint32_t reg_value = 0;
  651. uint32_t bank1_addr, bank2_addr;
  652. /* Check the parameters */
  653. assert_param(IS_FLASH_BANK_EXCLUSIVE(PCROPConfig & FLASH_BANK_BOTH));
  654. assert_param(IS_OB_PCROP_RDP(PCROPConfig & FLASH_PCROP1ER_PCROP_RDP));
  655. assert_param(IS_FLASH_MAIN_MEM_ADDRESS(PCROPStartAddr));
  656. assert_param(IS_FLASH_MAIN_MEM_ADDRESS(PCROPEndAddr));
  657. /* Wait for last operation to be completed */
  658. status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE);
  659. if(status == HAL_OK)
  660. {
  661. /* Get the information about the bank swapping */
  662. if (READ_BIT(SYSCFG->MEMRMP, SYSCFG_MEMRMP_FB_MODE) == 0)
  663. {
  664. bank1_addr = FLASH_BASE;
  665. bank2_addr = FLASH_BASE + FLASH_BANK_SIZE;
  666. }
  667. else
  668. {
  669. bank1_addr = FLASH_BASE + FLASH_BANK_SIZE;
  670. bank2_addr = FLASH_BASE;
  671. }
  672. /* Configure the Proprietary code readout protection */
  673. if((PCROPConfig & FLASH_BANK_BOTH) == FLASH_BANK_1)
  674. {
  675. reg_value = ((PCROPStartAddr - bank1_addr) >> 3);
  676. MODIFY_REG(FLASH->PCROP1SR, FLASH_PCROP1SR_PCROP1_STRT, reg_value);
  677. reg_value = ((PCROPEndAddr - bank1_addr) >> 3);
  678. MODIFY_REG(FLASH->PCROP1ER, FLASH_PCROP1ER_PCROP1_END, reg_value);
  679. }
  680. else if((PCROPConfig & FLASH_BANK_BOTH) == FLASH_BANK_2)
  681. {
  682. reg_value = ((PCROPStartAddr - bank2_addr) >> 3);
  683. MODIFY_REG(FLASH->PCROP2SR, FLASH_PCROP2SR_PCROP2_STRT, reg_value);
  684. reg_value = ((PCROPEndAddr - bank2_addr) >> 3);
  685. MODIFY_REG(FLASH->PCROP2ER, FLASH_PCROP2ER_PCROP2_END, reg_value);
  686. }
  687. MODIFY_REG(FLASH->PCROP1ER, FLASH_PCROP1ER_PCROP_RDP, (PCROPConfig & FLASH_PCROP1ER_PCROP_RDP));
  688. /* Set OPTSTRT Bit */
  689. SET_BIT(FLASH->CR, FLASH_CR_OPTSTRT);
  690. /* Wait for last operation to be completed */
  691. status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE);
  692. /* If the option byte program operation is completed, disable the OPTSTRT Bit */
  693. CLEAR_BIT(FLASH->CR, FLASH_CR_OPTSTRT);
  694. }
  695. return status;
  696. }
  697. /**
  698. * @brief Return the FLASH Write Protection Option Bytes value.
  699. *
  700. * @param[in] WRPArea: specifies the area to be returned.
  701. * This parameter can be one of the following values:
  702. * @arg OB_WRPAREA_BANK1_AREAA: Flash Bank 1 Area A
  703. * @arg OB_WRPAREA_BANK1_AREAB: Flash Bank 1 Area B
  704. * @arg OB_WRPAREA_BANK2_AREAA: Flash Bank 2 Area A
  705. * @arg OB_WRPAREA_BANK2_AREAB: Flash Bank 2 Area B
  706. *
  707. * @param[out] WRPStartOffset: specifies the address where to copied the start page
  708. * of the write protected area
  709. *
  710. * @param[out] WRDPEndOffset: specifies the address where to copied the end page of
  711. * the write protected area
  712. *
  713. * @retval None
  714. */
  715. static void FLASH_OB_GetWRP(uint32_t WRPArea, uint32_t * WRPStartOffset, uint32_t * WRDPEndOffset)
  716. {
  717. /* Check the parameters */
  718. assert_param(IS_OB_WRPAREA(WRPArea));
  719. /* Get the configuration of the write protected area */
  720. if(WRPArea == OB_WRPAREA_BANK1_AREAA)
  721. {
  722. *WRPStartOffset = READ_BIT(FLASH->WRP1AR, FLASH_WRP1AR_WRP1A_STRT);
  723. *WRDPEndOffset = (READ_BIT(FLASH->WRP1AR, FLASH_WRP1AR_WRP1A_END) >> 16);
  724. }
  725. else if(WRPArea == OB_WRPAREA_BANK1_AREAB)
  726. {
  727. *WRPStartOffset = READ_BIT(FLASH->WRP1BR, FLASH_WRP1BR_WRP1B_STRT);
  728. *WRDPEndOffset = (READ_BIT(FLASH->WRP1BR, FLASH_WRP1BR_WRP1B_END) >> 16);
  729. }
  730. else if(WRPArea == OB_WRPAREA_BANK2_AREAA)
  731. {
  732. *WRPStartOffset = READ_BIT(FLASH->WRP2AR, FLASH_WRP2AR_WRP2A_STRT);
  733. *WRDPEndOffset = (READ_BIT(FLASH->WRP2AR, FLASH_WRP2AR_WRP2A_END) >> 16);
  734. }
  735. else if(WRPArea == OB_WRPAREA_BANK2_AREAB)
  736. {
  737. *WRPStartOffset = READ_BIT(FLASH->WRP2BR, FLASH_WRP2BR_WRP2B_STRT);
  738. *WRDPEndOffset = (READ_BIT(FLASH->WRP2BR, FLASH_WRP2BR_WRP2B_END) >> 16);
  739. }
  740. }
  741. /**
  742. * @brief Return the FLASH Read Protection level.
  743. * @retval FLASH ReadOut Protection Status:
  744. * This return value can be one of the following values:
  745. * @arg OB_RDP_LEVEL_0: No protection
  746. * @arg OB_RDP_LEVEL_1: Read protection of the memory
  747. * @arg OB_RDP_LEVEL_2: Full chip protection
  748. */
  749. static uint32_t FLASH_OB_GetRDP(void)
  750. {
  751. if ((READ_BIT(FLASH->OPTR, FLASH_OPTR_RDP) != OB_RDP_LEVEL_0) &&
  752. (READ_BIT(FLASH->OPTR, FLASH_OPTR_RDP) != OB_RDP_LEVEL_2))
  753. {
  754. return (OB_RDP_LEVEL_1);
  755. }
  756. else
  757. {
  758. return (READ_BIT(FLASH->OPTR, FLASH_OPTR_RDP));
  759. }
  760. }
  761. /**
  762. * @brief Return the FLASH User Option Byte value.
  763. * @retval The FLASH User Option Bytes values:
  764. * BOR_LEV(Bit8-10), nRST_STOP(Bit12), nRST_STDBY(Bit13), nRST_SHDW(Bit14),
  765. * IWDG_SW(Bit16), IWDG_STOP(Bit17), IWDG_STDBY(Bit18), WWDG_SW(Bit19),
  766. * BFB2(Bit20), DUALBANK(Bit21), nBOOT1(Bit23), SRAM2_PE(Bit24) and SRAM2_RST(Bit25).
  767. */
  768. static uint32_t FLASH_OB_GetUser(void)
  769. {
  770. uint32_t user_config = READ_REG(FLASH->OPTR);
  771. CLEAR_BIT(user_config, FLASH_OPTR_RDP);
  772. return user_config;
  773. }
  774. /**
  775. * @brief Return the FLASH Write Protection Option Bytes value.
  776. *
  777. * @param PCROPConfig [inout]: specifies the configuration (Bank to be configured and PCROP_RDP option).
  778. * This parameter must be a combination of FLASH_BANK_1 or FLASH_BANK_2
  779. * with OB_PCROP_RDP_NOT_ERASE or OB_PCROP_RDP_ERASE
  780. *
  781. * @param PCROPStartAddr [out]: specifies the address where to copied the start address
  782. * of the Proprietary code readout protection
  783. *
  784. * @param PCROPEndAddr [out]: specifies the address where to copied the end address of
  785. * the Proprietary code readout protection
  786. *
  787. * @retval None
  788. */
  789. static void FLASH_OB_GetPCROP(uint32_t * PCROPConfig, uint32_t * PCROPStartAddr, uint32_t * PCROPEndAddr)
  790. {
  791. uint32_t reg_value = 0;
  792. uint32_t bank1_addr, bank2_addr;
  793. /* Check the parameters */
  794. assert_param(IS_FLASH_BANK_EXCLUSIVE((*PCROPConfig) & FLASH_BANK_BOTH));
  795. /* Get the information about the bank swapping */
  796. if (READ_BIT(SYSCFG->MEMRMP, SYSCFG_MEMRMP_FB_MODE) == 0)
  797. {
  798. bank1_addr = FLASH_BASE;
  799. bank2_addr = FLASH_BASE + FLASH_BANK_SIZE;
  800. }
  801. else
  802. {
  803. bank1_addr = FLASH_BASE + FLASH_BANK_SIZE;
  804. bank2_addr = FLASH_BASE;
  805. }
  806. if(((*PCROPConfig) & FLASH_BANK_BOTH) == FLASH_BANK_1)
  807. {
  808. reg_value = (READ_REG(FLASH->PCROP1SR) & FLASH_PCROP1SR_PCROP1_STRT);
  809. *PCROPStartAddr = (reg_value << 3) + bank1_addr;
  810. reg_value = (READ_REG(FLASH->PCROP1ER) & FLASH_PCROP1ER_PCROP1_END);
  811. *PCROPEndAddr = (reg_value << 3) + bank1_addr;
  812. }
  813. else if(((*PCROPConfig) & FLASH_BANK_BOTH) == FLASH_BANK_2)
  814. {
  815. reg_value = (READ_REG(FLASH->PCROP2SR) & FLASH_PCROP2SR_PCROP2_STRT);
  816. *PCROPStartAddr = (reg_value << 3) + bank2_addr;
  817. reg_value = (READ_REG(FLASH->PCROP2ER) & FLASH_PCROP2ER_PCROP2_END);
  818. *PCROPEndAddr = (reg_value << 3) + bank2_addr;
  819. }
  820. *PCROPConfig |= (READ_REG(FLASH->PCROP1ER) & FLASH_PCROP1ER_PCROP_RDP);
  821. }
  822. /**
  823. * @}
  824. */
  825. /**
  826. * @}
  827. */
  828. #endif /* HAL_FLASH_MODULE_ENABLED */
  829. /**
  830. * @}
  831. */
  832. /**
  833. * @}
  834. */
  835. /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/