summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--firmware/target/arm/as3525/usb-drv-as3525v2.c166
1 files changed, 83 insertions, 83 deletions
diff --git a/firmware/target/arm/as3525/usb-drv-as3525v2.c b/firmware/target/arm/as3525/usb-drv-as3525v2.c
index d4b24fba33..335c3144fe 100644
--- a/firmware/target/arm/as3525/usb-drv-as3525v2.c
+++ b/firmware/target/arm/as3525/usb-drv-as3525v2.c
@@ -461,102 +461,101 @@ void usb_drv_exit(void)
461 cpu_boost(0); 461 cpu_boost(0);
462} 462}
463 463
464static void handle_ep_int(int ep, bool dir_in) 464static void handle_ep_in_int(int ep)
465{ 465{
466 struct usb_endpoint *endpoint = &endpoints[ep][dir_in]; 466 struct usb_endpoint *endpoint = &endpoints[ep][DIR_IN];
467 if(dir_in) 467 unsigned long sts = DIEPINT(ep);
468 if(sts & DIEPINT_ahberr)
469 panicf("usb-drv: ahb error on EP%d IN", ep);
470 if(sts & DIEPINT_xfercompl)
468 { 471 {
469 unsigned long sts = DIEPINT(ep); 472 if(endpoint->busy)
470 if(sts & DIEPINT_ahberr)
471 panicf("usb-drv: ahb error on EP%d IN", ep);
472 if(sts & DIEPINT_xfercompl)
473 { 473 {
474 if(endpoint->busy) 474 endpoint->busy = false;
475 { 475 endpoint->status = 0;
476 endpoint->busy = false; 476 /* works even for EP0 */
477 endpoint->status = 0; 477 int size = (DIEPTSIZ(ep) & DEPTSIZ_xfersize_bits);
478 /* works even for EP0 */ 478 int transfered = endpoint->len - size;
479 int size = (DIEPTSIZ(ep) & DEPTSIZ_xfersize_bits); 479 logf("len=%d reg=%ld xfer=%d", endpoint->len, size, transfered);
480 int transfered = endpoint->len - size; 480 /* handle EP0 state if necessary,
481 logf("len=%d reg=%ld xfer=%d", endpoint->len, size, transfered); 481 * this is a ack if length is 0 */
482 /* handle EP0 state if necessary, 482 if(ep == 0)
483 * this is a ack if length is 0 */ 483 handle_ep0_complete(endpoint->len == 0);
484 if(ep == 0) 484 endpoint->len = size;
485 handle_ep0_complete(endpoint->len == 0); 485 usb_core_transfer_complete(ep, USB_DIR_IN, 0, transfered);
486 endpoint->len = size; 486 wakeup_signal(&endpoint->complete);
487 usb_core_transfer_complete(ep, USB_DIR_IN, 0, transfered);
488 wakeup_signal(&endpoint->complete);
489 }
490 } 487 }
491 if(sts & DIEPINT_timeout) 488 }
489 if(sts & DIEPINT_timeout)
490 {
491 panicf("usb-drv: timeout on EP%d IN", ep);
492 if(endpoint->busy)
492 { 493 {
493 panicf("usb-drv: timeout on EP%d IN", ep); 494 endpoint->busy = false;
494 if(endpoint->busy) 495 endpoint->status = -1;
495 { 496 /* for safety, act as if no bytes as been transfered */
496 endpoint->busy = false; 497 endpoint->len = 0;
497 endpoint->status = -1; 498 usb_core_transfer_complete(ep, USB_DIR_IN, 1, 0);
498 /* for safety, act as if no bytes as been transfered */ 499 wakeup_signal(&endpoint->complete);
499 endpoint->len = 0;
500 usb_core_transfer_complete(ep, USB_DIR_IN, 1, 0);
501 wakeup_signal(&endpoint->complete);
502 }
503 } 500 }
504 /* clear interrupts */
505 DIEPINT(ep) = sts;
506 } 501 }
507 else 502 /* clear interrupts */
503 DIEPINT(ep) = sts;
504}
505
506static void handle_ep_out_int(int ep)
507{
508 struct usb_endpoint *endpoint = &endpoints[ep][DIR_OUT];
509 unsigned long sts = DOEPINT(ep);
510 if(sts & DOEPINT_ahberr)
511 panicf("usb-drv: ahb error on EP%d OUT", ep);
512 if(sts & DOEPINT_xfercompl)
508 { 513 {
509 unsigned long sts = DOEPINT(ep); 514 logf("usb-drv: xfer complete on EP%d OUT", ep);
510 if(sts & DOEPINT_ahberr) 515 if(endpoint->busy)
511 panicf("usb-drv: ahb error on EP%d OUT", ep);
512 if(sts & DOEPINT_xfercompl)
513 { 516 {
514 logf("usb-drv: xfer complete on EP%d OUT", ep); 517 endpoint->busy = false;
515 if(endpoint->busy) 518 endpoint->status = 0;
516 { 519 /* works even for EP0 */
517 endpoint->busy = false; 520 int transfered = endpoint->len - (DOEPTSIZ(ep) & DEPTSIZ_xfersize_bits);
518 endpoint->status = 0; 521 logf("len=%d reg=%ld xfer=%d", endpoint->len,
519 /* works even for EP0 */ 522 (DOEPTSIZ(ep) & DEPTSIZ_xfersize_bits),
520 int transfered = endpoint->len - (DOEPTSIZ(ep) & DEPTSIZ_xfersize_bits); 523 transfered);
521 logf("len=%d reg=%ld xfer=%d", endpoint->len, 524 /* handle EP0 state if necessary,
522 (DOEPTSIZ(ep) & DEPTSIZ_xfersize_bits), 525 * this is a ack if length is 0 */
523 transfered); 526 if(ep == 0)
524 /* handle EP0 state if necessary, 527 handle_ep0_complete(endpoint->len == 0);
525 * this is a ack if length is 0 */ 528 usb_core_transfer_complete(ep, USB_DIR_OUT, 0, transfered);
526 if(ep == 0) 529 wakeup_signal(&endpoint->complete);
527 handle_ep0_complete(endpoint->len == 0);
528 usb_core_transfer_complete(ep, USB_DIR_OUT, 0, transfered);
529 wakeup_signal(&endpoint->complete);
530 }
531 } 530 }
532 if(sts & DOEPINT_setup) 531 }
532 if(sts & DOEPINT_setup)
533 {
534 logf("usb-drv: setup on EP%d OUT", ep);
535 if(ep != 0)
536 panicf("usb-drv: setup not on EP0, this is impossible");
537 if((DOEPTSIZ(ep) & DEPTSIZ_xfersize_bits) != 0)
533 { 538 {
534 logf("usb-drv: setup on EP%d OUT", ep); 539 logf("usb-drv: ignore spurious setup (xfersize=%ld)", DOEPTSIZ(ep) & DEPTSIZ_xfersize_bits);
535 if(ep != 0) 540 prepare_setup_ep0();
536 panicf("usb-drv: setup not on EP0, this is impossible"); 541 }
537 if((DOEPTSIZ(ep) & DEPTSIZ_xfersize_bits) != 0) 542 else
538 { 543 {
539 logf("usb-drv: ignore spurious setup (xfersize=%ld)", DOEPTSIZ(ep) & DEPTSIZ_xfersize_bits); 544 /* handle EP0 state */
540 prepare_setup_ep0(); 545 handle_ep0_setup();
541 } 546 logf(" rt=%x r=%x", ep0_setup_pkt->bRequestType, ep0_setup_pkt->bRequest);
542 else 547 /* handle set address */
548 if(ep0_setup_pkt->bRequestType == USB_TYPE_STANDARD &&
549 ep0_setup_pkt->bRequest == USB_REQ_SET_ADDRESS)
543 { 550 {
544 /* handle EP0 state */ 551 /* Set address now */
545 handle_ep0_setup(); 552 DCFG = (DCFG & ~bitm(DCFG, devadr)) | (ep0_setup_pkt->wValue << DCFG_devadr_bitp);
546 logf(" rt=%x r=%x", ep0_setup_pkt->bRequestType, ep0_setup_pkt->bRequest);
547 /* handle set address */
548 if(ep0_setup_pkt->bRequestType == USB_TYPE_STANDARD &&
549 ep0_setup_pkt->bRequest == USB_REQ_SET_ADDRESS)
550 {
551 /* Set address now */
552 DCFG = (DCFG & ~bitm(DCFG, devadr)) | (ep0_setup_pkt->wValue << DCFG_devadr_bitp);
553 }
554 usb_core_control_request(ep0_setup_pkt);
555 } 553 }
554 usb_core_control_request(ep0_setup_pkt);
556 } 555 }
557 /* clear interrupts */
558 DOEPINT(ep) = sts;
559 } 556 }
557 /* clear interrupts */
558 DOEPINT(ep) = sts;
560} 559}
561 560
562static void handle_ep_ints(void) 561static void handle_ep_ints(void)
@@ -568,10 +567,11 @@ static void handle_ep_ints(void)
568 567
569 FOR_EACH_IN_EP_AND_EP0(i, ep) 568 FOR_EACH_IN_EP_AND_EP0(i, ep)
570 if(daint & DAINT_IN_EP(ep)) 569 if(daint & DAINT_IN_EP(ep))
571 handle_ep_int(ep, true); 570 handle_ep_in_int(ep);
571
572 FOR_EACH_OUT_EP_AND_EP0(i, ep) 572 FOR_EACH_OUT_EP_AND_EP0(i, ep)
573 if(daint & DAINT_OUT_EP(ep)) 573 if(daint & DAINT_OUT_EP(ep))
574 handle_ep_int(ep, false); 574 handle_ep_out_int(ep);
575 575
576 /* write back to clear status */ 576 /* write back to clear status */
577 DAINT = daint; 577 DAINT = daint;