From 91216f24048ae3499ec96d06cd19bbe9a384c9dc Mon Sep 17 00:00:00 2001 From: gdisirio Date: Sat, 26 Apr 2014 09:58:18 +0000 Subject: [PATCH] git-svn-id: svn://svn.code.sf.net/p/chibios/svn/branches/kernel_3_dev@6886 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/hal/include/usb.h | 6 ++++++ os/hal/ports/STM32/LLD/OTGv1/usb_lld.h | 5 +++++ os/hal/ports/STM32/LLD/USBv1/usb_lld.h | 5 +++++ os/hal/src/usb.c | 25 ++++++++++++++++++++++++- 4 files changed, 40 insertions(+), 1 deletion(-) diff --git a/os/hal/include/usb.h b/os/hal/include/usb.h index ef470bf23..790a08fab 100644 --- a/os/hal/include/usb.h +++ b/os/hal/include/usb.h @@ -78,6 +78,12 @@ #define USB_EARLY_SET_ADDRESS 0 #define USB_LATE_SET_ADDRESS 1 +#define USB_EP0_STATUS_STAGE_SW 0 +#define USB_EP0_STATUS_STAGE_HW 1 + +#define USB_SET_ADDRESS_ACK_SW 0 +#define USB_SET_ADDRESS_ACK_HW 1 + /** * @name Helper macros for USB descriptors * @{ diff --git a/os/hal/ports/STM32/LLD/OTGv1/usb_lld.h b/os/hal/ports/STM32/LLD/OTGv1/usb_lld.h index 31e0094d7..d1609e069 100644 --- a/os/hal/ports/STM32/LLD/OTGv1/usb_lld.h +++ b/os/hal/ports/STM32/LLD/OTGv1/usb_lld.h @@ -42,6 +42,11 @@ #define USB_MAX_ENDPOINTS 5 #endif +/** + * @brief Status stage handling method. + */ +#define USB_EP0_STATUS_STAGE USB_EP0_STATUS_STAGE_SW + /** * @brief The address can be changed immediately upon packet reception. */ diff --git a/os/hal/ports/STM32/LLD/USBv1/usb_lld.h b/os/hal/ports/STM32/LLD/USBv1/usb_lld.h index 042129758..828129032 100644 --- a/os/hal/ports/STM32/LLD/USBv1/usb_lld.h +++ b/os/hal/ports/STM32/LLD/USBv1/usb_lld.h @@ -38,6 +38,11 @@ */ #define USB_MAX_ENDPOINTS USB_ENDOPOINTS_NUMBER +/** + * @brief Status stage handling method. + */ +#define USB_EP0_STATUS_STAGE USB_EP0_STATUS_STAGE_SW + /** * @brief This device requires the address change after the status packet. */ diff --git a/os/hal/src/usb.c b/os/hal/src/usb.c index a84702b5b..9b292b7d9 100644 --- a/os/hal/src/usb.c +++ b/os/hal/src/usb.c @@ -623,7 +623,12 @@ void _usb_ep0setup(USBDriver *usbp, usbep_t ep) { return; } } - +#if (USB_SET_ADDRESS_ACK_HANDLING == USB_SET_ADDRESS_ACK_HW) + if (usbp->setup[1] == USB_REQ_SET_ADDRESS) { + /* Zero-length packet sent by hardware */ + return; + } +#endif /* Transfer preparation. The request handler must have populated correctly the fields ep0next, ep0n and ep0endcb using the macro usbSetupTransfer().*/ @@ -645,10 +650,14 @@ void _usb_ep0setup(USBDriver *usbp, usbep_t ep) { /* No transmission phase, directly receiving the zero sized status packet.*/ usbp->ep0state = USB_EP0_WAITING_STS; +#if (USB_EP0_STATUS_STAGE == USB_EP0_STATUS_STAGE_SW) usbPrepareReceive(usbp, 0, NULL, 0); osalSysLockFromISR(); usbStartReceiveI(usbp, 0); osalSysUnlockFromISR(); +#else + usb_lld_end_setup(usbp, ep); +#endif } } else { @@ -665,10 +674,14 @@ void _usb_ep0setup(USBDriver *usbp, usbep_t ep) { /* No receive phase, directly sending the zero sized status packet.*/ usbp->ep0state = USB_EP0_SENDING_STS; +#if (USB_EP0_STATUS_STAGE == USB_EP0_STATUS_STAGE_SW) usbPrepareTransmit(usbp, 0, NULL, 0); osalSysLockFromISR(); usbStartTransmitI(usbp, 0); osalSysUnlockFromISR(); +#else + usb_lld_end_setup(usbp, ep); +#endif } } } @@ -705,10 +718,14 @@ void _usb_ep0in(USBDriver *usbp, usbep_t ep) { case USB_EP0_WAITING_TX0: /* Transmit phase over, receiving the zero sized status packet.*/ usbp->ep0state = USB_EP0_WAITING_STS; +#if (USB_EP0_STATUS_STAGE == USB_EP0_STATUS_STAGE_SW) usbPrepareReceive(usbp, 0, NULL, 0); osalSysLockFromISR(); usbStartReceiveI(usbp, 0); osalSysUnlockFromISR(); +#else + usb_lld_end_setup(usbp, ep); +#endif return; case USB_EP0_SENDING_STS: /* Status packet sent, invoking the callback if defined.*/ @@ -745,16 +762,22 @@ void _usb_ep0out(USBDriver *usbp, usbep_t ep) { case USB_EP0_RX: /* Receive phase over, sending the zero sized status packet.*/ usbp->ep0state = USB_EP0_SENDING_STS; +#if (USB_EP0_STATUS_STAGE == USB_EP0_STATUS_STAGE_SW) usbPrepareTransmit(usbp, 0, NULL, 0); osalSysLockFromISR(); usbStartTransmitI(usbp, 0); osalSysUnlockFromISR(); +#else + usb_lld_end_setup(usbp, ep); +#endif return; case USB_EP0_WAITING_STS: /* Status packet received, it must be zero sized, invoking the callback if defined.*/ +#if (USB_EP0_STATUS_STAGE == USB_EP0_STATUS_STAGE_SW) if (usbGetReceiveTransactionSizeI(usbp, 0) != 0) break; +#endif if (usbp->ep0endcb != NULL) usbp->ep0endcb(usbp); usbp->ep0state = USB_EP0_WAITING_SETUP;