cdc_startup.c 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315
  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_compat.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(STM32F303xC)
  89. /* set flash latency 1WS */
  90. _BMD(FLASH->ACR, FLASH_ACR_LATENCY, FLASH_ACR_LATENCY_1);
  91. /* use PLL 48MHz clock from 8Mhz HSI */
  92. _BMD(RCC->CFGR,
  93. RCC_CFGR_PLLMUL | RCC_CFGR_PLLSRC | RCC_CFGR_USBPRE,
  94. RCC_CFGR_PLLMUL12 | RCC_CFGR_USBPRE);
  95. _BST(RCC->CR, RCC_CR_PLLON);
  96. _WBS(RCC->CR, RCC_CR_PLLRDY);
  97. /* switch to PLL */
  98. _BMD(RCC->CFGR, RCC_CFGR_SW, RCC_CFGR_SW_PLL);
  99. _WVL(RCC->CFGR, RCC_CFGR_SWS, RCC_CFGR_SWS_PLL);
  100. _BST(RCC->AHBENR, RCC_AHBENR_GPIOAEN);
  101. _BST(GPIOA->AFR[1], (0x0E << 12) | (0x0E << 16));
  102. _BMD(GPIOA->MODER, (0x03 << 22) | (0x03 << 24), (0x02 << 22) | (0x02 << 24));
  103. #elif defined(STM32F373xC)
  104. /* set flash latency 1WS */
  105. _BMD(FLASH->ACR, FLASH_ACR_LATENCY, FLASH_ACR_LATENCY_1);
  106. _BMD(RCC->CFGR,
  107. RCC_CFGR_PLLMUL | RCC_CFGR_PLLSRC | RCC_CFGR_USBPRE | RCC_CFGR_PPRE1,
  108. RCC_CFGR_PLLMUL12 | RCC_CFGR_USBPRE | RCC_CFGR_PPRE1_DIV2);
  109. _BST(RCC->CR, RCC_CR_PLLON);
  110. _WBS(RCC->CR, RCC_CR_PLLRDY);
  111. /* switch to PLL */
  112. _BMD(RCC->CFGR, RCC_CFGR_SW, RCC_CFGR_SW_PLL);
  113. _WVL(RCC->CFGR, RCC_CFGR_SWS, RCC_CFGR_SWS_PLL);
  114. /* Enabling USB PA11 PA12 AF 0x0E.
  115. * This is still undocumented in the 7th!! revision of the datasheet.
  116. * Thank you, mo***rs from ST for extra 5 hrs of debugging.
  117. */
  118. _BST(RCC->AHBENR, RCC_AHBENR_GPIOAEN);
  119. _BST(GPIOA->AFR[1], (0x0E << 12) | (0x0E << 16));
  120. _BMD(GPIOA->MODER, (0x03 << 22) | (0x03 << 24), (0x02 << 22) | (0x02 << 24)); // MCO
  121. #elif defined(STM32F429xx) || defined(STM32F405xx) \
  122. || defined(STM32F401xC) || defined(STM32F401xE) || defined(STM32F411xE)
  123. /* set flash latency 2WS */
  124. _BMD(FLASH->ACR, FLASH_ACR_LATENCY, FLASH_ACR_LATENCY_2WS);
  125. /* setting up PLL 16MHz HSI, VCO=144MHz, PLLP = 72MHz PLLQ = 48MHz */
  126. _BMD(RCC->PLLCFGR,
  127. RCC_PLLCFGR_PLLM | RCC_PLLCFGR_PLLN | RCC_PLLCFGR_PLLSRC | RCC_PLLCFGR_PLLQ | RCC_PLLCFGR_PLLP,
  128. _VAL2FLD(RCC_PLLCFGR_PLLM, 8) | _VAL2FLD(RCC_PLLCFGR_PLLN, 72) | _VAL2FLD(RCC_PLLCFGR_PLLQ, 3));
  129. /* enabling PLL */
  130. _BST(RCC->CR, RCC_CR_PLLON);
  131. _WBS(RCC->CR, RCC_CR_PLLRDY);
  132. /* Setup CFGR to PLL*/
  133. /* APB1 | APB2 */
  134. /* STM32F411 <50Mhz | <100MHz */
  135. /* STM32F429 <45MHz | <90MHz */
  136. /* STM32F405, STM32F401 <42MHz | <84MHz */
  137. _BMD(RCC->CFGR, RCC_CFGR_SW | RCC_CFGR_PPRE1, RCC_CFGR_SW_PLL | RCC_CFGR_PPRE1_DIV2);
  138. _WVL(RCC->CFGR, RCC_CFGR_SWS, RCC_CFGR_SWS_PLL);
  139. #if defined(USBD_PRIMARY_OTGHS)
  140. /* enabling GPIOB and setting PB13, PB14 and PB15 to AF11 (USB_OTG2FS) */
  141. _BST(RCC->AHB1ENR, RCC_AHB1ENR_GPIOBEN);
  142. #if defined(USBD_VBUS_DETECT)
  143. _BST(GPIOB->AFR[1], (0x0C << 24) | (0x0C << 28) | (0x0C << 20));
  144. _BMD(GPIOB->MODER, (0x03 << 28) | (0x03 << 30) | (0x03 << 26), (0x02 << 28) | (0x02 << 30) | (0x02 << 26));
  145. #else //defined(USBD_VBUS_DETECT)
  146. _BST(GPIOB->AFR[1], (0x0C << 24) | (0x0C << 28));
  147. _BMD(GPIOB->MODER, (0x03 << 28) | (0x03 << 30), (0x02 << 28) | (0x02 << 30));
  148. #endif //defined(USBD_VBUS_DETECT)
  149. #else //defined(USBD_PRIMARY_OTGHS)
  150. /* enabling GPIOA and setting PA11 and PA12 to AF10 (USB_FS) */
  151. _BST(RCC->AHB1ENR, RCC_AHB1ENR_GPIOAEN);
  152. _BST(GPIOA->AFR[1], (0x0A << 12) | (0x0A << 16));
  153. _BMD(GPIOA->MODER, (0x03 << 22) | (0x03 << 24), (0x02 << 22) | (0x02 << 24));
  154. #endif //defined(USBD_PRIMARY_OTGHS)
  155. #elif defined(STM32F446xx) || defined(STM32F745xx)
  156. /* set flash latency 2WS */
  157. _BMD(FLASH->ACR, FLASH_ACR_LATENCY, FLASH_ACR_LATENCY_2WS);
  158. /* setting up PLL 16MHz HSI, VCO=144MHz, PLLP = 72MHz PLLQ = 48MHz */
  159. _BMD(RCC->PLLCFGR,
  160. RCC_PLLCFGR_PLLM | RCC_PLLCFGR_PLLN | RCC_PLLCFGR_PLLP | RCC_PLLCFGR_PLLSRC | RCC_PLLCFGR_PLLQ,
  161. _VAL2FLD(RCC_PLLCFGR_PLLM, 8) | _VAL2FLD(RCC_PLLCFGR_PLLN, 72) | _VAL2FLD(RCC_PLLCFGR_PLLQ, 3));
  162. /* enabling PLL */
  163. _BST(RCC->CR, RCC_CR_PLLON);
  164. _WBS(RCC->CR, RCC_CR_PLLRDY);
  165. /* switching to PLL */
  166. _BMD(RCC->CFGR, RCC_CFGR_SW, RCC_CFGR_SW_PLL);
  167. _WVL(RCC->CFGR, RCC_CFGR_SWS, RCC_CFGR_SWS_PLL);
  168. /* enabling GPIOA and setting PA11 and PA12 to AF10 (USB_FS) */
  169. #if defined(USBD_PRIMARY_OTGHS)
  170. _BST(RCC->AHB1ENR, RCC_AHB1ENR_GPIOBEN);
  171. _BST(GPIOB->AFR[1], (0x0C << 24) | (0x0C << 28));
  172. _BMD(GPIOB->MODER, (0x03 << 28) | (0x03 << 30), (0x02 << 28) | (0x02 << 30));
  173. #else
  174. _BST(RCC->AHB1ENR, RCC_AHB1ENR_GPIOAEN);
  175. _BST(GPIOA->AFR[1], (0x0A << 12) | (0x0A << 16));
  176. _BMD(GPIOA->MODER, (0x03 << 22) | (0x03 << 24), (0x02 << 22) | (0x02 << 24));
  177. #endif
  178. #elif defined(STM32F105xC) || defined(STM32F107xC)
  179. _BST(RCC->CR, RCC_CR_HSION);
  180. _WBS(RCC->CR, RCC_CR_HSIRDY);
  181. _BMD(RCC->CFGR, RCC_CFGR_SW, RCC_CFGR_SW_HSI);
  182. _BMD(RCC->CFGR, RCC_CFGR_SWS, RCC_CFGR_SWS_HSI);
  183. /* set flash latency 1WS */
  184. _BMD(FLASH->ACR, FLASH_ACR_LATENCY, FLASH_ACR_LATENCY_1);
  185. _BST(RCC->CR, RCC_CR_HSEON);
  186. _WBS(RCC->CR, RCC_CR_HSERDY);
  187. /* switch to HSE */
  188. _BMD(RCC->CFGR, RCC_CFGR_SW, RCC_CFGR_SW_HSE);
  189. _WVL(RCC->CFGR, RCC_CFGR_SWS, RCC_CFGR_SWS_HSE);
  190. #if defined(HSE_25MHZ)
  191. RCC->CFGR = RCC_CFGR_PLLMULL9 | RCC_CFGR_PLLSRC | \
  192. RCC_CFGR_ADCPRE_DIV8 | RCC_CFGR_PPRE2_DIV1 | \
  193. RCC_CFGR_PPRE1_DIV2 | RCC_CFGR_HPRE_DIV1 | \
  194. RCC_CFGR_OTGFSPRE*0;
  195. /* PREDIV1SRC= PLL2, PLL2MUL = 8, PREDIV1 = 5, PREDIV2=5 */
  196. RCC->CFGR2 = RCC_CFGR2_PREDIV1SRC | RCC_CFGR2_PLL2MUL8 | \
  197. RCC_CFGR2_PREDIV1_DIV5 | RCC_CFGR2_PREDIV2_DIV5;
  198. _BST(RCC->CR, RCC_CR_PLL2ON);
  199. _WBS(RCC->CR, RCC_CR_PLL2RDY);
  200. _BST(RCC->CR, RCC_CR_PLLON);
  201. _WBS(RCC->CR, RCC_CR_PLLRDY);
  202. #else
  203. RCC->CFGR = RCC_CFGR_PLLMULL9 | RCC_CFGR_PLLSRC | RCC_CFGR_ADCPRE_DIV8 | \
  204. RCC_CFGR_PPRE2_DIV1 | RCC_CFGR_PPRE1_DIV2 | RCC_CFGR_HPRE_DIV1;
  205. _BMD(RCC->CFGR2, RCC_CFGR2_PREDIV1, RCC_CFGR2_PREDIV1_DIV1);
  206. _BCL(RCC->CFGR2, RCC_CFGR2_PREDIV1SRC);
  207. _BST(RCC->CR, RCC_CR_PLLON);
  208. _WBS(RCC->CR, RCC_CR_PLLRDY);
  209. #endif
  210. RCC->CFGR |= RCC_CFGR_MCO_PLLCLK_DIV2;
  211. /* set flash latency 2WS */
  212. _BMD(FLASH->ACR, FLASH_ACR_LATENCY, FLASH_ACR_LATENCY_2);
  213. /* switch to PLL */
  214. _BMD(RCC->CFGR, RCC_CFGR_SW, RCC_CFGR_SW_PLL);
  215. _WVL(RCC->CFGR, RCC_CFGR_SWS, RCC_CFGR_SWS_PLL);
  216. #elif defined(STM32L433xx)
  217. /* using HSI16 as AHB/CPU clock, HSI48 as USB PHY clock */
  218. _BST(RCC->CR, RCC_CR_HSION);
  219. _WBS(RCC->CR, RCC_CR_HSIRDY);
  220. _BMD(RCC->CFGR, RCC_CFGR_SW, RCC_CFGR_SW_HSI);
  221. _WVL(RCC->CFGR, RCC_CFGR_SWS, RCC_CFGR_SWS_HSI);
  222. _BST(RCC->CRRCR, RCC_CRRCR_HSI48ON);
  223. _WBS(RCC->CRRCR, RCC_CRRCR_HSI48RDY);
  224. _BMD(RCC->CCIPR, RCC_CCIPR_CLK48SEL, 0);
  225. /* setup PA11 PA12 to AF10 (USB FS) */
  226. _BST(RCC->AHB2ENR, RCC_AHB2ENR_GPIOAEN);
  227. _BMD(GPIOA->MODER, (0x03 << 22) | (0x03 << 24), (0x02 << 22) | (0x02 << 24));
  228. _BST(GPIOA->AFR[1], (0x0A << 12) | (0x0A << 16));
  229. /* Disabling USB Vddusb power isolation. Vusb connected to Vdd */
  230. _BST(RCC->APB1ENR1, RCC_APB1ENR1_PWREN);
  231. _BST(PWR->CR2, PWR_CR2_USV);
  232. #elif defined(STM32F070xB)
  233. /* set flash latency 1WS */
  234. _BST(FLASH->ACR, FLASH_ACR_LATENCY);
  235. /* use PLL 48MHz clock from 8Mhz HSI */
  236. _BMD(RCC->CFGR,
  237. RCC_CFGR_PLLMUL | RCC_CFGR_PLLSRC | RCC_CFGR_USBPRE,
  238. RCC_CFGR_PLLMUL12 | RCC_CFGR_USBPRE);
  239. _BST(RCC->CR, RCC_CR_PLLON);
  240. _WBS(RCC->CR, RCC_CR_PLLRDY);
  241. /* switch to PLL */
  242. _BMD(RCC->CFGR, RCC_CFGR_SW, RCC_CFGR_SW_PLL);
  243. _WVL(RCC->CFGR, RCC_CFGR_SWS, RCC_CFGR_SWS_PLL);
  244. _BST(RCC->CFGR3, RCC_CFGR3_USBSW_PLLCLK);
  245. #elif defined(STM32F042x6)
  246. /* set flash latency 1WS */
  247. _BST(FLASH->ACR, FLASH_ACR_LATENCY);
  248. /* use HSI48 as clock incl. USB PHY clock, no PLL */
  249. _BST(RCC->CR2, RCC_CR2_HSI48ON);
  250. _WBS(RCC->CR2, RCC_CR2_HSI48RDY);
  251. #elif defined(STM32G4)
  252. /* using HSI16 as AHB/CPU clock, HSI48 as USB PHY clock */
  253. _BST(RCC->CRRCR, RCC_CRRCR_HSI48ON);
  254. _WBS(RCC->CRRCR, RCC_CRRCR_HSI48RDY);
  255. #elif defined(STM32WB55xx)
  256. /* using HSI16 as AHB/CPU clock, HSI48 as USB PHY clock */
  257. _BST(RCC->CR, RCC_CR_HSION);
  258. _WBS(RCC->CR, RCC_CR_HSIRDY);
  259. _BMD(RCC->CFGR, RCC_CFGR_SW, (0x01UL << RCC_CFGR_SW_Pos)); // HSI16
  260. _WVL(RCC->CFGR, RCC_CFGR_SWS, (0x01UL << RCC_CFGR_SWS_Pos));
  261. _BST(RCC->CRRCR, RCC_CRRCR_HSI48ON);
  262. _WBS(RCC->CRRCR, RCC_CRRCR_HSI48RDY);
  263. _BMD(RCC->CCIPR, RCC_CCIPR_CLK48SEL, 0);
  264. /* setup PA11 PA12 to AF10 (USB FS) */
  265. _BST(RCC->AHB2ENR, RCC_AHB2ENR_GPIOAEN);
  266. _BMD(GPIOA->MODER, (0x03 << 22) | (0x03 << 24), (0x02 << 22) | (0x02 << 24));
  267. _BST(GPIOA->AFR[1], (0x0A << 12) | (0x0A << 16));
  268. /* Disabling USB Vddusb power isolation. Vusb connected to Vdd */
  269. _BST(PWR->CR2, PWR_CR2_USV);
  270. #elif defined(STM32H743xx)
  271. /* Enable USB supply */
  272. _BST(PWR->CR3, PWR_CR3_SCUEN | PWR_CR3_LDOEN | PWR_CR3_USB33DEN);
  273. /* Enable HSI48 and use as USB PHY clock */
  274. _BST(RCC->CR, RCC_CR_HSI48ON);
  275. _WBS(RCC->CR, RCC_CR_HSI48RDY);
  276. _BMD(RCC->D2CCIP2R, RCC_D2CCIP2R_USBSEL, 3 << RCC_D2CCIP2R_USBSEL_Pos);
  277. /* enabling GPIOA and setting PA11 and PA12 to AF10 (USB_FS) */
  278. _BST(RCC->AHB4ENR, RCC_AHB4ENR_GPIOAEN);
  279. _BMD(GPIOA->MODER, (0x03 << 22) | (0x03 << 24), (0x02 << 22) | (0x02 << 24));
  280. _BST(GPIOA->AFR[1], (0x0A << 12) | (0x0A << 16));
  281. #else
  282. #error Not supported
  283. #endif
  284. }
  285. void __libc_init_array(void) {
  286. }
  287. void SystemInit(void) {
  288. cdc_init_rcc();
  289. }