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.
 
 
 
 

818 lines
20 KiB

#include "AT_H.h"
#include "Stdlib.h"
//函数声明
static int at_query_cver(void);
static int at_exec_ireboot(void);
static int at_exec_crestore(void);
static int at_query_tecfg(void);
static int at_query_ubaud(void);
static int at_exec_ubaud(char* str);
static int at_query_uparity(void);
static int at_exec_uparity(char* str);
static int at_query_htxcfg(void);
static int at_exec_htxcfg(char* str);
static int at_exec_hsendb(char* str);
static int at_exec_hsend(char* str);
static int at_query_hrxcfg(void);
static int at_exec_hrxcfg(char* str);
static int at_exec_hrecb(char* str);
static int at_exec_hrec(char* str);
static atcmd_t g_at_cmd_list[] =
{
/*01 查询at版本*/ { LORA_AT_IVER, " Get the version of the AT_Slave FW", at_query_cver, NULL, NULL },
/*02 重启*/ { LORA_AT_IREBOOT, " Trig a reset of the MCU", NULL, NULL, at_exec_ireboot },
/*03 重置到出厂模式*/ { LORA_AT_IDEFAULT, " Default Set", NULL, NULL, at_exec_crestore },
/*04 查询终端参数*/ { LORA_AT_GETSTATUS, " Get terminal configuration status", at_query_tecfg, NULL, NULL },
/*05 查询、设置串口波特率*/ { LORA_AT_UBAUD, " Set USART Baud Rate", at_query_ubaud, at_exec_ubaud, NULL },
/*06 查询、设置串口校验位*/ { LORA_AT_UPARITY, " Set USART Parity", at_query_uparity, at_exec_uparity, NULL },
//LoRa
/*07 查询、设置LoRa发送参数*/ { LORA_AT_HTXCFG, " Set lora send config", at_query_htxcfg, at_exec_htxcfg, NULL },
/*08 以16进制形式发送*/ { LORA_AT_HSENDB, " Send hexadecimal data", NULL, at_exec_hsendb, NULL },
/*09 以ASCII码形式发送*/ { LORA_AT_HSEND, " Send text data", NULL, at_exec_hsend, NULL },
/*10 查询、设置LoRa接收参数*/ { LORA_AT_HRXCFG, " Set lora receive config", at_query_hrxcfg, at_exec_hrxcfg, NULL },
/*11 设置以16进制接收数据*/ { LORA_AT_HRECB, " receive hexadecimal data", NULL, at_exec_hrecb, NULL},
/*12 设置以ASCII码形式接收*/ { LORA_AT_HREC, " receive text data", NULL, at_exec_hrec, NULL },
};
static char at_query_buf[RETURN_BUFF_SZIE]; //at指令查询输出缓冲
static bool uart_cfg_change = false;
//删除字符串首尾所有空字符
char* string_trim(char *str)
{
char *str_head = str;
char *str_tail = str + strlen(str) - 1;
while(*str_head == ' ')
{
str_head++;
}
while(*str_tail == ' ')
{
str_tail--;
}
*(str_tail + 1) = '\0';
return str_head;
}
//判断字符串里是否有空字符,有:-1,无:0
int8_t just_string_trim(char *str)
{
uint8_t str_length = strlen(str);
for(uint8_t h = 0; h < str_length; h++)
{
if(*(str + h) == ' ')
{
return -1;
}
}
return 0;
}
//判断字符串是否符合格式,符合:0,不符合:非0
int8_t string_islegal(char *str, uint8_t decimal)
{
uint8_t length = strlen(str);
if((decimal != 10) && (decimal != 16)) //目前只支持10进制及16进制
{
return -2;
}
if(length == 0) //空字符,非法
{
return -1;
}
switch(decimal)
{
case 10:
for(uint8_t i = 0; i < length; i++)
{
if((*(str + i) > '9') || (*(str + i) < '0')) //对十进制为非法字符
{
return -1;
}
}
break;
case 16:
for(uint8_t i = 0; i < length; i++)
{
if((*(str + i) <= '9' && *(str + i) >= '0') || (*(str + i) <= 'F' && *(str + i) >= 'A') || (*(str + i) <= 'f' && *(str + i) >= 'a'))
{
continue;
}
else //不在上述范围内为非法字符
{
return -1;
}
}
break;
default:
return -2;
}
return 0;
}
//字符串按分隔符分离
char* string_split(char *str, char split)
{
static char str_temp[256] = {'\0'};
static int split_point = 0;
static int length = 0;
char *ret;
int i = 0;
if(str != NULL) //新的字符串分离
{
split_point = 0; //初始化分离位置
length = strlen(str); //初始化最原始字符串长度
if(length == 0) //空字符直接返回,肯定找不到分隔字符
{
return NULL;
}
for(i = 0; i < length; i++)
{
str_temp[i] = str[i];
}
str_temp[i] = '\0';
ret = &str_temp[0]; //第一次指向头位置
for(i = 0; i < length; i++)
{
if(str_temp[i] == split) //找到字符
{
str_temp[i] = '\0'; //对应位置填空,分离第一个字符串
split_point = i; //记录位置,为查找下一个字符做准备
return ret; //返回第一个字符串
}
}
split_point = length; //从头到尾都没有
return ret; //整体返回
}
else
{
if(split_point == length) //上次寻找已经找寻到尾巴,说明已经全部分割完毕
{
return NULL;
}
else
{
ret = &str_temp[split_point + 1];
for(i = split_point + 1; i < length; i++) //从上回记录的下一个位置开始找起
{
if(str_temp[i] == split) //寻找
{
str_temp[i] = '\0'; //分离
split_point = i; //记录位置
return ret; //返回该字符串
}
}
split_point = length; //剩余部分找不到匹配字符
return ret; //剩余部分整体返回
}
}
}
int8_t hex2bin(const char *hex, uint8_t *bin, uint16_t bin_length)
{
uint16_t hex_length = strlen(hex);
const char *hex_end = hex + hex_length;
uint8_t *cur = bin;
uint8_t num_chars = hex_length & 1;
uint8_t byte = 0;
if(hex_length % 2 != 0)
{
return -1;
}
if(hex_length / 2 > bin_length)
{
return -1;
}
while(hex < hex_end)
{
if('A' <= *hex && *hex <= 'F')
{
byte |= 10 + (*hex - 'A');
}
else if('a' <= *hex && *hex <= 'f')
{
byte |= 10 + (*hex - 'a');
}
else if('0' <= *hex && *hex <= '9')
{
byte |= *hex - '0';
}
else
{
return -1;
}
hex++;
num_chars++;
if(num_chars >= 2)
{
num_chars = 0;
*cur++ = byte;
byte = 0;
}
else
{
byte <<= 4;
}
}
return cur - bin;
}
void lora_at_process(void)
{
if(!is_recive_data)
{
return ;
}
if(at_cipmode_flag)
{
//透传
}
else
{
const char *cmd_name;
int i=0;
int ret=AT_OK;
char at_returnbuf[100]={0};
// printf("RxLen=%d\r\n",RxLen);
// UART1_SendString(RxBuff, RxLen);
// printf("\r\n");
//验证数据
if(RxBuff[0]!='A'||RxBuff[1]!='T'||RxBuff[RxLen-1]!='\n'||RxBuff[RxLen-2]!='\r')
{
ret=AT_FORMAT_ERR;
printf("err code:%d\r\n",ret);
//长度置为0,方便下次接收
memset(RxBuff,0,255);
RxLen=0;
is_recive_data=false;
return;
}
//执行相关设置函数
for (i = 0; i < sizeof(g_at_cmd_list) / sizeof(atcmd_t); i++)
{
cmd_name = g_at_cmd_list[i].cmd_name;
uint8_t cmd_len = strlen(cmd_name);
char cmd_cache[cmd_len+1];//结束符\0的空间
snprintf(cmd_cache, cmd_len+1, "%s", &RxBuff[2]);//要写入的最大字符数(包括结尾的null字符)
if (strncmp(cmd_cache, cmd_name, cmd_len) != 0)
{
continue;
}
/* query cmd */
if(RxBuff[cmd_len+2]=='='&&RxBuff[cmd_len+3]=='?')
{
if (g_at_cmd_list[i].query_cmd != NULL)
{
ret = g_at_cmd_list[i].query_cmd();
if (ret == AT_OK)
{
snprintf(at_returnbuf, RETURN_BUFF_SZIE, "%s\r\n+OK\r\n", at_query_buf);
}
}
else
{
ret = AT_NOTALLOW_ERR;
}
}
/* help cmd */
else if(RxBuff[cmd_len+2]=='?')
{
if (g_at_cmd_list[i].test_cmd_str)
{
snprintf(at_returnbuf, RETURN_BUFF_SZIE, "AT%s:%s\r\n+OK\r\n",cmd_name, g_at_cmd_list[i].test_cmd_str);
}
else
{
ret = AT_HELPNULL_ERR;
}
}
/* exec cmd */
else if(RxBuff[cmd_len+2]=='='&&RxBuff[cmd_len+3]!='?')
{
if (g_at_cmd_list[i].exec_cmd != NULL)
{
//把等号后面,\r前面的内容传到执行函数去
RxBuff[RxLen-1]='\0';
RxBuff[RxLen-2]='\0';
ret = g_at_cmd_list[i].exec_cmd(&RxBuff[cmd_len+3]);
if (ret == AT_OK)
{
snprintf(at_returnbuf, RETURN_BUFF_SZIE, "+OK\r\n");
}
}
else
{
ret = AT_NOTALLOW_ERR;
}
}
/* exec cmd with out parameter */
else if(cmd_len+4==RxLen)
{
if (g_at_cmd_list[i].exec_cmd_no_para != NULL)
{
ret = g_at_cmd_list[i].exec_cmd_no_para();
if (ret == 0)//暂时只有重启和复位指令,执行不到这里来
{
}
}
else
{
ret = AT_NOTALLOW_ERR;
}
}
/* other error cmd */
else
{
ret = AT_FORMAT_ERR;
}
break;
}
//遍历完了都没找到匹配的
if (i == sizeof(g_at_cmd_list) / sizeof(atcmd_t))
{
ret = AT_NOTFOUND_ERR;
}
//打印结果
if(ret==AT_OK)
{
printf("%s",at_returnbuf);
}
else
{
printf("err code:%d\r\n",ret);
}
//长度置为0,方便下次接收
memset(RxBuff,0,255);
RxLen=0;
is_recive_data=false;
//串口这里特殊处理,AT指令修改串口配置,需应答完毕后修改
if(uart_cfg_change)
{
DelayMs(10);
uart1_init();
uart_cfg_change=false;
}
}
}
//查询AT版本
static int at_query_cver(void)
{
char* ver = AT_VER;
memset(at_query_buf,0,RETURN_BUFF_SZIE);
snprintf(at_query_buf, RETURN_BUFF_SZIE, "%s", ver);
return AT_OK;
}
//重启
static int at_exec_ireboot(void)
{
SYS_ResetExecute();
return AT_OK;
}
//恢复出厂
static int at_exec_crestore(void)
{
config_set_def();
SYS_ResetExecute();
return AT_OK;
}
//查询主要配置
static int at_query_tecfg(void)
{
return AT_OK;
}
//查询波特率
static int at_query_ubaud(void)
{
uint32_t baud;
baud=uart1_get_baud();
memset(at_query_buf,0,RETURN_BUFF_SZIE);
snprintf(at_query_buf, RETURN_BUFF_SZIE, "+BAUD:%d", baud);
return AT_OK;
}
//设置波特率
static int at_exec_ubaud(char* str)
{
uint32_t baudrate = 0;
str = string_trim(str);
if(string_islegal(str, 10) != 0)
{
return AT_PARA_ERR;
}
baudrate = strtol(str, NULL, 0);
if((baudrate != 38400) && (baudrate != 57600) && (baudrate != 115200)&& (baudrate != 1200)&& (baudrate != 2400)&& (baudrate != 4800)&& (baudrate != 9600)&& (baudrate != 19200))
{
return AT_PARA_ERR;
}
uart_param.baud=baudrate;
//flash保存
uart_cfg_change=true;
return AT_OK;
}
//查询奇偶校验
static int at_query_uparity(void)
{
memset(at_query_buf,0,RETURN_BUFF_SZIE);
switch (uart_param.parity) {
case NO_PARITY:
snprintf(at_query_buf, RETURN_BUFF_SZIE, "+PARITY:%s", "none");
break;
case ODD_PARITY:
snprintf(at_query_buf, RETURN_BUFF_SZIE, "+PARITY:%s", "Even");
break;
case EVEN_PARITY:
snprintf(at_query_buf, RETURN_BUFF_SZIE, "+PARITY:%s", "Odd");
break;
default:
snprintf(at_query_buf, RETURN_BUFF_SZIE, "+PARITY:%s", "none");
break;
}
return AT_OK;
}
//设置奇偶校验
static int at_exec_uparity(char* str)
{
uint8_t parity = 0;
str = string_trim(str);
if(string_islegal(str, 10) != 0)
{
return AT_PARA_ERR;
}
parity = strtol(str, NULL, 0);
if((parity != 0) && (parity != 1) && (parity != 2))
{
return AT_PARA_ERR;
}
uart_param.parity=(proto_parity_t)parity;
//flash保存
uart_cfg_change=true;
return AT_OK;
}
//查询LoRa配置
static int at_query_htxcfg(void)
{
int8_t sf = lora_param.sf_tx;
int8_t bw = lora_param.bw_tx;
int8_t power = lora_param.power;
uint32_t freq = lora_param.freq_tx;
uint16_t pream_len = lora_param.preamble_len_tx;
uint32_t tx_timeout = lora_param.tx_timeout;
int bwTemp=0;
switch(bw)
{
case 0:bwTemp=125;
break;
case 1:bwTemp=250;
break;
case 2:bwTemp=500;
break;
default:
break;
}
memset(at_query_buf,0,RETURN_BUFF_SZIE);
snprintf(at_query_buf, RETURN_BUFF_SZIE, "+HTXCFG:sf:%d,bw:%d,power:%d,freq:%d,preamble len:%d,tx timeout:%d",sf, bwTemp, power, freq, pream_len, tx_timeout);
return AT_OK;
}
//设置LoRa参数
static int at_exec_htxcfg(char* str)
{
char* param;
int8_t sf = 0;
int32_t bw = 0;
int8_t power = 0;
uint32_t freq = 0;
uint16_t preamble_len = 0;
uint32_t tx_timeout = 0;
/* check sf parameter */
param = string_split(str, ',');
if(param != NULL)
{
param = string_trim(param);
if(string_islegal(param, 10) != 0)
{
return AT_PARA_ERR;
}
sf = strtol(param, NULL, 0);
if((sf < 7) || (sf > 12))
{
return AT_PARA_ERR;
}
}
else
{
return AT_PARA_ERR;
}
/* check bw parameter */
param = string_split(NULL, ',');
if(param != NULL)
{
param = string_trim(param);
if(string_islegal(param, 10) != 0)
{
return AT_PARA_ERR;
}
bw = strtol(param, NULL, 0);
if(bw != 125 && bw != 250 && bw != 500)
{
return AT_PARA_ERR;
}
}
else
{
return AT_PARA_ERR;
}
/* check power parameter */
param = string_split(NULL, ',');
if(param != NULL)
{
param = string_trim(param);
if(string_islegal(param, 10) != 0)
{
return AT_PARA_ERR;
}
power = strtol(param, NULL, 0);
if((power < 0) || (power > 22))
{
return AT_PARA_ERR;
}
}
else
{
return AT_PARA_ERR;
}
/* check freq parameter */
param = string_split(NULL, ',');
if(param != NULL)
{
param = string_trim(param);
if(string_islegal(param, 10) != 0)
{
return AT_PARA_ERR;
}
freq = strtol(param, NULL, 0);
if((freq < 433000000) || (freq > 900000000))
{
return AT_PARA_ERR;
}
}
else
{
return AT_PARA_ERR;
}
/* check preamble length parameter */
param = string_split(NULL, ',');
if(param != NULL)
{
param = string_trim(param);
if(string_islegal(param, 10) != 0)
{
return AT_PARA_ERR;
}
preamble_len = strtol(param, NULL, 0);
if(preamble_len <= 0 || preamble_len > 50)
{
return AT_PARA_ERR;
}
}
else
{
return AT_PARA_ERR;
}
/* check preamble timeout parameter */
param = string_split(NULL, ',');
if(param != NULL)
{
param = string_trim(param);
if(string_islegal(param, 10) != 0)
{
return AT_PARA_ERR;
}
tx_timeout = strtol(param, NULL, 0);
if(tx_timeout < 0 || tx_timeout > 100000)
{
return AT_PARA_ERR;
}
}
else
{
return AT_PARA_ERR;
}
lora_param.sf_tx=sf ;
int bwTemp=0;
switch(bw)
{
case 125:bwTemp=0;
break;
case 250:bwTemp=1;
break;
case 500:bwTemp=2;
break;
default:
break;
}
lora_param.bw_tx=bwTemp;
lora_param.power=power;
lora_param.freq_tx=freq;
lora_param.preamble_len_tx=preamble_len;
lora_param.tx_timeout=tx_timeout;
//flash保存参数
//printf("%d,%d,%d,%d,%d,%d\r\n",sf,bw,power,freq,preamble_len,tx_timeout);
return AT_OK;
}
//查询LoRa接收参数
static int at_query_hrxcfg(void)
{
int8_t sf = lora_param.sf_rx;
int8_t bw = lora_param.bw_rx;
uint32_t freq = lora_param.freq_rx;
int8_t pream_len = lora_param.preamble_len_rx;
uint32_t rx_timeout = lora_param.rx_timeout;
int bwTemp=0;
switch(bw)
{
case 0:bwTemp=125;
break;
case 1:bwTemp=250;
break;
case 2:bwTemp=500;
break;
default:
break;
}
memset(at_query_buf,0,RETURN_BUFF_SZIE);
snprintf(at_query_buf, RETURN_BUFF_SZIE, "+HRXCFG:sf:%d,bw:%d,freq:%d,preamble len:%d,rx timeout:%d",sf, bwTemp, freq, pream_len, rx_timeout);
return AT_OK;
}
//设置LoRa接收参数
static int at_exec_hrxcfg(char* str)
{
char *param;
int8_t sf = 0;
int32_t bw = 0;
uint32_t freq = 0;
uint16_t preamble_len = 0;
/* check sf parameter */
param = string_split(str, ',');
if(param != NULL)
{
param = string_trim(param);
if(string_islegal(param, 10) != 0)
{
return AT_PARA_ERR;
}
sf = strtol(param, NULL, 0);
if((sf < 7) || (sf > 12))
{
return AT_PARA_ERR;
}
}
else
{
return AT_PARA_ERR;
}
/* check bw parameter */
param = string_split(NULL, ',');
if(param != NULL)
{
param = string_trim(param);
if(string_islegal(param, 10) != 0)
{
return AT_PARA_ERR;
}
bw = strtol(param, NULL, 0);
if(bw != 125 && bw != 250 && bw != 500)
{
return AT_PARA_ERR;
}
}
else
{
return AT_PARA_ERR;
}
/* check freq parameter */
param = string_split(NULL, ',');
if(param != NULL)
{
param = string_trim(param);
if(string_islegal(param, 10) != 0)
{
return AT_PARA_ERR;
}
freq = strtol(param, NULL, 0);
if((freq < 433000000) || (freq > 900000000))
{
return AT_PARA_ERR;
}
}
else
{
return AT_PARA_ERR;
}
/* check preamble length parameter */
param = string_split(NULL, ',');
if(param != NULL)
{
param = string_trim(param);
if(string_islegal(param, 10) != 0)
{
return AT_PARA_ERR;
}
preamble_len = strtol(param, NULL, 0);
if(preamble_len <= 0 || preamble_len > 50)
{
return AT_PARA_ERR;
}
}
else
{
return AT_PARA_ERR;
}
lora_param.sf_rx=sf ;
int bwTemp=0;
switch(bw)
{
case 125:bwTemp=0;
break;
case 250:bwTemp=1;
break;
case 500:bwTemp=2;
break;
default:
break;
}
lora_param.bw_rx=bwTemp;
lora_param.freq_rx=freq;
lora_param.preamble_len_rx=preamble_len;
//写入flash
return AT_OK;
}
//以16进制接收数据
static int at_exec_hrecb(char* str)
{
str = string_trim(str);
printf("%s\r\n",str);
return AT_OK;
}
//以ASCII码形式接收
static int at_exec_hrec(char* str)
{
str = string_trim(str);
printf("%s\r\n",str);
return AT_OK;
}
//以16进制发送数据
static int at_exec_hsendb(char* str)
{
str = string_trim(str);
printf("%s\r\n",str);
return AT_OK;
}
//以ASCII码发送数据
static int at_exec_hsend(char* str)
{
str = string_trim(str);
printf("%s\r\n",str);
return AT_OK;
}