ec800m.c 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413
  1. #include "ec800m.h"
  2. #include "usart.h"
  3. #include "systick.h"
  4. #include "cJson.h"
  5. #include "string.h"
  6. #include "log.h"
  7. #include "systick.h"
  8. #include "main.h"
  9. void EC800MPwoerOn(void)
  10. {
  11. rcu_periph_clock_enable(RCU_GPIOD);
  12. gpio_init(GPIOD, GPIO_MODE_OUT_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_2);
  13. gpio_bit_set(GPIOD,GPIO_PIN_2);
  14. delay_1ms(5000);
  15. gd_pull_EC800M_pwr_up();
  16. gd_pull_EC800M_rst_down();
  17. delay_1ms(50);
  18. gd_pull_EC800M_pwr_down();
  19. delay_1ms(320);
  20. gd_pull_EC800M_rst_up();
  21. delay_1ms(800);
  22. gd_pull_EC800M_pwr_up();
  23. }
  24. void EC800MSendCmd(char *buf, uint16_t len)
  25. {
  26. uint16_t i;
  27. uint16_t data;
  28. for (i = 0; i < len; i++)
  29. {
  30. data = buf[i];
  31. usart_data_transmit(COM_EC800, data);
  32. while (RESET == usart_flag_get(COM_EC800, USART_FLAG_TBE))
  33. ;
  34. }
  35. }
  36. void EC800MWaitReady()
  37. {
  38. if(WaitResponse(RSP_READY, 5000)==false) NVIC_SystemReset();
  39. }
  40. /*
  41. * 函数名:bool WaitResponse(char *expectStr, int timeout)
  42. * 输入参数:expectStr 需要匹配的关键字 timeout超时时间
  43. * 输出参数:true flase
  44. * 返回值:无
  45. * 函数作用:从UART0_RX_BUF缓冲区中匹配有无对应关键字有关键字则返回true无返回false
  46. */
  47. bool WaitResponse(char *expectStr, int timeout)
  48. {
  49. bool timeoutFlag = false;
  50. if (timeout >= 0)
  51. {
  52. timeoutFlag = true;
  53. }
  54. // gd_485_send((char *)&UART0_RX_BUF, strlen(UART0_RX_BUF)); 不清楚此处调用485意义
  55. while (1)
  56. {
  57. delay_1ms(50);
  58. if (UART0_RX_STAT > 0)
  59. {
  60. UART0_RX_STAT = 0;
  61. char *p = strstr((char *)&UART0_RX_BUF, expectStr);
  62. if (p)
  63. {
  64. Clear_DMA_Buffer();
  65. return true;
  66. }
  67. }
  68. timeout -= 50;
  69. if (timeoutFlag == true && timeout <= 0)
  70. {
  71. Clear_DMA_Buffer();
  72. return false;
  73. }
  74. };
  75. }
  76. /*
  77. * 函数名:void EC800MSetPDP()
  78. * 输入参数:无
  79. * 输出参数:无
  80. * 返回值:无
  81. * 函数作用:设置对应运营商和激活ip
  82. */
  83. void EC800MSetPDP()
  84. {
  85. delay_1ms(200);
  86. EC800MSendCmd(CMD_SET_PDP, strlen(CMD_SET_PDP));
  87. WaitResponse(RSP_OK, 1000);
  88. delay_1ms(200);
  89. EC800MSendCmd(CMD_SET_ACTIVE, strlen(CMD_SET_ACTIVE));
  90. WaitResponse(RSP_OK, 1000);
  91. delay_1ms(2000);
  92. }
  93. #define AT_Open "AT+QFOPEN=\"http.txt\",2 \r\n"
  94. #define AT_SEEK "AT+QFSEEK=1,0,0\r\n"
  95. #define AT_128SEEK "AT+QFSEEK=1,128,0\r\n"
  96. #define AT_128Read "AT+QFREAD=1,128\r\n"
  97. #define AT_LIST "AT+QFLST=\"*\"\r\n"
  98. #define AT_QFLDS "AT+QFLDS=\"UFS\"\r\n"
  99. //分包宏
  100. /*
  101. * 函数名:bool EC800MGetUrl(char *url)
  102. * 输入参数:url 网址信息
  103. * 输出参数:无
  104. * 返回值:无
  105. * 函数作用:从对应的http获取信息
  106. */
  107. bool EC800MGetUrl(char *url,char *dmaBuffer,uint32_t bufferSize)
  108. {
  109. // Set url
  110. EC800MSendCmd(AT_LIST, strlen(AT_LIST));
  111. if(WaitResponse("http.txt", 100)==true)
  112. return false;
  113. char command[100];
  114. sprintf(command, CMD_SET_URL, strlen(url)); // CMD_SET_URL "%d\r\n"
  115. EC800MSendCmd(command, strlen(command)); // 设置服务器URL 响应若参数格式正确,且不发送 HTTP(S) GET/POST 请求:CONNECT
  116. WaitResponse(RSP_CONNECT, 100);
  117. delay_1ms(200);
  118. EC800MSendCmd(url, strlen(url)); // 输入URL
  119. if (WaitResponse(RSP_OK, 5000) == false)
  120. return false;
  121. task_fwdgt_reload();
  122. // Send get request
  123. delay_1ms(200);
  124. EC800MSendCmd(CMD_GET, strlen(CMD_GET)); // 向服务器发送get请求
  125. if (WaitResponse("QHTTPGET:", 5000) == false)
  126. return false;
  127. task_fwdgt_reload();
  128. // read to UFS
  129. delay_1ms(200);
  130. EC800MSendCmd(CMD_GET_TO_FILE, strlen(CMD_GET_TO_FILE)); //"AT+QHTTPREADFILE=\"UFS:http.txt\",80\r\n"
  131. if (WaitResponse("QHTTPREADFILE:", 5000) == false)
  132. return false;
  133. task_fwdgt_reload();
  134. EC800MSendCmd("AT+QFLST=\"*\"\r\n", strlen("AT+QFLST=\"*\"\r\n"));
  135. if(WaitResponse("http.txt", 100)==true)
  136. return false;
  137. // get data from UFS
  138. delay_1ms(1000);
  139. task_fwdgt_reload(); dma_config_change(dmaBuffer,bufferSize);
  140. delay_1ms(1000);
  141. task_fwdgt_reload();
  142. EC800MSendCmd(CMD_READ_FILE, strlen(CMD_READ_FILE)); //"AT+QFDWL=http.txt\r\n"
  143. delay_1ms(1000);
  144. task_fwdgt_reload();
  145. return true;
  146. }
  147. /*
  148. * 函数名:void ConnectMQTTSever(uint8_t *host, uint16_t port, uint8_t keepalive, uint8_t *clientid)
  149. * 输入参数:host:mqtt服务器IP port:mqtt端口,keepalive mqtt心跳时间,clientid设备id
  150. * 输出参数:无
  151. * 返回值:无
  152. * 函数作用:与服务器建立连接
  153. */
  154. uint32_t try_connect; //记录尝试与平台建立连接的次数,每次1s当计数到1小时后重启设备
  155. void ConnectMQTTSever(uint8_t *host, uint16_t port, uint8_t keepalive, uint8_t *clientid,uint8_t *mqttUserName,uint8_t *mqttPassword)
  156. {
  157. char cmd[150];
  158. bool success = false;
  159. try_connect=0;
  160. // 主动断开连接
  161. EC800MSendCmd(CMD_MQTT_DISCONNECT, 0);
  162. // 设置mqtt版本
  163. EC800MSendCmd(CMD_MQTT_VERSION, strlen(CMD_MQTT_VERSION));
  164. WaitResponse(RSP_OK, 100);
  165. sprintf(cmd, "AT+QMTCFG=\"qmtping\",0,%d\r\n", keepalive);
  166. EC800MSendCmd(cmd, strlen(cmd));
  167. WaitResponse(RSP_OK, 0);
  168. // EC800MSendCmd(CMD_MQTT_DISCONNECT, 0);
  169. sprintf(cmd, "AT+QMTOPEN=0,\"%s\",%d\r\n", host, port);
  170. do
  171. {
  172. EC800MSendCmd(cmd, strlen(cmd));
  173. success = WaitResponse("QMTOPEN: 0,0", 1000);
  174. delay_1ms(1000);
  175. task_fwdgt_reload();
  176. try_connect++;
  177. if(try_connect==60*60){NVIC_SystemReset();}
  178. } while (!success);
  179. if (success)
  180. {
  181. if(mqttUserName==NULL)
  182. {
  183. sprintf(cmd, "AT+QMTCONN=0,\"%s\",\"%s\",\"%s\"\r\n", clientid, "", ""); // 后两个为username password
  184. }
  185. else
  186. {
  187. sprintf(cmd, "AT+QMTCONN=0,\"%s\",\"%s\",\"%s\"\r\n", clientid, mqttUserName, mqttPassword); // 后两个为username password
  188. }
  189. do
  190. {
  191. EC800MSendCmd(cmd, strlen(cmd));
  192. success = WaitResponse("QMTCONN: 0,0,0", 1000);
  193. delay_1ms(1000);
  194. task_fwdgt_reload();
  195. try_connect++;
  196. if(try_connect==60*60){NVIC_SystemReset();}
  197. } while (!success);
  198. }
  199. }
  200. /*
  201. * 函数名:void MQTTPublish(CONFIG_PARAMS *gateway)
  202. * 输入参数:CONFIG_PARAMS *gateway 网关内存储信息
  203. * 输出参数:无
  204. * 返回值:无
  205. * 函数作用:读出采集到的数据进行上报,若未采集到数据则不进行任何处理 23/4/4添加testId测试丢包情况7/18日重写此方法
  206. */
  207. void MQTTPublish(void)
  208. {
  209. GATEWAY_PARAMS *gateway;
  210. gateway=get_gateway_config_params();
  211. char *payload_out=malloc(30*1024); //要发送的字符串
  212. char mqtt_publish[200]; //发送字符串的指令
  213. sprintf((char *)payload_out,"{\"deviceId\":\"%s\",\"data\":[",gateway->deviceId);//组成json头部
  214. DEVICE_PARAMS *currentDevice=gateway->device_params;
  215. READ_MODBUS_COMMAND *read_modbus_command=NULL;
  216. READ_DLT645_COMMAND *read_dlt645_command=NULL;
  217. switch(currentDevice->protocol)
  218. {
  219. case DLT645_07:
  220. case DLT645_97:
  221. read_dlt645_command=currentDevice->params->node_read_dlt645_command;
  222. break;
  223. case MODBUS:
  224. read_modbus_command=currentDevice->params->node_read_modbus_command;
  225. break;
  226. }
  227. while(1)
  228. {
  229. __START__WHILE:
  230. switch(currentDevice->protocol)
  231. {
  232. case DLT645_07:
  233. case DLT645_97:
  234. if(read_dlt645_command->rxLen!=0)
  235. {
  236. float value;
  237. switch(read_dlt645_command->rxLen)
  238. {
  239. case 4:
  240. memcpy(&value, read_dlt645_command->data, 4);
  241. sprintf(payload_out+strlen(payload_out),"{\"deviceId\":\"%s\",\"%s\": %.2f},",currentDevice->deviceID,read_dlt645_command->keyword,value);
  242. break;
  243. case 5:
  244. sprintf(payload_out+strlen(payload_out),"{\"deviceId\":\"%s\",\"%s\": \"%02X%02X%02X%02X%02X\"},",currentDevice->deviceID,read_dlt645_command->keyword,read_dlt645_command->data[4],
  245. read_dlt645_command->data[3],read_dlt645_command->data[2],read_dlt645_command->data[1],read_dlt645_command->data[0]);
  246. break;
  247. break;
  248. case 9:
  249. memcpy(&value, read_dlt645_command->data, 4);
  250. sprintf(payload_out+strlen(payload_out),"{\"deviceId\":\"%s\",\"%s\":\"%02X%02X%02X%02X%02X%.2f\"},",currentDevice->deviceID,read_dlt645_command->keyword,read_dlt645_command->data[8],
  251. read_dlt645_command->data[7],read_dlt645_command->data[6],read_dlt645_command->data[5],read_dlt645_command->data[4],value);
  252. break;
  253. }
  254. }
  255. break;
  256. case MODBUS:
  257. {
  258. if(read_modbus_command->rxLen!=0)
  259. {
  260. if(read_modbus_command->functionCode==0x03)
  261. {
  262. if(read_modbus_command->decimalPoint!=0)
  263. {
  264. float value;
  265. memcpy(&value, read_modbus_command->value, 4); // 取出相应的值给value
  266. sprintf(payload_out+strlen(payload_out),"{\"deviceId\":\"%s\",\"%s\": %.2f},",currentDevice->deviceID,read_modbus_command->keyword,value);
  267. }
  268. else
  269. {
  270. uint32_t value;
  271. memcpy(&value, read_modbus_command->value, 4);
  272. sprintf(payload_out+strlen(payload_out),"{\"deviceId\":\"%s\",\"%s\": %d},",currentDevice->deviceID,read_modbus_command->keyword,value);
  273. }
  274. }
  275. else if(read_modbus_command->functionCode==0x01)
  276. {
  277. uint8_t value[4];
  278. uint8_t state;
  279. memcpy(&value, read_modbus_command->value, 4);
  280. if (value[2] == 0xFF)
  281. {
  282. state = 1;
  283. }
  284. else
  285. {
  286. state = 0;
  287. }
  288. sprintf(payload_out+strlen(payload_out),"{\"deviceId\":\"%s\",\"%s\": %d},",currentDevice->deviceID,read_modbus_command->keyword,state);
  289. }
  290. }
  291. }
  292. break;
  293. }
  294. switch(currentDevice->protocol)
  295. {
  296. case DLT645_07:
  297. case DLT645_97:
  298. read_dlt645_command=read_dlt645_command->nextParams;
  299. break;
  300. case MODBUS:
  301. read_modbus_command=read_modbus_command->nextParams;
  302. break;
  303. }
  304. if(read_dlt645_command==NULL&&read_modbus_command==NULL)
  305. {
  306. currentDevice=currentDevice->nextDevice;
  307. if(currentDevice==NULL)
  308. {
  309. goto __END__WHILE;
  310. }
  311. else
  312. {
  313. read_dlt645_command=currentDevice->params->node_read_dlt645_command;
  314. read_modbus_command=currentDevice->params->node_read_modbus_command;
  315. }
  316. }
  317. goto __START__WHILE;
  318. }
  319. __END__WHILE:
  320. if(strlen(payload_out)>40)//小于这个值组成的字符串证明没有数据采集到、就不进行发布
  321. {
  322. sprintf(payload_out+strlen(payload_out)-1,"]}");
  323. sprintf((char *)mqtt_publish, "AT+QMTPUBEX=0,0,0,0,\"%s\",%d\r\n", gateway->messageTopic, strlen(payload_out));
  324. EC800MSendCmd(mqtt_publish, strlen(mqtt_publish));
  325. bool success=WaitResponse(">", 1000);
  326. if(success)
  327. {
  328. delay_1ms(50);
  329. EC800MSendCmd(payload_out, strlen(payload_out));
  330. }
  331. else
  332. {
  333. NVIC_SystemReset();
  334. }
  335. }
  336. free(payload_out);
  337. payload_out=NULL;
  338. }
  339. /*
  340. * 函数名:void MQTTSubTopic(uint8_t *commandTopic)
  341. * 输入参数:uint8_t *commandTopic 订阅的主题
  342. * 输出参数:无
  343. * 返回值:无
  344. * 函数作用:读出采集到的数据进行上报,若未采集到数据则不进行任何处理
  345. */
  346. void MQTTSubTopic(uint8_t *commandTopic)
  347. {
  348. char AT_SUB[100];
  349. sprintf(AT_SUB, "AT+QMTSUB=0,1,\"%s\",0\r\n", commandTopic);
  350. bool success = false;
  351. uint8_t retry_count = 0;
  352. do
  353. {
  354. EC800MSendCmd(AT_SUB, strlen(AT_SUB));
  355. success = WaitResponse(RSP_OK, 1000);
  356. retry_count++;
  357. } while (!success && retry_count < 3);
  358. }
  359. #define AT_DELETE_FILE "AT+QFDEL=\"UFS:http.txt\"\r\n"
  360. void delete_config_file()
  361. {
  362. dma_config();
  363. EC800MSendCmd(AT_DELETE_FILE, strlen(AT_DELETE_FILE));
  364. WaitResponse("OK", 1000);
  365. }