Files
player/Project/Src/MyApp/at_host.c
2025-07-05 19:47:28 +08:00

408 lines
5.9 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#include "usart2.h"
#include "at_host.h"
#include "string.h"
#include "rtthread.h"
#include "stdlib.h"
typedef struct{
void *data;
int size;
int type;// 0:set;1,get
int cmd;
}send_pkt_def;
static uint8_t g_send_buff[CMD_AT_MAXLEN]={0};
static rt_event_t g_recv_event;
static send_pkt_def g_pkt;
static int at_puts_data(uint8_t *data,int len)
{
for (int i=0;i<len;i++)
{
usart2_put_byte(data[i]);
}
return 0;
}
static int at_get_byte(uint8_t *data)
{
return usart2_get_byte(data);
}
//计算命令帧长度
static int cmdlen(uint8_t *cmd)
{
int len=0;
while(*cmd!=0xfc)
{
len++;
if (CMD_AT_MAXLEN<len)
return -1;
cmd++;
}
return len;
}
//去转义,输出转义之后的数据长度
static int unescaped(uint8_t *dat,int len)
{
uint8_t *src=dat;
uint8_t *dsc=dat;
while(len>0)
{
if (*src<0xf0)
{
*dsc=*src;
dsc++;
src++;
len--;
}
else
{
*dsc=src[0]+src[1];
dsc++;
src+=2;
len-=2;
}
}
return dsc-dat;
}
//转义,输出转义后的数据长度
static int escaped(uint8_t *src,uint8_t *dsc,int src_len)
{
uint8_t *dsc_t=dsc;
while(src_len--)
{
if (*src<0xf0)
{
*dsc=*src;
dsc++;
src++;
}
else
{
*dsc=0xf0;
dsc++;
*dsc=*src-0xf0;
dsc++;
src++;
}
}
return dsc-dsc_t;
}
/**
* 找到指定字符的索引
*
*/
static int find_char_index (uint8_t *str,char ch,int len)
{
// int len=strlen(str);
for (int i=0;i<len;i++)
{
if (str[i]==ch)
return i;
}
return -1;
}
static void cb_recv_data(uint8_t d)
{
if((d==CMDAT_CMD_END)&&(g_recv_event!=0))
{
rt_event_send(g_recv_event,CMDAT_EVENT_RECV);
}
}
//初始化
int at_init(void)
{
if(g_recv_event==0)
{
g_recv_event=rt_event_create("at_event", RT_IPC_FLAG_FIFO);
usart2_init();
usart2_set_cbcall(cb_recv_data);
}
return 0;
}
//去初始化
int at_deinit(void)
{
if(g_recv_event)
{
usart2_deinit();
usart2_set_cbcall(0);
rt_event_delete(g_recv_event);
g_recv_event=0;
}
return 0;
}
//清除缓冲区
int at_clear_buff(void)
{
usart2_clear();
return 0;
}
//设置
static int at_send_set(uint8_t cmd,void *par, int size)
{
int len=0;
g_send_buff[0]=CMDAT_CMD_START;
len=escaped(&cmd,&g_send_buff[1],1);
g_send_buff[len+1]=CMDAT_CMD_SET;
if ((par==0)||size==0)
{
g_send_buff[len+2]=CMDAT_CMD_END;
at_puts_data(g_send_buff,len+2+1);
}
else
{
int par_len=0;
par_len=escaped(par,&g_send_buff[len+2],size);
g_send_buff[len+2+par_len]=CMDAT_CMD_END;
at_puts_data(g_send_buff,len+2+par_len+1);
}
return 0;
}
//查询
static int at_send_get(uint8_t cmd,void *par, int size)
{
int len=0;
g_send_buff[0]=CMDAT_CMD_START;
len=escaped(&cmd,&g_send_buff[1],1);
g_send_buff[len+1]=CMDAT_CMD_GET;
if ((par==0)||size==0)
{
g_send_buff[len+2]=CMDAT_CMD_END;
at_puts_data(g_send_buff,len+2+1);
}
else
{
int par_len=0;
par_len=escaped(par,&g_send_buff[len+2],size);
g_send_buff[len+2+par_len]=CMDAT_CMD_END;
at_puts_data(g_send_buff,len+2+par_len+1);
}
return 0;
}
//获取一个数据帧
int at_get_return_line(uint8_t *buff)
{
uint8_t t=0;
int len=0;
int act=0;
while(at_get_byte(&t)==0)
{
if(t==CMDAT_CMD_START) act=1;
if(act)
{
buff[len]=t;
len++;
}
if (t==CMDAT_CMD_END)
{
break;
}
}
if(t==CMDAT_CMD_END)
{
return len;
}
else
{
return -1;
}
}
//解析数据帧
int at_decode_line(uint8_t *buff,int buff_len,uint8_t **obj,int *obj_size,uint8_t *op,uint8_t **par,int *par_size)
{
if(buff[0]!=CMDAT_CMD_START)
return -1;
if(buff[buff_len-1]!=CMDAT_CMD_END)
return -1;
int in=-1;
in=find_char_index(buff+1,CMDAT_CMD_RET,buff_len-1);
if(in!=-1)
{
if(op) *op=CMDAT_CMD_RET;
if(obj_size) *obj_size=unescaped(buff+1,in);
if(obj) *obj=buff+1;
if(par_size) *par_size=unescaped(buff+1+in+1,buff_len-3-in);
if(par) *par=buff+1+in+1;
return 0;
}
in=find_char_index(buff+1,CMDAT_CMD_ACT,buff_len-1);
if(in!=-1)
{
if(op) *op=CMDAT_CMD_ACT;
if(obj_size) *obj_size=unescaped(buff+1,in);
if(obj) *obj=buff+1;
if(par_size) *par_size=unescaped(buff+1+in+1,buff_len-3-in);
if(par) *par=buff+1+in+1;
return 0;
}
return -1;
}
//字符转化为16进制
static uint8_t at_char_to_hex(char par)
{
uint8_t ret=0xff;
if (par>='0'&&par<='9')
{
ret=par-'0';
}
if (par>='A'&&par<='F')
{
ret=par-'A'+10;
}
if (par>='a'&&par<='f')
{
ret=par-'a'+10;
}
return ret;
}
//把字符串转化为hex低字节在前
int at_string_to_hex(char *str,void *hex)
{
char *str_s=str;
uint8_t *data=hex;
int index=0;
uint8_t tmp=0;
while (*str_s)
{
tmp=at_char_to_hex(*str_s);
if(tmp!=0xff)
{
data[index>>1]|=tmp<<((index&1)?0:4);
index++;
}
str_s++;
}
return index;
}
// 发送设置命令事件
int at_send_set_event(uint8_t cmd,void *par, int size)
{
if(g_recv_event)
{
if(g_pkt.data) free(g_pkt.data);
g_pkt.data=malloc(size);
memcpy(g_pkt.data,par,size);
g_pkt.size=size;
g_pkt.type=0;
g_pkt.cmd=cmd;
rt_event_send(g_recv_event,CMDAT_EVENT_USER);
return 0;
}
else
{
return -1;
}
}
// 发送获取命令事件
int at_send_get_event(uint8_t cmd,void *par, int size)
{
if(g_recv_event)
{
if(g_pkt.data) free(g_pkt.data);
g_pkt.data=malloc(size);
memcpy(g_pkt.data,par,size);
g_pkt.size=size;
g_pkt.type=1;
g_pkt.cmd=cmd;
rt_event_send(g_recv_event,CMDAT_EVENT_USER);
return 0;
}
else
{
return -1;
}
}
// 发送数据包
int at_send_packet(void)
{
if(g_pkt.data||g_pkt.cmd)
{
if(g_pkt.type==0)
{
return at_send_set(g_pkt.cmd,g_pkt.data,g_pkt.size);
}
else if(g_pkt.type==1)
{
return at_send_get(g_pkt.cmd,g_pkt.data,g_pkt.size);
}
}
return -1;
}
// 获取事件
int at_get_event(void)
{
rt_uint32_t ev;
if(g_recv_event)
{
if(rt_event_recv(g_recv_event,0xffffffff,RT_EVENT_FLAG_OR|RT_EVENT_FLAG_CLEAR,RT_WAITING_FOREVER,&ev)==RT_EOK)
return ev;
else
return 0;
}
return 0;
}
// 发送用户事件
int at_send_user_event(uint32_t ev)
{
if(g_recv_event)
{
rt_event_send(g_recv_event,ev);
return 0;
}
else
return -1;
}