Skip to content

Commit ee8e16a

Browse files
committed
feature(esp_tinyusb): Applied fix for UNPLUG event for v4.30a
1 parent 6380c3c commit ee8e16a

File tree

3 files changed

+47
-6
lines changed

3 files changed

+47
-6
lines changed

device/esp_tinyusb/README.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -349,6 +349,10 @@ To enable Mass Storage Device:
349349
- select the option from `menuconfig`
350350
- configure storage for MSC Device class: SPI Flash or SD/MMC (when supported by the hardware).
351351
352+
> **🔧 Self-powered Flash Drive**:
353+
>
354+
> When VBUS monitoring is enabled with `TINYUSB_PORT_HIGH_SPEED_0` (ESP32-P4 USB OTG 2.0), the storage filesystem is mounted and unmounted between the application and the USB Host based on software VBUS monitoring events. In this scenario, the Timer Task Stack Size (`configTIMER_TASK_STACK_DEPTH`) must be large enough to handle filesystem operations during detach events. It is recommended to set this value to at least 2304 bytes (2048 + 256).
355+
352356
**SPI-Flash Storage**
353357
354358
```c

device/esp_tinyusb/include_private/tinyusb_vbus_monitor.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ typedef struct {
2929
* @param config VBUS monitoring configuration
3030
*
3131
* @return
32-
* - ESP_ERR_INVALID_ARG if config is NULL
32+
* - ESP_ERR_INVALID_ARG if config is NULL or Timer Task Stack Depth is insufficient when MSC is enabled
3333
* - ESP_ERR_INVALID_STATE if VBUS monitoring is already initialized
3434
* - ESP_ERR_NO_MEM if debounce timer creation failed
3535
* - ESP_OK if VBUS monitoring was initialized successfully

device/esp_tinyusb/tinyusb_vbus_monitor.c

Lines changed: 42 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -12,18 +12,28 @@
1212
#include "freertos/timers.h"
1313
#include "driver/gpio.h"
1414
#include "tinyusb_vbus_monitor.h"
15-
<<<<<<< HEAD
16-
=======
1715
#include "tinyusb_device.h"
18-
>>>>>>> a562322070 (refactor(esp_tinyusb): Made attached and dettached functions available as private)
1916

2017
const static char *TAG = "VBUS mon";
2118

19+
// This value is used for checking Timer Task Stack Size when MSC is enabled
20+
// When value is changed, also update the README.md documentation
21+
#define VBUS_MON_TIMER_TASK_STACK_MIN 2304
22+
2223
#if (CONFIG_IDF_TARGET_ESP32P4)
23-
#include "soc/usb_dwc_struct.h"
2424
// On ESP32-P4 USB OTG 2.0 signals are not wired to GPIO matrix
2525
// So we need to override the Bvalid signal from PHY
26+
#include "soc/usb_dwc_struct.h" // For GOTGCTL (when supported) and DCTL registers access
2627
#define USB_DWC_REG USB_DWC_HS
28+
29+
#if (CONFIG_ESP32P4_REV_MIN_300)
30+
// On ESP32-P4 ECO5, BVALID override is not supported
31+
#define BVALID_OVERRIDE_SUPPORT_ENABLE 0
32+
#else
33+
#define BVALID_OVERRIDE_SUPPORT_ENABLE 1
34+
#endif // CONFIG_ESP32P4_REV_MIN_300
35+
#else
36+
#error "VBUS monitoring is supported only on ESP32-P4, USB OTG 2.0"
2737
#endif // CONFIG_IDF_TARGET_ESP32P4
2838

2939
/**
@@ -47,6 +57,7 @@ static vbus_monitor_context_t _vbus_ctx = {
4757
// Additional low-level USB DWC functions, which are not present in the IDF USB DWC HAL
4858
//
4959

60+
#if (BVALID_OVERRIDE_SUPPORT_ENABLE)
5061
// --------------- GOTGCTL register ------------------
5162

5263
static void usb_dwc_ll_gotgctl_set_bvalid_override_value(usb_dwc_dev_t *hw, uint8_t value)
@@ -58,6 +69,7 @@ static void usb_dwc_ll_gotgctl_enable_bvalid_override(usb_dwc_dev_t *hw, bool en
5869
{
5970
hw->gotgctl_reg.bvalidoven = enable ? 1 : 0;
6071
}
72+
#endif // BVALID_OVERRIDE_SUPPORT_ENABLE
6173

6274
// ------------------ DCTL register --------------------
6375

@@ -74,7 +86,9 @@ static void usb_dwc_ll_dctl_set_soft_disconnect(usb_dwc_dev_t *hw, bool enable)
7486
static void vbus_appeared(void)
7587
{
7688
ESP_LOGD(TAG, "Appeared");
89+
#if (BVALID_OVERRIDE_SUPPORT_ENABLE)
7790
usb_dwc_ll_gotgctl_set_bvalid_override_value(&USB_DWC_REG, 1);
91+
#endif // BVALID_OVERRIDE_SUPPORT_ENABLE
7892
usb_dwc_ll_dctl_set_soft_disconnect(&USB_DWC_REG, false);
7993
}
8094

@@ -84,8 +98,15 @@ static void vbus_appeared(void)
8498
static void vbus_disappeared(void)
8599
{
86100
ESP_LOGD(TAG, "Disappeared");
87-
usb_dwc_ll_gotgctl_set_bvalid_override_value(&USB_DWC_REG, 0);
88101
usb_dwc_ll_dctl_set_soft_disconnect(&USB_DWC_REG, true);
102+
#if (BVALID_OVERRIDE_SUPPORT_ENABLE)
103+
usb_dwc_ll_gotgctl_set_bvalid_override_value(&USB_DWC_REG, 0);
104+
#else
105+
// Workaround for ESP32-P4 ECO5, USB-OTG peripheral v4.30a
106+
// We are not able to detect the disconnection event from the PHY after VBUS goes low
107+
// So we need to notify the upper logic about the disconnection event manually
108+
tinyusb_device_detached();
109+
#endif // BVALID_OVERRIDE_SUPPORT_ENABLE
89110
}
90111

91112
/**
@@ -153,6 +174,14 @@ esp_err_t tinyusb_vbus_monitor_init(tinyusb_vbus_monitor_config_t *config)
153174
return ESP_ERR_INVALID_STATE;
154175
}
155176

177+
#if (CONFIG_TINYUSB_MSC_ENABLED)
178+
// When MSC is enabled, timer task stack size must be sufficient to handle FS operations during detach events
179+
#if (configTIMER_TASK_STACK_DEPTH < VBUS_MON_TIMER_TASK_STACK_MIN)
180+
ESP_LOGE(TAG, "When MSC is enabled, configTIMER_TASK_STACK_DEPTH must be at least %d bytes to handle FS operations during attach/detach events", VBUS_MON_TIMER_TASK_STACK_MIN);
181+
return ESP_ERR_INVALID_ARG;
182+
#endif // (configTIMER_TASK_STACK_DEPTH)
183+
#endif // (CONFIG_TINYUSB_MSC_ENABLED)
184+
156185
_vbus_ctx.gpio_num = config->gpio_num;
157186
_vbus_ctx.prev_state = false;
158187

@@ -189,12 +218,15 @@ esp_err_t tinyusb_vbus_monitor_init(tinyusb_vbus_monitor_config_t *config)
189218
}
190219
// Disable GPIO interrupt
191220
gpio_intr_disable(_vbus_ctx.gpio_num);
221+
222+
#if (BVALID_OVERRIDE_SUPPORT_ENABLE)
192223
// Set initial Bvalid override value and enable override
193224
usb_dwc_ll_gotgctl_set_bvalid_override_value(&USB_DWC_REG, 0);
194225
// Wait 1 microsecond (sufficient for >5 PHY clocks)
195226
esp_rom_delay_us(1);
196227
// Enable to override the signal from PHY
197228
usb_dwc_ll_gotgctl_enable_bvalid_override(&USB_DWC_REG, true);
229+
#endif // BVALID_OVERRIDE_SUPPORT_ENABLE
198230

199231
// Device could be already connected, check the status and start the timer if needed
200232
if (gpio_get_level(_vbus_ctx.gpio_num)) {
@@ -214,7 +246,9 @@ esp_err_t tinyusb_vbus_monitor_init(tinyusb_vbus_monitor_config_t *config)
214246

215247
timer_err:
216248
gpio_isr_handler_remove(_vbus_ctx.gpio_num);
249+
#if (BVALID_OVERRIDE_SUPPORT_ENABLE)
217250
usb_dwc_ll_gotgctl_enable_bvalid_override(&USB_DWC_REG, false);
251+
#endif // BVALID_OVERRIDE_SUPPORT_ENABLE
218252
isr_err:
219253
gpio_reset_pin(_vbus_ctx.gpio_num);
220254
_vbus_ctx.gpio_num = GPIO_NUM_NC;
@@ -248,8 +282,11 @@ esp_err_t tinyusb_vbus_monitor_deinit(void)
248282
xTimerDelete(_vbus_ctx.debounce_timer, 0);
249283
_vbus_ctx.debounce_timer = NULL;
250284

285+
#if (BVALID_OVERRIDE_SUPPORT_ENABLE)
251286
// Disable to override the signal from PHY
252287
usb_dwc_ll_gotgctl_enable_bvalid_override(&USB_DWC_REG, false);
288+
#endif // BVALID_OVERRIDE_SUPPORT_ENABLE
289+
253290
ESP_LOGD(TAG, "Deinit");
254291
return ESP_OK;
255292
}

0 commit comments

Comments
 (0)