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);
}