cdc_startup.c 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253
  1. /* This file is the part of the Lightweight USB device Stack for STM32 microcontrollers
  2. *
  3. * Copyright ©2016 Dmitry Filimonchuk <dmitrystu[at]gmail[dot]com>
  4. *
  5. * Licensed under the Apache License, Version 2.0 (the "License");
  6. * you may not use this file except in compliance with the License.
  7. * You may obtain a copy of the License at
  8. * http://www.apache.org/licenses/LICENSE-2.0
  9. * Unless required by applicable law or agreed to in writing, software
  10. * distributed under the License is distributed on an "AS IS" BASIS,
  11. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. * See the License for the specific language governing permissions and
  13. * limitations under the License.
  14. */
  15. #include "stm32.h"
  16. static void cdc_init_rcc (void) {
  17. #if defined(STM32L0)
  18. _BST(RCC->APB1ENR, RCC_APB1ENR_PWREN);
  19. _BMD(PWR->CR, PWR_CR_VOS, PWR_CR_VOS_0);
  20. _WBC(PWR->CSR, PWR_CSR_VOSF);
  21. /* set FLASH latency to 1 */
  22. _BST(FLASH->ACR, FLASH_ACR_LATENCY);
  23. /* set clock at 32MHz PLL 6/3 HSI */
  24. _BMD(RCC->CFGR, RCC_CFGR_PLLDIV | RCC_CFGR_PLLMUL | RCC_CFGR_PLLSRC, RCC_CFGR_PLLDIV3 | RCC_CFGR_PLLMUL6);
  25. _BST(RCC->CR, RCC_CR_HSION);
  26. _WBS(RCC->CR, RCC_CR_HSIRDY);
  27. _BST(RCC->CR, RCC_CR_PLLON);
  28. _WBS(RCC->CR, RCC_CR_PLLRDY);
  29. /* switch clock to PLL */
  30. _BMD(RCC->CFGR, RCC_CFGR_SW, RCC_CFGR_SW_PLL);
  31. _WVL(RCC->CFGR, RCC_CFGR_SWS, RCC_CFGR_SWS_PLL);
  32. #elif defined(STM32L1)
  33. _BST(RCC->APB1ENR, RCC_APB1ENR_PWREN);
  34. _BMD(PWR->CR, PWR_CR_VOS, PWR_CR_VOS_0);
  35. _WBC(PWR->CSR, PWR_CSR_VOSF);
  36. /* set FLASH latency to 1 */
  37. _BST(FLASH->ACR, FLASH_ACR_ACC64);
  38. _BST(FLASH->ACR, FLASH_ACR_LATENCY);
  39. /* set clock at 32 MHz PLL 6/3 HSI */
  40. _BMD(RCC->CFGR, RCC_CFGR_PLLDIV | RCC_CFGR_PLLMUL | RCC_CFGR_PLLSRC, RCC_CFGR_PLLDIV3 | RCC_CFGR_PLLMUL6);
  41. _BST(RCC->CR, RCC_CR_HSION);
  42. _WBS(RCC->CR, RCC_CR_HSIRDY);
  43. _BST(RCC->CR, RCC_CR_PLLON);
  44. _WBS(RCC->CR, RCC_CR_PLLRDY);
  45. /* switch clock to PLL */
  46. _BMD(RCC->CFGR, RCC_CFGR_SW, RCC_CFGR_SW_PLL);
  47. _WVL(RCC->CFGR, RCC_CFGR_SWS, RCC_CFGR_SWS_PLL);
  48. #elif defined(STM32L476xx)
  49. _BST(RCC->APB1ENR1, RCC_APB1ENR1_PWREN);
  50. /* Set power Range 1 */
  51. _BMD(PWR->CR1, PWR_CR1_VOS, PWR_CR1_VOS_0);
  52. _WBC(PWR->SR2, PWR_SR2_VOSF);
  53. /* Adjust Flash latency */
  54. _BMD(FLASH->ACR, FLASH_ACR_LATENCY, FLASH_ACR_LATENCY_2WS);
  55. /* set clock 48Mhz MSI */
  56. _BMD(RCC->CR, RCC_CR_MSIRANGE, RCC_CR_MSIRANGE_11 | RCC_CR_MSIRGSEL);
  57. /* set MSI as 48MHz USB */
  58. _BMD(RCC->CCIPR, RCC_CCIPR_CLK48SEL, RCC_CCIPR_CLK48SEL_0 | RCC_CCIPR_CLK48SEL_1);
  59. /* enable GPIOA clock */
  60. _BST(RCC->AHB2ENR, RCC_AHB2ENR_GPIOAEN);
  61. /* set GP11 and GP12 as USB data pins AF10 */
  62. _BST(GPIOA->AFR[1], (0x0A << 12) | (0x0A << 16));
  63. _BMD(GPIOA->MODER, (0x03 << 22) | (0x03 << 24), (0x02 << 22) | (0x02 << 24));
  64. #elif defined(STM32F103x6)
  65. /* set flash latency 1WS */
  66. _BMD(FLASH->ACR, FLASH_ACR_LATENCY, FLASH_ACR_LATENCY_1);
  67. /* use PLL 48MHz clock from 8Mhz HSI */
  68. _BMD(RCC->CFGR,
  69. RCC_CFGR_PLLMULL | RCC_CFGR_PLLSRC | RCC_CFGR_USBPRE,
  70. RCC_CFGR_PLLMULL12 | RCC_CFGR_USBPRE);
  71. _BST(RCC->CR, RCC_CR_PLLON);
  72. _WBS(RCC->CR, RCC_CR_PLLRDY);
  73. /* switch to PLL */
  74. _BMD(RCC->CFGR, RCC_CFGR_SW, RCC_CFGR_SW_PLL);
  75. _WVL(RCC->CFGR, RCC_CFGR_SWS, RCC_CFGR_SWS_PLL);
  76. #elif defined(STM32F303xE)
  77. /* set flash latency 1WS */
  78. _BMD(FLASH->ACR, FLASH_ACR_LATENCY, FLASH_ACR_LATENCY_1);
  79. /* use PLL 48MHz clock from 8Mhz HSI */
  80. _BMD(RCC->CFGR,
  81. RCC_CFGR_PLLMUL | RCC_CFGR_PLLSRC | RCC_CFGR_USBPRE,
  82. RCC_CFGR_PLLMUL12 | RCC_CFGR_USBPRE);
  83. _BST(RCC->CR, RCC_CR_PLLON);
  84. _WBS(RCC->CR, RCC_CR_PLLRDY);
  85. /* switch to PLL */
  86. _BMD(RCC->CFGR, RCC_CFGR_SW, RCC_CFGR_SW_PLL);
  87. _WVL(RCC->CFGR, RCC_CFGR_SWS, RCC_CFGR_SWS_PLL);
  88. #elif defined(STM32F373xC)
  89. /* set flash latency 1WS */
  90. _BMD(FLASH->ACR, FLASH_ACR_LATENCY, FLASH_ACR_LATENCY_1);
  91. _BMD(RCC->CFGR,
  92. RCC_CFGR_PLLMUL | RCC_CFGR_PLLSRC | RCC_CFGR_USBPRE | RCC_CFGR_PPRE1,
  93. RCC_CFGR_PLLMUL12 | RCC_CFGR_USBPRE | RCC_CFGR_PPRE1_DIV2);
  94. _BST(RCC->CR, RCC_CR_PLLON);
  95. _WBS(RCC->CR, RCC_CR_PLLRDY);
  96. /* switch to PLL */
  97. _BMD(RCC->CFGR, RCC_CFGR_SW, RCC_CFGR_SW_PLL);
  98. _WVL(RCC->CFGR, RCC_CFGR_SWS, RCC_CFGR_SWS_PLL);
  99. /* Enabling USB PA11 PA12 AF 0x0E.
  100. * This is still undocumented in the 7th!! revision of the datasheet.
  101. * Thank you, mo***rs from ST for extra 5 hrs of debugging.
  102. */
  103. _BST(RCC->AHBENR, RCC_AHBENR_GPIOAEN);
  104. _BST(GPIOA->AFR[1], (0x0E << 12) | (0x0E << 16));
  105. _BMD(GPIOA->MODER, (0x03 << 22) | (0x03 << 24), (0x02 << 22) | (0x02 << 24)); // MCO
  106. #elif defined(STM32F429xx)
  107. /* set flash latency 2WS */
  108. _BMD(FLASH->ACR, FLASH_ACR_LATENCY, FLASH_ACR_LATENCY_2WS);
  109. /* setting up PLL 16MHz HSI, VCO=144MHz, PLLP = 72MHz PLLQ = 48MHz */
  110. _BMD(RCC->PLLCFGR,
  111. RCC_PLLCFGR_PLLM | RCC_PLLCFGR_PLLN | RCC_PLLCFGR_PLLSRC | RCC_PLLCFGR_PLLQ | RCC_PLLCFGR_PLLP,
  112. _VAL2FLD(RCC_PLLCFGR_PLLM, 8) | _VAL2FLD(RCC_PLLCFGR_PLLN, 72) | _VAL2FLD(RCC_PLLCFGR_PLLQ, 3));
  113. /* enabling PLL */
  114. _BST(RCC->CR, RCC_CR_PLLON);
  115. _WBS(RCC->CR, RCC_CR_PLLRDY);
  116. /* switching to PLL */
  117. _BMD(RCC->CFGR, RCC_CFGR_SW, RCC_CFGR_SW_PLL);
  118. _WVL(RCC->CFGR, RCC_CFGR_SWS, RCC_CFGR_SWS_PLL);
  119. #if defined(USBD_PRIMARY_OTGHS)
  120. /* enabling GPIOB and setting PB13, PB14 and PB15 to AF11 (USB_OTG2FS) */
  121. _BST(RCC->AHB1ENR, RCC_AHB1ENR_GPIOBEN);
  122. #if defined(USBD_VBUS_DETECT)
  123. _BST(GPIOB->AFR[1], (0x0C << 24) | (0x0C << 28) | (0x0C << 20));
  124. _BMD(GPIOB->MODER, (0x03 << 28) | (0x03 << 30) | (0x03 << 26), (0x02 << 28) | (0x02 << 30) | (0x02 << 26));
  125. #else //defined(USBD_VBUS_DETECT)
  126. _BST(GPIOB->AFR[1], (0x0C << 24) | (0x0C << 28));
  127. _BMD(GPIOB->MODER, (0x03 << 28) | (0x03 << 30), (0x02 << 28) | (0x02 << 30));
  128. #endif //defined(USBD_VBUS_DETECT)
  129. #else //defined(USBD_PRIMARY_OTGHS)
  130. /* enabling GPIOA and setting PA11 and PA12 to AF10 (USB_FS) */
  131. _BST(RCC->AHB1ENR, RCC_AHB1ENR_GPIOAEN);
  132. _BST(GPIOA->AFR[1], (0x0A << 12) | (0x0A << 16));
  133. _BMD(GPIOA->MODER, (0x03 << 22) | (0x03 << 24), (0x02 << 22) | (0x02 << 24));
  134. #endif //defined(USBD_PRIMARY_OTGHS)
  135. #elif defined(STM32F446xx)
  136. /* set flash latency 2WS */
  137. _BMD(FLASH->ACR, FLASH_ACR_LATENCY, FLASH_ACR_LATENCY_2WS);
  138. /* setting up PLL 16MHz HSI, VCO=144MHz, PLLP = 72MHz PLLQ = 48MHz */
  139. _BMD(RCC->PLLCFGR,
  140. RCC_PLLCFGR_PLLM | RCC_PLLCFGR_PLLN | RCC_PLLCFGR_PLLP | RCC_PLLCFGR_PLLSRC | RCC_PLLCFGR_PLLQ,
  141. _VAL2FLD(RCC_PLLCFGR_PLLM, 8) | _VAL2FLD(RCC_PLLCFGR_PLLN, 72) | _VAL2FLD(RCC_PLLCFGR_PLLQ, 3));
  142. /* enabling PLL */
  143. _BST(RCC->CR, RCC_CR_PLLON);
  144. _WBS(RCC->CR, RCC_CR_PLLRDY);
  145. /* switching to PLL */
  146. _BMD(RCC->CFGR, RCC_CFGR_SW, RCC_CFGR_SW_PLL);
  147. _WVL(RCC->CFGR, RCC_CFGR_SWS, RCC_CFGR_SWS_PLL);
  148. /* enabling GPIOA and setting PA11 and PA12 to AF10 (USB_FS) */
  149. _BST(RCC->AHB1ENR, RCC_AHB1ENR_GPIOAEN);
  150. _BST(GPIOA->AFR[1], (0x0A << 12) | (0x0A << 16));
  151. _BMD(GPIOA->MODER, (0x03 << 22) | (0x03 << 24), (0x02 << 22) | (0x02 << 24));
  152. #elif defined(STM32F105xC) || defined(STM32F107xC)
  153. _BST(RCC->CR, RCC_CR_HSION);
  154. _WBS(RCC->CR, RCC_CR_HSIRDY);
  155. _BMD(RCC->CFGR, RCC_CFGR_SW, RCC_CFGR_SW_HSI);
  156. _BMD(RCC->CFGR, RCC_CFGR_SWS, RCC_CFGR_SWS_HSI);
  157. /* set flash latency 1WS */
  158. _BMD(FLASH->ACR, FLASH_ACR_LATENCY, FLASH_ACR_LATENCY_1);
  159. _BST(RCC->CR, RCC_CR_HSEON);
  160. _WBS(RCC->CR, RCC_CR_HSERDY);
  161. /* switch to HSE */
  162. _BMD(RCC->CFGR, RCC_CFGR_SW, RCC_CFGR_SW_HSE);
  163. _WVL(RCC->CFGR, RCC_CFGR_SWS, RCC_CFGR_SWS_HSE);
  164. #if defined(HSE_25MHZ)
  165. RCC->CFGR = RCC_CFGR_PLLMULL9 | RCC_CFGR_PLLSRC | \
  166. RCC_CFGR_ADCPRE_DIV8 | RCC_CFGR_PPRE2_DIV1 | \
  167. RCC_CFGR_PPRE1_DIV2 | RCC_CFGR_HPRE_DIV1 | \
  168. RCC_CFGR_OTGFSPRE*0;
  169. /* PREDIV1SRC= PLL2, PLL2MUL = 8, PREDIV1 = 5, PREDIV2=5 */
  170. RCC->CFGR2 = RCC_CFGR2_PREDIV1SRC | RCC_CFGR2_PLL2MUL8 | \
  171. RCC_CFGR2_PREDIV1_DIV5 | RCC_CFGR2_PREDIV2_DIV5;
  172. _BST(RCC->CR, RCC_CR_PLL2ON);
  173. _WBS(RCC->CR, RCC_CR_PLL2RDY);
  174. _BST(RCC->CR, RCC_CR_PLLON);
  175. _WBS(RCC->CR, RCC_CR_PLLRDY);
  176. #else
  177. RCC->CFGR = RCC_CFGR_PLLMULL9 | RCC_CFGR_PLLSRC | RCC_CFGR_ADCPRE_DIV8 | \
  178. RCC_CFGR_PPRE2_DIV1 | RCC_CFGR_PPRE1_DIV2 | RCC_CFGR_HPRE_DIV1;
  179. _BMD(RCC->CFGR2, RCC_CFGR2_PREDIV1, RCC_CFGR2_PREDIV1_DIV1);
  180. _BCL(RCC->CFGR2, RCC_CFGR2_PREDIV1SRC);
  181. _BST(RCC->CR, RCC_CR_PLLON);
  182. _WBS(RCC->CR, RCC_CR_PLLRDY);
  183. #endif
  184. RCC->CFGR |= RCC_CFGR_MCO_PLLCLK_DIV2;
  185. /* set flash latency 2WS */
  186. _BMD(FLASH->ACR, FLASH_ACR_LATENCY, FLASH_ACR_LATENCY_2);
  187. /* switch to PLL */
  188. _BMD(RCC->CFGR, RCC_CFGR_SW, RCC_CFGR_SW_PLL);
  189. _WVL(RCC->CFGR, RCC_CFGR_SWS, RCC_CFGR_SWS_PLL);
  190. #elif defined(STM32L433xx)
  191. /* using HSI16 as AHB/CPU clock, HSI48 as USB PHY clock */
  192. _BST(RCC->CR, RCC_CR_HSION);
  193. _WBS(RCC->CR, RCC_CR_HSIRDY);
  194. _BMD(RCC->CFGR, RCC_CFGR_SW, RCC_CFGR_SW_HSI);
  195. _WVL(RCC->CFGR, RCC_CFGR_SWS, RCC_CFGR_SWS_HSI);
  196. _BST(RCC->CRRCR, RCC_CRRCR_HSI48ON);
  197. _WBS(RCC->CRRCR, RCC_CRRCR_HSI48RDY);
  198. _BMD(RCC->CCIPR, RCC_CCIPR_CLK48SEL, 0);
  199. /* setup PA11 PA12 to AF10 (USB FS) */
  200. _BST(RCC->AHB2ENR, RCC_AHB2ENR_GPIOAEN);
  201. _BMD(GPIOA->MODER, (0x03 << 22) | (0x03 << 24), (0x02 << 22) | (0x02 << 24));
  202. _BST(GPIOA->AFR[1], (0x0A << 12) | (0x0A << 16));
  203. /* Disabling USB Vddusb power isolation. Vusb connected to Vdd */
  204. _BST(RCC->APB1ENR1, RCC_APB1ENR1_PWREN);
  205. _BST(PWR->CR2, PWR_CR2_USV);
  206. #elif defined(STM32F070xB)
  207. /* set flash latency 1WS */
  208. _BST(FLASH->ACR, FLASH_ACR_LATENCY);
  209. /* use PLL 48MHz clock from 8Mhz HSI */
  210. _BMD(RCC->CFGR,
  211. RCC_CFGR_PLLMUL | RCC_CFGR_PLLSRC | RCC_CFGR_USBPRE,
  212. RCC_CFGR_PLLMUL12 | RCC_CFGR_USBPRE);
  213. _BST(RCC->CR, RCC_CR_PLLON);
  214. _WBS(RCC->CR, RCC_CR_PLLRDY);
  215. /* switch to PLL */
  216. _BMD(RCC->CFGR, RCC_CFGR_SW, RCC_CFGR_SW_PLL);
  217. _WVL(RCC->CFGR, RCC_CFGR_SWS, RCC_CFGR_SWS_PLL);
  218. _BST(RCC->CFGR3, RCC_CFGR3_USBSW_PLLCLK);
  219. #elif defined(STM32G4)
  220. /* using HSI16 as AHB/CPU clock, HSI48 as USB PHY clock */
  221. _BST(RCC->CRRCR, RCC_CRRCR_HSI48ON);
  222. _WBS(RCC->CRRCR, RCC_CRRCR_HSI48RDY);
  223. #else
  224. #error Not supported
  225. #endif
  226. }
  227. void __libc_init_array(void) {
  228. }
  229. void SystemInit(void) {
  230. cdc_init_rcc();
  231. }