void usb_handle_setup(void) { rbdp->BDSTAT = DTSEN; // Reclaim reply buffer switch (bdp->BDADDR[USB_bmRequestType] & USB_bmRequestType_TypeMask) { case USB_bmRequestType_Standard: switch (bdp->BDADDR[USB_bmRequestType] & USB_bmRequestType_RecipientMask) { case USB_bmRequestType_Device: usb_handle_StandardDeviceRequest(bdp); break; case USB_bmRequestType_Interface: usb_handle_StandardInterfaceRequest(bdp); break; case USB_bmRequestType_Endpoint: usb_handle_StandardEndpointRequest(bdp); break; default: usb_RequestError(); } break; case USB_bmRequestType_Class: if (class_setup_handler) class_setup_handler(); break; case USB_bmRequestType_Vendor: if (vendor_setup_handler) class_setup_handler(); break; default: usb_RequestError(); } /* Prepare endpoint for new reception */ bdp->BDCNT = USB_EP0_BUFFER_SIZE; // Size of EP0, should always be ep0? (JTR in practice YES) // JTR, is the next OUT transfer to be a setup packet (DAT0) or a DATA packet (DAT1)? // note that this is not an entirely robust way of doing things. See the microchip stack for // further comments and a better system as this does not account for errors and retries. // JTR Breakdown of what is happening here FYI. //bdp->BDSTAT = (!(bdp->BDADDR[USB_bmRequestType] & USB_bmRequestType_PhaseMask) && // JTR meaning. If transfer was a CONTROL OUT then B7 (USB_bmRequestType_PhaseMask) of bmRequestType is '0' // && //bdp->BDADDR[USB_wLength] || bdp->BDADDR[USB_wLengthHigh]))? UOWN + DTS + DTSEN : UOWN + DTSEN; // If there is a CONTROL OUT DATA PACKET to follow then its count in (int) wLength will be != 0 // When both conditions are true then set for DAT1 (UOWN + DTS + DTSEN) // else set for DAT0 (UOWN + DTSEN) // See USB 2.0 spec 8.5.3 bdp->BDSTAT = (!(bdp->BDADDR[USB_bmRequestType] & USB_bmRequestType_PhaseMask) && (bdp->BDADDR[USB_wLength] || bdp->BDADDR[USB_wLengthHigh])) ? UOWN + DTS + DTSEN : UOWN + DTSEN; // JTR Note. For rbdp after a setup packet, the standard or class request handler will force the correct DTS state // JTR Note. that CONTROL IN and OUT DATA packet transfers do not come back here and there is no // univesal way and place of setting up EP0 after these DATA transfers in this stack. // JTR Note. that there is a PIC18 silicon errata issue that this does not address by being here. See DS80220F-page 6 EnablePacketTransfer(); }
void usb_handle_setup(void) { EP0_Inbdp->BDSTAT = DTSEN; // Reclaim reply buffer EnablePacketTransfer(); // JTR this is placed here to overcome a errate issue with early PIC18 USB pics. switch (EP0_Outbdp->BDADDR[USB_bmRequestType] & USB_bmRequestType_TypeMask) { case USB_bmRequestType_Standard: switch (EP0_Outbdp->BDADDR[USB_bmRequestType] & USB_bmRequestType_RecipientMask) { case USB_bmRequestType_Device: usb_handle_StandardDeviceRequest(EP0_Outbdp); break; case USB_bmRequestType_Interface: usb_handle_StandardInterfaceRequest(EP0_Outbdp); break; case USB_bmRequestType_Endpoint: usb_handle_StandardEndpointRequest(EP0_Outbdp); break; default: usb_RequestError(); } break; case USB_bmRequestType_Class: if (class_setup_handler) class_setup_handler(); break; case USB_bmRequestType_Vendor: //ROBOTS FIX: http://dangerousprototypes.com/forum/viewtopic.php?f=39&t=3849&view=unread#unread // did call class_setup_handler(); if (vendor_setup_handler) vendor_setup_handler(); break; default: usb_RequestError(); } /* Prepare endpoint for new reception */ EP0_Outbdp->BDCNT = USB_EP0_BUFFER_SIZE; // Size of EP0, should always be ep0? // JTR, is the next OUT transfer to be a setup packet (DAT0) or a DATA packet (DAT1)? // note that this is not an entirely robust way of doing things. See the microchip stack for // further comments and a better system as this does not account for errors and retries // and it results in the SIE not accepting the final out ZLP status packet for IN transfers // with a data stage. However it works but it is not anything to be proud of... EP0_Outbdp->BDSTAT = (!(EP0_Outbdp->BDADDR[USB_bmRequestType] & USB_bmRequestType_PhaseMask) && (EP0_Outbdp->BDADDR[USB_wLength] || EP0_Outbdp->BDADDR[USB_wLengthHigh])) ? UOWN + DTS + DTSEN : UOWN + DTSEN; }