You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

255 lines
7.6 KiB

2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
  1. #include "atcmd.h"
  2. #include "zport.h"
  3. #include <lwip/sockets.h>
  4. #include "config.h"
  5. extern ETH_HandleTypeDef heth;
  6. #define at_address_cmd_template(_config_get) \
  7. { \
  8. ip4_addr_t int_addr; \
  9. char ip_address[16]; \
  10. if (*p == '?') \
  11. { \
  12. printf("config ip address:%s\r\n", inet_ntoa(_config_get)); \
  13. } \
  14. else \
  15. { \
  16. if (len >= sizeof(ip_address)) \
  17. { /* 长度判断 */ \
  18. printf("AT+ERR\r\n"); \
  19. return AT_ERR; \
  20. } /* 拷贝len有效字符长度的字符串到ip_address中 */ \
  21. strncpy(ip_address, (const char *)p, len); \
  22. ip_address[len] = 0; /* 这个必须要加,否则转换会出错 */ \
  23. inet_aton(ip_address, &int_addr); \
  24. _config_get = int_addr.addr; \
  25. config_flash_write(); \
  26. printf("AT+OK\r\n"); \
  27. } \
  28. return AT_SUCCESS; \
  29. }
  30. #define at_processer_rx_buf_size 128
  31. #define at_processer_tx_buf_size 128
  32. // 接收到了多少数据
  33. volatile uint16_t s_at_cmd_uart_rx_off = 0;
  34. // 当前是否正在处理接收到的数据
  35. volatile bool s_at_cmd_uart_rx_buf_is_processing = false;
  36. static uint8_t at_rx_buf[at_processer_rx_buf_size];
  37. // static uint8_t at_tx_buf[at_processer_tx_buf_size];
  38. /* AT指令表 */
  39. const AT_cmd_func at_cmd_func[] = {
  40. {AT_CMD_TEST, "AT", at_cmd_test},
  41. {AT_CMD_IP, "AT+IP=", at_cmd_ip},
  42. {AT_CMD_GW, "AT+GW=", at_cmd_gw},
  43. {AT_CMD_NETMASK, "AT+NETMASK=", at_cmd_netmask},
  44. {AT_CMD_OBTAINING_IP_MODE, "AT+OBTAINING_IP_MODE=", at_cmd_obtaining_ip_mode},
  45. {AT_CMD_MAC, "AT+MAC=", at_cmd_mac},
  46. {AT_END, NULL, NULL}};
  47. unsigned int mstrlen(const char *s)
  48. {
  49. const char *ss = s;
  50. while (*ss)
  51. ss++;
  52. return ss - s;
  53. }
  54. int mstrncmp(const char *s1, const char *s2, int n)
  55. {
  56. const unsigned char *c1 = (const unsigned char *)s1;
  57. const unsigned char *c2 = (const unsigned char *)s2;
  58. unsigned char ch;
  59. int d = 0;
  60. while (n--)
  61. {
  62. d = (int)(ch = *c1++) - (int)*c2++;
  63. if (d || !ch)
  64. break;
  65. }
  66. return d;
  67. }
  68. /* 指令执行函数 */
  69. AT_STATUS at_cmd_test(unsigned char *p, unsigned char len)
  70. {
  71. printf("AT+OK\r\n");
  72. return AT_SUCCESS;
  73. }
  74. AT_STATUS at_cmd_ip(unsigned char *p, unsigned char len)
  75. {
  76. at_address_cmd_template(config_get()->ip);
  77. }
  78. AT_STATUS at_cmd_gw(unsigned char *p, unsigned char len)
  79. {
  80. at_address_cmd_template(config_get()->gw);
  81. }
  82. AT_STATUS at_cmd_netmask(unsigned char *p, unsigned char len)
  83. {
  84. at_address_cmd_template(config_get()->netmask);
  85. }
  86. AT_STATUS at_cmd_obtaining_ip_mode(unsigned char *p, unsigned char len)
  87. {
  88. if (*p == '?')
  89. {
  90. printf("config obtaining_ip_mode:%d\r\n", config_get()->obtaining_ip_mode);
  91. }
  92. else
  93. {
  94. if (((*p != '0') && (*p != '1')) || (len > 1))
  95. {
  96. printf("AT+ERR\r\n");
  97. return AT_ERR;
  98. }
  99. config_get()->obtaining_ip_mode = *p - 48; /* ascii码字符0十进制为48 */
  100. config_flash_write();
  101. printf("AT+OK\r\n");
  102. }
  103. return AT_SUCCESS;
  104. }
  105. AT_STATUS at_cmd_mac(unsigned char *p, unsigned char len)
  106. {
  107. if (*p == '?')
  108. {
  109. printf("mac:%.2x:%.2x:%.2x:%.2x:%.2x:%.2x\r\n", //
  110. heth.Init.MACAddr[0], heth.Init.MACAddr[1], heth.Init.MACAddr[2], //
  111. heth.Init.MACAddr[3], heth.Init.MACAddr[4], heth.Init.MACAddr[5]); //
  112. }
  113. else
  114. {
  115. printf("AT+OK\r\n");
  116. }
  117. return AT_SUCCESS;
  118. }
  119. /* 查找指令表中对应的指令 */
  120. unsigned char AT_cmd_search(unsigned char *p, unsigned char len)
  121. {
  122. unsigned char ret = 0;
  123. // unsigned char *pstr;
  124. unsigned char i, n;
  125. for (i = 1; at_cmd_func[i].cmd != AT_END; i++)
  126. {
  127. n = mstrlen((const char *)at_cmd_func[i].str);
  128. if (!mstrncmp((const char *)p, (const char *)at_cmd_func[i].str, n))
  129. {
  130. ret = i;
  131. break;
  132. }
  133. }
  134. return ret;
  135. }
  136. /* AT指令解析 */
  137. AT_STATUS at_cmd_parse(unsigned char *p, unsigned char len)
  138. {
  139. AT_STATUS ret = AT_SUCCESS;
  140. unsigned char index = 0;
  141. if (len < 4)
  142. return AT_ERR; /* 不符合指令最小长度 */
  143. if ((p[0] == 'A') && (p[1] == 'T') && (p[len - 2] == 0x0D) && (p[len - 1] == 0x0A))
  144. {
  145. if (len == 4)
  146. { /* 测试指令 */
  147. if (at_cmd_func[AT_CMD_TEST].cb != NULL)
  148. at_cmd_func[AT_CMD_TEST].cb(NULL, 0); /* 执行测试指令 */
  149. }
  150. else if (p[2] == '+')
  151. { /* 执行指令解析 */
  152. index = AT_cmd_search(p, len); /* 查找匹配的执行指令,0-已匹配,!0-未匹配 */
  153. if (index)
  154. {
  155. if (at_cmd_func[index].cb != NULL)
  156. { /* 判断指令对应执行函数是否存在 */
  157. unsigned char n;
  158. n = mstrlen((const char *)at_cmd_func[index].str);
  159. ret = at_cmd_func[index].cb(p + n, len - n - 2); /* 执行对应的指令函数, p+n:将指令参数传输执行函数,len-n-2:指令参数有效长度 */
  160. }
  161. else
  162. ret = AT_ERR_FUN_UNUSED; /* 没有可执行函数 */
  163. }
  164. else
  165. {
  166. ret = AT_ERR_UNINVAIL; /* 未找到匹配的指令 */
  167. }
  168. }
  169. }
  170. else
  171. { /* 格式不匹配 */
  172. return AT_ERR;
  173. }
  174. return ret;
  175. }
  176. void at_cmd_processer_push_data(uint8_t rxdata)
  177. {
  178. if (!s_at_cmd_uart_rx_buf_is_processing)
  179. {
  180. if (s_at_cmd_uart_rx_off < at_processer_rx_buf_size)
  181. {
  182. at_rx_buf[s_at_cmd_uart_rx_off] = rxdata;
  183. s_at_cmd_uart_rx_off++;
  184. }
  185. }
  186. }
  187. void at_cmd_processer_try_process_data(void)
  188. {
  189. /**
  190. * @brief
  191. * modbus协议3.5
  192. */
  193. if (s_at_cmd_uart_rx_off != 0)
  194. {
  195. uint16_t modbus_uart_rx_off_before = s_at_cmd_uart_rx_off;
  196. HAL_Delay(1);
  197. sys_critical_enter();
  198. if (s_at_cmd_uart_rx_off == modbus_uart_rx_off_before)
  199. {
  200. s_at_cmd_uart_rx_buf_is_processing = true;
  201. }
  202. sys_critical_exit();
  203. if (s_at_cmd_uart_rx_buf_is_processing)
  204. {
  205. if (at_cmd_parse(at_rx_buf, s_at_cmd_uart_rx_off) != AT_SUCCESS)
  206. {
  207. printf("at cmd parse error\r\n");
  208. }
  209. sys_critical_enter();
  210. s_at_cmd_uart_rx_off = 0;
  211. s_at_cmd_uart_rx_buf_is_processing = false;
  212. sys_critical_exit();
  213. }
  214. }
  215. }