ch32v00X_flash.c 30 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065
  1. /********************************** (C) COPYRIGHT *******************************
  2. * File Name : ch32v00X_flash.c
  3. * Author : WCH
  4. * Version : V1.0.1
  5. * Date : 2024/12/11
  6. * Description : This file provides all the FLASH firmware functions.
  7. *********************************************************************************
  8. * Copyright (c) 2021 Nanjing Qinheng Microelectronics Co., Ltd.
  9. * Attention: This software (modified or not) and binary are used for
  10. * microcontroller manufactured by Nanjing Qinheng Microelectronics.
  11. *******************************************************************************/
  12. #include <ch32v00X_flash.h>
  13. /* Flash Access Control Register bits */
  14. #define ACR_LATENCY_Mask ((uint32_t)0xFFFFFFFC)
  15. /* Flash Control Register bits */
  16. #define CR_PER_Set ((uint32_t)0x00000002)
  17. #define CR_PER_Reset ((uint32_t)0xFFFFFFFD)
  18. #define CR_MER_Set ((uint32_t)0x00000004)
  19. #define CR_MER_Reset ((uint32_t)0xFFFFFFFB)
  20. #define CR_OPTER_Set ((uint32_t)0x00000020)
  21. #define CR_OPTER_Reset ((uint32_t)0xFFFFFFDF)
  22. #define CR_STRT_Set ((uint32_t)0x00000040)
  23. #define CR_LOCK_Set ((uint32_t)0x00000080)
  24. #define CR_FLOCK_Set ((uint32_t)0x00008000)
  25. #define CR_PAGE_PG ((uint32_t)0x00010000)
  26. #define CR_PAGE_ER ((uint32_t)0x00020000)
  27. #define CR_PAGE_ER_Reset ((uint32_t)0xFFFDFFFF)
  28. #define CR_BUF_LOAD ((uint32_t)0x00040000)
  29. #define CR_BUF_RST ((uint32_t)0x00080000)
  30. #define CR_BER32 ((uint32_t)0x00800000)
  31. /* FLASH Status Register bits */
  32. #define SR_BSY ((uint32_t)0x00000001)
  33. #define SR_WRPRTERR ((uint32_t)0x00000010)
  34. #define SR_EOP ((uint32_t)0x00000020)
  35. /* FLASH Mask */
  36. #define RDPRT_Mask ((uint32_t)0x00000002)
  37. #define WRP0_Mask ((uint32_t)0x000000FF)
  38. #define WRP1_Mask ((uint32_t)0x0000FF00)
  39. #define WRP2_Mask ((uint32_t)0x00FF0000)
  40. #define WRP3_Mask ((uint32_t)0xFF000000)
  41. /* FLASH Keys */
  42. #define RDP_Key ((uint16_t)0x00A5)
  43. #define FLASH_KEY1 ((uint32_t)0x45670123)
  44. #define FLASH_KEY2 ((uint32_t)0xCDEF89AB)
  45. /* Delay definition */
  46. #define EraseTimeout ((uint32_t)0x000B0000)
  47. #define ProgramTimeout ((uint32_t)0x00002000)
  48. /* Flash Program Valid Address */
  49. #define ValidAddrStart (FLASH_BASE)
  50. #if defined(CH32V002)
  51. #define ValidAddrEnd (FLASH_BASE + 0x4000)
  52. #elif defined(CH32V004) || defined(CH32V005)
  53. #define ValidAddrEnd (FLASH_BASE + 0x8000)
  54. #elif defined(CH32V006) || defined(CH32V007_M007)
  55. #define ValidAddrEnd (FLASH_BASE + 0xF800)
  56. #endif
  57. /* FLASH Size */
  58. #define Size_256B 0x100
  59. #define Size_1KB 0x400
  60. #define Size_32KB 0x8000
  61. /********************************************************************************
  62. * @fn FLASH_SetLatency
  63. *
  64. * @brief Sets the code latency value.
  65. *
  66. * @param FLASH_Latency - specifies the FLASH Latency value.
  67. * FLASH_Latency_0 - FLASH Zero Latency cycle
  68. * FLASH_Latency_1 - FLASH One Latency cycle
  69. * FLASH_Latency_2 - FLASH Two Latency cycles
  70. *
  71. * @return None
  72. */
  73. void FLASH_SetLatency(uint32_t FLASH_Latency)
  74. {
  75. uint32_t tmpreg = 0;
  76. tmpreg = FLASH->ACTLR;
  77. tmpreg &= ACR_LATENCY_Mask;
  78. tmpreg |= FLASH_Latency;
  79. FLASH->ACTLR = tmpreg;
  80. }
  81. /********************************************************************************
  82. * @fn FLASH_Unlock
  83. *
  84. * @brief Unlocks the FLASH Program Erase Controller.
  85. *
  86. * @return None
  87. */
  88. void FLASH_Unlock(void)
  89. {
  90. /* Authorize the FPEC of Bank1 Access */
  91. FLASH->KEYR = FLASH_KEY1;
  92. FLASH->KEYR = FLASH_KEY2;
  93. }
  94. /********************************************************************************
  95. * @fn FLASH_Lock
  96. *
  97. * @brief Locks the FLASH Program Erase Controller.
  98. *
  99. * @return None
  100. */
  101. void FLASH_Lock(void)
  102. {
  103. FLASH->CTLR |= CR_LOCK_Set;
  104. }
  105. /********************************************************************************
  106. * @fn FLASH_ErasePage
  107. *
  108. * @brief Erases a specified FLASH page(1KB).
  109. *
  110. * @param Page_Address - The page address to be erased.
  111. *
  112. * @return FLASH Status - The returned value can be: FLASH_BUSY, FLASH_ERROR_PG,
  113. * FLASH_ERROR_WRP, FLASH_COMPLETE or FLASH_TIMEOUT.
  114. */
  115. FLASH_Status FLASH_ErasePage(uint32_t Page_Address)
  116. {
  117. FLASH_Status status = FLASH_COMPLETE;
  118. status = FLASH_WaitForLastOperation(EraseTimeout);
  119. if(status == FLASH_COMPLETE)
  120. {
  121. FLASH->CTLR &= (CR_OPTER_Reset & CR_PAGE_ER_Reset);
  122. FLASH->CTLR |= CR_PER_Set;
  123. FLASH->ADDR = Page_Address;
  124. FLASH->CTLR |= CR_STRT_Set;
  125. status = FLASH_WaitForLastOperation(EraseTimeout);
  126. FLASH->CTLR &= CR_PER_Reset;
  127. }
  128. return status;
  129. }
  130. /********************************************************************************
  131. * @fn FLASH_EraseAllPages
  132. *
  133. * @brief Erases all FLASH pages.
  134. *
  135. * @return FLASH Status - The returned value can be:FLASH_BUSY, FLASH_ERROR_PG,
  136. * FLASH_ERROR_WRP, FLASH_COMPLETE or FLASH_TIMEOUT.
  137. */
  138. FLASH_Status FLASH_EraseAllPages(void)
  139. {
  140. FLASH_Status status = FLASH_COMPLETE;
  141. status = FLASH_WaitForLastOperation(EraseTimeout);
  142. if(status == FLASH_COMPLETE)
  143. {
  144. FLASH->CTLR &= (CR_OPTER_Reset & CR_PAGE_ER_Reset);
  145. FLASH->CTLR |= CR_MER_Set;
  146. FLASH->CTLR |= CR_STRT_Set;
  147. status = FLASH_WaitForLastOperation(EraseTimeout);
  148. FLASH->CTLR &= CR_MER_Reset;
  149. }
  150. return status;
  151. }
  152. /********************************************************************************
  153. * @fn FLASH_EraseOptionBytes
  154. *
  155. * @brief Erases the FLASH option bytes.
  156. *
  157. * @return FLASH Status - The returned value can be: FLASH_BUSY, FLASH_ERROR_PG,
  158. * FLASH_ERROR_WRP, FLASH_COMPLETE or FLASH_TIMEOUT.
  159. */
  160. FLASH_Status FLASH_EraseOptionBytes(void)
  161. {
  162. FLASH_Status status = FLASH_COMPLETE;
  163. status = FLASH_WaitForLastOperation(EraseTimeout);
  164. if(status == FLASH_COMPLETE)
  165. {
  166. FLASH_Unlock();
  167. FLASH->OBKEYR = FLASH_KEY1;
  168. FLASH->OBKEYR = FLASH_KEY2;
  169. FLASH->CTLR &= (CR_OPTER_Reset & CR_PAGE_ER_Reset);
  170. FLASH->CTLR |= CR_OPTER_Set;
  171. FLASH->CTLR |= CR_STRT_Set;
  172. status = FLASH_WaitForLastOperation(EraseTimeout);
  173. FLASH->CTLR &= CR_OPTER_Reset;
  174. FLASH_Lock();
  175. }
  176. return status;
  177. }
  178. /*********************************************************************
  179. * @fn FLASH_OptionBytePR
  180. *
  181. * @brief Programs option bytes.
  182. *
  183. * @param pbuf - data.
  184. *
  185. * @return none
  186. */
  187. void FLASH_OptionBytePR(u32* pbuf)
  188. {
  189. uint8_t i;
  190. FLASH_EraseOptionBytes();
  191. FLASH_Unlock_Fast();
  192. FLASH_BufReset();
  193. for(i=0; i<4; i++)
  194. {
  195. FLASH_BufLoad((OB_BASE + 4*i), *pbuf++);
  196. }
  197. FLASH_ProgramPage_Fast(OB_BASE);
  198. FLASH_Lock_Fast();
  199. }
  200. /*********************************************************************
  201. * @fn FLASH_EnableWriteProtection
  202. *
  203. * @brief Write protects the desired sectors
  204. *
  205. * @param FLASH_Pages - specifies the address of the pages to be write protected.
  206. *
  207. * @return FLASH Status - The returned value can be: FLASH_BUSY, FLASH_ERROR_PG,
  208. * FLASH_ERROR_WRP, FLASH_COMPLETE , FLASH_TIMEOUT or FLASH_RDP.
  209. */
  210. FLASH_Status FLASH_EnableWriteProtection(uint32_t FLASH_Pages)
  211. {
  212. uint8_t WRP0_Data = 0xFF, WRP1_Data = 0xFF, WRP2_Data = 0xFF, WRP3_Data = 0xFF;
  213. uint32_t buf[4];
  214. uint8_t i;
  215. FLASH_Status status = FLASH_COMPLETE;
  216. if((FLASH->OBR & RDPRT_Mask) != (uint32_t)RESET)
  217. {
  218. status = FLASH_RDP;
  219. }
  220. else{
  221. FLASH_Pages = (uint32_t)(~FLASH_Pages);
  222. WRP0_Data = (uint8_t)(FLASH_Pages & WRP0_Mask);
  223. WRP1_Data = (uint8_t)((FLASH_Pages & WRP1_Mask) >> 8);
  224. WRP2_Data = (uint8_t)((FLASH_Pages & WRP2_Mask) >> 16);
  225. WRP3_Data = (uint8_t)((FLASH_Pages & WRP3_Mask) >> 24);
  226. status = FLASH_WaitForLastOperation(ProgramTimeout);
  227. if(status == FLASH_COMPLETE)
  228. {
  229. for(i=0; i<4; i++){
  230. buf[i] = *(uint32_t*)(OB_BASE + 4*i);
  231. }
  232. buf[2] = ((uint32_t)(((uint32_t)(WRP0_Data) & 0x00FF) + (((uint32_t)(~WRP0_Data) & 0x00FF) << 8) \
  233. + (((uint32_t)(WRP1_Data) & 0x00FF) << 16) + (((uint32_t)(~WRP1_Data) & 0x00FF) << 24)));
  234. buf[3] = ((uint32_t)(((uint32_t)(WRP2_Data) & 0x00FF) + (((uint32_t)(~WRP2_Data) & 0x00FF) << 8) \
  235. + (((uint32_t)(WRP3_Data) & 0x00FF) << 16) + (((uint32_t)(~WRP3_Data) & 0x00FF) << 24)));
  236. FLASH_OptionBytePR(buf);
  237. }
  238. }
  239. return status;
  240. }
  241. /*********************************************************************
  242. * @fn FLASH_EnableReadOutProtection
  243. *
  244. * @brief Enables the read out protection.
  245. *
  246. * @return FLASH Status - The returned value can be: FLASH_BUSY, FLASH_ERROR_PG,
  247. * FLASH_ERROR_WRP, FLASH_COMPLETE, FLASH_TIMEOUT or FLASH_RDP.
  248. */
  249. FLASH_Status FLASH_EnableReadOutProtection(void)
  250. {
  251. FLASH_Status status = FLASH_COMPLETE;
  252. uint32_t buf[4];
  253. uint8_t i;
  254. if((FLASH->OBR & RDPRT_Mask) != (uint32_t)RESET)
  255. {
  256. status = FLASH_RDP;
  257. }
  258. else{
  259. status = FLASH_WaitForLastOperation(EraseTimeout);
  260. if(status == FLASH_COMPLETE)
  261. {
  262. for(i=0; i<4; i++){
  263. buf[i] = *(uint32_t*)(OB_BASE + 4*i);
  264. }
  265. buf[0] = 0x000000FF + (buf[0] & 0xFFFF0000);
  266. FLASH_OptionBytePR(buf);
  267. }
  268. }
  269. return status;
  270. }
  271. /*********************************************************************
  272. * @fn FLASH_UserOptionByteConfig
  273. *
  274. * @brief Programs the FLASH User Option Byte - IWDG_SW / RST_STOP /
  275. * RST_STDBY / OB_PowerON_Start_Mode.
  276. *
  277. * @param OB_IWDG - Selects the IWDG mode
  278. * OB_IWDG_SW - Software IWDG selected
  279. * OB_IWDG_HW - Hardware IWDG selected
  280. * OB_STDBY - Reset event when entering Standby mode.
  281. * OB_STDBY_NoRST - No reset generated when entering in STANDBY.
  282. * OB_STDBY_RST - Reset generated when entering in STANDBY.
  283. * OB_RST - Selects the reset IO mode and Ignore delay time.
  284. * OB_RST_NoEN - Reset IO disable.
  285. * OB_RST_EN_DT12ms - Reset IO enable and Ignore delay time 12ms.
  286. * OB_RST_EN_DT1ms - Reset IO enable and Ignore delay time 1ms.
  287. * OB_RST_EN_DT128us - Reset IO enable and Ignore delay time 128us.
  288. * OB_PowerON_Start_Mode - Selects start mode after power on.
  289. * OB_PowerON_Start_Mode_BOOT - Boot start after power on.
  290. * OB_PowerON_Start_Mode_USER - User start after power on.
  291. *
  292. * @return FLASH Status - The returned value can be: FLASH_BUSY, FLASH_ERROR_PG,
  293. * FLASH_ERROR_WRP, FLASH_COMPLETE, FLASH_TIMEOUT or FLASH_RDP.
  294. */
  295. FLASH_Status FLASH_UserOptionByteConfig(uint16_t OB_IWDG, uint16_t OB_STDBY, uint16_t OB_RST, uint16_t OB_PowerON_Start_Mode)
  296. {
  297. FLASH_Status status = FLASH_COMPLETE;
  298. uint8_t UserByte;
  299. uint32_t buf[4];
  300. uint8_t i;
  301. if((FLASH->OBR & RDPRT_Mask) != (uint32_t)RESET)
  302. {
  303. status = FLASH_RDP;
  304. }
  305. else{
  306. UserByte = OB_IWDG | (uint16_t)(OB_STDBY | (uint16_t)(OB_RST | (uint16_t)(OB_PowerON_Start_Mode | 0xC2)));
  307. for(i=0; i<4; i++){
  308. buf[i] = *(uint32_t*)(OB_BASE + 4*i);
  309. }
  310. buf[0] = ((uint32_t)((((uint32_t)(UserByte) & 0x00FF) << 16) + (((uint32_t)(~UserByte) & 0x00FF) << 24))) + 0x00005AA5;
  311. FLASH_OptionBytePR(buf);
  312. }
  313. return status;
  314. }
  315. /*********************************************************************
  316. * @fn FLASH_GetUserOptionByte
  317. *
  318. * @brief Returns the FLASH User Option Bytes values.
  319. *
  320. * @return The FLASH User Option Bytes values:IWDG_SW(Bit0), RST_STDBY(Bit2)
  321. * , RST_MODE(Bit[3:4]) and START_MODE(Bit5).
  322. */
  323. uint32_t FLASH_GetUserOptionByte(void)
  324. {
  325. return (uint32_t)(FLASH->OBR >> 2);
  326. }
  327. /*********************************************************************
  328. * @fn FLASH_GetWriteProtectionOptionByte
  329. *
  330. * @brief Returns the FLASH Write Protection Option Bytes Register value.
  331. *
  332. * @return The FLASH Write Protection Option Bytes Register value.
  333. */
  334. uint32_t FLASH_GetWriteProtectionOptionByte(void)
  335. {
  336. return (uint32_t)(FLASH->WPR);
  337. }
  338. /*********************************************************************
  339. * @fn FLASH_GetReadOutProtectionStatus
  340. *
  341. * @brief Checks whether the FLASH Read Out Protection Status is set or not.
  342. *
  343. * @return FLASH ReadOut Protection Status(SET or RESET)
  344. */
  345. FlagStatus FLASH_GetReadOutProtectionStatus(void)
  346. {
  347. FlagStatus readoutstatus = RESET;
  348. if((FLASH->OBR & RDPRT_Mask) != (uint32_t)RESET)
  349. {
  350. readoutstatus = SET;
  351. }
  352. else
  353. {
  354. readoutstatus = RESET;
  355. }
  356. return readoutstatus;
  357. }
  358. /*********************************************************************
  359. * @fn FLASH_ITConfig
  360. *
  361. * @brief Enables or disables the specified FLASH interrupts.
  362. *
  363. * @param FLASH_IT - specifies the FLASH interrupt sources to be enabled or disabled.
  364. * FLASH_IT_ERROR - FLASH Error Interrupt.
  365. * FLASH_IT_EOP - FLASH end of operation Interrupt.
  366. * FLASH_IT_FWAKE - FLASH Wake Up Interrupt.
  367. * NewState - new state of the specified Flash interrupts(ENABLE or DISABLE).
  368. *
  369. * @return FLASH Prefetch Buffer Status (SET or RESET).
  370. */
  371. void FLASH_ITConfig(uint32_t FLASH_IT, FunctionalState NewState)
  372. {
  373. if(NewState != DISABLE)
  374. {
  375. FLASH->CTLR |= FLASH_IT;
  376. }
  377. else
  378. {
  379. FLASH->CTLR &= ~(uint32_t)FLASH_IT;
  380. }
  381. }
  382. /*********************************************************************
  383. * @fn FLASH_GetFlagStatus
  384. *
  385. * @brief Checks whether the specified FLASH flag is set or not.
  386. *
  387. * @param FLASH_FLAG - specifies the FLASH flag to check.
  388. * FLASH_FLAG_BSY - FLASH Busy flag
  389. * FLASH_FLAG_WRPRTERR - FLASH Write protected error flag
  390. * FLASH_FLAG_EOP - FLASH End of Operation flag
  391. * FLASH_FLAG_FWAKE - FLASH Wake Up flag
  392. * FLASH_FLAG_OPTERR - FLASH Option Byte error flag
  393. *
  394. * @return The new state of FLASH_FLAG (SET or RESET).
  395. */
  396. FlagStatus FLASH_GetFlagStatus(uint32_t FLASH_FLAG)
  397. {
  398. FlagStatus bitstatus = RESET;
  399. if(FLASH_FLAG == FLASH_FLAG_OPTERR)
  400. {
  401. if((FLASH->OBR & FLASH_FLAG_OPTERR) != (uint32_t)RESET)
  402. {
  403. bitstatus = SET;
  404. }
  405. else
  406. {
  407. bitstatus = RESET;
  408. }
  409. }
  410. else
  411. {
  412. if((FLASH->STATR & FLASH_FLAG) != (uint32_t)RESET)
  413. {
  414. bitstatus = SET;
  415. }
  416. else
  417. {
  418. bitstatus = RESET;
  419. }
  420. }
  421. return bitstatus;
  422. }
  423. /*********************************************************************
  424. * @fn FLASH_ClearFlag
  425. *
  426. * @brief Clears the FLASH's pending flags.
  427. *
  428. * @param FLASH_FLAG - specifies the FLASH flags to clear.
  429. * FLASH_FLAG_WRPRTERR - FLASH Write protected error flag
  430. * FLASH_FLAG_EOP - FLASH End of Operation flag
  431. * FLASH_FLAG_FWAKE - FLASH Wake Up flag
  432. *
  433. * @return none
  434. */
  435. void FLASH_ClearFlag(uint32_t FLASH_FLAG)
  436. {
  437. if(FLASH_FLAG == FLASH_FLAG_FWAKE)
  438. {
  439. FLASH->STATR &= ~FLASH_FLAG;
  440. }
  441. else
  442. {
  443. FLASH->STATR = FLASH_FLAG;
  444. }
  445. }
  446. /*********************************************************************
  447. * @fn FLASH_GetStatus
  448. *
  449. * @brief Returns the FLASH Status.
  450. *
  451. * @return FLASH Status - The returned value can be: FLASH_BUSY, FLASH_ERROR_PG,
  452. * FLASH_ERROR_WRP or FLASH_COMPLETE.
  453. */
  454. FLASH_Status FLASH_GetStatus(void)
  455. {
  456. FLASH_Status flashstatus = FLASH_COMPLETE;
  457. if((FLASH->STATR & FLASH_FLAG_BSY) == FLASH_FLAG_BSY)
  458. {
  459. flashstatus = FLASH_BUSY;
  460. }
  461. else
  462. {
  463. if((FLASH->STATR & FLASH_FLAG_WRPRTERR) != 0)
  464. {
  465. flashstatus = FLASH_ERROR_WRP;
  466. }
  467. else
  468. {
  469. flashstatus = FLASH_COMPLETE;
  470. }
  471. }
  472. return flashstatus;
  473. }
  474. /*********************************************************************
  475. * @fn FLASH_GetBank1Status
  476. *
  477. * @brief Returns the FLASH Bank1 Status.
  478. *
  479. * @return FLASH Status - The returned value can be: FLASH_BUSY, FLASH_ERROR_PG,
  480. * FLASH_ERROR_WRP or FLASH_COMPLETE.
  481. */
  482. FLASH_Status FLASH_GetBank1Status(void)
  483. {
  484. FLASH_Status flashstatus = FLASH_COMPLETE;
  485. if((FLASH->STATR & FLASH_FLAG_BANK1_BSY) == FLASH_FLAG_BSY)
  486. {
  487. flashstatus = FLASH_BUSY;
  488. }
  489. else
  490. {
  491. if((FLASH->STATR & FLASH_FLAG_BANK1_WRPRTERR) != 0)
  492. {
  493. flashstatus = FLASH_ERROR_WRP;
  494. }
  495. else
  496. {
  497. flashstatus = FLASH_COMPLETE;
  498. }
  499. }
  500. return flashstatus;
  501. }
  502. /*********************************************************************
  503. * @fn FLASH_WaitForLastOperation
  504. *
  505. * @brief Waits for a Flash operation to complete or a TIMEOUT to occur.
  506. *
  507. * @param Timeout - FLASH programming Timeout
  508. *
  509. * @return FLASH Status - The returned value can be: FLASH_BUSY, FLASH_ERROR_PG,
  510. * FLASH_ERROR_WRP or FLASH_COMPLETE.
  511. */
  512. FLASH_Status FLASH_WaitForLastOperation(uint32_t Timeout)
  513. {
  514. FLASH_Status status = FLASH_COMPLETE;
  515. status = FLASH_GetBank1Status();
  516. while((status == FLASH_BUSY) && (Timeout != 0x00))
  517. {
  518. status = FLASH_GetBank1Status();
  519. Timeout--;
  520. }
  521. if(Timeout == 0x00)
  522. {
  523. status = FLASH_TIMEOUT;
  524. }
  525. return status;
  526. }
  527. /*********************************************************************
  528. * @fn FLASH_WaitForLastBank1Operation
  529. *
  530. * @brief Waits for a Flash operation on Bank1 to complete or a TIMEOUT to occur.
  531. *
  532. * @param Timeout - FLASH programming Timeout
  533. *
  534. * @return FLASH Status - The returned value can be: FLASH_BUSY, FLASH_ERROR_PG,
  535. * FLASH_ERROR_WRP or FLASH_COMPLETE.
  536. */
  537. FLASH_Status FLASH_WaitForLastBank1Operation(uint32_t Timeout)
  538. {
  539. FLASH_Status status = FLASH_COMPLETE;
  540. status = FLASH_GetBank1Status();
  541. while((status == FLASH_FLAG_BANK1_BSY) && (Timeout != 0x00))
  542. {
  543. status = FLASH_GetBank1Status();
  544. Timeout--;
  545. }
  546. if(Timeout == 0x00)
  547. {
  548. status = FLASH_TIMEOUT;
  549. }
  550. return status;
  551. }
  552. /*********************************************************************
  553. * @fn FLASH_Unlock_Fast
  554. *
  555. * @brief Unlocks the Fast Program Erase Mode.
  556. *
  557. * @return none
  558. */
  559. void FLASH_Unlock_Fast(void)
  560. {
  561. /* Authorize the FPEC of Bank1 Access */
  562. FLASH->KEYR = FLASH_KEY1;
  563. FLASH->KEYR = FLASH_KEY2;
  564. /* Fast program mode unlock */
  565. FLASH->MODEKEYR = FLASH_KEY1;
  566. FLASH->MODEKEYR = FLASH_KEY2;
  567. }
  568. /*********************************************************************
  569. * @fn FLASH_Lock_Fast
  570. *
  571. * @brief Locks the Fast Program Erase Mode.
  572. *
  573. * @return none
  574. */
  575. void FLASH_Lock_Fast(void)
  576. {
  577. FLASH->CTLR |= CR_FLOCK_Set;
  578. }
  579. /*********************************************************************
  580. * @fn FLASH_BufReset
  581. *
  582. * @brief Flash Buffer reset.
  583. *
  584. * @return none
  585. */
  586. void FLASH_BufReset(void)
  587. {
  588. FLASH->CTLR &= (CR_OPTER_Reset & CR_PAGE_ER_Reset);
  589. FLASH->CTLR |= CR_PAGE_PG;
  590. FLASH->CTLR |= CR_BUF_RST;
  591. while(FLASH->STATR & SR_BSY)
  592. ;
  593. FLASH->CTLR &= ~CR_PAGE_PG;
  594. }
  595. /*********************************************************************
  596. * @fn FLASH_BufLoad
  597. *
  598. * @brief Flash Buffer load(4Byte).
  599. *
  600. * @param Address - specifies the address to be programmed.
  601. * Data0 - specifies the data0 to be programmed.
  602. *
  603. * @return none
  604. */
  605. void FLASH_BufLoad(uint32_t Address, uint32_t Data0)
  606. {
  607. if(((Address >= ValidAddrStart) && (Address < ValidAddrEnd)) || ((Address >= OB_BASE) && (Address < OB_BASE+0x100)))
  608. {
  609. FLASH->CTLR &= (CR_OPTER_Reset & CR_PAGE_ER_Reset);
  610. FLASH->CTLR |= CR_PAGE_PG;
  611. *(__IO uint32_t *)(Address) = Data0;
  612. FLASH->CTLR |= CR_BUF_LOAD;
  613. while(FLASH->STATR & SR_BSY)
  614. ;
  615. FLASH->CTLR &= ~CR_PAGE_PG;
  616. }
  617. }
  618. /*********************************************************************
  619. * @fn FLASH_ErasePage_Fast
  620. *
  621. * @brief Erases a specified FLASH page (1page = 256Byte).
  622. *
  623. * @param Page_Address - The page address to be erased.
  624. *
  625. * @return none
  626. */
  627. void FLASH_ErasePage_Fast(uint32_t Page_Address)
  628. {
  629. if((Page_Address >= ValidAddrStart) && (Page_Address < ValidAddrEnd))
  630. {
  631. FLASH->CTLR &= (CR_OPTER_Reset & CR_PAGE_ER_Reset);
  632. FLASH->CTLR |= CR_PAGE_ER;
  633. FLASH->ADDR = Page_Address;
  634. FLASH->CTLR |= CR_STRT_Set;
  635. while(FLASH->STATR & SR_BSY)
  636. ;
  637. FLASH->CTLR &= ~CR_PAGE_ER;
  638. }
  639. }
  640. /*********************************************************************
  641. * @fn FLASH_EraseBlock_32K_Fast
  642. *
  643. * @brief Erases a specified FLASH Block (1Block = 32KByte).
  644. *
  645. * @param Block_Address - The block address to be erased.
  646. * This function is only capable of erasing addresses
  647. * in the range of 0x08000000~0x08008000.
  648. *
  649. * @return none
  650. */
  651. void FLASH_EraseBlock_32K_Fast(uint32_t Block_Address)
  652. {
  653. FLASH->CTLR &= (CR_OPTER_Reset & CR_PAGE_ER_Reset);
  654. Block_Address &= 0xFFFF8000;
  655. FLASH->CTLR |= CR_BER32;
  656. FLASH->ADDR = Block_Address;
  657. FLASH->CTLR |= CR_STRT_Set;
  658. while(FLASH->STATR & SR_BSY)
  659. ;
  660. FLASH->CTLR &= ~CR_BER32;
  661. }
  662. /*********************************************************************
  663. * @fn FLASH_ProgramPage_Fast
  664. *
  665. * @brief Program a specified FLASH page (1page = 256Byte).
  666. *
  667. * @param Page_Address - The page address to be programed.
  668. *
  669. * @return none
  670. */
  671. void FLASH_ProgramPage_Fast(uint32_t Page_Address)
  672. {
  673. if(((Page_Address >= ValidAddrStart) && (Page_Address < ValidAddrEnd)) || (Page_Address == OB_BASE))
  674. {
  675. FLASH->CTLR &= (CR_OPTER_Reset & CR_PAGE_ER_Reset);
  676. FLASH->CTLR |= CR_PAGE_PG;
  677. FLASH->ADDR = Page_Address;
  678. FLASH->CTLR |= CR_STRT_Set;
  679. while(FLASH->STATR & SR_BSY)
  680. ;
  681. FLASH->CTLR &= ~CR_PAGE_PG;
  682. }
  683. }
  684. /*********************************************************************
  685. * @fn SystemReset_StartMode
  686. *
  687. * @brief Start mode after system reset.
  688. *
  689. * @param Mode - Start mode.
  690. * Start_Mode_USER - USER start after system reset
  691. * Start_Mode_BOOT - Boot start after system reset
  692. *
  693. * @return none
  694. */
  695. void SystemReset_StartMode(uint32_t Mode)
  696. {
  697. FLASH_Unlock();
  698. FLASH->BOOT_MODEKEYR = FLASH_KEY1;
  699. FLASH->BOOT_MODEKEYR = FLASH_KEY2;
  700. FLASH->STATR &= ~(1<<14);
  701. if(Mode == Start_Mode_BOOT){
  702. FLASH->STATR |= (1<<14);
  703. }
  704. FLASH_Lock();
  705. }
  706. /*********************************************************************
  707. * @fn ROM_ERASE
  708. *
  709. * @brief Select erases a specified FLASH .
  710. *
  711. * @param StartAddr - Erases Flash start address(StartAddr%256 == 0).
  712. * Cnt - Erases count.
  713. * Erase_Size - Erases size select.The returned value can be:
  714. * Size_32KB, Size_1KB, Size_256B.
  715. *
  716. * @return none.
  717. */
  718. static void ROM_ERASE(uint32_t StartAddr, uint32_t Cnt, uint32_t Erase_Size)
  719. {
  720. FLASH->CTLR &= (CR_OPTER_Reset & CR_PAGE_ER_Reset);
  721. do{
  722. if(Erase_Size == Size_32KB)
  723. {
  724. FLASH->CTLR |= CR_BER32;
  725. }
  726. else if(Erase_Size == Size_1KB)
  727. {
  728. FLASH->CTLR |= CR_PER_Set;
  729. }
  730. else if(Erase_Size == Size_256B)
  731. {
  732. FLASH->CTLR |= CR_PAGE_ER;
  733. }
  734. FLASH->ADDR = StartAddr;
  735. FLASH->CTLR |= CR_STRT_Set;
  736. while(FLASH->STATR & SR_BSY)
  737. ;
  738. if(Erase_Size == Size_32KB)
  739. {
  740. FLASH->CTLR &= ~CR_BER32;
  741. StartAddr += Size_32KB;
  742. }
  743. else if(Erase_Size == Size_1KB)
  744. {
  745. FLASH->CTLR &= ~CR_PER_Set;
  746. StartAddr += Size_1KB;
  747. }
  748. else if(Erase_Size == Size_256B)
  749. {
  750. FLASH->CTLR &= ~CR_PAGE_ER;
  751. StartAddr += Size_256B;
  752. }
  753. }while(--Cnt);
  754. }
  755. /*********************************************************************
  756. * @fn FLASH_ROM_ERASE
  757. *
  758. * @brief Erases a specified FLASH .
  759. *
  760. * @param StartAddr - Erases Flash start address(StartAddr%256 == 0).
  761. * Length - Erases Flash start Length(Length%256 == 0).
  762. *
  763. * @return FLASH Status - The returned value can be: FLASH_ADR_RANGE_ERROR,
  764. * FLASH_ALIGN_ERROR, FLASH_OP_RANGE_ERROR or FLASH_COMPLETE.
  765. */
  766. FLASH_Status FLASH_ROM_ERASE( uint32_t StartAddr, uint32_t Length )
  767. {
  768. uint32_t Addr0 = 0, Addr1 = 0, Length0 = 0, Length1 = 0;
  769. FLASH_Status status = FLASH_COMPLETE;
  770. if((StartAddr < ValidAddrStart) || (StartAddr >= ValidAddrEnd))
  771. {
  772. return FLASH_ADR_RANGE_ERROR;
  773. }
  774. if((StartAddr + Length) > ValidAddrEnd)
  775. {
  776. return FLASH_OP_RANGE_ERROR;
  777. }
  778. if((StartAddr & (Size_256B-1)) || (Length & (Size_256B-1)) || (Length == 0))
  779. {
  780. return FLASH_ALIGN_ERROR;
  781. }
  782. /* Authorize the FPEC of Bank1 Access */
  783. FLASH->KEYR = FLASH_KEY1;
  784. FLASH->KEYR = FLASH_KEY2;
  785. /* Fast program mode unlock */
  786. FLASH->MODEKEYR = FLASH_KEY1;
  787. FLASH->MODEKEYR = FLASH_KEY2;
  788. Addr0 = StartAddr;
  789. if(Length >= Size_32KB)
  790. {
  791. Length0 = Size_32KB - (Addr0 & (Size_32KB - 1));
  792. Addr1 = StartAddr + Length0;
  793. Length1 = Length - Length0;
  794. }
  795. else if(Length >= Size_1KB)
  796. {
  797. Length0 = Size_1KB - (Addr0 & (Size_1KB - 1));
  798. Addr1 = StartAddr + Length0;
  799. Length1 = Length - Length0;
  800. }
  801. else if(Length >= Size_256B)
  802. {
  803. Length0 = Length;
  804. }
  805. /* Erase 32KB */
  806. if(Length0 >= Size_32KB)//front
  807. {
  808. Length = Length0;
  809. if(Addr0 & (Size_32KB - 1))
  810. {
  811. Length0 = Size_32KB - (Addr0 & (Size_32KB - 1));
  812. }
  813. else
  814. {
  815. Length0 = 0;
  816. }
  817. ROM_ERASE((Addr0 + Length0), ((Length - Length0) >> 15), Size_32KB);
  818. }
  819. if(Length1 >= Size_32KB)//back
  820. {
  821. StartAddr = Addr1;
  822. Length = Length1;
  823. if((Addr1 + Length1) & (Size_32KB - 1))
  824. {
  825. Addr1 = ((StartAddr + Length1) & (~(Size_32KB - 1)));
  826. Length1 = (StartAddr + Length1) & (Size_32KB - 1);
  827. }
  828. else
  829. {
  830. Length1 = 0;
  831. }
  832. ROM_ERASE(StartAddr, ((Length - Length1) >> 15), Size_32KB);
  833. }
  834. /* Erase 1KB */
  835. if(Length0 >= Size_1KB) //front
  836. {
  837. Length = Length0;
  838. if(Addr0 & (Size_1KB - 1))
  839. {
  840. Length0 = Size_1KB - (Addr0 & (Size_1KB - 1));
  841. }
  842. else
  843. {
  844. Length0 = 0;
  845. }
  846. ROM_ERASE((Addr0 + Length0), ((Length - Length0) >> 10), Size_1KB);
  847. }
  848. if(Length1 >= Size_1KB) //back
  849. {
  850. StartAddr = Addr1;
  851. Length = Length1;
  852. if((Addr1 + Length1) & (Size_1KB - 1))
  853. {
  854. Addr1 = ((StartAddr + Length1) & (~(Size_1KB - 1)));
  855. Length1 = (StartAddr + Length1) & (Size_1KB - 1);
  856. }
  857. else
  858. {
  859. Length1 = 0;
  860. }
  861. ROM_ERASE(StartAddr, ((Length - Length1) >> 10), Size_1KB);
  862. }
  863. /* Erase 256B */
  864. if(Length0)//front
  865. {
  866. ROM_ERASE(Addr0, (Length0 >> 8), Size_256B);
  867. }
  868. if(Length1)//back
  869. {
  870. ROM_ERASE(Addr1, (Length1 >> 8), Size_256B);
  871. }
  872. FLASH->CTLR |= CR_FLOCK_Set;
  873. FLASH->CTLR |= CR_LOCK_Set;
  874. return status;
  875. }
  876. /*********************************************************************
  877. * @fn FLASH_ROM_WRITE
  878. *
  879. * @brief Writes a specified FLASH .
  880. *
  881. * @param StartAddr - Writes Flash start address(StartAddr%256 == 0).
  882. * Length - Writes Flash start Length(Length%256 == 0).
  883. * pbuf - Writes Flash value buffer.
  884. *
  885. * @return FLASH Status - The returned value can be: FLASH_ADR_RANGE_ERROR,
  886. * FLASH_ALIGN_ERROR, FLASH_OP_RANGE_ERROR or FLASH_COMPLETE.
  887. */
  888. FLASH_Status FLASH_ROM_WRITE( uint32_t StartAddr, uint32_t *pbuf, uint32_t Length )
  889. {
  890. uint32_t i, adr;
  891. uint8_t size;
  892. FLASH_Status status = FLASH_COMPLETE;
  893. if((StartAddr < ValidAddrStart) || (StartAddr >= ValidAddrEnd))
  894. {
  895. return FLASH_ADR_RANGE_ERROR;
  896. }
  897. if((StartAddr + Length) > ValidAddrEnd)
  898. {
  899. return FLASH_OP_RANGE_ERROR;
  900. }
  901. if((StartAddr & (Size_256B-1)) || (Length & (Size_256B-1)) || (Length == 0))
  902. {
  903. return FLASH_ALIGN_ERROR;
  904. }
  905. adr = StartAddr;
  906. i = Length >> 8;
  907. /* Authorize the FPEC of Bank1 Access */
  908. FLASH->KEYR = FLASH_KEY1;
  909. FLASH->KEYR = FLASH_KEY2;
  910. /* Fast program mode unlock */
  911. FLASH->MODEKEYR = FLASH_KEY1;
  912. FLASH->MODEKEYR = FLASH_KEY2;
  913. FLASH->CTLR &= (CR_OPTER_Reset & CR_PAGE_ER_Reset);
  914. do{
  915. FLASH->CTLR |= CR_PAGE_PG;
  916. FLASH->CTLR |= CR_BUF_RST;
  917. while(FLASH->STATR & SR_BSY)
  918. ;
  919. size = 64;
  920. while(size)
  921. {
  922. *(uint32_t *)StartAddr = *(uint32_t *)pbuf;
  923. FLASH->CTLR |= CR_BUF_LOAD;
  924. while(FLASH->STATR & SR_BSY)
  925. ;
  926. StartAddr += 4;
  927. pbuf += 1;
  928. size -= 1;
  929. }
  930. FLASH->ADDR = adr;
  931. FLASH->CTLR |= CR_STRT_Set;
  932. while(FLASH->STATR & SR_BSY)
  933. ;
  934. FLASH->CTLR &= ~CR_PAGE_PG;
  935. adr += 256;
  936. }while(--i);
  937. FLASH->CTLR |= CR_FLOCK_Set;
  938. FLASH->CTLR |= CR_LOCK_Set;
  939. return status;
  940. }