xtoolbox / TeenyUSB

Lightweight USB device and host stack for STM32 and other MCUs. Ready for USB 3.0 device.
http://www.tusb.org
MIT License
562 stars 175 forks source link

F723-HS-Device Initialization #5

Open RadioOperator opened 4 years ago

RadioOperator commented 4 years ago

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

xtoolbox commented 4 years ago

ST的USB核初始化这块确实有很多问题,官方库里面也有一些补丁代码在里面。 这个地方我之前是写入寄存器再读回来,如果读回的数据不正确就等一下再重新写 你这部分代码我研究一下,看看怎么样能合并进去