CH57x_flash.c 9.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283
  1. /********************************** (C) COPYRIGHT *******************************
  2. * File Name : CH57x_flash.c
  3. * Author : WCH
  4. * Version : V1.1
  5. * Date : 2020/03/20
  6. * Description :
  7. *******************************************************************************/
  8. /******************************************************************************/
  9. /* 头文件包含 */
  10. #include "CH57x_common.h"
  11. /* 操作Flash的保护状态标志 */
  12. #define CODEFLASH_SAFE_FLAG1 0x57
  13. #define CODEFLASH_SAFE_FLAG2 0xA8
  14. /* 操作Flash的保护状态变量 */
  15. unsigned char codeflash_access_flag1 = 0x0;
  16. unsigned char codeflash_access_flag2 = 0x0;
  17. /*******************************************************************************
  18. * Function Name : GetUniqueID
  19. * Description : 获取芯片唯一ID,小端模式,6B-ID, 2B-CKS
  20. * Input : buf: 存储8字节,前6字节(小端)ID,后2字节(小端)校验和
  21. * Return : None
  22. *******************************************************************************/
  23. void GetUniqueID(PUINT8 buf)
  24. {
  25. PUINT8 pID;
  26. UINT8 i;
  27. pID = (PUINT8)ROM_UUID_ADDR;
  28. for(i=0; i<8; i++) *buf++ = *pID++;
  29. }
  30. /*******************************************************************************
  31. * Function Name : GetMACAddress
  32. * Description : 获取网络MAC,小端模式,6B-MAC
  33. * Input : buf: 存储6字节,6字节(小端)物理 MAC
  34. * Return : None
  35. *******************************************************************************/
  36. void GetMACAddress(PUINT8 buf)
  37. {
  38. PUINT8 pMAC;
  39. UINT8 i;
  40. pMAC = (PUINT8)ROM_MAC_ADDR;
  41. for(i=0; i<6; i++) *buf++ = *pMAC++;
  42. }
  43. /*******************************************************************************
  44. * Function Name : FlashBlockErase
  45. * Description : Flash 块擦除,一次擦除512B
  46. * Input : addr: 32位地址,需要512对齐
  47. * codeflash: startAddr - 0x00000000 size - 0x3E800
  48. * dataflash: startAddr - 0x3E800(DATA_FLASH_ADDR) size - 0x0800(DATA_FLASH_SIZE)
  49. * Return : 0 - 成功,其他 - 错误
  50. *******************************************************************************/
  51. UINT8 FlashBlockErase(UINT32 addr)
  52. {
  53. UINT8 status = 0;
  54. volatile UINT8 op_step;
  55. if( addr & (0x200-1) ) return 1; //地址不对齐
  56. op_step = 0x11;
  57. codeflash_access_flag1 = 0;
  58. codeflash_access_flag2 = 0;
  59. R8_FLASH_PROTECT = RB_ROM_WE_MUST_10;
  60. //开启电压监控中断
  61. op_step += 0x11;
  62. if((R8_BAT_DET_CTRL & 0x0F) != 0x0D) PowerMonitor( ENABLE );
  63. op_step += 0x11;
  64. if((R8_BAT_STATUS & 0x03) != 0x00) return 2; //电源电压偏低,Flash不允许操作
  65. op_step += 0x11;
  66. if(((R8_BAT_STATUS & 0x03) == 0x00)
  67. &&(op_step == 0x44))
  68. {
  69. codeflash_access_flag1 = CODEFLASH_SAFE_FLAG1;
  70. }
  71. op_step += 0x11;
  72. if(((R8_BAT_STATUS & 0x03) == 0x00)
  73. &&(op_step == 0x55)
  74. &&(codeflash_access_flag1 == CODEFLASH_SAFE_FLAG1))
  75. {
  76. codeflash_access_flag2 = CODEFLASH_SAFE_FLAG2;
  77. }
  78. op_step += 0x11;
  79. if((codeflash_access_flag1 == CODEFLASH_SAFE_FLAG1)
  80. &&(codeflash_access_flag2 == CODEFLASH_SAFE_FLAG2)
  81. &&(op_step == 0x66))
  82. {
  83. R32_FLASH_ADDR = addr;
  84. if( addr < DATA_FLASH_ADDR ) R8_FLASH_PROTECT = RB_ROM_WE_MUST_10|RB_ROM_CODE_WE; // Codefalsh区
  85. else R8_FLASH_PROTECT = RB_ROM_WE_MUST_10|RB_ROM_DATA_WE; // datafalsh区
  86. }
  87. op_step += 0x11;
  88. /* 判断操作Flash的保护状态标志 */
  89. if((codeflash_access_flag1 == CODEFLASH_SAFE_FLAG1)
  90. &&(codeflash_access_flag2 == CODEFLASH_SAFE_FLAG2)
  91. &&(op_step == 0x77))
  92. {
  93. R8_FLASH_COMMAND = ROM_CMD_ERASE;
  94. status = (unsigned char)(R16_FLASH_STATUS & 0xff);
  95. }
  96. op_step = 0x00;
  97. codeflash_access_flag1 = 0x00;
  98. codeflash_access_flag2 = 0x00;
  99. R8_FLASH_PROTECT = RB_ROM_WE_MUST_10; // LOCK
  100. if( status != RB_ROM_ADDR_OK ) return 3; //操作失败
  101. return 0;
  102. }
  103. /*******************************************************************************
  104. * Function Name : FlashWriteDW
  105. * Description : Flash 双字写,地址需4字节对齐
  106. * Input : addr: 32位地址,需要4对齐
  107. * codeflash: startAddr - 0x00000000 size - 0x3E800
  108. * dataflash: startAddr - 0x3E800(DATA_FLASH_ADDR) size - 0x0800(DATA_FLASH_SIZE)
  109. dat: 32位写入数据
  110. * Return : FAILED - 错误
  111. SUCCESS - 成功
  112. *******************************************************************************/
  113. UINT8 FlashWriteDW(UINT32 addr, UINT32 dat)
  114. {
  115. UINT32 add = addr;
  116. UINT32 val = dat;
  117. UINT8 status = 0;
  118. volatile UINT8 op_step;
  119. if( addr & (4-1) ) return 1; //地址不对齐
  120. op_step = 0x11;
  121. codeflash_access_flag1 = 0;
  122. codeflash_access_flag2 = 0;
  123. R8_FLASH_PROTECT = RB_ROM_WE_MUST_10;
  124. //开启电压监控中断
  125. op_step += 0x11;
  126. if((R8_BAT_DET_CTRL & 0x0F) != 0x0D) PowerMonitor( ENABLE );
  127. op_step += 0x11;
  128. if((R8_BAT_STATUS & 0x03) != 0x00) return 2; //电源电压偏低,Flash不允许操作
  129. op_step += 0x11;
  130. if(((R8_BAT_STATUS & 0x01) == 0x00)
  131. &&(op_step == 0x44))
  132. {
  133. codeflash_access_flag1 = CODEFLASH_SAFE_FLAG1;
  134. }
  135. op_step += 0x11;
  136. if(((R8_BAT_STATUS & 0x01) == 0x00)
  137. &&(op_step == 0x55)
  138. &&(codeflash_access_flag1 == CODEFLASH_SAFE_FLAG1))
  139. {
  140. codeflash_access_flag2 = CODEFLASH_SAFE_FLAG2;
  141. }
  142. op_step += 0x11;
  143. if((codeflash_access_flag1 == CODEFLASH_SAFE_FLAG1)
  144. &&(codeflash_access_flag2 == CODEFLASH_SAFE_FLAG2)
  145. &&(op_step == 0x66))
  146. {
  147. if( addr < DATA_FLASH_ADDR ) R8_FLASH_PROTECT = RB_ROM_WE_MUST_10|RB_ROM_CODE_WE; // Codefalsh区
  148. else R8_FLASH_PROTECT = RB_ROM_WE_MUST_10|RB_ROM_DATA_WE; // datafalsh区
  149. }
  150. op_step += 0x11;
  151. /* 判断OTA操作Flash的保护状态标志 */
  152. if((codeflash_access_flag1==CODEFLASH_SAFE_FLAG1)
  153. &&(codeflash_access_flag2==CODEFLASH_SAFE_FLAG2)
  154. &&(op_step == 0x77))
  155. {
  156. R32_FLASH_ADDR = add;
  157. R32_FLASH_DATA = val;
  158. R8_FLASH_COMMAND = ROM_CMD_PROG;
  159. status = (unsigned char)(R16_FLASH_STATUS & 0xff);
  160. }
  161. op_step = 0x00;
  162. codeflash_access_flag1 = 0x00;
  163. codeflash_access_flag2 = 0x00;
  164. R8_FLASH_PROTECT = RB_ROM_WE_MUST_10;
  165. if( status != RB_ROM_ADDR_OK ) return 3; //操作失败
  166. return 0;
  167. }
  168. /*******************************************************************************
  169. * Function Name : FlashWriteBuf
  170. * Description : Flash 连续多个双字写入
  171. * Input : addr: 32位地址,需要4对齐
  172. * codeflash: startAddr - 0x00000000 size - 0x3E800
  173. * dataflash: startAddr - 0x3E800(DATA_FLASH_ADDR) size - 0x0800(DATA_FLASH_SIZE)
  174. * pdat: 待写入数据缓存区首地址
  175. * len: 待写入数据字节长度
  176. * Return : 0 - 成功,其他 - 错误
  177. *******************************************************************************/
  178. UINT8 FlashWriteBuf(UINT32 addr, PUINT32 pdat, UINT16 len)
  179. {
  180. UINT32 add = addr;
  181. PUINT32 p32 = pdat;
  182. UINT8 status = 0;
  183. UINT16 i;
  184. volatile UINT8 op_step;
  185. if( addr & (4-1) ) return 1; //地址不对齐
  186. op_step = 0x11;
  187. codeflash_access_flag1 = 0;
  188. codeflash_access_flag2 = 0;
  189. R8_FLASH_PROTECT = RB_ROM_WE_MUST_10;
  190. //开启电压监控中断
  191. op_step += 0x11;
  192. if((R8_BAT_DET_CTRL & 0x0F) != 0x0D) PowerMonitor( ENABLE );
  193. op_step += 0x11;
  194. if((R8_BAT_STATUS & 0x03) != 0x00) return 2; //电源电压偏低,Flash不允许操作
  195. op_step += 0x11;
  196. if(((R8_BAT_STATUS & 0x01) == 0x00)
  197. &&(op_step == 0x44))
  198. {
  199. codeflash_access_flag1 = CODEFLASH_SAFE_FLAG1;
  200. }
  201. op_step += 0x11;
  202. if(((R8_BAT_STATUS & 0x01) == 0x00)
  203. &&(op_step == 0x55)
  204. &&(codeflash_access_flag1 == CODEFLASH_SAFE_FLAG1))
  205. {
  206. codeflash_access_flag2 = CODEFLASH_SAFE_FLAG2;
  207. }
  208. op_step += 0x11;
  209. if((codeflash_access_flag1 == CODEFLASH_SAFE_FLAG1)
  210. &&(codeflash_access_flag2 == CODEFLASH_SAFE_FLAG2)
  211. &&(op_step == 0x66))
  212. {
  213. if( addr < DATA_FLASH_ADDR ) R8_FLASH_PROTECT = RB_ROM_WE_MUST_10|RB_ROM_CODE_WE; // Codefalsh区
  214. else R8_FLASH_PROTECT = RB_ROM_WE_MUST_10|RB_ROM_DATA_WE; // datafalsh区
  215. }
  216. op_step += 0x11;
  217. /* 判断OTA操作Flash的保护状态标志 */
  218. if((codeflash_access_flag1==CODEFLASH_SAFE_FLAG1)
  219. &&(codeflash_access_flag2==CODEFLASH_SAFE_FLAG2)
  220. &&(op_step == 0x77))
  221. {
  222. for(i=0; i<len; i+=4)
  223. {
  224. R32_FLASH_ADDR = add;
  225. R32_FLASH_DATA = *p32++;
  226. R8_FLASH_COMMAND = ROM_CMD_PROG;
  227. add += 4;
  228. //status = R8_FLASH_STATUS;
  229. status = (unsigned char)(R16_FLASH_STATUS & 0xff);
  230. if( status != RB_ROM_ADDR_OK ) break;
  231. }
  232. }
  233. op_step = 0x00;
  234. codeflash_access_flag1 = 0x00;
  235. codeflash_access_flag2 = 0x00;
  236. R8_FLASH_PROTECT = RB_ROM_WE_MUST_10;
  237. if( status != RB_ROM_ADDR_OK ) return 3; //操作失败
  238. return 0;
  239. }