drv_usbd_fs.c 6.2 KB

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