py32f0xx_hal_flash.c 32 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161
  1. /**
  2. ******************************************************************************
  3. * @file py32f0xx_hal_flash.c
  4. * @author MCU Application Team
  5. * @brief FLASH HAL module driver.
  6. * This file provides firmware functions to manage the following
  7. * functionalities of the internal FLASH memory:
  8. * + Program operations functions
  9. * + Memory Control functions
  10. * + Peripheral Errors functions
  11. *
  12. ******************************************************************************
  13. * @attention
  14. *
  15. * <h2><center>&copy; Copyright (c) 2023 Puya Semiconductor Co.
  16. * All rights reserved.</center></h2>
  17. *
  18. * This software component is licensed by Puya under BSD 3-Clause license,
  19. * the "License"; You may not use this file except in compliance with the
  20. * License. You may obtain a copy of the License at:
  21. * opensource.org/licenses/BSD-3-Clause
  22. *
  23. ******************************************************************************
  24. * @attention
  25. *
  26. * <h2><center>&copy; Copyright (c) 2016 STMicroelectronics.
  27. * All rights reserved.</center></h2>
  28. *
  29. * This software component is licensed by ST under BSD 3-Clause license,
  30. * the "License"; You may not use this file except in compliance with the
  31. * License. You may obtain a copy of the License at:
  32. * opensource.org/licenses/BSD-3-Clause
  33. *
  34. ******************************************************************************
  35. */
  36. /* Includes ------------------------------------------------------------------*/
  37. #include "py32f0xx_hal.h"
  38. /** @addtogroup PY32F0xx_HAL_Driver
  39. * @{
  40. */
  41. /** @defgroup FLASH FLASH
  42. * @brief FLASH HAL module driver
  43. * @{
  44. */
  45. #ifdef HAL_FLASH_MODULE_ENABLED
  46. /* Private typedef -----------------------------------------------------------*/
  47. /* Private defines -----------------------------------------------------------*/
  48. /* Private macros ------------------------------------------------------------*/
  49. /* Private variables ---------------------------------------------------------*/
  50. /** @defgroup FLASH_Private_Variables FLASH Private Variables
  51. * @{
  52. */
  53. /**
  54. * @brief Variable used for Program/Erase sectors under interruption
  55. */
  56. FLASH_ProcessTypeDef pFlash = {.Lock = HAL_UNLOCKED, \
  57. .ErrorCode = HAL_FLASH_ERROR_NONE, \
  58. .ProcedureOnGoing = FLASH_TYPENONE, \
  59. .Address = 0U, \
  60. .PageOrSector = 0U, \
  61. .NbPagesSectorsToErase = 0U
  62. };
  63. /**
  64. * @}
  65. */
  66. const uint32_t _FlashTimmingParam[8] = {0x1FFF0F1C, 0x1FFF0F30, 0x1FFF0F44, 0x1FFF0F58, 0x1FFF0F6C, 0x1FFF0F1C, 0x1FFF0F1C, 0x1FFF0F1C};
  67. /**
  68. * @brief Option byte program.
  69. * @note Enable this configuration, you need to add the corresponding optionbyte FLM file
  70. */
  71. #ifdef FLASH_OPT_PROGRAM_ENABLED
  72. #if defined ( __GNUC__ ) && !defined (__CC_ARM) /* GNU Compiler */
  73. const uint32_t u32ICG[] __attribute__((section(".opt_sec"))) =
  74. #elif defined (__CC_ARM)
  75. const uint32_t u32ICG[] __attribute__((at(OB_BASE))) =
  76. #elif defined (__ICCARM__)
  77. __root const uint32_t u32ICG[] @ OB_BASE =
  78. #else
  79. #error "unsupported compiler!!"
  80. #endif
  81. {
  82. FLASH_OPTR_CONSTANT,
  83. FLASH_SDKR_CONSTANT,
  84. 0xFFFFFFFF,
  85. FLASH_WRPR_CONSTANT,
  86. };
  87. #endif /* FLASH_OPT_PROGRAM_ENABLED */
  88. /* Private function prototypes -----------------------------------------------*/
  89. /** @defgroup FLASH_Private_Functions FLASH Private Functions
  90. * @{
  91. */
  92. static void FLASH_MassErase(void);
  93. static void FLASH_Program_Page(uint32_t Address, uint32_t * DataAddress);
  94. static void FLASH_PageErase(uint32_t PageAddress);
  95. static HAL_StatusTypeDef FLASH_WaitForLastOperation(uint32_t Timeout);
  96. /**
  97. * @}
  98. */
  99. /* Exported functions --------------------------------------------------------*/
  100. /** @defgroup FLASH_Exported_Functions FLASH Exported Functions
  101. * @{
  102. */
  103. /** @defgroup FLASH_Exported_Functions_Group2 Peripheral Control functions
  104. * @brief Management functions
  105. *
  106. @verbatim
  107. ===============================================================================
  108. ##### Peripheral Control functions #####
  109. ===============================================================================
  110. [..]
  111. This subsection provides a set of functions allowing to control the FLASH
  112. memory operations.
  113. @endverbatim
  114. * @{
  115. */
  116. /**
  117. * @brief Unlock the FLASH control register access.
  118. * @retval HAL Status
  119. */
  120. HAL_StatusTypeDef HAL_FLASH_Unlock(void)
  121. {
  122. HAL_StatusTypeDef status = HAL_OK;
  123. if (READ_BIT(FLASH->CR, FLASH_CR_LOCK) != 0x00U)
  124. {
  125. /* Authorize the FLASH Registers access */
  126. WRITE_REG(FLASH->KEYR, FLASH_KEY1);
  127. WRITE_REG(FLASH->KEYR, FLASH_KEY2);
  128. /* verify Flash is unlock */
  129. if (READ_BIT(FLASH->CR, FLASH_CR_LOCK) != 0x00U)
  130. {
  131. status = HAL_ERROR;
  132. }
  133. }
  134. return status;
  135. }
  136. /**
  137. * @brief Lock the FLASH control register access.
  138. * @retval HAL Status
  139. */
  140. HAL_StatusTypeDef HAL_FLASH_Lock(void)
  141. {
  142. HAL_StatusTypeDef status = HAL_ERROR;
  143. /* Set the LOCK Bit to lock the FLASH Registers access */
  144. SET_BIT(FLASH->CR, FLASH_CR_LOCK);
  145. /* verify Flash is locked */
  146. if (READ_BIT(FLASH->CR, FLASH_CR_LOCK) != 0x00u)
  147. {
  148. status = HAL_OK;
  149. }
  150. return status;
  151. }
  152. /**
  153. * @brief Unlock the FLASH Option Bytes Registers access.
  154. * @retval HAL Status
  155. */
  156. HAL_StatusTypeDef HAL_FLASH_OB_Unlock(void)
  157. {
  158. HAL_StatusTypeDef status = HAL_ERROR;
  159. if (READ_BIT(FLASH->CR, FLASH_CR_OPTLOCK) != 0x00U)
  160. {
  161. /* Authorizes the Option Byte register programming */
  162. WRITE_REG(FLASH->OPTKEYR, FLASH_OPTKEY1);
  163. WRITE_REG(FLASH->OPTKEYR, FLASH_OPTKEY2);
  164. /* verify option bytes are unlocked */
  165. if (READ_BIT(FLASH->CR, FLASH_CR_OPTLOCK) == 0x00U)
  166. {
  167. status = HAL_OK;
  168. }
  169. }
  170. return status;
  171. }
  172. /**
  173. * @brief Lock the FLASH Option Bytes Registers access.
  174. * @retval HAL Status
  175. */
  176. HAL_StatusTypeDef HAL_FLASH_OB_Lock(void)
  177. {
  178. HAL_StatusTypeDef status = HAL_ERROR;
  179. /* Set the OPTLOCK Bit to lock the FLASH Option Byte Registers access */
  180. SET_BIT(FLASH->CR, FLASH_CR_OPTLOCK);
  181. /* verify option bytes are locked */
  182. if (READ_BIT(FLASH->CR, FLASH_CR_OPTLOCK) != 0x00u)
  183. {
  184. status = HAL_OK;
  185. }
  186. return status;
  187. }
  188. /**
  189. * @brief Launch the option byte loading.
  190. * @retval HAL Status
  191. */
  192. HAL_StatusTypeDef HAL_FLASH_OB_Launch(void)
  193. {
  194. /* Set the bit to force the option byte reloading */
  195. SET_BIT(FLASH->CR, FLASH_CR_OBL_LAUNCH);
  196. /* We should not reach here : Option byte launch generates Option byte reset
  197. so return error */
  198. return HAL_ERROR;
  199. }
  200. /**
  201. * @}
  202. */
  203. /** @defgroup FLASH_Exported_Functions_Group3 Peripheral State and Errors functions
  204. * @brief Peripheral Errors functions
  205. *
  206. @verbatim
  207. ===============================================================================
  208. ##### Peripheral Errors functions #####
  209. ===============================================================================
  210. [..]
  211. This subsection permits to get in run-time Errors of the FLASH peripheral.
  212. @endverbatim
  213. * @{
  214. */
  215. /**
  216. * @brief Get the specific FLASH error flag.
  217. * @retval FLASH_ErrorCode The returned value can be
  218. * @arg @ref HAL_FLASH_ERROR_NONE No error set
  219. * @arg @ref HAL_FLASH_ERROR_WRP FLASH Write protection error
  220. * @arg @ref HAL_FLASH_ERROR_OPTV FLASH Option validity error
  221. * @note (*) availability depends on devices
  222. */
  223. uint32_t HAL_FLASH_GetError(void)
  224. {
  225. return pFlash.ErrorCode;
  226. }
  227. /**
  228. * @}
  229. */
  230. /**
  231. * @}
  232. */
  233. /* Private functions ---------------------------------------------------------*/
  234. /** @addtogroup FLASH_Private_Functions
  235. * @{
  236. */
  237. /**
  238. * @brief Wait for a FLASH operation to complete.
  239. * @param Timeout maximum flash operation timeout
  240. * @retval HAL_StatusTypeDef HAL Status
  241. */
  242. static HAL_StatusTypeDef FLASH_WaitForLastOperation(uint32_t Timeout)
  243. {
  244. /* Wait for the FLASH operation to complete by polling on BUSY flag to be reset.
  245. Even if the FLASH operation fails, the BUSY flag will be reset and an error
  246. flag will be set */
  247. uint32_t timeout = HAL_GetTick() + Timeout;
  248. /* Wait if any operation is ongoing */
  249. while (__HAL_FLASH_GET_FLAG(FLASH_FLAG_BSY) != 0x00U)
  250. {
  251. if (HAL_GetTick() >= timeout)
  252. {
  253. return HAL_TIMEOUT;
  254. }
  255. }
  256. /* Clear SR register */
  257. FLASH->SR = FLASH_FLAG_SR_CLEAR;
  258. return HAL_OK;
  259. }
  260. /**
  261. * @brief Full erase of FLASH memory Bank
  262. *
  263. * @retval None
  264. */
  265. static void FLASH_MassErase(void)
  266. {
  267. /* Clean the error context */
  268. pFlash.ErrorCode = HAL_FLASH_ERROR_NONE;
  269. /* Only bank1 will be erased*/
  270. SET_BIT(FLASH->CR, FLASH_CR_MER);
  271. *(__IO uint32_t *)(0x08000000) = 0x12344321;
  272. }
  273. /**
  274. * @brief Page erase of FLASH memory
  275. *
  276. * @retval None
  277. */
  278. static void FLASH_PageErase(uint32_t PageAddress)
  279. {
  280. /* Clean the error context */
  281. pFlash.ErrorCode = HAL_FLASH_ERROR_NONE;
  282. SET_BIT(FLASH->CR, FLASH_CR_PER);
  283. *(__IO uint32_t *)(PageAddress) = 0xFF;
  284. }
  285. /**
  286. * @brief Sector erase of FLASH memory
  287. *
  288. * @retval None
  289. */
  290. static void FLASH_SectorErase(uint32_t SectorAddress)
  291. {
  292. SET_BIT(FLASH->CR, FLASH_CR_SER);
  293. *(__IO uint32_t *)(SectorAddress) = 0xFF;
  294. }
  295. /**
  296. * @brief Page program of FLASH memory
  297. *
  298. * @retval None
  299. */
  300. static void FLASH_Program_Page(uint32_t Address, uint32_t * DataAddress)
  301. {
  302. uint8_t index=0;
  303. uint32_t dest = Address;
  304. uint32_t * src = DataAddress;
  305. uint32_t primask_bit;
  306. SET_BIT(FLASH->CR, FLASH_CR_PG);
  307. /* Enter critical section */
  308. primask_bit = __get_PRIMASK();
  309. __disable_irq();
  310. /* 32 words*/
  311. while(index<32U)
  312. {
  313. *(uint32_t *)dest = *src;
  314. src += 1U;
  315. dest += 4U;
  316. index++;
  317. if(index==31)
  318. {
  319. SET_BIT(FLASH->CR, FLASH_CR_PGSTRT);
  320. }
  321. }
  322. /* Exit critical section: restore previous priority mask */
  323. __set_PRIMASK(primask_bit);
  324. }
  325. /**
  326. * @}
  327. */
  328. /** @addtogroup FLASH_Exported_Functions
  329. * @{
  330. */
  331. /** @defgroup FLASH_Exported_Functions_Group1 Programming operation functions
  332. * @brief Programming operation functions
  333. *
  334. @verbatim
  335. ===============================================================================
  336. ##### Programming operation functions #####
  337. ===============================================================================
  338. [..]
  339. This subsection provides a set of functions allowing to manage the FLASH
  340. program operations.
  341. @endverbatim
  342. * @{
  343. */
  344. /**
  345. * @brief Perform a mass erase or erase the specified FLASH memory pages
  346. * @note To correctly run this function, the @ref HAL_FLASH_Unlock() function
  347. * must be called before.
  348. * Call the @ref HAL_FLASH_Lock() to disable the flash memory access
  349. * (recommended to protect the FLASH memory against possible unwanted operation)
  350. * @param[in] pEraseInit pointer to an FLASH_EraseInitTypeDef structure that
  351. * contains the configuration information for the erasing.
  352. *
  353. * @param[out] PageSectorError pointer to variable that
  354. * contains the configuration information on faulty page or sector in case of error
  355. * (0xFFFFFFFF means that all the pages or sectors have been correctly erased)
  356. *
  357. * @retval HAL_StatusTypeDef HAL Status
  358. */
  359. HAL_StatusTypeDef HAL_FLASH_Erase(FLASH_EraseInitTypeDef *pEraseInit, uint32_t *PageSectorError)
  360. {
  361. HAL_StatusTypeDef status = HAL_ERROR;
  362. uint32_t address = 0U;
  363. /* Process Locked */
  364. __HAL_LOCK(&pFlash);
  365. /* Config flash timming */
  366. __HAL_FLASH_TIMMING_SEQUENCE_CONFIG();
  367. /* Check the parameters */
  368. assert_param(IS_FLASH_TYPEERASE(pEraseInit->TypeErase));
  369. if (pEraseInit->TypeErase == FLASH_TYPEERASE_MASSERASE)
  370. {
  371. /* Mass Erase requested for Bank1 */
  372. /* Wait for last operation to be completed */
  373. if (FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE) == HAL_OK)
  374. {
  375. /*Mass erase to be done*/
  376. FLASH_MassErase();
  377. /* Wait for last operation to be completed */
  378. status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE);
  379. /* If the erase operation is completed, disable the MER Bit */
  380. CLEAR_BIT(FLASH->CR, FLASH_CR_MER);
  381. }
  382. }else if(pEraseInit->TypeErase == FLASH_TYPEERASE_PAGEERASE)
  383. {
  384. /* Page Erase is requested */
  385. /* Check the parameters */
  386. assert_param(IS_FLASH_PROGRAM_ADDRESS(pEraseInit->PageAddress));
  387. assert_param(IS_FLASH_NB_PAGES(pEraseInit->PageAddress, pEraseInit->NbPages));
  388. /* Wait for last operation to be completed */
  389. if (FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE) == HAL_OK)
  390. {
  391. /*Initialization of PageSectorError variable*/
  392. *PageSectorError = 0xFFFFFFFFU;
  393. /* Erase page by page to be done*/
  394. for(address = pEraseInit->PageAddress;
  395. address < ((pEraseInit->NbPages * FLASH_PAGE_SIZE) + pEraseInit->PageAddress);
  396. address += FLASH_PAGE_SIZE)
  397. {
  398. FLASH_PageErase(address);
  399. /* Wait for last operation to be completed */
  400. status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE);
  401. /* If the erase operation is completed, disable the PER Bit */
  402. CLEAR_BIT(FLASH->CR, FLASH_CR_PER);
  403. if (status != HAL_OK)
  404. {
  405. /* In case of error, stop erase procedure and return the faulty address */
  406. *PageSectorError = address;
  407. break;
  408. }
  409. }
  410. }
  411. }
  412. else if(pEraseInit->TypeErase == FLASH_TYPEERASE_SECTORERASE)
  413. {
  414. /* Sector Erase is requested */
  415. /* Check the parameters */
  416. assert_param(IS_FLASH_PROGRAM_ADDRESS(pEraseInit->SectorAddress));
  417. assert_param(IS_FLASH_NB_SECTORS(pEraseInit->SectorAddress, pEraseInit->NbSectors));
  418. /* Wait for last operation to be completed */
  419. if (FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE) == HAL_OK)
  420. {
  421. /*Initialization of PageSectorError variable*/
  422. *PageSectorError = 0xFFFFFFFFU;
  423. /* Erase page by page to be done*/
  424. for(address = pEraseInit->SectorAddress;
  425. address < ((pEraseInit->NbSectors * FLASH_SECTOR_SIZE) + pEraseInit->SectorAddress);
  426. address += FLASH_SECTOR_SIZE)
  427. {
  428. FLASH_SectorErase(address);
  429. /* Wait for last operation to be completed */
  430. status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE);
  431. /* If the erase operation is completed, disable the SER Bit */
  432. CLEAR_BIT(FLASH->CR, FLASH_CR_SER);
  433. if (status != HAL_OK)
  434. {
  435. /* In case of error, stop erase procedure and return the faulty address */
  436. *PageSectorError = address;
  437. break;
  438. }
  439. }
  440. }
  441. }
  442. /* Process Unlocked */
  443. __HAL_UNLOCK(&pFlash);
  444. return status;
  445. }
  446. /**
  447. * @brief Perform a mass erase or erase the specified FLASH memory pages with interrupt enabled.
  448. * @param pEraseInit Pointer to an @ref FLASH_EraseInitTypeDef structure that
  449. * contains the configuration information for the erasing.
  450. * @retval HAL Status
  451. */
  452. HAL_StatusTypeDef HAL_FLASH_Erase_IT(FLASH_EraseInitTypeDef *pEraseInit)
  453. {
  454. HAL_StatusTypeDef status;
  455. /* Check the parameters */
  456. assert_param(IS_FLASH_TYPEERASE(pEraseInit->TypeErase));
  457. /* Process Locked */
  458. __HAL_LOCK(&pFlash);
  459. /* Config flash timming */
  460. __HAL_FLASH_TIMMING_SEQUENCE_CONFIG();
  461. /* Reset error code */
  462. pFlash.ErrorCode = HAL_FLASH_ERROR_NONE;
  463. /* save procedure for interrupt treatment */
  464. pFlash.ProcedureOnGoing = pEraseInit->TypeErase;
  465. /* Wait for last operation to be completed */
  466. status = FLASH_WaitForLastOperation(FLASH_TIMEOUT_VALUE);
  467. if (status != HAL_OK)
  468. {
  469. /* Process Unlocked */
  470. __HAL_UNLOCK(&pFlash);
  471. }
  472. else
  473. {
  474. /* Enable End of Operation and Error interrupts */
  475. FLASH->CR |= FLASH_CR_EOPIE | FLASH_CR_ERRIE;
  476. if (pEraseInit->TypeErase == FLASH_TYPEERASE_MASSERASE)
  477. {
  478. /* Set Page to 0 for Interrupt callback management */
  479. pFlash.PageOrSector = 0;
  480. /* Proceed to Mass Erase */
  481. FLASH_MassErase();
  482. }else if (pEraseInit->TypeErase == FLASH_TYPEERASE_PAGEERASE)
  483. {
  484. /* Erase by page to be done */
  485. pFlash.NbPagesSectorsToErase = pEraseInit->NbPages;
  486. pFlash.PageOrSector = pEraseInit->PageAddress;
  487. /*Erase 1st page and wait for IT */
  488. FLASH_PageErase(pEraseInit->PageAddress);
  489. }else if (pEraseInit->TypeErase == FLASH_TYPEERASE_SECTORERASE)
  490. {
  491. /* Erase by sector to be done */
  492. pFlash.NbPagesSectorsToErase = pEraseInit->NbSectors;
  493. pFlash.PageOrSector = pEraseInit->SectorAddress;
  494. FLASH_SectorErase(pEraseInit->SectorAddress);
  495. }
  496. }
  497. /* return status */
  498. return status;
  499. }
  500. /**
  501. * @brief Program of a page at a specified address.
  502. * @param Address Specifies the address to be programmed.
  503. * @param DataAddr Page Start Address
  504. *
  505. * @retval HAL_StatusTypeDef HAL Status
  506. */
  507. HAL_StatusTypeDef HAL_FLASH_PageProgram(uint32_t Address, uint32_t * DataAddr )
  508. {
  509. return HAL_FLASH_Program(FLASH_TYPEPROGRAM_PAGE, Address, DataAddr);
  510. }
  511. /**
  512. * @brief Program of a page at a specified address.
  513. * @param TypeProgram Indicate the way to program at a specified address.
  514. * This parameter can be a value of @ref FLASH_Type_Program
  515. * @param Address Specifies the address to be programmed.
  516. * @param DataAddr Page Start Address
  517. *
  518. * @retval HAL_StatusTypeDef HAL Status
  519. */
  520. HAL_StatusTypeDef HAL_FLASH_Program(uint32_t TypeProgram, uint32_t Address, uint32_t * DataAddr )
  521. {
  522. HAL_StatusTypeDef status = HAL_ERROR;
  523. /* Process Locked */
  524. __HAL_LOCK(&pFlash);
  525. /* Config flash timming */
  526. __HAL_FLASH_TIMMING_SEQUENCE_CONFIG();
  527. /* Check the parameters */
  528. assert_param(IS_FLASH_TYPEPROGRAM(TypeProgram));
  529. assert_param(IS_FLASH_PROGRAM_ADDRESS(Address));
  530. /* must be the first address of the PAGE */
  531. if(Address%FLASH_PAGE_SIZE)
  532. {
  533. return HAL_ERROR;
  534. }
  535. /* Wait for last operation to be completed */
  536. status = FLASH_WaitForLastOperation(FLASH_TIMEOUT_VALUE);
  537. if(status == HAL_OK)
  538. {
  539. FLASH_Program_Page(Address, DataAddr);
  540. /* Wait for last operation to be completed */
  541. status = FLASH_WaitForLastOperation(FLASH_TIMEOUT_VALUE);
  542. /* If the program operation is completed, disable the PG Bit */
  543. CLEAR_BIT(FLASH->CR, FLASH_CR_PG);
  544. /* In case of error, stop programming procedure */
  545. if (status != HAL_OK)
  546. {
  547. return status;
  548. }
  549. }
  550. /* Process Unlocked */
  551. __HAL_UNLOCK(&pFlash);
  552. return status;
  553. }
  554. /**
  555. * @brief Program of a page at a specified address with interrupt enabled.
  556. * @param Address Specifies the address to be programmed.
  557. * @param DataAddr Specifies the buffer address to be programmed.
  558. *
  559. * @retval HAL Status
  560. */
  561. HAL_StatusTypeDef HAL_FLASH_PageProgram_IT(uint32_t Address, uint32_t *DataAddr)
  562. {
  563. return HAL_FLASH_Program_IT(FLASH_TYPEPROGRAM_PAGE, Address, DataAddr);
  564. }
  565. /**
  566. * @brief Program of a page at a specified address with interrupt enabled.
  567. * @param TypeProgram Indicate the way to program at a specified address.
  568. * This parameter can be a value of @ref FLASH_Type_Program
  569. * @param Address Specifies the address to be programmed.
  570. * @param DataAddr Specifies the buffer address to be programmed.
  571. *
  572. * @retval HAL Status
  573. */
  574. HAL_StatusTypeDef HAL_FLASH_Program_IT(uint32_t TypeProgram, uint32_t Address, uint32_t *DataAddr)
  575. {
  576. HAL_StatusTypeDef status;
  577. /* Check the parameters */
  578. assert_param(IS_FLASH_TYPEPROGRAM(TypeProgram));
  579. assert_param(IS_FLASH_PROGRAM_ADDRESS(Address));
  580. /* Process Locked */
  581. __HAL_LOCK(&pFlash);
  582. /* Config flash timming */
  583. __HAL_FLASH_TIMMING_SEQUENCE_CONFIG();
  584. /* Reset error code */
  585. pFlash.ErrorCode = HAL_FLASH_ERROR_NONE;
  586. /* Wait for last operation to be completed */
  587. status = FLASH_WaitForLastOperation(FLASH_TIMEOUT_VALUE);
  588. if (status != HAL_OK)
  589. {
  590. /* Process Unlocked */
  591. __HAL_UNLOCK(&pFlash);
  592. }else
  593. {
  594. /* Set internal variables used by the IRQ handler */
  595. pFlash.ProcedureOnGoing = TypeProgram;
  596. pFlash.Address = Address;
  597. /* Enable End of Operation and Error interrupts */
  598. __HAL_FLASH_ENABLE_IT(FLASH_IT_EOP | FLASH_IT_OPERR);
  599. FLASH_Program_Page(Address, DataAddr);
  600. }
  601. /* return status */
  602. return status;
  603. }
  604. /**
  605. * @}
  606. */
  607. /**
  608. * @}
  609. */
  610. /** @addtogroup FLASH_Exported_Functions
  611. * @{
  612. */
  613. /** @addtogroup FLASH_Exported_Functions_Group2
  614. * @{
  615. */
  616. /**
  617. * @brief Set the read protection level.
  618. * @param ReadProtectLevel specifies the read protection level.
  619. * This parameter can be one of the following values:
  620. * @arg @ref OB_RDP_LEVEL_0 No protection
  621. * @arg @ref OB_RDP_LEVEL_1 Read protection of the memory
  622. *
  623. * @note Warning: When enabling OB_RDP level 2 it's no more possible to go back to level 1 or 0
  624. * @retval HAL status
  625. */
  626. HAL_StatusTypeDef HAL_FLASH_OB_RDP_LevelConfig(uint8_t ReadProtectLevel)
  627. {
  628. HAL_StatusTypeDef status = HAL_OK;
  629. /* Check the parameters */
  630. assert_param(IS_OB_RDP_LEVEL(ReadProtectLevel));
  631. /* Wait for last operation to be completed */
  632. status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE);
  633. if(status == HAL_OK)
  634. {
  635. /* Process Locked */
  636. __HAL_LOCK(&pFlash);
  637. /* Clean the error context */
  638. pFlash.ErrorCode = HAL_FLASH_ERROR_NONE;
  639. /* If the previous operation is completed, proceed to erase the option bytes */
  640. SET_BIT(FLASH->OPTR, ReadProtectLevel);
  641. /* starts to modify Flash Option bytes */
  642. FLASH->CR|=FLASH_CR_OPTSTRT;
  643. /* set bit EOPIE */
  644. FLASH->CR|=FLASH_CR_EOPIE;
  645. /* trigger program */
  646. *((__IO uint32_t *)(0x40022080))=0xff;
  647. /* Wait for last operation to be completed */
  648. status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE);
  649. /* Process Unlocked */
  650. __HAL_UNLOCK(&pFlash);
  651. }
  652. return status;
  653. }
  654. /**
  655. * @}
  656. */
  657. /**
  658. * @}
  659. */
  660. /** @addtogroup FLASH_Private_Functions
  661. * @{
  662. */
  663. /**
  664. * @brief Return the FLASH User Option Byte value.
  665. * @retval The FLASH User Option Bytes values. It will be a combination of all the following values:
  666. * @arg @ref FLASH_OB_USER_BOR_ENABLE
  667. * @arg @ref FLASH_OB_USER_BOR_LEVEL
  668. * @arg @ref FLASH_OB_USER_RESET_CONFIG
  669. * @arg @ref FLASH_OB_USER_IWDG_SW
  670. * @arg @ref FLASH_OB_USER_WWDG_SW
  671. * @arg @ref FLASH_OB_USER_nBOOT1
  672. */
  673. static uint32_t FLASH_OB_GetUser(void)
  674. {
  675. uint32_t user = ((FLASH->OPTR & ~FLASH_OPTR_RDP) & OB_USER_ALL);
  676. return user;
  677. }
  678. /**
  679. * @brief Return the FLASH Read Protection level.
  680. * @retval FLASH ReadOut Protection Status:
  681. * This return value can be one of the following values:
  682. * @arg @ref OB_RDP_LEVEL_0 No protection
  683. * @arg @ref OB_RDP_LEVEL_1 Read protection of the memory
  684. */
  685. static uint32_t FLASH_OB_GetRDP(void)
  686. {
  687. uint32_t rdplvl = READ_BIT(FLASH->OPTR, FLASH_OPTR_RDP);
  688. if (rdplvl == OB_RDP_LEVEL_0)
  689. {
  690. return (OB_RDP_LEVEL_0);
  691. }else
  692. {
  693. return rdplvl;
  694. }
  695. }
  696. /**
  697. * @brief Set user & RDP configuration
  698. * @param UserType The FLASH User Option Bytes to be modified.
  699. * This parameter can be a combination of @ref FLASH_OB_USER_Type
  700. * @param UserConfig The FLASH User Option Bytes values.
  701. * This parameter can be a combination of:
  702. * @arg @ref FLASH_OB_USER_BOR_ENABLE
  703. * @arg @ref FLASH_OB_USER_BOR_LEVEL
  704. * @arg @ref FLASH_OB_USER_RESET_CONFIG
  705. * @arg @ref FLASH_OB_USER_IWDG_SW
  706. * @arg @ref FLASH_OB_USER_WWDG_SW
  707. * @arg @ref FLASH_OB_USER_nBOOT1
  708. * @param RDPLevel specifies the read protection level.
  709. * This parameter can be one of the following values:
  710. * @arg @ref OB_RDP_LEVEL_0 No protection
  711. * @arg @ref OB_RDP_LEVEL_1 Memory Read protection
  712. * @note (*) availability depends on devices
  713. * @retval None
  714. */
  715. static void FLASH_OB_OptrConfig(uint32_t UserType, uint32_t UserConfig, uint32_t RDPLevel)
  716. {
  717. uint32_t optr;
  718. /* Check the parameters */
  719. assert_param(IS_OB_USER_TYPE(UserType));
  720. assert_param(IS_OB_USER_CONFIG(UserType, UserConfig));
  721. assert_param(IS_OB_RDP_LEVEL(RDPLevel));
  722. /* Configure the RDP level in the option bytes register */
  723. optr = FLASH->OPTR;
  724. optr &= ~(UserType | FLASH_OPTR_RDP);
  725. FLASH->OPTR = (optr | UserConfig | RDPLevel);
  726. }
  727. /**
  728. * @}
  729. */
  730. /** @addtogroup FLASH_Exported_Functions
  731. * @{
  732. */
  733. /** @addtogroup FLASH_Exported_Functions_Group2
  734. * @{
  735. */
  736. /**
  737. * @brief Program option bytes
  738. * @note The function @ref HAL_FLASH_Unlock() should be called before to unlock the FLASH interface
  739. * The function @ref HAL_FLASH_OB_Unlock() should be called before to unlock the options bytes
  740. * The function @ref HAL_FLASH_OB_Launch() should be called after to force the reload of the options bytes
  741. * (system reset will occur)
  742. *
  743. * @param pOBInit pointer to an FLASH_OBInitStruct structure that
  744. * contains the configuration information for the programming.
  745. *
  746. * @retval HAL_StatusTypeDef HAL Status
  747. */
  748. HAL_StatusTypeDef HAL_FLASH_OBProgram(FLASH_OBProgramInitTypeDef *pOBInit)
  749. {
  750. uint32_t optr;
  751. HAL_StatusTypeDef status = HAL_ERROR;
  752. /* Process Locked */
  753. __HAL_LOCK(&pFlash);
  754. /* Config flash timming */
  755. __HAL_FLASH_TIMMING_SEQUENCE_CONFIG();
  756. /* Check the parameters */
  757. assert_param(IS_OPTIONBYTE(pOBInit->OptionType));
  758. /* WRP register */
  759. if ((pOBInit->OptionType & OPTIONBYTE_WRP) != 0)
  760. {
  761. /* Write protection configuration */
  762. FLASH->WRPR = (uint16_t)(~(pOBInit->WRPSector));
  763. }
  764. /* SDK register */
  765. if ((pOBInit->OptionType & OPTIONBYTE_SDK) != 0)
  766. {
  767. /* SDK protection configuration */
  768. FLASH->SDKR = (pOBInit->SDKStartAddr) | (pOBInit->SDKEndAddr<<8);
  769. }
  770. /* Option register */
  771. if ((pOBInit->OptionType & (OPTIONBYTE_RDP | OPTIONBYTE_USER)) == (OPTIONBYTE_RDP | OPTIONBYTE_USER))
  772. {
  773. /* Fully modify OPTR register with RDP & user data */
  774. FLASH_OB_OptrConfig(pOBInit->USERType, pOBInit->USERConfig, pOBInit->RDPLevel);
  775. }
  776. else if((pOBInit->OptionType & OPTIONBYTE_RDP) != 0x00U)
  777. {
  778. /* Only modify RDP so get current user data */
  779. optr = FLASH_OB_GetUser();
  780. FLASH_OB_OptrConfig(optr, optr, pOBInit->RDPLevel);
  781. }
  782. else if ((pOBInit->OptionType & OPTIONBYTE_USER) != 0x00U)
  783. {
  784. /* Only modify user so get current RDP level */
  785. optr = FLASH_OB_GetRDP();
  786. FLASH_OB_OptrConfig(pOBInit->USERType, pOBInit->USERConfig, optr);
  787. }
  788. else
  789. {
  790. /* nothing to do */
  791. }
  792. /* starts to modify Flash Option bytes */
  793. FLASH->CR|=FLASH_CR_OPTSTRT;
  794. /* set bit EOPIE */
  795. FLASH->CR|=FLASH_CR_EOPIE;
  796. /* trigger program */
  797. *((__IO uint32_t *)(0x40022080))=0xff;
  798. /* Wait for last operation to be completed */
  799. status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE);
  800. /* Process Unlocked */
  801. __HAL_UNLOCK(&pFlash);
  802. return status;
  803. }
  804. /**
  805. * @brief Get the Option byte configuration
  806. * @param pOBInit pointer to an FLASH_OBInitStruct structure that
  807. * contains the configuration information for the programming.
  808. *
  809. * @retval None
  810. */
  811. void HAL_FLASH_OBGetConfig(FLASH_OBProgramInitTypeDef *pOBInit)
  812. {
  813. pOBInit->OptionType = OPTIONBYTE_ALL;
  814. /* Get WRP sector */
  815. pOBInit->WRPSector = (uint16_t)(~FLASH->WRPR);
  816. /* Get SDK sector */
  817. pOBInit->SDKStartAddr = (FLASH->SDKR)&0x1F;
  818. pOBInit->SDKEndAddr = ((FLASH->SDKR)&0x1F00)>>8;
  819. /*Get RDP Level*/
  820. if (((FLASH->OPTR)&0xFF) == OB_RDP_LEVEL_0)
  821. {
  822. pOBInit->RDPLevel = OB_RDP_LEVEL_0;
  823. } else
  824. {
  825. pOBInit->RDPLevel = OB_RDP_LEVEL_1;
  826. }
  827. /*Get USER*/
  828. pOBInit->USERType = OB_USER_ALL;
  829. #if defined(FLASH_OPTR_WWDG_SW)
  830. pOBInit->USERConfig = (FLASH->OPTR)&(FLASH_OPTR_WWDG_SW | FLASH_OPTR_IWDG_SW | \
  831. FLASH_OPTR_NRST_MODE |FLASH_OPTR_BOR_EN | \
  832. FLASH_OPTR_BOR_LEV |FLASH_OPTR_nBOOT1);
  833. #else
  834. pOBInit->USERConfig = (FLASH->OPTR)&(FLASH_OPTR_IWDG_SW | \
  835. FLASH_OPTR_NRST_MODE |FLASH_OPTR_BOR_EN | \
  836. FLASH_OPTR_BOR_LEV |FLASH_OPTR_nBOOT1);
  837. #endif
  838. }
  839. /**
  840. * @}
  841. */
  842. /**
  843. * @}
  844. */
  845. /** @addtogroup FLASH_Exported_Functions
  846. * @{
  847. */
  848. /** @addtogroup FLASH_Exported_Functions_Group2
  849. * @{
  850. */
  851. /**
  852. * @brief Handle FLASH interrupt request.
  853. * @retval None
  854. */
  855. void HAL_FLASH_IRQHandler(void)
  856. {
  857. uint32_t param = 0xFFFFFFFFU;
  858. uint32_t error;
  859. /* Save flash errors. Only ECC detection can be checked here as ECCC
  860. generates NMI */
  861. error = (FLASH->SR & FLASH_FLAG_SR_ERROR);
  862. CLEAR_BIT(FLASH->CR, pFlash.ProcedureOnGoing);
  863. /* A] Set parameter for user or error callbacks */
  864. /* check operation was a program or erase */
  865. if ((pFlash.ProcedureOnGoing & (FLASH_TYPEPROGRAM_PAGE)) != 0x00U)
  866. {
  867. /* return adress being programmed */
  868. param = pFlash.Address;
  869. }else if ((pFlash.ProcedureOnGoing & (FLASH_TYPEERASE_MASSERASE | FLASH_TYPEERASE_SECTORERASE | FLASH_TYPEERASE_PAGEERASE)) != 0x00U)
  870. {
  871. /* return page number being erased (0 for mass erase) */
  872. param = pFlash.PageOrSector;
  873. }else
  874. {
  875. /* Nothing to do */
  876. }
  877. /* B] Check errors */
  878. if (error != 0x00U)
  879. {
  880. /*Save the error code*/
  881. pFlash.ErrorCode |= error;
  882. /* clear error flags */
  883. __HAL_FLASH_CLEAR_FLAG(error);
  884. /*Stop the procedure ongoing*/
  885. pFlash.ProcedureOnGoing = FLASH_TYPENONE;
  886. /* Error callback */
  887. HAL_FLASH_OperationErrorCallback(param);
  888. }
  889. /* C] Check FLASH End of Operation flag */
  890. if (__HAL_FLASH_GET_FLAG(FLASH_FLAG_EOP) != 0x00U)
  891. {
  892. /* Clear FLASH End of Operation pending bit */
  893. __HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_EOP);
  894. if (pFlash.ProcedureOnGoing == FLASH_TYPEERASE_PAGEERASE)
  895. {
  896. /* Nb of pages to erased can be decreased */
  897. pFlash.NbPagesSectorsToErase--;
  898. /* Check if there are still pages to erase*/
  899. if (pFlash.NbPagesSectorsToErase != 0x00U)
  900. {
  901. /* Increment page number */
  902. pFlash.PageOrSector += FLASH_PAGE_SIZE;
  903. FLASH_PageErase(pFlash.PageOrSector);
  904. }else
  905. {
  906. /* No more pages to erase: stop erase pages procedure */
  907. pFlash.ProcedureOnGoing = FLASH_TYPENONE;
  908. }
  909. }
  910. else if (pFlash.ProcedureOnGoing == FLASH_TYPEERASE_SECTORERASE)
  911. {
  912. /* Nb of sectors to erased can be decreased */
  913. pFlash.NbPagesSectorsToErase--;
  914. /* Check if there are still pages to erase*/
  915. if (pFlash.NbPagesSectorsToErase != 0x00U)
  916. {
  917. /* Increment page number */
  918. pFlash.PageOrSector += FLASH_SECTOR_SIZE;
  919. FLASH_SectorErase(pFlash.PageOrSector);
  920. }else
  921. {
  922. /* No more pages to erase: stop erase pages procedure */
  923. pFlash.ProcedureOnGoing = FLASH_TYPENONE;
  924. }
  925. }
  926. else
  927. {
  928. /*Stop the ongoing procedure */
  929. pFlash.ProcedureOnGoing = FLASH_TYPENONE;
  930. }
  931. /* User callback */
  932. HAL_FLASH_EndOfOperationCallback(param);
  933. }
  934. if (pFlash.ProcedureOnGoing == FLASH_TYPENONE)
  935. {
  936. /* Disable End of Operation and Error interrupts */
  937. __HAL_FLASH_DISABLE_IT(FLASH_IT_EOP | FLASH_IT_OPERR);
  938. /* Process Unlocked */
  939. __HAL_UNLOCK(&pFlash);
  940. }
  941. }
  942. /**
  943. * @brief FLASH end of operation interrupt callback.
  944. * @param ReturnValue The value saved in this parameter depends on the ongoing procedure
  945. * Mass Erase: 0
  946. * Page Erase: Page which has been erased
  947. * Program: Address which was selected for data program
  948. * @retval None
  949. */
  950. __weak void HAL_FLASH_EndOfOperationCallback(uint32_t ReturnValue)
  951. {
  952. /* Prevent unused argument(s) compilation warning */
  953. UNUSED(ReturnValue);
  954. /* NOTE : This function should not be modified, when the callback is needed,
  955. the HAL_FLASH_EndOfOperationCallback could be implemented in the user file
  956. */
  957. }
  958. /**
  959. * @brief FLASH operation error interrupt callback.
  960. * @param ReturnValue The value saved in this parameter depends on the ongoing procedure
  961. * Mass Erase: 0
  962. * Page Erase: Page number which returned an error
  963. * Program: Address which was selected for data program
  964. * @retval None
  965. */
  966. __weak void HAL_FLASH_OperationErrorCallback(uint32_t ReturnValue)
  967. {
  968. /* Prevent unused argument(s) compilation warning */
  969. UNUSED(ReturnValue);
  970. /* NOTE : This function should not be modified, when the callback is needed,
  971. the HAL_FLASH_OperationErrorCallback could be implemented in the user file
  972. */
  973. }
  974. /**
  975. * @}
  976. */
  977. /**
  978. * @}
  979. */
  980. #endif /* HAL_FLASH_MODULE_ENABLED */
  981. /**
  982. * @}
  983. */
  984. /**
  985. * @}
  986. */
  987. /************************ (C) COPYRIGHT Puya *****END OF FILE****/