dmitrystu / libusb_stm32

Lightweight USB device Stack for STM32 microcontrollers
Apache License 2.0
707 stars 160 forks source link

Porting to STM32F469 #52

Closed dragonman225 closed 4 years ago

dragonman225 commented 4 years ago

Hello, I'm trying to port this library to STM32F469, using a 32F469IDISCOVERY development board.

First I add STM32F469xx to the group of STM32F4 devices in usb.h,

#elif defined(STM32F405xx) || defined(STM32F415xx) || \
       defined(STM32F407xx) || defined(STM32F417xx) || \
       defined(STM32F427xx) || defined(STM32F437xx) || \
       defined(STM32F429xx) || defined(STM32F439xx) || \
+      defined(STM32F469xx)

then I modify usbd_stm32f429_otgfs.c and usbd_stm32f429_otghs.c since the name of the VBUS sense register field is different, as shown below.

        /* configuring Vbus sense and SOF output */
#if defined (USBD_VBUS_DETECT) && defined(USBD_SOF_OUT)
#if defined(STM32F469xx)
        OTG->GCCFG = USB_OTG_GCCFG_VBDEN;
#else
        OTG->GCCFG = USB_OTG_GCCFG_VBUSBSEN | USB_OTG_GCCFG_SOFOUTEN;
#endif
#elif defined(USBD_VBUS_DETECT)
#if defined(STM32F469xx)
        OTG->GCCFG = USB_OTG_GCCFG_VBDEN;
#else
        OTG->GCCFG = USB_OTG_GCCFG_VBUSBSEN;
#endif
#elif defined(USBD_SOF_OUT)
        OTG->GCCFG = USB_OTG_GCCFG_NOVBUSSENS | USB_OTG_GCCFG_SOFOUTEN;
#else
#if !defined(STM32F469xx)
        OTG->GCCFG = USB_OTG_GCCFG_NOVBUSSENS;
#endif
#endif

Finally, I add the following init code to cdc_startup.c. (Note that I haven't handle the USBD_PRIMARY_OTGHS case.)

#elif defined(STM32F469xx)
    /* set flash latency 4WS, see RM3086 p.80 */
    _BMD(FLASH->ACR, FLASH_ACR_LATENCY, FLASH_ACR_LATENCY_4WS);
    /* setting up PLL 16MHz HSI, VCO=144MHz, PLLP = 144MHz PLLQ = 48MHz  */
    _BMD(RCC->PLLCFGR,
        RCC_PLLCFGR_PLLM | RCC_PLLCFGR_PLLN | RCC_PLLCFGR_PLLP | RCC_PLLCFGR_PLLSRC | RCC_PLLCFGR_PLLQ,
        _VAL2FLD(RCC_PLLCFGR_PLLM, 4) | _VAL2FLD(RCC_PLLCFGR_PLLN, 72) | _VAL2FLD(RCC_PLLCFGR_PLLQ, 6));
    /* 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);
    _WVL(RCC->CFGR, RCC_CFGR_SWS, RCC_CFGR_SWS_PLL);
    /* enabling GPIOA */
    _BST(RCC->AHB1ENR, RCC_AHB1ENR_GPIOAEN);
    /* setting PA10 (ID), PA11 (DM) and PA12 (DP) to AF10 (USB_FS) */
    _BST(GPIOA->AFR[1], (0x0A << 8) | (0x0A << 12) | (0x0A << 16));
    /* setting PA9 (VBUS) to input mode, and PA10, PA11, PA12 to AF mode */
    _BMD(GPIOA->MODER, (0x03 << 18) | (0x03 << 20) | (0x03 << 22) | (0x03 << 24), (0x02 << 20) | (0x02 << 22) | (0x02 << 24));
    /* setting PA10 to open-drain */
    _BST(GPIOA->OTYPER, (0x01 << 10));
    /* setting PA11, PA12 to high speed */
    _BMD(GPIOA->OSPEEDR, (0x03 << 22) | (0x03 << 24), (0x02 << 22) | (0x02 << 24));
    /* setting PA9, PA11, PA12 to no pull, PA10 to pull-up */
    _BMD(GPIOA->PUPDR, (0x03 << 18) | (0x03 << 20) | (0x03 << 22) | (0x03 << 24), (0x01 << 20));

I can compile the demo code with this linker script, which is generated by CubeMX, and the following Makefile rule:

stm32f469ni: clean
  @$(MAKE) demo STARTUP='$(CMSISDEV)/ST/STM32F4xx/Source/Templates/gcc/startup_stm32f469xx.s' \
                LDSCRIPT='demo/stm32f469ni.ld' \
                DEFINES='STM32F4 STM32F469xx USBD_VBUS_DETECT' \
                CFLAGS='-mcpu=cortex-m4'

But the device would not enumerate, although if I trace the execution with a debugger, I could see that cdc_control() and cdc_getdesc() callbacks got called.

I wonder if I did something wrong or actually the USB control mechanism of STM32F469 is different from other F4 devices. Will keep debugging but if someone could point out the problems I would appreciate!

7134956 commented 4 years ago

Maybe there is something useful here? https://github.com/SushiBits/libusb_stm32/commit/4ce92607ee97278aa76892fdada73311960c412c

dragonman225 commented 4 years ago

I switch to the driver for STM32F446 and everything in the demo works. Thank you!