ec800.c 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429
  1. #include "ec800.h"
  2. #include "delay.h"
  3. #include "string.h"
  4. #include <stdlib.h>
  5. #include "fmc.h"
  6. #include "main.h"
  7. /*!
  8. \brief configure EC800M pin
  9. \param[out] none
  10. \retval none
  11. */
  12. #define RSP_READY "RDY"
  13. #define CMD_SET_PDP "AT+QICSGP=1,1,\"CTNET\",\"\",\"\",1\r\n"
  14. #define RSP_OK "OK"
  15. #define CMD_SET_ACTIVE "AT+QIACT=1\r\n"
  16. #define cmdOpenFile(cmd,filename) sprintf(cmd,"AT+QFOPEN=\"%s\",2\r\n",filename)
  17. #define cmdSetSeek(cmd,handle,offset) sprintf(cmd,"AT+QFSEEK=%d,%d,0\r\n",handle,offset)
  18. #define cmdReadFileData(cmd,handle) sprintf(cmd,"AT+QFREAD=%d,1024\r\n",handle)
  19. #define cmdLoadFile(cmd,filename) sprintf(cmd,"AT+QFDWL=%s\r\n",filename)
  20. uint8_t UART0_RX_BUF[UART0_RX_LEN];
  21. uint8_t UART0_RX_STAT;
  22. bool WaitResponse(char *expectStr, int timeout);
  23. void EC800MSendCmd(char *buf, uint16_t len);
  24. int get_file_handle(char *filename);
  25. static const char* my_memmem(const uint8_t* haystack, size_t hlen, const char* needle, size_t nlen);
  26. static void extract_data_from_buffer(const char *buffer, uint32_t *len_ptr, uint16_t *checkCode_ptr);
  27. static uint16_t checksum(const uint8_t *str, uint16_t len);
  28. void gd_EC800M_pin_init(void)
  29. {
  30. /* enable the EC800M power pin clock */
  31. rcu_periph_clock_enable(EC800M_PER_GPIO_CLK);
  32. /* configure EC800M GPIO port */
  33. gpio_init(EC800M_PER_GPIO_PORT, GPIO_MODE_OUT_PP, GPIO_OSPEED_50MHZ, EC800M_PER_PIN);
  34. GPIO_BC(EC800M_PER_GPIO_PORT) = EC800M_PER_PIN;
  35. /* enable the EC800M reset pin clock */
  36. rcu_periph_clock_enable(EC800M_RST_GPIO_CLK);
  37. /* configure EC800M GPIO port */
  38. gpio_init(EC800M_RST_GPIO_PORT, GPIO_MODE_OUT_PP, GPIO_OSPEED_50MHZ, EC800M_RST_PIN);
  39. GPIO_BC(EC800M_RST_GPIO_PORT) = EC800M_RST_PIN;
  40. }
  41. void gd_pull_EC800M_pwr_up(void)
  42. {
  43. GPIO_BOP(EC800M_PER_GPIO_PORT) = EC800M_PER_PIN;
  44. }
  45. void gd_pull_EC800M_pwr_down(void)
  46. {
  47. GPIO_BC(EC800M_PER_GPIO_PORT) = EC800M_PER_PIN;
  48. }
  49. void gd_pull_EC800M_rst_up(void)
  50. {
  51. GPIO_BOP(EC800M_RST_GPIO_PORT) = EC800M_RST_PIN;
  52. }
  53. void gd_pull_EC800M_rst_down(void)
  54. {
  55. GPIO_BC(EC800M_RST_GPIO_PORT) = EC800M_RST_PIN;
  56. }
  57. /*!
  58. \brief configure COM port
  59. \param[in] com: COM on the board
  60. \arg COM_EC800: EC800
  61. \arg COM_485: 485
  62. \arg COM_232: 232
  63. \param[out] none
  64. \retval none
  65. */
  66. void gd_com_init()
  67. {
  68. nvic_priority_group_set(NVIC_PRIGROUP_PRE2_SUB2); // 设置抢占优先级和子优先级的位数为 2
  69. nvic_irq_enable(USART0_IRQn, 0, 0);
  70. /* enable GPIO clock */
  71. rcu_periph_clock_enable(COM_EC800_GPIO_CLK);
  72. /* enable USART clock */
  73. rcu_periph_clock_enable(COM_EC800_CLK);
  74. /* connect port to USARTx_Tx */
  75. gpio_init(COM_EC800_GPIO_PORT, GPIO_MODE_AF_PP, GPIO_OSPEED_50MHZ, COM_EC800_TX_PIN);
  76. /* connect port to USARTx_Rx */
  77. gpio_init(COM_EC800_GPIO_PORT, GPIO_MODE_IN_FLOATING, GPIO_OSPEED_50MHZ, COM_EC800_RX_PIN);
  78. /* USART configure */
  79. usart_deinit(COM_EC800);
  80. usart_baudrate_set(COM_EC800, COM_EC800_BAUDRATE);
  81. usart_word_length_set(COM_EC800, USART_WL_8BIT);
  82. usart_stop_bit_set(COM_EC800, USART_STB_1BIT);
  83. usart_parity_config(COM_EC800, USART_PM_NONE);
  84. usart_hardware_flow_rts_config(COM_EC800, USART_RTS_DISABLE);
  85. usart_hardware_flow_cts_config(COM_EC800, USART_CTS_DISABLE);
  86. usart_receive_config(COM_EC800, USART_RECEIVE_ENABLE);
  87. usart_transmit_config(COM_EC800, USART_TRANSMIT_ENABLE);
  88. usart_enable(COM_EC800);
  89. usart_interrupt_enable(COM_EC800, USART_INT_IDLE);
  90. }
  91. void dma_config(void)
  92. {
  93. dma_parameter_struct dma_init_struct;
  94. rcu_periph_clock_enable(RCU_DMA0);
  95. dma_deinit(DMA0, DMA_CH4);
  96. dma_init_struct.direction = DMA_PERIPHERAL_TO_MEMORY;
  97. dma_init_struct.memory_addr = (uint32_t)UART0_RX_BUF;
  98. dma_init_struct.memory_inc = DMA_MEMORY_INCREASE_ENABLE;
  99. dma_init_struct.memory_width = DMA_MEMORY_WIDTH_8BIT;
  100. dma_init_struct.number = UART0_RX_LEN;
  101. dma_init_struct.periph_addr = (uint32_t)(&USART_DATA(USART0));// ((uint32_t)0x40013804);
  102. dma_init_struct.periph_inc = DMA_PERIPH_INCREASE_DISABLE;
  103. dma_init_struct.periph_width = DMA_PERIPHERAL_WIDTH_8BIT;
  104. dma_init_struct.priority = DMA_PRIORITY_ULTRA_HIGH;
  105. dma_init(DMA0, DMA_CH4, &dma_init_struct);
  106. dma_circulation_disable(DMA0, DMA_CH4);
  107. dma_memory_to_memory_disable(DMA0, DMA_CH4);
  108. usart_dma_transmit_config(USART0, USART_DENT_ENABLE|USART_DENR_ENABLE);
  109. nvic_irq_enable(DMA0_Channel4_IRQn, 2, 1);
  110. dma_interrupt_enable(DMA0, DMA_CH4, DMA_INT_FTF|DMA_INT_HTF|DMA_INT_ERR);
  111. dma_channel_enable(DMA0, DMA_CH4);
  112. }
  113. // 4G模块
  114. void USART0_IRQHandler(void)
  115. {
  116. if (RESET != usart_interrupt_flag_get(USART0, USART_INT_FLAG_IDLE)) // 空闲中断
  117. {
  118. usart_interrupt_flag_clear(USART0, USART_INT_FLAG_IDLE); /* 清除空闲中断标志位 */
  119. usart_data_receive(USART0); /* 清除接收完成标志位 */
  120. dma_channel_disable(DMA0, DMA_CH4); /* 关闭DMA传输 */
  121. UART0_RX_STAT = 0x01; /* 接受状态 0x01:已接收到数据 */
  122. dma_channel_enable(DMA0, DMA_CH4);
  123. }
  124. }
  125. void DMA0_Channel4_IRQHandler(void)
  126. {
  127. dma_interrupt_flag_clear(DMA0, DMA_CH4, DMA_INT_FLAG_G);
  128. }
  129. //清除dma buffer内数据
  130. void Clear_DMA_Buffer(void)
  131. {
  132. memset(UART0_RX_BUF,0,UART0_RX_LEN);
  133. }
  134. void EC800MPwoerOn(void)
  135. {
  136. rcu_periph_clock_enable(RCU_GPIOD);
  137. gpio_init(GPIOD, GPIO_MODE_OUT_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_2);
  138. gpio_bit_set(GPIOD,GPIO_PIN_2);
  139. Delay_Ms(5000);
  140. gd_pull_EC800M_pwr_up();
  141. gd_pull_EC800M_rst_down();
  142. Delay_Ms(50);
  143. gd_pull_EC800M_pwr_down();
  144. Delay_Ms(320);
  145. gd_pull_EC800M_rst_up();
  146. Delay_Ms(800);
  147. gd_pull_EC800M_pwr_up();
  148. }
  149. void EC800MWaitReady()
  150. {
  151. if(WaitResponse(RSP_READY, 5000)==FALSE) NVIC_SystemReset();
  152. }
  153. /*
  154. * 函数名:bool WaitResponse(char *expectStr, int timeout)
  155. * 输入参数:expectStr 需要匹配的关键字 timeout超时时间
  156. * 输出参数:true flase
  157. * 返回值:无
  158. * 函数作用:从UART0_RX_BUF缓冲区中匹配有无对应关键字有关键字则返回true无返回false
  159. */
  160. bool WaitResponse(char *expectStr, int timeout)
  161. {
  162. bool timeoutFlag = FALSE;
  163. if (timeout >= 0)
  164. {
  165. timeoutFlag = TRUE;
  166. }
  167. // gd_485_send((char *)&UART0_RX_BUF, strlen(UART0_RX_BUF)); 不清楚此处调用485意义
  168. while (1)
  169. {
  170. Delay_Ms(50);
  171. if (UART0_RX_STAT > 0)
  172. {
  173. UART0_RX_STAT = 0;
  174. char *p = strstr((char *)&UART0_RX_BUF, expectStr);
  175. if (p)
  176. {
  177. Clear_DMA_Buffer();
  178. return TRUE;
  179. }
  180. }
  181. timeout -= 50;
  182. if (timeoutFlag == TRUE && timeout <= 0)
  183. {
  184. Clear_DMA_Buffer();
  185. return FALSE;
  186. }
  187. };
  188. }
  189. /*
  190. * 函数名:bool WaitResponse(char *expectStr, int timeout)
  191. * 输入参数:expectStr 需要匹配的关键字 timeout超时时间
  192. * 输出参数:true flase
  193. * 返回值:无
  194. * 函数作用:从UART0_RX_BUF缓冲区中匹配有无对应关键字有关键字则返回true无返回false
  195. */
  196. bool WaitResponseNotclear(char *expectStr, int timeout)
  197. {
  198. bool timeoutFlag = FALSE;
  199. if (timeout >= 0)
  200. {
  201. timeoutFlag = TRUE;
  202. }
  203. // gd_485_send((char *)&UART0_RX_BUF, strlen(UART0_RX_BUF)); 不清楚此处调用485意义
  204. while (1)
  205. {
  206. Delay_Ms(50);
  207. if (UART0_RX_STAT > 0)
  208. {
  209. UART0_RX_STAT = 0;
  210. char *p = strstr((char *)&UART0_RX_BUF, expectStr);
  211. if (p)
  212. {
  213. return TRUE;
  214. }
  215. }
  216. timeout -= 50;
  217. if (timeoutFlag == TRUE && timeout <= 0)
  218. {
  219. return FALSE;
  220. }
  221. };
  222. }
  223. /*
  224. * 函数名:void EC800MSetPDP()
  225. * 输入参数:无
  226. * 输出参数:无
  227. * 返回值:无
  228. * 函数作用:设置对应运营商和激活ip
  229. */
  230. void EC800MSetPDP()
  231. {
  232. Delay_Ms(200);
  233. EC800MSendCmd(CMD_SET_PDP, strlen(CMD_SET_PDP));
  234. WaitResponse(RSP_OK, 1000);
  235. Delay_Ms(200);
  236. EC800MSendCmd(CMD_SET_ACTIVE, strlen(CMD_SET_ACTIVE));
  237. WaitResponse(RSP_OK, 1000);
  238. Delay_Ms(2000);
  239. }
  240. void EC800MSendCmd(char *buf, uint16_t len)
  241. {
  242. uint16_t i;
  243. uint16_t data;
  244. for (i = 0; i < len; i++)
  245. {
  246. data = buf[i];
  247. usart_data_transmit(COM_EC800, data);
  248. while (RESET == usart_flag_get(COM_EC800, USART_FLAG_TBE))
  249. ;
  250. }
  251. }
  252. //读取bin文件内容
  253. int read_bin_txt()
  254. {
  255. char *ptr;
  256. uint32_t len;
  257. uint16_t checkCode;
  258. char sub_str[] = "\r\n+QFDWL:";
  259. char cmd[50];
  260. uint32_t BufferSize=40*1024;//最大获取的数据空间
  261. uint8_t *dmabuffer=malloc(BufferSize);
  262. dma_config_change(dmabuffer,BufferSize);
  263. cmdLoadFile(cmd,"bin.txt");
  264. // Delay_Ms(1000);
  265. // EC800MSendCmd("AT+QFLST=\"*\"\r\n", strlen("AT+QFLST=\"*\"\r\n"));
  266. Delay_Ms(1000);
  267. EC800MSendCmd(cmd, strlen(cmd));
  268. Delay_Ms(5000);
  269. ptr = (char *)my_memmem(dmabuffer, BufferSize, sub_str, strlen(sub_str));
  270. if(ptr==NULL){ free(dmabuffer);return 2;}
  271. if(strstr(ptr,"ERROR"))
  272. {
  273. return 2;
  274. }
  275. extract_data_from_buffer(ptr,&len, &checkCode);
  276. uint16_t code=checksum(dmabuffer,len);
  277. if(checkCode==checksum(dmabuffer,len))
  278. {
  279. //校验成功数据正常,写入数据
  280. GD32_EraseFlash(GD32_A_START_PAGE,GD32_A_PAGE_NUM);//擦除A区原有程序
  281. GD32_WriteFlash(GD32_A_SADDR,(uint32_t *)dmabuffer,len);
  282. free(dmabuffer);
  283. return 1;
  284. }
  285. dma_config();
  286. free(dmabuffer);
  287. return 0;
  288. }
  289. ////获取文件句柄
  290. //int get_file_handle(char *filename)
  291. //{
  292. // int num;
  293. // char *ptr_start;
  294. // ptr_start=strstr((char *)&UART0_RX_BUF, filename);
  295. // if (ptr_start == NULL) {}
  296. // ptr_start = strchr(ptr_start, ':');
  297. // ptr_start++; // 跳过逗号
  298. // sscanf(ptr_start, "%d", &num);
  299. // return num;
  300. //}
  301. //手动控制dma搬运的数据地址和大小,在使用完成后需要恢复到默认的dma配置
  302. void dma_config_change(char *dmaBuffer,uint32_t bufferSize)
  303. {
  304. dma_parameter_struct dma_init_struct;
  305. rcu_periph_clock_enable(RCU_DMA0);
  306. dma_deinit(DMA0, DMA_CH4);
  307. dma_init_struct.direction = DMA_PERIPHERAL_TO_MEMORY;
  308. dma_init_struct.memory_addr = (uint32_t)dmaBuffer;
  309. dma_init_struct.memory_inc = DMA_MEMORY_INCREASE_ENABLE;
  310. dma_init_struct.memory_width = DMA_MEMORY_WIDTH_8BIT;
  311. dma_init_struct.number = bufferSize;
  312. dma_init_struct.periph_addr = (uint32_t)(&USART_DATA(USART0));// ((uint32_t)0x40013804);
  313. dma_init_struct.periph_inc = DMA_PERIPH_INCREASE_DISABLE;
  314. dma_init_struct.periph_width = DMA_PERIPHERAL_WIDTH_8BIT;
  315. dma_init_struct.priority = DMA_PRIORITY_ULTRA_HIGH;
  316. dma_init(DMA0, DMA_CH4, &dma_init_struct);
  317. dma_circulation_disable(DMA0, DMA_CH4);
  318. dma_memory_to_memory_disable(DMA0, DMA_CH4);
  319. usart_dma_transmit_config(USART0, USART_DENT_ENABLE|USART_DENR_ENABLE);
  320. //nvic_irq_enable(DMA0_Channel4_IRQn, 2, 2);
  321. dma_interrupt_enable(DMA0, DMA_CH4, DMA_INT_FTF|DMA_INT_ERR);
  322. dma_channel_enable(DMA0, DMA_CH4);
  323. }
  324. static const char* my_memmem(const uint8_t* haystack, size_t hlen, const char* needle, size_t nlen)
  325. {
  326. const char* cur;
  327. const char* last;
  328. last = haystack + hlen - nlen;
  329. for (cur = haystack; cur <= last; ++cur) {
  330. if (cur[0] == needle[0] && memcmp(cur, needle, nlen) == 0) {
  331. return cur;
  332. }
  333. }
  334. return NULL;
  335. }
  336. /*
  337. * 函数名:static void extract_data_from_buffer(const char* buffer, uint32_t *len_ptr, uint16_t *checkCode_ptr)
  338. * 输入参数:buffer字符串
  339. * 输出参数:json有效字符串长度len_ptr,checkCode_ptr校验码指针
  340. * 返回值:无
  341. * 函数作用:eg. QFDWL: 621,3e23 从json信息最后端取出这段json的有效长度和校验码
  342. */
  343. static void extract_data_from_buffer(const char *buffer, uint32_t *len_ptr, uint16_t *checkCode_ptr)
  344. {
  345. char *start = strstr(buffer, "+QFDWL:");
  346. if (start != NULL)
  347. {
  348. start += 8; // 跳过"+QFDWL:"
  349. uint32_t len = 0;
  350. sscanf(start, "%u,", &len); // 读取长度
  351. start = strchr(start, ',') + 1; // 跳过逗号
  352. uint16_t checkCode = 0;
  353. sscanf(start, "%hx", &checkCode); // 读取16进制数据
  354. // 将提取的数据存入形参
  355. *len_ptr = len;
  356. *checkCode_ptr = checkCode;
  357. }
  358. }
  359. // 模块下载download校验值
  360. static uint16_t checksum(const uint8_t *str, uint16_t len)
  361. {
  362. uint16_t sum = 0;
  363. uint8_t odd = 0;
  364. // 如果字符串长度为奇数,则将最后一个字符设置为高8位,低8位设置为0
  365. if (len % 2 == 1)
  366. {
  367. odd = 1;
  368. len--;
  369. }
  370. // 将每两个字符作为一个16位的数值进行异或操作
  371. for (uint16_t i = 0; i < len; i += 2)
  372. {
  373. sum ^= ((uint16_t)str[i] << 8) | (uint16_t)str[i + 1];
  374. }
  375. // 如果字符串长度为奇数,则还需要将最后一个字符与0xFF00异或
  376. if (odd)
  377. {
  378. sum ^= (uint16_t)str[len] << 8;
  379. }
  380. // 返回校验和
  381. return sum;
  382. }