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.

819 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;
}