From e74213d5c3646e173d323c8d0f6033c6ea4ed57a Mon Sep 17 00:00:00 2001 From: Giovanni Di Sirio Date: Sat, 26 Dec 2015 16:54:26 +0000 Subject: Synchronous USB API ready for testing, OTGv1 only so far. git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@8649 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/hal/ports/STM32/LLD/OTGv1/usb_lld.c | 4 ++-- os/hal/ports/STM32/LLD/OTGv1/usb_lld.h | 6 +++-- os/hal/src/usb.c | 43 ++++++++++++++++++++++++++++++++-- 3 files changed, 47 insertions(+), 6 deletions(-) (limited to 'os') diff --git a/os/hal/ports/STM32/LLD/OTGv1/usb_lld.c b/os/hal/ports/STM32/LLD/OTGv1/usb_lld.c index ab735b903..00ada1203 100644 --- a/os/hal/ports/STM32/LLD/OTGv1/usb_lld.c +++ b/os/hal/ports/STM32/LLD/OTGv1/usb_lld.c @@ -1005,7 +1005,7 @@ void usb_lld_init_endpoint(USBDriver *usbp, usbep_t ep) { /* OUT endpoint activation or deactivation.*/ otgp->oe[ep].DOEPTSIZ = 0; - if (usbp->epc[ep]->out_maxsize != 0) { + if (usbp->epc[ep]->out_state != NULL) { otgp->oe[ep].DOEPCTL = ctl | DOEPCTL_MPSIZ(usbp->epc[ep]->out_maxsize); otgp->DAINTMSK |= DAINTMSK_OEPM(ep); } @@ -1016,7 +1016,7 @@ void usb_lld_init_endpoint(USBDriver *usbp, usbep_t ep) { /* IN endpoint activation or deactivation.*/ otgp->ie[ep].DIEPTSIZ = 0; - if (usbp->epc[ep]->in_maxsize != 0) { + if (usbp->epc[ep]->in_state != NULL) { /* FIFO allocation for the IN endpoint.*/ fsize = usbp->epc[ep]->in_maxsize / 4; if (usbp->epc[ep]->in_multiplier > 1) diff --git a/os/hal/ports/STM32/LLD/OTGv1/usb_lld.h b/os/hal/ports/STM32/LLD/OTGv1/usb_lld.h index f59685c43..c90424c36 100644 --- a/os/hal/ports/STM32/LLD/OTGv1/usb_lld.h +++ b/os/hal/ports/STM32/LLD/OTGv1/usb_lld.h @@ -314,12 +314,14 @@ typedef struct { uint16_t out_maxsize; /** * @brief @p USBEndpointState associated to the IN endpoint. - * @details This structure maintains the state of the IN endpoint. + * @details This structure maintains the state of the IN endpoint, + * set to @p NULL if the IN endpoint is not used. */ USBInEndpointState *in_state; /** * @brief @p USBEndpointState associated to the OUT endpoint. - * @details This structure maintains the state of the OUT endpoint. + * @details This structure maintains the state of the OUT endpoint, + * set to @p NULL if the OUT endpoint is not used. */ USBOutEndpointState *out_state; /* End of the mandatory fields.*/ diff --git a/os/hal/src/usb.c b/os/hal/src/usb.c index 14d345b09..ce888e570 100644 --- a/os/hal/src/usb.c +++ b/os/hal/src/usb.c @@ -347,6 +347,14 @@ void usbInitEndpointI(USBDriver *usbp, usbep_t ep, /* Logically enabling the endpoint in the USBDriver structure.*/ usbp->epc[ep] = epcp; + /* Clearing the state structures, custom fields as well.*/ + if (epcp->in_state != NULL) { + memset(epcp->in_state, 0, sizeof(USBInEndpointState)); + } + if (epcp->out_state != NULL) { + memset(epcp->out_state, 0, sizeof(USBOutEndpointState)); + } + /* Low level endpoint activation.*/ usb_lld_init_endpoint(usbp, ep); } @@ -504,9 +512,10 @@ bool usbStartTransmitI(USBDriver *usbp, usbep_t ep) { * @param[in] n transaction size. It is recommended a multiple of * the packet size because the excess is discarded. * - * @return The received data effective size, it can be less than + * @return The received effective data size, it can be less than * the amount specified. * @retval MSG_RESET operation aborted by a reset. + * @retval MSG_TIMEOUT operation aborted by a suspend. * * @api */ @@ -534,6 +543,7 @@ msg_t usbReceive(USBDriver *usbp, usbep_t ep, uint8_t *buf, size_t n) { * @return The operation status. * @retval MSG_OK operation performed successfully. * @retval MSG_RESET operation aborted by a reset. + * @retval MSG_TIMEOUT operation aborted by a suspend. * * @api */ @@ -625,6 +635,17 @@ void _usb_reset(USBDriver *usbp) { /* Invalidates all endpoints into the USBDriver structure.*/ for (i = 0; i <= (unsigned)USB_MAX_ENDPOINTS; i++) { +#if USB_USE_WAIT == TRUE + /* Signaling the event to threads waiting on endpoints.*/ + if (usbp->epc[i] != NULL) { + if (usbp->epc[i]->in_state != NULL) { + osalThreadResumeI(&usbp->epc[i]->in_state->thread, MSG_RESET); + } + if (usbp->epc[i]->out_state != NULL) { + osalThreadResumeI(&usbp->epc[i]->out_state->thread, MSG_RESET); + } + } +#endif usbp->epc[i] = NULL; } @@ -654,6 +675,24 @@ void _usb_suspend(USBDriver *usbp) { /* Notification of suspend event.*/ _usb_isr_invoke_event_cb(usbp, USB_EVENT_SUSPEND); + + /* Signaling the event to threads waiting on endpoints.*/ +#if USB_USE_WAIT == TRUE + { + unsigned i; + + for (i = 0; i <= (unsigned)USB_MAX_ENDPOINTS; i++) { + if (usbp->epc[i] != NULL) { + if (usbp->epc[i]->in_state != NULL) { + osalThreadResumeI(&usbp->epc[i]->in_state->thread, MSG_TIMEOUT); + } + if (usbp->epc[i]->out_state != NULL) { + osalThreadResumeI(&usbp->epc[i]->out_state->thread, MSG_TIMEOUT); + } + } + } + } +#endif } /** @@ -668,7 +707,7 @@ void _usb_suspend(USBDriver *usbp) { void _usb_wakeup(USBDriver *usbp) { /* State transition.*/ - usbp->state = USB_ACTIVE; + usbp->state = USB_ACTIVE; /* Notification of suspend event.*/ _usb_isr_invoke_event_cb(usbp, USB_EVENT_WAKEUP); -- cgit v1.2.3