onchip_flash.c 9.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331
  1. #include "onechip_include_header.h"
  2. // 用户数据存储地址——选择Flash末尾区域,避免覆盖程序代码
  3. // STM32F103RE Flash: 0x08000000 ~ 0x0807FFFF (512KB)
  4. #define CFG_PARAM_START_ADDR 0x0807F800 // 最后1页(2KB)起始地址
  5. #define onechip_name "Onechip602"
  6. #define onechip_pswd "onechip1003"
  7. #define onechip_IP "192.168.1.10"
  8. #define onechip_PORT "8003"
  9. #define default_SN "2603001"
  10. /**
  11. * @brief 从指定Flash地址读取32位数据
  12. */
  13. uint32_t Flash_ReadWord(uint32_t address)
  14. {
  15. return *(__IO uint32_t*)address;
  16. }
  17. /**
  18. * @brief 从指定Flash地址读取16位数据
  19. */
  20. uint16_t Flash_ReadHalfWord(uint32_t address)
  21. {
  22. return *(__IO uint16_t*)address;
  23. }
  24. /**
  25. * @brief 向Flash写入16位数据(半字)
  26. * @param address 目标地址(必须为偶数,2字节对齐)
  27. * @param data 要写入的数据(16位)
  28. * @retval HAL_OK 成功,否则失败
  29. */
  30. HAL_StatusTypeDef Flash_WriteHalfWord(uint32_t address, uint16_t data)
  31. {
  32. HAL_StatusTypeDef status = HAL_ERROR;
  33. // 1. 解锁Flash
  34. HAL_FLASH_Unlock();
  35. // 2. 写入半字数据
  36. status = HAL_FLASH_Program(FLASH_TYPEPROGRAM_HALFWORD, address, data);
  37. // 3. 锁定Flash
  38. HAL_FLASH_Lock();
  39. return status;
  40. }
  41. /**
  42. * @brief 向Flash写入32位数据(字)
  43. * @param address 目标地址(必须为4字节对齐)
  44. * @param data 要写入的数据(32位)
  45. */
  46. HAL_StatusTypeDef Flash_WriteWord(uint32_t address, uint32_t data)
  47. {
  48. HAL_StatusTypeDef status = HAL_ERROR;
  49. HAL_FLASH_Unlock();
  50. status = HAL_FLASH_Program(FLASH_TYPEPROGRAM_WORD, address, data);
  51. HAL_FLASH_Lock();
  52. return status;
  53. }
  54. /**
  55. * @brief 擦除指定Flash页
  56. * @param page_address 页起始地址(必须是页边界对齐)
  57. */
  58. HAL_StatusTypeDef Flash_ErasePage(uint32_t page_address)
  59. {
  60. HAL_StatusTypeDef status = HAL_ERROR;
  61. FLASH_EraseInitTypeDef EraseInitStruct;
  62. uint32_t PageError = 0;
  63. // 计算页号
  64. // uint32_t page_num = (page_address - FLASH_BASE) / FLASH_PAGE_SIZE;
  65. HAL_FLASH_Unlock();
  66. EraseInitStruct.TypeErase = FLASH_TYPEERASE_PAGES;
  67. EraseInitStruct.PageAddress = page_address;
  68. EraseInitStruct.NbPages = 1;
  69. status = HAL_FLASHEx_Erase(&EraseInitStruct, &PageError);
  70. HAL_FLASH_Lock();
  71. return status;
  72. }
  73. /**
  74. * @brief 向Flash写入多个半字数据(自动处理擦除)
  75. * @param start_addr 起始地址
  76. * @param pBuffer 数据缓冲区
  77. * @param NumToWrite 要写入的半字数量
  78. */
  79. void Flash_WriteBuffer(uint32_t start_addr, uint8_t *pBuffer, uint32_t NumToWrite)
  80. {
  81. // 1. 擦除目标页
  82. uint32_t page_start = start_addr - (start_addr % FLASH_PAGE_SIZE);
  83. Flash_ErasePage(page_start);
  84. // 2. 依次写入每个半字
  85. for (uint32_t i = 0; i < NumToWrite; i=i+4) {
  86. Flash_WriteWord(start_addr + i, *(uint32_t *)(pBuffer+i));
  87. }
  88. }
  89. /**
  90. * @brief 向Flash写入多个半字数据(自动处理擦除)
  91. * @param start_addr 起始地址
  92. * @param pBuffer 数据缓冲区
  93. * @param NumToWrite 要写入的半字数量
  94. */
  95. void Flash_ReadBuffer(uint32_t start_addr, uint8_t *pBuffer, uint32_t NumToWrite){
  96. for (uint32_t i = 0; i < NumToWrite; i=i+4) {
  97. *(uint32_t *)(pBuffer+i) = *(__IO uint32_t*)(start_addr + i);
  98. }
  99. }
  100. /********************************************************************
  101. * checksum_calc()
  102. *
  103. *描述:接收数据checksum计算
  104. *参数:pdata:要计算的数据
  105. * len:要计算的数据长度
  106. *返回:checksum值
  107. *其他:无
  108. *--------------------------------------------------------------------
  109. *记录:
  110. ********************************************************************/
  111. uint32_t checksum_calc(uint8_t *pdata, uint8_t len)
  112. {
  113. uint8_t *tmp = pdata;
  114. uint32_t checksum = 0;
  115. for(uint8_t i = 0; i < len; i++)
  116. {
  117. checksum += tmp[i];
  118. }
  119. return checksum;
  120. }
  121. /********************************************************************
  122. * checksum_calc()
  123. *
  124. *描述:接收数据checksum计算
  125. *参数:pdata:要计算的数据
  126. * len:要计算的数据长度
  127. *返回:checksum值
  128. *其他:无
  129. *--------------------------------------------------------------------
  130. *记录:
  131. ********************************************************************/
  132. uint32_t checksum_calc1(uint8_t *wdata, int len)
  133. {
  134. uint32_t checksum = 0;
  135. for(int i = 0; i < len; i++)
  136. {
  137. checksum += wdata[i];
  138. }
  139. return checksum;
  140. }
  141. /********************************************************************
  142. * cfg_load_default_param()
  143. *
  144. *描述:加载默认参数
  145. *参数:无
  146. *返回:无
  147. *其他:无
  148. *--------------------------------------------------------------------
  149. *记录:
  150. ********************************************************************/
  151. void cfg_load_default_param(void)
  152. {
  153. #ifdef ONECHIP_MINI_ONE
  154. sysinf.lysis_offset = 0;
  155. sysinf.lysis_overHeat = 3;
  156. sysinf.lysis_overHeatTime = 10;
  157. sysinf.lysis_Kp = 5;
  158. sysinf.lysis_Ki = 0.01;
  159. sysinf.lysis_Kd = 0;
  160. #else
  161. sysinf.amplif_Kp_Slave = 20;
  162. sysinf.amplif_Ki_Slave = 0.05;
  163. sysinf.amplif_Kd_Slave = 0;
  164. sysinf.PresetTempVal_Slave = 72;
  165. sysinf.PresetTempTime_Slave = 5;
  166. sysinf.SetTempVal_Slave = 68;
  167. sysinf.holdTemp_Slave = 63.5;
  168. sysinf.PreHeatTime_Slave = 10;
  169. sysinf.readyTemp_Slave = 65.5;
  170. sysinf.adjtemp = -0.5;
  171. #endif
  172. sysinf.amplif_Kp = 20;
  173. sysinf.amplif_Ki = 0.05;
  174. sysinf.amplif_Kd = 0;
  175. sysinf.PresetTempVal = 72;
  176. sysinf.PresetTempTime = 5;
  177. sysinf.SetTempVal = 68;
  178. sysinf.holdTemp = 63.5;
  179. sysinf.PreHeatTime = 10;
  180. sysinf.readyTemp = 65.5;
  181. sysinf.adjtemp = -0.5;
  182. sysinf.log_level = VAN_LOG_ERROR|VAN_LOG_INFO|VAN_LOG_TEMP|VAN_LOG_WIFI;
  183. sysinf.skip_CheckOrRun = 0;
  184. sysinf.timeinner = 6000;
  185. sysinf.swingtime = 100;
  186. sysinf.swingspeed = 60;
  187. // sysinf.swingtimeRight = 40;
  188. // sysinf.swingtimePause = 100;
  189. // sysinf.runLoopTime = 600;
  190. // sysinf.runLoopSpeed = 80;
  191. strcpy(sysinf.wifiname, onechip_name);
  192. strcpy(sysinf.password, onechip_pswd);
  193. strcpy(sysinf.TCP_IP_Addr, onechip_IP);
  194. strcpy(sysinf.TCP_IP_PORT, onechip_PORT);
  195. memset(sysinf.SN, 0 ,sizeof(sysinf.SN));
  196. strcpy(sysinf.SN, default_SN);
  197. }
  198. /********************************************************************
  199. * cfg_param_verify()
  200. *
  201. *描述:配置参数校验
  202. *参数:无
  203. *返回:0/1:校验不通过/通过
  204. *其他:无
  205. *--------------------------------------------------------------------
  206. *记录:
  207. ********************************************************************/
  208. uint8_t cfg_param_verify(void)
  209. {
  210. unsigned char pramlen = sizeof(oneChipSysdef) - offsetof(oneChipSysdef, SN);
  211. uint32_t saveCrc = *(uint32_t *)(CFG_PARAM_START_ADDR + (pramlen-4));
  212. uint32_t calCrc = checksum_calc((uint8_t *)CFG_PARAM_START_ADDR, (pramlen-4));
  213. if((saveCrc == calCrc) && (saveCrc != 0xffffffff)) {
  214. Flash_ReadBuffer(CFG_PARAM_START_ADDR,(uint8_t *)&sysinf.SN, pramlen);
  215. }
  216. return 0;
  217. }
  218. /********************************************************************
  219. * cfg_save_cfg_param()
  220. *
  221. *描述:保存配置参数
  222. *参数:无
  223. *返回:0/1:保存失败/成功
  224. *其他:无
  225. *--------------------------------------------------------------------
  226. *记录:
  227. ********************************************************************/
  228. uint8_t cfg_save_cfg_param(void)
  229. {
  230. unsigned char pramlen = sizeof(oneChipSysdef) - offsetof(oneChipSysdef, SN);
  231. sysinf.checksum = (uint32_t)checksum_calc((uint8_t *)&sysinf.SN, (pramlen-4));
  232. Flash_WriteBuffer(CFG_PARAM_START_ADDR, (uint8_t *)&sysinf.SN, pramlen);
  233. return cfg_param_verify();
  234. }
  235. /********************************************************************
  236. * cfg_param_init()
  237. *
  238. *描述:配置参数初始化
  239. *参数:无
  240. *返回:0/1:初始化失败/成功
  241. *其他:无
  242. *--------------------------------------------------------------------
  243. *记录:
  244. ********************************************************************/
  245. uint8_t cfg_param_init(void)
  246. {
  247. uint8_t rlt = 0;
  248. unsigned char pramlen = sizeof(oneChipSysdef) - offsetof(oneChipSysdef, SN);
  249. uint32_t saveCrc = *(uint32_t *)(CFG_PARAM_START_ADDR + (pramlen-4));
  250. uint32_t calCrc = checksum_calc((uint8_t *)CFG_PARAM_START_ADDR, (pramlen-4));
  251. if((saveCrc == calCrc) && (saveCrc != 0xffffffff))
  252. {
  253. Flash_ReadBuffer(CFG_PARAM_START_ADDR,(uint8_t *)&sysinf.SN, pramlen);
  254. return 0;
  255. }
  256. else
  257. {
  258. cfg_load_default_param();
  259. rlt = cfg_save_cfg_param();
  260. Van_Device_Printf(VAN_LOG_ERROR, "load parm err,please checking....\r\n");
  261. }
  262. return rlt;
  263. }
  264. /**
  265. * @brief 跳转到应用程序段(执行APP)
  266. * @param appxaddr : 应用程序的起始地址
  267. * @retval 无
  268. */
  269. void iap_load_app(uint32_t appxaddr)
  270. {
  271. if (((*(volatile uint32_t *)appxaddr) & 0x2FFE0000) == 0x20000000) /* 检查栈顶地址是否合法.可以放在内部SRAM共64KB(0x20000000) */
  272. {
  273. /* 用户代码区第二个字为程序开始地址(复位地址) */
  274. iapfun jump2app = (iapfun) * (volatile uint32_t *)(appxaddr + 4);
  275. // HAL_DeInit();
  276. /* 初始化APP堆栈指针(用户代码区的第一个字用于存放栈顶地址) */
  277. __set_MSP(*(volatile uint32_t *)appxaddr);
  278. /* 跳转到APP */
  279. jump2app();
  280. }
  281. }