TeenyUSB
TeenyUSB copied to clipboard
F723-HS-Device Initialization
F723, 我试用过Composite Device Demo, 发现stm32_otg_init.c文件里面的code有问题。 在我单独的F723板子(STLINK-V3MINI) 上面不能枚举成功。 后来,我参考ST的源码,改来改去改到最后可以用了。 因为修改得比较乱,我也不知哪些是关键的部分,没有办法提交Pull requests。还有一个原因是,修改后的部分,可能只适用于F723的Device,我不知道如何融合到通用的stm32_otg_init.c文件里面。
现将,我修改过的代码部分放在这里,供您参考:
static void Wait_CoreReset(USB_OTG_GlobalTypeDef *USBx) { uint32_t count = 0U;
/* Wait for AHB master IDLE state. */ do { if (++count > 200000U) { break; } } while ((USBx->GRSTCTL & USB_OTG_GRSTCTL_AHBIDL) == 0U);
/* Core Soft Reset */ count = 0U; USBx->GRSTCTL |= USB_OTG_GRSTCTL_CSRST;
do { if (++count > 200000U) { break; } } while ((USBx->GRSTCTL & USB_OTG_GRSTCTL_CSRST) == USB_OTG_GRSTCTL_CSRST); }
#if defined(USB_HS_PHYC) static void USB_HS_PHYCInit(USB_OTG_GlobalTypeDef USBx) { uint32_t count = 0U; / Enable LDO / USB_HS_PHYC->USB_HS_PHYC_LDO |= USB_HS_PHYC_LDO_ENABLE; / wait for LDO Ready / while ((USB_HS_PHYC->USB_HS_PHYC_LDO & USB_HS_PHYC_LDO_STATUS) == 0U) { if (++count > 200000U) { break; } } / Controls PHY frequency operation selection / if (HSE_VALUE == 12000000){ / HSE = 12MHz / USB_HS_PHYC->USB_HS_PHYC_PLL = (uint32_t)(0x0 << 1); }else if (HSE_VALUE == 12500000){ / HSE = 12.5MHz / USB_HS_PHYC->USB_HS_PHYC_PLL = (uint32_t)(0x2 << 1); }else if (HSE_VALUE == 16000000){ / HSE = 16MHz / USB_HS_PHYC->USB_HS_PHYC_PLL = (uint32_t)(0x3 << 1); }else if (HSE_VALUE == 24000000){ / HSE = 24MHz / USB_HS_PHYC->USB_HS_PHYC_PLL = (uint32_t)(0x4 << 1); }else if (HSE_VALUE == 25000000){ / HSE = 25MHz / USB_HS_PHYC->USB_HS_PHYC_PLL = (uint32_t)(0x5 << 1); }else if (HSE_VALUE == 32000000){ / HSE = 32MHz / USB_HS_PHYC->USB_HS_PHYC_PLL = (uint32_t)(0x7 << 1); } / Control the tuning interface of the High Speed PHY / USB_HS_PHYC->USB_HS_PHYC_TUNE |= USB_HS_PHYC_TUNE_VALUE; / Enable PLL internal PHY / USB_HS_PHYC->USB_HS_PHYC_PLL |= USB_HS_PHYC_PLL_PLLEN; / 2ms Delay required to get internal phy clock stable */ HAL_Delay(2U); } #endif
// init the IO and OTG core static void tusb_otg_core_init(tusb_core_t* core) { USB_OTG_GlobalTypeDef* USBx = GetUSB(core); (void)USBx; if(GetUSB(core) == USB_OTG_FS){ // Init the FS core #if defined(OTG_FS_EMBEDDED_PHY) // 1. Init the IO tusb_setup_otg_fs_io(); // 2. Init the interrupt NVIC_SetPriority(OTG_FS_IRQn, 0); NVIC_EnableIRQ(OTG_FS_IRQn); // 3. Init the core __HAL_RCC_USB_OTG_FS_CLK_ENABLE(); /* Select FS Embedded PHY / USBx->GUSBCFG |= USB_OTG_GUSBCFG_PHYSEL; / Reset after a PHY select and set Host mode / Wait_CoreReset(USBx); / Deactivate the power down*/ USBx->GCCFG = USB_OTG_GCCFG_PWRDWN; #endif } #if defined(OTG_HS_EXTERNAL_PHY) || defined(OTG_HS_EMBEDDED_PHY) else if(GetUSB(core) == USB_OTG_HS){ // Init the HS core // 1. Init the IO // 2. Setup Interrupt #if defined(OTG_HS_EMBEDDED_PHY) // tusb_setup_otg_hs_io();
GPIO_InitTypeDef GPIO_InitStruct = {0};
__HAL_RCC_GPIOB_CLK_ENABLE();
/**USB_OTG_HS GPIO Configuration
PB14 ------> USB_OTG_HS_DM
PB15 ------> USB_OTG_HS_DP
*/
GPIO_InitStruct.Pin = GPIO_PIN_14|GPIO_PIN_15;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
GPIO_InitStruct.Alternate = GPIO_AF12_OTG_HS_FS;
HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
/* Peripheral clock enable */
__HAL_RCC_OTGPHYC_CLK_ENABLE();
__HAL_RCC_USB_OTG_HS_CLK_ENABLE();
__HAL_RCC_USB_OTG_HS_ULPI_CLK_ENABLE();
/* Peripheral interrupt init */
HAL_NVIC_SetPriority(OTG_HS_EP1_OUT_IRQn, 3, 0);
HAL_NVIC_EnableIRQ (OTG_HS_EP1_OUT_IRQn);
HAL_NVIC_SetPriority(OTG_HS_EP1_IN_IRQn, 2, 0);
HAL_NVIC_EnableIRQ (OTG_HS_EP1_IN_IRQn);
HAL_NVIC_SetPriority(OTG_HS_IRQn, 1, 0);
HAL_NVIC_EnableIRQ (OTG_HS_IRQn);
#elif defined(OTG_HS_EXTERNAL_PHY) OTG_HS_ULPI_IO_CLK_ENABLE(); set_io_af_mode( OTG_HS_ULPI_D0 ); set_io_af_mode( OTG_HS_ULPI_D1 ); set_io_af_mode( OTG_HS_ULPI_D2 ); set_io_af_mode( OTG_HS_ULPI_D3 ); set_io_af_mode( OTG_HS_ULPI_D4 ); set_io_af_mode( OTG_HS_ULPI_D5 ); set_io_af_mode( OTG_HS_ULPI_D6 ); set_io_af_mode( OTG_HS_ULPI_D7 ); set_io_af_mode( OTG_HS_ULPI_DIR ); set_io_af_mode( OTG_HS_ULPI_STP ); set_io_af_mode( OTG_HS_ULPI_NXT ); set_io_af_mode( OTG_HS_ULPI_CK );
NVIC_SetPriority(OTG_HS_IRQn, 0);
NVIC_EnableIRQ(OTG_HS_IRQn);
__HAL_RCC_USB_OTG_HS_CLK_ENABLE();
__HAL_RCC_USB_OTG_HS_ULPI_CLK_ENABLE();
#endif // 3. Init the OTG HS core #if defined(OTG_HS_EMBEDDED_PHY) // init embedded phy USBx->GCCFG &= ~(USB_OTG_GCCFG_PWRDWN); /* Init The UTMI Interface / USBx->GUSBCFG &= ~(USB_OTG_GUSBCFG_TSDPS | USB_OTG_GUSBCFG_ULPIFSLS | USB_OTG_GUSBCFG_PHYSEL); / Select vbus source / USBx->GUSBCFG &= ~(USB_OTG_GUSBCFG_ULPIEVBUSD | USB_OTG_GUSBCFG_ULPIEVBUSI); / Select UTMI Interace / USBx->GUSBCFG &= ~ USB_OTG_GUSBCFG_ULPI_UTMI_SEL; USBx->GCCFG |= USB_OTG_GCCFG_PHYHSEN; / Enables control of a High Speed USB PHY / USB_HS_PHYCInit(USBx); #elif defined(OTG_HS_EXTERNAL_PHY) // Init external phy __HAL_RCC_USB_OTG_HS_ULPI_CLK_ENABLE(); USBx->GCCFG &= ~(USB_OTG_GCCFG_PWRDWN); / Init The ULPI Interface / USBx->GUSBCFG &= ~(USB_OTG_GUSBCFG_TSDPS | USB_OTG_GUSBCFG_ULPIFSLS | USB_OTG_GUSBCFG_PHYSEL); / Select vbus source */ USBx->GUSBCFG &= ~(USB_OTG_GUSBCFG_ULPIEVBUSD | USB_OTG_GUSBCFG_ULPIEVBUSI); #endif
#if defined(ENABLE_VBUS_DETECT) USBx->GUSBCFG |= USB_OTG_GUSBCFG_ULPIEVBUSD; #endif /* Reset after a PHY select */ Wait_CoreReset(USBx); } #endif // defined(OTG_HS_EXTERNAL_PHY) || defined(OTG_HS_EMBEDDED_PHY)
#if defined(OTG_HS_ENABLE_DMA) if(GetUSB(core) == USB_OTG_HS){ // only HS core has DMA feature USBx->GAHBCFG |= USB_OTG_GAHBCFG_HBSTLEN_2; USBx->GAHBCFG |= USB_OTG_GAHBCFG_DMAEN; } #endif }
//for STM32F723 HS only void tusb_open_device(tusb_device_t* dev) { USB_OTG_GlobalTypeDef* USBx = GetUSB(dev);
/* Initialize low level driver */ GPIO_InitTypeDef GPIO_InitStruct = {0};
__HAL_RCC_GPIOB_CLK_ENABLE();
/**USB_OTG_HS GPIO Configuration
PB14 ------> USB_OTG_HS_DM
PB15 ------> USB_OTG_HS_DP
*/
GPIO_InitStruct.Pin = GPIO_PIN_14|GPIO_PIN_15;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
GPIO_InitStruct.Alternate = GPIO_AF12_OTG_HS_FS;
HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
/* Peripheral clock enable */ __HAL_RCC_OTGPHYC_CLK_ENABLE(); __HAL_RCC_USB_OTG_HS_CLK_ENABLE(); __HAL_RCC_USB_OTG_HS_ULPI_CLK_ENABLE();
/* Peripheral interrupt init */ HAL_NVIC_SetPriority(OTG_HS_EP1_OUT_IRQn, 3, 0); HAL_NVIC_EnableIRQ(OTG_HS_EP1_OUT_IRQn); HAL_NVIC_SetPriority(OTG_HS_EP1_IN_IRQn, 2, 0); HAL_NVIC_EnableIRQ(OTG_HS_EP1_IN_IRQn); HAL_NVIC_SetPriority(OTG_HS_IRQn, 1, 0); HAL_NVIC_EnableIRQ(OTG_HS_IRQn);
//USB_DisableGlobalInt(???) USBx->GAHBCFG &= ~USB_OTG_GAHBCFG_GINT;
USBx->GCCFG &= ~(USB_OTG_GCCFG_PWRDWN);
/* Init The UTMI Interface */ USBx->GUSBCFG &= ~(USB_OTG_GUSBCFG_TSDPS | USB_OTG_GUSBCFG_ULPIFSLS | USB_OTG_GUSBCFG_PHYSEL);
/* Select vbus source */ USBx->GUSBCFG &= ~(USB_OTG_GUSBCFG_ULPIEVBUSD | USB_OTG_GUSBCFG_ULPIEVBUSI);
/* Select UTMI Interace */ USBx->GUSBCFG &= ~ USB_OTG_GUSBCFG_ULPI_UTMI_SEL; USBx->GCCFG |= USB_OTG_GCCFG_PHYHSEN;
USB_HS_PHYCInit(USBx);
/* Reset after a PHY select */ Wait_CoreReset(USBx);
#if defined(OTG_HS_ENABLE_DMA) // only HS core has DMA feature USBx->GAHBCFG |= USB_OTG_GAHBCFG_HBSTLEN_2; USBx->GAHBCFG |= USB_OTG_GAHBCFG_DMAEN; #endif //#if defined(OTG_HS_ENABLE_DMA)
USBx->GUSBCFG &= ~(USB_OTG_GUSBCFG_FHMOD | USB_OTG_GUSBCFG_FDMOD); USBx->GUSBCFG |= USB_OTG_GUSBCFG_FDMOD; HAL_Delay(50U);
/* Deactivate VBUS Sensing B */ USBx->GCCFG &= ~USB_OTG_GCCFG_VBDEN;
/* B-peripheral session valid override enable */ USBx->GOTGCTL |= USB_OTG_GOTGCTL_BVALOEN; USBx->GOTGCTL |= USB_OTG_GOTGCTL_BVALOVAL;
/* Restart the Phy Clock */ USBx_PCGCCTL = 0U;
/* Device mode configuration */ USBx_DEVICE->DCFG |= DCFG_FRAME_INTERVAL_80; USBx_DEVICE->DCFG &= ~((uint32_t) 3U ); //High-speed
/* Clear all pending Device Interrupts */ USBx_DEVICE->DIEPMSK = 0U; USBx_DEVICE->DOEPMSK = 0U; USBx_DEVICE->DAINTMSK = 0U;
USBx_DEVICE->DIEPMSK &= ~(USB_OTG_DIEPMSK_TXFURM);
USBx_DEVICE->DTHRCTL = USB_OTG_DTHRCTL_TXTHRLEN_6 | USB_OTG_DTHRCTL_RXTHRLEN_6;
USBx_DEVICE->DTHRCTL |= USB_OTG_DTHRCTL_RXTHREN | USB_OTG_DTHRCTL_ISOTHREN | USB_OTG_DTHRCTL_NONISOTHREN;
/* Disable all interrupts. */ USBx->GINTMSK = 0U;
/* Clear any pending interrupts */ USBx->GINTSTS = 0xBFFFFFFFU;
/* Enable the common interrupts */ USBx->GINTMSK |= USB_OTG_GINTMSK_RXFLVLM;
/* Enable interrupts matching to the Device mode ONLY */ USBx->GINTMSK |= USB_OTG_GINTMSK_USBSUSPM | USB_OTG_GINTMSK_USBRST | USB_OTG_GINTMSK_ENUMDNEM | USB_OTG_GINTMSK_IEPINT | USB_OTG_GINTMSK_OEPINT | USB_OTG_GINTMSK_IISOIXFRM | USB_OTG_GINTMSK_PXFRM_IISOOXFRM | USB_OTG_GINTMSK_WUIM;
USBx->GINTMSK |= USB_OTG_GINTMSK_SOFM;
//HAL_PCDEx_ActivateLPM USBx->GINTMSK |= USB_OTG_GINTMSK_LPMINTM; USBx->GLPMCFG |= (USB_OTG_GLPMCFG_LPMEN | USB_OTG_GLPMCFG_LPMACK | USB_OTG_GLPMCFG_ENBESL);
//USB_DevDisconnect USBx_DEVICE->DCTL |= USB_OTG_DCTL_SDIS; HAL_Delay(3U);
// (void)USB_DevConnect(hpcd->Instance); USBx_DEVICE->DCTL &= ~USB_OTG_DCTL_SDIS; HAL_Delay(3U);
// __HAL_PCD_ENABLE(hpcd) // (void)USB_EnableGlobalInt ((HANDLE)->Instance) USBx->GAHBCFG |= USB_OTG_GAHBCFG_GINT; HAL_Delay(50);
tusb_init_otg_device(dev); }
ST的USB核初始化这块确实有很多问题,官方库里面也有一些补丁代码在里面。 这个地方我之前是写入寄存器再读回来,如果读回的数据不正确就等一下再重新写 你这部分代码我研究一下,看看怎么样能合并进去