git-svn-id: svn://svn.code.sf.net/p/chibios/svn/branches/kernel_3_dev@6886 35acf78f-673a-0410-8e92-d51de3d6d3f4

This commit is contained in:
gdisirio 2014-04-26 09:58:18 +00:00
parent e28a45245c
commit 91216f2404
4 changed files with 40 additions and 1 deletions

View File

@ -78,6 +78,12 @@
#define USB_EARLY_SET_ADDRESS 0 #define USB_EARLY_SET_ADDRESS 0
#define USB_LATE_SET_ADDRESS 1 #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 * @name Helper macros for USB descriptors
* @{ * @{

View File

@ -42,6 +42,11 @@
#define USB_MAX_ENDPOINTS 5 #define USB_MAX_ENDPOINTS 5
#endif #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. * @brief The address can be changed immediately upon packet reception.
*/ */

View File

@ -38,6 +38,11 @@
*/ */
#define USB_MAX_ENDPOINTS USB_ENDOPOINTS_NUMBER #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. * @brief This device requires the address change after the status packet.
*/ */

View File

@ -623,7 +623,12 @@ void _usb_ep0setup(USBDriver *usbp, usbep_t ep) {
return; 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 /* Transfer preparation. The request handler must have populated
correctly the fields ep0next, ep0n and ep0endcb using the macro correctly the fields ep0next, ep0n and ep0endcb using the macro
usbSetupTransfer().*/ usbSetupTransfer().*/
@ -645,10 +650,14 @@ void _usb_ep0setup(USBDriver *usbp, usbep_t ep) {
/* No transmission phase, directly receiving the zero sized status /* No transmission phase, directly receiving the zero sized status
packet.*/ packet.*/
usbp->ep0state = USB_EP0_WAITING_STS; usbp->ep0state = USB_EP0_WAITING_STS;
#if (USB_EP0_STATUS_STAGE == USB_EP0_STATUS_STAGE_SW)
usbPrepareReceive(usbp, 0, NULL, 0); usbPrepareReceive(usbp, 0, NULL, 0);
osalSysLockFromISR(); osalSysLockFromISR();
usbStartReceiveI(usbp, 0); usbStartReceiveI(usbp, 0);
osalSysUnlockFromISR(); osalSysUnlockFromISR();
#else
usb_lld_end_setup(usbp, ep);
#endif
} }
} }
else { else {
@ -665,10 +674,14 @@ void _usb_ep0setup(USBDriver *usbp, usbep_t ep) {
/* No receive phase, directly sending the zero sized status /* No receive phase, directly sending the zero sized status
packet.*/ packet.*/
usbp->ep0state = USB_EP0_SENDING_STS; usbp->ep0state = USB_EP0_SENDING_STS;
#if (USB_EP0_STATUS_STAGE == USB_EP0_STATUS_STAGE_SW)
usbPrepareTransmit(usbp, 0, NULL, 0); usbPrepareTransmit(usbp, 0, NULL, 0);
osalSysLockFromISR(); osalSysLockFromISR();
usbStartTransmitI(usbp, 0); usbStartTransmitI(usbp, 0);
osalSysUnlockFromISR(); 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: case USB_EP0_WAITING_TX0:
/* Transmit phase over, receiving the zero sized status packet.*/ /* Transmit phase over, receiving the zero sized status packet.*/
usbp->ep0state = USB_EP0_WAITING_STS; usbp->ep0state = USB_EP0_WAITING_STS;
#if (USB_EP0_STATUS_STAGE == USB_EP0_STATUS_STAGE_SW)
usbPrepareReceive(usbp, 0, NULL, 0); usbPrepareReceive(usbp, 0, NULL, 0);
osalSysLockFromISR(); osalSysLockFromISR();
usbStartReceiveI(usbp, 0); usbStartReceiveI(usbp, 0);
osalSysUnlockFromISR(); osalSysUnlockFromISR();
#else
usb_lld_end_setup(usbp, ep);
#endif
return; return;
case USB_EP0_SENDING_STS: case USB_EP0_SENDING_STS:
/* Status packet sent, invoking the callback if defined.*/ /* Status packet sent, invoking the callback if defined.*/
@ -745,16 +762,22 @@ void _usb_ep0out(USBDriver *usbp, usbep_t ep) {
case USB_EP0_RX: case USB_EP0_RX:
/* Receive phase over, sending the zero sized status packet.*/ /* Receive phase over, sending the zero sized status packet.*/
usbp->ep0state = USB_EP0_SENDING_STS; usbp->ep0state = USB_EP0_SENDING_STS;
#if (USB_EP0_STATUS_STAGE == USB_EP0_STATUS_STAGE_SW)
usbPrepareTransmit(usbp, 0, NULL, 0); usbPrepareTransmit(usbp, 0, NULL, 0);
osalSysLockFromISR(); osalSysLockFromISR();
usbStartTransmitI(usbp, 0); usbStartTransmitI(usbp, 0);
osalSysUnlockFromISR(); osalSysUnlockFromISR();
#else
usb_lld_end_setup(usbp, ep);
#endif
return; return;
case USB_EP0_WAITING_STS: case USB_EP0_WAITING_STS:
/* Status packet received, it must be zero sized, invoking the callback /* Status packet received, it must be zero sized, invoking the callback
if defined.*/ if defined.*/
#if (USB_EP0_STATUS_STAGE == USB_EP0_STATUS_STAGE_SW)
if (usbGetReceiveTransactionSizeI(usbp, 0) != 0) if (usbGetReceiveTransactionSizeI(usbp, 0) != 0)
break; break;
#endif
if (usbp->ep0endcb != NULL) if (usbp->ep0endcb != NULL)
usbp->ep0endcb(usbp); usbp->ep0endcb(usbp);
usbp->ep0state = USB_EP0_WAITING_SETUP; usbp->ep0state = USB_EP0_WAITING_SETUP;