drv_usb.c 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258
  1. /*
  2. * Copyright (c) 2006-2018, RT-Thread Development Team
  3. *
  4. * SPDX-License-Identifier: Apache-2.0
  5. *
  6. *
  7. * Change Logs:
  8. * Date Author Notes
  9. * 2017-10-30 ZYH the first version
  10. * 2017-11-15 ZYH update to 3.0.0
  11. */
  12. #include "drv_usb.h"
  13. #include <rtthread.h>
  14. #include <rtdevice.h>
  15. #include "board.h"
  16. #define USB_DISCONNECT_PIN 30 //PA9
  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. {0x1, USB_EP_ATTR_BULK, USB_DIR_IN, 64, ID_UNASSIGNED},
  23. {0x1, USB_EP_ATTR_BULK, USB_DIR_OUT, 64, ID_UNASSIGNED},
  24. {0x2, USB_EP_ATTR_INT, USB_DIR_OUT, 64, ID_UNASSIGNED},
  25. {0x2, USB_EP_ATTR_INT, USB_DIR_IN, 64, ID_UNASSIGNED},
  26. {0x3, USB_EP_ATTR_INT, USB_DIR_IN, 64, ID_UNASSIGNED},
  27. {0xFF, USB_EP_ATTR_TYPE_MASK, USB_DIR_MASK, 0, ID_ASSIGNED },
  28. };
  29. void USB_LP_CAN1_RX0_IRQHandler(void)
  30. {
  31. rt_interrupt_enter();
  32. HAL_PCD_IRQHandler(&_stm_pcd);
  33. rt_interrupt_leave();
  34. }
  35. void HAL_PCD_ResetCallback(PCD_HandleTypeDef *pcd)
  36. {
  37. /* open ep0 OUT and IN */
  38. HAL_PCD_EP_Open(pcd, 0x00, 0x40, EP_TYPE_CTRL);
  39. HAL_PCD_EP_Open(pcd, 0x80, 0x40, EP_TYPE_CTRL);
  40. rt_usbd_reset_handler(&_stm_udc);
  41. }
  42. void HAL_PCD_SetupStageCallback(PCD_HandleTypeDef *hpcd)
  43. {
  44. rt_usbd_ep0_setup_handler(&_stm_udc, (struct urequest *)hpcd->Setup);
  45. }
  46. void HAL_PCD_DataInStageCallback(PCD_HandleTypeDef *hpcd, uint8_t epnum)
  47. {
  48. if (epnum == 0)
  49. {
  50. rt_usbd_ep0_in_handler(&_stm_udc);
  51. }
  52. else
  53. {
  54. rt_usbd_ep_in_handler(&_stm_udc, 0x80 | epnum, hpcd->IN_ep[epnum].xfer_count);
  55. }
  56. }
  57. void HAL_PCD_ConnectCallback(PCD_HandleTypeDef *hpcd)
  58. {
  59. rt_usbd_connect_handler(&_stm_udc);
  60. }
  61. void HAL_PCD_SOFCallback(PCD_HandleTypeDef *hpcd)
  62. {
  63. // rt_usbd_sof_handler(&_stm_udc);
  64. }
  65. void HAL_PCD_DisconnectCallback(PCD_HandleTypeDef *hpcd)
  66. {
  67. rt_usbd_disconnect_handler(&_stm_udc);
  68. }
  69. void HAL_PCD_DataOutStageCallback(PCD_HandleTypeDef *hpcd, uint8_t epnum)
  70. {
  71. if (epnum != 0)
  72. {
  73. rt_usbd_ep_out_handler(&_stm_udc, epnum, hpcd->OUT_ep[epnum].xfer_count);
  74. }
  75. else
  76. {
  77. rt_usbd_ep0_out_handler(&_stm_udc, hpcd->OUT_ep[0].xfer_count);
  78. }
  79. }
  80. void HAL_PCDEx_SetConnectionState(PCD_HandleTypeDef *hpcd, uint8_t state)
  81. {
  82. if (state == 1)
  83. {
  84. rt_pin_write(USB_DISCONNECT_PIN, PIN_HIGH);
  85. }
  86. else
  87. {
  88. rt_pin_write(USB_DISCONNECT_PIN, PIN_LOW);
  89. }
  90. }
  91. void HAL_PCD_MspInit(PCD_HandleTypeDef *pcdHandle)
  92. {
  93. if (pcdHandle->Instance == USB)
  94. {
  95. __HAL_RCC_GPIOA_CLK_ENABLE();
  96. rt_pin_mode(USB_DISCONNECT_PIN, PIN_MODE_OUTPUT);
  97. rt_pin_write(USB_DISCONNECT_PIN, PIN_LOW);
  98. /* Peripheral clock enable */
  99. __HAL_RCC_USB_CLK_ENABLE();
  100. /* Peripheral interrupt init */
  101. HAL_NVIC_SetPriority(USB_LP_CAN1_RX0_IRQn, 5, 0);
  102. HAL_NVIC_EnableIRQ(USB_LP_CAN1_RX0_IRQn);
  103. }
  104. }
  105. void HAL_PCD_MspDeInit(PCD_HandleTypeDef *pcdHandle)
  106. {
  107. if (pcdHandle->Instance == USB)
  108. {
  109. /* Peripheral clock disable */
  110. __HAL_RCC_USB_CLK_DISABLE();
  111. /* Peripheral interrupt Deinit*/
  112. HAL_NVIC_DisableIRQ(USB_LP_CAN1_RX0_IRQn);
  113. }
  114. }
  115. static rt_err_t _ep_set_stall(rt_uint8_t address)
  116. {
  117. HAL_PCD_EP_SetStall(&_stm_pcd, address);
  118. return RT_EOK;
  119. }
  120. static rt_err_t _ep_clear_stall(rt_uint8_t address)
  121. {
  122. HAL_PCD_EP_ClrStall(&_stm_pcd, address);
  123. return RT_EOK;
  124. }
  125. static rt_err_t _set_address(rt_uint8_t address)
  126. {
  127. HAL_PCD_SetAddress(&_stm_pcd, address);
  128. return RT_EOK;
  129. }
  130. static rt_err_t _set_config(rt_uint8_t address)
  131. {
  132. return RT_EOK;
  133. }
  134. static rt_err_t _ep_enable(uep_t ep)
  135. {
  136. RT_ASSERT(ep != RT_NULL);
  137. RT_ASSERT(ep->ep_desc != RT_NULL);
  138. HAL_PCD_EP_Open(&_stm_pcd, ep->ep_desc->bEndpointAddress,
  139. ep->ep_desc->wMaxPacketSize, ep->ep_desc->bmAttributes);
  140. return RT_EOK;
  141. }
  142. static rt_err_t _ep_disable(uep_t ep)
  143. {
  144. RT_ASSERT(ep != RT_NULL);
  145. RT_ASSERT(ep->ep_desc != RT_NULL);
  146. HAL_PCD_EP_Close(&_stm_pcd, ep->ep_desc->bEndpointAddress);
  147. return RT_EOK;
  148. }
  149. static rt_size_t _ep_read(rt_uint8_t address, void *buffer)
  150. {
  151. rt_size_t size = 0;
  152. RT_ASSERT(buffer != RT_NULL);
  153. return size;
  154. }
  155. static rt_size_t _ep_read_prepare(rt_uint8_t address, void *buffer, rt_size_t size)
  156. {
  157. HAL_PCD_EP_Receive(&_stm_pcd, address, buffer, size);
  158. return size;
  159. }
  160. static rt_size_t _ep_write(rt_uint8_t address, void *buffer, rt_size_t size)
  161. {
  162. HAL_PCD_EP_Transmit(&_stm_pcd, address, buffer, size);
  163. return size;
  164. }
  165. static rt_err_t _ep0_send_status(void)
  166. {
  167. HAL_PCD_EP_Transmit(&_stm_pcd, 0x00, NULL, 0);
  168. return RT_EOK;
  169. }
  170. static rt_err_t _suspend(void)
  171. {
  172. return RT_EOK;
  173. }
  174. static rt_err_t _wakeup(void)
  175. {
  176. return RT_EOK;
  177. }
  178. static rt_err_t _init(rt_device_t device)
  179. {
  180. PCD_HandleTypeDef *pcd;
  181. /* Set LL Driver parameters */
  182. pcd = (PCD_HandleTypeDef *)device->user_data;
  183. pcd->Instance = USB;
  184. pcd->Init.dev_endpoints = 8;
  185. pcd->Init.speed = PCD_SPEED_FULL;
  186. pcd->Init.ep0_mps = DEP0CTL_MPS_8;
  187. pcd->Init.low_power_enable = DISABLE;
  188. pcd->Init.lpm_enable = DISABLE;
  189. pcd->Init.battery_charging_enable = DISABLE;
  190. /* Initialize LL Driver */
  191. HAL_PCD_Init(pcd);
  192. HAL_PCDEx_PMAConfig(pcd, 0x00, PCD_SNG_BUF, 0x18);
  193. HAL_PCDEx_PMAConfig(pcd, 0x80, PCD_SNG_BUF, 0x58);
  194. HAL_PCDEx_PMAConfig(pcd, 0x81, PCD_SNG_BUF, 0x98);
  195. HAL_PCDEx_PMAConfig(pcd, 0x01, PCD_SNG_BUF, 0x118);
  196. HAL_PCDEx_PMAConfig(pcd, 0x82, PCD_SNG_BUF, 0xD8);
  197. HAL_PCDEx_PMAConfig(pcd, 0x02, PCD_SNG_BUF, 0x158);
  198. HAL_PCDEx_PMAConfig(pcd, 0x83, PCD_SNG_BUF, 0x198);
  199. HAL_PCD_Start(pcd);
  200. return RT_EOK;
  201. }
  202. const static struct udcd_ops _udc_ops =
  203. {
  204. _set_address,
  205. _set_config,
  206. _ep_set_stall,
  207. _ep_clear_stall,
  208. _ep_enable,
  209. _ep_disable,
  210. _ep_read_prepare,
  211. _ep_read,
  212. _ep_write,
  213. _ep0_send_status,
  214. _suspend,
  215. _wakeup,
  216. };
  217. int stm_usbd_register(void)
  218. {
  219. rt_memset((void *)&_stm_udc, 0, sizeof(struct udcd));
  220. _stm_udc.parent.type = RT_Device_Class_USBDevice;
  221. _stm_udc.parent.init = _init;
  222. _stm_udc.parent.user_data = &_stm_pcd;
  223. _stm_udc.ops = &_udc_ops;
  224. /* Register endpoint infomation */
  225. _stm_udc.ep_pool = _ep_pool;
  226. _stm_udc.ep0.id = &_ep_pool[0];
  227. rt_device_register((rt_device_t)&_stm_udc, "usbd", 0);
  228. rt_usb_device_init();
  229. return 0;
  230. }
  231. INIT_DEVICE_EXPORT(stm_usbd_register);