X-Git-Url: https://codewiz.org/gitweb?a=blobdiff_plain;f=bertos%2Fcpu%2Fcortex-m3%2Fdrv%2Fusb_stm32.c;h=393b3cc4a49aa619b272ef802a519136770fdc97;hb=563795df4180aaceb7d69306551230c98fbca879;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..393b3cc4 100644 --- a/bertos/cpu/cortex-m3/drv/usb_stm32.c +++ b/bertos/cpu/cortex-m3/drv/usb_stm32.c @@ -148,18 +148,18 @@ static stm32_UsbMemSlot *mem_use; static stm32_UsbMemSlot memory_buffer[EP_MAX_NUM]; /* Endpoint TX and RX buffers */ -/// \cond -/* XXX: use the empty cond section to silent a buggy doxygen warning */ static size_t rx_size, tx_size; #define EP_BUFFER_SIZE _MIN(CONFIG_USB_BUFSIZE, USB_XFER_MAX_SIZE) STATIC_ASSERT(!(EP_BUFFER_SIZE & 0x03)); static uint8_t ep_buffer[EP_MAX_NUM][EP_BUFFER_SIZE] ALIGNED(4); -/// \endcond 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) { @@ -1123,13 +1123,14 @@ static void usb_endpointRead_complete(int ep) rx_size = ep_cnfg[ep].size; } -ssize_t usb_endpointRead(int ep, void *buffer, ssize_t size) +ssize_t usb_endpointReadTimeout(int ep, void *buffer, ssize_t size, + ticks_t timeout) { int ep_num = usb_ep_logical_to_hw(ep); 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)) @@ -1158,7 +1159,11 @@ ssize_t usb_endpointRead(int ep, void *buffer, ssize_t size) /* Blocking read */ __usb_ep_read(ep_num, ep_buffer[ep_num], size, usb_endpointRead_complete); - event_wait(&usb_event_done[ep_num >> 1]); + if (timeout < 0) + event_wait(&usb_event_done[ep_num >> 1]); + else + if (!event_waitTimeout(&usb_event_done[ep_num >> 1], timeout)) + return 0; memcpy(buffer, ep_buffer[ep_num], rx_size); return rx_size; @@ -1177,13 +1182,14 @@ static void usb_endpointWrite_complete(int ep) tx_size = ep_cnfg[ep].size; } -ssize_t usb_endpointWrite(int ep, const void *buffer, ssize_t size) +ssize_t usb_endpointWriteTimeout(int ep, const void *buffer, ssize_t size, + ticks_t timeout) { int ep_num = usb_ep_logical_to_hw(ep); 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)) @@ -1213,7 +1219,11 @@ ssize_t usb_endpointWrite(int ep, const void *buffer, ssize_t size) memcpy(ep_buffer[ep_num], buffer, size); __usb_ep_write(ep_num, ep_buffer[ep_num], size, usb_endpointWrite_complete); - event_wait(&usb_event_done[ep_num >> 1]); + if (timeout < 0) + event_wait(&usb_event_done[ep_num >> 1]); + else + if (!event_waitTimeout(&usb_event_done[ep_num >> 1], timeout)) + return 0; return tx_size; } @@ -1495,11 +1505,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 +1816,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 +1868,7 @@ static void usb_isr(void) { usb_isr_correct_transfer(interrupt); } + in_atomic = false; } /* USB: hardware initialization */