X-Git-Url: https://codewiz.org/gitweb?a=blobdiff_plain;f=bertos%2Fcpu%2Fcortex-m3%2Fdrv%2Fusb_stm32.c;h=ac3f55fa40bc2af8ffb05a10130a43adf464647e;hb=80ac3ae104b48f42eb8911de0879a477cf812a4c;hp=c562512e1bb9858230136bcaf41d43e07d68e3db;hpb=04c4555a23598bef73d01a903c03e2dd5ac238cf;p=bertos.git diff --git a/bertos/cpu/cortex-m3/drv/usb_stm32.c b/bertos/cpu/cortex-m3/drv/usb_stm32.c index c562512e..ac3f55fa 100644 --- a/bertos/cpu/cortex-m3/drv/usb_stm32.c +++ b/bertos/cpu/cortex-m3/drv/usb_stm32.c @@ -160,6 +160,9 @@ static uint8_t ep_buffer[EP_MAX_NUM][EP_BUFFER_SIZE] ALIGNED(4); static Event usb_event_done[EP_MAX_SLOTS]; +/* Check if we're running in atomic (non-sleepable) context or not */ +static volatile bool in_atomic = false; + /* Allocate a free block of the packet memory */ static stm32_UsbMemSlot *usb_malloc(void) { @@ -1129,7 +1132,7 @@ ssize_t usb_endpointRead(int ep, void *buffer, ssize_t size) ssize_t max_size = sizeof(ep_buffer[ep_num]); /* Non-blocking read for EP0 */ - if (ep_num == CTRL_ENP_OUT) + if (in_atomic && (ep_num == CTRL_ENP_OUT)) { size = usb_size(size, usb_le16_to_cpu(setup_packet.wLength)); if (UNLIKELY(size > max_size)) @@ -1183,7 +1186,7 @@ ssize_t usb_endpointWrite(int ep, const void *buffer, ssize_t size) ssize_t max_size = sizeof(ep_buffer[ep_num]); /* Non-blocking write for EP0 */ - if (ep_num == CTRL_ENP_IN) + if (in_atomic && (ep_num == CTRL_ENP_IN)) { size = usb_size(size, usb_le16_to_cpu(setup_packet.wLength)); if (UNLIKELY(size > max_size)) @@ -1495,11 +1498,8 @@ static void usb_get_descriptor_handler(void) if ((setup_packet.mRequestType & USB_RECIP_MASK) == USB_RECIP_DEVICE) usb_get_descriptor(); - /* Getting descriptor for a device is a standard request */ - else if ((setup_packet.mRequestType & USB_DIR_MASK) == USB_DIR_IN) - usb_event_handler(usb_dev); else - ep_cnfg[CTRL_ENP_OUT].status = STALLED; + usb_event_handler(usb_dev); } /* USB setup packet: SET_ADDRESS handler */ @@ -1809,6 +1809,9 @@ static void usb_isr(void) interrupt.status = usb->ISTR; interrupt.status &= usb->CNTR | 0x1f; + /* Set the context as atomic */ + in_atomic = true; + if (interrupt.PMAOVR) { LOG_WARN("%s: DMA overrun / underrun\n", __func__); @@ -1858,6 +1861,7 @@ static void usb_isr(void) { usb_isr_correct_transfer(interrupt); } + in_atomic = false; } /* USB: hardware initialization */