usb_std.c 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255
  1. // SPDX-License-Identifier: BSD-3-Clause
  2. // Copyright (c) 2016-2022, Alex Taradov <alex@taradov.com>. All rights reserved.
  3. /*- Includes ----------------------------------------------------------------*/
  4. #include "usb.h"
  5. #include "usb_std.h"
  6. #include "usb_descriptors.h"
  7. /*- Definitions -------------------------------------------------------------*/
  8. #define USB_EP_NUM 16
  9. /*- Types -------------------------------------------------------------------*/
  10. typedef struct
  11. {
  12. void (*send)(void);
  13. void (*recv)(int size);
  14. } usb_ep_callback_t;
  15. /*- Variables ---------------------------------------------------------------*/
  16. static usb_ep_callback_t usb_ep_callbacks[USB_EP_NUM];
  17. /*- Implementations ---------------------------------------------------------*/
  18. //-----------------------------------------------------------------------------
  19. void usb_init(void)
  20. {
  21. for (int i = 0; i < USB_EP_NUM; i++)
  22. {
  23. usb_ep_callbacks[i].send = NULL;
  24. usb_ep_callbacks[i].recv = NULL;
  25. }
  26. usb_hw_init();
  27. }
  28. //-----------------------------------------------------------------------------
  29. void usb_set_send_callback(int ep, void (*callback)(void))
  30. {
  31. usb_ep_callbacks[ep].send = callback;
  32. }
  33. //-----------------------------------------------------------------------------
  34. void usb_set_recv_callback(int ep, void (*callback)(int size))
  35. {
  36. usb_ep_callbacks[ep].recv = callback;
  37. }
  38. //-----------------------------------------------------------------------------
  39. bool usb_handle_standard_request(usb_request_t *request)
  40. {
  41. static uint8_t usb_config = 0;
  42. switch (USB_CMD_VALUE(request))
  43. {
  44. case USB_CMD(IN, DEVICE, STANDARD, GET_DESCRIPTOR):
  45. {
  46. int type = request->wValue >> 8;
  47. int index = request->wValue & 0xff;
  48. int length = request->wLength;
  49. if (USB_DEVICE_DESCRIPTOR == type)
  50. {
  51. length = USB_LIMIT(length, usb_device_descriptor.bLength);
  52. usb_control_send((uint8_t *)&usb_device_descriptor, length);
  53. }
  54. else if (USB_CONFIGURATION_DESCRIPTOR == type)
  55. {
  56. length = USB_LIMIT(length, sizeof(usb_configuration_hierarchy_t));
  57. usb_control_send((uint8_t *)&usb_configuration_hierarchy, length);
  58. }
  59. else if (USB_STRING_DESCRIPTOR == type)
  60. {
  61. if (0 == index)
  62. {
  63. length = USB_LIMIT(length, usb_string_descriptor_zero.bLength);
  64. usb_control_send((uint8_t *)&usb_string_descriptor_zero, length);
  65. }
  66. else if (index < USB_STR_COUNT)
  67. {
  68. const char *str = usb_strings[index];
  69. int len = strlen(str);
  70. int size = len*2 + 2;
  71. alignas(4) uint8_t buf[size];
  72. buf[0] = size;
  73. buf[1] = USB_STRING_DESCRIPTOR;
  74. for (int i = 0; i < len; i++)
  75. {
  76. buf[2 + i*2] = str[i];
  77. buf[3 + i*2] = 0;
  78. }
  79. length = USB_LIMIT(length, size);
  80. usb_control_send(buf, length);
  81. }
  82. else
  83. {
  84. return false;
  85. }
  86. }
  87. #ifdef USB_ENABLE_BOS
  88. else if (USB_BINARY_OBJECT_STORE_DESCRIPTOR == type)
  89. {
  90. length = USB_LIMIT(length, sizeof(usb_bos_hierarchy_t));
  91. usb_control_send((uint8_t *)&usb_bos_hierarchy, length);
  92. }
  93. #endif
  94. else
  95. {
  96. return false;
  97. }
  98. } break;
  99. case USB_CMD(OUT, DEVICE, STANDARD, SET_ADDRESS):
  100. {
  101. usb_control_send_zlp();
  102. usb_set_address(request->wValue);
  103. } break;
  104. case USB_CMD(OUT, DEVICE, STANDARD, SET_CONFIGURATION):
  105. {
  106. usb_config = request->wValue;
  107. usb_control_send_zlp();
  108. if (usb_config)
  109. {
  110. int size = usb_configuration_hierarchy.configuration.wTotalLength;
  111. usb_descriptor_header_t *desc = (usb_descriptor_header_t *)&usb_configuration_hierarchy;
  112. while (size)
  113. {
  114. if (USB_ENDPOINT_DESCRIPTOR == desc->bDescriptorType)
  115. usb_configure_endpoint((usb_endpoint_descriptor_t *)desc);
  116. size -= desc->bLength;
  117. desc = (usb_descriptor_header_t *)((uint8_t *)desc + desc->bLength);
  118. }
  119. usb_configuration_callback(usb_config);
  120. }
  121. } break;
  122. case USB_CMD(IN, DEVICE, STANDARD, GET_CONFIGURATION):
  123. {
  124. usb_control_send(&usb_config, sizeof(uint8_t));
  125. } break;
  126. case USB_CMD(IN, DEVICE, STANDARD, GET_STATUS):
  127. case USB_CMD(IN, INTERFACE, STANDARD, GET_STATUS):
  128. {
  129. uint16_t status = 0;
  130. usb_control_send((uint8_t *)&status, sizeof(status));
  131. } break;
  132. case USB_CMD(IN, ENDPOINT, STANDARD, GET_STATUS):
  133. {
  134. int ep = request->wIndex & USB_INDEX_MASK;
  135. int dir = request->wIndex & USB_DIRECTION_MASK;
  136. uint16_t status = 0;
  137. if (usb_endpoint_configured(ep, dir))
  138. {
  139. status = usb_endpoint_get_status(ep, dir);
  140. usb_control_send((uint8_t *)&status, sizeof(status));
  141. }
  142. else
  143. {
  144. return false;
  145. }
  146. } break;
  147. case USB_CMD(OUT, DEVICE, STANDARD, SET_FEATURE):
  148. {
  149. return false;
  150. } break;
  151. case USB_CMD(OUT, INTERFACE, STANDARD, SET_FEATURE):
  152. {
  153. usb_control_send_zlp();
  154. } break;
  155. case USB_CMD(OUT, ENDPOINT, STANDARD, SET_FEATURE):
  156. {
  157. int ep = request->wIndex & USB_INDEX_MASK;
  158. int dir = request->wIndex & USB_DIRECTION_MASK;
  159. if (0 == request->wValue && ep && usb_endpoint_configured(ep, dir))
  160. {
  161. usb_endpoint_set_feature(ep, dir);
  162. usb_control_send_zlp();
  163. }
  164. else
  165. {
  166. return false;
  167. }
  168. } break;
  169. case USB_CMD(OUT, DEVICE, STANDARD, CLEAR_FEATURE):
  170. {
  171. return false;
  172. } break;
  173. case USB_CMD(OUT, INTERFACE, STANDARD, CLEAR_FEATURE):
  174. {
  175. usb_control_send_zlp();
  176. } break;
  177. case USB_CMD(OUT, ENDPOINT, STANDARD, CLEAR_FEATURE):
  178. {
  179. int ep = request->wIndex & USB_INDEX_MASK;
  180. int dir = request->wIndex & USB_DIRECTION_MASK;
  181. if (0 == request->wValue && ep && usb_endpoint_configured(ep, dir))
  182. {
  183. usb_endpoint_clear_feature(ep, dir);
  184. usb_control_send_zlp();
  185. }
  186. else
  187. {
  188. return false;
  189. }
  190. } break;
  191. default:
  192. {
  193. for (int i = 0; i < USB_ARRAY_SIZE(usb_class_handlers); i++)
  194. {
  195. if (usb_class_handlers[i](request))
  196. return true;
  197. }
  198. return false;
  199. } break;
  200. }
  201. return true;
  202. }
  203. //-----------------------------------------------------------------------------
  204. void usb_send_callback(int ep)
  205. {
  206. if (usb_ep_callbacks[ep].send)
  207. usb_ep_callbacks[ep].send();
  208. }
  209. //-----------------------------------------------------------------------------
  210. void usb_recv_callback(int ep, int size)
  211. {
  212. if (usb_ep_callbacks[ep].recv)
  213. usb_ep_callbacks[ep].recv(size);
  214. }