main.c 28 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946
  1. /*
  2. * Copyright (c) 2006-2021, RT-Thread Development Team
  3. *
  4. * SPDX-License-Identifier: Apache-2.0
  5. *
  6. * Change Logs:
  7. * Date Author Notes
  8. * 2021-09-11 RT-Thread first version
  9. */
  10. #define RTC_Alarm_RETRY RTC_BKP_DR2
  11. #define RTC_Lora_Cfg RTC_BKP_DR4
  12. #include <rtthread.h>
  13. #include "main.h"
  14. #define DBG_LVL DBG_LOG
  15. #include <rtdbg.h>
  16. #include <stdlib.h>
  17. #include <usart.h>
  18. #include <easyflash.h>
  19. #include "Host.h"
  20. #include "driver_adc.h"
  21. #include "bsp_rtc.h"
  22. #include "rtc.h"
  23. #include "modbus_host.h"
  24. #include "loar.h"
  25. #include "wwdg.h"
  26. #include "gprs.h"
  27. #include "driver_spiflash.h"
  28. #include "iap.h"
  29. static void test_env(void);
  30. static void Trans_protect(void);
  31. extern UART_HandleTypeDef huart1;
  32. extern UART_HandleTypeDef huart2;
  33. extern UART_HandleTypeDef huart3;
  34. extern ADC_HandleTypeDef hadcx;
  35. extern RTC_DateTypeDef GetData; // 获取日期结构体
  36. extern RTC_TimeTypeDef GetTime; // 获取时间结构体
  37. extern RTC_HandleTypeDef hrtc;
  38. extern int Config_GPRS_State;
  39. extern uint8_t Tigger_RTC_Check;
  40. extern void All_standby(uint16_t stime, uint8_t level);
  41. extern void loat_cfg_mode(void);
  42. extern char GPRSReadFlag; // 这是串口3接收中断标记位
  43. extern uint8_t Get_loarID(void); // 获取模块ID
  44. extern LOAR_Parameter loar_par; // 这里面存放loar的参数和ID
  45. extern uint8_t GPRS_ReadBuff[]; // 串口3接收到的数据
  46. extern uint8_t Host_Service(void); // 主机服务程序
  47. extern uint8_t Lora_cfg_RTC; // RTC中的lora配置标记位
  48. extern uint8_t Valve_Mode; // 阀控模式
  49. extern uint8_t RTC_Shotdown; // 即刻休眠标记位
  50. SYS_INFO sys_info = {0}; /*其他系统信息结构体*/
  51. DateTime nowdate;
  52. uint8_t at_config(void);
  53. uint16_t VBAT_FORMAT_CONVERT(uint8_t type);
  54. uint8_t LedPlay(uint16_t Ledperiod, uint16_t LedOn_Cnt, uint16_t *pTimerCnt);
  55. uint8_t run_status = 0; // 0:开机未联网,1:正在联网,2:联网成功
  56. uint16_t TimerCnt;
  57. uint16_t LedOn_Rate;
  58. uint16_t Polar;
  59. uint16_t LedOn_Cnt;
  60. uint8_t easyflash_configured = 0;
  61. uint8_t Read_Para_ok = 0; // 标记开机读取参数完成 1:读取完成
  62. uint8_t Freq = 0; // 记录拨码开关读到的值
  63. uint16_t MCU_Temp = 0;
  64. uint8_t EXTI0_1_GPIO_PIN0 = 0;
  65. uint8_t Init_ok = 0; // 记录成功读取变送器数据的次数
  66. uint8_t All_finsh = Zero; // 事件处理完成标志
  67. uint8_t imei_fill = Zero; // 记录Imei是否已填充
  68. uint16_t Now_date = 0; // 写入IAP固件信息时记录时间
  69. uint16_t Now_Version = 0; // 传递给bl的版本号
  70. uint16_t VBAT = 0; // 采集的电压值
  71. BL_Para bl_par = {0}; // 存放BL传递相关参数
  72. Revise_par rev_par = {0}; // 从机交互相关参数
  73. volatile uint8_t RTC_Check = 0; // 记录开机时间点是否正确
  74. volatile uint8_t Start_LTE = Zero; // 开始LTE服务标志
  75. volatile uint8_t wwdg_state = Zero; // 标记看门后状态 初始化后置One 开始喂狗
  76. Record e_code[MAX_e_code_NUM] = {0}; // 错误码保存
  77. ///
  78. ///
  79. /// ver_d 版本号的16进制 整数
  80. /// 如最大值65535 代表版本号V65.535
  81. ///
  82. ///
  83. #define ver_d 3018
  84. /*
  85. * 2002 : 每次都开启定位
  86. * 2003 : 02 修改下发FTP 地址相关 (大数据平台) 修改 lte_app1.bin
  87. * 20031 : 测试FTP专用
  88. * 2004 : 关闭每次都开启定位,打印在那进入得休眠模式
  89. * 2005 : RC_IN 主动接受 长按主动上报
  90. * 2006 : 每次都开启定位,修改GSP定位相关问题
  91. * 2007 : GPS倍数问题修改 定时时间60s 3s等待时间改为6s led指示灯每33*30ms一反转 第二次测试使用
  92. * 2008 : GPS倍数问题修改,包含询问状态信息里的,修改4G透传模式 唐第一版测试
  93. * 2009 : 调整读取传感器数据位置,强制延时120s
  94. * 2010 : GPS读取7次去中间三次的平均值,每次都开启GPS(已经关闭)
  95. * 2011 : 修改参数修正的异常现象,传感器强制延时10s 添加要素模型-10w,修改读取传感器列表上报不全问题
  96. *---------
  97. * 2001 : 修改升级固件,不上报update √ +版本号问题
  98. * 2002 : 修改固件远程升级文件名,lte_appl.bin
  99. * 2003 : 13个要素不上传数据问题修改上传指令 修改 最大16个要素模型,mqtt下发最大长度不超过1990,1960内为准
  100. * 2004 : 默认温湿度传感器 + 默认前十次开启定位(远程控制清空)
  101. * --------
  102. * 2005 : 1.默认前二十次开启定位(远程控制清空),修改-1 未 =99
  103. * 2.修改上报数据抬头(删除版本号)json_head
  104. * 3.状态信息中添加上报时间间隔 interval
  105. * 4.调整默认传感器参数
  106. * 2006 : 传感器强制延时5s
  107. * 2007 : 增加跳过前20次GPS定位指令 写1000
  108. * 2008 : 增加读不到传感器进入休眠模式,删除无用程序,LED灯触发上报闪灯
  109. */
  110. /**
  111. * @brief 250815 接手代码
  112. *
  113. * 3001 : 恢复了按键指示
  114. * 3002 : 新增startUp_time 在开机log中展示
  115. * 3003 :新增定位成功后闪烁
  116. * 3004 : 去除无论如何都上报定位信息的问题
  117. * 3005 : 新增触发必定位,以加快验证定位功能
  118. * 3006 : 测试定位功能
  119. * 3007 : 修改升级url为 lte_appL.bin
  120. * 3008 : 修改:回传升级成功信息时不再定位
  121. * 3009 :修改为测试服务器+分支topic
  122. * 3010 : 继续修改topic
  123. * 3011 : 修改服务器为大数据平台
  124. * 3012 : 修改默认要素为温湿压
  125. * 3013 : 修改大数据平台为域名
  126. * 3014 : 修正没有状态上传的问题
  127. * 3015 : 测试没有状态上传的问题
  128. * 3016 : 升级到户外验证设备进行测试
  129. * * 3017/8 : 临时增强了rt_thread_idle_excute 防崩溃
  130. * 3019 : 定制了一个mqtt直传客户平台
  131. */
  132. char Version[22] = "Version "; // 版本号记录
  133. char task_id[9] = ""; // 任务单ID(若有)
  134. //默认的两个要素
  135. Sensor Def_Sensor[3] = {
  136. {"e1",1,0,1,0,-10,1,.eName = "Etemp",.eNum = "101",.cfged = 1},
  137. {"e2",1,1,1,0,-10,1,.eName = "Ehumi",.eNum = "102",.cfged = 1},
  138. {"e3",1,2,1,0,-10,1,.eName = "Airpress",.eNum = "103",.cfged = 1}
  139. };
  140. int main(void)
  141. {
  142. Show_Version();
  143. MX_RTC_Init();
  144. Enadble_module(1);
  145. Excute_ADC();
  146. EfErrCode easyinit = easyflash_init();
  147. if (easyinit == EF_NO_ERR)
  148. {
  149. easyflash_configured = 1;
  150. test_env();
  151. Trans_protect();
  152. Read_Para();
  153. }
  154. Check_Free();
  155. Host_Service();
  156. while (All_finsh == Zero)
  157. {
  158. rt_thread_mdelay(100);
  159. }
  160. All_standby(sys_info.interval, 3);
  161. return RT_EOK;
  162. }
  163. extern LOAR_Tx loar_t;
  164. extern uint8_t Get_loarID(void);
  165. extern Loar_Device Slave_list[];
  166. extern Bak_info bak_info;
  167. extern uint8_t Active_detection;
  168. extern uint8_t occupy_LTE;
  169. extern Sensor sensor[MAX_SENSOR_NUM];
  170. extern uint8_t printf_sensor_list(uint8_t Type);
  171. uint8_t bl_par_chg = 0;
  172. // 开机读取参数
  173. void Read_Para(void)
  174. {
  175. uint8_t sys_info_chg = 0; // 是否需要更新sys_info
  176. uint8_t loar_par_chg = 0; // 是否需要更新loar_par
  177. char strbuf[30];
  178. rt_memset(strbuf, 0, 30);
  179. Read_Para_ok = 0;
  180. /************** 参数1 的RAID1 ***************/
  181. if (ef_get_env_blob("sys_info", &sys_info, sizeof(sys_info), NULL) > 0)//有 sys_info 值
  182. {
  183. upgrade_bak_para(101);// 不是第一次进入 直接更新
  184. }
  185. else if (restore_bak_para(1) == One)//没有 "sys_info" 但是 200 地址有
  186. {
  187. ef_set_env_blob("sys_info", &sys_info, sizeof(sys_info)); //保存到 sys_info
  188. Recode_e_code(27, 1);
  189. }
  190. /************** 参数1 的RAID1 ***************/
  191. /************** 参数2 的RAID1 ***************/
  192. if (ef_get_env_blob("sensor", &sensor, sizeof(Sensor) * MAX_SENSOR_NUM, NULL) > 0)
  193. {
  194. upgrade_bak_para(102);
  195. #if Node_Type == LTE
  196. for (uint8_t a = 0; a < MAX_SENSOR_NUM; a++)
  197. {
  198. if(sensor[a].en_corr == 1 && a > (sys_info.Sensor_num - 1))//if 有修正要素 or 大于要素模型个数
  199. {
  200. sensor[a].en_corr = 0;
  201. }
  202. //rt_kprintf("s%d en %d > %d\n" , a , sensor[a].en_corr , sys_info.Sensor_num);
  203. }
  204. #endif
  205. }
  206. else if (restore_bak_para(2) == One)
  207. {
  208. ef_set_env_blob("sensor", &sensor, sizeof(Sensor) * MAX_SENSOR_NUM);
  209. Recode_e_code(27, 2);
  210. }
  211. /**
  212. * @brief 250917 新增默认要素分配
  213. *
  214. */
  215. if(sensor[0].cfged == 0 && sensor[1].cfged == 0)
  216. {
  217. memset(sensor , 0 , sizeof(sensor));
  218. memcpy(sensor , Def_Sensor , sizeof(Def_Sensor));
  219. sys_info.Sensor_num = 0;
  220. for(uint8_t a = 0 ; a < MAX_SENSOR_NUM ; a++)
  221. {
  222. if(sensor[a].cfged == 1)
  223. {
  224. sys_info.Sensor_num++;
  225. }
  226. }
  227. rt_kprintf("empty init sensor %d\n",sys_info.Sensor_num);
  228. ef_set_env_blob("sensor", &sensor, sizeof(Sensor) * MAX_SENSOR_NUM);
  229. ef_set_env_blob("sys_info", &sys_info, sizeof(sys_info));
  230. }
  231. ef_get_env_blob("sensor", &sensor, sizeof(Sensor) * MAX_SENSOR_NUM, NULL);
  232. ef_get_env_blob("bl_par", &bl_par, sizeof(BL_Para), NULL);
  233. // 运行模式
  234. if (sys_info.run_mode != One && sys_info.run_mode != Zero) // 校验标记位合法性
  235. {
  236. sys_info.run_mode = Zero;
  237. sys_info_chg = 1;
  238. }
  239. LOG_I(" Node_Type LTE");
  240. // 读取上报时间间隔的参数
  241. if (sys_info.interval <= 0 || sys_info.interval > 120) // 校验标记位合法性
  242. {
  243. sys_info.interval = 15; //默认上报时间为15分钟
  244. sys_info_chg = 1;
  245. LOG_W("INR def");
  246. }
  247. LOG_I(" Report interval %d", sys_info.interval);
  248. LOG_I(" Device IMEI: %s", sys_info.imei);
  249. if (sys_info.imei[0] != '\0')
  250. {
  251. imei_fill = One;
  252. sys_info.imei[15] = '\0';
  253. }
  254. LOG_I(" Device ICCID: %s", sys_info.iccid);
  255. if (sys_info.platform == Zero)
  256. {
  257. LOG_I(" Platform 120.27");
  258. }
  259. else if (sys_info.platform == One)
  260. {
  261. LOG_I(" Platform 8.136");
  262. }
  263. else
  264. {
  265. // LOG_W("plat reset");
  266. sys_info.platform = One;//默认大数据
  267. sys_info_chg = 1;
  268. }
  269. //更新固件是否正常
  270. if (sys_info.update_url[0] == '\0' || strstr(sys_info.update_url, ".bin") == NULL)//异常进入
  271. {
  272. if (Node_Type == LTE)
  273. {
  274. rt_sprintf(sys_info.update_url, "lte_appL.bin");
  275. sys_info_chg = 1;
  276. }
  277. }
  278. else
  279. {
  280. LOG_I(" Update url %s", sys_info.update_url);
  281. }
  282. // 读取485所接入的传感器数量
  283. if ((sys_info.Sensor_num < 0) || (sys_info.Sensor_num > MAX_SENSOR_NUM)) // 校验标记位合法性
  284. {
  285. // LOG_W("S_num reset %d", sys_info.Sensor_num);
  286. sys_info.Sensor_num = 0;//默认为 0 个
  287. sys_info_chg = 1;
  288. }
  289. LOG_I(" Sensor_num %d", sys_info.Sensor_num);
  290. int startUp_time = 0;
  291. ef_get_env_blob("startUp_time", &startUp_time, sizeof(startUp_time) , NULL);
  292. LOG_I(" startUp_time %d", startUp_time);
  293. if (Valve_Mode == 1)//不满足
  294. {
  295. if (sys_info.V1_Sta != One && sys_info.V1_Sta != Zero)
  296. {
  297. LOG_W("V1_Sta reset");
  298. sys_info.V1_Sta = Zero;
  299. sys_info_chg = 1;
  300. }
  301. LOG_I(" V1_Sta %d", sys_info.V1_Sta);
  302. if (sys_info.V2_Sta != One && sys_info.V2_Sta != Zero)
  303. {
  304. LOG_W("V2_Sta reset");
  305. sys_info.V2_Sta = Zero;
  306. sys_info_chg = 1;
  307. }
  308. LOG_I(" V2_Sta %d", sys_info.V2_Sta);
  309. }
  310. if (loar_par_chg == 1) //loar相关
  311. {
  312. loar_par_chg = 0;
  313. Para_upgrade(1);
  314. }
  315. printf_sensor_list(1);
  316. if (sys_info_chg == 1)
  317. {
  318. sys_info_chg = 0;
  319. Para_upgrade(2);
  320. }
  321. // 对启动状态参数自增 表明app正常启动
  322. LOG_I("BL ^");
  323. uint8_t IAP_success = 0;
  324. ///
  325. ///
  326. /// boot_state 是为了向BL传递当前启动状态的标记位
  327. ///
  328. ///
  329. if (bl_par.boot_state < One)
  330. {
  331. bl_par.boot_state += 20;
  332. }
  333. bl_par_chg = 1;
  334. ///
  335. ///
  336. /// Now_date Now_Version这两个参数向BL传递当前的时间和固件版本信息 用于保留备份时的信息
  337. ///
  338. /// upgrade_flag 是app与bl间交互的重要指令
  339. ///
  340. ///
  341. ///
  342. /// 此处校验向BL传递的版本号和日期与当前状态对比是否有更改 有改动则更新flash中的两项
  343. ///
  344. ///
  345. if (bl_par.Now_Version != Now_Version)
  346. {
  347. bl_par_chg = 1;
  348. bl_par.Now_Version = Now_Version;
  349. // LOG_I("update Now_Version %d %d", bl_par.Now_Version, Now_Version);
  350. }
  351. ///
  352. ///
  353. /// 校验 upgrade_flag 若为150说明刚 还原过固件,若是IAP升级 写入版本号信息
  354. /// 150 由BL写入 App 清除 当在BL中读取到150 说明App未能成功启动 会触发还原
  355. ///
  356. ///
  357. if (bl_par.upgrade_flag == 150)
  358. {
  359. bl_par.iap_boot_state &= 0xFF00;//清空低八位
  360. bl_par.iap_boot_state = bl_par.iap_boot_state >> 8;
  361. if (bl_par.iap_boot_state == One)//iap
  362. {
  363. /// 读出bak_info
  364. ef_get_env_blob("bak_info", &bak_info, sizeof(bak_info), NULL);
  365. LOG_I("app upgrade √");
  366. bak_info.Bak_sta[0] = One;//有固件
  367. bak_info.FW_Version[0] = Now_Version;
  368. bak_info.FW_Ver_tim[0] = Now_date;
  369. /// 更新bak_info
  370. ef_set_env_blob("bak_info", &bak_info, sizeof(Bak_info));
  371. IAP_success = One;
  372. ef_set_env_blob("IAP_success", &IAP_success, sizeof(IAP_success));
  373. Recode_e_code(2, ver_d % 200);
  374. /// 立即上报一次数据 同时上报成功信息
  375. if (Valve_Mode == 0 && RTC_Check != One)
  376. {
  377. bl_par.iap_boot_state = 0;
  378. bl_par.upgrade_flag = Zero;
  379. Para_upgrade(3);//保存bl_par
  380. Trigger_report(5);//复位mcu 备份寄存器2写入0x6400
  381. }
  382. }
  383. else//bakx块
  384. {
  385. LOG_I("bak%d->app", bl_par.iap_boot_state);
  386. /// 分情况记录参数
  387. if (bl_par.iap_boot_state == 110)
  388. {
  389. Recode_e_code(3, 1);
  390. }
  391. else if (bl_par.iap_boot_state == 120)
  392. {
  393. Recode_e_code(3, 2);
  394. }
  395. else
  396. {
  397. Recode_e_code(3, 0);
  398. }
  399. }
  400. bl_par.iap_boot_state = 0;
  401. bl_par.upgrade_flag = Zero;
  402. bl_par_chg = 1;
  403. }
  404. /// 限制revise_time 上限
  405. if (abs(rev_par.revise_time) > 100)
  406. {
  407. rev_par.revise_time = rev_par.revise_time / 5;
  408. }
  409. if (abs(rev_par.revise_time) > 30)
  410. {
  411. rev_par.revise_time = rev_par.revise_time / 2;
  412. }
  413. // LOG_I("revise_t %d", rev_par.revise_time);
  414. Read_Para_ok = 1;
  415. LOG_I("BL $");
  416. if (MCU_Temp > 600)
  417. {
  418. Recode_e_code(1, MCU_Temp / 10);
  419. }
  420. }
  421. void Enadble_module(uint8_t en)
  422. {
  423. if (en)
  424. {
  425. // HAL_GPIO_WritePin(CONTROL_12V_GPIO_Port, CONTROL_12V_Pin, 1); //开启12V 这个开启操作挪到ADC里面 了
  426. HAL_GPIO_WritePin(CONTROL_5V_GPIO_Port, CONTROL_5V_Pin, 0); // 开启 5V
  427. HAL_GPIO_WritePin(Flash_CTL_Port, Flash_CTL_Pin, GPIO_PIN_RESET); // 开启Flash供电
  428. HAL_GPIO_WritePin(RUN_STATUS_GPIO_Port, RUN_STATUS_Pin, GPIO_PIN_RESET); // 开启led
  429. // LOG_I("Enable each");
  430. }
  431. else
  432. {
  433. HAL_GPIO_WritePin(CONTROL_12V_GPIO_Port, CONTROL_12V_Pin, GPIO_PIN_RESET); // 关闭12V
  434. HAL_GPIO_WritePin(CONTROL_5V_GPIO_Port, CONTROL_5V_Pin, GPIO_PIN_SET); // 关闭 5V
  435. if (Valve_Mode != 1)
  436. {
  437. HAL_GPIO_WritePin(MODULE_CTL_GPIO_Port, MODULE_CTL_Pin, GPIO_PIN_SET); // 4G去使能 4G断电
  438. HAL_GPIO_DeInit(MODULE_CTL_GPIO_Port, MODULE_CTL_Pin);
  439. }
  440. HAL_GPIO_WritePin(Flash_CTL_Port, Flash_CTL_Pin, GPIO_PIN_SET); // 关闭Flash供电 给不给高电平不要紧 已经是兆欧级别的对地阻值了
  441. HAL_GPIO_WritePin(GPIOA, EXT_KEY_Pin, GPIO_PIN_RESET);
  442. HAL_GPIO_WritePin(RUN_STATUS_GPIO_Port, RUN_STATUS_Pin, GPIO_PIN_RESET); // 关闭led
  443. // LOG_I("Disable each");
  444. }
  445. }
  446. //向备份寄存器2中写入 0x6400
  447. void Trigger_report(uint8_t type)
  448. {
  449. Recode_e_code(11, type);
  450. rt_kprintf("--------- RTC Reset ----------\r\n");
  451. __HAL_RCC_PWR_CLK_ENABLE(); // 使能电源时钟PWR
  452. HAL_PWR_EnableBkUpAccess(); // 取消备份区域写保护
  453. HAL_RTCEx_BKUPWrite(&hrtc, RTC_Alarm_RETRY, 0x6400);
  454. HAL_PWR_DisableBkUpAccess(); // 开启备份区域写保护
  455. RESET_MCU();
  456. }
  457. /***************************
  458. * 初始化PC7
  459. * 此函数硬件复位MCU
  460. * 物理复位 最为致命
  461. *
  462. *************************/
  463. void RESET_MCU(void)
  464. {
  465. rt_kprintf("---------- RESET_MCU ----------\r\n");
  466. GPIO_InitTypeDef GPIO_InitStruct = {0};
  467. /*Configure GPIO pins : Reset_Pin */
  468. GPIO_InitStruct.Pin = MCU_RESET_Pin;
  469. GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
  470. GPIO_InitStruct.Pull = GPIO_PULLDOWN;
  471. HAL_GPIO_Init(MCU_RESET_Port, &GPIO_InitStruct);
  472. }
  473. Boot boot = {0};
  474. static void test_env(void)
  475. {
  476. ef_get_env_blob("boot", &boot, sizeof(boot), NULL);
  477. boot.boot_times += 1;
  478. if (RTC_Check == One)
  479. {
  480. boot.timed_start += 1;
  481. }
  482. rt_kprintf("The system now boot %lu/%lu times\n\n", boot.timed_start, boot.boot_times);
  483. ef_set_env_blob("boot", &boot, sizeof(boot));
  484. }
  485. /**
  486. * @brief 用于运输模式保护
  487. *
  488. * 1. 当所有要素NA10次进入运输保护
  489. * 2. 保护后,两小时开机上报一次数据
  490. * 3. 保护后,开机上报数据或者开机检查传感器的时候,能读到要素>0就退出保护
  491. *
  492. *
  493. */
  494. extern int16_t READ_MODBUS_DATA_1(uint8_t times);
  495. Trans_para Trans_p = {0}; // 存放保护模式相关参数 main 初始化easyflash完成后调用
  496. //确保数据无误
  497. static void Trans_protect(void)
  498. {
  499. if (Node_Type == LTE)
  500. {
  501. ef_get_env_blob("Trans_p", &Trans_p, sizeof(Trans_p), NULL);
  502. ef_get_env_blob("bl_par", &bl_par, sizeof(BL_Para), NULL);
  503. bl_par.iap_boot_state &= 0xFF00;//清空第八位
  504. bl_par.iap_boot_state = bl_par.iap_boot_state >> 8;//读取高八位,实际拿到是那个固件升级
  505. if (RTC_Check != One)//RTC校验失败
  506. {
  507. if (bl_par.upgrade_flag == 150 && bl_par.iap_boot_state == One)//if跟IAP块有关
  508. {
  509. return;
  510. }
  511. //LOG_W("not in RTC_Check");
  512. if(Trans_p.en == One && Tigger_RTC_Check != One)
  513. {
  514. LOG_I("wait 3s 120min");
  515. rt_thread_mdelay(4500);
  516. All_standby(120, 3);//相关
  517. }
  518. return;
  519. }
  520. if (Trans_p.en != One)
  521. {
  522. //LOG_W("not in Trans_p.en");
  523. return;
  524. }
  525. }
  526. }
  527. uint8_t Get_lora_Freq(void)
  528. {
  529. uint8_t Freq = 0;
  530. if (HAL_GPIO_ReadPin(GPIOD, GPIO_PIN_3) == GPIO_PIN_SET)
  531. {
  532. Freq += 1;
  533. }
  534. if (HAL_GPIO_ReadPin(GPIOD, GPIO_PIN_2) == GPIO_PIN_SET)
  535. {
  536. Freq += 2;
  537. }
  538. if (HAL_GPIO_ReadPin(GPIOD, GPIO_PIN_1) == GPIO_PIN_SET)
  539. {
  540. Freq += 3;
  541. }
  542. if (HAL_GPIO_ReadPin(GPIOD, GPIO_PIN_0) == GPIO_PIN_SET)
  543. {
  544. Freq += 4;
  545. }
  546. LOG_I("Freq %d", Freq);
  547. if (Freq > 9)
  548. {
  549. Freq = 9;
  550. }
  551. return Freq;
  552. }
  553. extern uint8_t sys_info_upgrade_flag;
  554. void Para_upgrade(uint8_t type)
  555. {
  556. if (type == 1)
  557. {
  558. LOG_W("loar_par SET %d", ef_set_env_blob("loar_par", &loar_par, sizeof(loar_par)));
  559. }
  560. if (type == 2)
  561. {
  562. sys_info_upgrade_flag = 0;
  563. LOG_W("sys_info SET %d", ef_set_env_blob("sys_info", &sys_info, sizeof(sys_info)));
  564. upgrade_bak_para(1); // 更新备份参数区
  565. }
  566. if (type == 3)
  567. {
  568. bl_par_chg = 0;
  569. LOG_I("bl_par SET %d", ef_set_env_blob("bl_par", &bl_par, sizeof(bl_par)));
  570. }
  571. }
  572. uint8_t Double_INR = 0;
  573. #define Protect_vol 3.5 // 电池欠压保护电压
  574. void Check_VBAT(void)
  575. {
  576. VBAT = VBAT_FORMAT_CONVERT(1);
  577. /// //判断电池电压区间
  578. ///
  579. /// 电压 >= 3.5 正常工作
  580. /// 电压 < 3.5 持续60分钟休眠
  581. ///
  582. ///
  583. LOG_I("VBAT %d.%d%d", VBAT / 100, (VBAT / 10) % 10, VBAT % 10);
  584. if (VBAT >= Protect_vol * 100 && VBAT < 450) //不在 350 - 450 区间 返回
  585. {
  586. return;
  587. }
  588. else // 在 350 - 450 区间
  589. {
  590. // Reflash_BL_Sta_Check(); // 修改bl的状态码,使其不初始化ef
  591. // rt_thread_mdelay(2000);
  592. // RTC_Shotdown = One;
  593. LOG_W("INR=60");
  594. sys_info.run_mode = Zero;
  595. // Recode_e_code(4, VBAT / 10); //此时ef并没有初始化 没法进行记录
  596. if (Valve_Mode == 1)
  597. {
  598. inter_standby(60);
  599. }
  600. else
  601. {
  602. All_standby(60, 1);
  603. All_standby(60, 3);
  604. }
  605. }
  606. }
  607. extern void Usart4_SendString(char *str);
  608. //打印版本号
  609. void Show_Version(void)
  610. {
  611. sys_info.run_mode = Zero;
  612. Now_Version = ver_d;
  613. rt_sprintf((Version + 8), "%d.%03d %s", ver_d / 1000, ver_d % 1000, task_id);
  614. // rt_kprintf("\nWelcome to use Yunfei low-power acquisition Host/LTE node.%s\n", Version);
  615. rt_kprintf("\n%s\n", Version);
  616. // LOG_W("CRC32 : %08X",CRC_32((uint8_t *)Version , 13));
  617. }
  618. //打印e_code
  619. void Check_Free(void)
  620. {
  621. if (Tigger_RTC_Check == One)
  622. {
  623. RTC_DateTypeDef date = {0};
  624. RTC_TimeTypeDef time = {0};
  625. ef_get_env_blob("e_code", &e_code, sizeof(Record) * (MAX_e_code_NUM), NULL);
  626. if (e_code[0].Time_Stampe > MAX_e_code_NUM)
  627. {
  628. e_code[0].code = MAX_e_code_NUM;
  629. }
  630. else
  631. {
  632. e_code[0].code = e_code[0].Time_Stampe;
  633. }
  634. LOG_I("e_code cnt %d", e_code[0].Time_Stampe);
  635. for (uint8_t a = 1; a <= e_code[0].code; a++)
  636. {
  637. Prase_Time_Stampe(&date, &time, e_code[a].Time_Stampe);
  638. LOG_I("%d c %03d p %03d %02d/%02d/%02d %02d:%02d:%02d",
  639. a,
  640. e_code[a].code, e_code[a].para,
  641. date.Year, date.Month, date.Date,
  642. time.Hours, time.Minutes, time.Seconds);
  643. if (a == MAX_e_code_NUM - 1)
  644. {
  645. a++;
  646. }
  647. }
  648. }
  649. }
  650. // 开启ADC检查
  651. void Excute_ADC(void)
  652. {
  653. uint16_t value = 0;
  654. MX_ADCx_Init(1);// PB0
  655. Check_VBAT();//读取电池电压
  656. MX_ADCx_Init(2);//MCU内部温度初始化
  657. value = VBAT_FORMAT_CONVERT(2);
  658. MCU_Temp = value;
  659. // LOG_I("temp %d.%d\n", value / 10, value % 10);
  660. HAL_GPIO_WritePin(CONTROL_12V_GPIO_Port, CONTROL_12V_Pin, 1); // 开启12V
  661. }
  662. extern uint8_t ReFlash_RTC(void);
  663. extern uint32_t Get_Time_Stampe(void);
  664. ///
  665. ///
  666. /// 记录异常状态码 同时记录时间戳 和一个参数
  667. ///
  668. ///
  669. /// @param code 异常码 para随码参数
  670. void Recode_e_code(uint8_t code, uint8_t para)
  671. {
  672. if (easyflash_configured == 1)
  673. {
  674. ef_get_env_blob("e_code", &e_code, sizeof(Record) * (MAX_e_code_NUM), NULL); // 读出flash中的错误码列表
  675. e_code[0].Time_Stampe++; // 累计码位置指向偏移
  676. if (e_code[0].Time_Stampe % MAX_e_code_NUM == 0) // 避过0位置
  677. {
  678. e_code[0].Time_Stampe++;// 60循环 从1开始
  679. }
  680. e_code[e_code[0].Time_Stampe % MAX_e_code_NUM].code = code; // 放入错误码
  681. e_code[e_code[0].Time_Stampe % MAX_e_code_NUM].para = para; // 放入附带参数
  682. ReFlash_RTC(); // 刷新时间
  683. e_code[e_code[0].Time_Stampe % MAX_e_code_NUM].Time_Stampe = Get_Time_Stampe(); // 放入时间戳
  684. LOG_W("e_code SET %d c %d p %d", ef_set_env_blob("e_code", &e_code, sizeof(Record) * (MAX_e_code_NUM)), code, para);
  685. }
  686. }
  687. void Reflash_BL_Sta_Check(void)
  688. {
  689. __HAL_RCC_PWR_CLK_ENABLE(); // 使能电源时钟PWR
  690. HAL_PWR_EnableBkUpAccess(); // 取消备份区域写保护
  691. HAL_RTCEx_BKUPWrite(&hrtc, RTC_BKP_DR3, 0x699D);
  692. HAL_PWR_DisableBkUpAccess(); // 开启备份区域写保护
  693. // rt_kprintf("B %04X \r\n", HAL_RTCEx_BKUPRead(&hrtc, RTC_BKP_DR3));
  694. }
  695. /**
  696. * @brief 更新写在flash固定位置中得重要参数备份
  697. *
  698. * @param type 1-3 对应参数号 直接进行更新
  699. *
  700. * type 101-103 对应参数号 检查是否已经存在进行按需备份
  701. *
  702. */
  703. void upgrade_bak_para(uint8_t type)
  704. {
  705. uint8_t flag = One;
  706. uint8_t bak_sta = 0;
  707. if ((type >= 1 && type <= 3) || (type >= 101 && type <= 103))
  708. {
  709. switch (type)
  710. {
  711. case 1:
  712. SPI_FLASH_SectorErase(bak_flg_SYS_INFO);
  713. SPI_FLASH_BufferWrite((uint8_t *)&flag, bak_flg_SYS_INFO, sizeof(flag));
  714. SPI_FLASH_SectorErase(bak_addr_SYS_INFO);
  715. SPI_FLASH_BufferWrite((uint8_t *)&sys_info, bak_addr_SYS_INFO, sizeof(sys_info));
  716. // rt_kprintf("UP A");
  717. break;
  718. case 2:
  719. SPI_FLASH_SectorErase(bak_flg_Sensor);
  720. SPI_FLASH_BufferWrite((uint8_t *)&flag, bak_flg_Sensor, sizeof(flag));
  721. SPI_FLASH_SectorErase(bak_addr_Sensor);
  722. SPI_FLASH_BufferWrite((uint8_t *)&sensor, bak_addr_Sensor, sizeof(Sensor) * MAX_SENSOR_NUM);
  723. // rt_kprintf("UP B");
  724. break;
  725. case 3:
  726. SPI_FLASH_SectorErase(bak_flg_Loar_Device);
  727. SPI_FLASH_BufferWrite((uint8_t *)&flag, bak_flg_Loar_Device, sizeof(flag));
  728. SPI_FLASH_SectorErase(bak_addr_Loar_Device);
  729. SPI_FLASH_BufferWrite((uint8_t *)&Slave_list, bak_addr_Loar_Device, sizeof(Loar_Device) * (MAX_Slave_NUM + 1));
  730. // rt_kprintf("UP C");
  731. break;
  732. case 101:
  733. SPI_FLASH_BufferRead(&bak_sta, bak_flg_Sensor, 1);
  734. if (bak_sta != One)
  735. {
  736. SPI_FLASH_SectorErase(bak_flg_SYS_INFO);
  737. SPI_FLASH_BufferWrite((uint8_t *)&flag, bak_flg_SYS_INFO, sizeof(flag));
  738. SPI_FLASH_SectorErase(bak_addr_SYS_INFO);
  739. SPI_FLASH_BufferWrite((uint8_t *)&sys_info, bak_addr_SYS_INFO, sizeof(sys_info));
  740. }
  741. break;
  742. case 102:
  743. SPI_FLASH_BufferRead(&bak_sta, bak_flg_Sensor, 1);
  744. if (bak_sta != One)
  745. {
  746. SPI_FLASH_SectorErase(bak_flg_Sensor);
  747. SPI_FLASH_BufferWrite((uint8_t *)&flag, bak_flg_Sensor, sizeof(flag));
  748. SPI_FLASH_SectorErase(bak_addr_Sensor);
  749. SPI_FLASH_BufferWrite((uint8_t *)&sensor, bak_addr_Sensor, sizeof(Sensor) * MAX_SENSOR_NUM);
  750. }
  751. break;
  752. case 103:
  753. SPI_FLASH_BufferRead(&bak_sta, bak_flg_Loar_Device, 1);
  754. if (bak_sta != One)
  755. {
  756. SPI_FLASH_SectorErase(bak_flg_Loar_Device);
  757. SPI_FLASH_BufferWrite((uint8_t *)&flag, bak_flg_Loar_Device, sizeof(flag));
  758. SPI_FLASH_SectorErase(bak_addr_Loar_Device);
  759. SPI_FLASH_BufferWrite((uint8_t *)&Slave_list, bak_addr_Loar_Device, sizeof(Loar_Device) * (MAX_Slave_NUM + 1));
  760. }
  761. break;
  762. default:
  763. break;
  764. }
  765. }
  766. }
  767. /**
  768. * @brief 将flash中固定地址区的参数还原出来
  769. *
  770. * 调用可以一键还原所有备份参数 美滋滋
  771. *
  772. * @param type 1-3 对应参数号 0x9D对应全体
  773. */
  774. uint8_t restore_bak_para(uint8_t type)
  775. {
  776. uint8_t bak_flg = 0;
  777. uint8_t result = 0;
  778. if (type < 1 || (type > 3 && type != 0x9D))
  779. {
  780. return result;
  781. }
  782. // SYS_INFO
  783. if (type == 1 || type == 0x9D)
  784. {
  785. SPI_FLASH_BufferRead(&bak_flg, bak_flg_SYS_INFO, 1);
  786. if (bak_flg == One)
  787. {
  788. SPI_FLASH_BufferRead((uint8_t *)&sys_info, bak_addr_SYS_INFO, sizeof(SYS_INFO));
  789. result = One;
  790. // rt_kprintf("RES A");
  791. }
  792. bak_flg = 0;
  793. }
  794. // Sensor
  795. if (type == 2 || type == 0x9D)
  796. {
  797. SPI_FLASH_BufferRead(&bak_flg, bak_flg_Sensor, 1);
  798. if (bak_flg == One)
  799. {
  800. SPI_FLASH_BufferRead((uint8_t *)&sensor, bak_addr_Sensor, sizeof(Sensor) * MAX_SENSOR_NUM);
  801. result = One;
  802. // rt_kprintf("RES B");
  803. }
  804. bak_flg = 0;
  805. }
  806. // Loar_Device
  807. if (type == 3 || type == 0x9D)
  808. {
  809. SPI_FLASH_BufferRead(&bak_flg, bak_flg_Loar_Device, 1);
  810. if (bak_flg == One)
  811. {
  812. SPI_FLASH_BufferRead((uint8_t *)&Slave_list, bak_addr_Loar_Device, sizeof(Loar_Device) * (MAX_Slave_NUM + 1));
  813. result = One;
  814. // rt_kprintf("RES C");
  815. }
  816. bak_flg = 0;
  817. }
  818. return result;
  819. }