@@ -515,198 +515,203 @@ static void usb_device_intr(void) {
515515 HWREGH (USB0_BASE + USB_O_CSRL0 ) = 0 ;
516516 pbdrv_usb_setup_data_to_send = 0 ;
517517 pbdrv_usb_addr_needs_setting = false;
518- } else if (peri_csr & USB_CSRL0_SETEND ) {
518+ }
519+
520+ if (peri_csr & USB_CSRL0_SETEND ) {
519521 // Error in SETUP transaction
520522 HWREGH (USB0_BASE + USB_O_CSRL0 ) = USB_CSRL0_SETENDC ;
521523 pbdrv_usb_setup_data_to_send = 0 ;
522524 pbdrv_usb_addr_needs_setting = false;
523- } else {
524- if (pbdrv_usb_addr_needs_setting ) {
525- USBDevAddrSet (USB0_BASE , pbdrv_usb_addr );
526- pbdrv_usb_addr_needs_setting = false;
527- }
525+ }
528526
529- if (peri_csr & USB_CSRL0_RXRDY ) {
530- // Got a new setup packet
531- pbdrv_usb_setup_packet_union_t setup_pkt ;
532- bool handled = false;
533- pbdrv_usb_setup_data_to_send = 0 ;
527+ // If we got here (and didn't wipe out this flag),
528+ // then this indicates completion of the SET_ADDRESS command.
529+ // We thus have to make it take effect at this point.
530+ if (pbdrv_usb_addr_needs_setting ) {
531+ USBDevAddrSet (USB0_BASE , pbdrv_usb_addr );
532+ pbdrv_usb_addr_needs_setting = false;
533+ }
534534
535- setup_pkt .u [0 ] = HWREG (USB0_BASE + USB_O_FIFO0 );
536- setup_pkt .u [1 ] = HWREG (USB0_BASE + USB_O_FIFO0 );
537- HWREGH (USB0_BASE + USB_O_CSRL0 ) = USB_CSRL0_RXRDYC ;
535+ if (peri_csr & USB_CSRL0_RXRDY ) {
536+ // Got a new setup packet
537+ pbdrv_usb_setup_packet_union_t setup_pkt ;
538+ bool handled = false;
539+ pbdrv_usb_setup_data_to_send = 0 ;
538540
539- switch (setup_pkt .s .bmRequestType & BM_REQ_TYPE_MASK ) {
540- case BM_REQ_TYPE_STANDARD :
541- switch (setup_pkt .s .bmRequestType & BM_REQ_RECIP_MASK ) {
542- case BM_REQ_RECIP_DEV :
543- switch (setup_pkt .s .bRequest ) {
544- case SET_ADDRESS :
545- pbdrv_usb_addr = setup_pkt .s .wValue ;
546- pbdrv_usb_addr_needs_setting = true;
547- handled = true;
548- break ;
541+ setup_pkt .u [0 ] = HWREG (USB0_BASE + USB_O_FIFO0 );
542+ setup_pkt .u [1 ] = HWREG (USB0_BASE + USB_O_FIFO0 );
543+ HWREGH (USB0_BASE + USB_O_CSRL0 ) = USB_CSRL0_RXRDYC ;
544+
545+ switch (setup_pkt .s .bmRequestType & BM_REQ_TYPE_MASK ) {
546+ case BM_REQ_TYPE_STANDARD :
547+ switch (setup_pkt .s .bmRequestType & BM_REQ_RECIP_MASK ) {
548+ case BM_REQ_RECIP_DEV :
549+ switch (setup_pkt .s .bRequest ) {
550+ case SET_ADDRESS :
551+ pbdrv_usb_addr = setup_pkt .s .wValue ;
552+ pbdrv_usb_addr_needs_setting = true;
553+ handled = true;
554+ break ;
549555
550- case SET_CONFIGURATION :
551- if (setup_pkt .s .wValue <= 1 ) {
552- pbdrv_usb_config = setup_pkt .s .wValue ;
556+ case SET_CONFIGURATION :
557+ if (setup_pkt .s .wValue <= 1 ) {
558+ pbdrv_usb_config = setup_pkt .s .wValue ;
553559
554- if (pbdrv_usb_config == 1 ) {
555- // configuring
560+ if (pbdrv_usb_config == 1 ) {
561+ // configuring
556562
557- // Reset data toggle, clear stall, flush fifo
558- HWREGB (USB0_BASE + USB_O_TXCSRL1 ) = USB_TXCSRL1_CLRDT | USB_TXCSRL1_FLUSH ;
559- HWREGB (USB0_BASE + USB_O_RXCSRL1 ) = USB_RXCSRL1_CLRDT | USB_RXCSRL1_FLUSH ;
560- } else {
561- // deconfiguring
563+ // Reset data toggle, clear stall, flush fifo
564+ HWREGB (USB0_BASE + USB_O_TXCSRL1 ) = USB_TXCSRL1_CLRDT | USB_TXCSRL1_FLUSH ;
565+ HWREGB (USB0_BASE + USB_O_RXCSRL1 ) = USB_RXCSRL1_CLRDT | USB_RXCSRL1_FLUSH ;
566+ } else {
567+ // deconfiguring
562568
563- // Set stall condition
564- HWREGB (USB0_BASE + USB_O_TXCSRL1 ) = USB_TXCSRL1_STALL ;
565- HWREGB (USB0_BASE + USB_O_RXCSRL1 ) = USB_RXCSRL1_STALL ;
566- }
567- handled = true;
569+ // Set stall condition
570+ HWREGB (USB0_BASE + USB_O_TXCSRL1 ) = USB_TXCSRL1_STALL ;
571+ HWREGB (USB0_BASE + USB_O_RXCSRL1 ) = USB_RXCSRL1_STALL ;
568572 }
569- break ;
573+ handled = true;
574+ }
575+ break ;
570576
571- case GET_CONFIGURATION :
572- pbdrv_usb_setup_misc_tx_byte = pbdrv_usb_config ;
577+ case GET_CONFIGURATION :
578+ pbdrv_usb_setup_misc_tx_byte = pbdrv_usb_config ;
579+ pbdrv_usb_setup_data_to_send = & pbdrv_usb_setup_misc_tx_byte ;
580+ pbdrv_usb_setup_data_to_send_sz = 1 ;
581+ handled = true;
582+ break ;
583+
584+ case GET_STATUS :
585+ pbdrv_usb_setup_misc_tx_byte = 1 ; // self-powered
586+ pbdrv_usb_setup_data_to_send = & pbdrv_usb_setup_misc_tx_byte ;
587+ pbdrv_usb_setup_data_to_send_sz = 2 ;
588+ handled = true;
589+ break ;
590+
591+ case GET_DESCRIPTOR :
592+ if (usb_get_descriptor (setup_pkt .s .wValue )) {
593+ handled = true;
594+ }
595+ break ;
596+ }
597+ break ;
598+
599+ case BM_REQ_RECIP_IF :
600+ if (setup_pkt .s .wIndex == 0 ) {
601+ switch (setup_pkt .s .bRequest ) {
602+ case GET_INTERFACE :
603+ pbdrv_usb_setup_misc_tx_byte = 0 ;
573604 pbdrv_usb_setup_data_to_send = & pbdrv_usb_setup_misc_tx_byte ;
574605 pbdrv_usb_setup_data_to_send_sz = 1 ;
575606 handled = true;
576607 break ;
577608
578609 case GET_STATUS :
579- pbdrv_usb_setup_misc_tx_byte = 1 ; // self-powered
610+ pbdrv_usb_setup_misc_tx_byte = 0 ;
580611 pbdrv_usb_setup_data_to_send = & pbdrv_usb_setup_misc_tx_byte ;
581612 pbdrv_usb_setup_data_to_send_sz = 2 ;
582613 handled = true;
583614 break ;
584-
585- case GET_DESCRIPTOR :
586- if (usb_get_descriptor (setup_pkt .s .wValue )) {
587- handled = true;
588- }
589- break ;
590615 }
591- break ;
592-
593- case BM_REQ_RECIP_IF :
594- if (setup_pkt .s .wIndex == 0 ) {
595- switch (setup_pkt .s .bRequest ) {
596- case GET_INTERFACE :
597- pbdrv_usb_setup_misc_tx_byte = 0 ;
598- pbdrv_usb_setup_data_to_send = & pbdrv_usb_setup_misc_tx_byte ;
599- pbdrv_usb_setup_data_to_send_sz = 1 ;
600- handled = true;
601- break ;
602-
603- case GET_STATUS :
604- pbdrv_usb_setup_misc_tx_byte = 0 ;
605- pbdrv_usb_setup_data_to_send = & pbdrv_usb_setup_misc_tx_byte ;
606- pbdrv_usb_setup_data_to_send_sz = 2 ;
607- handled = true;
608- break ;
616+ }
617+ break ;
618+
619+ case BM_REQ_RECIP_EP :
620+ switch (setup_pkt .s .bRequest ) {
621+ case GET_STATUS :
622+ if (setup_pkt .s .wIndex == 1 ) {
623+ pbdrv_usb_setup_misc_tx_byte = !!(HWREGB (USB0_BASE + USB_O_RXCSRL1 ) & USB_RXCSRL1_STALL );
624+ pbdrv_usb_setup_data_to_send = & pbdrv_usb_setup_misc_tx_byte ;
625+ pbdrv_usb_setup_data_to_send_sz = 2 ;
626+ handled = true;
627+ } else if (setup_pkt .s .wIndex == 0x81 ) {
628+ pbdrv_usb_setup_misc_tx_byte = !!(HWREGB (USB0_BASE + USB_O_TXCSRL1 ) & USB_TXCSRL1_STALL );
629+ pbdrv_usb_setup_data_to_send = & pbdrv_usb_setup_misc_tx_byte ;
630+ pbdrv_usb_setup_data_to_send_sz = 2 ;
631+ handled = true;
609632 }
610- }
611- break ;
633+ break ;
612634
613- case BM_REQ_RECIP_EP :
614- switch (setup_pkt .s .bRequest ) {
615- case GET_STATUS :
635+ case CLEAR_FEATURE :
636+ if (setup_pkt .s .wValue == 0 ) {
616637 if (setup_pkt .s .wIndex == 1 ) {
617- pbdrv_usb_setup_misc_tx_byte = !!(HWREGB (USB0_BASE + USB_O_RXCSRL1 ) & USB_RXCSRL1_STALL );
618- pbdrv_usb_setup_data_to_send = & pbdrv_usb_setup_misc_tx_byte ;
619- pbdrv_usb_setup_data_to_send_sz = 2 ;
638+ HWREGB (USB0_BASE + USB_O_RXCSRL1 ) &= ~USB_RXCSRL1_STALL ;
620639 handled = true;
621640 } else if (setup_pkt .s .wIndex == 0x81 ) {
622- pbdrv_usb_setup_misc_tx_byte = !!(HWREGB (USB0_BASE + USB_O_TXCSRL1 ) & USB_TXCSRL1_STALL );
623- pbdrv_usb_setup_data_to_send = & pbdrv_usb_setup_misc_tx_byte ;
624- pbdrv_usb_setup_data_to_send_sz = 2 ;
641+ HWREGB (USB0_BASE + USB_O_TXCSRL1 ) &= ~USB_TXCSRL1_STALL ;
625642 handled = true;
626643 }
627- break ;
628-
629- case CLEAR_FEATURE :
630- if (setup_pkt .s .wValue == 0 ) {
631- if (setup_pkt .s .wIndex == 1 ) {
632- HWREGB (USB0_BASE + USB_O_RXCSRL1 ) &= ~USB_RXCSRL1_STALL ;
633- handled = true;
634- } else if (setup_pkt .s .wIndex == 0x81 ) {
635- HWREGB (USB0_BASE + USB_O_TXCSRL1 ) &= ~USB_TXCSRL1_STALL ;
636- handled = true;
637- }
638- }
639- break ;
644+ }
645+ break ;
640646
641- case SET_FEATURE :
642- if (setup_pkt .s .wValue == 0 ) {
643- if (setup_pkt .s .wIndex == 1 ) {
644- HWREGB (USB0_BASE + USB_O_RXCSRL1 ) |= USB_RXCSRL1_STALL ;
645- handled = true;
646- } else if (setup_pkt .s .wIndex == 0x81 ) {
647- HWREGB (USB0_BASE + USB_O_TXCSRL1 ) |= USB_TXCSRL1_STALL ;
648- handled = true;
649- }
647+ case SET_FEATURE :
648+ if (setup_pkt .s .wValue == 0 ) {
649+ if (setup_pkt .s .wIndex == 1 ) {
650+ HWREGB (USB0_BASE + USB_O_RXCSRL1 ) |= USB_RXCSRL1_STALL ;
651+ handled = true;
652+ } else if (setup_pkt .s .wIndex == 0x81 ) {
653+ HWREGB (USB0_BASE + USB_O_TXCSRL1 ) |= USB_TXCSRL1_STALL ;
654+ handled = true;
650655 }
651- break ;
652- }
653- break ;
654- }
655- break ;
656-
657- case BM_REQ_TYPE_VENDOR :
658- switch (setup_pkt .s .bRequest ) {
659- case PBDRV_USB_VENDOR_REQ_WEBUSB :
660- if (setup_pkt .s .wIndex == WEBUSB_REQ_GET_URL && setup_pkt .s .wValue == PBDRV_USB_WEBUSB_LANDING_PAGE_URL_IDX ) {
661- pbdrv_usb_setup_data_to_send = pbdrv_usb_webusb_landing_page .u ;
662- pbdrv_usb_setup_data_to_send_sz = pbdrv_usb_webusb_landing_page .s .bLength ;
663- handled = true;
664- }
665- break ;
656+ }
657+ break ;
658+ }
659+ break ;
660+ }
661+ break ;
662+
663+ case BM_REQ_TYPE_VENDOR :
664+ switch (setup_pkt .s .bRequest ) {
665+ case PBDRV_USB_VENDOR_REQ_WEBUSB :
666+ if (setup_pkt .s .wIndex == WEBUSB_REQ_GET_URL && setup_pkt .s .wValue == PBDRV_USB_WEBUSB_LANDING_PAGE_URL_IDX ) {
667+ pbdrv_usb_setup_data_to_send = pbdrv_usb_webusb_landing_page .u ;
668+ pbdrv_usb_setup_data_to_send_sz = pbdrv_usb_webusb_landing_page .s .bLength ;
669+ handled = true;
670+ }
671+ break ;
672+
673+ case PBDRV_USB_VENDOR_REQ_MS_20 :
674+ if (setup_pkt .s .wIndex == MS_OS_20_DESCRIPTOR_INDEX ) {
675+ pbdrv_usb_setup_data_to_send = pbdrv_usb_ms_20_desc_set .u ;
676+ pbdrv_usb_setup_data_to_send_sz = sizeof (pbdrv_usb_ms_20_desc_set .s );
677+ handled = true;
678+ }
679+ break ;
680+ }
681+ }
666682
667- case PBDRV_USB_VENDOR_REQ_MS_20 :
668- if ( setup_pkt . s . wIndex == MS_OS_20_DESCRIPTOR_INDEX ) {
669- pbdrv_usb_setup_data_to_send = pbdrv_usb_ms_20_desc_set . u ;
670- pbdrv_usb_setup_data_to_send_sz = sizeof ( pbdrv_usb_ms_20_desc_set . s );
671- handled = true;
672- }
673- break ;
674- }
675- }
683+ if (! handled ) {
684+ // send stall
685+ HWREGH ( USB0_BASE + USB_O_CSRL0 ) = USB_CSRL0_STALL ;
686+ } else {
687+ if ( pbdrv_usb_setup_data_to_send ) {
688+ // Clamp by host request size
689+ if ( setup_pkt . s . wLength < pbdrv_usb_setup_data_to_send_sz ) {
690+ pbdrv_usb_setup_data_to_send_sz = setup_pkt . s . wLength ;
691+ }
676692
677- if (!handled ) {
678- // send stall
679- HWREGH (USB0_BASE + USB_O_CSRL0 ) = USB_CSRL0_STALL ;
680- } else {
681- if (pbdrv_usb_setup_data_to_send ) {
682- // Clamp by host request size
683- if (setup_pkt .s .wLength < pbdrv_usb_setup_data_to_send_sz ) {
684- pbdrv_usb_setup_data_to_send_sz = setup_pkt .s .wLength ;
685- }
686-
687- // Send as much as we can in one chunk
688- usb_setup_send_chunk ();
689- if (pbdrv_usb_setup_data_to_send_sz == 0 ) {
690- pbdrv_usb_setup_data_to_send = 0 ;
691- HWREGH (USB0_BASE + USB_O_CSRL0 ) = USB_CSRL0_TXRDY | USB_CSRL0_DATAEND ;
692- } else {
693- HWREGH (USB0_BASE + USB_O_CSRL0 ) = USB_CSRL0_TXRDY ;
694- }
693+ // Send as much as we can in one chunk
694+ usb_setup_send_chunk ();
695+ if (pbdrv_usb_setup_data_to_send_sz == 0 ) {
696+ pbdrv_usb_setup_data_to_send = 0 ;
697+ HWREGH (USB0_BASE + USB_O_CSRL0 ) = USB_CSRL0_TXRDY | USB_CSRL0_DATAEND ;
695698 } else {
696- // Just get ready to send ACK, no data
697- HWREGH (USB0_BASE + USB_O_CSRL0 ) = USB_CSRL0_DATAEND ;
699+ HWREGH (USB0_BASE + USB_O_CSRL0 ) = USB_CSRL0_TXRDY ;
698700 }
699- }
700- } else if (pbdrv_usb_setup_data_to_send ) {
701- // Need to continue to TX data
702- usb_setup_send_chunk ();
703- if (pbdrv_usb_setup_data_to_send_sz == 0 ) {
704- pbdrv_usb_setup_data_to_send = 0 ;
705- HWREGH (USB0_BASE + USB_O_CSRL0 ) = USB_CSRL0_TXRDY | USB_CSRL0_DATAEND ;
706701 } else {
707- HWREGH (USB0_BASE + USB_O_CSRL0 ) = USB_CSRL0_TXRDY ;
702+ // Just get ready to send ACK, no data
703+ HWREGH (USB0_BASE + USB_O_CSRL0 ) = USB_CSRL0_DATAEND ;
708704 }
709705 }
706+ } else if (pbdrv_usb_setup_data_to_send ) {
707+ // Need to continue to TX data
708+ usb_setup_send_chunk ();
709+ if (pbdrv_usb_setup_data_to_send_sz == 0 ) {
710+ pbdrv_usb_setup_data_to_send = 0 ;
711+ HWREGH (USB0_BASE + USB_O_CSRL0 ) = USB_CSRL0_TXRDY | USB_CSRL0_DATAEND ;
712+ } else {
713+ HWREGH (USB0_BASE + USB_O_CSRL0 ) = USB_CSRL0_TXRDY ;
714+ }
710715 }
711716 }
712717
0 commit comments