usb_glue_st.c 8.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212
  1. /*
  2. * Copyright (c) 2024, sakumisu
  3. *
  4. * SPDX-License-Identifier: Apache-2.0
  5. */
  6. #include "usb_config.h"
  7. #include "stdint.h"
  8. #include "usb_dwc2_reg.h"
  9. /* you can find this config in function: USB_DevInit, file:stm32xxx_ll_usb.c, for example:
  10. *
  11. * USBx->GCCFG |= USB_OTG_GCCFG_PWRDWN;
  12. * USBx->GCCFG |= USB_OTG_GCCFG_NOVBUSSENS;
  13. * USBx->GCCFG &= ~USB_OTG_GCCFG_VBUSBSEN;
  14. * USBx->GCCFG &= ~USB_OTG_GCCFG_VBUSASEN;
  15. *
  16. */
  17. extern void HAL_Delay(uint32_t Delay);
  18. #if defined(STM32F722xx) || defined(STM32F723xx) || defined(STM32F730xx) || defined(STM32F732xx) || defined(STM32F733xx)
  19. /**
  20. * @brief USB_HS_PHY_Registers
  21. */
  22. typedef struct
  23. {
  24. __IO uint32_t USB_HS_PHYC_PLL; /*!< This register is used to control the PLL of the HS PHY. 000h */
  25. __IO uint32_t Reserved04; /*!< Reserved 004h */
  26. __IO uint32_t Reserved08; /*!< Reserved 008h */
  27. __IO uint32_t USB_HS_PHYC_TUNE; /*!< This register is used to control the tuning interface of the High Speed PHY. 00Ch */
  28. __IO uint32_t Reserved10; /*!< Reserved 010h */
  29. __IO uint32_t Reserved14; /*!< Reserved 014h */
  30. __IO uint32_t USB_HS_PHYC_LDO; /*!< This register is used to control the regulator (LDO). 018h */
  31. } USB_HS_PHYC_GlobalTypeDef;
  32. #define USB_HS_PHYC_CONTROLLER_BASE 0x40017C00UL
  33. #define USB_HS_PHYC ((USB_HS_PHYC_GlobalTypeDef *) USB_HS_PHYC_CONTROLLER_BASE)
  34. /******************** Bit definition for USBPHYC_PLL1 register ********************/
  35. #define USB_HS_PHYC_PLL1_PLLEN_Pos (0U)
  36. #define USB_HS_PHYC_PLL1_PLLEN_Msk (0x1UL << USB_HS_PHYC_PLL1_PLLEN_Pos) /*!< 0x00000001 */
  37. #define USB_HS_PHYC_PLL1_PLLEN USB_HS_PHYC_PLL1_PLLEN_Msk /*!< Enable PLL */
  38. #define USB_HS_PHYC_PLL1_PLLSEL_Pos (1U)
  39. #define USB_HS_PHYC_PLL1_PLLSEL_Msk (0x7UL << USB_HS_PHYC_PLL1_PLLSEL_Pos) /*!< 0x0000000E */
  40. #define USB_HS_PHYC_PLL1_PLLSEL USB_HS_PHYC_PLL1_PLLSEL_Msk /*!< Controls PHY frequency operation selection */
  41. #define USB_HS_PHYC_PLL1_PLLSEL_1 (0x1UL << USB_HS_PHYC_PLL1_PLLSEL_Pos) /*!< 0x00000002 */
  42. #define USB_HS_PHYC_PLL1_PLLSEL_2 (0x2UL << USB_HS_PHYC_PLL1_PLLSEL_Pos) /*!< 0x00000004 */
  43. #define USB_HS_PHYC_PLL1_PLLSEL_3 (0x4UL << USB_HS_PHYC_PLL1_PLLSEL_Pos) /*!< 0x00000008 */
  44. #define USB_HS_PHYC_PLL1_PLLSEL_12MHZ 0x00000000U /*!< PHY PLL1 input clock frequency 12 MHz */
  45. #define USB_HS_PHYC_PLL1_PLLSEL_12_5MHZ USB_HS_PHYC_PLL1_PLLSEL_1 /*!< PHY PLL1 input clock frequency 12.5 MHz */
  46. #define USB_HS_PHYC_PLL1_PLLSEL_16MHZ (uint32_t)(USB_HS_PHYC_PLL1_PLLSEL_1 | USB_HS_PHYC_PLL1_PLLSEL_2) /*!< PHY PLL1 input clock frequency 16 MHz */
  47. #define USB_HS_PHYC_PLL1_PLLSEL_24MHZ USB_HS_PHYC_PLL1_PLLSEL_3 /*!< PHY PLL1 input clock frequency 24 MHz */
  48. #define USB_HS_PHYC_PLL1_PLLSEL_25MHZ (uint32_t)(USB_HS_PHYC_PLL1_PLLSEL_2 | USB_HS_PHYC_PLL1_PLLSEL_3) /*!< PHY PLL1 input clock frequency 25 MHz */
  49. /******************** Bit definition for USBPHYC_LDO register ********************/
  50. #define USB_HS_PHYC_LDO_USED_Pos (0U)
  51. #define USB_HS_PHYC_LDO_USED_Msk (0x1UL << USB_HS_PHYC_LDO_USED_Pos) /*!< 0x00000001 */
  52. #define USB_HS_PHYC_LDO_USED USB_HS_PHYC_LDO_USED_Msk /*!< Monitors the usage status of the PHY's LDO */
  53. #define USB_HS_PHYC_LDO_STATUS_Pos (1U)
  54. #define USB_HS_PHYC_LDO_STATUS_Msk (0x1UL << USB_HS_PHYC_LDO_STATUS_Pos) /*!< 0x00000002 */
  55. #define USB_HS_PHYC_LDO_STATUS USB_HS_PHYC_LDO_STATUS_Msk /*!< Monitors the status of the PHY's LDO. */
  56. #define USB_HS_PHYC_LDO_DISABLE_Pos (2U)
  57. #define USB_HS_PHYC_LDO_DISABLE_Msk (0x1UL << USB_HS_PHYC_LDO_DISABLE_Pos) /*!< 0x00000004 */
  58. #define USB_HS_PHYC_LDO_DISABLE USB_HS_PHYC_LDO_DISABLE_Msk /*!< Controls disable of the High Speed PHY's LDO */
  59. /* Legacy */
  60. #define USB_HS_PHYC_PLL_PLLEN_Pos USB_HS_PHYC_PLL1_PLLEN_Pos
  61. #define USB_HS_PHYC_PLL_PLLEN_Msk USB_HS_PHYC_PLL1_PLLEN_Msk
  62. #define USB_HS_PHYC_PLL_PLLEN USB_HS_PHYC_PLL1_PLLEN
  63. #define USB_HS_PHYC_PLL_PLLSEL_Pos USB_HS_PHYC_PLL1_PLLSEL_Pos
  64. #define USB_HS_PHYC_PLL_PLLSEL_Msk USB_HS_PHYC_PLL1_PLLSEL_Msk
  65. #define USB_HS_PHYC_PLL_PLLSEL USB_HS_PHYC_PLL1_PLLSEL
  66. #define USB_HS_PHYC_PLL_PLLSEL_1 USB_HS_PHYC_PLL1_PLLSEL_1
  67. #define USB_HS_PHYC_PLL_PLLSEL_2 USB_HS_PHYC_PLL1_PLLSEL_2
  68. #define USB_HS_PHYC_PLL_PLLSEL_3 USB_HS_PHYC_PLL1_PLLSEL_3
  69. #define USB_HS_PHYC_LDO_ENABLE_Pos USB_HS_PHYC_LDO_DISABLE_Pos
  70. #define USB_HS_PHYC_LDO_ENABLE_Msk USB_HS_PHYC_LDO_DISABLE_Msk
  71. #define USB_HS_PHYC_LDO_ENABLE USB_HS_PHYC_LDO_DISABLE
  72. #if !defined (USB_HS_PHYC_TUNE_VALUE)
  73. #define USB_HS_PHYC_TUNE_VALUE 0x00000F13U /*!< Value of USB HS PHY Tune */
  74. #endif /* USB_HS_PHYC_TUNE_VALUE */
  75. /**
  76. * @brief Enables control of a High Speed USB PHY
  77. * Init the low level hardware : GPIO, CLOCK, NVIC...
  78. * @param USBx Selected device
  79. * @retval HAL status
  80. */
  81. static int usb_hsphy_init(uint32_t hse_value)
  82. {
  83. __IO uint32_t count = 0U;
  84. /* Enable LDO */
  85. USB_HS_PHYC->USB_HS_PHYC_LDO |= USB_HS_PHYC_LDO_ENABLE;
  86. /* wait for LDO Ready */
  87. while ((USB_HS_PHYC->USB_HS_PHYC_LDO & USB_HS_PHYC_LDO_STATUS) == 0U)
  88. {
  89. count++;
  90. if (count > 200000U)
  91. {
  92. return -1;
  93. }
  94. }
  95. /* Controls PHY frequency operation selection */
  96. if (hse_value == 12000000U) /* HSE = 12MHz */
  97. {
  98. USB_HS_PHYC->USB_HS_PHYC_PLL = (0x0U << 1);
  99. }
  100. else if (hse_value == 12500000U) /* HSE = 12.5MHz */
  101. {
  102. USB_HS_PHYC->USB_HS_PHYC_PLL = (0x2U << 1);
  103. }
  104. else if (hse_value == 16000000U) /* HSE = 16MHz */
  105. {
  106. USB_HS_PHYC->USB_HS_PHYC_PLL = (0x3U << 1);
  107. }
  108. else if (hse_value == 24000000U) /* HSE = 24MHz */
  109. {
  110. USB_HS_PHYC->USB_HS_PHYC_PLL = (0x4U << 1);
  111. }
  112. else if (hse_value == 25000000U) /* HSE = 25MHz */
  113. {
  114. USB_HS_PHYC->USB_HS_PHYC_PLL = (0x5U << 1);
  115. }
  116. else if (hse_value == 32000000U) /* HSE = 32MHz */
  117. {
  118. USB_HS_PHYC->USB_HS_PHYC_PLL = (0x7U << 1);
  119. }
  120. else
  121. {
  122. /* ... */
  123. }
  124. /* Control the tuning interface of the High Speed PHY */
  125. USB_HS_PHYC->USB_HS_PHYC_TUNE |= USB_HS_PHYC_TUNE_VALUE;
  126. /* Enable PLL internal PHY */
  127. USB_HS_PHYC->USB_HS_PHYC_PLL |= USB_HS_PHYC_PLL_PLLEN;
  128. /* 2ms Delay required to get internal phy clock stable */
  129. HAL_Delay(2U);
  130. return 0;
  131. }
  132. #endif
  133. uint32_t usbd_get_dwc2_gccfg_conf(uint32_t reg_base)
  134. {
  135. #if __has_include("stm32h7xx.h") || __has_include("stm32f7xx.h") || __has_include("stm32l4xx.h")
  136. #define USB_OTG_GLB ((DWC2_GlobalTypeDef *)(reg_base))
  137. /* B-peripheral session valid override enable */
  138. USB_OTG_GLB->GOTGCTL |= USB_OTG_GOTGCTL_BVALOEN;
  139. USB_OTG_GLB->GOTGCTL |= USB_OTG_GOTGCTL_BVALOVAL;
  140. #endif
  141. #ifdef CONFIG_USB_HS
  142. #if defined(STM32F722xx) || defined(STM32F723xx) || defined(STM32F730xx) || defined(STM32F732xx) || defined(STM32F733xx)
  143. USB_OTG_GLB->GCCFG = (1 << 23);
  144. usb_hsphy_init(25000000U);
  145. return (1 << 23); /* Enable USB HS PHY USBx->GCCFG |= USB_OTG_GCCFG_PHYHSEN;*/
  146. #elif __has_include("stm32h7rsxx.h")
  147. return (1 << 21);
  148. #else
  149. return 0;
  150. #endif
  151. #else
  152. #if __has_include("stm32h7xx.h") || __has_include("stm32f7xx.h") || __has_include("stm32l4xx.h")
  153. return (1 << 16);
  154. #else
  155. return ((1 << 16) | (1 << 21));
  156. #endif
  157. #endif
  158. }
  159. uint32_t usbh_get_dwc2_gccfg_conf(uint32_t reg_base)
  160. {
  161. #if __has_include("stm32h7xx.h") || __has_include("stm32f7xx.h") || __has_include("stm32l4xx.h")
  162. #define USB_OTG_GLB ((DWC2_GlobalTypeDef *)(reg_base))
  163. /* B-peripheral session valid override enable */
  164. USB_OTG_GLB->GOTGCTL &= ~USB_OTG_GOTGCTL_BVALOEN;
  165. USB_OTG_GLB->GOTGCTL &= ~USB_OTG_GOTGCTL_BVALOVAL;
  166. #endif
  167. #ifdef CONFIG_USB_HS
  168. #if defined(STM32F722xx) || defined(STM32F723xx) || defined(STM32F730xx) || defined(STM32F732xx) || defined(STM32F733xx)
  169. USB_OTG_GLB->GCCFG = (1 << 23);
  170. usb_hsphy_init(25000000U);
  171. return (1 << 23); /* Enable USB HS PHY USBx->GCCFG |= USB_OTG_GCCFG_PHYHSEN;*/
  172. #else
  173. return 0;
  174. #endif
  175. #else
  176. #if __has_include("stm32h7xx.h") || __has_include("stm32f7xx.h") || __has_include("stm32l4xx.h")
  177. return (1 << 16);
  178. #else
  179. return ((1 << 16) | (1 << 21));
  180. #endif
  181. #endif
  182. }
  183. void usbd_dwc2_delay_ms(uint8_t ms)
  184. {
  185. HAL_Delay(ms);
  186. }