mcu_flash_drv.c 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200
  1. #include "board.h"
  2. #define FLASH_BYPASS do{M0P_FLASH->BYPASS = 0x5A5A;\
  3. M0P_FLASH->BYPASS = 0xA5A5; }while(0)
  4. // HC32L196
  5. // page Size:512bytes
  6. // total size:256Kbyes(512page)
  7. // space :0x08000000 ~ 0x0803FFFF
  8. void McuFlash_init(void)
  9. {
  10. rt_base_t level;
  11. level = rt_hw_interrupt_disable();
  12. #if defined(SYSCLK_4M_MODE)
  13. FLASH_BYPASS;
  14. M0P_FLASH->TNVS = 0x020u;
  15. FLASH_BYPASS;
  16. M0P_FLASH->TPGS = 0x017u;
  17. FLASH_BYPASS;
  18. M0P_FLASH->TPROG = 0x01Bu;
  19. FLASH_BYPASS;
  20. M0P_FLASH->TSERASE = 0x04650u;
  21. FLASH_BYPASS;
  22. M0P_FLASH->TMERASE = 0x0222E0u;
  23. FLASH_BYPASS;
  24. M0P_FLASH->TPRCV = 0x018u;
  25. FLASH_BYPASS;
  26. M0P_FLASH->TSRCV = 0x0F0u;
  27. FLASH_BYPASS;
  28. M0P_FLASH->TMRCV = 0x03E8u;
  29. #elif defined(SYSCLK_8M_MODE)
  30. FLASH_BYPASS;
  31. M0P_FLASH->TNVS = 0x040u;
  32. FLASH_BYPASS;
  33. M0P_FLASH->TPGS = 0x02Eu;
  34. FLASH_BYPASS;
  35. M0P_FLASH->TPROG = 0x036u;
  36. FLASH_BYPASS;
  37. M0P_FLASH->TSERASE = 0x08CA0u;
  38. FLASH_BYPASS;
  39. M0P_FLASH->TMERASE = 0x0445C0u;
  40. FLASH_BYPASS;
  41. M0P_FLASH->TPRCV = 0x030u;
  42. FLASH_BYPASS;
  43. M0P_FLASH->TSRCV = 0x1E0u;
  44. FLASH_BYPASS;
  45. M0P_FLASH->TMRCV = 0x07D0u;
  46. #elif defined(SYSCLK_16M_MODE)
  47. FLASH_BYPASS;
  48. M0P_FLASH->TNVS = 0x080u;
  49. FLASH_BYPASS;
  50. M0P_FLASH->TPGS = 0x05Cu;
  51. FLASH_BYPASS;
  52. M0P_FLASH->TPROG = 0x06Cu;
  53. FLASH_BYPASS;
  54. M0P_FLASH->TSERASE = 0x11940u;
  55. FLASH_BYPASS;
  56. M0P_FLASH->TMERASE = 0x088B80u;
  57. FLASH_BYPASS;
  58. M0P_FLASH->TPRCV = 0x060u;
  59. FLASH_BYPASS;
  60. M0P_FLASH->TSRCV = 0x3C0u;
  61. FLASH_BYPASS;
  62. M0P_FLASH->TMRCV = 0x0FA0u;
  63. #endif
  64. rt_hw_interrupt_enable(level);
  65. }
  66. void McuFlash_WaitBusy(void)
  67. {
  68. while(M0P_FLASH->CR_f.BUSY){
  69. // wait until not busy
  70. }
  71. }
  72. void McuFlash_Unlock(void)
  73. {
  74. rt_base_t level;
  75. level = rt_hw_interrupt_disable();
  76. FLASH_BYPASS;
  77. M0P_FLASH->SLOCK0 = 0xFFFFFFFF; // 0:forbid PE; 1:allow PE;
  78. FLASH_BYPASS;
  79. M0P_FLASH->SLOCK1 = 0xFFFFFFFF;
  80. FLASH_BYPASS;
  81. M0P_FLASH->SLOCK2 = 0xFFFFFFFF;
  82. FLASH_BYPASS;
  83. M0P_FLASH->SLOCK3 = 0xFFFFFFFF;
  84. rt_hw_interrupt_enable(level);
  85. }
  86. void McuFlash_Lock(void)
  87. {
  88. rt_base_t level;
  89. McuFlash_WaitBusy();
  90. level = rt_hw_interrupt_disable();
  91. FLASH_BYPASS;
  92. M0P_FLASH->SLOCK0 = 0x00000000; // 0:forbid PE; 1:allow PE;
  93. FLASH_BYPASS;
  94. M0P_FLASH->SLOCK1 = 0x00000000;
  95. FLASH_BYPASS;
  96. M0P_FLASH->SLOCK2 = 0x00000000;
  97. FLASH_BYPASS;
  98. M0P_FLASH->SLOCK3 = 0x00000000;
  99. rt_hw_interrupt_enable(level);
  100. }
  101. #ifndef BOOTLOADER_ENABLE
  102. void McuFlash_ErasePage(uint32_t addr)
  103. {
  104. rt_base_t level;
  105. McuFlash_WaitBusy();
  106. level = rt_hw_interrupt_disable();
  107. FLASH_BYPASS;
  108. M0P_FLASH->CR_f.OP = 0x2u; // 0:read; 1:probram; 2:sector rease; 3:chip erase
  109. *((volatile uint8_t *)addr) = 0xFFu; // start erase page
  110. rt_hw_interrupt_enable(level);
  111. }
  112. void McuFlash_WordPP(uint32_t addr, uint32_t data)
  113. {
  114. rt_base_t level;
  115. McuFlash_WaitBusy();
  116. level = rt_hw_interrupt_disable();
  117. FLASH_BYPASS;
  118. M0P_FLASH->CR_f.OP = 0x1u; // 0:read; 1:probram; 2:sector rease; 3:chip erase
  119. *((volatile uint32_t *)addr) = data; // start program
  120. rt_hw_interrupt_enable(level);
  121. }
  122. #endif
  123. void McuFlash_EraseSegment(uint32_t start, uint32_t len)
  124. {
  125. uint32_t end;
  126. // Page size = 512byts
  127. // total 512xPages
  128. end = start+len-1; // be sure start + len < 0xFFFFFFFFu - 0xFFu
  129. while(start<=end){
  130. McuFlash_ErasePage(start);
  131. start += 512;
  132. }
  133. }
  134. // prepare for word programming
  135. void McuFlash_OpenWP(uint32_t addr, McuFlash_WP_t *p)
  136. {
  137. p->addr = addr & ~0x3u; // must 4 bytes aligned
  138. p->idx = 0;
  139. }
  140. // program words from buffer
  141. void McuFlash_Buf2WP(uint8_t *buf, uint32_t len, McuFlash_WP_t *p)
  142. {
  143. while(len--){ // program size is 4 byte
  144. p->u.byte[p->idx] = *buf++;
  145. if (p->idx==3){
  146. p->idx = 0;
  147. McuFlash_WordPP(p->addr, p->u.word);
  148. p->addr += 4;
  149. } else {
  150. p->idx++;
  151. }
  152. }
  153. }
  154. // program last not enough gathered word if exists
  155. void McuFlash_CloseWP(McuFlash_WP_t *p)
  156. {
  157. if (p->idx!=0){
  158. while(p->idx<4){
  159. p->u.byte[p->idx] = 0xFFu;
  160. p->idx++;
  161. }
  162. p->idx = 0;
  163. McuFlash_WordPP(p->addr, p->u.word);
  164. p->addr += 4;
  165. }
  166. }