From b6b473a6a1fde7e7154dc2f1a2abaa395d526f62 Mon Sep 17 00:00:00 2001 From: gdisirio Date: Mon, 13 Aug 2012 10:14:45 +0000 Subject: Performance improvements to the STM32 OTG driver. git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@4562 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- demos/ARMCM4-STM32F407-LWIP-FATFS-USB/main.c | 9 ++- os/hal/include/serial_usb.h | 4 +- os/hal/platforms/STM32/OTGv1/usb_lld.c | 67 ++++++++++++-------- os/hal/platforms/STM32/OTGv1/usb_lld.h | 6 ++ testhal/STM32F4xx/USB_CDC/.cproject | 50 +++++++++++++++ testhal/STM32F4xx/USB_CDC/.project | 95 ++++++++++++++++++++++++++++ testhal/STM32F4xx/USB_CDC/main.c | 9 ++- 7 files changed, 206 insertions(+), 34 deletions(-) create mode 100644 testhal/STM32F4xx/USB_CDC/.cproject create mode 100644 testhal/STM32F4xx/USB_CDC/.project diff --git a/demos/ARMCM4-STM32F407-LWIP-FATFS-USB/main.c b/demos/ARMCM4-STM32F407-LWIP-FATFS-USB/main.c index f23488ec8..0b1651e2a 100644 --- a/demos/ARMCM4-STM32F407-LWIP-FATFS-USB/main.c +++ b/demos/ARMCM4-STM32F407-LWIP-FATFS-USB/main.c @@ -364,13 +364,14 @@ static const USBEndpointConfig ep1config = { 0x0000, &ep1instate, NULL, + 2, NULL }; /** - * @brief OUT EP2 state. + * @brief IN EP2 state. */ -USBOutEndpointState ep2outstate; +USBInEndpointState ep2instate; /** * @brief EP2 initialization structure (IN only). @@ -382,8 +383,9 @@ static const USBEndpointConfig ep2config = { NULL, 0x0010, 0x0000, + &ep2instate, NULL, - &ep2outstate, + 1, NULL }; @@ -404,6 +406,7 @@ static const USBEndpointConfig ep3config = { 0x0040, NULL, &ep3outstate, + 0, NULL }; diff --git a/os/hal/include/serial_usb.h b/os/hal/include/serial_usb.h index 4ad65d76d..104375391 100644 --- a/os/hal/include/serial_usb.h +++ b/os/hal/include/serial_usb.h @@ -47,11 +47,11 @@ * @brief Serial over USB buffers size. * @details Configuration parameter, the buffer size must be a multiple of * the USB data endpoint maximum packet size. - * @note The default is 64 bytes for both the transmission and receive + * @note The default is 256 bytes for both the transmission and receive * buffers. */ #if !defined(SERIAL_USB_BUFFERS_SIZE) || defined(__DOXYGEN__) -#define SERIAL_USB_BUFFERS_SIZE 64 +#define SERIAL_USB_BUFFERS_SIZE 256 #endif /** @} */ diff --git a/os/hal/platforms/STM32/OTGv1/usb_lld.c b/os/hal/platforms/STM32/OTGv1/usb_lld.c index b4238a8a0..78fc45a71 100644 --- a/os/hal/platforms/STM32/OTGv1/usb_lld.c +++ b/os/hal/platforms/STM32/OTGv1/usb_lld.c @@ -85,6 +85,7 @@ static const USBEndpointConfig ep0config = { 0x40, &ep0_state.in, &ep0_state.out, + 1, ep0setup_buffer }; @@ -448,31 +449,43 @@ static void otg_rxfifo_handler(USBDriver *usbp) { * @notapi */ static void otg_txfifo_handler(USBDriver *usbp, usbep_t ep) { - uint32_t n; - - /* Number of bytes remaining in current transaction.*/ - n = usbp->epc[ep]->in_state->txsize - usbp->epc[ep]->in_state->txcnt; - if (n > usbp->epc[ep]->in_maxsize) - n = usbp->epc[ep]->in_maxsize; - - if (usbp->epc[ep]->in_state->txqueued) { - /* Queue associated.*/ - otg_fifo_write_from_queue(ep, - usbp->epc[ep]->in_state->mode.queue.txqueue, - n); - } - else { - /* Linear buffer associated.*/ - otg_fifo_write_from_buffer(ep, - usbp->epc[ep]->in_state->mode.linear.txbuf, - n); - usbp->epc[ep]->in_state->mode.linear.txbuf += n; - } - usbp->epc[ep]->in_state->txcnt += n; - /* Interrupt disabled on transaction end.*/ - if (usbp->epc[ep]->in_state->txcnt >= usbp->epc[ep]->in_state->txsize) - OTG->DIEPEMPMSK &= ~DIEPEMPMSK_INEPTXFEM(ep); + /* The TXFIFO is filled until there is space and data to be transmitted.*/ + while (TRUE) { + uint32_t n; + + /* Number of bytes remaining in current transaction.*/ + n = usbp->epc[ep]->in_state->txsize - usbp->epc[ep]->in_state->txcnt; + if (n > usbp->epc[ep]->in_maxsize) + n = usbp->epc[ep]->in_maxsize; + + /* Checks if in the TXFIFO there is enough space to accommodate the + next packet.*/ + if (((OTG->ie[ep].DTXFSTS & DTXFSTS_INEPTFSAV_MASK) * 4) < n) + return; + + /* Handles the two cases: linear buffer or queue.*/ + if (usbp->epc[ep]->in_state->txqueued) { + /* Queue associated.*/ + otg_fifo_write_from_queue(ep, + usbp->epc[ep]->in_state->mode.queue.txqueue, + n); + } + else { + /* Linear buffer associated.*/ + otg_fifo_write_from_buffer(ep, + usbp->epc[ep]->in_state->mode.linear.txbuf, + n); + usbp->epc[ep]->in_state->mode.linear.txbuf += n; + } + usbp->epc[ep]->in_state->txcnt += n; + + /* Interrupt disabled on transaction end.*/ + if (usbp->epc[ep]->in_state->txcnt >= usbp->epc[ep]->in_state->txsize) { + OTG->DIEPEMPMSK &= ~DIEPEMPMSK_INEPTXFEM(ep); + return; + } + } } /** @@ -650,8 +663,8 @@ void usb_lld_start(USBDriver *usbp) { - Full Speed 1.1 PHY.*/ OTG->GUSBCFG = GUSBCFG_FDMOD | GUSBCFG_TRDT(TRDT_VALUE) | GUSBCFG_PHYSEL; - /* Interrupt on TXFIFOs empty.*/ - OTG->GAHBCFG = GAHBCFG_PTXFELVL | GAHBCFG_TXFELVL; + /* Interrupts on TXFIFOs half empty.*/ + OTG->GAHBCFG = 0; /* 48MHz 1.1 PHY.*/ OTG->DCFG = 0x02200000 | DCFG_PFIVL(0) | DCFG_DSPD_FS11; @@ -806,6 +819,8 @@ void usb_lld_init_endpoint(USBDriver *usbp, usbep_t ep) { if (usbp->epc[ep]->in_cb != NULL) { /* FIFO allocation for the IN endpoint.*/ fsize = usbp->epc[ep]->in_maxsize / 4; + if (usbp->epc[ep]->in_multiplier > 1) + fsize *= usbp->epc[ep]->in_multiplier; OTG->DIEPTXF[ep - 1] = DIEPTXF_INEPTXFD(fsize) | DIEPTXF_INEPTXSA(otg_ram_alloc(usbp, fsize)); otg_txfifo_flush(ep); diff --git a/os/hal/platforms/STM32/OTGv1/usb_lld.h b/os/hal/platforms/STM32/OTGv1/usb_lld.h index 8b2903982..30e96c71b 100644 --- a/os/hal/platforms/STM32/OTGv1/usb_lld.h +++ b/os/hal/platforms/STM32/OTGv1/usb_lld.h @@ -231,6 +231,12 @@ typedef struct { */ USBOutEndpointState *out_state; /* End of the mandatory fields.*/ + /** + * @brief Determines the space allocated for the TXFIFO as multiples of + * the packet size (@p in_maxsize). Note that zero is interpreted + * as one for simplicity and robustness. + */ + uint16_t in_multiplier; /** * @brief Pointer to a buffer for setup packets. * @details Setup packets require a dedicated 8-bytes buffer, set this diff --git a/testhal/STM32F4xx/USB_CDC/.cproject b/testhal/STM32F4xx/USB_CDC/.cproject new file mode 100644 index 000000000..10ff121bb --- /dev/null +++ b/testhal/STM32F4xx/USB_CDC/.cproject @@ -0,0 +1,50 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/testhal/STM32F4xx/USB_CDC/.project b/testhal/STM32F4xx/USB_CDC/.project new file mode 100644 index 000000000..29c5c4c72 --- /dev/null +++ b/testhal/STM32F4xx/USB_CDC/.project @@ -0,0 +1,95 @@ + + + TEST-STM32F4xx-USB_CDC + + + + + + org.eclipse.cdt.managedbuilder.core.genmakebuilder + clean,full,incremental, + + + ?name? + + + + org.eclipse.cdt.make.core.append_environment + true + + + org.eclipse.cdt.make.core.autoBuildTarget + all + + + org.eclipse.cdt.make.core.buildArguments + -j + + + org.eclipse.cdt.make.core.buildCommand + make + + + org.eclipse.cdt.make.core.cleanBuildTarget + clean + + + org.eclipse.cdt.make.core.contents + org.eclipse.cdt.make.core.activeConfigSettings + + + org.eclipse.cdt.make.core.enableAutoBuild + false + + + org.eclipse.cdt.make.core.enableCleanBuild + true + + + org.eclipse.cdt.make.core.enableFullBuild + true + + + org.eclipse.cdt.make.core.fullBuildTarget + all + + + org.eclipse.cdt.make.core.stopOnError + true + + + org.eclipse.cdt.make.core.useDefaultBuildCmd + true + + + + + org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder + full,incremental, + + + + + + org.eclipse.cdt.core.cnature + org.eclipse.cdt.managedbuilder.core.managedBuildNature + org.eclipse.cdt.managedbuilder.core.ScannerConfigNature + + + + board + 2 + CHIBIOS/boards/ST_STM32F4_DISCOVERY + + + os + 2 + CHIBIOS/os + + + test + 2 + CHIBIOS/test + + + diff --git a/testhal/STM32F4xx/USB_CDC/main.c b/testhal/STM32F4xx/USB_CDC/main.c index a122591e4..02f7b4829 100644 --- a/testhal/STM32F4xx/USB_CDC/main.c +++ b/testhal/STM32F4xx/USB_CDC/main.c @@ -242,13 +242,14 @@ static const USBEndpointConfig ep1config = { 0x0000, &ep1instate, NULL, + 2, NULL }; /** - * @brief OUT EP2 state. + * @brief IN EP2 state. */ -USBOutEndpointState ep2outstate; +USBInEndpointState ep2instate; /** * @brief EP2 initialization structure (IN only). @@ -260,8 +261,9 @@ static const USBEndpointConfig ep2config = { NULL, 0x0010, 0x0000, + &ep2instate, NULL, - &ep2outstate, + 1, NULL }; @@ -282,6 +284,7 @@ static const USBEndpointConfig ep3config = { 0x0040, NULL, &ep3outstate, + 0, NULL }; -- cgit v1.2.3