X-Git-Url: https://codewiz.org/gitweb?a=blobdiff_plain;f=bertos%2Fcpu%2Fcortex-m3%2Fdrv%2Fusb_stm32.c;h=924f86d2095e22204576cdfe051d569835402d1f;hb=b89651ff400d369dc9cba9af837b88dde647e22f;hp=154f0a04743a1b8f9b874a633031162730cfa93d;hpb=93308de29d9092161217cfff1b1375b482937214;p=bertos.git diff --git a/bertos/cpu/cortex-m3/drv/usb_stm32.c b/bertos/cpu/cortex-m3/drv/usb_stm32.c index 154f0a04..924f86d2 100644 --- a/bertos/cpu/cortex-m3/drv/usb_stm32.c +++ b/bertos/cpu/cortex-m3/drv/usb_stm32.c @@ -58,6 +58,10 @@ #include "usb_stm32.h" +/* XXX: consider to move this to cfg/compiler.h */ +#define ALIGNED(x) __attribute__ ((__aligned__(x))) + +/* XXX: consider to move this to cfg/macros.h */ #define ALIGN_UP(value, align) (((value) & ((align) - 1)) ? \ (((value) + ((align) - 1)) & ~((align) - 1)) : \ (value)) @@ -88,7 +92,8 @@ struct stm32_usb static struct stm32_usb *usb = (struct stm32_usb *)USB_BASE_ADDR; /* Endpoint descriptors: used for handling requests to use with endpoints */ -static stm32_UsbEp ep_cnfg[ENP_MAX_NUMB]; +static stm32_UsbEp ep_cnfg[EP_MAX_NUM]; +STATIC_ASSERT(EP_MAX_NUM <= EP_MAX_HW_NUM); /* USB EP0 control descriptor */ static const UsbEndpointDesc USB_CtrlEpDescr0 = @@ -144,8 +149,19 @@ static UsbDevice *usb_dev; static stm32_UsbMemSlot *mem_use; /* USB packet memory management: memory buffer metadata */ -#define EP_MAX_SLOTS 16 -static stm32_UsbMemSlot memory_buffer[EP_MAX_SLOTS]; +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 bool rx_done, tx_done; +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 /* Allocate a free block of the packet memory */ static stm32_UsbMemSlot *usb_malloc(void) @@ -198,13 +214,13 @@ static bool usb_alloc_buffer(uint16_t *pOffset, uint32_t *size, mem = mem->next; } /* Check for out-of-memory condition */ - if ((*pOffset + max_size) >= USB_BDT_OFFSET) + if (UNLIKELY((*pOffset + max_size) >= USB_BDT_OFFSET)) return false; /* * Allocate a new memory block, next to the last allocated block. */ mem_useNew = usb_malloc(); - if (mem_useNew == NULL) + if (UNLIKELY(mem_useNew == NULL)) return false; /* Insert the block to the list of allocated blocks */ if (mem_use == NULL) @@ -675,12 +691,18 @@ out: \ static stm32_UsbIoStatus __usb_ep_read(int ep, void *buffer, ssize_t size, void (*complete)(int)) { - if (UNLIKELY(ep >= ENP_MAX_NUMB)) + if (UNLIKELY((ep >= EP_MAX_NUM) || (ep & 0x01))) { + LOG_ERR("%s: invalid EP number %d\n", __func__, ep); + ASSERT(0); + return STALLED; + } + if (UNLIKELY((size_t)buffer & 0x03)) + { + LOG_ERR("%s: unaligned buffer @ %p\n", __func__, buffer); ASSERT(0); return STALLED; } - ASSERT(!(ep & 0x01)); return USB_EP_IO(ep, read, buffer, size, complete); } @@ -688,12 +710,18 @@ __usb_ep_read(int ep, void *buffer, ssize_t size, void (*complete)(int)) static stm32_UsbIoStatus __usb_ep_write(int ep, const void *buffer, ssize_t size, void (*complete)(int)) { - if (UNLIKELY(ep >= ENP_MAX_NUMB)) + if (UNLIKELY((ep >= EP_MAX_NUM) || !(ep & 0x01))) { + LOG_ERR("%s: invalid EP number %d\n", __func__, ep); + ASSERT(0); + return STALLED; + } + if (UNLIKELY((size_t)buffer & 0x03)) + { + LOG_ERR("%s: unaligned buffer @ %p\n", __func__, buffer); ASSERT(0); return STALLED; } - ASSERT(ep & 0x01); return USB_EP_IO(ep, write, buffer, size, complete); } @@ -1080,14 +1108,9 @@ static void usb_status_handler(UNUSED_ARG(int, EP)) } } -static bool rx_done; -static size_t rx_size; -static uint8_t rx_buffer[_MIN(CONFIG_USB_RXBUFSIZE, USB_RX_MAX_SIZE)] - __attribute__ ((__aligned__(4))); - static void usb_endpointRead_complete(int ep) { - if (UNLIKELY(ep >= ENP_MAX_NUMB)) + if (UNLIKELY(ep >= EP_MAX_NUM)) { ASSERT(0); return; @@ -1101,13 +1124,7 @@ static void usb_endpointRead_complete(int ep) ssize_t usb_endpointRead(int ep, void *buffer, ssize_t size) { int ep_num = usb_ep_logical_to_hw(ep); - ssize_t max_size = sizeof(rx_buffer); - - if (UNLIKELY((size_t)buffer & 0x03)) - { - LOG_ERR("unaligned buffer @ %p\n", buffer); - ASSERT(0); - } + ssize_t max_size = sizeof(ep_buffer[ep_num]); /* Non-blocking read for EP0 */ if (ep_num == CTRL_ENP_OUT) @@ -1115,7 +1132,7 @@ ssize_t usb_endpointRead(int ep, void *buffer, ssize_t size) size = usb_size(size, usb_le16_to_cpu(setup_packet.wLength)); if (UNLIKELY(size > max_size)) { - LOG_ERR("%s: rx_buffer exceeded, try to enlarge CONFIG_USB_RXBUFSIZE\n", + LOG_ERR("%s: ep_buffer exceeded, try to enlarge CONFIG_USB_BUFSIZE\n", __func__); ASSERT(0); return -USB_BUF_OVERFLOW; @@ -1124,9 +1141,9 @@ ssize_t usb_endpointRead(int ep, void *buffer, ssize_t size) usb_status_handler(ep_num); else { - __usb_ep_read(ep_num, rx_buffer, size, + __usb_ep_read(ep_num, ep_buffer[ep_num], size, usb_status_handler); - memcpy(buffer, rx_buffer, size); + memcpy(buffer, ep_buffer[ep_num], size); } return size; } @@ -1137,22 +1154,18 @@ ssize_t usb_endpointRead(int ep, void *buffer, ssize_t size) rx_size = 0; /* Blocking read */ - __usb_ep_read(ep_num, rx_buffer, size, usb_endpointRead_complete); + __usb_ep_read(ep_num, ep_buffer[ep_num], size, + usb_endpointRead_complete); while (!rx_done) cpu_relax(); - memcpy(buffer, rx_buffer, rx_size); + memcpy(buffer, ep_buffer[ep_num], rx_size); return rx_size; } -static bool tx_done; -static size_t tx_size; -static uint8_t tx_buffer[_MIN(CONFIG_USB_TXBUFSIZE, USB_TX_MAX_SIZE)] - __attribute__ ((__aligned__(4))); - static void usb_endpointWrite_complete(int ep) { - if (UNLIKELY(ep >= ENP_MAX_NUMB)) + if (UNLIKELY(ep >= EP_MAX_NUM)) { ASSERT(0); return; @@ -1166,13 +1179,7 @@ static void usb_endpointWrite_complete(int ep) ssize_t usb_endpointWrite(int ep, const void *buffer, ssize_t size) { int ep_num = usb_ep_logical_to_hw(ep); - ssize_t max_size = sizeof(tx_buffer); - - if (UNLIKELY((size_t)buffer & 0x03)) - { - LOG_ERR("unaligned buffer @ %p\n", buffer); - ASSERT(0); - } + ssize_t max_size = sizeof(ep_buffer[ep_num]); /* Non-blocking write for EP0 */ if (ep_num == CTRL_ENP_IN) @@ -1180,7 +1187,7 @@ ssize_t usb_endpointWrite(int ep, const void *buffer, ssize_t size) size = usb_size(size, usb_le16_to_cpu(setup_packet.wLength)); if (UNLIKELY(size > max_size)) { - LOG_ERR("%s: tx_buffer exceeded, try to enlarge CONFIG_USB_TXBUFSIZE\n", + LOG_ERR("%s: ep_buffer exceeded, try to enlarge CONFIG_USB_BUFSIZE\n", __func__); ASSERT(0); return -USB_BUF_OVERFLOW; @@ -1189,8 +1196,8 @@ ssize_t usb_endpointWrite(int ep, const void *buffer, ssize_t size) usb_status_handler(ep_num); else { - memcpy(tx_buffer, buffer, size); - __usb_ep_write(ep_num, tx_buffer, size, + memcpy(ep_buffer[ep_num], buffer, size); + __usb_ep_write(ep_num, ep_buffer[ep_num], size, usb_status_handler); } return size; @@ -1202,8 +1209,9 @@ ssize_t usb_endpointWrite(int ep, const void *buffer, ssize_t size) tx_size = 0; /* Blocking write */ - memcpy(tx_buffer, buffer, size); - __usb_ep_write(ep_num, tx_buffer, size, usb_endpointWrite_complete); + memcpy(ep_buffer[ep_num], buffer, size); + __usb_ep_write(ep_num, ep_buffer[ep_num], size, + usb_endpointWrite_complete); while (!tx_done) cpu_relax();