5#include <initializer_list>
8#include "esp_intr_alloc.h"
9#include "libxr_type.hpp"
10#include "usb/core/ep_pool.hpp"
11#include "usb/device/dev_core.hpp"
13#if SOC_USB_OTG_SUPPORTED && defined(CONFIG_IDF_TARGET_ESP32S3) && \
14 CONFIG_IDF_TARGET_ESP32S3
19class ESP32USBEndpoint;
24class ESP32USBDevice :
public USB::EndpointPool,
public USB::DeviceCore
35 enum class DirectionHint : int8_t
43 DirectionHint direction_hint = DirectionHint::BothDirections;
46 explicit EPConfig(RawData buffer) : buffer(buffer) {}
47 EPConfig(RawData buffer,
bool is_in)
49 direction_hint(is_in ? DirectionHint::InOnly : DirectionHint::OutOnly)
55 const std::initializer_list<EPConfig> ep_cfgs,
56 USB::DeviceDescriptor::PacketSize0 packet_size, uint16_t vid, uint16_t pid,
58 const std::initializer_list<const USB::DescriptorStrings::LanguagePack*> lang_list,
59 const std::initializer_list<
const std::initializer_list<USB::ConfigDescriptorItem*>>
61 ConstRawData uid = {
nullptr, 0});
63 void Init(
bool in_isr)
override;
64 void Deinit(
bool in_isr)
override;
66 ErrorCode SetAddress(uint8_t address, USB::DeviceCore::Context context)
override;
67 void Start(
bool in_isr)
override;
68 void Stop(
bool in_isr)
override;
71 friend class ESP32USBEndpoint;
73 static constexpr uint8_t ENDPOINT_COUNT = 7;
74 static constexpr uint8_t IN_ENDPOINT_LIMIT = 5;
75 static constexpr uint32_t INTERRUPT_DISPATCH_GUARD = 64U;
76 static constexpr size_t SETUP_PACKET_BYTES = 8U;
77 static constexpr size_t SETUP_DMA_BUFFER_BYTES = 64U;
84 bool setup_direction_out =
false;
92 USB::Endpoint* in[ENDPOINT_COUNT] = {};
93 USB::Endpoint* out[ENDPOINT_COUNT] = {};
101 uint16_t depth_words = 0U;
102 uint16_t rx_words = 0U;
103 uint16_t tx_next_words = 0U;
104 uint16_t tx_words[ENDPOINT_COUNT] = {};
105 bool tx_bound[ENDPOINT_COUNT] = {};
106 uint8_t allocated_in = 0U;
114 intr_handle_t intr_handle =
nullptr;
115 void* phy_handle =
nullptr;
116 bool phy_ready =
false;
117 bool irq_ready =
false;
118 bool started =
false;
119 bool rom_usb_cleaned =
false;
122 static void IRAM_ATTR IsrEntry(
void* arg);
123 bool EnsurePhyReady();
124 bool EnsureInterruptReady();
125 void EnsureRomUsbCleaned();
126 void InitializeCore();
127 void ClearTxFifoRegisters();
129 void ResetFifoState();
130 void ResetDeviceState();
131 void ResetEndpointHardwareState();
132 void ReloadSetupPacketCount();
133 void HandleInterrupt();
134 void HandleBusReset(
bool in_isr);
135 void HandleEndpointInterrupt(
bool in_isr,
bool in_dir);
136 void HandleRxFifoLevel();
137 void ResetControlState();
138 void UpdateSetupState(
const uint8_t* setup);
139 bool LastSetupDirectionOut()
const {
return control_.setup_direction_out; }
140 bool DmaEnabled()
const {
return true; }
142 bool AllocateTxFifo(uint8_t ep_num, uint16_t packet_size,
bool is_bulk,
143 uint16_t& fifo_words);
144 bool EnsureRxFifo(uint16_t packet_size);
147 EndpointMap endpoint_map_ = {};
149 FifoState fifo_state_ = {};
151 RuntimeState runtime_ = {};
153 alignas(SETUP_DMA_BUFFER_BYTES) uint8_t setup_packet_[SETUP_DMA_BUFFER_BYTES] = {};
155 ControlState control_ = {};