]> rtime.felk.cvut.cz Git - lincan.git/blob - embedded/libs4c/usb/more/usb_com.c
Merge branch 'master' into can-usb1
[lincan.git] / embedded / libs4c / usb / more / usb_com.c
1 /*********************************************************/
2 /***   Module : USB communication                      ***/
3 /***   Author : Roman Bartosinski (bartosr@centrum.cz) ***/
4 /***   Modify : 14.01.2003                             ***/
5 /*********************************************************/
6
7 #include <cpu_def.h>
8 #include <system_def.h>
9 #include <stdio.h>
10 #include "pdiusb.h"
11 #include <h8s2633h.h>
12 /*#include <usb/usb_spec.h>*/
13 #include "usb_defs.h"
14 #include <usb/usb.h>
15 #include <usb/usb_com.h>
16
17
18 /* Queued USB Module */
19 typedef volatile struct{
20   unsigned char *first;
21   unsigned char *last;
22   unsigned char *begin;
23   unsigned char *end;
24 } usb_com_que_t;
25
26 #define USB_COM_BUF_LEN    80 //(80*8)
27
28 usb_com_que_t usb_com_que_in;   /* input queue */
29 unsigned char usb_com_buf_in[USB_COM_BUF_LEN];
30 usb_com_que_t usb_com_que_out;  /* output queue */
31 unsigned char usb_com_buf_out[USB_COM_BUF_LEN];
32
33 int usb_com_init( void);
34 int usb_com_put(usb_com_que_t *q, int c);
35 int usb_com_get(usb_com_que_t *q);
36
37 usb_vendor_extension_fnc_t *usb_vendor_extension=0;
38
39 #ifdef PDIUSB_WITH_ADD_IRQ_HANDLER
40 /* usb irq handler struct */
41 irq_handler_t usb_irq_handler;
42 #elif defined(PDIUSB_WITH_EXCPTVECT_SET)
43 void usb_isr(void) __attribute__ ((interrupt_handler));
44 #endif /*PDIUSB_WITH_EXCPTVECT_SET*/
45
46 int usb_irq_cnt;
47
48 /* common external function for pdiusb module */
49   void pdiSendCommand( unsigned char byCmd) {
50     writeb( byCmd, PDIUSB_COMMAND_ADDR);
51   }
52   unsigned char pdiReadData( unsigned char byCount, unsigned char *pbyData) {
53     unsigned char out = byCount;
54     
55     while (byCount--) {
56       *pbyData = readb( PDIUSB_READ_DATA_ADDR);
57       pbyData++;
58     }
59     
60     return out;
61   }
62   void pdiWriteData( unsigned char byCount, unsigned char *pbyData) {
63     while (byCount--) {
64       writeb( *pbyData++, PDIUSB_WRITE_DATA_ADDR);
65     }
66   }            
67   
68   
69 /* usb communication module */
70   /* data */
71   usb_flags_t usb_flags;  
72   unsigned char usb_address;
73   unsigned char usb_interface;
74   usb_control_ep_t usb_rxtx_control;
75   usb_bulk_ep_t usb_rx_bulk, usb_tx_bulk;
76   
77   volatile unsigned int usb_last_irq;
78   // internal buffer for data from/to control req. - must be global
79   unsigned char ctrl_data[PDI_EP0_PACKET_SIZE];
80                    
81   typeof(msec_time) usb_start = 0, usb_stop = 0;
82   
83
84     
85 /* functions */
86   int usb_run( void) {
87     int ret = 0;
88     if ( usb_flags.running) {
89 #ifdef USE_USB_WITH_IRQ
90       if (!usb_flags.bits.was_int) return ret;
91       usb_flags.was_int = 0;
92 #else
93       ret = usb_test_interrupt();
94       if ( usb_flags.request == 1) {
95         usb_answer_to_request();
96       }
97       if ( usb_flags.request == 2) { // request is set in  usb_answer_to_request()
98         if (( usb_rxtx_control.dreq.bmRequestType & USB_DATA_DIR_MASK)==USB_DATA_DIR_TO_HOST) {
99           unsigned int now = usb_rxtx_control.bytes;
100           if ( now > PDI_EP0_PACKET_SIZE) now = PDI_EP0_PACKET_SIZE;
101           if ( usb_rxtx_control.next_pkt_fnc )
102             if( usb_rxtx_control.next_pkt_fnc(&usb_rxtx_control, now, USB_NEXT_PKT_SEND) ) {
103               usb_stall_ep0();
104               return -1;
105             }
106           debugPrint( DBG_HIGH, ("CNTR send 1.data (%d)\n", now));
107           pdiWriteEndpoint( PDI_EP0_TX, now, usb_rxtx_control.data);
108           usb_rxtx_control.data += now;
109           if ( !(usb_rxtx_control.bytes -= now)) {
110             usb_flags.request = 3;
111           }
112         }
113       }
114       if ( usb_flags.request == 3) {
115         if ( !usb_rxtx_control.dreq.wLength ||
116              (usb_rxtx_control.dreq.bmRequestType & USB_DATA_DIR_MASK)==USB_DATA_DIR_FROM_HOST) {
117           pdiWriteEndpoint( PDI_EP0_TX, 0, 0);
118           if ( usb_rxtx_control.complete_fnc )
119             usb_rxtx_control.complete_fnc(&usb_rxtx_control, USB_COMPLETE_OK);
120           usb_rxtx_control.next_pkt_fnc = NULL;
121           usb_rxtx_control.complete_fnc = NULL;
122         }
123       }
124 #endif
125     }
126     return ret;
127   }  
128   
129   int usb_test_interrupt( void) { //_naked {
130     unsigned char usb_last_status;
131     int ret = 0;
132 //    INTERRUPT_PRE(0);
133 //    LEDr = 1;
134 //    EA=0;
135     usb_last_irq = pdiGetInterrupt();
136     if ( usb_last_irq) {
137       ret = 1;
138       debugPrint( DBG_MEDIUM, ("USB Interrupt 0x%X\n",usb_last_irq));
139       if ( usb_last_irq & PDI_INT_BUSRESET) {                  // D12 - Bus reset reached
140         usb_flags.configured = 0;
141         if ( usb_flags.running && usb_flags.stop_request) {
142           usb_flags.running = 0;
143           usb_flags.stop_request = 0;
144         }
145         debugPrint( DBG_HIGH, ("Bus Reset\n"));
146       } else {
147         if ( usb_last_irq & PDI_INT_SUSPEND) {            // D12 - Suspend flag changed
148           debugPrint( DBG_HIGH, ("Suspend Changed\n"));
149         }
150         // it must be first b/c tx and rx can be sended all together
151         if ( usb_last_irq & PDI_INT_EP0_IN) {                 // D12 - Ep0TxDone - data in EP0 was sended
152           usb_last_status = pdiGetLastTransStatus( PDI_EP0_TX);
153           debugPrint( DBG_HIGH, ("Ep0-Tx LTS=0x%X\n", usb_last_status));    
154           if (( usb_last_status & PDI_LTSTAT_RXTX_OK) && usb_flags.request > 1) {
155             if ( usb_flags.request == 2) {
156               unsigned int now = usb_rxtx_control.bytes;
157               if ( now > PDI_EP0_PACKET_SIZE) now = PDI_EP0_PACKET_SIZE;
158
159               if ( usb_rxtx_control.next_pkt_fnc )
160                 if( usb_rxtx_control.next_pkt_fnc(&usb_rxtx_control, now, USB_NEXT_PKT_SEND) ) {
161                   usb_stall_ep0();
162                   return -1;
163                 }
164
165               debugPrint( DBG_HIGH, ("CNTR data\n"));
166               pdiWriteEndpoint( PDI_EP0_TX, now, usb_rxtx_control.data);
167               usb_rxtx_control.data += now;
168               if ( !(usb_rxtx_control.bytes -= now)) {
169                 usb_flags.request = 3;
170               }
171             } else if ( usb_flags.request == 3) {
172               debugPrint( DBG_HIGH, ("CNTR ack\n"));
173               usb_flags.request = 0;
174               
175               if ( usb_rxtx_control.complete_fnc )
176                 usb_rxtx_control.complete_fnc(&usb_rxtx_control, USB_COMPLETE_OK);
177               usb_rxtx_control.next_pkt_fnc = NULL;
178               usb_rxtx_control.complete_fnc = NULL;
179               
180             } else {
181               debugPrint( DBG_LOW, ("tx ... ???\n"));
182             }
183           }
184         }
185         
186         if ( usb_last_irq & PDI_INT_EP0_OUT) {                // D12 - Ep0RxDone - some data was received in EP0
187           usb_last_status = pdiGetLastTransStatus( PDI_EP0_RX);
188           debugPrint( DBG_HIGH, ("Ep0-Rx LTS=0x%X\n", usb_last_status));
189           if ( usb_last_status & PDI_LTSTAT_RXTX_OK) {
190             if ( usb_last_status & PDI_LTSTAT_SETUP) {
191               if ( usb_flags.request) {
192                 debugPrint( DBG_HIGH, ("!!! New setup, but last not ack ...\n"));
193               }
194               usb_flags.request = 1; // Standard_requests();
195               if ( usb_rxtx_control.complete_fnc )
196                 usb_rxtx_control.complete_fnc(&usb_rxtx_control, USB_COMPLETE_FAIL);
197               usb_rxtx_control.next_pkt_fnc = NULL;
198               usb_rxtx_control.complete_fnc = NULL;
199             } else {
200               if ( usb_flags.request == 2) {
201                 unsigned int now = usb_rxtx_control.bytes;
202                 if ( now > PDI_EP0_PACKET_SIZE) now = PDI_EP0_PACKET_SIZE;
203                 debugPrint( DBG_HIGH, ("CNTR data\n"));
204                 ret = pdiReadEndpoint( PDI_EP0_RX, now, usb_rxtx_control.data);
205                 
206                 if(ret>usb_rxtx_control.bytes)
207                   ret = usb_rxtx_control.bytes;
208                 
209                 usb_rxtx_control.data += ret;
210                 
211                 if ( usb_rxtx_control.next_pkt_fnc ) {
212                   if( usb_rxtx_control.next_pkt_fnc(&usb_rxtx_control, ret, USB_NEXT_PKT_REC) ) {
213                     usb_stall_ep0();
214                     return -1;
215                   }
216                 }
217                 
218                 if (!(usb_rxtx_control.bytes -= ret)) {
219                   usb_rxtx_control.data -= usb_rxtx_control.dreq.wLength;
220                   usb_flags.request = 3;
221                 }
222               } else if ( usb_flags.request == 3) {
223                 debugPrint( DBG_HIGH, ("CNTR ack\n"));
224                 usb_flags.request = 0;
225                 pdiReadEndpoint( PDI_EP0_RX, 0, 0);
226                 if ( usb_rxtx_control.complete_fnc )
227                   usb_rxtx_control.complete_fnc(&usb_rxtx_control, USB_COMPLETE_OK);
228                 usb_rxtx_control.next_pkt_fnc = NULL;
229                 usb_rxtx_control.complete_fnc = NULL;
230               } else {
231                 pdiReadEndpoint( PDI_EP0_RX, 0, 0);
232               }
233             }
234           }
235         }
236         if ( usb_last_irq & PDI_INT_EP1_OUT) {                // D12 - Ep1RxDone - some data was received in EP1
237           usb_last_status = pdiGetLastTransStatus( PDI_EP1_RX);
238           debugPrint( DBG_HIGH, ("Ep1-Rx LTS=0x%X\n", usb_last_status));
239           if ( usb_last_status & PDI_LTSTAT_RXTX_OK) {
240             pdiSetEpStatus( PDI_EP1_OUT, PDI_SET_EP_STALLED);
241           }
242         }
243         if ( usb_last_irq & PDI_INT_EP1_IN) {                 // D12 - Ep1TxDone - data in EP1 was sended
244           usb_last_status = pdiGetLastTransStatus( PDI_EP1_TX);
245           debugPrint( DBG_HIGH, ("Ep1-Tx LTS=0x%X\n", usb_last_status));
246           if ( usb_last_status & PDI_LTSTAT_RXTX_OK) {
247             pdiSetEpStatus( PDI_EP1_IN, PDI_SET_EP_STALLED);
248           }
249         }
250
251         if ( usb_last_irq & PDI_INT_EP2_OUT) {                // D12 - Ep2RxDone - some data was received in EP2
252           usb_last_status = pdiGetLastTransStatus( PDI_EP2_RX);
253           debugPrint( DBG_HIGH, ("Ep2-Rx LTS=0x%X\n", usb_last_status));
254           if ( usb_last_status & PDI_LTSTAT_RXTX_OK) {            
255             if ( usb_flags.terminal_mode) {
256               unsigned char hlpbfr[PDI_EP2_PACKET_SIZE], now = PDI_EP2_PACKET_SIZE, i;
257             MoreRead:
258               now = pdiReadEndpoint( PDI_EP2_RX, now, hlpbfr);
259               for(i=0;i<now;i++) {
260                 usb_tm_rcv++;
261                 if (usb_com_put( &usb_com_que_in, hlpbfr[i])<0) { /* nevkladat dalsi */
262                   break;
263                 }
264               }
265               if(now==PDI_EP2_PACKET_SIZE) goto MoreRead;              
266             } else {
267               unsigned long now = usb_rx_bulk.remain;
268               if ( now > PDI_EP2_PACKET_SIZE) now = PDI_EP2_PACKET_SIZE;
269   
270               if ( !usb_flags.bits.bulk_rx_data) {
271                 usb_flags.bulk_rx_data = 1;
272                 usb_start = msec_time;
273               }
274   
275               ReadAgain:
276                 ret = pdiReadEndpoint( PDI_EP2_RX, now, usb_rx_bulk.data);
277                 usb_rx_bulk.data += now;
278                 if ( !( usb_rx_bulk.remain -= now)) {
279                   //usb_rx_bulk.data -= usb_rx_bulk.bytes; /* read again */
280                   usb_stop = msec_time;              
281                   usb_flags.bulk_rx_data = 0;
282                 // complete_func or set flag(event)
283                 }
284               if ( usb_rx_bulk.remain > 0 && usb_rx_bulk.remain <= PDI_EP2_PACKET_SIZE) 
285                 goto ReadAgain;
286             }
287           }
288         }
289         if ( usb_last_irq & PDI_INT_EP2_IN) {                 // D12 - Ep2TxDone - data in EP2 was sended
290           usb_last_status = pdiGetLastTransStatus( PDI_EP2_TX);
291           debugPrint( DBG_HIGH, ("Ep2-Tx LTS=0x%X\n", usb_last_status));
292           if ( usb_last_status & PDI_LTSTAT_RXTX_OK) {
293             if ( usb_flags.terminal_mode) {
294               int ch = usb_com_get( &usb_com_que_out);
295               usb_tm_snded++;
296               if ( ch < 0) {
297                 usb_flags.bulk_tx_data = 0;                
298               } else {
299                 unsigned char uchr = ch;
300                 usb_flags.bulk_tx_data = 1;
301                 pdiWriteEndpoint( PDI_EP2_TX, 1, &uchr);
302               }
303             } else {
304               if ( usb_tx_bulk.remain) {
305                 unsigned int now = usb_tx_bulk.remain;
306                 if ( now > PDI_EP2_PACKET_SIZE) now = PDI_EP2_PACKET_SIZE;
307                 pdiWriteEndpoint( PDI_EP2_TX, now, usb_tx_bulk.data);
308                 usb_tx_bulk.data += now;
309                 if (!(usb_tx_bulk.remain -= now)) {
310                   // complete_func or set flag(event)
311                 }
312               }
313             }
314           }
315         }
316         ret = 0;
317       }
318     }
319 //    EA=1;
320 //    LEDr = 0;
321 //    INTERRUPT_POST();
322    return ret;
323   }
324
325
326 // ************************************
327   void usb_init( void) {
328     usb_last_irq = 0; usb_address = 0; usb_interface = 0;
329     usb_flags.word = 0;
330     
331     usb_com_init();
332
333 #ifdef USE_USB_WITH_IRQ
334     usb_irq_cnt=0;
335    #ifdef PDIUSB_WITH_ADD_IRQ_HANDLER
336     if( test_irq_handler( ISR_USB_INTV, &usb_irq_handler)==0)
337       add_irq_handler( ISR_USB_INTV, &usb_irq_handler);
338    #elif defined(PDIUSB_WITH_EXCPTVECT_SET)
339     excptvec_set(ISR_USB_INTV,&usb_isr);
340    #endif /*PDIUSB_WITH_ADD_IRQ_HANDLER*/
341     //*((char*)0xfffa1f) |= 0x04; /* It must be here for pull-up INT signal in usb_isr function */
342 #endif    
343     debugPrint(DBG_MEDIUM,("# Usb Inited\n"));    
344   }
345
346   void usb_connect_bus( void) {
347     debugPrint(DBG_MEDIUM,("Usb connect to bus\n"));
348     usb_flags.running = 1;
349     usb_last_irq = 0;
350     pdiSetDMA( PDI_DMA_EP4_INT | PDI_DMA_EP5_INT); // ???
351     pdiSetMode( PDI_MODE_NO_LAZY_CLOCK | PDI_MODE_CLOCK_RUNNING | PDI_MODE_SOFT_CONNECT | PDI_CLOCK_SET_TO_ONE | PDI_CLOCK_4M);
352   }
353   void usb_disconnect_bus( void) {
354     debugPrint(DBG_MEDIUM,("Usb disconnect from bus\n"));
355     pdiSetMode( PDI_MODE_NO_LAZY_CLOCK | PDI_MODE_CLOCK_RUNNING | PDI_CLOCK_SET_TO_ONE | PDI_CLOCK_4M);
356     usb_flags.configured = 0;
357     usb_flags.stop_request = 1;
358   }
359
360   void usb_stall_ep0( void) {
361     pdiSetEpStatus( PDI_EP0_TX, PDI_SET_EP_STALLED); pdiSetEpStatus( PDI_EP0_RX, PDI_SET_EP_STALLED);
362   }
363   
364
365 // ************************************
366 // ***   Common send/receive fncs   ***
367 // ************************************
368 /*
369   void usb_send_to_usb( unsigned char idx, unsigned char maxb) {
370     debugPrint( DBG_HIGH,("USB Send EP#%d (max=%d) <- buff 0x%lX, cnt %d\n",usb_ep[idx].ep, maxb, (unsigned long)usb_ep[idx].buff,usb_ep[idx].bytes));
371     if ( !usb_ep[idx].bytes) pdiWriteEndpoint( usb_ep[idx].ep, 0, 0);
372     else {
373       if ( usb_ep[idx].bytes > maxb) {
374         pdiWriteEndpoint( usb_ep[idx].ep, maxb, usb_ep[idx].buff);
375         usb_ep[idx].bytes -= maxb;
376         usb_ep[idx].buff += maxb;
377       } else {
378         pdiWriteEndpoint( usb_ep[idx].ep, usb_ep[idx].bytes, usb_ep[idx].buff);
379         usb_ep[idx].buff += usb_ep[idx].bytes;
380         usb_ep[idx].bytes = 0;
381 //        if ( usending) usending = 0;
382       }
383     }
384   }
385
386   unsigned char usb_receive_from_usb( unsigned char idx, unsigned char maxb) {
387     unsigned char ret = 0;
388
389     ret = (unsigned char)usb_ep[idx].bytes;
390     if ( !ret || ret > maxb) ret = maxb;
391     debugPrint( DBG_HIGH,("USB Receive EP#%d ->buff 0x%lX,cnt %d,(max %d)\n",usb_ep[idx].ep,(unsigned long)usb_ep[idx].buff,usb_ep[idx].bytes,ret));
392     if ( !usb_ep[idx].bytes) {
393 //      ureceiving = 0;
394       pdiReadEndpoint( usb_ep[idx].ep, 0, 0);
395       return 0xff; // too_small_buffer error
396     }
397     do {
398       ret = pdiReadEndpoint( usb_ep[idx].ep, ret, usb_ep[idx].buff);
399       debugPrint( DBG_HIGH,(" - really readed %d\n", ret));
400       usb_ep[idx].buff += ret;
401       usb_ep[idx].bytes -= ret;
402     } while (( ret == maxb) && usb_ep[idx].bytes);
403     return ret;
404   }
405 */
406
407
408 #ifdef DEBUG
409   char *ReqRecipient( char rqt) {
410     switch ( rqt & USB_RECIPIENT) {
411       case USB_RECIPIENT_DEVICE:    return "DEVICE";
412       case USB_RECIPIENT_INTERFACE: return "INTERFACE";
413       case USB_RECIPIENT_ENDPOINT:  return "ENDPOINT";
414     }
415     return "OTHER";
416   }
417   char *ReqType( char rqt) {
418     switch ( rqt & USB_REQUEST_TYPE_MASK) {
419       case USB_STANDARD_REQUEST: return "STANDARD";
420       case USB_CLASS_REQUEST:    return "CLASS";
421       case USB_VENDOR_REQUEST:   return "VENDOR";
422     }
423     return "RESERVED";
424   }
425   char *ReqName( char req) {
426     switch ( req & USB_REQUEST_MASK) {
427       case USB_REQUEST_GET_STATUS:        return "GET STATUS";
428       case USB_REQUEST_CLEAR_FEATURE:     return "CLEAR FEATURE";
429       case USB_REQUEST_SET_FEATURE:       return "SET FEATURE";
430       case USB_REQUEST_SET_ADDRESS:       return "SET ADDRESS";
431       case USB_REQUEST_GET_DESCRIPTOR:    return "GET DESCRIPTOR";
432       case USB_REQUEST_SET_DESCRIPTOR:    return "SET DESCRIPTOR";
433       case USB_REQUEST_GET_CONFIGURATION: return "GET CONFIGURATION";
434       case USB_REQUEST_SET_CONFIGURATION: return "SET CONFIGURATION";
435       case USB_REQUEST_GET_INTERFACE:     return "GET INTERFACE";
436       case USB_REQUEST_SET_INTERFACE:     return "SET INTERFACE";
437       case USB_REQUEST_SYNC_FRAME:        return "SYNC FRAME";
438     }
439     return "UNKNOWN";
440   }
441 #endif
442
443
444   void usb_set_control_data(usb_control_ep_t *ep, void *buff, int size)
445   {
446     ep->data = (unsigned char *) buff;
447     ep->bytes = size;
448     usb_flags.request = 2;
449     debugPrint( DBG_HIGH,("usb_set_control_data buff=0x%lx, len=%d\n", (long)buff, size));
450   }
451
452   void usb_set_control_ack(usb_control_ep_t *ep)
453   {
454     ep->data = NULL;
455     ep->bytes = 0;
456     usb_flags.request = 3;
457     debugPrint( DBG_HIGH,("usb_set_control_ack\n"));
458   }
459   
460
461  /*
462   ***********************************
463   ***   Execute device requests   ***
464   ***********************************
465   */
466   void usb_answer_to_request( void) {
467     USB_DEVICE_REQUEST *pdreq = &usb_rxtx_control.dreq;
468     
469     debugPrint( DBG_MEDIUM,("Process usb setup packet\n"));
470     usb_rxtx_control.req_size=pdiReadEndpoint( PDI_EP0_RX, 255, (unsigned char *)pdreq);
471     if ( usb_rxtx_control.req_size == 0xff) {
472       /*LEDr = 1; SetLeds( hlp[0]);*/
473       debugPrint( DBG_LOW,("! BIG Setup packet\n"));
474       usb_stall_ep0();
475       return;
476     }
477     pdiAckSetupControl();
478     /* !!! it must be here !!! */
479     pdreq->wValue = SWAP( pdreq->wValue);
480     pdreq->wIndex = SWAP( pdreq->wIndex);
481     pdreq->wLength = SWAP( pdreq->wLength);
482
483     usb_rxtx_control.next_pkt_fnc = NULL;
484     usb_rxtx_control.complete_fnc = NULL;
485
486     ctrl_data[0] = ctrl_data[1] = 0; // we need only 2 bytes
487
488     #ifdef DEBUG
489       debugPrint( DBG_HIGH, ("Receive (0x%X) %s req. for %s , data %s host\n", 
490                   pdreq->bmRequestType, ReqType( pdreq->bmRequestType), 
491                   ReqRecipient(pdreq->bmRequestType),
492                   ((pdreq->bmRequestType & USB_DATA_DIR_MASK) ? "TO":"FROM")));
493       debugPrint( DBG_HIGH, ("   Request (0x%X) %s\n", pdreq->bRequest, 
494                   ((!(pdreq->bmRequestType&USB_REQUEST_TYPE_MASK))? ReqName( pdreq->bRequest):"UNKNOWN")));
495     #endif
496     
497     switch( pdreq->bmRequestType & USB_RECIPIENT) {
498       case USB_RECIPIENT_DEVICE:
499         switch( pdreq->bmRequestType & USB_REQUEST_TYPE_MASK) {
500           case USB_STANDARD_REQUEST:
501             switch( pdreq->bRequest) {
502               case USB_REQUEST_GET_STATUS:
503                 #ifdef USB_MY_SELF_POWER 
504                   ctrl_data[0]=1;
505                 #else 
506                   ctrl_data[0]=0;
507                 #endif
508                 USB_SET_CONTROL_DATA( &ctrl_data, 2);
509                 //pdiWriteEndpoint( PDI_EP0_TX, 2, hlp);
510                 break;
511               case USB_REQUEST_SET_ADDRESS:
512                 usb_address = ( unsigned char)( pdreq->wValue & DEVICE_ADDRESS_MASK);
513                 pdiSetAddressEnable( usb_address | PDI_ENAD_ENABLE);
514                 USB_SET_CONTROL_ACK;
515                 //pdiWriteEndpoint( PDI_EP0_TX, 0, 0);
516                 break;
517               case USB_REQUEST_GET_DESCRIPTOR:
518                 usb_get_descriptor();
519                 break;
520               case USB_REQUEST_GET_CONFIGURATION:
521                 if ( usb_flags.configured) ctrl_data[0] = 1;
522                 USB_SET_CONTROL_DATA( &ctrl_data, 1);
523                 //pdiWriteEndpoint( PDI_EP0_TX, 1, hlp);
524                 break;
525               case USB_REQUEST_SET_CONFIGURATION:
526                 if (LSB( pdreq->wValue) < 2) {
527                   if ( LSB( pdreq->wValue)) {
528                     pdiSetEndpointEnable( usb_flags.configured=1);
529                   } else {
530                     pdiSetEndpointEnable( usb_flags.configured=0);
531                   }
532                   USB_SET_CONTROL_ACK;
533                   //pdiWriteEndpoint( PDI_EP0_TX, 0, 0);
534                 } else
535                   usb_stall_ep0();
536                 break;                
537               default:
538                 usb_stall_ep0();
539                 break;
540             }
541
542             break;
543           case USB_VENDOR_REQUEST:
544             if(usb_vendor_extension) {
545               int ret;
546               ret = usb_vendor_extension(&usb_rxtx_control, pdreq);
547               if (ret<0) {
548                 usb_stall_ep0();
549                 break;
550               }
551               if (ret>0) {
552                 break;
553               }
554             }
555           
556             switch ( pdreq->bRequest) {
557               case USB_VENDOR_START_TRANSFER:
558                 {
559                   unsigned long max = ((long)pdreq->wIndex << 16)+pdreq->wValue;
560                   usb_rx_bulk.remain = ( usb_rx_bulk.bytes < max) ? usb_rx_bulk.bytes : max;
561                 }
562                 USB_SET_CONTROL_ACK;
563                 break;
564               case USB_VENDOR_CONTROL_TERMINAL_MODE:
565                 if ( pdreq->wValue == 1) usb_flags.terminal_mode = 1;
566                 else usb_flags.terminal_mode = 0;
567                 USB_SET_CONTROL_ACK;
568                 break;
569               default:
570                 USB_SET_CONTROL_ACK;
571                 //pdiWriteEndpoint( PDI_EP0_TX, 0, 0);
572                 break;
573             }            
574             break;            
575           case USB_CLASS_REQUEST:
576             usb_stall_ep0();
577           default:
578             usb_stall_ep0();
579             break;
580         }
581         break;
582       case USB_RECIPIENT_INTERFACE:
583         if (( pdreq->bmRequestType & USB_REQUEST_TYPE_MASK) == USB_STANDARD_REQUEST) {
584           switch( pdreq->bRequest) {
585             case USB_REQUEST_GET_STATUS:
586               USB_SET_CONTROL_DATA( &ctrl_data, 2);
587               //pdiWriteEndpoint( PDI_EP0_TX, 2, hlp);
588               break;
589             case USB_REQUEST_GET_INTERFACE:
590               debugPrint( DBG_HIGH,("ReqIfc=%d Now ifc=%d\n", pdreq->wIndex, usb_interface));
591               USB_SET_CONTROL_DATA( &ctrl_data, 1); // alternate interface
592               //pdiWriteEndpoint( PDI_EP0_TX, 1, hlp);
593               break;
594             case USB_REQUEST_SET_INTERFACE:
595               //if (( dreq.wValue == 0) && ( dreq.wIndex == 0))
596               if ( pdreq->wIndex < 1) { // mame jen 2 pokusne interface
597                 usb_interface = (unsigned char) pdreq->wIndex;
598                 USB_SET_CONTROL_ACK;
599                 //pdiWriteEndpoint( PDI_EP0_TX, 0, 0);
600               } else
601                 usb_stall_ep0();
602               break;
603             default:
604               usb_stall_ep0();                          
605           }
606         } else
607           usb_stall_ep0();
608         break;
609       case USB_RECIPIENT_ENDPOINT:
610         if (( pdreq->bmRequestType & USB_REQUEST_TYPE_MASK) == USB_STANDARD_REQUEST) {
611           switch( pdreq->bRequest) {
612             case USB_REQUEST_GET_STATUS:
613             case USB_REQUEST_CLEAR_FEATURE:
614             case USB_REQUEST_SET_FEATURE:
615               {
616                 ctrl_data[0] = ( unsigned char)(( pdreq->wIndex & PDI_CNT_EP)<<1);
617                 if ( pdreq->wIndex & ( unsigned char) USB_ENDPOINT_DIRECTION_MASK)
618                   ctrl_data[0]++;
619                 if ( pdreq->bRequest == USB_REQUEST_GET_STATUS) {
620                   ctrl_data[0] = pdiSelectEp( ctrl_data[0]); // endpoint in
621                   ctrl_data[0] = (( ctrl_data[0] & PDI_SELEP_STALL) == PDI_SELEP_STALL);
622                   USB_SET_CONTROL_DATA( &ctrl_data, 2);
623                   //pdiWriteEndpoint( PDI_EP0_TX, 2, hlp);
624                 } else {
625                   if ( pdreq->bRequest == USB_REQUEST_CLEAR_FEATURE) {
626                     pdiSetEpStatus( ctrl_data[0], 0);
627                     //pdiWriteEndpoint( PDI_EP0_TX, 0, 0);
628                   } else {
629                     pdiSetEpStatus( ctrl_data[0], 1);
630                     //pdiWriteEndpoint( PDI_EP0_TX, 0, 0);
631                   }
632                   USB_SET_CONTROL_ACK;
633                 }
634               }
635               break;
636             default:
637               usb_stall_ep0();
638           }
639         } else 
640           usb_stall_ep0();
641         break;
642 //      case USB_RECIPIENT_OTHER:
643       default:
644         usb_stall_ep0();
645         break;
646     }
647 //    usb_flags.command = 0; // ??? data or ack stage ???
648
649 #ifdef USE_USB_WITH_IRQ
650 // send data if it is needed
651       if ( usb_flags.request == 2) { // request is set to data stage
652         if (( usb_rxtx_control.dreq.bmRequestType & USB_DATA_DIR_MASK)==USB_DATA_DIR_TO_HOST) {
653           unsigned int now = usb_rxtx_control.bytes;
654           if ( now > PDI_EP0_PACKET_SIZE) now = PDI_EP0_PACKET_SIZE;
655           if ( usb_rxtx_control.next_pkt_fnc )
656             if( usb_rxtx_control.next_pkt_fnc(&usb_rxtx_control, now, USB_NEXT_PKT_SEND) ) {
657               usb_stall_ep0();
658               return;
659             }
660           debugPrint( DBG_HIGH, ("CNTR send 1.data (%d)\n", now));
661           pdiWriteEndpoint( PDI_EP0_TX, now, usb_rxtx_control.data);
662           usb_rxtx_control.data += now;
663           if ( !(usb_rxtx_control.bytes -= now)) {
664             usb_flags.request = 3;
665           }
666         }
667       }
668       if ( usb_flags.request == 3) {
669         if ( !usb_rxtx_control.dreq.wLength ||
670              (usb_rxtx_control.dreq.bmRequestType & USB_DATA_DIR_MASK)==USB_DATA_DIR_FROM_HOST) {
671           pdiWriteEndpoint( PDI_EP0_TX, 0, 0);
672           if ( usb_rxtx_control.complete_fnc )
673             usb_rxtx_control.complete_fnc(&usb_rxtx_control, USB_COMPLETE_OK);
674           usb_rxtx_control.next_pkt_fnc = NULL;
675           usb_rxtx_control.complete_fnc = NULL;
676         }
677       }
678 #endif
679   }
680
681 #ifdef DEBUG
682   char *DescType( unsigned char desc) {
683     switch ( desc) {
684       case USB_DESCRIPTOR_TYPE_DEVICE:                    return"DEVICE";
685       case USB_DESCRIPTOR_TYPE_CONFIGURATION:             return"CONFIGURATION";
686       case USB_DESCRIPTOR_TYPE_STRING:                    return"STRING";
687       case USB_DESCRIPTOR_TYPE_INTERFACE:                 return"INTERFACE";
688       case USB_DESCRIPTOR_TYPE_ENDPOINT:                  return"ENDPOINT";
689       case USB_DESCRIPTOR_TYPE_DEVICE_QUALIFIER:          return"DEVICE_QUALIFIER";
690       case USB_DESCRIPTOR_TYPE_OTHER_SPEED_CONFIGURATION: return"OTHER_SPEED_CONFIG";
691       case USB_DESCRIPTOR_TYPE_POWER:                     return"POWER";
692     }
693     return "UNKNOWN";
694   }
695 #endif
696
697   void usb_get_descriptor( void) {
698     unsigned int size;
699     unsigned short wVal = usb_rxtx_control.dreq.wValue;
700     debugPrint( DBG_MEDIUM, (" - %s descriptor\n", DescType(MSB( wVal))));
701     switch ( MSB( wVal)) {
702       case USB_DESCRIPTOR_TYPE_DEVICE:
703         usb_rxtx_control.data = (unsigned char *) &usb_device_descriptor;
704         size = sizeof( USB_DEVICE_DESCRIPTOR);
705         break;
706       case USB_DESCRIPTOR_TYPE_CONFIGURATION:
707         usb_rxtx_control.data  = (unsigned char *) &usb_config_0;
708         size = CONFIG_0_DESCRIPTOR_LENGTH;
709         break;
710       case USB_DESCRIPTOR_TYPE_STRING:
711         if ( LSB( wVal) < USB_CNT_STRINGS) {
712           usb_rxtx_control.data  = (unsigned char *) StringDescriptors[ LSB( wVal)];
713           size = *usb_rxtx_control.data;
714         } else {
715           usb_stall_ep0();
716           return;
717         }
718         break;
719       default:
720         usb_stall_ep0();
721         return;
722     }    
723     usb_rxtx_control.bytes = ( usb_rxtx_control.dreq.wLength < size) ? usb_rxtx_control.dreq.wLength : size;
724     usb_flags.request = 2;
725     //usb_send_to_usb( SEND_EP0, PDI_EP0_PACKET_SIZE);
726   }
727
728
729 /*****************************************************************************/
730 /*****************************************************************************/
731 /*****************************************************************************/
732 /***                                                                       ***/
733 /*** USB with IRQ                                                          ***/
734 /***                                                                       ***/
735 /*****************************************************************************/
736 /*****************************************************************************/
737 /*****************************************************************************/
738
739  #ifdef PDIUSB_WITH_EXCPTVECT_SET
740   void usb_isr(void)
741  #else /*PDIUSB_WITH_EXCPTVECT_SET*/
742   void usb_isr(int intno, void *dev_id, struct pt_regs *regs)
743  #endif /*PDIUSB_WITH_EXCPTVECT_SET*/
744   {
745     unsigned char usb_last_status;
746     
747     usb_irq_cnt++;    
748     usb_last_irq = pdiGetInterrupt();
749     if ( usb_last_irq) {
750       usb_flags.was_int = 1;
751       
752       debugPrint( DBG_INT, ("USB Interrupt 0x%X\n",usb_last_irq));
753       if ( usb_last_irq & PDI_INT_BUSRESET) {                  // D12 - Bus reset reached
754         usb_flags.configured = 0;
755         if ( usb_flags.running && usb_flags.stop_request) {
756           usb_flags.running = 0;
757           usb_flags.stop_request = 0;
758         }
759         debugPrint( DBG_INT, ("Bus Reset\n"));
760       } else {
761         if ( usb_last_irq & PDI_INT_SUSPEND) {            // D12 - Suspend flag changed
762           debugPrint( DBG_INT, ("Suspend Changed\n"));
763         }
764         // it must be first b/c tx and rx can be sended all together
765         if ( usb_last_irq & PDI_INT_EP0_IN) {                 // D12 - Ep0TxDone - data in EP0 was sended
766           usb_last_status = pdiGetLastTransStatus( PDI_EP0_TX);
767           debugPrint( DBG_INT, ("Ep0-Tx LTS=0x%X\n", usb_last_status));    
768           if (( usb_last_status & PDI_LTSTAT_RXTX_OK) && usb_flags.request > 1) {
769             if ( usb_flags.request == 2) {
770               unsigned int now = usb_rxtx_control.bytes;
771               if ( now > PDI_EP0_PACKET_SIZE) now = PDI_EP0_PACKET_SIZE;
772               debugPrint( DBG_INT, ("CNTR data\n"));
773               pdiWriteEndpoint( PDI_EP0_TX, now, usb_rxtx_control.data);
774               usb_rxtx_control.data += now;
775               if ( !(usb_rxtx_control.bytes -= now)) {
776                 usb_flags.request = 3;
777               }
778             } else if ( usb_flags.request == 3) {
779               debugPrint( DBG_INT, ("CNTR ack\n"));
780               usb_flags.request = 0;
781             } else {
782               debugPrint( DBG_INT, ("tx 0 ... ???\n"));
783             }
784           }
785         }
786         
787         if ( usb_last_irq & PDI_INT_EP0_OUT) {                // D12 - Ep0RxDone - some data was received in EP0
788           usb_last_status = pdiGetLastTransStatus( PDI_EP0_RX);
789           debugPrint( DBG_INT, ("Ep0-Rx LTS=0x%X\n", usb_last_status));
790           if ( usb_last_status & PDI_LTSTAT_RXTX_OK) {
791             if ( usb_last_status & PDI_LTSTAT_SETUP) {
792               if ( usb_flags.request) {
793                 debugPrint( DBG_INT, ("!!! New setup, but last not ack ...\n"));
794               }
795               usb_flags.request = 1; // Standard_requests();
796               usb_answer_to_request();
797             } else {
798               if ( usb_flags.request == 2) {
799                 unsigned int now = usb_rxtx_control.bytes, ret;
800                 if ( now > PDI_EP0_PACKET_SIZE) now = PDI_EP0_PACKET_SIZE;
801                 debugPrint( DBG_INT, ("CNTR data\n"));
802                 ret = pdiReadEndpoint( PDI_EP0_RX, now, usb_rxtx_control.data);
803
804                 if(ret>usb_rxtx_control.bytes)
805                   ret = usb_rxtx_control.bytes;
806
807                 usb_rxtx_control.data += ret;
808
809                 if ( usb_rxtx_control.next_pkt_fnc ) {
810                   if( usb_rxtx_control.next_pkt_fnc(&usb_rxtx_control, ret, USB_NEXT_PKT_REC) ) {
811                     usb_stall_ep0();
812                   }
813                 }
814
815                 if (!(usb_rxtx_control.bytes -= ret)) {
816                   usb_rxtx_control.data -= usb_rxtx_control.dreq.wLength;
817                   usb_flags.request = 3;
818                 }
819               } else if ( usb_flags.request == 3) {
820                 debugPrint( DBG_INT, ("CNTR ack\n"));
821                 usb_flags.request = 0;
822                 pdiReadEndpoint( PDI_EP0_RX, 0, 0);
823                 if ( usb_rxtx_control.complete_fnc )
824                   usb_rxtx_control.complete_fnc(&usb_rxtx_control, USB_COMPLETE_OK);
825                 usb_rxtx_control.next_pkt_fnc = NULL;
826                 usb_rxtx_control.complete_fnc = NULL;
827               } else {
828                 pdiReadEndpoint( PDI_EP0_RX, 0, 0);
829               }
830             }
831           }
832         }
833         if ( usb_last_irq & PDI_INT_EP1_OUT) {                // D12 - Ep1RxDone - some data was received in EP1
834           usb_last_status = pdiGetLastTransStatus( PDI_EP1_RX);
835           debugPrint( DBG_INT, ("Ep1-Rx LTS=0x%X\n", usb_last_status));
836           if ( usb_last_status & PDI_LTSTAT_RXTX_OK) {
837             pdiSetEpStatus( PDI_EP1_OUT, PDI_SET_EP_STALLED);
838           }
839         }
840         if ( usb_last_irq & PDI_INT_EP1_IN) {                 // D12 - Ep1TxDone - data in EP1 was sended
841           usb_last_status = pdiGetLastTransStatus( PDI_EP1_TX);
842           debugPrint( DBG_INT, ("Ep1-Tx LTS=0x%X\n", usb_last_status));
843           if ( usb_last_status & PDI_LTSTAT_RXTX_OK) {
844             pdiSetEpStatus( PDI_EP1_IN, PDI_SET_EP_STALLED);
845           }
846         }
847
848         if ( usb_last_irq & PDI_INT_EP2_OUT) {                // D12 - Ep2RxDone - some data was received in EP2
849           usb_last_status = pdiGetLastTransStatus( PDI_EP2_RX);
850           debugPrint( DBG_INT, ("Ep2-Rx LTS=0x%X\n", usb_last_status));
851           if ( usb_last_status & PDI_LTSTAT_RXTX_OK) {
852             if ( usb_flags.terminal_mode) {
853               unsigned char hlpbfr[PDI_EP2_PACKET_SIZE], now = PDI_EP2_PACKET_SIZE, i;
854             MoreRead:
855               now = pdiReadEndpoint( PDI_EP2_RX, now, hlpbfr);
856               for(i=0;i<now;i++) {
857                 usb_tm_rcv++;
858                 if (usb_com_put( &usb_com_que_in, hlpbfr[i])<0) { /* nevkladat dalsi */
859                   break;
860                 }
861               }
862               if(now==PDI_EP2_PACKET_SIZE) goto MoreRead;              
863             } else {
864               unsigned char now = (usb_rx_bulk.remain > (unsigned long)PDI_EP2_PACKET_SIZE)?PDI_EP2_PACKET_SIZE:(unsigned char)usb_rx_bulk.remain;
865   //            unsigned char hlp[2];            
866                 
867                 if ( !usb_flags.bits.bulk_rx_data) {
868                   usb_flags.bulk_rx_data = 1;
869                   usb_start = msec_time;
870                 }
871   //              if ( now > PDI_EP2_PACKET_SIZE) now = PDI_EP2_PACKET_SIZE;
872               ReadAgain:
873                 now = pdiReadEndpoint( PDI_EP2_RX, now, usb_rx_bulk.data);
874                 usb_rx_bulk.data += now;
875                 if ( !( usb_rx_bulk.remain -= now)) {
876                   usb_stop = msec_time;
877                   usb_flags.bulk_rx_data = 0;
878                 // complete_func or set flag(event)
879                 }
880               if ( usb_rx_bulk.remain > 0 && usb_rx_bulk.remain <= PDI_EP2_PACKET_SIZE) 
881                 goto ReadAgain;
882             }  
883           }
884         }
885         if ( usb_last_irq & PDI_INT_EP2_IN) {                 // D12 - Ep2TxDone - data in EP2 was sended
886           usb_last_status = pdiGetLastTransStatus( PDI_EP2_TX);
887           debugPrint( DBG_INT, ("Ep2-Tx LTS=0x%X\n", usb_last_status));
888           if ( usb_last_status & PDI_LTSTAT_RXTX_OK) {
889             if ( usb_flags.terminal_mode) {              
890               int ch;
891               usb_tm_snded++;
892               ch = usb_com_get( &usb_com_que_out);
893               if ( ch < 0) {
894                 usb_flags.bulk_tx_data = 0;
895               } else {
896                 unsigned char uchr = ch;                
897                 usb_flags.bulk_tx_data = 1;
898                 pdiWriteEndpoint( PDI_EP2_TX, 1, &uchr);
899               }
900             } else {
901               if ( usb_tx_bulk.remain) {
902                 unsigned int now = usb_tx_bulk.remain;
903                 if ( now > PDI_EP2_PACKET_SIZE) now = PDI_EP2_PACKET_SIZE;
904                 pdiWriteEndpoint( PDI_EP2_TX, now, usb_tx_bulk.data);
905                 usb_tx_bulk.data += now;
906                 if (!(usb_tx_bulk.remain -= now)) {
907                   // complete_func or set flag(event)
908                 }
909               }
910             }
911           }
912         }
913       }
914     }
915   }
916
917 #ifdef PDIUSB_WITH_ADD_IRQ_HANDLER
918   irq_handler_t usb_irq_handler = {
919     handler: usb_isr,
920     flags:   0,
921     dev_id:  0,
922     devname: "usb",
923     next:    0
924   };
925 #endif /*PDIUSB_WITH_ADD_IRQ_HANDLER*/
926
927   
928 /*****************************************************************************/
929 /*****************************************************************************/
930 /*****************************************************************************/
931 /***                                                                       ***/
932 /*** USB COM Emulator Module                                               ***/
933 /***                                                                       ***/
934 /*****************************************************************************/
935 /*****************************************************************************/
936 /*****************************************************************************/ 
937   int usb_tm_snd;
938   int usb_tm_snded;
939   int usb_tm_rcv;
940
941   int usb_com_init( void) {        
942     usb_tm_snd = 0;
943     usb_tm_snded = 0;
944     usb_tm_rcv = 0;
945     
946     usb_com_que_in.begin=usb_com_buf_in;
947     usb_com_que_in.end=usb_com_que_in.begin+sizeof(usb_com_buf_in);
948     usb_com_que_in.first=usb_com_que_in.begin;
949     usb_com_que_in.last=usb_com_que_in.begin;
950   
951     usb_com_que_out.begin=usb_com_buf_out;
952     usb_com_que_out.end=usb_com_que_out.begin+sizeof(usb_com_buf_out);
953     usb_com_que_out.first=usb_com_que_out.begin;
954     usb_com_que_out.last=usb_com_que_out.begin;
955   
956     return 1;
957   }
958
959   /* put character c into queue, if full return -1 */
960   int usb_com_put(usb_com_que_t *q, int c)
961   {
962     unsigned char *p=q->last;
963     *(p++)=(unsigned char)c;
964     if (p==q->end) p=q->begin;
965     if (p==q->first) return -1;
966     q->last=p;
967     return c;
968   }
969   /* get character from queue, if empty return -1 */
970   int usb_com_get(usb_com_que_t *q)
971   {
972     unsigned char *p;
973     int c;
974     p=q->first;
975     if(p==q->last) return -1;
976     c=*(p++);
977     if(p==q->end) p=q->begin;
978     q->first=p;
979     return c;
980   }
981
982 /*
983   int usb_com_sendch(int c) {
984     if ( usb_flags.terminal_mode) {
985       usb_tm_snd++;
986       if ( !usb_flags.bits.bulk_tx_data) { // hned poslat - atomicke nastaveni flagu ... 
987         unsigned char byte = c;
988         pdiWriteEndpoint( PDI_EP2_TX, 1, (unsigned char *)&byte);
989         usb_flags.bulk_tx_data = 1; 
990       } else {        
991         if( usb_com_put(&usb_com_que_out,c)<0){ // nevejde se 
992 #ifdef USE_USB_WITH_IRQ 
993           while( usb_com_que_out.last == usb_com_que_out.first-1); // Wait if buffer is full !@#$%^&* 
994           if( usb_com_put(&usb_com_que_out,c)<0)                   // case (last==end and first==begin) not respected 
995 #endif
996             c=-1;
997         }
998       }
999     }
1000     return c;
1001   }
1002 */  
1003   void usb_com_start_send( void) {
1004     if ( !usb_flags.bits.bulk_tx_data &&
1005          usb_com_que_out.first != usb_com_que_out.last) {
1006       int ch;
1007       ch = usb_com_get( &usb_com_que_out);
1008       if ( ch >= 0) {
1009         unsigned char byte = ch;
1010         usb_flags.bulk_tx_data = 1;
1011         pdiWriteEndpoint( PDI_EP2_TX, 1, &byte);
1012       }
1013     }
1014   }
1015   
1016   int usb_com_sendch(int c) {
1017     if ( usb_flags.terminal_mode) {
1018       usb_tm_snd++;
1019 #ifndef USE_USB_WITH_IRQ
1020       if( !usb_flags.bits.bulk_tx_data) {
1021         unsigned char byte = c;
1022         usb_flags.bulk_tx_data = 1;
1023         pdiWriteEndpoint( PDI_EP2_TX, 1, &byte);        
1024         return c;
1025       }
1026 #endif
1027       if( usb_com_put(&usb_com_que_out,c)<0){ /* nevejde se */
1028       
1029 #ifdef USE_USB_WITH_IRQ 
1030         if ( !usb_flags.bits.bulk_tx_data) {
1031           usb_com_start_send();
1032         } else {
1033           while( usb_com_que_out.last == usb_com_que_out.first-1); /* Wait if buffer is full !@#$%^&* */
1034         }
1035         if( usb_com_put(&usb_com_que_out,c)<0)                   /* case (last==end and first==begin) isn't respected */
1036 #endif
1037           c=-1;
1038       }
1039     }
1040     return c;
1041   }
1042   
1043   
1044   
1045   int usb_com_recch() {
1046     int val;
1047     if ( !usb_flags.bits.terminal_mode) return -1;
1048     val=usb_com_get(&usb_com_que_in);
1049     return val;
1050   }
1051   
1052   int usb_com_sendstr(const char *s) {
1053     int cnt=0;
1054     while(*s)
1055     {
1056       if(usb_com_sendch((unsigned char)(*(s++)))<0) break;
1057       cnt++;
1058     }
1059     return cnt;    
1060   }
1061