| 
									
										
										
										
											2023-06-10 11:52:00 +08:00
										 |  |  | #include "stdio.h"
 | 
					
						
							|  |  |  | #include "rtthread.h"
 | 
					
						
							|  |  |  | #include "board.h"
 | 
					
						
							|  |  |  | #include "mystdlib.h"
 | 
					
						
							|  |  |  | #include "list.h"
 | 
					
						
							|  |  |  | #include "mystring.h"
 | 
					
						
							|  |  |  | #include "signal.h"
 | 
					
						
							|  |  |  | #include "prot_uc.h"
 | 
					
						
							|  |  |  | #include "buff.h"
 | 
					
						
							|  |  |  | #include "bytearray.h"
 | 
					
						
							|  |  |  | #include "debug.h"
 | 
					
						
							|  |  |  | #include "crc.h"
 | 
					
						
							|  |  |  | #include "dev_flash.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // 接收buff大小
 | 
					
						
							|  |  |  | #define RECV_BUFF_SIZE  300
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static void recv_irq(void *t,uint8_t d) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   protu_def *p=t; | 
					
						
							|  |  |  |   p->buff[p->buff_index]=d; | 
					
						
							|  |  |  |   p->buff_index++; | 
					
						
							|  |  |  |   switch(p->buff_index){ | 
					
						
							|  |  |  |     case 2: | 
					
						
							|  |  |  |       if(p->buff[0]==0x59&&p->buff[1]==0x6d) | 
					
						
							|  |  |  |       { | 
					
						
							|  |  |  |         p->is_big_data=0; | 
					
						
							|  |  |  |         p->num_to_recv=4; | 
					
						
							|  |  |  |       }else{ | 
					
						
							|  |  |  |         p->buff[0]=p->buff[1]; | 
					
						
							|  |  |  |         p->num_to_recv=0; | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |       break; | 
					
						
							|  |  |  |     case 4: | 
					
						
							|  |  |  |       { | 
					
						
							|  |  |  |         int len=p->buff[2]|(p->buff[3]<<8); | 
					
						
							|  |  |  |         if(len<65535){ | 
					
						
							|  |  |  |           p->is_big_data=0; | 
					
						
							|  |  |  |           p->num_to_recv+=len+2; | 
					
						
							|  |  |  |         }else{ | 
					
						
							|  |  |  |           p->is_big_data=1; | 
					
						
							|  |  |  |           p->num_to_recv=11; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |       break; | 
					
						
							|  |  |  |     case 11: | 
					
						
							|  |  |  |       { | 
					
						
							|  |  |  |         if(p->is_big_data==1) | 
					
						
							|  |  |  |         { | 
					
						
							|  |  |  |           int len=p->buff[7]|(p->buff[8]<<8)|(p->buff[9]<<16)|(p->buff[10]<<24); | 
					
						
							|  |  |  |           p->num_to_recv=4+len+2; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |       break; | 
					
						
							|  |  |  |     default: | 
					
						
							|  |  |  |       break; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   // 此时一帧数据已完成
 | 
					
						
							|  |  |  |   if(p->num_to_recv>0&&p->num_to_recv==p->buff_index) | 
					
						
							|  |  |  |   { | 
					
						
							|  |  |  |     //DBG_LOG("recv:%s",str_temp(arr_string(p->buff)));
 | 
					
						
							|  |  |  |     rt_sem_release(p->sem); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static void recv_end_irq(void *t,uint32_t len) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   protu_def *p=t; | 
					
						
							|  |  |  |   p->num_to_recv=len; | 
					
						
							|  |  |  |   p->buff_index=len; | 
					
						
							|  |  |  |   rt_sem_release(p->sem); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | array_def *protu_decode_str(protu_def *p,array_def *data); | 
					
						
							|  |  |  | array_def *protu_encode_str(protu_def *p,array_def *data); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // 查找指定解码器
 | 
					
						
							|  |  |  | codec_item *protu_find_codec(const char *name) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   extern const int codecstruct$$Base; | 
					
						
							|  |  |  |   extern const int codecstruct$$Limit; | 
					
						
							|  |  |  |   codec_item *start=(codec_item *)&codecstruct$$Base; | 
					
						
							|  |  |  |   codec_item *end=(codec_item *)&codecstruct$$Limit; | 
					
						
							|  |  |  |   for(codec_item *t=start;t<end;t++) | 
					
						
							|  |  |  |   { | 
					
						
							|  |  |  |     if(strcmp(t->name,name)==0) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |       return t; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   return 0; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | // 返回正在使用的解码器
 | 
					
						
							|  |  |  | codec_item *protu_codec_inuse(protu_def *p) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   return p->codec; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | void protu_codec_set(protu_def *p,codec_item *c) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   p->codec=c; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // 尝试解码
 | 
					
						
							|  |  |  | static array_def *protu_try_decode(protu_def *p,array_def *data) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   array_def *decode_data=0; | 
					
						
							|  |  |  |   if(p->codec==0||p->codec->decode==protu_decode_str|| | 
					
						
							|  |  |  |     (decode_data=p->codec->decode(p,data),strcmp(p->str_err,"ok")!=0)) | 
					
						
							|  |  |  |   { | 
					
						
							|  |  |  |     CHECK_DO(decode_data,arr_delete); | 
					
						
							|  |  |  |     extern const int codecstruct$$Base; | 
					
						
							|  |  |  |     extern const int codecstruct$$Limit; | 
					
						
							|  |  |  |     codec_item *start=(codec_item *)&codecstruct$$Base; | 
					
						
							|  |  |  |     codec_item *end=(codec_item *)&codecstruct$$Limit; | 
					
						
							|  |  |  |     for(codec_item *t=start;t<end;t++) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |       decode_data=t->decode(p,data); | 
					
						
							|  |  |  |       if(strcmp(p->str_err,"ok")==0) | 
					
						
							|  |  |  |       { | 
					
						
							|  |  |  |         p->codec=t; | 
					
						
							|  |  |  |         break; | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |       else{ | 
					
						
							|  |  |  |         arr_delete(decode_data); | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   if(decode_data==0) | 
					
						
							|  |  |  |     decode_data=arr_creat(); | 
					
						
							|  |  |  |   return decode_data; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static void protu_run(void *t) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   protu_def *p=t; | 
					
						
							|  |  |  |   array_def *data; | 
					
						
							|  |  |  |   array_def *decode_data; | 
					
						
							|  |  |  |   while(p->run) | 
					
						
							|  |  |  |   { | 
					
						
							|  |  |  |     rt_sem_take(p->sem,RT_WAITING_FOREVER); | 
					
						
							|  |  |  |     //DBG_LOG("protu run");
 | 
					
						
							|  |  |  |     data=arr_creat(); | 
					
						
							|  |  |  |     arr_appends(data,p->buff,p->buff_index); | 
					
						
							|  |  |  |     p->num_to_recv=0; | 
					
						
							|  |  |  |     p->buff_index=0; | 
					
						
							|  |  |  |     DBG_LOG("recv:%s",str_temp(arr_string(data))); | 
					
						
							|  |  |  |     decode_data=protu_try_decode(p,data); | 
					
						
							|  |  |  |     //DBG_LOG("decode:%s",str_temp(arr_string(decode_data)));
 | 
					
						
							|  |  |  |     if(p->codec) | 
					
						
							|  |  |  |       emit protu_recv_signal(p,p->codec->name, p->cmd,arr_temp(decode_data),str_temp(str_duplicate(p->str_err))); | 
					
						
							|  |  |  |     arr_delete(data); | 
					
						
							|  |  |  |     irq_disable(); | 
					
						
							|  |  |  |     p->num_to_recv=0; | 
					
						
							|  |  |  |     irq_enable(); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // 根据设备类型初始化编解码指针
 | 
					
						
							|  |  |  | static void protu_set_endecode_fun(protu_def *u) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   const sys_param_def *par=sys_param(); | 
					
						
							|  |  |  |   if(strcmp(par->device_type,"coder")==0) | 
					
						
							|  |  |  |   { | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   else if(strcmp(par->device_type,"checker")==0) | 
					
						
							|  |  |  |   { | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static int protu_init(void) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   const sys_param_def *par=sys_param(); | 
					
						
							| 
									
										
										
										
											2023-06-16 18:07:44 +08:00
										 |  |  |   const char *name="uart4"; | 
					
						
							|  |  |  |   if(strcmp((par->host_if),"utcp")==0) | 
					
						
							|  |  |  |     name="utcp"; | 
					
						
							|  |  |  |   protu_def *protu=protu_creat(dev_get(name)); | 
					
						
							| 
									
										
										
										
											2023-06-10 11:52:00 +08:00
										 |  |  |   app_variable("protu",protu,0); | 
					
						
							| 
									
										
										
										
											2023-06-14 18:05:04 +08:00
										 |  |  |    | 
					
						
							|  |  |  |   // 如果通信接口不是用的串口,则增加一个串口的通信
 | 
					
						
							|  |  |  |   if(strcmp(par->host_if,"uart4")==0) | 
					
						
							|  |  |  |   { | 
					
						
							|  |  |  |     app_variable("protu2",protu,0); | 
					
						
							|  |  |  |   }else | 
					
						
							|  |  |  |   { | 
					
						
							|  |  |  |     protu_def *protu2=protu_creat(dev_get("uart4")); | 
					
						
							|  |  |  |     app_variable("protu2",protu2,0); | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2023-06-10 11:52:00 +08:00
										 |  |  |   return 0; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | app_init_export(protu_init) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | protu_def *protu_creat(uart_def *uart) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   static uint16_t count=0; | 
					
						
							|  |  |  |   char name[20]={0}; | 
					
						
							|  |  |  |   protu_def *p=calloc(1,sizeof(protu_def)); | 
					
						
							|  |  |  |   param_check(p); | 
					
						
							|  |  |  |   p->uart=uart; | 
					
						
							|  |  |  |   sprintf(name,"protu_sem#%d",count); | 
					
						
							|  |  |  |   p->sem=rt_sem_create(name,0,RT_IPC_FLAG_FIFO); | 
					
						
							|  |  |  |   p->buff=malloc(RECV_BUFF_SIZE); | 
					
						
							|  |  |  |   p->run=1; | 
					
						
							|  |  |  |   p->cmd=0xff;// 命令字不可能是0xff
 | 
					
						
							|  |  |  |   protu_set_endecode_fun(p); | 
					
						
							|  |  |  |   sprintf(name,"protu_t#%d",count); | 
					
						
							|  |  |  |   rt_thread_t rt_t=rt_thread_create(name,protu_run,p,2048,5,20); | 
					
						
							|  |  |  |   rt_thread_startup(rt_t); | 
					
						
							| 
									
										
										
										
											2023-06-14 22:15:00 +08:00
										 |  |  |   int bsp=sys_param()->uartbsp; | 
					
						
							|  |  |  |   if(bsp==9600) | 
					
						
							|  |  |  |     p->uart->init(p->uart,9600); | 
					
						
							|  |  |  |   else | 
					
						
							|  |  |  |     p->uart->init(p->uart,0); | 
					
						
							| 
									
										
										
										
											2023-06-10 11:52:00 +08:00
										 |  |  |   //p->uart->set_irq(p->uart,recv_irq,p);
 | 
					
						
							|  |  |  |   p->uart->set_end_irq(p->uart,p->buff,RECV_BUFF_SIZE,recv_end_irq,p); | 
					
						
							|  |  |  |    | 
					
						
							|  |  |  |   count++; | 
					
						
							|  |  |  |   return p; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | int protu_send(protu_def *p,array_def *data) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2023-06-14 18:05:04 +08:00
										 |  |  |   DBG_LOG("send:%s",str_temp(arr_string(data))); | 
					
						
							| 
									
										
										
										
											2023-06-10 11:52:00 +08:00
										 |  |  |   return p->uart->write(p->uart,arr_data(data),arr_length(data)); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // 槽函数,回复上位机
 | 
					
						
							|  |  |  | void protu_reply_call(protu_def *p,array_def *data) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   param_check(p); | 
					
						
							|  |  |  |   array_def *t=0; | 
					
						
							|  |  |  |   if(p->codec) | 
					
						
							|  |  |  |     t=p->codec->encode(p,data); | 
					
						
							|  |  |  |   // DBG_LOG("send encode:%s",arr_string(t));
 | 
					
						
							|  |  |  |   if(t){ | 
					
						
							|  |  |  |     protu_send(p,t); | 
					
						
							|  |  |  |     arr_delete(t); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // 槽函数,主动上发
 | 
					
						
							|  |  |  | void protu_send_call(protu_def *p,uint8_t cmd,array_def *data) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   array_def *t=0; | 
					
						
							|  |  |  |   if(cmd!=0){ | 
					
						
							|  |  |  |     p->cmd=cmd; | 
					
						
							|  |  |  |     p->cmd_no++; | 
					
						
							|  |  |  |     if(p->codec) | 
					
						
							|  |  |  |       t=p->codec->encode(p,data); | 
					
						
							|  |  |  |   }else if(p->cmd==0) | 
					
						
							|  |  |  |   { | 
					
						
							|  |  |  |     // 命令字为0是字符串
 | 
					
						
							|  |  |  |     t=protu_encode_str(p,data); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   if(t){ | 
					
						
							|  |  |  |     protu_send(p,t); | 
					
						
							|  |  |  |     arr_delete(t); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // 字符串解码
 | 
					
						
							|  |  |  | array_def *protu_decode_str(protu_def *p,array_def *data) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   array_def *r=arr_creat(); | 
					
						
							|  |  |  |   param_check(r); | 
					
						
							|  |  |  |   DBG_LOG("decode for command"); | 
					
						
							|  |  |  |   str_set(p->str_err,"ok"); | 
					
						
							|  |  |  |   p->cmd=0; | 
					
						
							| 
									
										
										
										
											2023-06-14 18:05:04 +08:00
										 |  |  |   if(str_is_print_str((const char *)arr_data(data),arr_length(data))==1) | 
					
						
							| 
									
										
										
										
											2023-06-10 11:52:00 +08:00
										 |  |  |   { | 
					
						
							| 
									
										
										
										
											2023-06-14 18:05:04 +08:00
										 |  |  |     arr_append(data,0); | 
					
						
							| 
									
										
										
										
											2023-06-10 11:52:00 +08:00
										 |  |  |     arr_appends_from(r,data); | 
					
						
							|  |  |  |   }else{ | 
					
						
							|  |  |  |     DBG_WARN("data not a string"); | 
					
						
							|  |  |  |     str_set(p->str_err,"not string"); | 
					
						
							| 
									
										
										
										
											2023-06-14 18:05:04 +08:00
										 |  |  |     //arr_remove(data,arr_length(data)-1,1);
 | 
					
						
							| 
									
										
										
										
											2023-06-10 11:52:00 +08:00
										 |  |  |   } | 
					
						
							|  |  |  |   return r; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // 字符串编码
 | 
					
						
							|  |  |  | array_def *protu_encode_str(protu_def *p,array_def *data) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   array_def *t=arr_creat(); | 
					
						
							|  |  |  |   param_check(t); | 
					
						
							|  |  |  |   arr_appends_from(t,data); | 
					
						
							|  |  |  |   return t; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-06-14 18:05:04 +08:00
										 |  |  | protuc_codec_export(string,protu_decode_str,protu_encode_str); | 
					
						
							| 
									
										
										
										
											2023-06-10 11:52:00 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 |