FlashPrg.c 37 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844
  1. /* -----------------------------------------------------------------------------
  2. * Copyright (c) 2014 - 2019 ARM Ltd.
  3. *
  4. * This software is provided 'as-is', without any express or implied warranty.
  5. * In no event will the authors be held liable for any damages arising from
  6. * the use of this software. Permission is granted to anyone to use this
  7. * software for any purpose, including commercial applications, and to alter
  8. * it and redistribute it freely, subject to the following restrictions:
  9. *
  10. * 1. The origin of this software must not be misrepresented; you must not
  11. * claim that you wrote the original software. If you use this software in
  12. * a product, an acknowledgment in the product documentation would be
  13. * appreciated but is not required.
  14. *
  15. * 2. Altered source versions must be plainly marked as such, and must not be
  16. * misrepresented as being the original software.
  17. *
  18. * 3. This notice may not be removed or altered from any source distribution.
  19. *
  20. *
  21. * $Date: 2021-7-1
  22. * $Revision: V1.0.0
  23. *
  24. * Project: Flash Programming Functions for Puya PY32F030xx Flash
  25. * --------------------------------------------------------------------------- */
  26. /* History:
  27. * Version 1.0.0
  28. * Initial release
  29. */
  30. #include "FlashOS.h" /* FlashOS Structures */
  31. typedef volatile unsigned char vu8;
  32. typedef unsigned char u8;
  33. typedef volatile unsigned short vu16;
  34. typedef unsigned short u16;
  35. typedef volatile unsigned long vu32;
  36. typedef unsigned long u32;
  37. #define M8(adr) (*((vu8 *) (adr)))
  38. #define M16(adr) (*((vu16 *) (adr)))
  39. #define M32(adr) (*((vu32 *) (adr)))
  40. #define SET_BIT(REG, BIT) ((REG) |= (BIT))
  41. #define CLEAR_BIT(REG, BIT) ((REG) &= ~(BIT))
  42. #define READ_BIT(REG, BIT) ((REG) & (BIT))
  43. #define CLEAR_REG(REG) ((REG) = (0x0))
  44. #define WRITE_REG(REG, VAL) ((REG) = (VAL))
  45. #define READ_REG(REG) ((REG))
  46. #define MODIFY_REG(REG, CLEARMASK, SETMASK) WRITE_REG((REG), (((READ_REG(REG)) & (~(CLEARMASK))) | (SETMASK)))
  47. /* Peripheral Memory Map */
  48. #define FLASH_BASE (0x08000000UL) /*!< FLASH base address */
  49. #define FLASH_END (0x0803FFFFUL) /*!< FLASH end address */
  50. #define FLASH_SIZE (FLASH_END - FLASH_BASE + 1)
  51. #define FLASH_PAGE_SIZE 0x00000100U /*!< FLASH Page Size, 256 Bytes */
  52. #define FLASH_PAGE_NB (FLASH_SIZE / FLASH_PAGE_SIZE)
  53. #define FLASH_SECTOR_SIZE 0x00002000U /*!< FLASH Sector Size, 8k Bytes */
  54. #define FLASH_SECTOR_NB (FLASH_SIZE / FLASH_SECTOR_SIZE)
  55. #define SRAM1_BASE (0x20000000UL) /*!< SRAM1(8 KB) base address */
  56. #define SRAM2_BASE (0x20002000UL) /*!< SRAM2(24 KB) base address */
  57. #define OB_BASE (0x1FFF1D00UL) /*!< Flash Option Bytes base address */
  58. #define UID_BASE (0x1FFF1C00UL) /*!< Unique device ID register base address */
  59. #define OTP_BASE (0x1FFF1A00UL)
  60. #define RCC_BASE 0x40021000
  61. #define IWDG_BASE 0x40003000
  62. #define WWDG_BASE 0x40002C00
  63. #define FLASH_R_BASE 0x40022000
  64. #define FLAHS_SIZE_ADDR 0x1FFF1FFC
  65. #define FLAHS_BANK_SIZE (((M32(FLAHS_SIZE_ADDR) & 0x3) + 1) * 32 * 1024)
  66. #define RCC ((RCC_TypeDef*) RCC_BASE)
  67. #define IWDG ((IWDG_TypeDef *) IWDG_BASE)
  68. #define WWDG ((WWDG_TypeDef *) WWDG_BASE)
  69. #define FLASH ((FLASH_TypeDef*) FLASH_R_BASE)
  70. #define HSI_24M_TRIM_ADDR (0x1FFF1E10UL)
  71. #define FLASH_24M_TRIM_ADDR (0x1FFF1E98UL)
  72. /**
  73. * @brief RCC Registers
  74. */
  75. typedef struct
  76. {
  77. vu32 CR; /*!< RCC CR Register, Address offset: 0x00 */
  78. vu32 ICSCR; /*!< RCC ICSCR Register, Address offset: 0x04 */
  79. } RCC_TypeDef;
  80. /**
  81. * @brief IWDG Registers
  82. */
  83. typedef struct
  84. {
  85. vu32 KR; /*!< IWDG KR Register, Address offset: 0x0 */
  86. vu32 PR; /*!< IWDG PR Register, Address offset: 0x4 */
  87. vu32 RLR; /*!< IWDG RLR Register, Address offset: 0x8 */
  88. vu32 SR; /*!< IWDG SR Register, Address offset: 0xC */
  89. vu32 ICNTR; /*!< IWDG ICNTR Register, Address offset: 0x10 */
  90. vu32 ICR; /*!< IWDG ICR Register, Address offset: 0x14 */
  91. } IWDG_TypeDef;
  92. /**
  93. * @brief WWDG Registers
  94. */
  95. typedef struct
  96. {
  97. vu32 CR; /*!< WWDR CR Register, Address offset: 0x0 */
  98. vu32 CFR; /*!< WWDG CFR Register, Address offset: 0x4 */
  99. vu32 SR; /*!< WWDG SR Register, Address offset: 0x8 */
  100. } WWDG_TypeDef;
  101. /**
  102. * @brief FLASH Registers
  103. */
  104. typedef struct
  105. {
  106. vu32 ACR; /*!< FLASH ACR Register, Address offset: 0x00 */
  107. vu32 RESERVED1;
  108. vu32 KEYR; /*!< FLASH KEYR Register, Address offset: 0x08 */
  109. vu32 OPTKEYR; /*!< FLASH OPTKEYR Register, Address offset: 0x0C */
  110. vu32 SR; /*!< FLASH SR Register, Address offset: 0x10 */
  111. vu32 CR; /*!< FLASH CR Register, Address offset: 0x14 */
  112. vu32 ECCR; /*!< FLASH ECCR Register, Address offset: 0x18 */
  113. vu32 RESERVED2;
  114. vu32 OPTR; /*!< FLASH OPTR Register, Address offset: 0x20 */
  115. vu32 RESERVED3;
  116. vu32 WRPR; /*!< FLASH WRPR Register, Address offset: 0x28 */
  117. vu32 RESERVED4;
  118. vu32 PCROPR0; /*!< FLASH PCROPR0 Register, Address offset: 0x30 */
  119. vu32 PCROPR1; /*!< FLASH PCROPR1 Register, Address offset: 0x34 */
  120. vu32 RESERVED5[22];
  121. vu32 LPCR; /*!< FLASH LPCR Register, Address offset: 0x90 */
  122. vu32 RESERVED6[27];
  123. vu32 TS0; /*!< FLASH TS0 Register, Address offset: 0x100 */
  124. vu32 TS1; /*!< FLASH TS1 Register, Address offset: 0x104 */
  125. vu32 TS2P; /*!< FLASH TS2P Register, Address offset: 0x108 */
  126. vu32 TPS3; /*!< FLASH TPS3 Register, Address offset: 0x10C */
  127. vu32 TS3; /*!< FLASH TS3 Register, Address offset: 0x110 */
  128. vu32 PERTPE; /*!< FLASH PERTPE Register, Address offset: 0x114 */
  129. vu32 SMERTPE; /*!< FLASH SMERTPE Register, Address offset: 0x118 */
  130. vu32 PRGTPE; /*!< FLASH PRGTPE Register, Address offset: 0x11C */
  131. vu32 PRETPE; /*!< FLASH PRETPE Register, Address offset: 0x120 */
  132. vu32 TACLK2PW; /*!< FLASH TACLK2PW Register, Address offset: 0x124 */
  133. } FLASH_TypeDef;
  134. /* Flash Keys */
  135. #define FLASH_KEY1 ((unsigned int)0x45670123)
  136. #define FLASH_KEY2 ((unsigned int)0xCDEF89AB)
  137. #define FLASH_OPTKEY1 ((unsigned int)0x08192A3B)
  138. #define FLASH_OPTKEY2 ((unsigned int)0x4C5D6E7F)
  139. #define RCC_CR_MSIDIV_Pos (0U)
  140. #define RCC_CR_MSIDIV_Msk (0x7UL<<RCC_CR_MSIDIV_Pos) /*!< 0x00000007 */
  141. #define RCC_CR_MSIDIV RCC_CR_MSIDIV_Msk
  142. #define RCC_CR_MSIDIV_0 (0x1UL<<RCC_CR_MSIDIV_Pos) /*!< 0x00000001 */
  143. #define RCC_CR_MSIDIV_1 (0x2UL<<RCC_CR_MSIDIV_Pos) /*!< 0x00000002 */
  144. #define RCC_CR_MSIDIV_2 (0x4UL<<RCC_CR_MSIDIV_Pos) /*!< 0x00000004 */
  145. #define RCC_CR_HSIKERON_Pos (6U)
  146. #define RCC_CR_HSIKERON_Msk (0x1UL<<RCC_CR_HSIKERON_Pos) /*!< 0x00000040 */
  147. #define RCC_CR_HSIKERON RCC_CR_HSIKERON_Msk
  148. #define RCC_CR_MSION_Pos (7U)
  149. #define RCC_CR_MSION_Msk (0x1UL<<RCC_CR_MSION_Pos) /*!< 0x00000080 */
  150. #define RCC_CR_MSION RCC_CR_MSION_Msk
  151. #define RCC_CR_HSION_Pos (8U)
  152. #define RCC_CR_HSION_Msk (0x1UL<<RCC_CR_HSION_Pos) /*!< 0x00000100 */
  153. #define RCC_CR_HSION RCC_CR_HSION_Msk
  154. #define RCC_CR_MSIRDY_Pos (9U)
  155. #define RCC_CR_MSIRDY_Msk (0x1UL<<RCC_CR_MSIRDY_Pos) /*!< 0x00000200 */
  156. #define RCC_CR_MSIRDY RCC_CR_MSIRDY_Msk
  157. #define RCC_CR_HSIRDY_Pos (10U)
  158. #define RCC_CR_HSIRDY_Msk (0x1UL<<RCC_CR_HSIRDY_Pos) /*!< 0x00000400 */
  159. #define RCC_CR_HSIRDY RCC_CR_HSIRDY_Msk
  160. #define RCC_CR_HSIDIV_Pos (11U)
  161. #define RCC_CR_HSIDIV_Msk (0x7UL<<RCC_CR_HSIDIV_Pos) /*!< 0x00003800 */
  162. #define RCC_CR_HSIDIV RCC_CR_HSIDIV_Msk
  163. #define RCC_CR_HSIDIV_0 (0x1UL<<RCC_CR_HSIDIV_Pos) /*!< 0x00000800 */
  164. #define RCC_CR_HSIDIV_1 (0x2UL<<RCC_CR_HSIDIV_Pos) /*!< 0x00001000 */
  165. #define RCC_CR_HSIDIV_2 (0x4UL<<RCC_CR_HSIDIV_Pos) /*!< 0x00002000 */
  166. #define RCC_ICSCR_HSI_TRIMCR_Pos (0U)
  167. #define RCC_ICSCR_HSI_TRIMCR_Msk (0x1FFFUL<<RCC_ICSCR_HSI_TRIMCR_Pos) /*!< 0x00001FFF */
  168. #define RCC_ICSCR_HSI_TRIMCR RCC_ICSCR_HSI_TRIMCR_Msk
  169. #define RCC_ICSCR_HSI_FS_OPCR_Pos (13U)
  170. #define RCC_ICSCR_HSI_FS_OPCR_Msk (0x7UL<<RCC_ICSCR_HSI_FS_OPCR_Pos) /*!< 0x0000E000 */
  171. #define RCC_ICSCR_HSI_FS_OPCR RCC_ICSCR_HSI_FS_OPCR_Msk
  172. #define RCC_ICSCR_HSI_FS_OPCR_0 (0x1UL<<RCC_ICSCR_HSI_FS_OPCR_Pos) /*!< 0x00002000 */
  173. #define RCC_ICSCR_HSI_FS_OPCR_1 (0x2UL<<RCC_ICSCR_HSI_FS_OPCR_Pos) /*!< 0x00004000 */
  174. #define RCC_ICSCR_HSI_FS_OPCR_2 (0x4UL<<RCC_ICSCR_HSI_FS_OPCR_Pos) /*!< 0x00008000 */
  175. /********************************* Bit definition for FLASH_ACR register ********************************************/
  176. #define FLASH_ACR_LATENCY_Pos (0U)
  177. #define FLASH_ACR_LATENCY_Msk (0x3UL<<FLASH_ACR_LATENCY_Pos) /*!< 0x00000003 */
  178. #define FLASH_ACR_LATENCY FLASH_ACR_LATENCY_Msk /*!< Latency */
  179. #define FLASH_ACR_LATENCY_0 (0x1UL<<FLASH_ACR_LATENCY_Pos) /*!< 0x00000001 */
  180. #define FLASH_ACR_LATENCY_1 (0x2UL<<FLASH_ACR_LATENCY_Pos) /*!< 0x00000002 */
  181. /********************************* Bit definition for FLASH_SR register *********************************************/
  182. #define FLASH_SR_EOP_Pos (0U)
  183. #define FLASH_SR_EOP_Msk (0x1UL<<FLASH_SR_EOP_Pos) /*!< 0x00000001 */
  184. #define FLASH_SR_EOP FLASH_SR_EOP_Msk /*!< End of operation */
  185. #define FLASH_SR_WRPERR_Pos (4U)
  186. #define FLASH_SR_WRPERR_Msk (0x1UL<<FLASH_SR_WRPERR_Pos) /*!< 0x00000010 */
  187. #define FLASH_SR_WRPERR FLASH_SR_WRPERR_Msk /*!< Write protection error */
  188. #define FLASH_SR_OPTVERR_Pos (15U)
  189. #define FLASH_SR_OPTVERR_Msk (0x1UL<<FLASH_SR_OPTVERR_Pos) /*!< 0x00008000 */
  190. #define FLASH_SR_OPTVERR FLASH_SR_OPTVERR_Msk /*!< Option and trimming bits loading validity error */
  191. #define FLASH_SR_BSY0_Pos (16U)
  192. #define FLASH_SR_BSY0_Msk (0x1UL<<FLASH_SR_BSY0_Pos) /*!< 0x00010000 */
  193. #define FLASH_SR_BSY0 FLASH_SR_BSY0_Msk /*!< Bank0 Busy */
  194. #define FLASH_SR_BSY1_Pos (17U)
  195. #define FLASH_SR_BSY1_Msk (0x1UL<<FLASH_SR_BSY1_Pos) /*!< 0x00020000 */
  196. #define FLASH_SR_BSY1 FLASH_SR_BSY1_Msk /*!< Bank1 Busy */
  197. /********************************* Bit definition for FLASH_CR register *********************************************/
  198. #define FLASH_CR_PG_Pos (0U)
  199. #define FLASH_CR_PG_Msk (0x1UL<<FLASH_CR_PG_Pos) /*!< 0x00000001 */
  200. #define FLASH_CR_PG FLASH_CR_PG_Msk /*!< Page Program */
  201. #define FLASH_CR_PER_Pos (1U)
  202. #define FLASH_CR_PER_Msk (0x1UL<<FLASH_CR_PER_Pos) /*!< 0x00000002 */
  203. #define FLASH_CR_PER FLASH_CR_PER_Msk /*!< Page Erase */
  204. #define FLASH_CR_MER0_Pos (2U)
  205. #define FLASH_CR_MER0_Msk (0x1UL<<FLASH_CR_MER0_Pos) /*!< 0x00000004 */
  206. #define FLASH_CR_MER0 FLASH_CR_MER0_Msk /*!< Bank 0 Mass Erase */
  207. #define FLASH_CR_MER1_Pos (3U)
  208. #define FLASH_CR_MER1_Msk (0x1UL<<FLASH_CR_MER1_Pos) /*!< 0x00000008 */
  209. #define FLASH_CR_MER1 FLASH_CR_MER1_Msk /*!< Bank 1 Mass Erase */
  210. #define FLASH_CR_UPG_Pos (4U)
  211. #define FLASH_CR_UPG_Msk (0x1UL<<FLASH_CR_UPG_Pos) /*!< 0x00000010 */
  212. #define FLASH_CR_UPG FLASH_CR_UPG_Msk /*!< Userdata Program */
  213. #define FLASH_CR_UPER_Pos (5U)
  214. #define FLASH_CR_UPER_Msk (0x1UL<<FLASH_CR_UPER_Pos) /*!< 0x00000020 */
  215. #define FLASH_CR_UPER FLASH_CR_UPER_Msk /*!< Userdata Page Erase */
  216. #define FLASH_CR_SER_Pos (11U)
  217. #define FLASH_CR_SER_Msk (0x1UL<<FLASH_CR_SER_Pos) /*!< 0x00000800 */
  218. #define FLASH_CR_SER FLASH_CR_SER_Msk /*!< Sector Erase */
  219. #define FLASH_CR_OPTSTRT_Pos (17U)
  220. #define FLASH_CR_OPTSTRT_Msk (0x1UL<<FLASH_CR_OPTSTRT_Pos) /*!< 0x00020000 */
  221. #define FLASH_CR_OPTSTRT FLASH_CR_OPTSTRT_Msk /*!< Option bytes Programming Start */
  222. #define FLASH_CR_UPGSTRT_Pos (18U)
  223. #define FLASH_CR_UPGSTRT_Msk (0x1UL<<FLASH_CR_UPGSTRT_Pos) /*!< 0x00040000 */
  224. #define FLASH_CR_UPGSTRT FLASH_CR_UPGSTRT_Msk /*!< Userdata Programming Start */
  225. #define FLASH_CR_PGSTRT_Pos (19U)
  226. #define FLASH_CR_PGSTRT_Msk (0x1UL<<FLASH_CR_PGSTRT_Pos) /*!< 0x00080000 */
  227. #define FLASH_CR_PGSTRT FLASH_CR_PGSTRT_Msk /*!< Programming Start */
  228. #define FLASH_CR_RDERR0IE_Pos (22U)
  229. #define FLASH_CR_RDERR0IE_Msk (0x1UL<<FLASH_CR_RDERR0IE_Pos) /*!< 0x00400000 */
  230. #define FLASH_CR_RDERR0IE FLASH_CR_RDERR0IE_Msk /*!< Bank0 pcrop read error interrupt enable */
  231. #define FLASH_CR_RDERR1IE_Pos (23U)
  232. #define FLASH_CR_RDERR1IE_Msk (0x1UL<<FLASH_CR_RDERR1IE_Pos) /*!< 0x00800000 */
  233. #define FLASH_CR_RDERR1IE FLASH_CR_RDERR1IE_Msk /*!< Bank1 pcrop read error interrupt enable */
  234. #define FLASH_CR_EOPIE_Pos (24U)
  235. #define FLASH_CR_EOPIE_Msk (0x1UL<<FLASH_CR_EOPIE_Pos) /*!< 0x01000000 */
  236. #define FLASH_CR_EOPIE FLASH_CR_EOPIE_Msk /*!< End of operation interrupt enable */
  237. #define FLASH_CR_ERRIE_Pos (25U)
  238. #define FLASH_CR_ERRIE_Msk (0x1UL<<FLASH_CR_ERRIE_Pos) /*!< 0x02000000 */
  239. #define FLASH_CR_ERRIE FLASH_CR_ERRIE_Msk /*!< Error interrupt enable */
  240. #define FLASH_CR_OBL_LAUNCH_Pos (27U)
  241. #define FLASH_CR_OBL_LAUNCH_Msk (0x1UL<<FLASH_CR_OBL_LAUNCH_Pos) /*!< 0x08000000 */
  242. #define FLASH_CR_OBL_LAUNCH FLASH_CR_OBL_LAUNCH_Msk /*!< Force the option bytes loading */
  243. #define FLASH_CR_OPTLOCK_Pos (30U)
  244. #define FLASH_CR_OPTLOCK_Msk (0x1UL<<FLASH_CR_OPTLOCK_Pos) /*!< 0x40000000 */
  245. #define FLASH_CR_OPTLOCK FLASH_CR_OPTLOCK_Msk /*!< Option Lock */
  246. #define FLASH_CR_LOCK_Pos (31U)
  247. #define FLASH_CR_LOCK_Msk (0x1UL<<FLASH_CR_LOCK_Pos) /*!< 0x80000000 */
  248. #define FLASH_CR_LOCK FLASH_CR_LOCK_Msk /*!< Lock */
  249. #define FLASH_OPTR_IWDG_STDBY_Pos (10U)
  250. #define FLASH_OPTR_IWDG_STDBY_Msk (0x1UL<<FLASH_OPTR_IWDG_STDBY_Pos) /*!< 0x00000400 */
  251. #define FLASH_OPTR_IWDG_STDBY FLASH_OPTR_IWDG_STDBY_Msk /*!< IWDG Standy Count Control */
  252. #define FLASH_OPTR_IWDG_STOP_Pos (11U)
  253. #define FLASH_OPTR_IWDG_STOP_Msk (0x1UL<<FLASH_OPTR_IWDG_STOP_Pos) /*!< 0x00000800 */
  254. #define FLASH_OPTR_IWDG_STOP FLASH_OPTR_IWDG_STOP_Msk /*!< IWDG Stop Count Control */
  255. #define FLASH_OPTR_IWDG_SW_Pos (12U)
  256. #define FLASH_OPTR_IWDG_SW_Msk (0x1UL<<FLASH_OPTR_IWDG_SW_Pos) /*!< 0x00001000 */
  257. #define FLASH_OPTR_IWDG_SW FLASH_OPTR_IWDG_SW_Msk /*!< IWDG Software Enable */
  258. #define FLASH_OPTR_WWDG_SW_Pos (13U)
  259. #define FLASH_OPTR_WWDG_SW_Msk (0x1UL<<FLASH_OPTR_WWDG_SW_Pos) /*!< 0x00002000 */
  260. #define FLASH_OPTR_WWDG_SW FLASH_OPTR_WWDG_SW_Msk /*!< WWDG Software Enable */
  261. #define FLASH_OPTR_BFB_Pos (23U)
  262. #define FLASH_OPTR_BFB_Msk (0x1UL<<FLASH_OPTR_BFB_Pos) /*!< 0x00800000 */
  263. #define FLASH_OPTR_BFB FLASH_OPTR_BFB_Msk /*!< Boot Flash Bank */
  264. #define WWDG_CR_T_Pos (0U)
  265. #define WWDG_CR_T_Msk (0x7FUL<<WWDG_CR_T_Pos) /*!< 0x0000007F */
  266. #define WWDG_CR_T WWDG_CR_T_Msk /*!< wwdg counter bit6 */
  267. #define WWDG_CR_WDGA_Pos (7U)
  268. #define WWDG_CR_WDGA_Msk (0x1UL<<WWDG_CR_WDGA_Pos) /*!< 0x00000080 */
  269. #define WWDG_CR_WDGA WWDG_CR_WDGA_Msk /*!< WWDG Activation */
  270. #define WWDG_CFR_W_Pos (0U)
  271. #define WWDG_CFR_W_Msk (0x7FUL<<WWDG_CFR_W_Pos) /*!< 0x0000007F */
  272. #define WWDG_CFR_W WWDG_CFR_W_Msk /*!< window value bit 6 */
  273. #define WWDG_CFR_WDGTB_Pos (7U)
  274. #define WWDG_CFR_WDGTB_Msk (0x3UL<<WWDG_CFR_WDGTB_Pos) /*!< 0x00000180 */
  275. #define WWDG_CFR_WDGTB WWDG_CFR_WDGTB_Msk /*!< time base bit 1 */
  276. #define WWDG_CFR_WDGTB_0 (0x1UL<<WWDG_CFR_WDGTB_Pos) /*!< 0x00000080 */
  277. #define WWDG_CFR_WDGTB_1 (0x2UL<<WWDG_CFR_WDGTB_Pos) /*!< 0x00000100 */
  278. #define WWDG_CFR_EWI_Pos (9U)
  279. #define WWDG_CFR_EWI_Msk (0x1UL<<WWDG_CFR_EWI_Pos) /*!< 0x00000200 */
  280. #define WWDG_CFR_EWI WWDG_CFR_EWI_Msk /*!< Early wakeup interrupt */
  281. int ErasePage(unsigned long adr);
  282. u32 RCC_ICSCR_HSI_FS_RESTORE;
  283. void InitRccAndFlashParam(void);
  284. void UnInitRccAndFlashParam(void);
  285. /*
  286. * Initialize Flash Programming Functions
  287. * Parameter: adr: Device Base Address
  288. * clk: Clock Frequency (Hz)
  289. * fnc: Function Code (1 - Erase, 2 - Program, 3 - Verify)
  290. * Return Value: 0 - OK, 1 - Failed
  291. */
  292. int Init(unsigned long adr, unsigned long clk, unsigned long fnc)
  293. {
  294. FLASH->KEYR = FLASH_KEY1; /* Unlock Flash */
  295. FLASH->KEYR = FLASH_KEY2;
  296. InitRccAndFlashParam();
  297. #ifdef FLASH_OB
  298. FLASH->OPTKEYR = FLASH_OPTKEY1; /* Unlock Option Bytes */
  299. FLASH->OPTKEYR = FLASH_OPTKEY2;
  300. #endif
  301. FLASH->ACR &= ~FLASH_ACR_LATENCY; /* Zero Wait State, no Prefetch */
  302. FLASH->SR |= FLASH_SR_EOP; /* Clear EOP flag */
  303. while (FLASH->SR & (FLASH_SR_BSY0 | FLASH_SR_BSY1)); /* Check FLASH_SR_BSY */
  304. if ((FLASH->OPTR & FLASH_OPTR_WWDG_SW) == 0) /* Test if WWDG is running (IWDG in HW mode) */
  305. {
  306. /* Set WWDG time out to maximum */
  307. WWDG->CFR |= WWDG_CFR_WDGTB; /* Set prescaler to maximum */
  308. SET_BIT(WWDG->CR, WWDG_CR_T); /* Reload WWDG */
  309. }
  310. if ((FLASH->OPTR & FLASH_OPTR_IWDG_SW) == 0) /* Test if IWDG is running (IWDG in HW mode) */
  311. {
  312. /* Set IWDG time out to maximum */
  313. IWDG->KR = 0xAAAA; /* Reload IWDG */
  314. IWDG->KR = 0x5555; /* Enable write access to IWDG_PR and IWDG_RLR */
  315. IWDG->PR = 0x06; /* Set prescaler to maximum */
  316. IWDG->RLR = 0xFFF; /* Set reload value to maximum */
  317. }
  318. return (0);
  319. }
  320. /*
  321. * De-Initialize Flash Programming Functions
  322. * Parameter: fnc: Function Code (1 - Erase, 2 - Program, 3 - Verify)
  323. * Return Value: 0 - OK, 1 - Failed
  324. */
  325. int UnInit(unsigned long fnc)
  326. {
  327. UnInitRccAndFlashParam();
  328. FLASH->CR |= FLASH_CR_LOCK; /* Lock Flash */
  329. #ifdef FLASH_OB
  330. FLASH->CR |= FLASH_CR_OPTLOCK; /* Lock Option Bytes */
  331. #endif
  332. return (0);
  333. }
  334. /*
  335. * Erase complete Flash Memory
  336. * Return Value: 0 - OK, 1 - Failed
  337. */
  338. int EraseChip(void)
  339. {
  340. #ifdef FLASH_OTP
  341. EraseSector(OTP_BASE);
  342. #endif /* FLASH_OTP */
  343. #ifdef FLASH_MEM
  344. FLASH->SR |= FLASH_SR_EOP; /* Reset FLASH_EOP */
  345. if (READ_BIT(FLASH->OPTR, FLASH_OPTR_BFB) != FLASH_OPTR_BFB)
  346. {
  347. FLASH->CR |= FLASH_CR_MER0; /* Mass BANK0 Erase Enabled */
  348. FLASH->CR |= FLASH_CR_EOPIE;
  349. M32(FLASH_BASE) = 0xFF; /*BANK0*/
  350. __asm("DSB");
  351. while (FLASH->SR & (FLASH_SR_BSY0 | FLASH_SR_BSY1))
  352. {
  353. WWDG->CR |= WWDG_CR_T; /* Reload WWDG */
  354. IWDG->KR = 0xAAAAU; /* Reload IWDG */
  355. }
  356. if (FLASH_SR_EOP != (FLASH->SR & FLASH_SR_EOP)) /* Check for FLASH_SR_EOP */
  357. {
  358. FLASH->SR |= FLASH_SR_EOP; /* Reset FLASH_EOP */
  359. return (1); /* Failed */
  360. }
  361. FLASH->CR &= ~(FLASH_CR_MER0); /* Mass Erase Disabled */
  362. FLASH->CR &= ~FLASH_CR_EOPIE; /* Reset FLASH_EOPIE */
  363. FLASH->SR |= FLASH_SR_EOP; /* Reset FLASH_EOP */
  364. FLASH->CR |= FLASH_CR_MER1; /* Mass BANK1 Erase Enabled */
  365. FLASH->CR |= FLASH_CR_EOPIE;
  366. M32(FLASH_BASE + FLAHS_BANK_SIZE) = 0xFF; /*BANK1*/
  367. }
  368. else
  369. {
  370. FLASH->CR |= FLASH_CR_MER1; /* Mass BANK1 Erase Enabled */
  371. FLASH->CR |= FLASH_CR_EOPIE;
  372. M32(FLASH_BASE + FLAHS_BANK_SIZE) = 0xFF; /*BANK1*/
  373. __asm("DSB");
  374. while (FLASH->SR & (FLASH_SR_BSY0 | FLASH_SR_BSY1))
  375. {
  376. WWDG->CR |= WWDG_CR_T; /* Reload WWDG */
  377. IWDG->KR = 0xAAAAU; /* Reload IWDG */
  378. }
  379. if (FLASH_SR_EOP != (FLASH->SR & FLASH_SR_EOP)) /* Check for FLASH_SR_EOP */
  380. {
  381. FLASH->SR |= FLASH_SR_EOP; /* Reset FLASH_EOP */
  382. return (1); /* Failed */
  383. }
  384. FLASH->CR &= ~(FLASH_CR_MER1); /* Mass Erase Disabled */
  385. FLASH->CR &= ~FLASH_CR_EOPIE; /* Reset FLASH_EOPIE */
  386. FLASH->SR |= FLASH_SR_EOP; /* Reset FLASH_EOP */
  387. FLASH->CR |= FLASH_CR_MER0; /* Mass BANK0 Erase Enabled */
  388. FLASH->CR |= FLASH_CR_EOPIE;
  389. M32(FLASH_BASE) = 0xFF; /*BANK0*/
  390. }
  391. __asm("DSB");
  392. while (FLASH->SR & (FLASH_SR_BSY0 | FLASH_SR_BSY1))
  393. {
  394. WWDG->CR |= WWDG_CR_T; /* Reload WWDG */
  395. IWDG->KR = 0xAAAAU; /* Reload IWDG */
  396. }
  397. if (FLASH_SR_EOP != (FLASH->SR & FLASH_SR_EOP)) /* Check for FLASH_SR_EOP */
  398. {
  399. FLASH->SR |= FLASH_SR_EOP; /* Reset FLASH_EOP */
  400. return (1); /* Failed */
  401. }
  402. FLASH->CR &= ~(FLASH_CR_MER0 | FLASH_CR_MER1); /* Mass Erase Disabled */
  403. FLASH->CR &= ~FLASH_CR_EOPIE; /* Reset FLASH_EOPIE */
  404. #endif /* FLASH_MEM */
  405. return (0); /* Done */
  406. }
  407. /*
  408. * Erase Sector in Flash Memory
  409. * Parameter: adr: Sector Address
  410. * Return Value: 0 - OK, 1 - Failed
  411. */
  412. #ifdef FLASH_MEM
  413. int EraseSector(unsigned long adr)
  414. {
  415. FLASH->SR |= FLASH_SR_EOP; /* Clear EOP flag */
  416. FLASH->CR |= FLASH_CR_SER; /* Sector Erase Enabled */
  417. FLASH->CR |= FLASH_CR_EOPIE;
  418. M32(adr) = 0xFFFFFFFF; /* Sector Address */
  419. while (FLASH->SR & (FLASH_SR_BSY0 | FLASH_SR_BSY1))
  420. {
  421. WWDG->CR |= WWDG_CR_T; /* Reload WWDG */
  422. IWDG->KR = 0xAAAAU; /* Reload IWDG */
  423. }
  424. if (FLASH_SR_EOP != (FLASH->SR & FLASH_SR_EOP)) /* Check for FLASH_SR_EOP */
  425. {
  426. FLASH->SR |= FLASH_SR_EOP; /* Reset FLASH_EOP */
  427. return (1); /* Failed */
  428. }
  429. FLASH->CR &= ~FLASH_CR_SER; /* Sector Erase Disabled */
  430. FLASH->CR &= ~FLASH_CR_EOPIE;
  431. return (0); /* Done */
  432. }
  433. #endif
  434. #ifdef FLASH_OTP
  435. int EraseSector(unsigned long adr)
  436. {
  437. FLASH->SR |= FLASH_SR_EOP;
  438. FLASH->CR |= FLASH_CR_UPER;
  439. FLASH->CR |= FLASH_CR_EOPIE;
  440. M32(adr) = 0xFF;
  441. __asm("DSB");
  442. while (FLASH->SR & (FLASH_SR_BSY0 | FLASH_SR_BSY1))
  443. {
  444. WWDG->CR |= WWDG_CR_T;
  445. IWDG->KR = 0xAAAAU;
  446. }
  447. if (FLASH_SR_EOP != (FLASH->SR & FLASH_SR_EOP)) /* Check for FLASH_SR_EOP */
  448. {
  449. FLASH->SR |= FLASH_SR_EOP; /* Reset FLASH_EOP */
  450. return (1); /* Failed */
  451. }
  452. FLASH->CR &= ~FLASH_CR_UPER;
  453. FLASH->CR &= ~FLASH_CR_EOPIE;
  454. return (0); /* Done */
  455. }
  456. #endif /* FLASH_OTP */
  457. #ifdef FLASH_OB
  458. int EraseSector(unsigned long adr)
  459. {
  460. return (0);
  461. }
  462. #endif /* FLASH_OB */
  463. /*
  464. * Program Page in Flash Memory
  465. * Parameter: adr: Page Start Address
  466. * sz: Page Size
  467. * buf: Page Data
  468. * Return Value: 0 - OK, 1 - Failed
  469. */
  470. #ifdef FLASH_MEM
  471. int ProgramPage(unsigned long adr, unsigned long sz, unsigned char *buf)
  472. {
  473. sz = (sz + (FLASH_PAGE_SIZE - 1)) & ~(FLASH_PAGE_SIZE - 1); /* Adjust size for 32 Words */
  474. SET_BIT(FLASH->SR, FLASH_SR_EOP); /* Clear EOP flag */
  475. while (sz)
  476. {
  477. FLASH->CR |= FLASH_CR_PG; /* Programming Enabled */
  478. for (u8 i = 0; i < FLASH_PAGE_SIZE / 4; i++)
  479. {
  480. M32(adr + i * 4) = *((u32 *)(buf + i * 4)); /* Program the first word of the Double Word */
  481. if (i == (FLASH_PAGE_SIZE / 4 - 2))
  482. {
  483. FLASH->CR |= FLASH_CR_PGSTRT;
  484. }
  485. }
  486. __asm("DSB");
  487. while (FLASH->SR & (FLASH_SR_BSY0 | FLASH_SR_BSY1))
  488. {
  489. WWDG->CR |= WWDG_CR_T;
  490. IWDG->KR = 0x0000AAAAU;
  491. }
  492. if (FLASH_SR_EOP != (FLASH->SR & FLASH_SR_EOP)) /* Check for FLASH_SR_EOP */
  493. {
  494. FLASH->SR |= FLASH_SR_EOP; /* Reset FLASH_EOP */
  495. return (1); /* Failed */
  496. }
  497. FLASH->CR &= ~FLASH_CR_PG; /* Programming Disabled */
  498. FLASH->CR &= ~FLASH_CR_EOPIE; /* Reset FLASH_EOPIE */
  499. adr += FLASH_PAGE_SIZE; /* Go to next Page */
  500. buf += FLASH_PAGE_SIZE;
  501. sz -= FLASH_PAGE_SIZE;
  502. }
  503. return (0); /* Done */
  504. }
  505. #endif /* FLASH_MEM */
  506. #ifdef FLASH_OTP
  507. int ProgramPage(unsigned long adr, unsigned long sz, unsigned char *buf)
  508. {
  509. sz = (sz + (FLASH_PAGE_SIZE - 1)) & ~(FLASH_PAGE_SIZE - 1); /* Adjust size for 32 Words */
  510. SET_BIT(FLASH->SR, FLASH_SR_EOP); /* Clear EOP flag */
  511. while (sz)
  512. {
  513. FLASH->CR |= FLASH_CR_UPG; /* Programming Enabled */
  514. for (u8 i = 0; i < FLASH_PAGE_SIZE / 4; i++)
  515. {
  516. M32(adr + i * 4) = *((u32 *)(buf + i * 4)); /* Program the first word of the Double Word */
  517. if (i == (FLASH_PAGE_SIZE / 4 - 2))
  518. {
  519. FLASH->CR |= FLASH_CR_PGSTRT;
  520. }
  521. }
  522. while (FLASH->SR & (FLASH_SR_BSY0 | FLASH_SR_BSY1))
  523. {
  524. WWDG->CR |= WWDG_CR_T;
  525. IWDG->KR = 0x0000AAAAU;
  526. }
  527. if (FLASH_SR_EOP != (FLASH->SR & FLASH_SR_EOP)) /* Check for FLASH_SR_EOP */
  528. {
  529. FLASH->SR |= FLASH_SR_EOP; /* Reset FLASH_EOP */
  530. return (1); /* Failed */
  531. }
  532. FLASH->CR &= ~FLASH_CR_UPG; /* Programming Disabled */
  533. adr += FLASH_PAGE_SIZE; /* Go to next Page */
  534. buf += FLASH_PAGE_SIZE;
  535. sz -= FLASH_PAGE_SIZE;
  536. }
  537. return (0); /* Done */
  538. }
  539. #endif /* FLASH_OTP */
  540. #ifdef FLASH_OB
  541. int ProgramPage(unsigned long adr, unsigned long sz, unsigned char *buf)
  542. {
  543. u32 optr;
  544. u32 wrpr;
  545. u32 pcropr0;
  546. u32 pcropr1;
  547. optr = M16(buf + 0x00) | (M16(buf + 0x04) << 16);
  548. wrpr = M16(buf + 0x10) | (M16(buf + 0x14) << 16);
  549. pcropr0 = M16(buf + 0x18) | (M16(buf + 0x1C) << 16);
  550. pcropr1 = M32(buf + 0x20) | (M16(buf + 0x24) << 16);
  551. FLASH->SR |= FLASH_SR_EOP; /* Reset FLASH_EOP */
  552. FLASH->OPTR = optr & 0x03FFFFFF;
  553. FLASH->WRPR = wrpr & 0xFFFFFFFF;
  554. FLASH->PCROPR0 = pcropr0 & 0x01FF01FF;
  555. FLASH->PCROPR1 = pcropr1 & 0x01FF01FF;
  556. FLASH->CR |= FLASH_CR_OPTSTRT;
  557. FLASH->CR |= FLASH_CR_EOPIE;
  558. M32(0x1FFF1D00) = 0xFFFFFFFF;
  559. while (FLASH->SR & (FLASH_SR_BSY0 | FLASH_SR_BSY1))
  560. {
  561. WWDG->CR |= WWDG_CR_T;
  562. IWDG->KR = 0xAAAAU;
  563. }
  564. if (FLASH_SR_EOP != (FLASH->SR & FLASH_SR_EOP)) /* Check for FLASH_SR_EOP */
  565. {
  566. FLASH->SR |= FLASH_SR_EOP; /* Reset FLASH_EOP */
  567. return (1); /* Failed */
  568. }
  569. FLASH->CR &= ~FLASH_CR_OPTSTRT; /* Programming Disabled */
  570. FLASH->CR &= ~FLASH_CR_EOPIE; /* Reset FLASH_EOPIE */
  571. return (0); /* Done */
  572. }
  573. #endif /* FLASH_OB */
  574. #ifdef FLASH_OB
  575. unsigned long Verify(unsigned long adr, unsigned long sz, unsigned char *buf)
  576. {
  577. unsigned long baseaddr = 0x1FFF1D00;
  578. unsigned long offset = 0;
  579. if (adr != baseaddr || sz < 0x24)
  580. {
  581. return (adr);
  582. }
  583. if (M16(buf + offset) != M16(baseaddr + offset))
  584. {
  585. return (baseaddr + offset);
  586. }
  587. offset = 0x4;
  588. if (M16(buf + offset) != M16(baseaddr + offset))
  589. {
  590. return (baseaddr + offset);
  591. }
  592. offset = 0x10;
  593. if (M16(buf + offset) != M16(baseaddr + offset))
  594. {
  595. return (baseaddr + offset);
  596. }
  597. offset = 0x14;
  598. if (M16(buf + offset) != M16(baseaddr + offset))
  599. {
  600. return (baseaddr + offset);
  601. }
  602. offset = 0x18;
  603. if (M16(buf + offset) != M16(baseaddr + offset))
  604. {
  605. return (baseaddr + offset);
  606. }
  607. offset = 0x1C;
  608. if (M16(buf + offset) != M16(baseaddr + offset))
  609. {
  610. return (baseaddr + offset);
  611. }
  612. offset = 0x20;
  613. if (M16(buf + offset) != M16(baseaddr + offset))
  614. {
  615. return (baseaddr + offset);
  616. }
  617. offset = 0x24;
  618. if (M16(buf + offset) != M16(baseaddr + offset))
  619. {
  620. return (baseaddr + offset);
  621. }
  622. return (adr + sz);
  623. }
  624. #endif /* FLASH_OB */
  625. #ifdef FLASH_MEM
  626. int ErasePage(unsigned long adr)
  627. {
  628. FLASH->SR |= FLASH_SR_EOP; /* Reset FLASH_EOP */
  629. FLASH->CR |= FLASH_CR_PER; /* page Erase Enabled */
  630. FLASH->CR |= FLASH_CR_EOPIE;
  631. M32(adr) = 0xFF; /* Sector Address */
  632. __asm("DSB");
  633. while (FLASH->SR & (FLASH_SR_BSY0 | FLASH_SR_BSY1))
  634. {
  635. WWDG->CR |= WWDG_CR_T;
  636. IWDG->KR = 0xAAAAU;
  637. }
  638. if (FLASH_SR_EOP != (FLASH->SR & FLASH_SR_EOP)) /* Check for FLASH_SR_EOP */
  639. {
  640. FLASH->SR |= FLASH_SR_EOP; /* Reset FLASH_EOP */
  641. return (1); /* Failed */
  642. }
  643. FLASH->CR &= ~FLASH_CR_PER; /* page Erase Disabled */
  644. FLASH->CR &= ~FLASH_CR_EOPIE; /* Reset FLASH_EOPIE */
  645. return (0); /* Done */
  646. }
  647. #endif /* FLASH_MEM */
  648. #define RCC_HSICALIBRATION_8MHz ((0x1<<13) | ((*(vu32 *)(0x1FFF1E04)) & 0x1FFF)) /*!< 8MHz HSI calibration trimming value */
  649. #define RCC_HSICALIBRATION_16MHz ((0x2<<13) | ((*(vu32 *)(0x1FFF1E08)) & 0x1FFF)) /*!< 16MHz HSI calibration trimming value */
  650. #define RCC_HSICALIBRATION_22p12MHz ((0x3<<13) | ((*(vu32 *)(0x1FFF1E0C)) & 0x1FFF)) /*!< 22.12MHz HSI calibration trimming value */
  651. #define RCC_HSICALIBRATION_24MHz ((0x4<<13) | ((*(vu32 *)(0x1FFF1E10)) & 0x1FFF)) /*!< 24MHz HSI calibration trimming value */
  652. #define RCC_HSICALIBRATION_48MHz ((0x5<<13) | ((*(vu32 *)(0x1FFF1E14)) & 0x1FFF)) /*!< 48MHz HSI calibration trimming value */
  653. #define RCC_HSICALIBRATION_64MHz ((0x6<<13) | ((*(vu32 *)(0x1FFF1E18)) & 0x1FFF)) /*!< 64MHz HSI calibration trimming value */
  654. /********************************* Bit definition for RCC_CR register ***********************************************/
  655. #define RCC_CR_HSIRDY_Pos (10U)
  656. #define RCC_CR_HSIRDY_Msk (0x1UL<<RCC_CR_HSIRDY_Pos) /*!< 0x00000400 */
  657. #define RCC_CR_HSIRDY RCC_CR_HSIRDY_Msk
  658. /********************************* Bit definition for RCC_ICSCR register ********************************************/
  659. #define RCC_ICSCR_HSI_TRIMCR_Pos (0U)
  660. #define RCC_ICSCR_HSI_TRIMCR_Msk (0x1FFFUL<<RCC_ICSCR_HSI_TRIMCR_Pos) /*!< 0x00001FFF */
  661. #define RCC_ICSCR_HSI_TRIMCR RCC_ICSCR_HSI_TRIMCR_Msk
  662. #define RCC_ICSCR_HSI_FS_OPCR_Pos (13U)
  663. #define RCC_ICSCR_HSI_FS_OPCR_Msk (0x7UL<<RCC_ICSCR_HSI_FS_OPCR_Pos) /*!< 0x0000E000 */
  664. #define RCC_ICSCR_HSI_FS_OPCR RCC_ICSCR_HSI_FS_OPCR_Msk
  665. #define RCC_ICSCR_HSI_FS_OPCR_0 (0x1UL<<RCC_ICSCR_HSI_FS_OPCR_Pos) /*!< 0x00002000 */
  666. #define RCC_ICSCR_HSI_FS_OPCR_1 (0x2UL<<RCC_ICSCR_HSI_FS_OPCR_Pos) /*!< 0x00004000 */
  667. #define RCC_ICSCR_HSI_FS_OPCR_2 (0x4UL<<RCC_ICSCR_HSI_FS_OPCR_Pos) /*!< 0x00008000 */
  668. /* Set HSI 24M and Triming Data */
  669. void InitRccAndFlashParam(void)
  670. {
  671. RCC_ICSCR_HSI_FS_RESTORE = READ_BIT(RCC->ICSCR, RCC_ICSCR_HSI_FS_OPCR);
  672. MODIFY_REG(RCC->ICSCR, (RCC_ICSCR_HSI_FS_OPCR | RCC_ICSCR_HSI_TRIMCR), RCC_HSICALIBRATION_24MHz); /* HSI_24MHz */
  673. while (RCC_CR_HSIRDY != READ_BIT(RCC->CR, RCC_CR_HSIRDY));
  674. }
  675. /* Set HSI and Triming Data defult*/
  676. void UnInitRccAndFlashParam(void)
  677. {
  678. MODIFY_REG(RCC->ICSCR, RCC_ICSCR_HSI_FS_OPCR, RCC_ICSCR_HSI_FS_RESTORE);
  679. switch (RCC_ICSCR_HSI_FS_RESTORE)
  680. {
  681. case (RCC_ICSCR_HSI_FS_OPCR_1|RCC_ICSCR_HSI_FS_OPCR_2): /* 64MHz */
  682. FLASH->ACR |= FLASH_ACR_LATENCY_1; /* 2 Wait State */
  683. MODIFY_REG(RCC->ICSCR, (RCC_ICSCR_HSI_FS_OPCR | RCC_ICSCR_HSI_TRIMCR), RCC_HSICALIBRATION_64MHz); /* HSI_64MHz */
  684. break;
  685. case (RCC_ICSCR_HSI_FS_OPCR_0|RCC_ICSCR_HSI_FS_OPCR_2): /* 48MHz */
  686. FLASH->ACR |= FLASH_ACR_LATENCY_0; /* 1 Wait State */
  687. MODIFY_REG(RCC->ICSCR, (RCC_ICSCR_HSI_FS_OPCR | RCC_ICSCR_HSI_TRIMCR), RCC_HSICALIBRATION_48MHz); /* HSI_48MHz */
  688. break;
  689. case RCC_ICSCR_HSI_FS_OPCR_2: /* 24MHz */
  690. MODIFY_REG(RCC->ICSCR, (RCC_ICSCR_HSI_FS_OPCR | RCC_ICSCR_HSI_TRIMCR), RCC_HSICALIBRATION_24MHz); /* HSI_24MHz */
  691. break;
  692. case (RCC_ICSCR_HSI_FS_OPCR_0|RCC_ICSCR_HSI_FS_OPCR_1): /* 22.12MHz */
  693. MODIFY_REG(RCC->ICSCR, (RCC_ICSCR_HSI_FS_OPCR | RCC_ICSCR_HSI_TRIMCR), RCC_HSICALIBRATION_22p12MHz); /* HSI_22.12MHz */
  694. break;
  695. case RCC_ICSCR_HSI_FS_OPCR_1: /* 16MHz */
  696. MODIFY_REG(RCC->ICSCR, (RCC_ICSCR_HSI_FS_OPCR | RCC_ICSCR_HSI_TRIMCR), RCC_HSICALIBRATION_16MHz); /* HSI_16MHz */
  697. break;
  698. default: /* 8MHz */
  699. MODIFY_REG(RCC->ICSCR, (RCC_ICSCR_HSI_FS_OPCR | RCC_ICSCR_HSI_TRIMCR), RCC_HSICALIBRATION_8MHz); /* HSI_16MHz */
  700. break;
  701. }
  702. while (RCC_CR_HSIRDY != READ_BIT(RCC->CR, RCC_CR_HSIRDY));
  703. }