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
36 enum class DirectionHint : int8_t
46 DirectionHint direction_hint =
47 DirectionHint::BothDirections;
56 explicit EPConfig(RawData buffer) : buffer(buffer) {}
62 EPConfig(RawData buffer,
bool is_in)
64 direction_hint(is_in ? DirectionHint::InOnly : DirectionHint::OutOnly)
82 const std::initializer_list<EPConfig> ep_cfgs,
83 USB::DeviceDescriptor::PacketSize0 packet_size, uint16_t vid, uint16_t pid,
85 const std::initializer_list<const USB::DescriptorStrings::LanguagePack*> lang_list,
86 const std::initializer_list<
const std::initializer_list<USB::ConfigDescriptorItem*>>
88 ConstRawData uid = {
nullptr, 0});
93 void Init(
bool in_isr)
override;
98 void Deinit(
bool in_isr)
override;
104 ErrorCode SetAddress(uint8_t address, USB::DeviceCore::Context context)
override;
109 void Start(
bool in_isr)
override;
114 void Stop(
bool in_isr)
override;
117 friend class ESP32USBEndpoint;
119 static constexpr uint8_t ENDPOINT_COUNT = 7;
120 static constexpr uint8_t IN_ENDPOINT_LIMIT = 5;
121 static constexpr uint32_t INTERRUPT_DISPATCH_GUARD = 64U;
122 static constexpr size_t SETUP_PACKET_BYTES = 8U;
123 static constexpr size_t SETUP_DMA_BUFFER_BYTES = 64U;
130 bool setup_direction_out =
141 USB::Endpoint* in[ENDPOINT_COUNT] =
143 USB::Endpoint* out[ENDPOINT_COUNT] =
153 uint16_t depth_words =
157 uint16_t tx_next_words =
159 uint16_t tx_words[ENDPOINT_COUNT] =
162 bool tx_bound[ENDPOINT_COUNT] = {};
164 uint8_t allocated_in = 0U;
173 intr_handle_t intr_handle =
175 void* phy_handle =
nullptr;
176 bool phy_ready =
false;
179 bool started =
false;
180 bool rom_usb_cleaned =
false;
187 static void IRAM_ATTR IsrEntry(
void* arg);
192 bool EnsurePhyReady();
197 bool EnsureInterruptReady();
202 void EnsureRomUsbCleaned();
207 void InitializeCore();
212 void ClearTxFifoRegisters();
222 void ResetFifoState();
227 void ResetDeviceState();
232 void ResetEndpointHardwareState();
237 void ReloadSetupPacketCount();
242 void HandleInterrupt();
247 void HandleBusReset(
bool in_isr);
252 void HandleEndpointInterrupt(
bool in_isr,
bool in_dir);
257 void HandleRxFifoLevel();
262 void ResetControlState();
267 void UpdateSetupState(
const uint8_t* setup);
273 bool LastSetupDirectionOut()
const {
return control_.setup_direction_out; }
278 bool DmaEnabled()
const {
return true; }
283 bool AllocateTxFifo(uint8_t ep_num, uint16_t packet_size,
bool is_bulk,
284 uint16_t& fifo_words);
290 bool EnsureRxFifo(uint16_t packet_size);
292 EndpointMap endpoint_map_ = {};
293 FifoState fifo_state_ =
295 RuntimeState runtime_ =
297 alignas(SETUP_DMA_BUFFER_BYTES) uint8_t setup_packet_[SETUP_DMA_BUFFER_BYTES] =
299 ControlState control_ = {};