471 lines
		
	
	
		
			10 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
		
		
			
		
	
	
			471 lines
		
	
	
		
			10 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
|   | #include "stdio.h"
 | |||
|  | #include "rtthread.h"
 | |||
|  | #include "board.h"
 | |||
|  | #include "mystdlib.h"
 | |||
|  | #include "list.h"
 | |||
|  | #include "mystring.h"
 | |||
|  | #include "signal.h"
 | |||
|  | #include "prot_mcu.h"
 | |||
|  | #include "buff.h"
 | |||
|  | #include "bytearray.h"
 | |||
|  | #include "debug.h"
 | |||
|  | #include "crc.h"
 | |||
|  | 
 | |||
|  | 
 | |||
|  | 
 | |||
|  | typedef struct{ | |||
|  |   uint16_t no; | |||
|  |   list_def *cmds;//int
 | |||
|  |   uint8_t addr; | |||
|  |   uint8_t cmd; | |||
|  |   array_def *data; | |||
|  |   int retry; | |||
|  |   int timeout_ms; | |||
|  | }protm_slave; | |||
|  | 
 | |||
|  | 
 | |||
|  | 
 | |||
|  | static int protm_slave_sub(void *a,void *b) | |||
|  | { | |||
|  |   protm_slave *a_=a; | |||
|  |   protm_slave *b_=b; | |||
|  |   return a_->addr-b_->addr; | |||
|  | } | |||
|  | 
 | |||
|  | static int protm_slave_del(void *t) | |||
|  | { | |||
|  |   protm_slave *p=t; | |||
|  |   CHECK_DO(p->cmds,list_delete); | |||
|  |   return 0; | |||
|  | } | |||
|  | 
 | |||
|  | 
 | |||
|  | static protm_slave *protm_slave_creat(void) | |||
|  | { | |||
|  |   protm_slave *p=calloc(1,sizeof(protm_slave)); | |||
|  |   param_check(p); | |||
|  |   return p; | |||
|  | } | |||
|  | 
 | |||
|  | 
 | |||
|  | 
 | |||
|  | 
 | |||
|  | 
 | |||
|  | 
 | |||
|  | 
 | |||
|  | array_def *protm_decode(protm_def *p,array_def *data); | |||
|  | protm_slave *protm_get_slave(protm_def *p,uint8_t addr); | |||
|  | 
 | |||
|  | 
 | |||
|  | 
 | |||
|  | typedef struct{ | |||
|  |   array_def *data; | |||
|  |   int addr; | |||
|  | }send_data_def; | |||
|  | 
 | |||
|  | 
 | |||
|  | // <20><><EFBFBD><EFBFBD><EFBFBD>¼<EFBFBD>
 | |||
|  | #define EVENT_RECV      0x1
 | |||
|  | #define EVENT_SEND      0x2
 | |||
|  | #define EVENT_TIMEOUT   0x4
 | |||
|  | 
 | |||
|  | 
 | |||
|  | 
 | |||
|  | struct _protm_def{ | |||
|  |   uart_def *uart; | |||
|  |   array_def *buff; | |||
|  |   int num_to_recv; | |||
|  |   rt_event_t event; | |||
|  |   rt_timer_t timer; | |||
|  |   int run; | |||
|  |   char *str_err; | |||
|  |   list_def *slaves;//protm_slave
 | |||
|  |   list_def *slaves_addr;//int
 | |||
|  |   list_def *send_data;//send_data_def
 | |||
|  |   int in_send;//<2F>ڷ<EFBFBD><DAB7><EFBFBD>״̬ʱΪ1
 | |||
|  |   uint8_t recv_cmd; | |||
|  |   uint8_t recv_src; | |||
|  |    | |||
|  | }; | |||
|  | 
 | |||
|  | 
 | |||
|  | 
 | |||
|  | 
 | |||
|  | 
 | |||
|  | static void recv_irq(void *t,uint8_t d) | |||
|  | { | |||
|  |   protm_def *p=t; | |||
|  |   arr_append(p->buff,d); | |||
|  |   switch(arr_length(p->buff)){ | |||
|  |     case 2: | |||
|  |       if(arr_get(p->buff,0)=='Y'&&arr_get(p->buff,1)=='e') | |||
|  |       { | |||
|  |         p->num_to_recv=4; | |||
|  |       }else{ | |||
|  |         arr_remove(p->buff,0,1); | |||
|  |         p->num_to_recv=0; | |||
|  |       } | |||
|  |       break; | |||
|  |     case 4: | |||
|  |       { | |||
|  |         int len=arr_get(p->buff,2)|(arr_get(p->buff,3)<<8); | |||
|  |         p->num_to_recv=len; | |||
|  |       } | |||
|  |       break; | |||
|  |     default: | |||
|  |       break; | |||
|  |   } | |||
|  |   // <20><>ʱһ֡<D2BB><D6A1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
 | |||
|  |   if(p->num_to_recv>0&&p->num_to_recv==arr_length(p->buff)) | |||
|  |   { | |||
|  |     rt_event_send(p->event,EVENT_RECV); | |||
|  |   } | |||
|  | } | |||
|  | 
 | |||
|  | 
 | |||
|  | 
 | |||
|  | /*
 | |||
|  | * <EFBFBD><EFBFBD><EFBFBD>ӻ<EFBFBD>ͨ<EFBFBD>ŵĴ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ǵ<EFBFBD><EFBFBD>еģ<EFBFBD>һ<EFBFBD><EFBFBD>ͨ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>֮<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ܿ<EFBFBD>ʼ<EFBFBD><EFBFBD>һ<EFBFBD><EFBFBD>ͨ<EFBFBD><EFBFBD> | |||
|  | * Э<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>յ<EFBFBD>ͨ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Dz<EFBFBD><EFBFBD>еģ<EFBFBD>Ӧ<EFBFBD>ò<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ͨ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ᱻ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> | |||
|  | */ | |||
|  | 
 | |||
|  | static void protm_send_next(void *t); | |||
|  | int protm_send(protm_def *p,send_data_def *d); | |||
|  | static void protm_send_timeout(void *t); | |||
|  | static void protm_run(void *t) | |||
|  | { | |||
|  |   protm_def *p=t; | |||
|  |   array_def *data; | |||
|  |   array_def *decode_data; | |||
|  |   uint32_t ev; | |||
|  |   while(p->run) | |||
|  |   { | |||
|  |     rt_event_recv(p->event,0xffffffff,RT_EVENT_FLAG_OR|RT_EVENT_FLAG_CLEAR,RT_WAITING_FOREVER,&ev); | |||
|  |     if(ev&EVENT_RECV) | |||
|  |     { | |||
|  |       // DBG_LOG("protmcu:recv event.");
 | |||
|  |       data=arr_duplicate(p->buff); | |||
|  |       arr_clear(p->buff); | |||
|  |       //DBG_LOG("recv:%s",str_temp(arr_string(data)));
 | |||
|  |       decode_data=protm_decode(p,data); | |||
|  |       arr_delete(data); | |||
|  |       emit protm_recv_signal(p,p->recv_src,p->recv_cmd,arr_temp(decode_data),str_temp(str_duplicate(p->str_err))); | |||
|  |       irq_disable(); | |||
|  |       p->num_to_recv=0; | |||
|  |       irq_enable(); | |||
|  |       protm_send_next(p); | |||
|  |     } | |||
|  |     else if(ev&EVENT_TIMEOUT) | |||
|  |     { | |||
|  |       protm_send_timeout(p); | |||
|  |     } | |||
|  |     if (ev&EVENT_SEND) | |||
|  |     { | |||
|  |       // DBG_LOG("protmcu:send event.");
 | |||
|  |       if(list_length(p->send_data)>0) | |||
|  |       { | |||
|  |         send_data_def *a=(send_data_def *)list_get(p->send_data,0); | |||
|  |         protm_send(p,a); | |||
|  |       } | |||
|  |     } | |||
|  |     ev=0; | |||
|  |   } | |||
|  | } | |||
|  | 
 | |||
|  | 
 | |||
|  | // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>һ<EFBFBD><D2BB>
 | |||
|  | static void protm_send_next(void *t) | |||
|  | { | |||
|  |   protm_def *p=t; | |||
|  |   rt_timer_stop(p->timer); | |||
|  |   list_remove(p->send_data,0); | |||
|  |   // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>б<EFBFBD><D0B1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ݣ<EFBFBD><DDA3><EFBFBD>ʱ<EFBFBD><CAB1><EFBFBD><EFBFBD>
 | |||
|  |   if (list_length(p->send_data)>0) | |||
|  |   { | |||
|  |     // DBG_LOG("protmcu:EVENT_SEND.");
 | |||
|  |     rt_event_send(p->event,EVENT_SEND); | |||
|  |   } | |||
|  |   else{ | |||
|  |     irq_disable(); | |||
|  |     p->in_send=0; | |||
|  |     irq_enable(); | |||
|  |   } | |||
|  | } | |||
|  | 
 | |||
|  | 
 | |||
|  | static void protm_send_timeout_cb(void *t) | |||
|  | { | |||
|  |   protm_def *p=t; | |||
|  |   rt_event_send(p->event,EVENT_TIMEOUT); | |||
|  | } | |||
|  | 
 | |||
|  | // <20><><EFBFBD>ճ<EFBFBD>ʱ
 | |||
|  | static void protm_send_timeout(void *t) | |||
|  | { | |||
|  |   protm_def *p=t; | |||
|  |   send_data_def *s=list_get(p->send_data,0); | |||
|  |   protm_slave *sl=protm_get_slave(p,s->addr); | |||
|  |   if(sl->retry>0){ | |||
|  |     sl->retry--; | |||
|  |     DBG_WARN("slave:%d retry left ",s->addr,sl->retry); | |||
|  |     list_shift(p->send_data); | |||
|  |   }else{ | |||
|  |     DBG_WARN("slave:%d retry timeout,remove the send data.",s->addr); | |||
|  |     list_remove(p->send_data,0); | |||
|  |   } | |||
|  |   // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>б<EFBFBD><D0B1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ݣ<EFBFBD><DDA3><EFBFBD>ʱ<EFBFBD><CAB1><EFBFBD><EFBFBD>
 | |||
|  |   if (list_length(p->send_data)>0) | |||
|  |   { | |||
|  |     // DBG_LOG("protmcu:EVENT_SEND.");
 | |||
|  |     rt_event_send(p->event,EVENT_SEND); | |||
|  |   } | |||
|  |   else{ | |||
|  |     irq_disable(); | |||
|  |     p->in_send=0; | |||
|  |     irq_enable(); | |||
|  |   } | |||
|  | } | |||
|  | 
 | |||
|  | 
 | |||
|  | 
 | |||
|  | 
 | |||
|  | 
 | |||
|  | // <20><><EFBFBD>Ͷ<EFBFBD><CDB6><EFBFBD>ɾ<EFBFBD><C9BE><EFBFBD><EFBFBD>Ŀ
 | |||
|  | static int _list_send_data_del(void *t) | |||
|  | { | |||
|  |   send_data_def *a=t; | |||
|  |   arr_delete(a->data); | |||
|  |   return 0; | |||
|  | } | |||
|  | 
 | |||
|  | 
 | |||
|  | protm_def *protm_creat(uart_def *uart,int *addrs,int num) | |||
|  | { | |||
|  |   static int count=0; | |||
|  |   char name[20]={0}; | |||
|  |   protm_def *p=calloc(1,sizeof(protm_def)); | |||
|  |   param_check(p); | |||
|  |   p->uart=uart; | |||
|  |   sprintf(name,"protm_event#%d",count); | |||
|  |   p->event=rt_event_create(name,RT_IPC_FLAG_FIFO); | |||
|  |   p->buff=arr_creat(); | |||
|  |   p->run=1; | |||
|  |   p->slaves=list_creat(sizeof(protm_slave),protm_slave_sub,protm_slave_del,0); | |||
|  |   p->slaves_addr=list_creat_int(); | |||
|  |   p->send_data=list_creat(sizeof(send_data_def),0,_list_send_data_del,0); | |||
|  |   // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʱ<EFBFBD><CAB1>ʱ<EFBFBD><CAB1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ָ<EFBFBD><D6B8>ʱ<EFBFBD><CAB1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ٵȴ<D9B5><C8B4>ӻ<EFBFBD><D3BB><EFBFBD><EFBFBD><EFBFBD>
 | |||
|  |   p->timer=rt_timer_create("port_timer",protm_send_timeout_cb,p, | |||
|  |       rt_tick_from_millisecond(55), | |||
|  |       RT_TIMER_FLAG_ONE_SHOT|RT_TIMER_FLAG_SOFT_TIMER); | |||
|  |   list_appends(p->slaves_addr,addrs,num); | |||
|  |   sprintf(name,"protm_t#%d",count); | |||
|  |   rt_thread_t rt_t=rt_thread_create(name,protm_run,p,512,5,20); | |||
|  |   rt_thread_startup(rt_t); | |||
|  |   p->uart->init(p->uart); | |||
|  |   p->uart->set_irq(p->uart,recv_irq,p); | |||
|  |    | |||
|  |   count++; | |||
|  |   return p; | |||
|  | } | |||
|  | 
 | |||
|  | 
 | |||
|  | // <20>õ<EFBFBD>ָ<EFBFBD><D6B8><EFBFBD><EFBFBD>ַ<EFBFBD>Ĵӻ<C4B4>,<2C>Ҳ<EFBFBD><D2B2><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
 | |||
|  | protm_slave *protm_get_slave(protm_def *p,uint8_t addr) | |||
|  | { | |||
|  |   protm_slave *r=0; | |||
|  |   for(int i=0;i<list_length(p->slaves);i++) | |||
|  |   { | |||
|  |     r=list_get(p->slaves,i); | |||
|  |     if(r->addr==addr) | |||
|  |       return r; | |||
|  |   } | |||
|  |   r=protm_slave_creat(); | |||
|  |   r->addr=addr; | |||
|  |   r->cmds=list_creat_int(); | |||
|  |   r->no=0; | |||
|  |   list_append(p->slaves,r); | |||
|  |   free(r); | |||
|  |   return list_get(p->slaves,-1); | |||
|  | } | |||
|  | 
 | |||
|  | 
 | |||
|  | 
 | |||
|  | // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>дӻ<D0B4><D3BB><EFBFBD>ˮ<EFBFBD><CBAE>
 | |||
|  | void protm_set_no_all(protm_def *p,uint16_t no,list_def *cmd/*int*/) | |||
|  | { | |||
|  |   for(int i=0;i<list_length(p->slaves);i++) | |||
|  |   { | |||
|  |     protm_slave *s=list_get(p->slaves,i); | |||
|  |     s->no=no; | |||
|  |     list_clear(s->cmds); | |||
|  |     list_append_from(s->cmds,cmd); | |||
|  |   } | |||
|  | } | |||
|  | 
 | |||
|  | 
 | |||
|  | // <20><><EFBFBD>õ<EFBFBD><C3B5><EFBFBD><EFBFBD>ӻ<EFBFBD><D3BB><EFBFBD>ˮ<EFBFBD><CBAE>
 | |||
|  | void protm_set_no(protm_def *p,uint8_t addr,uint16_t no,list_def *cmd/*int*/) | |||
|  | { | |||
|  |   protm_slave *s=protm_get_slave(p,addr); | |||
|  |   s->no=no; | |||
|  |   list_clear(s->cmds); | |||
|  |   list_append_from(s->cmds,cmd); | |||
|  | } | |||
|  | 
 | |||
|  | 
 | |||
|  | 
 | |||
|  | 
 | |||
|  | 
 | |||
|  | // <20><><EFBFBD><EFBFBD>
 | |||
|  | array_def *protm_decode(protm_def *p,array_def *data) | |||
|  | { | |||
|  |   array_def *r=arr_creat(); | |||
|  |   param_check(r); | |||
|  |   str_set(p->str_err,"ok"); | |||
|  |   if(arr_length(data)<10) | |||
|  |   { | |||
|  |     DBG_WARN("recv data len too less."); | |||
|  |     str_set(p->str_err,"recv data len too less."); | |||
|  |     return r; | |||
|  |   } | |||
|  |   uint8_t src=arr_get(data,4); | |||
|  |   p->recv_src=src; | |||
|  |   uint16_t len=arr_get(data,2)|(arr_get(data,3)<<8); | |||
|  |   uint8_t crc=crc_crc8(arr_data(data),arr_length(data)-1); | |||
|  |   if(len!=arr_length(data)) | |||
|  |   { | |||
|  |     // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ȳ<EFBFBD><C8B2><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ݶ<EFBFBD>ʧ
 | |||
|  |     DBG_WARN("recv data have lossed."); | |||
|  |     str_set(p->str_err,"recv data have lossed."); | |||
|  |     return r; | |||
|  |   } | |||
|  |   uint16_t no=arr_get(data,7)|(arr_get(data,8)<<8); | |||
|  |   uint16_t h_no=protm_get_slave(p,src)->no; | |||
|  |   if(no!=h_no) | |||
|  |   { | |||
|  |     // <20><><EFBFBD><EFBFBD>һ<EFBFBD><D2BB>ָ<EFBFBD><D6B8><EFBFBD>ȴ<EFBFBD><C8B4>䷵<EFBFBD>أ<EFBFBD><D8A3><EFBFBD>ʱ<EFBFBD><CAB1>ˮ<EFBFBD><CBAE>Ӧ<EFBFBD><D3A6>ͬ
 | |||
|  |     //DBG_WARN("slave_addr=%d cmd_no error:h_no=%d,no=%d.",src,h_no,no);
 | |||
|  |     //str_set(p->str_err,"cmd no err.");
 | |||
|  |     //return r;
 | |||
|  |   } | |||
|  |   if(crc!=arr_get(data,-1)) | |||
|  |   { | |||
|  |     DBG_WARN("recv data crc check error:%02x,%02x.",crc,arr_get(data,-1)); | |||
|  |     str_set(p->str_err,"crc check err."); | |||
|  |   } | |||
|  |   p->recv_cmd=arr_get(data,6); | |||
|  |   list_def *cmds=protm_get_slave(p,src)->cmds; | |||
|  |   if(list_contains(cmds,(int []){p->recv_cmd})==0){ | |||
|  |     // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>У<EFBFBD>鲻<EFBFBD><E9B2BB>
 | |||
|  |     DBG_WARN("cmd check err.cmds=%s,recv_cmd=%d",tappend(list_string(cmds),0),p->recv_cmd); | |||
|  |     str_set(p->str_err,"cmd check err."); | |||
|  |   } | |||
|  |   arr_delete(r); | |||
|  |   return arr_mid(data,9,len-10); | |||
|  | } | |||
|  | 
 | |||
|  | 
 | |||
|  | // <20><><EFBFBD><EFBFBD>
 | |||
|  | array_def *protm_encode(protm_def *p,uint8_t dst,uint8_t cmd,list_def *comp_cmd/*int*/,array_def *data) | |||
|  | { | |||
|  |   array_def *t=arr_creat(); | |||
|  |   param_check(t); | |||
|  |   uint16_t len=arr_length(data)+10; | |||
|  |   protm_slave *slave=protm_get_slave(p,dst); | |||
|  |   slave->no++; | |||
|  |   protm_set_no(p,dst,slave->no,comp_cmd); | |||
|  |   arr_append(t,'Y'); | |||
|  |   arr_append(t,'e'); | |||
|  |   arr_append(t,len&0xff); | |||
|  |   arr_append(t,len>>8); | |||
|  |   arr_append(t,0);// Դ<><D4B4>ַ
 | |||
|  |   arr_append(t,dst);// Ŀ<><C4BF><EFBFBD><EFBFBD>ַ
 | |||
|  |   arr_append(t,cmd);// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
 | |||
|  |   arr_append(t,slave->no&0xff); | |||
|  |   arr_append(t,slave->no>>8); | |||
|  |   arr_appends_from(t,data); | |||
|  |   arr_append(t,crc_crc8(arr_data(t),arr_length(t))); | |||
|  |   return t; | |||
|  | } | |||
|  | 
 | |||
|  | // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ݣ<EFBFBD><DDA3><EFBFBD><EFBFBD><EFBFBD>ǰ<EFBFBD>ȿ<EFBFBD><C8BF><EFBFBD><EFBFBD><EFBFBD>ʱ<EFBFBD><CAB1>ʱ<EFBFBD><CAB1>
 | |||
|  | int protm_send(protm_def *p,send_data_def *d) | |||
|  | { | |||
|  |   rt_tick_t tick=0; | |||
|  |   protm_slave *s=protm_get_slave(p,d->addr); | |||
|  |   //DBG_LOG("send:%s",str_temp(arr_string(d->data)));
 | |||
|  |   tick=rt_tick_from_millisecond(s->timeout_ms); | |||
|  |   rt_timer_control(p->timer,RT_TIMER_CTRL_SET_TIME,&tick); | |||
|  |   rt_timer_start(p->timer); | |||
|  |   if(d->data==0) | |||
|  |   { | |||
|  |     DBG_WARN("addr=%d,d->data=0",d->addr); | |||
|  |     return 0; | |||
|  |   } | |||
|  |   return p->uart->write(p->uart,arr_data(d->data),arr_length(d->data)); | |||
|  | } | |||
|  | 
 | |||
|  | 
 | |||
|  | //// <20>ۺ<EFBFBD><DBBA><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ݵ<EFBFBD>ָ<EFBFBD><D6B8><EFBFBD><EFBFBD>ַ
 | |||
|  | //void protm_send_call(protm_def *p,list_def *addrs/*int*/,uint8_t cmd,list_def *comp_cmd/*int*/,array_def *data)
 | |||
|  | //{
 | |||
|  | //  param_check(p);
 | |||
|  | //  for(int i=0;i<list_length(addrs);i++)
 | |||
|  | //  {
 | |||
|  | //    uint8_t dst=(uint8_t)list_get_int(addrs,i);
 | |||
|  | //    if(list_contains(p->slaves_addr,(int []){dst})==1)
 | |||
|  | //    {
 | |||
|  | //      array_def *t=0;
 | |||
|  | //      t=protm_encode(p,dst,cmd,comp_cmd,data);
 | |||
|  | //      protm_send(p,t);
 | |||
|  | //      arr_delete(t);
 | |||
|  | //    }
 | |||
|  | //  }
 | |||
|  | //}
 | |||
|  | 
 | |||
|  | 
 | |||
|  | 
 | |||
|  | // <20>ۺ<EFBFBD><DBBA><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ݵ<EFBFBD>ָ<EFBFBD><D6B8><EFBFBD><EFBFBD>ַ
 | |||
|  | void protm_send_call(protm_def *p,uint8_t addr,uint8_t cmd,list_def *comp_cmd/*int*/,array_def *data,int timeout_ms,int retry) | |||
|  | { | |||
|  |   param_check(p); | |||
|  |   if(list_contains(p->slaves_addr,(int []){addr})==1) | |||
|  |   { | |||
|  |     array_def *t=0; | |||
|  |     t=protm_encode(p,addr,cmd,comp_cmd,data); | |||
|  |     //protm_send(p,t);
 | |||
|  |     //arr_delete(t);
 | |||
|  |     // <20><><EFBFBD>ӵ<EFBFBD><D3B5><EFBFBD><EFBFBD>Ͷ<EFBFBD><CDB6>У<EFBFBD><D0A3><EFBFBD><EFBFBD>ͱ<EFBFBD><CDB1><EFBFBD><EFBFBD>ȵ<EFBFBD><C8B5><EFBFBD>Ӧ<EFBFBD><D3A6><EFBFBD><EFBFBD>ʱ<EFBFBD><CAB1><EFBFBD>ܷ<EFBFBD><DCB7><EFBFBD><EFBFBD><EFBFBD>һ<EFBFBD><D2BB>
 | |||
|  |     DBG_LOG("send to:%d",addr); | |||
|  |     send_data_def sd={0}; | |||
|  |     sd.addr=addr;sd.data=t; | |||
|  |     protm_slave *s=protm_get_slave(p,addr); | |||
|  |     s->retry=retry; | |||
|  |     s->timeout_ms=timeout_ms; | |||
|  |     list_append(p->send_data,&sd); | |||
|  |     if(p->in_send==0){ | |||
|  |       irq_disable(); | |||
|  |       p->in_send=1; | |||
|  |       irq_enable(); | |||
|  |       //DBG_LOG("send call");
 | |||
|  |       rt_event_send(p->event,EVENT_SEND); | |||
|  |     } | |||
|  |   } | |||
|  | } | |||
|  | 
 | |||
|  | 
 | |||
|  | 
 | |||
|  | 
 | |||
|  | // <20><><EFBFBD><EFBFBD>1<EFBFBD><31>ʾ<EFBFBD>˵<EFBFBD>ַ<EFBFBD><D6B7><EFBFBD>Է<EFBFBD><D4B7>͵<EFBFBD><CDB5><EFBFBD><EFBFBD><EFBFBD><EFBFBD>˿<EFBFBD>
 | |||
|  | int protm_contains(protm_def *p,uint8_t addr) | |||
|  | { | |||
|  |   param_check(p); | |||
|  |   return list_contains(p->slaves_addr,(int []){addr}); | |||
|  | } | |||
|  | 
 | |||
|  | 
 | |||
|  | 
 | |||
|  | 
 | |||
|  | 
 | |||
|  | 
 |