Ver código fonte

Work/f411 fixup (#138)

* fix AHB1 clocks in demo for F411 #136

* #135 add sequental TX data and variable packet length

* #135 fix F429 RX buffer overflow

* #135 rewrite cdc_txonly() to achieve a cyclic bulk transaction length

* #135 fix F105 RX buffer overflow

* #135 set demo code back to loopback

* #135 revert clear STALL on write
Dmitry Filimonchuk 2 anos atrás
pai
commit
397c0517a3
5 arquivos alterados com 35 adições e 20 exclusões
  1. 18 3
      demo/cdc_loop.c
  2. 7 3
      demo/cdc_startup.c
  3. 4 0
      readme.md
  4. 1 3
      src/usbd_stm32f105_otgfs.c
  5. 5 11
      src/usbd_stm32f429_otgfs.c

+ 18 - 3
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) {

+ 7 - 3
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) */

+ 4 - 0
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)

+ 1 - 3
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 */

+ 5 - 11
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;