1 /*********************************************************/
2 /*** Module : USB communication ***/
3 /*** Author : Roman Bartosinski (bartosr@centrum.cz) ***/
4 /*** Modify : 14.01.2003 ***/
5 /*********************************************************/
8 #include <system_def.h>
12 /*#include <usb/usb_spec.h>*/
15 #include <usb/usb_com.h>
18 /* Queued USB Module */
19 typedef volatile struct{
26 #define USB_COM_BUF_LEN 80 //(80*8)
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];
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);
37 usb_vendor_extension_fnc_t *usb_vendor_extension=0;
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*/
48 /* common external function for pdiusb module */
49 void pdiSendCommand( unsigned char byCmd) {
50 writeb( byCmd, PDIUSB_COMMAND_ADDR);
52 unsigned char pdiReadData( unsigned char byCount, unsigned char *pbyData) {
53 unsigned char out = byCount;
56 *pbyData = readb( PDIUSB_READ_DATA_ADDR);
62 void pdiWriteData( unsigned char byCount, unsigned char *pbyData) {
64 writeb( *pbyData++, PDIUSB_WRITE_DATA_ADDR);
69 /* usb communication module */
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;
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];
81 typeof(msec_time) usb_start = 0, usb_stop = 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;
93 ret = usb_test_interrupt();
94 if ( usb_flags.request == 1) {
95 usb_answer_to_request();
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) ) {
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;
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;
129 int usb_test_interrupt( void) { //_naked {
130 unsigned char usb_last_status;
135 usb_last_irq = pdiGetInterrupt();
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;
145 debugPrint( DBG_HIGH, ("Bus Reset\n"));
147 if ( usb_last_irq & PDI_INT_SUSPEND) { // D12 - Suspend flag changed
148 debugPrint( DBG_HIGH, ("Suspend Changed\n"));
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;
159 if ( usb_rxtx_control.next_pkt_fnc )
160 if( usb_rxtx_control.next_pkt_fnc(&usb_rxtx_control, now, USB_NEXT_PKT_SEND) ) {
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;
171 } else if ( usb_flags.request == 3) {
172 debugPrint( DBG_HIGH, ("CNTR ack\n"));
173 usb_flags.request = 0;
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;
181 debugPrint( DBG_LOW, ("tx ... ???\n"));
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"));
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;
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);
206 if(ret>usb_rxtx_control.bytes)
207 ret = usb_rxtx_control.bytes;
209 usb_rxtx_control.data += ret;
211 if ( usb_rxtx_control.next_pkt_fnc ) {
212 if( usb_rxtx_control.next_pkt_fnc(&usb_rxtx_control, ret, USB_NEXT_PKT_REC) ) {
218 if (!(usb_rxtx_control.bytes -= ret)) {
219 usb_rxtx_control.data -= usb_rxtx_control.dreq.wLength;
220 usb_flags.request = 3;
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;
231 pdiReadEndpoint( PDI_EP0_RX, 0, 0);
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);
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);
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;
258 now = pdiReadEndpoint( PDI_EP2_RX, now, hlpbfr);
261 if (usb_com_put( &usb_com_que_in, hlpbfr[i])<0) { /* nevkladat dalsi */
265 if(now==PDI_EP2_PACKET_SIZE) goto MoreRead;
267 unsigned long now = usb_rx_bulk.remain;
268 if ( now > PDI_EP2_PACKET_SIZE) now = PDI_EP2_PACKET_SIZE;
270 if ( !usb_flags.bits.bulk_rx_data) {
271 usb_flags.bulk_rx_data = 1;
272 usb_start = msec_time;
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)
284 if ( usb_rx_bulk.remain > 0 && usb_rx_bulk.remain <= PDI_EP2_PACKET_SIZE)
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);
297 usb_flags.bulk_tx_data = 0;
299 unsigned char uchr = ch;
300 usb_flags.bulk_tx_data = 1;
301 pdiWriteEndpoint( PDI_EP2_TX, 1, &uchr);
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)
326 // ************************************
327 void usb_init( void) {
328 usb_last_irq = 0; usb_address = 0; usb_interface = 0;
333 #ifdef USE_USB_WITH_IRQ
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 */
343 debugPrint(DBG_MEDIUM,("# Usb Inited\n"));
346 void usb_connect_bus( void) {
347 debugPrint(DBG_MEDIUM,("Usb connect to bus\n"));
348 usb_flags.running = 1;
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);
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;
360 void usb_stall_ep0( void) {
361 pdiSetEpStatus( PDI_EP0_TX, PDI_SET_EP_STALLED); pdiSetEpStatus( PDI_EP0_RX, PDI_SET_EP_STALLED);
365 // ************************************
366 // *** Common send/receive fncs ***
367 // ************************************
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);
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;
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;
386 unsigned char usb_receive_from_usb( unsigned char idx, unsigned char maxb) {
387 unsigned char ret = 0;
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) {
394 pdiReadEndpoint( usb_ep[idx].ep, 0, 0);
395 return 0xff; // too_small_buffer error
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);
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";
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";
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";
444 void usb_set_control_data(usb_control_ep_t *ep, void *buff, int size)
446 ep->data = (unsigned char *) buff;
448 usb_flags.request = 2;
449 debugPrint( DBG_HIGH,("usb_set_control_data buff=0x%lx, len=%d\n", (long)buff, size));
452 void usb_set_control_ack(usb_control_ep_t *ep)
456 usb_flags.request = 3;
457 debugPrint( DBG_HIGH,("usb_set_control_ack\n"));
462 ***********************************
463 *** Execute device requests ***
464 ***********************************
466 void usb_answer_to_request( void) {
467 USB_DEVICE_REQUEST *pdreq = &usb_rxtx_control.dreq;
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"));
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);
483 usb_rxtx_control.next_pkt_fnc = NULL;
484 usb_rxtx_control.complete_fnc = NULL;
486 ctrl_data[0] = ctrl_data[1] = 0; // we need only 2 bytes
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")));
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
508 USB_SET_CONTROL_DATA( &ctrl_data, 2);
509 //pdiWriteEndpoint( PDI_EP0_TX, 2, hlp);
511 case USB_REQUEST_SET_ADDRESS:
512 usb_address = ( unsigned char)( pdreq->wValue & DEVICE_ADDRESS_MASK);
513 pdiSetAddressEnable( usb_address | PDI_ENAD_ENABLE);
515 //pdiWriteEndpoint( PDI_EP0_TX, 0, 0);
517 case USB_REQUEST_GET_DESCRIPTOR:
518 usb_get_descriptor();
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);
525 case USB_REQUEST_SET_CONFIGURATION:
526 if (LSB( pdreq->wValue) < 2) {
527 if ( LSB( pdreq->wValue)) {
528 pdiSetEndpointEnable( usb_flags.configured=1);
530 pdiSetEndpointEnable( usb_flags.configured=0);
533 //pdiWriteEndpoint( PDI_EP0_TX, 0, 0);
543 case USB_VENDOR_REQUEST:
544 if(usb_vendor_extension) {
546 ret = usb_vendor_extension(&usb_rxtx_control, pdreq);
556 switch ( pdreq->bRequest) {
557 case USB_VENDOR_START_TRANSFER:
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;
564 case USB_VENDOR_CONTROL_TERMINAL_MODE:
565 if ( pdreq->wValue == 1) usb_flags.terminal_mode = 1;
566 else usb_flags.terminal_mode = 0;
571 //pdiWriteEndpoint( PDI_EP0_TX, 0, 0);
575 case USB_CLASS_REQUEST:
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);
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);
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;
599 //pdiWriteEndpoint( PDI_EP0_TX, 0, 0);
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:
616 ctrl_data[0] = ( unsigned char)(( pdreq->wIndex & PDI_CNT_EP)<<1);
617 if ( pdreq->wIndex & ( unsigned char) USB_ENDPOINT_DIRECTION_MASK)
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);
625 if ( pdreq->bRequest == USB_REQUEST_CLEAR_FEATURE) {
626 pdiSetEpStatus( ctrl_data[0], 0);
627 //pdiWriteEndpoint( PDI_EP0_TX, 0, 0);
629 pdiSetEpStatus( ctrl_data[0], 1);
630 //pdiWriteEndpoint( PDI_EP0_TX, 0, 0);
642 // case USB_RECIPIENT_OTHER:
647 // usb_flags.command = 0; // ??? data or ack stage ???
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) ) {
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;
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;
682 char *DescType( unsigned char 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";
697 void usb_get_descriptor( void) {
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);
706 case USB_DESCRIPTOR_TYPE_CONFIGURATION:
707 usb_rxtx_control.data = (unsigned char *) &usb_config_0;
708 size = CONFIG_0_DESCRIPTOR_LENGTH;
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;
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);
729 /*****************************************************************************/
730 /*****************************************************************************/
731 /*****************************************************************************/
733 /*** USB with IRQ ***/
735 /*****************************************************************************/
736 /*****************************************************************************/
737 /*****************************************************************************/
739 #ifdef PDIUSB_WITH_EXCPTVECT_SET
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*/
745 unsigned char usb_last_status;
748 usb_last_irq = pdiGetInterrupt();
750 usb_flags.was_int = 1;
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;
759 debugPrint( DBG_INT, ("Bus Reset\n"));
761 if ( usb_last_irq & PDI_INT_SUSPEND) { // D12 - Suspend flag changed
762 debugPrint( DBG_INT, ("Suspend Changed\n"));
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;
778 } else if ( usb_flags.request == 3) {
779 debugPrint( DBG_INT, ("CNTR ack\n"));
780 usb_flags.request = 0;
782 debugPrint( DBG_INT, ("tx 0 ... ???\n"));
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"));
795 usb_flags.request = 1; // Standard_requests();
796 usb_answer_to_request();
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);
804 if(ret>usb_rxtx_control.bytes)
805 ret = usb_rxtx_control.bytes;
807 usb_rxtx_control.data += ret;
809 if ( usb_rxtx_control.next_pkt_fnc ) {
810 if( usb_rxtx_control.next_pkt_fnc(&usb_rxtx_control, ret, USB_NEXT_PKT_REC) ) {
815 if (!(usb_rxtx_control.bytes -= ret)) {
816 usb_rxtx_control.data -= usb_rxtx_control.dreq.wLength;
817 usb_flags.request = 3;
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;
828 pdiReadEndpoint( PDI_EP0_RX, 0, 0);
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);
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);
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;
855 now = pdiReadEndpoint( PDI_EP2_RX, now, hlpbfr);
858 if (usb_com_put( &usb_com_que_in, hlpbfr[i])<0) { /* nevkladat dalsi */
862 if(now==PDI_EP2_PACKET_SIZE) goto MoreRead;
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];
867 if ( !usb_flags.bits.bulk_rx_data) {
868 usb_flags.bulk_rx_data = 1;
869 usb_start = msec_time;
871 // if ( now > PDI_EP2_PACKET_SIZE) now = PDI_EP2_PACKET_SIZE;
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)
880 if ( usb_rx_bulk.remain > 0 && usb_rx_bulk.remain <= PDI_EP2_PACKET_SIZE)
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) {
892 ch = usb_com_get( &usb_com_que_out);
894 usb_flags.bulk_tx_data = 0;
896 unsigned char uchr = ch;
897 usb_flags.bulk_tx_data = 1;
898 pdiWriteEndpoint( PDI_EP2_TX, 1, &uchr);
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)
917 #ifdef PDIUSB_WITH_ADD_IRQ_HANDLER
918 irq_handler_t usb_irq_handler = {
925 #endif /*PDIUSB_WITH_ADD_IRQ_HANDLER*/
928 /*****************************************************************************/
929 /*****************************************************************************/
930 /*****************************************************************************/
932 /*** USB COM Emulator Module ***/
934 /*****************************************************************************/
935 /*****************************************************************************/
936 /*****************************************************************************/
941 int usb_com_init( void) {
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;
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;
959 /* put character c into queue, if full return -1 */
960 int usb_com_put(usb_com_que_t *q, int c)
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;
969 /* get character from queue, if empty return -1 */
970 int usb_com_get(usb_com_que_t *q)
975 if(p==q->last) return -1;
977 if(p==q->end) p=q->begin;
983 int usb_com_sendch(int c) {
984 if ( usb_flags.terminal_mode) {
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;
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
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) {
1007 ch = usb_com_get( &usb_com_que_out);
1009 unsigned char byte = ch;
1010 usb_flags.bulk_tx_data = 1;
1011 pdiWriteEndpoint( PDI_EP2_TX, 1, &byte);
1016 int usb_com_sendch(int c) {
1017 if ( usb_flags.terminal_mode) {
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);
1027 if( usb_com_put(&usb_com_que_out,c)<0){ /* nevejde se */
1029 #ifdef USE_USB_WITH_IRQ
1030 if ( !usb_flags.bits.bulk_tx_data) {
1031 usb_com_start_send();
1033 while( usb_com_que_out.last == usb_com_que_out.first-1); /* Wait if buffer is full !@#$%^&* */
1035 if( usb_com_put(&usb_com_que_out,c)<0) /* case (last==end and first==begin) isn't respected */
1045 int usb_com_recch() {
1047 if ( !usb_flags.bits.terminal_mode) return -1;
1048 val=usb_com_get(&usb_com_que_in);
1052 int usb_com_sendstr(const char *s) {
1056 if(usb_com_sendch((unsigned char)(*(s++)))<0) break;