pipe.h 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163
  1. #pragma once
  2. #include <stdio.h>
  3. #include "freertos/FreeRTOS.h"
  4. #include "freertos/semphr.h"
  5. #include "esp_err.h"
  6. #include "esp_attr.h"
  7. #include "hal/usbh_ll.h"
  8. #include "hcd.h"
  9. #if defined(ARDUINO_ARCH_ESP32) && defined(CONFIG_ARDUHAL_ESP_LOG)
  10. #include "esp32-hal-log.h"
  11. #else
  12. #include "esp_log.h"
  13. #endif
  14. #define TRANSFER_DATA_MAX_BYTES 256 //Just assume that will only IN/OUT 64 bytes for now
  15. #define USB_DESC_EP_GET_ADDRESS(desc_ptr) ((desc_ptr).bEndpointAddress & 0x7F)
  16. #define BASE_PIPE_EVENT 0x1000
  17. #define CDC_BASE_PIPE_EVENT 0x2000
  18. /**
  19. * @brief Build get string request
  20. */
  21. #define USB_CTRL_REQ_INIT_GET_STRING(ctrl_req_ptr, lang, desc_index, len) ( \
  22. { \
  23. (ctrl_req_ptr)->bRequestType = USB_B_REQUEST_TYPE_DIR_IN | USB_B_REQUEST_TYPE_TYPE_STANDARD | USB_B_REQUEST_TYPE_RECIP_DEVICE; \
  24. (ctrl_req_ptr)->bRequest = USB_B_REQUEST_GET_DESCRIPTOR; \
  25. (ctrl_req_ptr)->wValue = (USB_W_VALUE_DT_STRING << 8) | ((desc_index)&0xFF); \
  26. (ctrl_req_ptr)->wIndex = (lang); \
  27. (ctrl_req_ptr)->wLength = (len); \
  28. })
  29. typedef struct
  30. {
  31. hcd_pipe_handle_t handle;
  32. hcd_pipe_event_t event;
  33. } pipe_event_msg_t;
  34. class USBHostPipe;
  35. class USBHostPort;
  36. /**
  37. * @brief Pipe callback definition to pass events to class callback
  38. */
  39. typedef void (*pipe_cb_t)(pipe_event_msg_t msg, usb_irp_t *irp, USBHostPipe *context);
  40. class USBHostPipe
  41. {
  42. protected:
  43. //
  44. hcd_pipe_handle_t handle;
  45. //
  46. hcd_port_handle_t port_hdl;
  47. //
  48. xTaskHandle taskHandle;
  49. public:
  50. //
  51. usb_desc_ep_t endpoint;
  52. //
  53. pipe_cb_t callback = nullptr;
  54. //
  55. QueueHandle_t pipeEvtQueue;
  56. USBHostPipe(hcd_port_handle_t handle = nullptr);
  57. ~USBHostPipe();
  58. // master port which this pipe belongs to
  59. USBHostPort *port;
  60. /**
  61. * @brief Register pipe event from class space
  62. */
  63. void onPipeEvent(pipe_cb_t cb);
  64. /**
  65. * @brief Initialize pipe from endpoint data
  66. */
  67. void init(usb_desc_ep_t *ep_desc = nullptr, uint8_t addr = 0);
  68. /**
  69. * @brief Free all queues and pipe belongs to this object
  70. */
  71. void freePipe();
  72. /**
  73. * @brief Update address, usually used with control pipe
  74. */
  75. void updateAddress(uint8_t);
  76. /**
  77. * @brief Update port handle, do we need it???
  78. */
  79. void updatePort(hcd_port_handle_t handle);
  80. /**
  81. * @brief Reset pipe
  82. */
  83. void reset();
  84. /**
  85. * @brief Get pipe state
  86. */
  87. hcd_pipe_state_t getState();
  88. /**
  89. * @brief Allocate IRP before enqueue new request
  90. */
  91. usb_irp_t *allocateIRP(size_t size);
  92. /**
  93. * @brief Free IRP and data buffer
  94. */
  95. void freeIRP(usb_irp_t *);
  96. /**
  97. * @brief Get pipe handle
  98. */
  99. hcd_pipe_handle_t getHandle();
  100. // pipes are IN or OUT, but it is better to have functions in base class
  101. // laterr need to add assert if pipe is IN/OUT
  102. /**
  103. * @brief Send data IN request
  104. */
  105. void inData(size_t size = 0);
  106. /**
  107. * @brief Send data OUT request
  108. */
  109. void outData(uint8_t *data, size_t len);
  110. // ------------------- standard USB requests ------------------------ //
  111. /**
  112. * @brief Prepare and enqueue get device descriptor request
  113. */
  114. void getDeviceDescriptor();
  115. /**
  116. * @brief Prepare and enqueue set device address request
  117. */
  118. void setDeviceAddress(uint8_t addr);
  119. /**
  120. * @brief Prepare and enqueue get configuration descriptor request
  121. */
  122. void getCurrentConfiguration();
  123. /**
  124. * @brief Prepare and enqueue set configuration request
  125. */
  126. void setConfiguration(uint8_t);
  127. /**
  128. * @brief Prepare and enqueue get configuration descriptor request
  129. */
  130. void getConfigDescriptor();
  131. /**
  132. * @brief Prepare and enqueue get string by id request
  133. */
  134. void getString(uint8_t);
  135. };