hal_flash.c 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548
  1. ////////////////////////////////////////////////////////////////////////////////
  2. /// @file hal_flash.c
  3. /// @author AE TEAM
  4. /// @brief THIS FILE PROVIDES ALL THE FLASH FIRMWARE FUNCTIONS.
  5. ////////////////////////////////////////////////////////////////////////////////
  6. /// @attention
  7. ///
  8. /// THE EXISTING FIRMWARE IS ONLY FOR REFERENCE, WHICH IS DESIGNED TO PROVIDE
  9. /// CUSTOMERS WITH CODING INFORMATION ABOUT THEIR PRODUCTS SO THEY CAN SAVE
  10. /// TIME. THEREFORE, MINDMOTION SHALL NOT BE LIABLE FOR ANY DIRECT, INDIRECT OR
  11. /// CONSEQUENTIAL DAMAGES ABOUT ANY CLAIMS ARISING OUT OF THE CONTENT OF SUCH
  12. /// HARDWARE AND/OR THE USE OF THE CODING INFORMATION CONTAINED HEREIN IN
  13. /// CONNECTION WITH PRODUCTS MADE BY CUSTOMERS.
  14. ///
  15. /// <H2><CENTER>&COPY; COPYRIGHT MINDMOTION </CENTER></H2>
  16. ////////////////////////////////////////////////////////////////////////////////
  17. // Define to prevent recursive inclusion
  18. #define _HAL_FLASH_C_
  19. // Files includes
  20. #include "hal_flash.h"
  21. ////////////////////////////////////////////////////////////////////////////////
  22. /// @addtogroup MM32_Hardware_Abstract_Layer
  23. /// @{
  24. ////////////////////////////////////////////////////////////////////////////////
  25. /// @addtogroup FLASH_HAL
  26. /// @{
  27. ////////////////////////////////////////////////////////////////////////////////
  28. /// @addtogroup FLASH_Exported_Functions
  29. /// @{
  30. ////////////////////////////////////////////////////////////////////////////////
  31. /// @brief Sets the code latency value.
  32. /// @note This function can be used for all MM32 devices.
  33. /// @param latency: specifies the FLASH Latency value.
  34. /// This parameter can be one of the following values:
  35. /// @arg FLASH_Latency_0: FLASH Zero Latency cycle
  36. /// @arg FLASH_Latency_1: FLASH One Latency cycle
  37. /// @arg FLASH_Latency_2: FLASH Two Latency cycles
  38. /// @arg FLASH_Latency_3: FLASH Three Latency cycles
  39. /// @retval None.
  40. ////////////////////////////////////////////////////////////////////////////////
  41. void FLASH_SetLatency(FLASH_Latency_TypeDef latency)
  42. {
  43. FLASH->ACR = (FLASH->ACR & (~FLASH_ACR_LATENCY)) | latency;
  44. }
  45. ////////////////////////////////////////////////////////////////////////////////
  46. /// @brief Enables or disables the Half cycle flash access.
  47. /// @note This function can be used for all MM32 devices.
  48. /// @param half_cycle_access: specifies the FLASH Half cycle Access mode.
  49. /// This parameter can be one of the following values:
  50. /// @arg FLASH_HalfCycleAccess_Enable: FLASH Half Cycle Enable
  51. /// @arg FLASH_HalfCycleAccess_Disable: FLASH Half Cycle Disable
  52. /// @retval None.
  53. ////////////////////////////////////////////////////////////////////////////////
  54. void FLASH_HalfCycleAccessCmd(FLASH_HalfCycleAccess_TypeDef half_cycle_access)
  55. {
  56. FLASH->ACR &= ~FLASH_ACR_HLFCYA;
  57. FLASH->ACR |= half_cycle_access;
  58. }
  59. ////////////////////////////////////////////////////////////////////////////////
  60. /// @brief Enables or disables the Prefetch Buffer.
  61. /// @note This function can be used for all MM32 devices.
  62. /// @param prefetch_buffer: specifies the Prefetch buffer status.
  63. /// This parameter can be one of the following values:
  64. /// @arg FLASH_PrefetchBuffer_Enable: FLASH Prefetch Buffer Enable
  65. /// @arg FLASH_PrefetchBuffer_Disable: FLASH Prefetch Buffer Disable
  66. /// @retval None.
  67. ////////////////////////////////////////////////////////////////////////////////
  68. void FLASH_PrefetchBufferCmd(FLASH_PrefetchBuffer_TypeDef prefetch_buffer)
  69. {
  70. FLASH->ACR &= ~FLASH_ACR_PRFTBE;
  71. FLASH->ACR |= prefetch_buffer;
  72. }
  73. ////////////////////////////////////////////////////////////////////////////////
  74. /// @brief Locks the FLASH Program Erase Controller.
  75. /// @note This function can be used for all MM32 devices.
  76. /// @param None.
  77. /// @retval None.
  78. ////////////////////////////////////////////////////////////////////////////////
  79. void FLASH_Lock(void)
  80. {
  81. FLASH->CR |= FLASH_CR_LOCK;
  82. }
  83. ////////////////////////////////////////////////////////////////////////////////
  84. /// @brief Unlocks the FLASH Program Erase Controller.
  85. /// @note This function can be used for all MM32 devices.
  86. /// @param None.
  87. /// @retval None.
  88. ////////////////////////////////////////////////////////////////////////////////
  89. void FLASH_Unlock()
  90. {
  91. FLASH->KEYR = FLASH_KEY1;
  92. FLASH->KEYR = FLASH_KEY2;
  93. }
  94. ////////////////////////////////////////////////////////////////////////////////
  95. /// @brief Enable to program the FLASH Option Byte.
  96. /// @note This function can be used for all MM32 devices.
  97. /// @param None.
  98. /// @retval None.
  99. ////////////////////////////////////////////////////////////////////////////////
  100. void FLASH_OPTB_Enable(void)
  101. {
  102. FLASH->OPTKEYR = FLASH_KEY1;
  103. FLASH->OPTKEYR = FLASH_KEY2;
  104. }
  105. ////////////////////////////////////////////////////////////////////////////////
  106. /// @brief Erases a specified FLASH page.
  107. /// @note This function can be used for all MM32 devices.
  108. /// @param page_address: The page address to be erased.
  109. /// @retval FLASH Status: The returned value can be: FLASH_BUSY,
  110. /// FLASH_ERROR_PG, FLASH_ERROR_WRP, FLASH_COMPLETE or FLASH_TIMEOUT.
  111. ////////////////////////////////////////////////////////////////////////////////
  112. FLASH_Status FLASH_ErasePage(u32 page_address)
  113. {
  114. FLASH->CR |= FLASH_CR_PER;
  115. FLASH->AR = page_address;
  116. FLASH->CR |= FLASH_CR_STRT;
  117. return FLASH_WaitForLastOperation(EraseTimeout);
  118. }
  119. ////////////////////////////////////////////////////////////////////////////////
  120. /// @brief Erases all FLASH pages.
  121. /// @note This function can be used for all MM32 devices.
  122. /// @param None.
  123. /// @retval FLASH Status: The returned value can be: FLASH_ERROR_PG,
  124. /// FLASH_ERROR_WRP, FLASH_COMPLETE or FLASH_TIMEOUT.
  125. ////////////////////////////////////////////////////////////////////////////////
  126. FLASH_Status FLASH_EraseAllPages()
  127. {
  128. FLASH->AR = FLASH_BASE;
  129. FLASH->CR |= (FLASH_CR_MER | FLASH_CR_STRT);
  130. return FLASH_WaitForLastOperation(EraseTimeout);
  131. }
  132. ////////////////////////////////////////////////////////////////////////////////
  133. /// @brief Erases the FLASH option bytes.
  134. /// @note This function can be used for all MM32 devices.
  135. /// @param None.
  136. /// @retval FLASH Status: The returned value can be: FLASH_ERROR_PG,
  137. /// FLASH_ERROR_WRP, FLASH_COMPLETE or FLASH_TIMEOUT.
  138. ////////////////////////////////////////////////////////////////////////////////
  139. FLASH_Status FLASH_EraseOptionBytes()
  140. {
  141. FLASH_OPTB_Enable();
  142. FLASH->AR = OB_BASE;
  143. FLASH->CR |= (FLASH_CR_OPTER | FLASH_CR_STRT);
  144. return FLASH_WaitForLastOperation(EraseTimeout);
  145. }
  146. ////////////////////////////////////////////////////////////////////////////////
  147. /// @brief Programs a half word at a specified address.
  148. /// @note This function can be used for all MM32 devices.
  149. /// @param address: specifies the address to be programmed.
  150. /// @param data: specifies the data to be programmed.
  151. /// @retval FLASH Status: The returned value can be: FLASH_ERROR_PG,
  152. /// FLASH_ERROR_WRP, FLASH_COMPLETE or FLASH_TIMEOUT.
  153. ////////////////////////////////////////////////////////////////////////////////
  154. FLASH_Status FLASH_ProgramHalfWord(u32 address, u16 data)
  155. {
  156. FLASH->CR |= FLASH_CR_PG;
  157. *(vu16*)address = data;
  158. return FLASH_WaitForLastOperation(ProgramTimeout);
  159. }
  160. ////////////////////////////////////////////////////////////////////////////////
  161. /// @brief Programs a word at a specified address.
  162. /// @note This function can be used for all MM32 devices.
  163. /// @param address: specifies the address to be programmed.
  164. /// @param data: specifies the data to be programmed.
  165. /// @retval FLASH Status: The returned value can be: FLASH_ERROR_PG,
  166. /// FLASH_ERROR_WRP, FLASH_COMPLETE or FLASH_TIMEOUT.
  167. ////////////////////////////////////////////////////////////////////////////////
  168. FLASH_Status FLASH_ProgramWord(u32 address, u32 data)
  169. {
  170. FLASH_Status ret = FLASH_ProgramHalfWord(address, data);
  171. if (ret == FLASH_COMPLETE) {
  172. ret = FLASH_ProgramHalfWord(address + 2, data >> 16);
  173. }
  174. return ret;
  175. }
  176. ////////////////////////////////////////////////////////////////////////////////
  177. /// @brief Programs a byte at a specified Option Byte Data address.
  178. /// @note This function can be used for all MM32 devices.
  179. /// @param address: specifies the address to be programmed.
  180. /// This parameter can be 0x1FFFF804 or 0x1FFFF806.
  181. /// @param data: specifies the data to be programmed.
  182. /// @retval FLASH Status: The returned value can be: FLASH_ERROR_PG,
  183. /// FLASH_ERROR_WRP, FLASH_COMPLETE or FLASH_TIMEOUT.
  184. ////////////////////////////////////////////////////////////////////////////////
  185. FLASH_Status FLASH_ProgramOptionByteData(u32 address, u8 data)
  186. {
  187. FLASH_Status ret;
  188. __IO u16 temp;
  189. FLASH_OPTB_Enable();
  190. FLASH->CR |= FLASH_CR_OPTPG;
  191. temp = (u16)(~data);
  192. temp = (temp << 8) & 0xFF00;
  193. temp = temp | (u16)data;
  194. address = address & (~0x1);
  195. *(vu16*)address = temp;
  196. ret = FLASH_WaitForLastOperation(ProgramTimeout);
  197. return ret;
  198. }
  199. ////////////////////////////////////////////////////////////////////////////////
  200. /// @brief Programs a half word at a specified Option Byte Data address.
  201. /// @note This function can be used for all MM32 devices.
  202. /// @param address: specifies the address to be programmed.
  203. /// This parameter can be 0x1FFFF804 or 0x1FFFF806.
  204. /// @param data: specifies the data to be programmed.
  205. /// @retval FLASH Status: The returned value can be: FLASH_ERROR_PG,
  206. /// FLASH_ERROR_WRP, FLASH_COMPLETE or FLASH_TIMEOUT.
  207. ////////////////////////////////////////////////////////////////////////////////
  208. FLASH_Status FLASH_ProgramOptionHalfWord(u32 address, u16 data)
  209. {
  210. FLASH_Status ret;
  211. FLASH_OPTB_Enable();
  212. FLASH->CR |= FLASH_CR_OPTPG;
  213. *(vu16*)address = data;
  214. ret = FLASH_WaitForLastOperation(ProgramTimeout);
  215. return ret;
  216. }
  217. ////////////////////////////////////////////////////////////////////////////////
  218. /// @brief Read protection for the specified address
  219. /// @note This function can be used for all MM32 devices.
  220. /// @retval None.
  221. ////////////////////////////////////////////////////////////////////////////////
  222. FLASH_Status FLASH_ProgramProtect(u32 address, u16 data)
  223. {
  224. return FLASH_ProgramOptionHalfWord(address, data);
  225. // FLASH_Status ret;
  226. // ret = FLASH_ProgramOptionHalfWord(address, 0x7F80);
  227. //
  228. // if (ret == FLASH_COMPLETE) {
  229. // ret = FLASH_ProgramOptionHalfWord(address + 2, 0xFF00);
  230. // }
  231. // return ret;
  232. }
  233. ////////////////////////////////////////////////////////////////////////////////
  234. /// @brief Write protection for the specified address
  235. /// @note This function can be used for all MM32 devices.
  236. /// @param page: specifies the address of the pages to be write
  237. /// protected.
  238. /// This parameter is (0x01 << ((Absolute address - 0x08000000)/0x1000))
  239. /// @retval FLASH Status: The returned value can be: FLASH_ERROR_PG,
  240. /// FLASH_ERROR_WRP, FLASH_COMPLETE or FLASH_TIMEOUT.
  241. ////////////////////////////////////////////////////////////////////////////////
  242. FLASH_Status FLASH_EnableWriteProtection(u32 page)
  243. {
  244. FLASH_Status ret;
  245. u8 i;
  246. for (i = 0; i < 4; i++) {
  247. ret = FLASH_ProgramOptionHalfWord((OB_BASE + 8 + i * 2), ~(page >> (i * 8)));
  248. if (ret != FLASH_COMPLETE) {
  249. break;
  250. }
  251. }
  252. return ret;
  253. }
  254. ////////////////////////////////////////////////////////////////////////////////
  255. /// @brief Programs the FLASH User Option Byte: IWDG_SW / RST_STOP / RST_STDBY.
  256. /// @note This function can be used for all MM32 devices.
  257. /// @param ob_iwdg: Selects the IWDG mode
  258. /// @param ob_stop: Reset event when entering STOP mode.
  259. /// @param standby: Reset event when entering Standby mode.
  260. /// @retval FLASH Status: The returned value can be: FLASH_ERROR_PG,
  261. /// FLASH_ERROR_WRP, FLASH_COMPLETE or FLASH_TIMEOUT.
  262. ////////////////////////////////////////////////////////////////////////////////
  263. FLASH_Status FLASH_UserOptionByteConfig(OB_IWDG_TypeDef ob_iwdg, OB_STOP_TypeDef ob_stop, OB_STDBY_TypeDef standby)
  264. {
  265. FLASH_OPTB_Enable();
  266. FLASH->CR |= FLASH_CR_OPTPG;
  267. OB->USER = ob_iwdg;
  268. OB->USER |= ob_stop;
  269. OB->USER |= standby;
  270. OB->USER |= 0xF8;
  271. // OB->USER = iwdg | stop | stdby | 0xF8;
  272. return FLASH_WaitForLastOperation(ProgramTimeout);
  273. }
  274. ////////////////////////////////////////////////////////////////////////////////
  275. /// @brief Returns the FLASH User Option Bytes values.
  276. /// @note This function can be used for all MM32 devices.
  277. /// @param None.
  278. /// @retval The FLASH User Option Bytes values:IWDG_SW(Bit0), RST_STOP(Bit1)
  279. /// and RST_STDBY(Bit2).
  280. ////////////////////////////////////////////////////////////////////////////////
  281. u32 FLASH_GetUserOptionByte()
  282. {
  283. return (FLASH->OBR >> 2);
  284. }
  285. ////////////////////////////////////////////////////////////////////////////////
  286. /// @brief Returns the FLASH Write Protection Option Bytes Register value.
  287. /// @note This function can be used for all MM32 devices.
  288. /// @param None.
  289. /// @retval The FLASH Write Protection Option Bytes Register value.
  290. ////////////////////////////////////////////////////////////////////////////////
  291. u32 FLASH_GetWriteProtectionOptionByte()
  292. {
  293. return (FLASH->WRPR);
  294. }
  295. ////////////////////////////////////////////////////////////////////////////////
  296. /// @brief Checks whether the FLASH Prefetch Buffer status is set or not.
  297. /// @note This function can be used for all MM32 devices.
  298. /// @param None.
  299. /// @retval FLASH Prefetch Buffer Status (SET or RESET).
  300. ////////////////////////////////////////////////////////////////////////////////
  301. FlagStatus FLASH_GetPrefetchBufferStatus(void)
  302. {
  303. return (FLASH->ACR & FLASH_ACR_PRFTBS) ? SET : RESET;
  304. }
  305. ////////////////////////////////////////////////////////////////////////////////
  306. /// @brief Enables or disables the specified FLASH interrupts.
  307. /// @note This function can be used for all MM32 devices.
  308. /// @param interrupt: specifies the FLASH interrupt sources to be enabled or
  309. /// disabled.
  310. /// @param state: new state of the specified Flash interrupts.
  311. /// This parameter can be: ENABLE or DISABLE.
  312. /// @retval None.
  313. ////////////////////////////////////////////////////////////////////////////////
  314. void FLASH_ITConfig(FLASH_IT_TypeDef interrupt, FunctionalState state)
  315. {
  316. (state) ? (FLASH->CR |= interrupt) : (FLASH->CR &= ~interrupt);
  317. }
  318. ////////////////////////////////////////////////////////////////////////////////
  319. /// @brief Checks whether the specified FLASH flag is set or not.
  320. /// @note This function can be used for all MM32 devices.
  321. /// @param flag: specifies the FLASH flags to clear.
  322. /// This parameter can be one of the following values:
  323. /// @arg FLASH_FLAG_BSY: FLASH Busy flag
  324. /// @arg FLASH_FLAG_PGERR: FLASH Program error flag
  325. /// @arg FLASH_FLAG_WRPRTERR: FLASH Write protected error flag
  326. /// @arg FLASH_FLAG_EOP: FLASH End of Operation flag
  327. /// @arg FLASH_FLAG_OPTERR: FLASH Option Byte error flag
  328. /// @retval The new state of FLASH_FLAG (SET or RESET).
  329. ////////////////////////////////////////////////////////////////////////////////
  330. FlagStatus FLASH_GetFlagStatus(u16 flag)
  331. {
  332. return ((flag == FLASH_FLAG_OPTERR) ? (FLASH->OBR & FLASH_FLAG_OPTERR) : (FLASH->SR & flag)) ? SET : RESET;
  333. }
  334. ////////////////////////////////////////////////////////////////////////////////
  335. /// @brief Clears the FLASH's pending flags.
  336. /// @note This function can be used for all MM32 devices.
  337. /// @param flag: specifies the FLASH flags to clear.
  338. /// This parameter can be any combination of the following values:
  339. /// @arg FLASH_FLAG_PGERR: FLASH Program error flag
  340. /// @arg FLASH_FLAG_WRPRTERR: FLASH Write protected error flag
  341. /// @arg FLASH_FLAG_EOP: FLASH End of Operation flag
  342. /// @retval None.
  343. ////////////////////////////////////////////////////////////////////////////////
  344. void FLASH_ClearFlag(u16 flag)
  345. {
  346. FLASH->SR = flag;
  347. }
  348. ////////////////////////////////////////////////////////////////////////////////
  349. /// @brief Returns the FLASH Status.
  350. /// @note This function can be used for all MM32 devices.
  351. /// @param None.
  352. /// @retval FLASH Status: The returned value can be: FLASH_BUSY,
  353. /// FLASH_ERROR_PG, FLASH_ERROR_WRP or FLASH_COMPLETE.
  354. ////////////////////////////////////////////////////////////////////////////////
  355. FLASH_Status FLASH_GetStatus()
  356. {
  357. return (FLASH_Status)((FLASH->SR & FLASH_FLAG_BSY))
  358. ? FLASH_BUSY
  359. : ((FLASH->SR & FLASH_FLAG_PGERR) ? FLASH_ERROR_PG
  360. : ((FLASH->SR & FLASH_FLAG_WRPRTERR) ? FLASH_ERROR_WRP : FLASH_COMPLETE));
  361. }
  362. ////////////////////////////////////////////////////////////////////////////////
  363. /// @brief Waits for a Flash operation to complete or a TIMEOUT to occur.
  364. /// @note This function can be used for all MM32 devices
  365. /// @param time_out: FLASH programming time_out
  366. /// @retval FLASH Status: The returned value can be: FLASH_ERROR_PG,
  367. /// FLASH_ERROR_WRP, FLASH_COMPLETE or FLASH_TIMEOUT.
  368. ////////////////////////////////////////////////////////////////////////////////
  369. FLASH_Status FLASH_WaitForLastOperation(u32 time_out)
  370. {
  371. u32 i;
  372. FLASH_Status ret;
  373. do {
  374. ret = FLASH_GetStatus();
  375. time_out--;
  376. for (i = 0xFF; i != 0; i--)
  377. ;
  378. } while ((ret == FLASH_BUSY) && (time_out != 0x00));
  379. FLASH->CR = 0;
  380. FLASH->SR = FLASH_SR_EOP | FLASH_SR_WRPRTERR | FLASH_SR_PGERR;
  381. return (FLASH_Status)((time_out == 0x00) ? FLASH_TIMEOUT : ret);
  382. }
  383. ////////////////////////////////////////////////////////////////////////////////
  384. /// @brief Erases a specified FLASH page.
  385. /// @note This function can be used for all MM32 devices.
  386. /// @param Page_Address: The page address to be erased.
  387. /// @retval None.
  388. ////////////////////////////////////////////////////////////////////////////////
  389. void exFLASH_EraseEE(u32 page_address)
  390. {
  391. FLASH_Unlock();
  392. FLASH_ErasePage(page_address);
  393. FLASH_Lock();
  394. }
  395. ////////////////////////////////////////////////////////////////////////////////
  396. /// @brief Programs a buffer at a specified address.
  397. /// @note This function can be used for all MM32 devices.
  398. /// @param *buf: the pointer of the buffer to be programmed.
  399. /// @param addr: specifies the address to be programmed.
  400. /// @param len: the number of bytes in the buffer.
  401. /// This parameter can only be even.
  402. /// @retval None.
  403. ////////////////////////////////////////////////////////////////////////////////
  404. void exFLASH_ProgramEE(u16* buf, u32 addr, u16 len)
  405. {
  406. u16 i;
  407. FLASH_Unlock();
  408. for (i = 0; i < len / 2; i++) {
  409. FLASH_ProgramHalfWord(addr, *buf);
  410. addr += 2;
  411. buf++;
  412. }
  413. FLASH_Lock();
  414. }
  415. ////////////////////////////////////////////////////////////////////////////////
  416. /// @brief Determine if the data that at the ptr address with the length is len
  417. /// is empty.
  418. /// @note This function can be used for all MM32 devices.
  419. /// @param *ptr: the pointer of the starting address.
  420. /// @param len: the number of bytes.
  421. /// This parameter can only be even.
  422. /// @retval 1 presents the data is empty,
  423. /// 0 presents the data has been written.
  424. ////////////////////////////////////////////////////////////////////////////////
  425. u8 exFLASH_FindEmpty(u16* ptr, u16 len)
  426. {
  427. u16 i;
  428. for (i = 0; i < (len / 2); i++) {
  429. if (*(ptr + i) != 0xffff)
  430. return 0;
  431. }
  432. return 1;
  433. }
  434. ////////////////////////////////////////////////////////////////////////////////
  435. /// @brief Locate the writable area on the specified address.
  436. /// @note This function can be used for all MM32 devices.
  437. /// @param page_address: specifies the beginning of the EEprom.
  438. /// The EEprom can be some continuously pages in the flash.
  439. /// @param len: the number of bytes to be written.
  440. /// This parameter can only be even.
  441. /// @retval the pointer of the starting address.
  442. ////////////////////////////////////////////////////////////////////////////////
  443. void* exFLASH_Locate(u32 page_address, u16 len)
  444. {
  445. u16 i;
  446. u16* ptr = (u16*)page_address;
  447. for (i = 0; i < (0x0800 / len); i++) {
  448. if (exFLASH_FindEmpty(ptr, len)) {
  449. if (i == 0)
  450. return 0;
  451. break;
  452. }
  453. ptr += len / 2;
  454. }
  455. return ptr;
  456. }
  457. ////////////////////////////////////////////////////////////////////////////////
  458. /// @brief Programs a buffer at a specified address.
  459. /// @note This function can be used for all MM32 devices.
  460. /// @param *buf: the pointer of the buffer to be programmed.
  461. /// @param page_address: specifies the beginning of the EEprom.
  462. /// The EEprom can be some continuously pages in the flash.
  463. /// @param len: the number of bytes in the buffer.
  464. /// This parameter can only be even.
  465. /// @retval None.
  466. ////////////////////////////////////////////////////////////////////////////////
  467. void exFLASH_WriteEE(u16* buf, u32 page_address, u16 len)
  468. {
  469. u16* ptr = exFLASH_Locate(page_address, len);
  470. if (ptr == 0) {
  471. exFLASH_EraseEE(page_address + 0x000);
  472. exFLASH_EraseEE(page_address + 0x400);
  473. exFLASH_ProgramEE(buf, page_address, len);
  474. }
  475. else {
  476. if (ptr == (u16*)(page_address + ((0x0400 / len) - 1) * len)) {
  477. exFLASH_EraseEE(page_address + 0x400);
  478. exFLASH_ProgramEE(buf, (u32)ptr, len);
  479. }
  480. else if (ptr == (u16*)(page_address + 0x0800)) {
  481. exFLASH_EraseEE(page_address + 0x000);
  482. exFLASH_ProgramEE(buf, (u32)page_address, len);
  483. }
  484. else {
  485. exFLASH_ProgramEE(buf, (u32)ptr, len);
  486. }
  487. }
  488. }
  489. ////////////////////////////////////////////////////////////////////////////////
  490. /// @brief Read the beginning address of the last written data.
  491. /// @note This function can be used for all MM32 devices.
  492. /// @param page_address: specifies the beginning of the EEprom.
  493. /// The EEprom can be some continuously pages in the flash.
  494. /// @param len: the number of bytes have been written.
  495. /// This parameter can only be even.
  496. /// @retval the beginning address of the last written data.
  497. /// 0 presents that this is the first time to use this as EEprom.
  498. ////////////////////////////////////////////////////////////////////////////////
  499. void* exFLASH_ReadEE(u32 page_address, u16 len)
  500. {
  501. u16* ptr = exFLASH_Locate(page_address, len);
  502. return (ptr == 0) ? 0 : (ptr - len / 2);
  503. }
  504. /// @}
  505. /// @}
  506. /// @}