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 kEndpointCount = 7;
74 static constexpr uint8_t kInEndpointLimit = 5;
75 static constexpr uint32_t kInterruptDispatchGuard = 64U;
76 static constexpr size_t kSetupPacketBytes = 8U;
77 static constexpr size_t kSetupDmaBufferBytes = 64U;
84 bool setup_direction_out =
false;
92 USB::Endpoint* in[kEndpointCount] = {};
93 USB::Endpoint* out[kEndpointCount] = {};
101 uint16_t depth_words = 0U;
102 uint16_t rx_words = 0U;
103 uint16_t tx_next_words = 0U;
104 uint16_t tx_words[kEndpointCount] = {};
105 bool tx_bound[kEndpointCount] = {};
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 core_inited =
false;
120 bool rom_usb_cleaned =
false;
123 static void IRAM_ATTR IsrEntry(
void* arg);
124 bool EnsurePhyReady();
125 bool EnsureInterruptReady();
126 void EnsureRomUsbCleaned();
127 void InitializeCore();
128 void ClearTxFifoRegisters();
130 void ResetFifoState();
131 void ResetDeviceState();
132 void ResetEndpointHardwareState();
133 void ReloadSetupPacketCount();
134 void HandleInterrupt();
135 void HandleBusReset(
bool in_isr);
136 void HandleEndpointInterrupt(
bool in_isr,
bool in_dir);
137 void HandleRxFifoLevel();
138 void ResetControlState();
139 void UpdateSetupState(
const uint8_t* setup);
140 bool LastSetupDirectionOut()
const {
return control_.setup_direction_out; }
141 bool DmaEnabled()
const {
return true; }
143 bool AllocateTxFifo(uint8_t ep_num, uint16_t packet_size,
bool is_bulk,
144 uint16_t& fifo_words);
145 bool EnsureRxFifo(uint16_t packet_size);
148 EndpointMap endpoint_map_ = {};
150 FifoState fifo_state_ = {};
152 RuntimeState runtime_ = {};
154 alignas(kSetupDmaBufferBytes) uint8_t setup_packet_[kSetupDmaBufferBytes] = {};
156 ControlState control_ = {};