]> rtime.felk.cvut.cz Git - can-usb1.git/blob - ulan/embedded/app/u2u/ver2/ul_dcnv.c
Initializing repo
[can-usb1.git] / ulan / embedded / app / u2u / ver2 / ul_dcnv.c
1 #include <system_def.h>
2 #include <cpu_def.h>
3 #include <stdio.h>
4 #include <usb/usb.h>
5 #include "ul_dcnv.h"
6
7 //#define U2UBFL_LNMM     0x080         /* Length of received frame must match expected len */ 
8 #define U2UBFL_NORE     0x040         /* Do not try to repeat if error occurs */ 
9 #define U2UBFL_TAIL     0x020         /* Message has tail frame */
10 #define U2UBFL_REC      0x010         /* Request receiption of block */
11 #define U2UBFL_FAIL     0x008         /* Message cannot be send - error */
12 #define U2UBFL_PROC     0x004         /* Message succesfull send */
13 #define U2UBFL_AAP      0x003         /* Request imediate proccessing of frame by receiver station with acknowledge */
14 #define U2UBFL_PRQ      0x002         /* Request imediate proccessing of frame by receiver station */
15 #define U2UBFL_ARQ      0x001         /* Request imediate acknowledge by receiving station */
16
17 unsigned char 
18 cbfl_ul2ps(unsigned int bfl,int proc)
19 {
20   unsigned char ret=0;
21   if(bfl&UL_BFL_ARQ) ret|=U2UBFL_ARQ;
22   if(bfl&UL_BFL_PRQ) ret|=U2UBFL_PRQ;
23   if(proc) ret|=U2UBFL_PROC;
24   if(bfl&UL_BFL_FAIL) ret|=U2UBFL_FAIL;
25   if(bfl&UL_BFL_REC) ret|=U2UBFL_REC;
26   if(bfl&UL_BFL_TAIL) ret|=U2UBFL_TAIL;
27   if(bfl&UL_BFL_NORE) ret|=U2UBFL_NORE;
28   return ret;
29 }
30
31 unsigned int 
32 cbfl_ps2ul(unsigned char bfl)
33 {
34   unsigned int ret=0;
35   if(bfl&U2UBFL_ARQ) ret|=UL_BFL_ARQ;
36   if(bfl&U2UBFL_PRQ) ret|=UL_BFL_PRQ;
37   if(bfl&U2UBFL_REC) ret|=UL_BFL_REC;
38   else ret|=UL_BFL_SND;
39   if(bfl&U2UBFL_TAIL) ret|=UL_BFL_TAIL;
40   if(bfl&U2UBFL_NORE) ret|=UL_BFL_NORE;
41   return ret;
42 }
43
44 int 
45 ul_dcnv_init(ul_dcnv_state_t XDATA *cnvst,ul_fd_t tx_fd,ul_fd_t rx_fd) 
46 {
47   cnvst->tx_2send=-1;
48   cnvst->rx_2rec=-1;            //wait for request for receiving
49   cnvst->tx_error=cnvst->rx_error=0;
50   cnvst->rx_wait4host=0;
51 #ifndef UL_WITHOUT_HANDLE 
52   cnvst->tx_fd=tx_fd;
53   cnvst->rx_fd=rx_fd;
54   cnvst->tx_tail=0;
55   cnvst->rx_tail=0;
56   cnvst->stamp_queue.head=cnvst->stamp_queue.stamps;
57   cnvst->stamp_queue.tail=cnvst->stamp_queue.head;
58 #endif
59
60   return 0;
61 }
62
63 int 
64 ul_dcnv_send(ul_dcnv_state_t XDATA *cnvst, unsigned char XDATA *buff, int size)
65 {
66  #ifndef UL_WITHOUT_HANDLE
67   ul_msginfo msginfo;
68  #endif /*UL_WITHOUT_HANDLE*/
69   int ret=0,stamp;
70
71   if (cnvst->tx_2send==-1) {
72     if(size<8) return 0;
73     cnvst->tx_2send =buff[6]+buff[7]*0x100;
74     msginfo.dadr=buff[0]&0x7F;  // dadr
75     msginfo.sadr=buff[1]&0x7F;  // sadr
76     msginfo.cmd =buff[2];       // cmd
77     msginfo.flg =cbfl_ps2ul(buff[3]); // flg zpravy
78     msginfo.flg |= UL_BFL_M2IN;
79     cnvst->tx_psstamp=buff[4];      // stamp
80     if(cnvst->tx_tail) {
81       msginfo.len=cnvst->tx_2send;
82       ret = ul_tailmsg(cnvst->tx_fd, &msginfo);
83     } else
84       ret = ul_newmsg(cnvst->tx_fd, &msginfo);
85     if(ret<0) {
86       cnvst->tx_error++;
87       return -1;
88     }
89     cnvst->tx_tail=msginfo.flg&UL_BFL_TAIL?1:0;
90     buff+=8;
91   } else {
92     if (cnvst->tx_2send>0) {
93       if(ul_write(cnvst->tx_fd, buff, size) != size){
94         cnvst->tx_error++;
95         ret=-1;
96       }
97       cnvst->tx_2send-=size;
98     }
99   }
100   if (cnvst->tx_2send<=0) {
101     cnvst->tx_2send=-1;
102     if(!cnvst->tx_tail){
103       stamp=ul_freemsg(cnvst->tx_fd);
104       if(stamp>=0){
105         cnvst->stamp_queue.head->ps=cnvst->tx_psstamp;
106         cnvst->stamp_queue.head->ul=stamp;
107         ps2ul_stamp_idx_inc(&cnvst->stamp_queue, &cnvst->stamp_queue.head);
108       }
109     }
110   }
111   return ret;
112 }
113
114 int 
115 ul_dcnv_rec(ul_dcnv_state_t XDATA *cnvst, unsigned char XDATA *buff, int size)
116 {
117   int ret;
118   if (cnvst->rx_2rec == -1) {
119     return 0;
120   } else {
121     if(size>cnvst->rx_2rec) size=cnvst->rx_2rec;
122     ret=ul_read(cnvst->rx_fd, buff, size);
123     if(ret!=size){
124       cnvst->rx_error++;
125       ret=-2;
126       cnvst->rx_2rec=-1;
127       ul_abortmsg(cnvst->rx_fd);
128     } else {
129       cnvst->rx_2rec-=size;
130       if(!cnvst->rx_2rec) {
131         cnvst->rx_2rec=-1;
132         if(!cnvst->rx_tail) {
133           ul_freemsg(cnvst->rx_fd);
134         }
135       }
136     }
137     return ret;
138   }
139 }
140
141 int 
142 ul_dcnv_rec_start(ul_dcnv_state_t XDATA *cnvst, unsigned char XDATA *buff, int size)
143 {
144   ul_msginfo msginfo;
145   int proc, psstamp, ret;
146   ps2ul_stamp_t *stamp_p;
147
148   
149   ul_inepoll(cnvst->tx_fd);
150
151   /* I can't call ul_acceptmsg during processing of a tx message (tail) - tx message will be freed */
152   if ((cnvst->tx_2send==-1) && (cnvst->tx_tail==0) &&
153       (ul_acceptmsg(cnvst->tx_fd, &msginfo)>=0)) { 
154     ul_freemsg(cnvst->tx_fd);
155   }
156
157   if (cnvst->rx_2rec==-1){
158     proc=0;
159     psstamp=0;
160     if (cnvst->rx_tail) {
161       ret=ul_actailmsg(cnvst->rx_fd, &msginfo);
162       psstamp=cnvst->rx_tail_stamp;
163       proc=1;
164     } else
165       ret=ul_acceptmsg(cnvst->rx_fd, &msginfo);
166     if (ret<0) return 0;
167     cnvst->rx_2rec=msginfo.len;
168     stamp_p=cnvst->stamp_queue.tail;
169     while(stamp_p!=cnvst->stamp_queue.head){
170       if(stamp_p->ul==msginfo.stamp){
171         psstamp=stamp_p->ps;
172         cnvst->rx_tail_stamp=psstamp;
173         if(!(msginfo.flg&UL_BFL_FAIL))
174           proc=1;
175         ps2ul_stamp_idx_inc(&cnvst->stamp_queue, &stamp_p);
176         cnvst->stamp_queue.tail=stamp_p;
177         break;
178       }
179       ps2ul_stamp_idx_inc(&cnvst->stamp_queue, &stamp_p);
180     }
181     if (proc && !(msginfo.flg&UL_BFL_REC))
182       cnvst->rx_2rec=0;
183     buff[0]=msginfo.dadr;      
184     buff[1]=msginfo.sadr;
185     buff[2]=msginfo.cmd;       
186     buff[3]=cbfl_ul2ps(msginfo.flg,proc);
187     buff[4]=psstamp;
188     buff[5]=0;
189     buff[6]=cnvst->rx_2rec%0x100;  
190     buff[7]=cnvst->rx_2rec/0x100;
191     if ((cnvst->rx_tail) || !(msginfo.flg&UL_BFL_TAIL) || (msginfo.flg&UL_BFL_FAIL)) {
192       cnvst->rx_tail=0;
193       if (cnvst->rx_2rec<=0) {
194         ul_freemsg(cnvst->rx_fd);
195         cnvst->rx_2rec=-1;    
196       }
197     } else 
198       cnvst->rx_tail=1;
199     buff+=8; size-=8;
200     return 8;
201   } else 
202     return 0;
203 }