Skip to content

Support for IDF v5.5 and ESP32-C5 #268

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 17 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/push.yml
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ jobs:
runs-on: ubuntu-latest
strategy:
matrix:
target: [esp32, esp32s2, esp32s3, esp32c2, esp32c3, esp32c6, esp32h2, esp32p4]
target: [esp32, esp32s2, esp32s3, esp32c2, esp32c3, esp32c6, esp32h2, esp32p4, esp32c5]
fail-fast: false
steps:
- name: Checkout repository
Expand Down
8 changes: 4 additions & 4 deletions components/arduino_tinyusb/patches/dcd_dwc2.patch
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,11 @@
dwc2_regs_t* dwc2 = DWC2_REG(rhport);
const uint8_t epnum = tu_edpt_number(p_endpoint_desc->bEndpointAddress);
@@ -266,7 +277,18 @@
depctl.bm.set_data0_iso_even = 1;
depctl.set_data0_iso_even = 1;
}
if (dir == TUSB_DIR_IN) {
- depctl.bm.tx_fifo_num = epnum;
+ //depctl.bm.tx_fifo_num = epnum;
- depctl.tx_fifo_num = epnum;
+ //depctl.tx_fifo_num = epnum;
+ uint8_t fifo_num = epnum;
+#if TU_CHECK_MCU(OPT_MCU_ESP32S2, OPT_MCU_ESP32S3)
+ // Special Case for EP5, which is used by CDC but not actually called by the driver
Expand All @@ -34,7 +34,7 @@
+ fifo_num = get_free_fifo();
+ }
+#endif
+ depctl.bm.tx_fifo_num = fifo_num;
+ depctl.tx_fifo_num = fifo_num;
}

dwc2_dep_t* dep = &dwc2->ep[dir == TUSB_DIR_IN ? 0 : 1][epnum];
Expand Down
106 changes: 53 additions & 53 deletions components/arduino_tinyusb/src/dcd_dwc2.c
Original file line number Diff line number Diff line change
Expand Up @@ -41,12 +41,6 @@
#include "device/dcd.h"
#include "dwc2_common.h"

#if TU_CHECK_MCU(OPT_MCU_GD32VF103)
#define DWC2_EP_COUNT(_dwc2) DWC2_EP_MAX
#else
#define DWC2_EP_COUNT(_dwc2) ((_dwc2)->ghwcfg2_bm.num_dev_ep + 1)
#endif

//--------------------------------------------------------------------+
// MACRO TYPEDEF CONSTANT ENUM
//--------------------------------------------------------------------+
Expand Down Expand Up @@ -79,6 +73,16 @@ CFG_TUD_MEM_SECTION static struct {
TUD_EPBUF_DEF(setup_packet, 8);
} _dcd_usbbuf;

TU_ATTR_ALWAYS_INLINE static inline uint8_t dwc2_ep_count(const dwc2_regs_t* dwc2) {
#if TU_CHECK_MCU(OPT_MCU_GD32VF103)
return DWC2_EP_MAX;
#else
const dwc2_ghwcfg2_t ghwcfg2 = {.value = dwc2->ghwcfg2};
return ghwcfg2.num_dev_ep + 1;
#endif
}


//--------------------------------------------------------------------
// DMA
//--------------------------------------------------------------------
Expand All @@ -102,7 +106,8 @@ bool dcd_dcache_clean_invalidate(const void* addr, uint32_t data_size) {
TU_ATTR_ALWAYS_INLINE static inline bool dma_device_enabled(const dwc2_regs_t* dwc2) {
(void) dwc2;
// Internal DMA only
return CFG_TUD_DWC2_DMA_ENABLE && dwc2->ghwcfg2_bm.arch == GHWCFG2_ARCH_INTERNAL_DMA;
const dwc2_ghwcfg2_t ghwcfg2 = {.value = dwc2->ghwcfg2};
return CFG_TUD_DWC2_DMA_ENABLE && ghwcfg2.arch == GHWCFG2_ARCH_INTERNAL_DMA;
}

static void dma_setup_prepare(uint8_t rhport) {
Expand Down Expand Up @@ -261,20 +266,15 @@ static void edpt_activate(uint8_t rhport, const tusb_desc_endpoint_t* p_endpoint
xfer->interval = p_endpoint_desc->bInterval;

// Endpoint control
union {
uint32_t value;
dwc2_depctl_t bm;
} depctl;
depctl.value = 0;

depctl.bm.mps = xfer->max_size;
depctl.bm.active = 1;
depctl.bm.type = p_endpoint_desc->bmAttributes.xfer;
dwc2_depctl_t depctl = {.value = 0};
depctl.mps = xfer->max_size;
depctl.active = 1;
depctl.type = p_endpoint_desc->bmAttributes.xfer;
if (p_endpoint_desc->bmAttributes.xfer != TUSB_XFER_ISOCHRONOUS) {
depctl.bm.set_data0_iso_even = 1;
depctl.set_data0_iso_even = 1;
}
if (dir == TUSB_DIR_IN) {
//depctl.bm.tx_fifo_num = epnum;
//depctl.tx_fifo_num = epnum;
uint8_t fifo_num = epnum;
#if TU_CHECK_MCU(OPT_MCU_ESP32S2, OPT_MCU_ESP32S3)
// Special Case for EP5, which is used by CDC but not actually called by the driver
Expand All @@ -285,7 +285,7 @@ static void edpt_activate(uint8_t rhport, const tusb_desc_endpoint_t* p_endpoint
fifo_num = get_free_fifo();
}
#endif
depctl.bm.tx_fifo_num = fifo_num;
depctl.tx_fifo_num = fifo_num;
}

dwc2_dep_t* dep = &dwc2->ep[dir == TUSB_DIR_IN ? 0 : 1][epnum];
Expand Down Expand Up @@ -365,31 +365,22 @@ static void edpt_schedule_packets(uint8_t rhport, const uint8_t epnum, const uin
}

// transfer size: A full OUT transfer (multiple packets, possibly) triggers XFRC.
union {
uint32_t value;
dwc2_ep_tsize_t bm;
} deptsiz;
deptsiz.value = 0;
deptsiz.bm.xfer_size = total_bytes;
deptsiz.bm.packet_count = num_packets;

dwc2_ep_tsize_t deptsiz = {.value = 0};
deptsiz.xfer_size = total_bytes;
deptsiz.packet_count = num_packets;
dep->tsiz = deptsiz.value;

// control
union {
dwc2_depctl_t bm;
uint32_t value;
} depctl;
depctl.value = dep->ctl;

depctl.bm.clear_nak = 1;
depctl.bm.enable = 1;
if (depctl.bm.type == DEPCTL_EPTYPE_ISOCHRONOUS && xfer->interval == 1) {
const uint32_t odd_now = (dwc2->dsts_bm.frame_number & 1u);
dwc2_depctl_t depctl = {.value = dep->ctl};
depctl.clear_nak = 1;
depctl.enable = 1;
if (depctl.type == DEPCTL_EPTYPE_ISOCHRONOUS && xfer->interval == 1) {
const dwc2_dsts_t dsts = {.value = dwc2->dsts};
const uint32_t odd_now = dsts.frame_number & 1u;
if (odd_now) {
depctl.bm.set_data0_iso_even = 1;
depctl.set_data0_iso_even = 1;
} else {
depctl.bm.set_data1_iso_odd = 1;
depctl.set_data1_iso_odd = 1;
}
}

Expand Down Expand Up @@ -432,7 +423,8 @@ bool dcd_init(uint8_t rhport, const tusb_rhport_init_t* rh_init) {

// XCVRDLY: transceiver delay between xcvr_sel and txvalid during device chirp is required
// when using with some PHYs such as USB334x (USB3341, USB3343, USB3346, USB3347)
if (dwc2->ghwcfg2_bm.hs_phy_type == GHWCFG2_HSPHY_ULPI) {
const dwc2_ghwcfg2_t ghwcfg2 = {.value = dwc2->ghwcfg2};
if (ghwcfg2.hs_phy_type == GHWCFG2_HSPHY_ULPI) {
dcfg |= DCFG_XCVRDLY;
}
} else {
Expand Down Expand Up @@ -667,7 +659,7 @@ void dcd_edpt_clear_stall(uint8_t rhport, uint8_t ep_addr) {
// 7.4.1 Initialization on USB Reset
static void handle_bus_reset(uint8_t rhport) {
dwc2_regs_t *dwc2 = DWC2_REG(rhport);
const uint8_t ep_count = DWC2_EP_COUNT(dwc2);
const uint8_t ep_count = dwc2_ep_count(dwc2);

tu_memclr(xfer_status, sizeof(xfer_status));

Expand Down Expand Up @@ -697,7 +689,9 @@ static void handle_bus_reset(uint8_t rhport) {
dfifo_device_init(rhport);

// 5. Reset device address
dwc2->dcfg_bm.address = 0;
dwc2_dcfg_t dcfg = {.value = dwc2->dcfg};
dcfg.address = 0;
dwc2->dcfg = dcfg.value;

// Fixed both control EP0 size to 64 bytes
dwc2->epin[0].ctl &= ~(0x03 << DIEPCTL_MPSIZ_Pos);
Expand All @@ -717,8 +711,9 @@ static void handle_bus_reset(uint8_t rhport) {

static void handle_enum_done(uint8_t rhport) {
dwc2_regs_t *dwc2 = DWC2_REG(rhport);
const dwc2_dsts_t dsts = {.value = dwc2->dsts};
tusb_speed_t speed;
switch (dwc2->dsts_bm.enum_speed) {
switch (dsts.enum_speed) {
case DCFG_SPEED_HIGH:
speed = TUSB_SPEED_HIGH;
break;
Expand Down Expand Up @@ -763,12 +758,12 @@ static void handle_rxflvl_irq(uint8_t rhport) {
const volatile uint32_t* rx_fifo = dwc2->fifo[0];

// Pop control word off FIFO
const dwc2_grxstsp_t grxstsp_bm = dwc2->grxstsp_bm;
const uint8_t epnum = grxstsp_bm.ep_ch_num;
const dwc2_grxstsp_t grxstsp = {.value = dwc2->grxstsp};
const uint8_t epnum = grxstsp.ep_ch_num;

dwc2_dep_t* epout = &dwc2->epout[epnum];

switch (grxstsp_bm.packet_status) {
switch (grxstsp.packet_status) {
case GRXSTS_PKTSTS_GLOBAL_OUT_NAK:
// Global OUT NAK: do nothing
break;
Expand All @@ -790,7 +785,7 @@ static void handle_rxflvl_irq(uint8_t rhport) {

case GRXSTS_PKTSTS_RX_DATA: {
// Out packet received
const uint16_t byte_count = grxstsp_bm.byte_count;
const uint16_t byte_count = grxstsp.byte_count;
xfer_ctl_t* xfer = XFER_CTL_BASE(epnum, TUSB_DIR_OUT);

if (byte_count) {
Expand All @@ -804,7 +799,8 @@ static void handle_rxflvl_irq(uint8_t rhport) {

// short packet, minus remaining bytes (xfer_size)
if (byte_count < xfer->max_size) {
xfer->total_len -= epout->tsiz_bm.xfer_size;
const dwc2_ep_tsize_t tsiz = {.value = epout->tsiz};
xfer->total_len -= tsiz.xfer_size;
if (epnum == 0) {
xfer->total_len -= _dcd_data.ep0_pending[TUSB_DIR_OUT];
_dcd_data.ep0_pending[TUSB_DIR_OUT] = 0;
Expand Down Expand Up @@ -866,11 +862,13 @@ static void handle_epin_slave(uint8_t rhport, uint8_t epnum, dwc2_diepint_t diep
// - 64 bytes or
// - Half/Empty of TX FIFO size (configured by GAHBCFG.TXFELVL)
if (diepint_bm.txfifo_empty && (dwc2->diepempmsk & (1 << epnum))) {
const uint16_t remain_packets = epin->tsiz_bm.packet_count;
dwc2_ep_tsize_t tsiz = {.value = epin->tsiz};
const uint16_t remain_packets = tsiz.packet_count;

// Process every single packet (only whole packets can be written to fifo)
for (uint16_t i = 0; i < remain_packets; i++) {
const uint16_t remain_bytes = (uint16_t) epin->tsiz_bm.xfer_size;
tsiz.value = epin->tsiz;
const uint16_t remain_bytes = (uint16_t) tsiz.xfer_size;
const uint16_t xact_bytes = tu_min16(remain_bytes, xfer->max_size);

// Check if dtxfsts has enough space available
Expand All @@ -889,7 +887,8 @@ static void handle_epin_slave(uint8_t rhport, uint8_t epnum, dwc2_diepint_t diep
}

// Turn off TXFE if all bytes are written.
if (epin->tsiz_bm.xfer_size == 0) {
tsiz.value = epin->tsiz;
if (tsiz.xfer_size == 0) {
dwc2->diepempmsk &= ~(1 << epnum);
}
}
Expand Down Expand Up @@ -920,7 +919,8 @@ static void handle_epout_dma(uint8_t rhport, uint8_t epnum, dwc2_doepint_t doepi
xfer_ctl_t* xfer = XFER_CTL_BASE(epnum, TUSB_DIR_OUT);

// determine actual received bytes
const uint16_t remain = epout->tsiz_bm.xfer_size;
const dwc2_ep_tsize_t tsiz = {.value = epout->tsiz};
const uint16_t remain = tsiz.xfer_size;
xfer->total_len -= remain;

// this is ZLP, so prepare EP0 for next setup
Expand Down Expand Up @@ -956,7 +956,7 @@ static void handle_epin_dma(uint8_t rhport, uint8_t epnum, dwc2_diepint_t diepin
static void handle_ep_irq(uint8_t rhport, uint8_t dir) {
dwc2_regs_t* dwc2 = DWC2_REG(rhport);
const bool is_dma = dma_device_enabled(dwc2);
const uint8_t ep_count = DWC2_EP_COUNT(dwc2);
const uint8_t ep_count = dwc2_ep_count(dwc2);
const uint8_t daint_offset = (dir == TUSB_DIR_IN) ? DAINT_IEPINT_Pos : DAINT_OEPINT_Pos;
dwc2_dep_t* ep_base = &dwc2->ep[dir == TUSB_DIR_IN ? 0 : 1][0];

Expand Down
16 changes: 15 additions & 1 deletion configs/builds.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
"file":"libspi_flash.a",
"src":"build/esp-idf/spi_flash/libspi_flash.a",
"out":"lib/libspi_flash.a",
"targets":["esp32","esp32c2","esp32c3","esp32s2","esp32s3","esp32c6","esp32h2","esp32p4"]
"targets":["esp32","esp32c2","esp32c3","esp32s2","esp32s3","esp32c6","esp32h2","esp32p4","esp32c5"]
},
{
"file":"libesp_psram.a",
Expand Down Expand Up @@ -44,6 +44,20 @@
}
],
"targets":[
{
"target": "esp32c5",
"features":["qio_ram"],
"idf_libs":["qio","80m"],
"bootloaders":[
["qio","80m"],
["dio","80m"],
["qio","40m"],
["dio","40m"]
],
"mem_variants":[
["dio","80m"]
]
},
{
"target": "esp32p4",
"features":["qio_ram"],
Expand Down
57 changes: 57 additions & 0 deletions configs/defconfig.esp32c5
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
CONFIG_XTAL_FREQ_AUTO=y
CONFIG_XTAL_FREQ=0
CONFIG_SPIRAM_TRY_ALLOCATE_WIFI_LWIP=y
CONFIG_ESP_DEFAULT_CPU_FREQ_MHZ_240=y
CONFIG_SPIRAM=y

CONFIG_BT_ENABLED=y
CONFIG_BT_BLE_BLUFI_ENABLE=y
CONFIG_RTC_CLK_CAL_CYCLES=576
# CONFIG_ESP_TASK_WDT_CHECK_IDLE_TASK_CPU0 is not set
CONFIG_FREERTOS_IDLE_TASK_STACKSIZE=2304
# This Enables RISCV LP for C6 - but it can't be used within Arduino at this time.
#CONFIG_ULP_COPROC_ENABLED=y
#CONFIG_ULP_COPROC_LP_CORE=y
#CONFIG_ULP_COPROC_RESERVE_MEM=4096

#
# OpenThread
#
CONFIG_OPENTHREAD_ENABLED=y
# Border Router disabled
# CONFIG_OPENTHREAD_BORDER_ROUTER=y
# CONFIG_OPENTHREAD_RADIO_SPINEL_UART=y

# DNS64 and NAT64 will be disabled for a while
# OT IDF issue https://github.com/espressif/esp-idf/issues/15069
# CONFIG_OPENTHREAD_DNS64_CLIENT=y

# Radio for RPC
# CONFIG_OPENTHREAD_RADIO=y
# CONFIG_OPENTHREAD_RADIO_NATIVE=y
# CONFIG_OPENTHREAD_DIAG=n
CONFIG_OPENTHREAD_COMMISSIONER=y
CONFIG_OPENTHREAD_JOINER=y
CONFIG_OPENTHREAD_CLI=y
CONFIG_OPENTHREAD_SRP_CLIENT=y
CONFIG_OPENTHREAD_DNS_CLIENT=y
# Default dataset for quick start
CONFIG_OPENTHREAD_NETWORK_NAME="OpenThread-ESP"
CONFIG_OPENTHREAD_MESH_LOCAL_PREFIX="fd00:db8:a0:0::/64"
CONFIG_OPENTHREAD_NETWORK_CHANNEL=15
CONFIG_OPENTHREAD_NETWORK_PANID=0x1234
CONFIG_OPENTHREAD_NETWORK_EXTPANID="dead00beef00cafe"
CONFIG_OPENTHREAD_NETWORK_MASTERKEY="00112233445566778899aabbccddeeff"
CONFIG_OPENTHREAD_NETWORK_PSKC="104810e2315100afd6bc9215a6bfac53"
# end of OpenThread

# Matter shall use only WiFi
CONFIG_ENABLE_MATTER_OVER_THREAD=n

#
# Zigbee
#
CONFIG_ZB_ENABLED=y
CONFIG_ZB_ZED=y
CONFIG_ZB_RADIO_NATIVE=y
# end of Zigbee
4 changes: 2 additions & 2 deletions tools/config.sh
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,11 @@ if [ -z $IDF_PATH ]; then
fi

if [ -z $IDF_BRANCH ]; then
IDF_BRANCH="release/v5.4"
IDF_BRANCH="master"
fi

if [ -z $AR_PR_TARGET_BRANCH ]; then
AR_PR_TARGET_BRANCH="master"
AR_PR_TARGET_BRANCH="release/v3.3.x"
fi

if [ -z $IDF_TARGET ]; then
Expand Down
3 changes: 3 additions & 0 deletions tools/gen_pioarduino_manifest.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,9 @@ def convert_version(version_string):
'v7.7.7' becomes '7.7.7'
"""

if version_string == 'heads/master':
return ".".join(("5", "5", "0")) #temporary

regex_pattern = (
r"v(?P<MAJOR>0|[1-9]\d*)\.(?P<MINOR>0|[1-9]\d*)\.*(?P<PATCH>0|[1-9]\d*)*"
)
Expand Down