libxr
Embedded C++ framework for bare-metal, RTOS and Linux
Loading...
Searching...
No Matches
esp_usb.hpp
1#pragma once
2
3#include <cstddef>
4#include <cstdint>
5
6#include "esp_def.hpp"
7#include "esp_dma_utils.h"
8#include "esp_heap_caps.h"
9#include "usb/core/ep.hpp"
10
11#if (SOC_USB_OTG_SUPPORTED && defined(CONFIG_IDF_TARGET_ESP32S3) && \
12 CONFIG_IDF_TARGET_ESP32S3) || \
13 defined(__DOXYGEN__)
14
15#include "soc/usb_dwc_struct.h"
16
17namespace LibXR::ESPUSBDetail
18{
19
20inline constexpr uint32_t DWC2_FS_REG_BASE = 0x60080000UL;
21inline constexpr size_t FIFO_BASE_OFFSET = 0x1000U;
22inline constexpr size_t FIFO_STRIDE = 0x1000U;
23
24inline constexpr uint8_t RX_STATUS_GLOBAL_OUT_NAK = 1U;
25inline constexpr uint8_t RX_STATUS_DATA = 2U;
26inline constexpr uint8_t RX_STATUS_TRANSFER_COMPLETE = 3U;
27inline constexpr uint8_t RX_STATUS_SETUP_DONE = 4U;
28inline constexpr uint8_t RX_STATUS_SETUP_DATA = 6U;
29
30inline constexpr uint8_t ENUM_SPEED_FULL_30_TO_60_MHZ = 1U;
31inline constexpr uint8_t ENUM_SPEED_FULL_48_MHZ = 3U;
32
33inline constexpr size_t WORD_SIZE = sizeof(uint32_t);
34inline constexpr uint8_t FLUSH_ALL_TX_FIFO = 0x10U;
35inline constexpr uint32_t DMA_BURST_INCR4 = 4U;
36inline constexpr uint32_t DMA_MEMORY_CAPS =
37 MALLOC_CAP_INTERNAL | MALLOC_CAP_DMA | MALLOC_CAP_8BIT;
38inline constexpr uint16_t ESP32_SX_FS_DMA_MIN_RX_FIFO_WORDS = 88U;
39inline constexpr uint16_t ESP32_SX_FS_MIN_TX_FIFO_WORDS = 16U;
40inline constexpr uint32_t DISABLE_OUT_WAIT_GUARD = 100000U;
41
42#if defined(CONFIG_USB_ALIGN_SIZE)
43inline constexpr size_t USB_DMA_ALIGNMENT = CONFIG_USB_ALIGN_SIZE;
44#elif defined(CONFIG_CACHE_L1_CACHE_LINE_SIZE)
45inline constexpr size_t USB_DMA_ALIGNMENT = CONFIG_CACHE_L1_CACHE_LINE_SIZE;
46#else
47inline constexpr size_t USB_DMA_ALIGNMENT = 64U;
48#endif
49
50constexpr uint32_t PackTxFifoSizeReg(uint16_t start, uint16_t words)
51{
52 return (static_cast<uint32_t>(words) << 16U) | static_cast<uint32_t>(start);
53}
54
55bool CacheSyncDmaBuffer(const void* addr, size_t size, bool cache_to_mem,
56 bool allow_unaligned = false);
57size_t AlignUp(size_t value, size_t align);
58esp_dma_mem_info_t UsbDmaMemInfo();
59bool CanUseDirectInDmaBuffer(const void* ptr, size_t size);
60bool CanUseDirectOutDmaBuffer(const void* ptr, size_t size);
61uint16_t CalcRxFifoWords(uint16_t largest_packet_size, uint8_t ep_count);
62uint16_t CalcConfiguredRxFifoWords(uint16_t largest_packet_size, uint8_t ep_count,
63 bool dma_enabled);
64uint16_t GetHardwareFifoDepthWords();
65uint8_t EncodeEp0Mps(uint16_t packet_size);
66uint16_t ClampPacketSize(LibXR::USB::Endpoint::Type type, uint16_t requested);
67uint16_t CalcTxFifoWords(uint16_t packet_size, bool dma_enabled);
68volatile uint32_t* GetEndpointFifo(usb_dwc_dev_t* dev, uint8_t ep_num);
69void WriteFifoPacket(volatile uint32_t* fifo, const uint8_t* src, size_t size);
70void ReadFifoPacket(const volatile uint32_t* fifo, uint8_t* dst, size_t size);
71uint16_t PacketCount(size_t size, uint16_t max_packet_size);
72void FlushTxFifo(usb_dwc_dev_t* dev, uint8_t fifo_num);
73void DisableInEndpointAndWait(usb_dwc_dev_t* dev);
74void DisableInEndpointAndWait(usb_dwc_dev_t* dev, uint8_t ep_num);
75
76template <typename EpCtl>
77void StartEndpointTransfer(volatile EpCtl& reg)
78{
79 EpCtl ctl = {};
80 ctl.val = reg.val;
81 ctl.snak = 0;
82 ctl.cnak = 1;
83 ctl.epdis = 0;
84 ctl.epena = 1;
85 reg.val = ctl.val;
86}
87
88template <typename DoepCtl>
89void DisableOutEndpointAndWait(volatile DoepCtl& ctl)
90{
91 DoepCtl disable = {};
92 disable.val = ctl.val;
93 disable.snak = 1;
94 const bool was_enabled = disable.epena;
95 if (was_enabled)
96 {
97 disable.epdis = 1;
98 }
99 ctl.val = disable.val;
100
101 if (!was_enabled)
102 {
103 return;
104 }
105
106 uint32_t guard = DISABLE_OUT_WAIT_GUARD;
107 while (ctl.epena && guard > 0U)
108 {
109 --guard;
110 }
111}
112
113} // namespace LibXR::ESPUSBDetail
114
115#endif
Type
端点类型 Endpoint type
Definition ep.hpp:68