diff --git a/demo/cdc_loop.c b/demo/cdc_loop.c index 986a7ba..788d5b9 100644 --- a/demo/cdc_loop.c +++ b/demo/cdc_loop.c @@ -358,9 +358,24 @@ static void cdc_rxonly (usbd_device *dev, uint8_t event, uint8_t ep) { } static void cdc_txonly(usbd_device *dev, uint8_t event, uint8_t ep) { - uint8_t _t = dev->driver->frame_no(); - memset(fifo, _t, CDC_DATA_SZ); - usbd_ep_write(dev, ep, fifo, CDC_DATA_SZ); + static uint8_t psize = 0x00U; + static uint8_t remained = 0x00U; + static uint8_t lastsym = 0x00U; + + uint8_t _t = (remained < CDC_DATA_SZ) ? remained : CDC_DATA_SZ; + // fill buffer by sequental data + for (size_t i = 0; i < _t; ++i) { + fifo[i] = lastsym++; + } + usbd_ep_write(dev, ep, fifo, _t); + + if (remained < CDC_DATA_SZ) { + // bulk xfer completed. increase bulk size + remained = ++psize; + } else { + // continue to send remained data or ZLP + remained -= _t; + } } static void cdc_rxtx(usbd_device *dev, uint8_t event, uint8_t ep) { diff --git a/demo/cdc_startup.c b/demo/cdc_startup.c index 612b64f..42b02c3 100644 --- a/demo/cdc_startup.c +++ b/demo/cdc_startup.c @@ -104,7 +104,7 @@ static void cdc_init_rcc (void) { /* switch to PLL */ _BMD(RCC->CFGR, RCC_CFGR_SW, RCC_CFGR_SW_PLL); _WVL(RCC->CFGR, RCC_CFGR_SWS, RCC_CFGR_SWS_PLL); - + _BST(RCC->AHBENR, RCC_AHBENR_GPIOAEN); _BST(GPIOA->AFR[1], (0x0E << 12) | (0x0E << 16)); _BMD(GPIOA->MODER, (0x03 << 22) | (0x03 << 24), (0x02 << 22) | (0x02 << 24)); @@ -141,8 +141,12 @@ static void cdc_init_rcc (void) { /* enabling PLL */ _BST(RCC->CR, RCC_CR_PLLON); _WBS(RCC->CR, RCC_CR_PLLRDY); - /* switching to PLL */ - _BMD(RCC->CFGR, RCC_CFGR_SW, RCC_CFGR_SW_PLL); + /* Setup CFGR to PLL*/ + /* APB1 | APB2 */ + /* STM32F411 <50Mhz | <100MHz */ + /* STM32F429 <45MHz | <90MHz */ + /* STM32F405, STM32F401 <42MHz | <84MHz */ + _BMD(RCC->CFGR, RCC_CFGR_SW | RCC_CFGR_PPRE1, RCC_CFGR_SW_PLL | RCC_CFGR_PPRE1_DIV2); _WVL(RCC->CFGR, RCC_CFGR_SWS, RCC_CFGR_SWS_PLL); #if defined(USBD_PRIMARY_OTGHS) /* enabling GPIOB and setting PB13, PB14 and PB15 to AF11 (USB_OTG2FS) */ diff --git a/readme.md b/readme.md index a365c79..504c87d 100644 --- a/readme.md +++ b/readme.md @@ -128,6 +128,10 @@ STM32G431RB, STM32F411CEUx, STM32F405RG, STM32F446RE, STM32F373CC, STM32L053R8, STM32F745VE, STM32F401CE, STM32H743. See [hardware.md](hardware.md) for details. +### Don't copy-paste the startup code from the demo without considering RCC and USB clock requirements. +The HSI oscillator usually does not meet the timing requirements for USB and may cause performance loss +and a high error rate. + ### Implemented definitions for classes ### 1. USB HID based on [Device Class Definition for Human Interface Devices (HID) Version 1.11](https://www.usb.org/sites/default/files/documents/hid1_11.pdf) 2. USB DFU based on [USB Device Firmware Upgrade Specification, Revision 1.1](https://www.usb.org/sites/default/files/DFU_1.1.pdf) diff --git a/src/usbd_stm32f105_otgfs.c b/src/usbd_stm32f105_otgfs.c index 455baf3..770af5e 100644 --- a/src/usbd_stm32f105_otgfs.c +++ b/src/usbd_stm32f105_otgfs.c @@ -338,6 +338,7 @@ static int32_t ep_read(uint8_t ep, void* buf, uint16_t blen) { tmp >>= 8; } } + _BST(EPOUT(ep)->DOEPCTL, USB_OTG_DOEPCTL_CNAK | USB_OTG_DOEPCTL_EPENA); return (len < blen) ? len : blen; } @@ -413,9 +414,6 @@ static void evt_poll(usbd_device *dev, usbd_evt_callback callback) { } evt = usbd_evt_epsetup; break; - case 0x03: /* OUT completed */ - case 0x04: /* SETUP completed */ - _BST(EPOUT(ep)->DOEPCTL, USB_OTG_DOEPCTL_CNAK | USB_OTG_DOEPCTL_EPENA); // fall through default: /* pop GRXSTSP */ diff --git a/src/usbd_stm32f429_otgfs.c b/src/usbd_stm32f429_otgfs.c index 5e8d237..a41479e 100644 --- a/src/usbd_stm32f429_otgfs.c +++ b/src/usbd_stm32f429_otgfs.c @@ -335,26 +335,24 @@ static int32_t ep_read(uint8_t ep, void* buf, uint16_t blen) { tmp >>= 8; } } + _BST(EPOUT(ep)->DOEPCTL, USB_OTG_DOEPCTL_CNAK | USB_OTG_DOEPCTL_EPENA); return (len < blen) ? len : blen; } static int32_t ep_write(uint8_t ep, const void *buf, uint16_t blen) { - uint32_t len, tmp; + uint32_t len, tmp = 0; ep &= 0x7F; volatile uint32_t* fifo = EPFIFO(ep); USB_OTG_INEndpointTypeDef* epi = EPIN(ep); + /* check if EP enabled*/ + if (ep != 0 && epi->DIEPCTL & USB_OTG_DIEPCTL_EPENA) return -1; /* transfer data size in 32-bit words */ len = (blen + 3) >> 2; /* no enough space in TX fifo */ - if (len > epi->DTXFSTS) return -1; - if (ep != 0 && epi->DIEPCTL & USB_OTG_DIEPCTL_EPENA) { - return -1; - } - epi->DIEPTSIZ = 0; + if (len > 0 && len > _FLD2VAL(USB_OTG_DTXFSTS_INEPTFSAV, epi->DTXFSTS)) return -1; epi->DIEPTSIZ = (1 << 19) + blen; _BMD(epi->DIEPCTL, USB_OTG_DIEPCTL_STALL, USB_OTG_DOEPCTL_EPENA | USB_OTG_DOEPCTL_CNAK); /* push data to FIFO */ - tmp = 0; for (int idx = 0; idx < blen; idx++) { tmp |= (uint32_t)((const uint8_t*)buf)[idx] << ((idx & 0x03) << 3); if ((idx & 0x03) == 0x03 || (idx + 1) == blen) { @@ -410,10 +408,6 @@ static void evt_poll(usbd_device *dev, usbd_evt_callback callback) { } evt = usbd_evt_epsetup; break; - case 0x03: /* OUT completed */ - case 0x04: /* SETUP completed */ - _BST(EPOUT(ep)->DOEPCTL, USB_OTG_DOEPCTL_CNAK | USB_OTG_DOEPCTL_EPENA); - // fall through default: /* pop GRXSTSP */ OTG->GRXSTSP;