aboutsummaryrefslogtreecommitdiffstats
path: root/os
diff options
context:
space:
mode:
authorgdisirio <gdisirio@35acf78f-673a-0410-8e92-d51de3d6d3f4>2014-04-26 09:58:18 +0000
committergdisirio <gdisirio@35acf78f-673a-0410-8e92-d51de3d6d3f4>2014-04-26 09:58:18 +0000
commit91216f24048ae3499ec96d06cd19bbe9a384c9dc (patch)
tree069ec000b9e3742b210fa892968cc846983ee929 /os
parente28a45245cae96beaa746ea22802185c44bd2fd5 (diff)
downloadChibiOS-91216f24048ae3499ec96d06cd19bbe9a384c9dc.tar.gz
ChibiOS-91216f24048ae3499ec96d06cd19bbe9a384c9dc.tar.bz2
ChibiOS-91216f24048ae3499ec96d06cd19bbe9a384c9dc.zip
git-svn-id: svn://svn.code.sf.net/p/chibios/svn/branches/kernel_3_dev@6886 35acf78f-673a-0410-8e92-d51de3d6d3f4
Diffstat (limited to 'os')
-rw-r--r--os/hal/include/usb.h6
-rw-r--r--os/hal/ports/STM32/LLD/OTGv1/usb_lld.h5
-rw-r--r--os/hal/ports/STM32/LLD/USBv1/usb_lld.h5
-rw-r--r--os/hal/src/usb.c25
4 files changed, 40 insertions, 1 deletions
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
@@ -43,6 +43,11 @@
#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.
*/
#define USB_SET_ADDRESS_MODE USB_EARLY_SET_ADDRESS
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
@@ -39,6 +39,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.
*/
#define USB_SET_ADDRESS_MODE USB_LATE_SET_ADDRESS
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;