drv_usbd.c 7.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291
  1. /*
  2. * Copyright (c) 2006-2023, RT-Thread Development Team
  3. *
  4. * SPDX-License-Identifier: Apache-2.0
  5. *
  6. * Change Logs:
  7. * Date Author Notes
  8. * 2019-04-10 ZYH first version
  9. * 2019-10-27 flybreak Compatible with the HS
  10. */
  11. #include <rtthread.h>
  12. #ifdef BSP_USING_USBD
  13. #include <rtdevice.h>
  14. #include "board.h"
  15. #include <string.h>
  16. #include <drv_config.h>
  17. static PCD_HandleTypeDef _stm_pcd;
  18. static struct udcd _stm_udc;
  19. static struct ep_id _ep_pool[] =
  20. {
  21. {0x0, USB_EP_ATTR_CONTROL, USB_DIR_INOUT, 64, ID_ASSIGNED },
  22. #ifdef BSP_USBD_EP_ISOC
  23. {0x1, USB_EP_ATTR_ISOC, USB_DIR_IN, 64, ID_UNASSIGNED},
  24. {0x1, USB_EP_ATTR_ISOC, USB_DIR_OUT, 64, ID_UNASSIGNED},
  25. #else
  26. {0x1, USB_EP_ATTR_BULK, USB_DIR_IN, 64, ID_UNASSIGNED},
  27. {0x1, USB_EP_ATTR_BULK, USB_DIR_OUT, 64, ID_UNASSIGNED},
  28. {0x2, USB_EP_ATTR_BULK, USB_DIR_IN, 64, ID_UNASSIGNED},
  29. {0x2, USB_EP_ATTR_BULK, USB_DIR_OUT, 64, ID_UNASSIGNED},
  30. {0x3, USB_EP_ATTR_BULK, USB_DIR_IN, 64, ID_UNASSIGNED},
  31. {0x3, USB_EP_ATTR_BULK, USB_DIR_OUT, 64, ID_UNASSIGNED},
  32. #endif
  33. {0x4, USB_EP_ATTR_INT, USB_DIR_IN, 64, ID_UNASSIGNED},
  34. {0x4, USB_EP_ATTR_INT, USB_DIR_OUT, 64, ID_UNASSIGNED},
  35. {0x5, USB_EP_ATTR_INT, USB_DIR_IN, 64, ID_UNASSIGNED},
  36. {0x5, USB_EP_ATTR_INT, USB_DIR_OUT, 64, ID_UNASSIGNED},
  37. {0x6, USB_EP_ATTR_INT, USB_DIR_IN, 64, ID_UNASSIGNED},
  38. {0x6, USB_EP_ATTR_INT, USB_DIR_OUT, 64, ID_UNASSIGNED},
  39. {0x7, USB_EP_ATTR_BULK, USB_DIR_IN, 64, ID_UNASSIGNED},
  40. {0x8, USB_EP_ATTR_BULK, USB_DIR_IN, 64, ID_UNASSIGNED},
  41. {0x9, USB_EP_ATTR_BULK, USB_DIR_IN, 64, ID_UNASSIGNED},
  42. #if !defined(SOC_SERIES_STM32F1)
  43. {0x9, USB_EP_ATTR_BULK, USB_DIR_OUT, 64, ID_UNASSIGNED},
  44. #endif
  45. {0xFF, USB_EP_ATTR_TYPE_MASK, USB_DIR_MASK, 0, ID_ASSIGNED },
  46. };
  47. void USBD_IRQ_HANDLER(void)
  48. {
  49. rt_interrupt_enter();
  50. HAL_PCD_IRQHandler(&_stm_pcd);
  51. /* leave interrupt */
  52. rt_interrupt_leave();
  53. }
  54. void HAL_PCD_ResetCallback(PCD_HandleTypeDef *pcd)
  55. {
  56. /* open ep0 OUT and IN */
  57. HAL_PCD_EP_Open(pcd, 0x00, 0x40, EP_TYPE_CTRL);
  58. HAL_PCD_EP_Open(pcd, 0x80, 0x40, EP_TYPE_CTRL);
  59. rt_usbd_reset_handler(&_stm_udc);
  60. }
  61. void HAL_PCD_SetupStageCallback(PCD_HandleTypeDef *hpcd)
  62. {
  63. rt_usbd_ep0_setup_handler(&_stm_udc, (struct urequest *)hpcd->Setup);
  64. }
  65. void HAL_PCD_DataInStageCallback(PCD_HandleTypeDef *hpcd, uint8_t epnum)
  66. {
  67. if (epnum == 0)
  68. {
  69. rt_usbd_ep0_in_handler(&_stm_udc);
  70. }
  71. else
  72. {
  73. rt_usbd_ep_in_handler(&_stm_udc, 0x80 | epnum, hpcd->IN_ep[epnum].xfer_count);
  74. }
  75. }
  76. void HAL_PCD_ConnectCallback(PCD_HandleTypeDef *hpcd)
  77. {
  78. rt_usbd_connect_handler(&_stm_udc);
  79. }
  80. void HAL_PCD_SOFCallback(PCD_HandleTypeDef *hpcd)
  81. {
  82. rt_usbd_sof_handler(&_stm_udc);
  83. }
  84. void HAL_PCD_DisconnectCallback(PCD_HandleTypeDef *hpcd)
  85. {
  86. rt_usbd_disconnect_handler(&_stm_udc);
  87. }
  88. void HAL_PCD_DataOutStageCallback(PCD_HandleTypeDef *hpcd, uint8_t epnum)
  89. {
  90. if (epnum != 0)
  91. {
  92. rt_usbd_ep_out_handler(&_stm_udc, epnum, hpcd->OUT_ep[epnum].xfer_count);
  93. }
  94. else
  95. {
  96. rt_usbd_ep0_out_handler(&_stm_udc, hpcd->OUT_ep[0].xfer_count);
  97. }
  98. }
  99. void HAL_PCDEx_SetConnectionState(PCD_HandleTypeDef *hpcd, uint8_t state)
  100. {
  101. if (state == 1)
  102. {
  103. #if defined(SOC_SERIES_STM32F1)
  104. rt_pin_mode(BSP_USB_CONNECT_PIN,PIN_MODE_OUTPUT);
  105. rt_pin_write(BSP_USB_CONNECT_PIN, BSP_USB_PULL_UP_STATUS);
  106. #endif
  107. }
  108. else
  109. {
  110. #if defined(SOC_SERIES_STM32F1)
  111. rt_pin_mode(BSP_USB_CONNECT_PIN,PIN_MODE_OUTPUT);
  112. rt_pin_write(BSP_USB_CONNECT_PIN, !BSP_USB_PULL_UP_STATUS);
  113. #endif
  114. }
  115. }
  116. static rt_err_t _ep_set_stall(rt_uint8_t address)
  117. {
  118. HAL_PCD_EP_SetStall(&_stm_pcd, address);
  119. return RT_EOK;
  120. }
  121. static rt_err_t _ep_clear_stall(rt_uint8_t address)
  122. {
  123. HAL_PCD_EP_ClrStall(&_stm_pcd, address);
  124. return RT_EOK;
  125. }
  126. static rt_err_t _set_address(rt_uint8_t address)
  127. {
  128. HAL_PCD_SetAddress(&_stm_pcd, address);
  129. return RT_EOK;
  130. }
  131. static rt_err_t _set_config(rt_uint8_t address)
  132. {
  133. return RT_EOK;
  134. }
  135. static rt_err_t _ep_enable(uep_t ep)
  136. {
  137. RT_ASSERT(ep != RT_NULL);
  138. RT_ASSERT(ep->ep_desc != RT_NULL);
  139. HAL_PCD_EP_Open(&_stm_pcd, ep->ep_desc->bEndpointAddress,
  140. ep->ep_desc->wMaxPacketSize, ep->ep_desc->bmAttributes);
  141. return RT_EOK;
  142. }
  143. static rt_err_t _ep_disable(uep_t ep)
  144. {
  145. RT_ASSERT(ep != RT_NULL);
  146. RT_ASSERT(ep->ep_desc != RT_NULL);
  147. HAL_PCD_EP_Close(&_stm_pcd, ep->ep_desc->bEndpointAddress);
  148. return RT_EOK;
  149. }
  150. static rt_ssize_t _ep_read(rt_uint8_t address, void *buffer)
  151. {
  152. rt_size_t size = 0;
  153. RT_ASSERT(buffer != RT_NULL);
  154. return size;
  155. }
  156. static rt_ssize_t _ep_read_prepare(rt_uint8_t address, void *buffer, rt_size_t size)
  157. {
  158. HAL_PCD_EP_Receive(&_stm_pcd, address, buffer, size);
  159. return size;
  160. }
  161. static rt_ssize_t _ep_write(rt_uint8_t address, void *buffer, rt_size_t size)
  162. {
  163. HAL_PCD_EP_Transmit(&_stm_pcd, address, buffer, size);
  164. return size;
  165. }
  166. static rt_err_t _ep0_send_status(void)
  167. {
  168. HAL_PCD_EP_Transmit(&_stm_pcd, 0x00, NULL, 0);
  169. return RT_EOK;
  170. }
  171. static rt_err_t _suspend(void)
  172. {
  173. return RT_EOK;
  174. }
  175. static rt_err_t _wakeup(void)
  176. {
  177. return RT_EOK;
  178. }
  179. static rt_err_t _init(rt_device_t device)
  180. {
  181. PCD_HandleTypeDef *pcd;
  182. /* Set LL Driver parameters */
  183. pcd = (PCD_HandleTypeDef *)device->user_data;
  184. pcd->Instance = USBD_INSTANCE;
  185. memset(&pcd->Init, 0, sizeof pcd->Init);
  186. pcd->Init.dev_endpoints = 8;
  187. pcd->Init.speed = USBD_PCD_SPEED;
  188. pcd->Init.ep0_mps = EP_MPS_64;
  189. #if !defined(SOC_SERIES_STM32F1)
  190. pcd->Init.phy_itface = USBD_PCD_PHY_MODULE;
  191. #endif
  192. /* Initialize LL Driver */
  193. HAL_PCD_Init(pcd);
  194. /* USB interrupt Init */
  195. HAL_NVIC_SetPriority(USBD_IRQ_TYPE, 2, 0);
  196. HAL_NVIC_EnableIRQ(USBD_IRQ_TYPE);
  197. #if !defined(SOC_SERIES_STM32F1)
  198. HAL_PCDEx_SetRxFiFo(pcd, 0x80);
  199. HAL_PCDEx_SetTxFiFo(pcd, 0, 0x40);
  200. HAL_PCDEx_SetTxFiFo(pcd, 1, 0x40);
  201. HAL_PCDEx_SetTxFiFo(pcd, 2, 0x40);
  202. HAL_PCDEx_SetTxFiFo(pcd, 3, 0x40);
  203. #else
  204. HAL_PCDEx_PMAConfig(pcd, 0x00, PCD_SNG_BUF, 0x18);
  205. HAL_PCDEx_PMAConfig(pcd, 0x80, PCD_SNG_BUF, 0x58);
  206. HAL_PCDEx_PMAConfig(pcd, 0x81, PCD_SNG_BUF, 0x98);
  207. HAL_PCDEx_PMAConfig(pcd, 0x01, PCD_SNG_BUF, 0x118);
  208. HAL_PCDEx_PMAConfig(pcd, 0x82, PCD_SNG_BUF, 0xD8);
  209. HAL_PCDEx_PMAConfig(pcd, 0x02, PCD_SNG_BUF, 0x158);
  210. HAL_PCDEx_PMAConfig(pcd, 0x83, PCD_SNG_BUF, 0x198);
  211. #endif
  212. HAL_PCD_Start(pcd);
  213. return RT_EOK;
  214. }
  215. const static struct udcd_ops _udc_ops =
  216. {
  217. _set_address,
  218. _set_config,
  219. _ep_set_stall,
  220. _ep_clear_stall,
  221. _ep_enable,
  222. _ep_disable,
  223. _ep_read_prepare,
  224. _ep_read,
  225. _ep_write,
  226. _ep0_send_status,
  227. _suspend,
  228. _wakeup,
  229. };
  230. #ifdef RT_USING_DEVICE_OPS
  231. const static struct rt_device_ops _ops =
  232. {
  233. _init,
  234. RT_NULL,
  235. RT_NULL,
  236. RT_NULL,
  237. RT_NULL,
  238. RT_NULL,
  239. };
  240. #endif
  241. int stm_usbd_register(void)
  242. {
  243. rt_memset((void *)&_stm_udc, 0, sizeof(struct udcd));
  244. _stm_udc.parent.type = RT_Device_Class_USBDevice;
  245. #ifdef RT_USING_DEVICE_OPS
  246. _stm_udc.parent.ops = &_ops;
  247. #else
  248. _stm_udc.parent.init = _init;
  249. #endif
  250. _stm_udc.parent.user_data = &_stm_pcd;
  251. _stm_udc.ops = &_udc_ops;
  252. /* Register endpoint infomation */
  253. _stm_udc.ep_pool = _ep_pool;
  254. _stm_udc.ep0.id = &_ep_pool[0];
  255. #ifdef BSP_USBD_SPEED_HS
  256. _stm_udc.device_is_hs = RT_TRUE;
  257. #endif
  258. rt_device_register((rt_device_t)&_stm_udc, "usbd", 0);
  259. rt_usb_device_init();
  260. return RT_EOK;
  261. }
  262. INIT_DEVICE_EXPORT(stm_usbd_register);
  263. #endif