drv_usbd.c 7.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273
  1. /*
  2. * File : stm32_usbd.c
  3. * This file is part of RT-Thread RTOS
  4. * COPYRIGHT (C) 2015, RT-Thread Development Team
  5. *
  6. * The license and distribution terms for this file may be
  7. * found in the file LICENSE in this distribution or at
  8. * http://www.rt-thread.org/license/LICENSE
  9. *
  10. * Change Logs:
  11. * Date Author Notes
  12. * 2017-10-30 ZYH the first version
  13. */
  14. #include "drv_usbd.h"
  15. #include <rtthread.h>
  16. #include <rtdevice.h>
  17. #include "board.h"
  18. //#define USB_DISCONNECT_PIN 30 //PA9
  19. static PCD_HandleTypeDef _stm_pcd;
  20. static struct udcd _stm_udc;
  21. static struct ep_id _ep_pool[] =
  22. {
  23. {0x0, USB_EP_ATTR_CONTROL, USB_DIR_INOUT, 64, ID_ASSIGNED },
  24. {0x1, USB_EP_ATTR_BULK, USB_DIR_IN, 64, ID_UNASSIGNED},
  25. {0x1, USB_EP_ATTR_BULK, USB_DIR_OUT, 64, ID_UNASSIGNED},
  26. {0x2, USB_EP_ATTR_INT, USB_DIR_IN, 64, ID_UNASSIGNED},
  27. {0x2, USB_EP_ATTR_INT, USB_DIR_OUT, 64, ID_UNASSIGNED},
  28. {0x3, USB_EP_ATTR_BULK, USB_DIR_IN, 64, ID_UNASSIGNED},
  29. {0x3, USB_EP_ATTR_BULK, USB_DIR_OUT, 64, ID_UNASSIGNED},
  30. {0xFF, USB_EP_ATTR_TYPE_MASK, USB_DIR_MASK, 0, ID_ASSIGNED },
  31. };
  32. void OTG_FS_IRQHandler(void)
  33. {
  34. rt_interrupt_enter();
  35. HAL_PCD_IRQHandler(&_stm_pcd);
  36. /* leave interrupt */
  37. rt_interrupt_leave();
  38. }
  39. void HAL_PCD_ResetCallback(PCD_HandleTypeDef *pcd)
  40. {
  41. /* open ep0 OUT and IN */
  42. HAL_PCD_EP_Open(pcd, 0x00, 0x40, EP_TYPE_CTRL);
  43. HAL_PCD_EP_Open(pcd, 0x80, 0x40, EP_TYPE_CTRL);
  44. rt_usbd_reset_handler(&_stm_udc);
  45. }
  46. void HAL_PCD_SetupStageCallback(PCD_HandleTypeDef *hpcd)
  47. {
  48. rt_usbd_ep0_setup_handler(&_stm_udc, (struct urequest *)hpcd->Setup);
  49. }
  50. void HAL_PCD_DataInStageCallback(PCD_HandleTypeDef *hpcd, uint8_t epnum)
  51. {
  52. if (epnum == 0)
  53. {
  54. rt_usbd_ep0_in_handler(&_stm_udc);
  55. }
  56. else
  57. {
  58. rt_usbd_ep_in_handler(&_stm_udc, 0x80 | epnum, hpcd->IN_ep[epnum].xfer_count);
  59. }
  60. }
  61. void HAL_PCD_ConnectCallback(PCD_HandleTypeDef *hpcd)
  62. {
  63. rt_usbd_connect_handler(&_stm_udc);
  64. }
  65. void HAL_PCD_SOFCallback(PCD_HandleTypeDef *hpcd)
  66. {
  67. rt_usbd_sof_handler(&_stm_udc);
  68. }
  69. void HAL_PCD_DisconnectCallback(PCD_HandleTypeDef *hpcd)
  70. {
  71. rt_usbd_disconnect_handler(&_stm_udc);
  72. }
  73. void HAL_PCD_DataOutStageCallback(PCD_HandleTypeDef *hpcd, uint8_t epnum)
  74. {
  75. if (epnum != 0)
  76. {
  77. rt_usbd_ep_out_handler(&_stm_udc, epnum, hpcd->OUT_ep[epnum].xfer_count);
  78. }
  79. else
  80. {
  81. rt_usbd_ep0_out_handler(&_stm_udc, hpcd->OUT_ep[0].xfer_count);
  82. }
  83. }
  84. void HAL_PCDEx_SetConnectionState(PCD_HandleTypeDef *hpcd, uint8_t state)
  85. {
  86. if (state == 1)
  87. {
  88. }
  89. else
  90. {
  91. }
  92. }
  93. void HAL_PCD_MspInit(PCD_HandleTypeDef *pcdHandle)
  94. {
  95. GPIO_InitTypeDef GPIO_InitStruct;
  96. if (pcdHandle->Instance == USB_OTG_FS)
  97. {
  98. /* USER CODE BEGIN USB_MspInit 0 */
  99. __HAL_RCC_GPIOA_CLK_ENABLE();
  100. GPIO_InitStruct.Pin = GPIO_PIN_11 | GPIO_PIN_12;
  101. GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
  102. GPIO_InitStruct.Pull = GPIO_NOPULL;
  103. GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
  104. GPIO_InitStruct.Alternate = GPIO_AF10_OTG_FS;
  105. HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
  106. /* Peripheral clock enable */
  107. __HAL_RCC_USB_OTG_FS_CLK_ENABLE();
  108. /* Peripheral interrupt init */
  109. HAL_NVIC_SetPriority(OTG_FS_IRQn, 5, 0);
  110. HAL_NVIC_EnableIRQ(OTG_FS_IRQn);
  111. }
  112. }
  113. void HAL_PCD_MspDeInit(PCD_HandleTypeDef *pcdHandle)
  114. {
  115. if (pcdHandle->Instance == USB_OTG_FS)
  116. {
  117. /* Peripheral clock disable */
  118. __HAL_RCC_USB_OTG_FS_CLK_DISABLE();
  119. /**USB_OTG_FS GPIO Configuration
  120. PA11 ------> USB_OTG_FS_DM
  121. PA12 ------> USB_OTG_FS_DP
  122. */
  123. HAL_GPIO_DeInit(GPIOA, GPIO_PIN_11 | GPIO_PIN_12);
  124. /* Peripheral interrupt Deinit*/
  125. HAL_NVIC_DisableIRQ(OTG_FS_IRQn);
  126. }
  127. }
  128. static rt_err_t _ep_set_stall(rt_uint8_t address)
  129. {
  130. HAL_PCD_EP_SetStall(&_stm_pcd, address);
  131. return RT_EOK;
  132. }
  133. static rt_err_t _ep_clear_stall(rt_uint8_t address)
  134. {
  135. HAL_PCD_EP_ClrStall(&_stm_pcd, address);
  136. return RT_EOK;
  137. }
  138. static rt_err_t _set_address(rt_uint8_t address)
  139. {
  140. HAL_PCD_SetAddress(&_stm_pcd, address);
  141. return RT_EOK;
  142. }
  143. static rt_err_t _set_config(rt_uint8_t address)
  144. {
  145. return RT_EOK;
  146. }
  147. static rt_err_t _ep_enable(uep_t ep)
  148. {
  149. RT_ASSERT(ep != RT_NULL);
  150. RT_ASSERT(ep->ep_desc != RT_NULL);
  151. HAL_PCD_EP_Open(&_stm_pcd, ep->ep_desc->bEndpointAddress,
  152. ep->ep_desc->wMaxPacketSize, ep->ep_desc->bmAttributes);
  153. return RT_EOK;
  154. }
  155. static rt_err_t _ep_disable(uep_t ep)
  156. {
  157. RT_ASSERT(ep != RT_NULL);
  158. RT_ASSERT(ep->ep_desc != RT_NULL);
  159. HAL_PCD_EP_Close(&_stm_pcd, ep->ep_desc->bEndpointAddress);
  160. return RT_EOK;
  161. }
  162. static rt_size_t _ep_read(rt_uint8_t address, void *buffer)
  163. {
  164. rt_size_t size = 0;
  165. RT_ASSERT(buffer != RT_NULL);
  166. return size;
  167. }
  168. static rt_size_t _ep_read_prepare(rt_uint8_t address, void *buffer, rt_size_t size)
  169. {
  170. HAL_PCD_EP_Receive(&_stm_pcd, address, buffer, size);
  171. return size;
  172. }
  173. static rt_size_t _ep_write(rt_uint8_t address, void *buffer, rt_size_t size)
  174. {
  175. HAL_PCD_EP_Transmit(&_stm_pcd, address, buffer, size);
  176. return size;
  177. }
  178. static rt_err_t _ep0_send_status(void)
  179. {
  180. HAL_PCD_EP_Transmit(&_stm_pcd, 0x00, NULL, 0);
  181. return RT_EOK;
  182. }
  183. static rt_err_t _suspend(void)
  184. {
  185. return RT_EOK;
  186. }
  187. static rt_err_t _wakeup(void)
  188. {
  189. return RT_EOK;
  190. }
  191. static rt_err_t _init(rt_device_t device)
  192. {
  193. PCD_HandleTypeDef *pcd;
  194. /* Set LL Driver parameters */
  195. pcd = (PCD_HandleTypeDef *)device->user_data;
  196. pcd->Instance = USB_OTG_FS;
  197. pcd->Init.dev_endpoints = 4;
  198. pcd->Init.speed = PCD_SPEED_FULL;
  199. pcd->Init.dma_enable = DISABLE;
  200. pcd->Init.ep0_mps = DEP0CTL_MPS_64;
  201. pcd->Init.phy_itface = PCD_PHY_EMBEDDED;
  202. pcd->Init.Sof_enable = DISABLE;
  203. pcd->Init.low_power_enable = DISABLE;
  204. pcd->Init.lpm_enable = DISABLE;
  205. pcd->Init.vbus_sensing_enable = DISABLE;
  206. pcd->Init.use_dedicated_ep1 = DISABLE;
  207. /* Initialize LL Driver */
  208. HAL_PCD_Init(pcd);
  209. HAL_PCDEx_SetRxFiFo(pcd, 0x80);
  210. HAL_PCDEx_SetTxFiFo(pcd, 0, 0x40);
  211. HAL_PCDEx_SetTxFiFo(pcd, 1, 0x40);
  212. HAL_PCDEx_SetTxFiFo(pcd, 2, 0x40);
  213. HAL_PCDEx_SetTxFiFo(pcd, 3, 0x40);
  214. HAL_PCD_Start(pcd);
  215. return RT_EOK;
  216. }
  217. const static struct udcd_ops _udc_ops =
  218. {
  219. _set_address,
  220. _set_config,
  221. _ep_set_stall,
  222. _ep_clear_stall,
  223. _ep_enable,
  224. _ep_disable,
  225. _ep_read_prepare,
  226. _ep_read,
  227. _ep_write,
  228. _ep0_send_status,
  229. _suspend,
  230. _wakeup,
  231. };
  232. int stm_usbd_register(void)
  233. {
  234. rt_memset((void *)&_stm_udc, 0, sizeof(struct udcd));
  235. _stm_udc.parent.type = RT_Device_Class_USBDevice;
  236. _stm_udc.parent.init = _init;
  237. _stm_udc.parent.user_data = &_stm_pcd;
  238. _stm_udc.ops = &_udc_ops;
  239. /* Register endpoint infomation */
  240. _stm_udc.ep_pool = _ep_pool;
  241. _stm_udc.ep0.id = &_ep_pool[0];
  242. rt_device_register((rt_device_t)&_stm_udc, "usbd", 0);
  243. rt_usb_device_init();
  244. return RT_EOK;
  245. }
  246. INIT_DEVICE_EXPORT(stm_usbd_register);