FlashPrg.c 29 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668
  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 PY32F032xx 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 (0x0800FFFFUL) /*!< FLASH end address */
  50. #define FLASH_SIZE (FLASH_END - FLASH_BASE + 1)
  51. #define FLASH_PAGE_SIZE 0x00000080U /*!< FLASH Page Size, 128 Bytes */
  52. #define FLASH_PAGE_NB (FLASH_SIZE / FLASH_PAGE_SIZE)
  53. #define FLASH_SECTOR_SIZE 0x00001000U /*!< FLASH Sector Size, 4096 Bytes */
  54. #define FLASH_SECTOR_NB (FLASH_SIZE / FLASH_SECTOR_SIZE)
  55. #define SRAM_BASE (0x20000000UL) /*!< SRAM base address */
  56. #define SRAM_END (0x20001FFFUL) /*!< SRAM end address */
  57. #define RCC_BASE 0x40021000
  58. #define WWDG_BASE 0x40002C00
  59. #define IWDG_BASE 0x40003000
  60. #define FLASH_R_BASE 0x40022000
  61. #define OB_BASE 0x1FFF0F80UL /*!< FLASH Option Bytes base address */
  62. #define UID_BASE 0x1FFF0F00UL /*!< Unique device ID register base address */
  63. #define OTP_BASE 0x1FFF0E00UL
  64. #define RCC ((RCC_TypeDef *)RCC_BASE)
  65. #define WWDG ((WWDG_TypeDef *)WWDG_BASE)
  66. #define IWDG ((IWDG_TypeDef *)IWDG_BASE)
  67. #define FLASH ((FLASH_TypeDef *)FLASH_R_BASE)
  68. typedef struct
  69. {
  70. vu32 CR; /*!< RCC Clock Sources Control Register, Address offset: 0x00 */
  71. vu32 ICSCR; /*!< RCC Internal Clock Sources Calibration Register, Address offset: 0x04 */
  72. } RCC_TypeDef;
  73. /* Independent WATCHDOG */
  74. typedef struct
  75. {
  76. vu32 KR; /*!< IWDG Key register, Address offset: 0x00 */
  77. vu32 PR; /*!< IWDG Prescaler register, Address offset: 0x04 */
  78. vu32 RLR; /*!< IWDG Reload register, Address offset: 0x08 */
  79. vu32 SR; /*!< IWDG Status register, Address offset: 0x0C */
  80. } IWDG_TypeDef;
  81. /* WWDG Registers */
  82. typedef struct
  83. {
  84. vu32 CR; /*!< WWDG CR Register, Address offset: 0x0 */
  85. vu32 CFR; /*!< WWDG CFR Register, Address offset: 0x4 */
  86. vu32 SR; /*!< WWDG SR Register, Address offset: 0x8 */
  87. } WWDG_TypeDef;
  88. /* Flash Registers */
  89. typedef struct
  90. {
  91. vu32 ACR; /*!< FLASH ACR Register, Address offset: 0x00 */
  92. vu32 RESERVED1;
  93. vu32 KEYR; /*!< FLASH KEYR Register, Address offset: 0x08 */
  94. vu32 OPTKEYR; /*!< FLASH OPTKEYR Register, Address offset: 0x0C */
  95. vu32 SR; /*!< FLASH SR Register, Address offset: 0x10 */
  96. vu32 CR; /*!< FLASH CR Register, Address offset: 0x14 */
  97. vu32 RESERVED2[2];
  98. vu32 OPTR; /*!< FLASH OPTR Register, Address offset: 0x20 */
  99. vu32 RESERVED3;
  100. vu32 WRPR; /*!< FLASH WRPR Register, Address offset: 0x28 */
  101. vu32 PCROPR; /*!< FLASH PCROPR Register, Address offset: 0x2C */
  102. vu32 SECR; /*!< FLASH SECR Register, Address offset: 0x30 */
  103. vu32 RESERVED5[23];
  104. vu32 LPCR; /*!< FLASH LPCR Register, Address offset: 0x90 */
  105. vu32 RESERVED6[27];
  106. vu32 TS0; /*!< FLASH TS0 Register, Address offset: 0x100 */
  107. vu32 TS1; /*!< FLASH TS1 Register, Address offset: 0x104 */
  108. vu32 TS2P; /*!< FLASH TS2P Register, Address offset: 0x108 */
  109. vu32 TPS3; /*!< FLASH TPS3 Register, Address offset: 0x10C */
  110. vu32 TS3; /*!< FLASH TS3 Register, Address offset: 0x110 */
  111. vu32 ERSTPE; /*!< FLASH ERSTPE Register, Address offset: 0x114 */
  112. vu32 PRGTPE; /*!< FLASH PRGTPE Register, Address offset: 0x118 */
  113. vu32 PRETPE; /*!< FLASH PRETPE Register, Address offset: 0x11C */
  114. vu32 ACLK2PW; /*!< FLASH ACLK2PW Register, Address offset: 0x120 */
  115. } FLASH_TypeDef;
  116. /********************************* Bit definition for FLASH_ACR register ********************************************/
  117. #define FLASH_ACR_LATENCY_Pos (0U)
  118. #define FLASH_ACR_LATENCY_Msk (0x3UL<<FLASH_ACR_LATENCY_Pos) /*!< 0x00000003 */
  119. #define FLASH_ACR_LATENCY FLASH_ACR_LATENCY_Msk /*!< Latency */
  120. /********************************* Bit definition for FLASH_KEYR register *******************************************/
  121. #define FLASH_KEY1_Pos (0U)
  122. #define FLASH_KEY1_Msk (0x45670123UL << FLASH_KEY1_Pos) /*!< 0x45670123 */
  123. #define FLASH_KEY1 FLASH_KEY1_Msk /*!< Flash program erase key1 */
  124. #define FLASH_KEY2_Pos (0U)
  125. #define FLASH_KEY2_Msk (0xCDEF89ABUL << FLASH_KEY2_Pos) /*!< 0xCDEF89AB */
  126. #define FLASH_KEY2 FLASH_KEY2_Msk /*!< Flash program erase key2: used with FLASH_PEKEY1
  127. to unlock the write access to the FPEC. */
  128. /********************************* Bit definition for FLASH_OPTKEYR register ****************************************/
  129. #define FLASH_OPTKEY1_Pos (0U)
  130. #define FLASH_OPTKEY1_Msk (0x08192A3BUL << FLASH_OPTKEY1_Pos) /*!< 0x08192A3B */
  131. #define FLASH_OPTKEY1 FLASH_OPTKEY1_Msk /*!< Flash option key1 */
  132. #define FLASH_OPTKEY2_Pos (0U)
  133. #define FLASH_OPTKEY2_Msk (0x4C5D6E7FUL << FLASH_OPTKEY2_Pos) /*!< 0x4C5D6E7F */
  134. #define FLASH_OPTKEY2 FLASH_OPTKEY2_Msk /*!< Flash option key2: used with FLASH_OPTKEY1 to
  135. unlock the write access to the option byte block */
  136. /********************************* Bit definition for FLASH_SR register *********************************************/
  137. #define FLASH_SR_EOP_Pos (0U)
  138. #define FLASH_SR_EOP_Msk (0x1UL<<FLASH_SR_EOP_Pos) /*!< 0x00000001 */
  139. #define FLASH_SR_EOP FLASH_SR_EOP_Msk /*!< End of operation */
  140. #define FLASH_SR_WRPERR_Pos (4U)
  141. #define FLASH_SR_WRPERR_Msk (0x1UL<<FLASH_SR_WRPERR_Pos) /*!< 0x00000010 */
  142. #define FLASH_SR_WRPERR FLASH_SR_WRPERR_Msk /*!< Write protection error */
  143. #define FLASH_SR_RDERR_Pos (11U)
  144. #define FLASH_SR_RDERR_Msk (0x1UL<<FLASH_SR_RDERR_Pos) /*!< 0x00000800 */
  145. #define FLASH_SR_RDERR FLASH_SR_RDERR_Msk /*!< pcrop read error */
  146. #define FLASH_SR_OPTVERR_Pos (15U)
  147. #define FLASH_SR_OPTVERR_Msk (0x1UL<<FLASH_SR_OPTVERR_Pos) /*!< 0x00008000 */
  148. #define FLASH_SR_OPTVERR FLASH_SR_OPTVERR_Msk /*!< Option and trimming bits loading validity error */
  149. #define FLASH_SR_BSY_Pos (16U)
  150. #define FLASH_SR_BSY_Msk (0x1UL<<FLASH_SR_BSY_Pos) /*!< 0x00010000 */
  151. #define FLASH_SR_BSY FLASH_SR_BSY_Msk /*!< Busy */
  152. #define FLASH_SR_USERLOCK_Pos (28U)
  153. #define FLASH_SR_USERLOCK_Msk (0x1UL<<FLASH_SR_USERLOCK_Pos) /*!< 0x10000000 */
  154. #define FLASH_SR_USERLOCK FLASH_SR_USERLOCK_Msk
  155. /********************************* Bit definition for FLASH_CR register *********************************************/
  156. #define FLASH_CR_PG_Pos (0U)
  157. #define FLASH_CR_PG_Msk (0x1UL<<FLASH_CR_PG_Pos) /*!< 0x00000001 */
  158. #define FLASH_CR_PG FLASH_CR_PG_Msk /*!< Page Program */
  159. #define FLASH_CR_PER_Pos (1U)
  160. #define FLASH_CR_PER_Msk (0x1UL<<FLASH_CR_PER_Pos) /*!< 0x00000002 */
  161. #define FLASH_CR_PER FLASH_CR_PER_Msk /*!< Page Erase */
  162. #define FLASH_CR_MER_Pos (2U)
  163. #define FLASH_CR_MER_Msk (0x1UL<<FLASH_CR_MER_Pos) /*!< 0x00000004 */
  164. #define FLASH_CR_MER FLASH_CR_MER_Msk /*!< Mass Erase */
  165. #define FLASH_CR_UPG_Pos (4U)
  166. #define FLASH_CR_UPG_Msk (0x1UL<<FLASH_CR_UPG_Pos) /*!< 0x00000010 */
  167. #define FLASH_CR_UPG FLASH_CR_UPG_Msk /*!< Userdata Program */
  168. #define FLASH_CR_UPER_Pos (5U)
  169. #define FLASH_CR_UPER_Msk (0x1UL<<FLASH_CR_UPER_Pos) /*!< 0x00000020 */
  170. #define FLASH_CR_UPER FLASH_CR_UPER_Msk /*!< Userdata Page Erase */
  171. #define FLASH_CR_SER_Pos (11U)
  172. #define FLASH_CR_SER_Msk (0x1UL<<FLASH_CR_SER_Pos) /*!< 0x00000800 */
  173. #define FLASH_CR_SER FLASH_CR_SER_Msk /*!< Sector Erase */
  174. #define FLASH_CR_OPTSTRT_Pos (17U)
  175. #define FLASH_CR_OPTSTRT_Msk (0x1UL<<FLASH_CR_OPTSTRT_Pos) /*!< 0x00020000 */
  176. #define FLASH_CR_OPTSTRT FLASH_CR_OPTSTRT_Msk /*!< Option bytes Programming Start */
  177. #define FLASH_CR_UPGSTRT_Pos (18U)
  178. #define FLASH_CR_UPGSTRT_Msk (0x1UL<<FLASH_CR_UPGSTRT_Pos) /*!< 0x00040000 */
  179. #define FLASH_CR_UPGSTRT FLASH_CR_UPGSTRT_Msk /*!< Userdata Programming Start */
  180. #define FLASH_CR_PGSTRT_Pos (19U)
  181. #define FLASH_CR_PGSTRT_Msk (0x1UL<<FLASH_CR_PGSTRT_Pos) /*!< 0x00080000 */
  182. #define FLASH_CR_PGSTRT FLASH_CR_PGSTRT_Msk /*!< Programming Start */
  183. #define FLASH_CR_RDERRIE_Pos (22U)
  184. #define FLASH_CR_RDERRIE_Msk (0x1UL<<FLASH_CR_RDERRIE_Pos) /*!< 0x00400000 */
  185. #define FLASH_CR_RDERRIE FLASH_CR_RDERRIE_Msk /*!< pcrop read error interrupt enable */
  186. #define FLASH_CR_EOPIE_Pos (24U)
  187. #define FLASH_CR_EOPIE_Msk (0x1UL<<FLASH_CR_EOPIE_Pos) /*!< 0x01000000 */
  188. #define FLASH_CR_EOPIE FLASH_CR_EOPIE_Msk /*!< End of operation interrupt enable */
  189. #define FLASH_CR_ERRIE_Pos (25U)
  190. #define FLASH_CR_ERRIE_Msk (0x1UL<<FLASH_CR_ERRIE_Pos) /*!< 0x02000000 */
  191. #define FLASH_CR_ERRIE FLASH_CR_ERRIE_Msk /*!< Error interrupt enable */
  192. #define FLASH_CR_OBL_LAUNCH_Pos (27U)
  193. #define FLASH_CR_OBL_LAUNCH_Msk (0x1UL<<FLASH_CR_OBL_LAUNCH_Pos) /*!< 0x08000000 */
  194. #define FLASH_CR_OBL_LAUNCH FLASH_CR_OBL_LAUNCH_Msk /*!< Force the option bytes loading */
  195. #define FLASH_CR_SECPROT_Pos (28U)
  196. #define FLASH_CR_SECPROT_Msk (0x1UL<<FLASH_CR_SECPROT_Pos) /*!< 0x08000000 */
  197. #define FLASH_CR_SECPROT FLASH_CR_SECPROT_Msk
  198. #define FLASH_CR_OPTLOCK_Pos (30U)
  199. #define FLASH_CR_OPTLOCK_Msk (0x1UL<<FLASH_CR_OPTLOCK_Pos) /*!< 0x40000000 */
  200. #define FLASH_CR_OPTLOCK FLASH_CR_OPTLOCK_Msk /*!< Option Lock */
  201. #define FLASH_CR_LOCK_Pos (31U)
  202. #define FLASH_CR_LOCK_Msk (0x1UL<<FLASH_CR_LOCK_Pos) /*!< 0x80000000 */
  203. #define FLASH_CR_LOCK FLASH_CR_LOCK_Msk /*!< Lock */
  204. #define FLASH_OPTR_IWDG_STOP_Pos (13U)
  205. #define FLASH_OPTR_IWDG_STOP_Msk (0x3UL<<FLASH_OPTR_IWDG_STOP_Pos) /*!< 0x00000800 */
  206. #define FLASH_OPTR_IWDG_STOP FLASH_OPTR_IWDG_STOP_Msk /*!< NRST mode Count Control */
  207. #define FLASH_OPTR_IWDG_SW_Pos (14U)
  208. #define FLASH_OPTR_IWDG_SW_Msk (0x1UL<<FLASH_OPTR_IWDG_SW_Pos) /*!< 0x00001000 */
  209. #define FLASH_OPTR_IWDG_SW FLASH_OPTR_IWDG_SW_Msk /*!< IWDG Software Enable */
  210. #define FLASH_OPTR_WWDG_SW_Pos (15U)
  211. #define FLASH_OPTR_WWDG_SW_Msk (0x1UL<<FLASH_OPTR_WWDG_SW_Pos) /*!< 0x00002000 */
  212. #define FLASH_OPTR_WWDG_SW FLASH_OPTR_WWDG_SW_Msk /*!< WWDG Software Enable */
  213. /********************************* Bit definition for FLASH_WRPR0 register ******************************************/
  214. #define FLASH_WRPR_BK_WRPX_Pos (0U)
  215. #define FLASH_WRPR_BK_WRPX_Msk (0xFFFFUL<<FLASH_WRPR_BK_WRPX_Pos) /*!< 0x0000FFFF */
  216. #define FLASH_WRPR_BK_WRPX FLASH_WRPR_BK_WRPX_Msk /*!< Sector Write Protection */
  217. #define WWDG_CR_T_Pos (0U)
  218. #define WWDG_CR_T_Msk (0x7FUL << WWDG_CR_T_Pos) /*!< 0x0000007F */
  219. #define WWDG_CR_T WWDG_CR_T_Msk /*!<T[6:0] bits (7-Bit counter (MSB to LSB)) */
  220. #define WWDG_CFR_WDGTB_Pos (7U)
  221. #define WWDG_CFR_WDGTB_Msk (0x3UL<<WWDG_CFR_WDGTB_Pos) /*!< 0x00000180 */
  222. #define WWDG_CFR_WDGTB WWDG_CFR_WDGTB_Msk /*!< time base bit 1 */
  223. u32 RCC_ICSCR_HSI_FS_RESTORE;
  224. int ErasePage(unsigned long adr);
  225. /*
  226. * Initialize Flash Programming Functions
  227. * Parameter: adr: Device Base Address
  228. * clk: Clock Frequency (Hz)
  229. * fnc: Function Code (1 - Erase, 2 - Program, 3 - Verify)
  230. * Return Value: 0 - OK, 1 - Failed
  231. */
  232. int Init(unsigned long adr, unsigned long clk, unsigned long fnc)
  233. {
  234. FLASH->KEYR = FLASH_KEY1; /* Unlock Flash */
  235. FLASH->KEYR = FLASH_KEY2;
  236. #ifdef FLASH_OB
  237. FLASH->OPTKEYR = FLASH_OPTKEY1; /* Unlock Option Bytes */
  238. FLASH->OPTKEYR = FLASH_OPTKEY2;
  239. #endif
  240. FLASH->ACR &= ~FLASH_ACR_LATENCY; /* Zero Wait State, no Prefetch */
  241. FLASH->SR |= FLASH_SR_EOP; /* Reset FLASH_EOP */
  242. while (FLASH->SR & FLASH_SR_BSY); /* Check FLASH_SR_BSY */
  243. if ((FLASH->OPTR & FLASH_OPTR_IWDG_SW) == 0x00) /* Test if IWDG is running (IWDG in HW mode) */
  244. {
  245. /* Set IWDG time out to ~32.768 second */
  246. IWDG->KR = 0xAAAA; /* Reload IWDG */
  247. IWDG->KR = 0x5555; /* Enable write access to IWDG_PR and IWDG_RLR */
  248. IWDG->PR = 0x06; /* Set prescaler to 256 */
  249. IWDG->RLR = 0xFFF; /* Set reload value to 4095 */
  250. }
  251. if (FLASH_OPTR_WWDG_SW != READ_BIT(FLASH->OPTR, FLASH_OPTR_WWDG_SW)) /* Test if WWDG is running (WWDG in HW mode) */
  252. {
  253. /* Set WWDG time out to maximum */
  254. SET_BIT(WWDG->CFR, WWDG_CFR_WDGTB); /* Set prescaler to maximum */
  255. SET_BIT(WWDG->CR, WWDG_CR_T); /* Reload WWDG */
  256. }
  257. return (0);
  258. }
  259. /*
  260. * De-Initialize Flash Programming Functions
  261. * Parameter: fnc: Function Code (1 - Erase, 2 - Program, 3 - Verify)
  262. * Return Value: 0 - OK, 1 - Failed
  263. */
  264. int UnInit(unsigned long fnc)
  265. {
  266. #ifdef FLASH_OB
  267. FLASH->CR |= FLASH_CR_OPTLOCK; /* Lock Option Bytes */
  268. #endif
  269. FLASH->CR |= FLASH_CR_LOCK; /* Lock Flash */
  270. return (0);
  271. }
  272. /*
  273. * Erase complete Flash Memory
  274. * Return Value: 0 - OK, 1 - Failed
  275. */
  276. int EraseChip(void)
  277. {
  278. #ifdef FLASH_OTP
  279. ErasePage(OTP_BASE);
  280. #endif /* FLASH_OTP */
  281. #ifdef FLASH_MEM
  282. FLASH->SR |= FLASH_SR_EOP; /* Reset FLASH_EOP */
  283. FLASH->CR |= FLASH_CR_MER; /* Mass Erase Enabled */
  284. FLASH->CR |= FLASH_CR_EOPIE;
  285. M32(FLASH_BASE) = 0xFF;
  286. __asm("DSB");
  287. while (FLASH->SR & FLASH_SR_BSY)
  288. {
  289. SET_BIT(WWDG->CR, WWDG_CR_T); /* Reload WWDG */
  290. IWDG->KR = 0xAAAA; /* Reload IWDG */
  291. }
  292. if (FLASH_SR_EOP != (FLASH->SR & FLASH_SR_EOP)) /* Check for FLASH_SR_EOP */
  293. {
  294. FLASH->SR |= FLASH_SR_EOP; /* Reset FLASH_EOP */
  295. return (1); /* Failed */
  296. }
  297. FLASH->SR |= FLASH_SR_EOP; /* Reset FLASH_EOP */
  298. FLASH->CR &= ~FLASH_CR_MER; /* Mass Erase Disabled */
  299. FLASH->CR &= ~FLASH_CR_EOPIE; /* Reset FLASH_EOPIE */
  300. #endif
  301. return (0); /* Done */
  302. }
  303. /*
  304. * Erase Sector in Flash Memory
  305. * Parameter: adr: Sector Address
  306. * Return Value: 0 - OK, 1 - Failed
  307. */
  308. #ifdef FLASH_MEM
  309. int EraseSector(unsigned long adr)
  310. {
  311. FLASH->SR |= FLASH_SR_EOP; /* Reset FLASH_EOP */
  312. FLASH->CR |= FLASH_CR_SER; /* Sector Erase Enabled */
  313. FLASH->CR |= FLASH_CR_EOPIE;
  314. M32(adr) = 0xFF; /* Sector Address */
  315. __asm("DSB");
  316. while (FLASH->SR & FLASH_SR_BSY)
  317. {
  318. SET_BIT(WWDG->CR, WWDG_CR_T); /* Reload WWDG */
  319. IWDG->KR = 0xAAAA; /* Reload IWDG */
  320. }
  321. if (FLASH_SR_EOP != (FLASH->SR & FLASH_SR_EOP)) /* Check for FLASH_SR_EOP */
  322. {
  323. FLASH->SR |= FLASH_SR_EOP; /* Reset FLASH_EOP */
  324. return (1); /* Failed */
  325. }
  326. FLASH->SR |= FLASH_SR_EOP; /* Reset FLASH_EOP */
  327. FLASH->CR &= ~FLASH_CR_SER; /* Sector Erase Disabled */
  328. FLASH->CR &= ~FLASH_CR_EOPIE; /* Reset FLASH_EOPIE */
  329. return (0); /* Done */
  330. }
  331. #endif
  332. #ifdef FLASH_OTP
  333. int EraseSector(unsigned long adr)
  334. {
  335. ErasePage(OTP_BASE);
  336. return (0); /* Done */
  337. }
  338. #endif /* FLASH_OTP */
  339. #ifdef FLASH_OB
  340. int EraseSector(unsigned long adr)
  341. {
  342. /* erase sector is not needed for
  343. - Flash Option bytes
  344. - Flash One Time Programmable bytes
  345. */
  346. return (0); /* Done */
  347. }
  348. #endif
  349. #ifdef FLASH_OTP
  350. int ErasePage(unsigned long adr)
  351. {
  352. FLASH->SR |= FLASH_SR_EOP;
  353. FLASH->CR |= FLASH_CR_UPER;
  354. FLASH->CR |= FLASH_CR_EOPIE;
  355. M32(adr) = 0xFF;
  356. __asm("DSB");
  357. while (FLASH->SR & FLASH_SR_BSY)
  358. {
  359. SET_BIT(WWDG->CR, WWDG_CR_T); /* Reload WWDG */
  360. IWDG->KR = 0xAAAA; /* Reload IWDG */
  361. }
  362. if (FLASH_SR_EOP != (FLASH->SR & FLASH_SR_EOP)) /* Check for FLASH_SR_EOP */
  363. {
  364. FLASH->SR |= FLASH_SR_EOP; /* Reset FLASH_EOP */
  365. return (1); /* Failed */
  366. }
  367. FLASH->SR |= FLASH_SR_EOP; /* Reset FLASH_EOP */
  368. FLASH->CR &= ~FLASH_CR_UPER;
  369. FLASH->CR &= ~FLASH_CR_EOPIE;
  370. return (0); /* Done */
  371. }
  372. #endif /* FLASH_OTP */
  373. /*
  374. * Blank Check Checks if Memory is Blank
  375. * Parameter: adr: Block Start Address
  376. * sz: Block Size (in bytes)
  377. * pat: Block Pattern
  378. * Return Value: 0 - OK, 1 - Failed
  379. */
  380. int BlankCheck(unsigned long adr, unsigned long sz, unsigned char pat)
  381. {
  382. return (1); /* Always Force Erase */
  383. }
  384. /*
  385. * Program Page in Flash Memory
  386. * Parameter: adr: Page Start Address
  387. * sz: Page Size
  388. * buf: Page Data
  389. * Return Value: 0 - OK, 1 - Failed
  390. */
  391. #ifdef FLASH_MEM
  392. int ProgramPage(unsigned long adr, unsigned long sz, unsigned char *buf)
  393. {
  394. sz = (sz + (FLASH_PAGE_SIZE - 1)) & ~(FLASH_PAGE_SIZE - 1); /* Adjust size for 32 Words */
  395. FLASH->SR |= FLASH_SR_EOP; /* Reset FLASH_EOP */
  396. while (sz)
  397. {
  398. FLASH->CR |= FLASH_CR_PG; /* Programming Enabled */
  399. FLASH->CR |= FLASH_CR_EOPIE;
  400. for (u8 i = 0; i < (FLASH_PAGE_SIZE / 4); i++)
  401. {
  402. M32(adr + i * 4) = *((u32 *)(buf + i * 4)); /* Program the first word of the Double Word */
  403. if (i == (FLASH_PAGE_SIZE / 4 - 2))
  404. {
  405. FLASH->CR |= FLASH_CR_PGSTRT;
  406. }
  407. }
  408. __asm("DSB");
  409. while (FLASH->SR & FLASH_SR_BSY)
  410. {
  411. SET_BIT(WWDG->CR, WWDG_CR_T); /* Reload WWDG */
  412. IWDG->KR = 0xAAAA; /* Reload IWDG */
  413. }
  414. if (FLASH_SR_EOP != (FLASH->SR & FLASH_SR_EOP)) /* Check for FLASH_SR_EOP */
  415. {
  416. FLASH->SR |= FLASH_SR_EOP; /* Reset FLASH_EOP */
  417. return (1); /* Failed */
  418. }
  419. FLASH->SR |= FLASH_SR_EOP; /* Reset FLASH_EOP */
  420. FLASH->CR &= ~FLASH_CR_PG; /* Programming Disabled */
  421. FLASH->CR &= ~FLASH_CR_EOPIE; /* Reset FLASH_EOPIE */
  422. adr += FLASH_PAGE_SIZE; /* Go to next Page */
  423. buf += FLASH_PAGE_SIZE;
  424. sz -= FLASH_PAGE_SIZE;
  425. }
  426. return (0); /* Done */
  427. }
  428. #endif /* FLASH_MEM */
  429. #ifdef FLASH_OTP
  430. int ProgramPage(unsigned long adr, unsigned long sz, unsigned char *buf)
  431. {
  432. sz = (sz + (FLASH_PAGE_SIZE - 1)) & ~(FLASH_PAGE_SIZE - 1); /* Adjust size for 32 Words */
  433. SET_BIT(FLASH->SR, FLASH_SR_EOP); /* Clear EOP flag */
  434. while (sz)
  435. {
  436. FLASH->CR |= FLASH_CR_UPG; /* Programming Enabled */
  437. for (u8 i = 0; i < FLASH_PAGE_SIZE / 4; i++)
  438. {
  439. M32(adr + i * 4) = *((u32 *)(buf + i * 4)); /* Program the first word of the Double Word */
  440. if (i == (FLASH_PAGE_SIZE / 4 - 2))
  441. {
  442. FLASH->CR |= FLASH_CR_PGSTRT;
  443. }
  444. }
  445. while (FLASH->SR & FLASH_SR_BSY)
  446. {
  447. SET_BIT(WWDG->CR, WWDG_CR_T); /* Reload WWDG */
  448. IWDG->KR = 0xAAAA; /* Reload IWDG */
  449. }
  450. if (FLASH_SR_EOP != (FLASH->SR & FLASH_SR_EOP)) /* Check for FLASH_SR_EOP */
  451. {
  452. FLASH->SR |= FLASH_SR_EOP; /* Reset FLASH_EOP */
  453. return (1); /* Failed */
  454. }
  455. FLASH->SR |= FLASH_SR_EOP; /* Reset FLASH_EOP */
  456. FLASH->CR &= ~FLASH_CR_UPG; /* Programming Disabled */
  457. adr += FLASH_PAGE_SIZE; /* Go to next Page */
  458. buf += FLASH_PAGE_SIZE;
  459. sz -= FLASH_PAGE_SIZE;
  460. }
  461. return (0); /* Done */
  462. }
  463. #endif /* FLASH_OTP */
  464. #ifdef FLASH_OB
  465. int ProgramPage(unsigned long adr, unsigned long sz, unsigned char *buf)
  466. {
  467. u32 optr0;
  468. u32 optr1;
  469. u32 wrpr;
  470. u32 pcropsr;
  471. u32 pcroper;
  472. u32 secsize;
  473. optr0 = *((u32 *)(buf + 0x00));
  474. optr1 = *((u32 *)(buf + 0x04));
  475. wrpr = *((u32 *)(buf + 0x10));
  476. pcropsr = *((u32 *)(buf + 0x14));
  477. pcroper = *((u32 *)(buf + 0x18));
  478. secsize = *((u32 *)(buf + 0x1C));
  479. FLASH->SR |= FLASH_SR_EOP; /* Reset FLASH_EOP*/
  480. FLASH->OPTR = ((optr0 & 0x0000FFFF) | ((optr1 & 0x0000FFFF) << 16)); /*Write OPTR values*/
  481. FLASH->WRPR = (wrpr & 0x0000FFFF); /* Write WRPR values*/
  482. FLASH->PCROPR = ((pcropsr & 0x0000FFFF) | ((pcroper & 0x0000FFFF) << 16)); /*Write PCROPR values*/
  483. FLASH->SECR = (secsize & 0x0000FFFF); /* Write SECR values*/
  484. FLASH->CR |= FLASH_CR_OPTSTRT;
  485. FLASH->CR |= FLASH_CR_EOPIE;
  486. M32(OB_BASE) = 0xFF;
  487. __asm("DSB");
  488. while (FLASH->SR & FLASH_SR_BSY)
  489. {
  490. SET_BIT(WWDG->CR, WWDG_CR_T); /* Reload WWDG */
  491. IWDG->KR = 0xAAAA; /* Reload IWDG */
  492. }
  493. if (FLASH_SR_EOP != (FLASH->SR & FLASH_SR_EOP)) /* Check for FLASH_SR_EOP */
  494. {
  495. FLASH->SR |= FLASH_SR_EOP; /* Reset FLASH_EOP */
  496. return (1); /* Failed */
  497. }
  498. FLASH->SR |= FLASH_SR_EOP; /* Reset FLASH_EOP */
  499. FLASH->CR &= ~FLASH_CR_OPTSTRT; /* Programming Disabled */
  500. FLASH->CR &= ~FLASH_CR_EOPIE; /* Reset FLASH_EOPIE */
  501. return (0); /* Done */
  502. }
  503. #endif /* FLASH_OB */
  504. #ifdef FLASH_OB
  505. unsigned long Verify(unsigned long adr, unsigned long sz, unsigned char *buf)
  506. {
  507. u32 optr0;
  508. u32 optr1;
  509. u32 wrpr;
  510. u32 pcropsr;
  511. u32 pcroper;
  512. u32 secsize;
  513. optr0 = *((u32 *)(buf + 0x00));
  514. optr1 = *((u32 *)(buf + 0x04));
  515. wrpr = *((u32 *)(buf + 0x10));
  516. pcropsr = *((u32 *)(buf + 0x14));
  517. pcroper = *((u32 *)(buf + 0x18));
  518. secsize = *((u32 *)(buf + 0x1C));
  519. if (M32(adr + 0x00) != optr0)
  520. {
  521. return (adr + 0x00);
  522. }
  523. if (M32(adr + 0x04) != optr1)
  524. {
  525. return (adr + 0x04);
  526. }
  527. if (M32(adr + 0x10) != wrpr)
  528. {
  529. return (adr + 0x10);
  530. }
  531. if (M32(adr + 0x14) != pcropsr)
  532. {
  533. return (adr + 0x14);
  534. }
  535. if (M32(adr + 0x18) != pcroper)
  536. {
  537. return (adr + 0x18);
  538. }
  539. if (M32(adr + 0x1C) != secsize)
  540. {
  541. return (adr + 0x1C);
  542. }
  543. return (adr + sz);
  544. }
  545. #endif /* FLASH_OB */
  546. #ifdef FLASH_MEM
  547. int ErasePage(unsigned long adr)
  548. {
  549. FLASH->SR |= FLASH_SR_EOP; /* Reset FLASH_EOP */
  550. FLASH->CR |= FLASH_CR_PER; /* page Erase Enabled */
  551. FLASH->CR |= FLASH_CR_EOPIE;
  552. M32(adr) = 0xFF; /* Sector Address */
  553. __asm("DSB");
  554. while (FLASH->SR & FLASH_SR_BSY)
  555. {
  556. SET_BIT(WWDG->CR, WWDG_CR_T); /* Reload WWDG */
  557. IWDG->KR = 0xAAAA; /* Reload IWDG */
  558. }
  559. if (FLASH_SR_EOP != (FLASH->SR & FLASH_SR_EOP)) /* Check for FLASH_SR_EOP */
  560. {
  561. FLASH->SR |= FLASH_SR_EOP; /* Reset FLASH_EOP */
  562. return (1); /* Failed */
  563. }
  564. FLASH->SR |= FLASH_SR_EOP; /* Reset FLASH_EOP */
  565. FLASH->CR &= ~FLASH_CR_PER; /* page Erase Disabled */
  566. FLASH->CR &= ~FLASH_CR_EOPIE; /* Reset FLASH_EOPIE */
  567. return (0); /* Done */
  568. }
  569. #endif /* FLASH_MEM */