Host.c 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755
  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-12-01 19813 the first version
  9. */
  10. #define DBG_TAG "Host"
  11. #define DBG_LVL DBG_LOG
  12. #include <rtdbg.h>
  13. #include "Host.h"
  14. #include <rtthread.h>
  15. #include "modbus_host.h"
  16. #include "main.h"
  17. #include "stdlib.h"
  18. extern void LOAR_SEND_DATA(uint8_t address, uint8_t Inclued_Sensor);
  19. extern uint16_t LTEReadCnt; // 串口4接收到的数据个数
  20. extern uint8_t LTEReadFlag; // 串口4接收数据完成标记位
  21. extern uint8_t LTE_ReadBuff[LTE_CMD_BUFSIZE]; // 串口4接收数据缓存
  22. extern uint16_t GPRSReadCnt; // 串口3接收到的数据个数
  23. extern uint8_t GPRSReadFlag; // 串口3接收数据完成标记位
  24. extern uint8_t GPRS_ReadBuff[]; // 串口3接收数据缓存
  25. extern uint8_t Start_LTE; // 用于通知LTE 可以开始了
  26. extern LOAR_Parameter loar_par; // 这里面存放loar的参数和ID
  27. extern void Loar_Send_CMD(uint8_t Address, uint8_t Cmd); // 用于唤醒从机
  28. extern LOAR_Tx loar_t; // Loar预发送buffer
  29. extern uint8_t RTC_Check; // 记录是否计划时刻唤醒 *** 关键参数 ***
  30. extern uint8_t Valve_Mode; // 阀控使能标记位
  31. extern uint8_t occupy_lora; // 独占Lora标记位
  32. extern uint8_t Freq; // 频段标记位
  33. extern uint8_t Tigger_RTC_Check; // 记录本次是主动触发的上报任务
  34. extern RTC_TimeTypeDef GetTime; // 时间记录结构体
  35. extern RTC_DateTypeDef GetData; // 日期记录结构体
  36. extern BL_Para bl_par; // 闹钟定时的修正参数
  37. extern uint8_t bl_par_chg; // 需要写入bl par的标记位
  38. extern Revise_par rev_par; // 备用时间修正参数
  39. extern uint8_t ReFlash_RTC(void); // 刷新RTC时间
  40. extern uint8_t start_monitor; // 开启监听器
  41. extern void Recode_e_code(uint8_t code, uint8_t para); // 记录异常码
  42. extern uint8_t Lora_Get_CSQ(uint8_t addr); // 获取lora的CSQ
  43. extern uint8_t slave_fw; // 从机固件状态
  44. extern uint8_t Expand_Guard_T; // 扩容警戒线程时间
  45. uint8_t Monitoring_button = One; // 用于开启或关闭监听按键功能
  46. //uint8_t Matching_running = Zero; // 标明配对模式是否运行中
  47. volatile uint8_t Recv_count = 0; // 校验无误的已配对从机上报的数据量 *** 关键参数 ***
  48. uint8_t Recv_cnt = 0; // Recv_count 的复制版 仅用于上报状态
  49. #if (Node_Type == Host)
  50. Loar_Device Slave_list[MAX_Slave_NUM + 1] = {0}; // 用于存放从机信息
  51. Loar_Device_Data Data_list[MAX_Slave_NUM + 1] = {0}; // 存放从机上报的数据
  52. #else
  53. Loar_Device Slave_list[1] = {0}; // 用于存放从机信息
  54. Loar_Device_Data Data_list[1] = {0}; // 存放从机上报的数据
  55. #endif
  56. uint16_t slave_sta = 0; // 本次从机上报的情况
  57. uint8_t up_slave_flg = 0; // 升级从机标记位
  58. uint8_t slave_online = 0; // 从机在线状态的熵增抑制参数
  59. uint8_t Host_Service(void)
  60. {
  61. if (RTC_Check == One)//RCT 准备好了
  62. {
  63. Start_LTE = One;
  64. }
  65. if (RTC_Check == Zero && Valve_Mode == 0 /*&& Node_Type != Monitor*/) // RTC 没准备好
  66. {
  67. LOG_I("wait 3s");
  68. rt_thread_mdelay(6000);
  69. All_standby(sys_info.interval, 3);
  70. }
  71. return 0;
  72. }
  73. extern RTC_TimeTypeDef GetTime;
  74. uint8_t slave_check(uint16_t time_point)
  75. {
  76. uint8_t i = 0;
  77. ReFlash_RTC();
  78. for (i = 0; i <= sys_info.slaves_Number - 1; i++)
  79. {
  80. if ((GPRS_ReadBuff[2] == Slave_list[i].Address) &&
  81. (GPRS_ReadBuff[3] == Slave_list[i].ID[0]) &&
  82. (GPRS_ReadBuff[4] == Slave_list[i].ID[1]) &&
  83. (GPRS_ReadBuff[5] == Slave_list[i].ID[2]) &&
  84. (GPRS_ReadBuff[6] == Slave_list[i].ID[3]))
  85. {
  86. // LOG_I("\nSaved device found .address:%d ID : %02X %02X %02X %02X\n", Slave_list[i].Address,
  87. // Slave_list[i].ID[0], Slave_list[i].ID[1], Slave_list[i].ID[2], Slave_list[i].ID[3]);
  88. if (GPRS_ReadBuff[9] != sys_info.interval) // 对数据进行处理 同时校准时间间隔
  89. {
  90. LOG_W("INR ×");
  91. LOAR_SEND_DATA(Slave_list[i].Address, Zero);
  92. return 1;
  93. format_uartbuf(3);
  94. }
  95. else // 对数据进行处理
  96. {
  97. if (Data_list[Slave_list[i].Address].saved == 1) // 已处理过 不再进行对时操作
  98. {
  99. LOG_I("time √");
  100. Time_fine_tuning(Zero, 0, Slave_list[i].Address);
  101. return 1;
  102. }
  103. ///
  104. /// 校验时间点
  105. /// 从机上报的时间点
  106. /// 在(address * 10 -1) - (address * 10 + 2 )之间
  107. /// 超出则进行微调
  108. ///
  109. if (((GetTime.Hours == 15) && (GetTime.Minutes <= 30)) || (GPRS_ReadBuff[0] == 0x5B))
  110. {
  111. RTC_time_synchronization(Slave_list[i].Address);
  112. return 1;
  113. }
  114. else if (time_point < ((sys_info.slaves_Number * 10 + 10) - (Slave_list[i].Address * 10) - 1)) // 时间提前
  115. {
  116. // if (((sys_info.slaves_Number * 10 + 10) - (Slave_list[i].Address * 10) - time_point) <= 15)
  117. // {
  118. // Time_fine_tuning(One, ((sys_info.slaves_Number * 10 + 10) - (Slave_list[i].Address * 10)) - time_point, Slave_list[i].Address);
  119. // }
  120. // else
  121. // {
  122. // Time_fine_tuning(One, 15, Slave_list[i].Address);
  123. // }
  124. Time_fine_tuning(Zero, ((sys_info.slaves_Number * 10 + 10) - (Slave_list[i].Address * 10)) - time_point, Slave_list[i].Address);
  125. LOG_I("time ->");
  126. return 1;
  127. }
  128. else if (time_point > ((sys_info.slaves_Number * 10 + 10) - (Slave_list[i].Address * 10) + 2)) // 时间延后
  129. {
  130. // if ((time_point - (sys_info.slaves_Number * 10 + 10) - (Slave_list[i].Address * 10)) <= 3)
  131. // {
  132. // Time_fine_tuning(Zero, time_point - ((sys_info.slaves_Number * 10 + 10) - (Slave_list[i].Address * 10)), Slave_list[i].Address);
  133. // }
  134. // else
  135. // {
  136. // Time_fine_tuning(Zero, 2, Slave_list[i].Address);
  137. // }
  138. Time_fine_tuning(One, time_point - ((sys_info.slaves_Number * 10 + 10) - (Slave_list[i].Address * 10)), Slave_list[i].Address);
  139. LOG_I("time <-");
  140. return 1;
  141. }
  142. else
  143. {
  144. LOG_I("time √");
  145. Time_fine_tuning(Zero, 0, Slave_list[i].Address);
  146. return 1;
  147. }
  148. ///
  149. /// 校验时间点
  150. /// 从机上报的时间点
  151. /// 在(address * 10 -1) - (address * 10 + 2 )之间
  152. /// 超出则进行微调
  153. ///
  154. }
  155. }
  156. }
  157. format_uartbuf(3);
  158. return 0;
  159. }
  160. extern uint8_t Freq;
  161. extern uint8_t loar_data_process(uint8_t cfg_address, uint8_t type);
  162. extern uint8_t Read_Para_ok;
  163. extern uint8_t Set_lora_SF(uint8_t SF);
  164. uint8_t Matching_service(void)
  165. {
  166. return 1;
  167. }
  168. uint8_t Pairing_response(void)
  169. {
  170. // LOG_I("Pairing_response");
  171. uint8_t i = 0;
  172. char strbuf[30];
  173. rt_memset(strbuf, 0, 30);
  174. rt_kprintf("%d ", GPRSReadCnt);
  175. for (uint8_t j = 0; j < GPRSReadCnt; j++)
  176. {
  177. rt_kprintf("%02X ", GPRS_ReadBuff[j]);
  178. }
  179. if (GPRS_ReadBuff[0] == 0x5A && GPRS_ReadBuff[1] == 0x05 && GPRS_ReadBuff[2] < 20 && GPRSReadCnt == 9) // 校验是否为配对的广播包
  180. {
  181. if (sys_info.slaves_Number == 0) // 当从机数量为0时 直接分配地址 1
  182. {
  183. LOG_I("First device");
  184. Slave_list[0].Address = 1;
  185. Slave_list[0].ID[0] = GPRS_ReadBuff[3];
  186. Slave_list[0].ID[1] = GPRS_ReadBuff[4];
  187. Slave_list[0].ID[2] = GPRS_ReadBuff[5];
  188. Slave_list[0].ID[3] = GPRS_ReadBuff[6];
  189. sys_info.slaves_Number++;
  190. ef_set_env_blob("Slave_list", &Slave_list, sizeof(Loar_Device) * sys_info.slaves_Number);
  191. ef_set_env_blob("sys_info", &sys_info, sizeof(sys_info));
  192. upgrade_bak_para(3); // 更新备份参数区
  193. upgrade_bak_para(1); // 更新备份参数区
  194. // LOG_W("\nFirst device added. address:%d ID : %02X %02X %02X %02X\n", Slave_list[0].Address,
  195. // Slave_list[0].ID[0], Slave_list[0].ID[1], Slave_list[0].ID[2], Slave_list[0].ID[3]);
  196. log_w_slave(0);
  197. LOAR_SEND_DATA(1, One);
  198. Recode_e_code(8, Slave_list[0].Address);
  199. return 1;
  200. }
  201. else
  202. {
  203. for (i = 0; i <= sys_info.slaves_Number - 1; i++)
  204. {
  205. if ((GPRS_ReadBuff[3] == Slave_list[i].ID[0]) &&
  206. (GPRS_ReadBuff[4] == Slave_list[i].ID[1]) &&
  207. (GPRS_ReadBuff[5] == Slave_list[i].ID[2]) &&
  208. (GPRS_ReadBuff[6] == Slave_list[i].ID[3]))
  209. {
  210. if (Slave_list[i].Address != 0)
  211. {
  212. LOAR_SEND_DATA(Slave_list[i].Address, One);
  213. LOG_W("Saved found");
  214. log_w_slave(i);
  215. // LOG_W("\nSaved device found .address:%d ID : %02X %02X %02X %02X\n", Slave_list[i].Address,
  216. // Slave_list[i].ID[0], Slave_list[i].ID[1], Slave_list[i].ID[2], Slave_list[i].ID[3]);
  217. Recode_e_code(8, Slave_list[i].Address);
  218. return 1;
  219. }
  220. }
  221. }
  222. }
  223. if (GPRS_ReadBuff[2] >= 0 && GPRS_ReadBuff[2] <= MAX_Slave_NUM && sys_info.slaves_Number <= MAX_Slave_NUM) // 当新设备加入时
  224. {
  225. LOG_W("New device");
  226. Slave_list[sys_info.slaves_Number].Address = sys_info.slaves_Number + 1;
  227. Slave_list[sys_info.slaves_Number].ID[0] = GPRS_ReadBuff[3];
  228. Slave_list[sys_info.slaves_Number].ID[1] = GPRS_ReadBuff[4];
  229. Slave_list[sys_info.slaves_Number].ID[2] = GPRS_ReadBuff[5];
  230. Slave_list[sys_info.slaves_Number].ID[3] = GPRS_ReadBuff[6];
  231. rt_sprintf(strbuf, "Slave_list[%d]", sys_info.slaves_Number);
  232. rt_memset(strbuf, 0, 30);
  233. sys_info.slaves_Number++;
  234. ef_set_env_blob("Slave_list", &Slave_list, sizeof(Loar_Device) * sys_info.slaves_Number);
  235. ef_set_env_blob("sys_info", &sys_info, sizeof(sys_info));
  236. upgrade_bak_para(3); // 更新备份参数区
  237. upgrade_bak_para(1); // 更新备份参数区
  238. LOAR_SEND_DATA(sys_info.slaves_Number, One);
  239. log_w_slave(sys_info.slaves_Number - 1);
  240. // LOG_W("\nNew device addr %d ID %02X %02X %02X %02X\n", Slave_list[sys_info.slaves_Number - 1].Address,
  241. // Slave_list[sys_info.slaves_Number - 1].ID[0], Slave_list[sys_info.slaves_Number - 1].ID[1],
  242. // Slave_list[sys_info.slaves_Number - 1].ID[2], Slave_list[sys_info.slaves_Number - 1].ID[3]);
  243. Recode_e_code(8, Slave_list[sys_info.slaves_Number - 1].Address);
  244. return 1;
  245. }
  246. }
  247. else
  248. {
  249. LOG_W("Invalid data");
  250. }
  251. return 0;
  252. }
  253. //LED闪烁(PB7)
  254. void LED_buling(uint16_t speed, uint8_t excute_time)
  255. {
  256. /************* 给led闪烁 ***************/
  257. for (uint8_t a = 0; a < 6 * excute_time; a++)
  258. {
  259. HAL_GPIO_TogglePin(RUN_STATUS_GPIO_Port, RUN_STATUS_Pin);
  260. rt_thread_mdelay(speed);
  261. }
  262. /************* 给led闪烁 ***************/
  263. }
  264. /** 微调时间 */
  265. extern void LOAR_SendAckWithCRC(void);
  266. void Time_fine_tuning(uint8_t type, uint8_t value, uint8_t address)
  267. {
  268. // if (value >= 3) 有在线维护机制兜底 不必限制修正参数
  269. // value = 2;
  270. if (value > 5)
  271. value = 5;
  272. memset(loar_t.TxBuf, 0, 8);
  273. loar_t.TxCount = 0; // 给txcount清零
  274. loar_t.TxBuf[loar_t.TxCount++] = 0x5A; // 放入帧头
  275. loar_t.TxBuf[loar_t.TxCount++] = 0x04; // 放入数据长度
  276. loar_t.TxBuf[loar_t.TxCount++] = 0xFE; // 放入指令码
  277. loar_t.TxBuf[loar_t.TxCount++] = address; // 放入从机地址
  278. loar_t.TxBuf[loar_t.TxCount++] = type; // 放入修正类型
  279. loar_t.TxBuf[loar_t.TxCount++] = value; // 放入修正值
  280. if (address == up_slave_flg)
  281. {
  282. loar_t.TxBuf[loar_t.TxCount++] = One;
  283. }
  284. else
  285. {
  286. loar_t.TxBuf[loar_t.TxCount++] = Zero;
  287. }
  288. LOAR_SendAckWithCRC(); // 添加CRC并发送
  289. }
  290. /** RTC对时 */
  291. /**
  292. * @brief 为从机进行对时
  293. *
  294. * @param address 从机addr
  295. */
  296. void RTC_time_synchronization(uint8_t address)
  297. {
  298. ReFlash_RTC();
  299. memset(loar_t.TxBuf, 0, 9);
  300. loar_t.TxCount = 0; // 给txcount赋值
  301. loar_t.TxBuf[loar_t.TxCount++] = 0x5A; // 放入帧头
  302. loar_t.TxBuf[loar_t.TxCount++] = 0x05; // 放入数据长度
  303. loar_t.TxBuf[loar_t.TxCount++] = 0xFF; // 放入指令码
  304. loar_t.TxBuf[loar_t.TxCount++] = address; // 放入从机地址
  305. loar_t.TxBuf[loar_t.TxCount++] = GetTime.Hours; // 放入时间
  306. loar_t.TxBuf[loar_t.TxCount++] = GetTime.Minutes;
  307. loar_t.TxBuf[loar_t.TxCount++] = GetTime.Seconds;
  308. if (address == up_slave_flg)
  309. {
  310. loar_t.TxBuf[loar_t.TxCount++] = One;
  311. }
  312. else
  313. {
  314. loar_t.TxBuf[loar_t.TxCount++] = Zero;
  315. }
  316. // LOG_I("Send RTC_time packet");
  317. LOAR_SendAckWithCRC(); // 添加CRC并发送
  318. }
  319. extern Sensor sensor[MAX_SENSOR_NUM];
  320. extern void GenerateValue(int val, int factor, char *eval);
  321. uint8_t Data_fill(void)
  322. {
  323. uint8_t address = GPRS_ReadBuff[2], i = 0;
  324. int16_t vbat, value = 0;
  325. if (Data_list[address].saved == 1)
  326. {
  327. // LOG_W("Filter duplicate data");
  328. return 0;
  329. }
  330. if (address > MAX_Slave_NUM)
  331. {
  332. return 0;
  333. }
  334. char imei8[8];
  335. memset(imei8, 0, 8);
  336. Data_list[address].Address = address; // 首先塞入从机地址 同时在数组中索引角标也是从机地址
  337. // LOG_I("Data_fill addr:%d", GPRS_ReadBuff[2]);
  338. /// 塞入从机IMEI
  339. /// 从机IMEI由主机IMEI后六位+从机ID拼接出来
  340. ///
  341. rt_sprintf(imei8, "%02X%02X%02X%02X",
  342. Slave_list[address - 1].ID[0],
  343. Slave_list[address - 1].ID[1],
  344. Slave_list[address - 1].ID[2],
  345. Slave_list[address - 1].ID[3]);
  346. rt_sprintf(Data_list[address].imei, "%06s%08s", (char *)(sys_info.imei + 9), imei8);
  347. // LOG_I("S%d.imei %s ", address, Data_list[address].imei);
  348. /// 塞入本次上报中的电池电压
  349. vbat = GPRS_ReadBuff[7] * 256 + GPRS_ReadBuff[8];
  350. rt_sprintf(Data_list[address].volt, "%d.%02d", vbat / 100, vbat % 100);
  351. LOG_I("volt :%s", Data_list[address].volt);
  352. rt_sprintf(Data_list[address].Version, "%d", GPRS_ReadBuff[10]);
  353. Data_list[address].ver = GPRS_ReadBuff[10];
  354. LOG_I("v %s", Data_list[address].Version);
  355. /// 塞入本次接收到的数据
  356. for (i = 0; i < GPRSReadCnt - 13; i++)
  357. {
  358. if (i % 2 == 0)
  359. {
  360. value = GPRS_ReadBuff[i + 11] * 256 + GPRS_ReadBuff[i + 1 + 11];
  361. if (value == 32767) // 此处添加数据校验
  362. {
  363. rt_sprintf(Data_list[address].eValue[i / 2], "-99.99");
  364. }
  365. else
  366. {
  367. GenerateValue((int16_t)value, sensor[i / 2].factor, (char *)(&Data_list[address].eValue[i / 2]));
  368. }
  369. LOG_I("S%d v%d :%s ", address, i / 2, Data_list[address].eValue[i / 2]);
  370. value = 0;
  371. }
  372. }
  373. rt_kprintf("\n");
  374. if (Lora_Get_CSQ(address) >= 15 && address == up_slave_flg && slave_fw == One)
  375. {
  376. send_s_fw(address);
  377. }
  378. else if (address == up_slave_flg)
  379. {
  380. up_slave_flg = 200 + up_slave_flg;
  381. ef_set_env_blob("up_slave_flg", &up_slave_flg, sizeof(up_slave_flg));
  382. }
  383. Data_list[address].saved = 1;
  384. return 1;
  385. }
  386. extern uint8_t json_head[]; // 上报数据头
  387. extern char json_fram[]; // 数据格式模板
  388. extern Sensor sensor[]; // 要素模型
  389. extern char sys_info_volt[5];
  390. extern char json_time[20];
  391. uint16_t slave_json_format(char *buff, uint8_t address)
  392. {
  393. uint16_t i = 0;
  394. uint16_t total = 0; /* 记录当前数据长度 */
  395. char ekey[4] = {0};
  396. if (Data_list[address].saved != 1)
  397. {
  398. LOG_W("No Addr %d", address);
  399. return 0;
  400. }
  401. else
  402. {
  403. Recv_count--;
  404. }
  405. fill_json_time(); /* 塞入时间 */
  406. rt_memset(buff, 0, json_buf_len);
  407. total = rt_sprintf((char *)buff, (const char *)json_head, Data_list[address].imei, Data_list[address].SNR, Data_list[address].volt, json_time);
  408. //total = rt_sprintf((char *)buff, (const char *)json_head, Data_list[address].imei, Data_list[address].SNR, Data_list[address].volt, json_time, Data_list[address].Version);
  409. ///
  410. ///
  411. /// 根据传感器数量塞入数据/*传感器eName不能为空*/
  412. ///
  413. ///
  414. for (i = 0; i < MAX_SENSOR_NUM; i++)
  415. {
  416. if (rt_strcmp(sensor[i].eName, "\0") != 0 && sensor[i].cfged == 1)
  417. {
  418. total += rt_sprintf((char *)buff + total, json_fram, Data_list[address].eValue[i], sensor[i].eKey, sensor[i].eName, sensor[i].eNum);
  419. }
  420. }
  421. rt_sprintf(ekey, "e%d", sys_info.Sensor_num + 1);
  422. total += rt_sprintf((char *)buff + total, json_fram, Data_list[address].volt, ekey, "VOLT", "124");
  423. memset(ekey, 0, 4);
  424. rt_sprintf(ekey, "e%d", sys_info.Sensor_num + 2); /* ekey */
  425. total += rt_sprintf((char *)buff + total, json_fram, Data_list[address].CSQ, ekey, "RSSI", "224"); /* 填充电量值 */
  426. memset(ekey, 0, 4);
  427. buff[total - 1] = ']';
  428. buff[total] = '}';
  429. buff[++total] = '}';
  430. buff[++total] = '\0';
  431. return total; /* 返回前数据长度 */
  432. }
  433. ///
  434. ///
  435. /// 是否使用配对模式下的配置呢
  436. ///
  437. /// One 使用
  438. /// Zero 不使用
  439. ///
  440. /// @param Type
  441. void use_match_cfg(uint8_t Type)
  442. {
  443. if (Type == One)
  444. {
  445. if (Set_TXRX_Frequency_Band(10, 10) != 0)
  446. {
  447. LOG_I("Set_Band √");
  448. }
  449. }
  450. if (Type == Zero)
  451. {
  452. if (Set_TXRX_Frequency_Band(Freq, Freq) != 0)
  453. {
  454. LOG_I("Set Freq %d √", Freq);
  455. }
  456. }
  457. }
  458. /// 输入在slave_list中的位置
  459. void log_w_slave(uint8_t addr)
  460. {
  461. LOG_W("addr %d ID %02X %02X %02X %02X\n", Slave_list[addr].Address,
  462. Slave_list[addr].ID[0], Slave_list[addr].ID[1], Slave_list[addr].ID[2], Slave_list[addr].ID[3]);
  463. }
  464. /// 为从机发送固件
  465. extern uint8_t Expand_Guard_T;
  466. extern void SPI_FLASH_BufferRead(uint8_t *pBuffer, uint32_t ReadAddr, uint16_t NumByteToRead);
  467. uint8_t *s_fw_buf;
  468. uint8_t send_s_fw(uint8_t addr)
  469. {
  470. uint8_t result = 0;
  471. uint8_t time_out = 0;
  472. static uint8_t percent = 0;
  473. static uint8_t part = 0;
  474. static uint8_t retry = 3;
  475. const uint16_t buf_size = 1024;
  476. const uint8_t fw_size = 96;
  477. const uint32_t slave_addr = 0x1C0000;
  478. static uint8_t pack_num = 6;
  479. addr--;
  480. if (s_fw_buf == RT_NULL)
  481. {
  482. s_fw_buf = rt_malloc(buf_size); // 申请内存
  483. }
  484. if (s_fw_buf == RT_NULL)
  485. {
  486. return 0;
  487. }
  488. memset(s_fw_buf, 0, buf_size);
  489. Expand_Guard_T = One; // 扩容时间
  490. memset(loar_t.TxBuf, 0, 9);
  491. loar_t.TxCount = 0;
  492. loar_t.TxBuf[loar_t.TxCount++] = 0x6A;
  493. loar_t.TxBuf[loar_t.TxCount++] = Slave_list[addr].Address;
  494. loar_t.TxBuf[loar_t.TxCount++] = Slave_list[addr].ID[0];
  495. loar_t.TxBuf[loar_t.TxCount++] = Slave_list[addr].ID[1];
  496. loar_t.TxBuf[loar_t.TxCount++] = Slave_list[addr].ID[2];
  497. loar_t.TxBuf[loar_t.TxCount++] = Slave_list[addr].ID[3];
  498. loar_t.TxBuf[loar_t.TxCount++] = 0x6A;
  499. LOAR_SendAckWithCRC();
  500. Set_TXRX_Frequency_Band(11, 11); // 设置频段
  501. // Set_lora_SF(7);
  502. while (percent < fw_size && retry > 0) // 主任务
  503. {
  504. rt_thread_mdelay(100);
  505. if (send_s_fw_process() == 1)
  506. {
  507. if (GPRS_ReadBuff[1] <= fw_size && GPRS_ReadBuff[2] <= pack_num && GPRS_ReadBuff[3] == 0x6A)
  508. {
  509. time_out = 0;
  510. percent = GPRS_ReadBuff[1];
  511. part = GPRS_ReadBuff[2];
  512. LOG_W("ask %d->%d", percent, part);
  513. format_uartbuf(3);
  514. if (part == 1)
  515. {
  516. SPI_FLASH_BufferRead(s_fw_buf, ((percent * 1024) + slave_addr), 1024);
  517. retry = 3;
  518. }
  519. reply_fw(percent, part);
  520. }
  521. else
  522. {
  523. format_uartbuf(3);
  524. }
  525. }
  526. time_out++;
  527. if (time_out >= 100)
  528. {
  529. time_out = 0;
  530. retry--;
  531. }
  532. }
  533. if (retry > 0 && percent == fw_size)
  534. {
  535. result = 1;
  536. up_slave_flg = One + up_slave_flg;
  537. }
  538. else
  539. {
  540. up_slave_flg = Zero + up_slave_flg;
  541. }
  542. Recode_e_code(22, up_slave_flg); // 记录操作
  543. ef_set_env_blob("up_slave_flg", &up_slave_flg, sizeof(up_slave_flg));
  544. Set_TXRX_Frequency_Band(Freq, Freq); // 设置频段
  545. return result;
  546. }
  547. /// 用于解析收到的从机数据请求包
  548. uint8_t send_s_fw_process(void)
  549. {
  550. uint8_t result = 0;
  551. if (GPRS_ReadBuff[0] == 0x6A && GPRSReadFlag == 1) /// 若解析到有效数据
  552. {
  553. if (pairing_data_process(0, 1) == 1)
  554. {
  555. result = 1;
  556. }
  557. }
  558. return result;
  559. }
  560. void reply_fw(uint8_t packet, uint8_t part)
  561. {
  562. if (part > 6)
  563. {
  564. return;
  565. }
  566. uint8_t count = 0;
  567. uint8_t fill_num = 0;
  568. memset(loar_t.TxBuf, 0, 205);
  569. loar_t.TxCount = 0;
  570. loar_t.TxBuf[loar_t.TxCount++] = 0x6A;
  571. loar_t.TxBuf[loar_t.TxCount++] = packet;
  572. loar_t.TxBuf[loar_t.TxCount++] = part;
  573. if (part == 6) // 决定填充数量
  574. {
  575. fill_num = 24;
  576. }
  577. else
  578. {
  579. fill_num = 200;
  580. }
  581. // 0xFF 判断
  582. if ((*(s_fw_buf + (part - 1) * 200) == 0xFF) && *(s_fw_buf + (part - 1) * 200 + fill_num - 1) == 0xFF)
  583. {
  584. for (uint8_t a = 0; a < fill_num; a++)
  585. {
  586. if (s_fw_buf[(part - 1) * 200 + a] == 0xFF)
  587. {
  588. count++;
  589. }
  590. }
  591. }
  592. if (count == fill_num) // 填充数据
  593. {
  594. loar_t.TxBuf[loar_t.TxCount++] = 0xFF;
  595. }
  596. else
  597. {
  598. loar_t.TxCount += fill_num;
  599. memcpy((uint8_t *)(loar_t.TxBuf + 3), (uint8_t *)(s_fw_buf + (part - 1) * 200), fill_num);
  600. }
  601. LOAR_SendAckWithCRC();
  602. }
  603. #define THREAD_PRIORITY 12
  604. #define THREAD_STACK_SIZE 2048
  605. #define THREAD_TIMESLICE 5
  606. extern uint8_t EXTI0_1_GPIO_PIN0;
  607. /*
  608. // 这个线程专门用来监听配置按键是否按下 以实现长按进入配置模式
  609. static void Matching_service_task(void *param)
  610. {
  611. uint8_t i, press_time = 2; // presstime 长按响应时间(秒)
  612. // 进入PA0的上升沿中断之后 该标志位被置1
  613. if (Node_Type != Host)
  614. {
  615. LOG_I("jump Match");
  616. return;
  617. }
  618. while (Monitoring_button == One && Node_Type == Host)
  619. {
  620. ///
  621. ///
  622. /// 2022/05/13修改 更换新版硬件之后,不能一按到底进入配置模式,故而放弃中断的方式,尝试直接监听高电平
  623. ///
  624. ///
  625. while (EXTI0_1_GPIO_PIN0 == 1 || HAL_GPIO_ReadPin(EXT_KEY_GPIO_Port, EXT_KEY_Pin) == GPIO_PIN_SET)
  626. {
  627. // 判断检验周期内按键是否都是按下的状态
  628. // 若持续按下不足3s 则本次不响应
  629. for (i = 0; i <= press_time * 10; i++)
  630. {
  631. if (HAL_GPIO_ReadPin(EXT_KEY_GPIO_Port, EXT_KEY_Pin) == GPIO_PIN_SET)
  632. {
  633. rt_thread_mdelay(100); // 100ms检测一次按键状态
  634. }
  635. else
  636. {
  637. // 中途松手 本次按下无效 等待下一次按下进中断
  638. EXTI0_1_GPIO_PIN0 = 0;
  639. break;
  640. }
  641. LOG_I("press_time %d/%d", i, press_time * 10);
  642. if (i == press_time * 10)
  643. {
  644. Matching_service();
  645. }
  646. }
  647. }
  648. rt_thread_mdelay(30); // 加入延时 让出cpu
  649. }
  650. }
  651. // 这个线程时为了监听按键是否按下了 超过1S 是的话 进入配对从机模式
  652. int Matching_service_thread(void)
  653. {
  654. rt_thread_t tid1 = RT_NULL;
  655. tid1 = rt_thread_create("Matching_service_task",
  656. Matching_service_task, RT_NULL,
  657. 2048,
  658. 6, THREAD_TIMESLICE);
  659. // 如果获得线程控制块,启动这个线程
  660. if (tid1 != RT_NULL)
  661. {
  662. rt_thread_startup(tid1);
  663. }
  664. else
  665. LOG_I("Match ×");
  666. return 0;
  667. }
  668. */
  669. //INIT_APP_EXPORT(Matching_service_thread); // 监听配置的按键有没有按下