py32f002b_hal_flash.c 29 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041
  1. /**
  2. ******************************************************************************
  3. * @file py32f002b_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 PY32F002B_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] = {0x1FFF011C, 0x1FFF011C, 0x1FFF011C, 0x1FFF011C, 0x1FFF011C, 0x1FFF0130, 0x1FFF011C, 0x1FFF011C};
  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. /**
  96. * @}
  97. */
  98. /* Exported functions --------------------------------------------------------*/
  99. /** @defgroup FLASH_Exported_Functions FLASH Exported Functions
  100. * @{
  101. */
  102. /** @defgroup FLASH_Exported_Functions_Group2 Peripheral Control functions
  103. * @brief Management functions
  104. *
  105. @verbatim
  106. ===============================================================================
  107. ##### Peripheral Control functions #####
  108. ===============================================================================
  109. [..]
  110. This subsection provides a set of functions allowing to control the FLASH
  111. memory operations.
  112. @endverbatim
  113. * @{
  114. */
  115. /**
  116. * @brief Unlock the FLASH control register access.
  117. * @retval HAL Status
  118. */
  119. HAL_StatusTypeDef HAL_FLASH_Unlock(void)
  120. {
  121. HAL_StatusTypeDef status = HAL_OK;
  122. if (READ_BIT(FLASH->CR, FLASH_CR_LOCK) != 0x00U)
  123. {
  124. /* Authorize the FLASH Registers access */
  125. WRITE_REG(FLASH->KEYR, FLASH_KEY1);
  126. WRITE_REG(FLASH->KEYR, FLASH_KEY2);
  127. /* verify Flash is unlock */
  128. if (READ_BIT(FLASH->CR, FLASH_CR_LOCK) != 0x00U)
  129. {
  130. status = HAL_ERROR;
  131. }
  132. }
  133. return status;
  134. }
  135. /**
  136. * @brief Lock the FLASH control register access.
  137. * @retval HAL Status
  138. */
  139. HAL_StatusTypeDef HAL_FLASH_Lock(void)
  140. {
  141. HAL_StatusTypeDef status = HAL_ERROR;
  142. /* Set the LOCK Bit to lock the FLASH Registers access */
  143. SET_BIT(FLASH->CR, FLASH_CR_LOCK);
  144. /* verify Flash is locked */
  145. if (READ_BIT(FLASH->CR, FLASH_CR_LOCK) != 0x00u)
  146. {
  147. status = HAL_OK;
  148. }
  149. return status;
  150. }
  151. /**
  152. * @brief Unlock the FLASH Option Bytes Registers access.
  153. * @retval HAL Status
  154. */
  155. HAL_StatusTypeDef HAL_FLASH_OB_Unlock(void)
  156. {
  157. HAL_StatusTypeDef status = HAL_ERROR;
  158. if (READ_BIT(FLASH->CR, FLASH_CR_OPTLOCK) != 0x00U)
  159. {
  160. /* Authorizes the Option Byte register programming */
  161. WRITE_REG(FLASH->OPTKEYR, FLASH_OPTKEY1);
  162. WRITE_REG(FLASH->OPTKEYR, FLASH_OPTKEY2);
  163. /* verify option bytes are unlocked */
  164. if (READ_BIT(FLASH->CR, FLASH_CR_OPTLOCK) == 0x00U)
  165. {
  166. status = HAL_OK;
  167. }
  168. }
  169. return status;
  170. }
  171. /**
  172. * @brief Lock the FLASH Option Bytes Registers access.
  173. * @retval HAL Status
  174. */
  175. HAL_StatusTypeDef HAL_FLASH_OB_Lock(void)
  176. {
  177. HAL_StatusTypeDef status = HAL_ERROR;
  178. /* Set the OPTLOCK Bit to lock the FLASH Option Byte Registers access */
  179. SET_BIT(FLASH->CR, FLASH_CR_OPTLOCK);
  180. /* verify option bytes are locked */
  181. if (READ_BIT(FLASH->CR, FLASH_CR_OPTLOCK) != 0x00u)
  182. {
  183. status = HAL_OK;
  184. }
  185. return status;
  186. }
  187. /**
  188. * @brief Launch the option byte loading.
  189. * @retval HAL Status
  190. */
  191. HAL_StatusTypeDef HAL_FLASH_OB_Launch(void)
  192. {
  193. /* Set the bit to force the option byte reloading */
  194. SET_BIT(FLASH->CR, FLASH_CR_OBL_LAUNCH);
  195. /* We should not reach here : Option byte launch generates Option byte reset
  196. so return error */
  197. return HAL_ERROR;
  198. }
  199. /**
  200. * @}
  201. */
  202. /** @defgroup FLASH_Exported_Functions_Group3 Peripheral State and Errors functions
  203. * @brief Peripheral Errors functions
  204. *
  205. @verbatim
  206. ===============================================================================
  207. ##### Peripheral Errors functions #####
  208. ===============================================================================
  209. [..]
  210. This subsection permits to get in run-time Errors of the FLASH peripheral.
  211. @endverbatim
  212. * @{
  213. */
  214. /**
  215. * @brief Get the specific FLASH error flag.
  216. * @retval FLASH_ErrorCode The returned value can be
  217. * @arg @ref HAL_FLASH_ERROR_NONE No error set
  218. * @arg @ref HAL_FLASH_ERROR_WRP FLASH Write protection error
  219. * @arg @ref HAL_FLASH_ERROR_OPTV FLASH Option validity error
  220. * @note (*) availability depends on devices
  221. */
  222. uint32_t HAL_FLASH_GetError(void)
  223. {
  224. return pFlash.ErrorCode;
  225. }
  226. /**
  227. * @}
  228. */
  229. /**
  230. * @}
  231. */
  232. /* Private functions ---------------------------------------------------------*/
  233. /** @addtogroup FLASH_Private_Functions
  234. * @{
  235. */
  236. /**
  237. * @brief Wait for a FLASH operation to complete.
  238. * @param Timeout maximum flash operation timeout
  239. * @retval HAL_StatusTypeDef HAL Status
  240. */
  241. HAL_StatusTypeDef FLASH_WaitForLastOperation(uint32_t Timeout)
  242. {
  243. /* Wait for the FLASH operation to complete by polling on BUSY flag to be reset.
  244. Even if the FLASH operation fails, the BUSY flag will be reset and an error
  245. flag will be set */
  246. uint32_t timeout = HAL_GetTick() + Timeout;
  247. /* Wait if any operation is ongoing */
  248. while (__HAL_FLASH_GET_FLAG(FLASH_FLAG_BSY) != 0x00U)
  249. {
  250. if (HAL_GetTick() >= timeout)
  251. {
  252. return HAL_TIMEOUT;
  253. }
  254. }
  255. /* Clear SR register */
  256. FLASH->SR = FLASH_FLAG_SR_CLEAR;
  257. return HAL_OK;
  258. }
  259. /**
  260. * @brief Full erase of FLASH memory Bank
  261. *
  262. * @retval None
  263. */
  264. static void FLASH_MassErase(void)
  265. {
  266. /* Clean the error context */
  267. pFlash.ErrorCode = HAL_FLASH_ERROR_NONE;
  268. /* Only bank1 will be erased*/
  269. SET_BIT(FLASH->CR, FLASH_CR_MER);
  270. *(__IO uint32_t *)(0x08000000) = 0x12344321;
  271. }
  272. /**
  273. * @brief Page erase of FLASH memory
  274. *
  275. * @retval None
  276. */
  277. static void FLASH_PageErase(uint32_t PageAddress)
  278. {
  279. /* Clean the error context */
  280. pFlash.ErrorCode = HAL_FLASH_ERROR_NONE;
  281. SET_BIT(FLASH->CR, FLASH_CR_PER);
  282. *(__IO uint32_t *)(PageAddress) = 0xFF;
  283. }
  284. /**
  285. * @brief Sector erase of FLASH memory
  286. *
  287. * @retval None
  288. */
  289. static void FLASH_SectorErase(uint32_t SectorAddress)
  290. {
  291. SET_BIT(FLASH->CR, FLASH_CR_SER);
  292. *(__IO uint32_t *)(SectorAddress) = 0xFF;
  293. }
  294. /**
  295. * @brief Page program of FLASH memory
  296. *
  297. * @retval None
  298. */
  299. static void FLASH_Program_Page(uint32_t Address, uint32_t * DataAddress)
  300. {
  301. uint8_t index=0;
  302. uint32_t dest = Address;
  303. uint32_t * src = DataAddress;
  304. uint32_t primask_bit;
  305. SET_BIT(FLASH->CR, FLASH_CR_PG);
  306. /* Enter critical section */
  307. primask_bit = __get_PRIMASK();
  308. __disable_irq();
  309. /* 32 words*/
  310. while(index<32U)
  311. {
  312. *(uint32_t *)dest = *src;
  313. src += 1U;
  314. dest += 4U;
  315. index++;
  316. if(index==31)
  317. {
  318. SET_BIT(FLASH->CR, FLASH_CR_PGSTRT);
  319. }
  320. }
  321. /* Exit critical section: restore previous priority mask */
  322. __set_PRIMASK(primask_bit);
  323. }
  324. /**
  325. * @}
  326. */
  327. /** @addtogroup FLASH_Exported_Functions
  328. * @{
  329. */
  330. /** @defgroup FLASH_Exported_Functions_Group1 Programming operation functions
  331. * @brief Programming operation functions
  332. *
  333. @verbatim
  334. ===============================================================================
  335. ##### Programming operation functions #####
  336. ===============================================================================
  337. [..]
  338. This subsection provides a set of functions allowing to manage the FLASH
  339. program operations.
  340. @endverbatim
  341. * @{
  342. */
  343. /**
  344. * @brief Perform a mass erase or erase the specified FLASH memory pages
  345. * @note To correctly run this function, the @ref HAL_FLASH_Unlock() function
  346. * must be called before.
  347. * Call the @ref HAL_FLASH_Lock() to disable the flash memory access
  348. * (recommended to protect the FLASH memory against possible unwanted operation)
  349. * @param[in] pEraseInit pointer to an FLASH_EraseInitTypeDef structure that
  350. * contains the configuration information for the erasing.
  351. *
  352. * @param[out] PageSectorError pointer to variable that
  353. * contains the configuration information on faulty page or sector in case of error
  354. * (0xFFFFFFFF means that all the pages or sectors have been correctly erased)
  355. *
  356. * @retval HAL_StatusTypeDef HAL Status
  357. */
  358. HAL_StatusTypeDef HAL_FLASH_Erase(FLASH_EraseInitTypeDef *pEraseInit, uint32_t *PageSectorError)
  359. {
  360. HAL_StatusTypeDef status = HAL_ERROR;
  361. uint32_t address = 0U;
  362. /* Process Locked */
  363. __HAL_LOCK(&pFlash);
  364. /* Config flash timming */
  365. __HAL_FLASH_TIMMING_SEQUENCE_CONFIG();
  366. /* Check the parameters */
  367. assert_param(IS_FLASH_TYPEERASE(pEraseInit->TypeErase));
  368. if (pEraseInit->TypeErase == FLASH_TYPEERASE_MASSERASE)
  369. {
  370. /* Mass Erase requested for Bank1 */
  371. /* Wait for last operation to be completed */
  372. if (FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE) == HAL_OK)
  373. {
  374. /*Mass erase to be done*/
  375. FLASH_MassErase();
  376. /* Wait for last operation to be completed */
  377. status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE);
  378. /* If the erase operation is completed, disable the MER Bit */
  379. CLEAR_BIT(FLASH->CR, FLASH_CR_MER);
  380. }
  381. }else if(pEraseInit->TypeErase == FLASH_TYPEERASE_PAGEERASE)
  382. {
  383. /* Page Erase is requested */
  384. /* Check the parameters */
  385. assert_param(IS_FLASH_PROGRAM_ADDRESS(pEraseInit->PageAddress));
  386. assert_param(IS_FLASH_NB_PAGES(pEraseInit->PageAddress, pEraseInit->NbPages));
  387. /* Wait for last operation to be completed */
  388. if (FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE) == HAL_OK)
  389. {
  390. /*Initialization of PageSectorError variable*/
  391. *PageSectorError = 0xFFFFFFFFU;
  392. /* Erase page by page to be done*/
  393. for(address = pEraseInit->PageAddress;
  394. address < ((pEraseInit->NbPages * FLASH_PAGE_SIZE) + pEraseInit->PageAddress);
  395. address += FLASH_PAGE_SIZE)
  396. {
  397. FLASH_PageErase(address);
  398. /* Wait for last operation to be completed */
  399. status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE);
  400. /* If the erase operation is completed, disable the PER Bit */
  401. CLEAR_BIT(FLASH->CR, FLASH_CR_PER);
  402. if (status != HAL_OK)
  403. {
  404. /* In case of error, stop erase procedure and return the faulty address */
  405. *PageSectorError = address;
  406. break;
  407. }
  408. }
  409. }
  410. }
  411. else if(pEraseInit->TypeErase == FLASH_TYPEERASE_SECTORERASE)
  412. {
  413. /* Sector Erase is requested */
  414. /* Check the parameters */
  415. assert_param(IS_FLASH_PROGRAM_ADDRESS(pEraseInit->SectorAddress));
  416. assert_param(IS_FLASH_NB_SECTORS(pEraseInit->SectorAddress, pEraseInit->NbSectors));
  417. /* Wait for last operation to be completed */
  418. if (FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE) == HAL_OK)
  419. {
  420. /*Initialization of PageSectorError variable*/
  421. *PageSectorError = 0xFFFFFFFFU;
  422. /* Erase page by page to be done*/
  423. for(address = pEraseInit->SectorAddress;
  424. address < ((pEraseInit->NbSectors * FLASH_SECTOR_SIZE) + pEraseInit->SectorAddress);
  425. address += FLASH_SECTOR_SIZE)
  426. {
  427. FLASH_SectorErase(address);
  428. /* Wait for last operation to be completed */
  429. status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE);
  430. /* If the erase operation is completed, disable the SER Bit */
  431. CLEAR_BIT(FLASH->CR, FLASH_CR_SER);
  432. if (status != HAL_OK)
  433. {
  434. /* In case of error, stop erase procedure and return the faulty address */
  435. *PageSectorError = address;
  436. break;
  437. }
  438. }
  439. }
  440. }
  441. /* Process Unlocked */
  442. __HAL_UNLOCK(&pFlash);
  443. return status;
  444. }
  445. /**
  446. * @brief Perform a mass erase or erase the specified FLASH memory pages with interrupt enabled.
  447. * @param pEraseInit Pointer to an @ref FLASH_EraseInitTypeDef structure that
  448. * contains the configuration information for the erasing.
  449. * @retval HAL Status
  450. */
  451. HAL_StatusTypeDef HAL_FLASH_Erase_IT(FLASH_EraseInitTypeDef *pEraseInit)
  452. {
  453. HAL_StatusTypeDef status;
  454. /* Check the parameters */
  455. assert_param(IS_FLASH_TYPEERASE(pEraseInit->TypeErase));
  456. /* Process Locked */
  457. __HAL_LOCK(&pFlash);
  458. /* Config flash timming */
  459. __HAL_FLASH_TIMMING_SEQUENCE_CONFIG();
  460. /* Reset error code */
  461. pFlash.ErrorCode = HAL_FLASH_ERROR_NONE;
  462. /* save procedure for interrupt treatment */
  463. pFlash.ProcedureOnGoing = pEraseInit->TypeErase;
  464. /* Wait for last operation to be completed */
  465. status = FLASH_WaitForLastOperation(FLASH_TIMEOUT_VALUE);
  466. if (status != HAL_OK)
  467. {
  468. /* Process Unlocked */
  469. __HAL_UNLOCK(&pFlash);
  470. }
  471. else
  472. {
  473. /* Enable End of Operation and Error interrupts */
  474. FLASH->CR |= FLASH_CR_EOPIE | FLASH_CR_ERRIE;
  475. if (pEraseInit->TypeErase == FLASH_TYPEERASE_MASSERASE)
  476. {
  477. /* Set Page to 0 for Interrupt callback management */
  478. pFlash.PageOrSector = 0;
  479. /* Proceed to Mass Erase */
  480. FLASH_MassErase();
  481. }else if (pEraseInit->TypeErase == FLASH_TYPEERASE_PAGEERASE)
  482. {
  483. /* Erase by page to be done */
  484. pFlash.NbPagesSectorsToErase = pEraseInit->NbPages;
  485. pFlash.PageOrSector = pEraseInit->PageAddress;
  486. /*Erase 1st page and wait for IT */
  487. FLASH_PageErase(pEraseInit->PageAddress);
  488. }else if (pEraseInit->TypeErase == FLASH_TYPEERASE_SECTORERASE)
  489. {
  490. /* Erase by sector to be done */
  491. pFlash.NbPagesSectorsToErase = pEraseInit->NbSectors;
  492. pFlash.PageOrSector = pEraseInit->SectorAddress;
  493. FLASH_SectorErase(pEraseInit->SectorAddress);
  494. }
  495. }
  496. /* return status */
  497. return status;
  498. }
  499. /**
  500. * @brief Program of a page at a specified address.
  501. * @param Address Specifies the address to be programmed.
  502. * @param DataAddr Page Start Address
  503. *
  504. * @retval HAL_StatusTypeDef HAL Status
  505. */
  506. HAL_StatusTypeDef HAL_FLASH_PageProgram(uint32_t Address, uint32_t * DataAddr )
  507. {
  508. return HAL_FLASH_Program(FLASH_TYPEPROGRAM_PAGE, Address, DataAddr);
  509. }
  510. /**
  511. * @brief Program of a page at a specified address.
  512. * @param TypeProgram Indicate the way to program at a specified address.
  513. * This parameter can be a value of @ref FLASH_Type_Program
  514. * @param Address Specifies the address to be programmed.
  515. * @param DataAddr Page Start Address
  516. *
  517. * @retval HAL_StatusTypeDef HAL Status
  518. */
  519. HAL_StatusTypeDef HAL_FLASH_Program(uint32_t TypeProgram, uint32_t Address, uint32_t * DataAddr )
  520. {
  521. HAL_StatusTypeDef status = HAL_ERROR;
  522. /* Process Locked */
  523. __HAL_LOCK(&pFlash);
  524. /* Config flash timming */
  525. __HAL_FLASH_TIMMING_SEQUENCE_CONFIG();
  526. /* Check the parameters */
  527. assert_param(IS_FLASH_TYPEPROGRAM(TypeProgram));
  528. assert_param(IS_FLASH_PROGRAM_ADDRESS(Address));
  529. /* must be the first address of the PAGE */
  530. if(Address%FLASH_PAGE_SIZE)
  531. {
  532. return HAL_ERROR;
  533. }
  534. /* Wait for last operation to be completed */
  535. status = FLASH_WaitForLastOperation(FLASH_TIMEOUT_VALUE);
  536. if(status == HAL_OK)
  537. {
  538. FLASH_Program_Page(Address, DataAddr);
  539. /* Wait for last operation to be completed */
  540. status = FLASH_WaitForLastOperation(FLASH_TIMEOUT_VALUE);
  541. /* If the program operation is completed, disable the PG Bit */
  542. CLEAR_BIT(FLASH->CR, FLASH_CR_PG);
  543. /* In case of error, stop programming procedure */
  544. if (status != HAL_OK)
  545. {
  546. return status;
  547. }
  548. }
  549. /* Process Unlocked */
  550. __HAL_UNLOCK(&pFlash);
  551. return status;
  552. }
  553. /**
  554. * @brief Program of a page at a specified address with interrupt enabled.
  555. * @param Address Specifies the address to be programmed.
  556. * @param DataAddr Specifies the buffer address to be programmed.
  557. *
  558. * @retval HAL Status
  559. */
  560. HAL_StatusTypeDef HAL_FLASH_PageProgram_IT(uint32_t Address, uint32_t *DataAddr)
  561. {
  562. return HAL_FLASH_Program_IT(FLASH_TYPEPROGRAM_PAGE, Address, DataAddr);
  563. }
  564. /**
  565. * @brief Program of a page at a specified address with interrupt enabled.
  566. * @param TypeProgram Indicate the way to program at a specified address.
  567. * This parameter can be a value of @ref FLASH_Type_Program
  568. * @param Address Specifies the address to be programmed.
  569. * @param DataAddr Specifies the buffer address to be programmed.
  570. *
  571. * @retval HAL Status
  572. */
  573. HAL_StatusTypeDef HAL_FLASH_Program_IT(uint32_t TypeProgram, uint32_t Address, uint32_t *DataAddr)
  574. {
  575. HAL_StatusTypeDef status;
  576. /* Check the parameters */
  577. assert_param(IS_FLASH_TYPEPROGRAM(TypeProgram));
  578. assert_param(IS_FLASH_PROGRAM_ADDRESS(Address));
  579. /* Process Locked */
  580. __HAL_LOCK(&pFlash);
  581. /* Config flash timming */
  582. __HAL_FLASH_TIMMING_SEQUENCE_CONFIG();
  583. /* Reset error code */
  584. pFlash.ErrorCode = HAL_FLASH_ERROR_NONE;
  585. /* Wait for last operation to be completed */
  586. status = FLASH_WaitForLastOperation(FLASH_TIMEOUT_VALUE);
  587. if (status != HAL_OK)
  588. {
  589. /* Process Unlocked */
  590. __HAL_UNLOCK(&pFlash);
  591. }else
  592. {
  593. /* Set internal variables used by the IRQ handler */
  594. pFlash.ProcedureOnGoing = TypeProgram;
  595. pFlash.Address = Address;
  596. /* Enable End of Operation and Error interrupts */
  597. __HAL_FLASH_ENABLE_IT(FLASH_IT_EOP | FLASH_IT_OPERR);
  598. FLASH_Program_Page(Address, DataAddr);
  599. }
  600. /* return status */
  601. return status;
  602. }
  603. /**
  604. * @brief Set User configuration
  605. * @param UserType The FLASH User Option Bytes to be modified.
  606. * This parameter can be a combination of @ref FLASH_OB_USER_Type
  607. * @param UserConfig The FLASH User Option Bytes values.
  608. * This parameter can be a combination of:
  609. * @arg @ref FLASH_OB_USER_BOR_ENABLE
  610. * @arg @ref FLASH_OB_USER_BOR_LEVEL
  611. * @arg @ref FLASH_OB_USER_IWDG_STOP
  612. * @arg @ref FLASH_OB_USER_IWDG_SW
  613. * @arg @ref FLASH_OB_USER_SWD_NRST
  614. * @retval None
  615. */
  616. static void FLASH_OB_OptrConfig(uint32_t UserType, uint32_t UserConfig)
  617. {
  618. uint32_t optr;
  619. /* Check the parameters */
  620. assert_param(IS_OB_USER_TYPE(UserType));
  621. assert_param(IS_OB_USER_CONFIG(UserType, UserConfig));
  622. optr = FLASH->OPTR;
  623. optr &= ~(UserType | 0xff);
  624. FLASH->OPTR = (optr | UserConfig | 0xAA);
  625. }
  626. /**
  627. * @brief Program option bytes
  628. * @note The function @ref HAL_FLASH_Unlock() should be called before to unlock the FLASH interface
  629. * The function @ref HAL_FLASH_OB_Unlock() should be called before to unlock the options bytes
  630. * The function @ref HAL_FLASH_OB_Launch() should be called after to force the reload of the options bytes
  631. * (system reset will occur)
  632. *
  633. * @param pOBInit pointer to an FLASH_OBInitStruct structure that
  634. * contains the configuration information for the programming.
  635. *
  636. * @retval HAL_StatusTypeDef HAL Status
  637. */
  638. HAL_StatusTypeDef HAL_FLASH_OBProgram(FLASH_OBProgramInitTypeDef *pOBInit)
  639. {
  640. HAL_StatusTypeDef status = HAL_ERROR;
  641. /* Process Locked */
  642. __HAL_LOCK(&pFlash);
  643. /* Config flash timming */
  644. __HAL_FLASH_TIMMING_SEQUENCE_CONFIG();
  645. /* Check the parameters */
  646. assert_param(IS_OPTIONBYTE(pOBInit->OptionType));
  647. /* WRP register */
  648. if ((pOBInit->OptionType & OPTIONBYTE_WRP) != 0)
  649. {
  650. /* Write protection configuration */
  651. FLASH->WRPR = (uint16_t)(~(pOBInit->WRPSector));
  652. }
  653. /* SDK register */
  654. if ((pOBInit->OptionType & OPTIONBYTE_SDK) != 0)
  655. {
  656. /* SDK protection configuration */
  657. FLASH->SDKR = (pOBInit->SDKStartAddr) | (pOBInit->SDKEndAddr<<8);
  658. }
  659. if ((pOBInit->OptionType & OPTIONBYTE_USER) != 0x00U)
  660. {
  661. FLASH_OB_OptrConfig(pOBInit->USERType, pOBInit->USERConfig);
  662. }
  663. else
  664. {
  665. /* nothing to do */
  666. }
  667. /* starts to modify Flash Option bytes */
  668. FLASH->CR|=FLASH_CR_OPTSTRT;
  669. /* set bit EOPIE */
  670. FLASH->CR|=FLASH_CR_EOPIE;
  671. /* trigger program */
  672. *((__IO uint32_t *)(0x40022080))=0xff;
  673. /* Wait for last operation to be completed */
  674. status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE);
  675. /* Process Unlocked */
  676. __HAL_UNLOCK(&pFlash);
  677. return status;
  678. }
  679. /**
  680. * @brief Program option bytes
  681. * @note The function @ref HAL_FLASH_Unlock() should be called before to unlock the FLASH interface
  682. * The function @ref HAL_FLASH_OB_Unlock() should be called before to unlock the options bytes
  683. * The function @ref HAL_FLASH_OB_Launch() should be called after to force the reload of the options bytes
  684. * (system reset will occur)
  685. *
  686. * @param pBOOTInit pointer to an FLASH_OBBootProgramInitTypeDef structure that
  687. * contains the configuration information for the programming.
  688. *
  689. * @retval HAL_StatusTypeDef HAL Status
  690. */
  691. HAL_StatusTypeDef HAL_FLASH_OBBOOTProgram(FLASH_OBBootProgramInitTypeDef *pBOOTInit)
  692. {
  693. HAL_StatusTypeDef status = HAL_ERROR;
  694. /* Process Locked */
  695. __HAL_LOCK(&pFlash);
  696. /* Config flash timming */
  697. __HAL_FLASH_TIMMING_SEQUENCE_CONFIG();
  698. /* Check the parameters */
  699. assert_param(IS_OB_BOOTTYPE(pBOOTInit->BOOTType));
  700. assert_param(IS_OB_BOOTSIZE(pBOOTInit->BOOTSize));
  701. MODIFY_REG(FLASH->BTCR, FLASH_BTCR_NBOOT1 | FLASH_BTCR_BOOT0 | FLASH_BTCR_BOOT_SIZE ,pBOOTInit->BOOTType | pBOOTInit->BOOTSize );
  702. /* starts to modify Flash Option bytes */
  703. FLASH->CR|=FLASH_CR_OPTSTRT;
  704. /* set bit EOPIE */
  705. FLASH->CR|=FLASH_CR_EOPIE;
  706. /* trigger program */
  707. *((__IO uint32_t *)(0x40022080))=0xff;
  708. /* Wait for last operation to be completed */
  709. status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE);
  710. /* Process Unlocked */
  711. __HAL_UNLOCK(&pFlash);
  712. return status;
  713. }
  714. /**
  715. * @brief Get the Boot configuration
  716. * @param pBOOTInit pointer to an FLASH_OBInitStruct structure that
  717. * contains the configuration information for the programming.
  718. *
  719. * @retval None
  720. */
  721. void HAL_FLASH_OBBOOTGetConfig(FLASH_OBBootProgramInitTypeDef *pBOOTInit)
  722. {
  723. pBOOTInit->BOOTType= READ_BIT(FLASH->BTCR,FLASH_BTCR_BOOT0 | FLASH_BTCR_NBOOT1 ) ;
  724. pBOOTInit->BOOTSize= READ_BIT(FLASH->BTCR,FLASH_BTCR_BOOT_SIZE);
  725. }
  726. /**
  727. * @brief Get the Option byte configuration
  728. * @param pOBInit pointer to an FLASH_OBInitStruct structure that
  729. * contains the configuration information for the programming.
  730. *
  731. * @retval None
  732. */
  733. void HAL_FLASH_OBGetConfig(FLASH_OBProgramInitTypeDef *pOBInit)
  734. {
  735. pOBInit->OptionType = OPTIONBYTE_ALL;
  736. /* Get WRP sector */
  737. pOBInit->WRPSector = (uint16_t)(~FLASH->WRPR);
  738. /* Get SDK sector */
  739. pOBInit->SDKStartAddr = (FLASH->SDKR)&0x1F;
  740. pOBInit->SDKEndAddr = ((FLASH->SDKR)&0x1F00)>>8;
  741. /*Get USER*/
  742. pOBInit->USERType = OB_USER_ALL;
  743. pOBInit->USERConfig = (FLASH->OPTR)&(FLASH_OPTR_IWDG_SW | FLASH_OPTR_IWDG_STOP | \
  744. FLASH_OPTR_NRST_MODE | FLASH_OPTR_BOR_EN | \
  745. FLASH_OPTR_BOR_LEV | FLASH_OPTR_SWD_MODE);
  746. }
  747. /**
  748. * @brief Handle FLASH interrupt request.
  749. * @retval None
  750. */
  751. void HAL_FLASH_IRQHandler(void)
  752. {
  753. uint32_t param = 0xFFFFFFFFU;
  754. uint32_t error;
  755. /* Save flash errors. Only ECC detection can be checked here as ECCC
  756. generates NMI */
  757. error = (FLASH->SR & FLASH_FLAG_SR_ERROR);
  758. CLEAR_BIT(FLASH->CR, pFlash.ProcedureOnGoing);
  759. /* A] Set parameter for user or error callbacks */
  760. /* check operation was a program or erase */
  761. if ((pFlash.ProcedureOnGoing & (FLASH_TYPEPROGRAM_PAGE)) != 0x00U)
  762. {
  763. /* return adress being programmed */
  764. param = pFlash.Address;
  765. }else if ((pFlash.ProcedureOnGoing & (FLASH_TYPEERASE_MASSERASE | FLASH_TYPEERASE_SECTORERASE | FLASH_TYPEERASE_PAGEERASE)) != 0x00U)
  766. {
  767. /* return page number being erased (0 for mass erase) */
  768. param = pFlash.PageOrSector;
  769. }else
  770. {
  771. /* Nothing to do */
  772. }
  773. /* B] Check errors */
  774. if (error != 0x00U)
  775. {
  776. /*Save the error code*/
  777. pFlash.ErrorCode |= error;
  778. /* clear error flags */
  779. __HAL_FLASH_CLEAR_FLAG(error);
  780. /*Stop the procedure ongoing*/
  781. pFlash.ProcedureOnGoing = FLASH_TYPENONE;
  782. /* Error callback */
  783. HAL_FLASH_OperationErrorCallback(param);
  784. }
  785. /* C] Check FLASH End of Operation flag */
  786. if (__HAL_FLASH_GET_FLAG(FLASH_FLAG_EOP) != 0x00U)
  787. {
  788. /* Clear FLASH End of Operation pending bit */
  789. __HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_EOP);
  790. if (pFlash.ProcedureOnGoing == FLASH_TYPEERASE_PAGEERASE)
  791. {
  792. /* Nb of pages to erased can be decreased */
  793. pFlash.NbPagesSectorsToErase--;
  794. /* Check if there are still pages to erase*/
  795. if (pFlash.NbPagesSectorsToErase != 0x00U)
  796. {
  797. /* Increment page number */
  798. pFlash.PageOrSector += FLASH_PAGE_SIZE;
  799. FLASH_PageErase(pFlash.PageOrSector);
  800. }else
  801. {
  802. /* No more pages to erase: stop erase pages procedure */
  803. pFlash.ProcedureOnGoing = FLASH_TYPENONE;
  804. }
  805. }
  806. else if (pFlash.ProcedureOnGoing == FLASH_TYPEERASE_SECTORERASE)
  807. {
  808. /* Nb of sectors to erased can be decreased */
  809. pFlash.NbPagesSectorsToErase--;
  810. /* Check if there are still pages to erase*/
  811. if (pFlash.NbPagesSectorsToErase != 0x00U)
  812. {
  813. /* Increment page number */
  814. pFlash.PageOrSector += FLASH_SECTOR_SIZE;
  815. FLASH_SectorErase(pFlash.PageOrSector);
  816. }else
  817. {
  818. /* No more pages to erase: stop erase pages procedure */
  819. pFlash.ProcedureOnGoing = FLASH_TYPENONE;
  820. }
  821. }
  822. else
  823. {
  824. /*Stop the ongoing procedure */
  825. pFlash.ProcedureOnGoing = FLASH_TYPENONE;
  826. }
  827. /* User callback */
  828. HAL_FLASH_EndOfOperationCallback(param);
  829. }
  830. if (pFlash.ProcedureOnGoing == FLASH_TYPENONE)
  831. {
  832. /* Disable End of Operation and Error interrupts */
  833. __HAL_FLASH_DISABLE_IT(FLASH_IT_EOP | FLASH_IT_OPERR);
  834. /* Process Unlocked */
  835. __HAL_UNLOCK(&pFlash);
  836. }
  837. }
  838. /**
  839. * @brief FLASH end of operation interrupt callback.
  840. * @param ReturnValue The value saved in this parameter depends on the ongoing procedure
  841. * Mass Erase: 0
  842. * Page Erase: Page which has been erased
  843. * Program: Address which was selected for data program
  844. * @retval None
  845. */
  846. __weak void HAL_FLASH_EndOfOperationCallback(uint32_t ReturnValue)
  847. {
  848. /* Prevent unused argument(s) compilation warning */
  849. UNUSED(ReturnValue);
  850. /* NOTE : This function should not be modified, when the callback is needed,
  851. the HAL_FLASH_EndOfOperationCallback could be implemented in the user file
  852. */
  853. }
  854. /**
  855. * @brief FLASH operation error interrupt callback.
  856. * @param ReturnValue The value saved in this parameter depends on the ongoing procedure
  857. * Mass Erase: 0
  858. * Page Erase: Page number which returned an error
  859. * Program: Address which was selected for data program
  860. * @retval None
  861. */
  862. __weak void HAL_FLASH_OperationErrorCallback(uint32_t ReturnValue)
  863. {
  864. /* Prevent unused argument(s) compilation warning */
  865. UNUSED(ReturnValue);
  866. /* NOTE : This function should not be modified, when the callback is needed,
  867. the HAL_FLASH_OperationErrorCallback could be implemented in the user file
  868. */
  869. }
  870. /**
  871. * @}
  872. */
  873. /**
  874. * @}
  875. */
  876. #endif /* HAL_FLASH_MODULE_ENABLED */
  877. /**
  878. * @}
  879. */
  880. /**
  881. * @}
  882. */
  883. /************************ (C) COPYRIGHT Puya *****END OF FILE****/