Skip to content

Commit 1164cd9

Browse files
committed
added vbus_monitor files
1 parent 80b30e0 commit 1164cd9

File tree

3 files changed

+132
-1
lines changed

3 files changed

+132
-1
lines changed

device/esp_tinyusb/CMakeLists.txt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ set(srcs
33
"tinyusb.c"
44
"usb_descriptors.c"
55
"tinyusb_task.c"
6+
"tinyusb_vbus_monitor.c"
67
)
78

89
set(priv_req "")
@@ -47,7 +48,7 @@ idf_component_register(SRCS ${srcs}
4748
INCLUDE_DIRS "include"
4849
PRIV_INCLUDE_DIRS "include_private"
4950
PRIV_REQUIRES ${priv_req}
50-
REQUIRES fatfs vfs
51+
REQUIRES fatfs vfs esp_timer
5152
)
5253

5354
# Determine whether tinyusb is fetched from component registry or from local path
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
/*
2+
* SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD
3+
*
4+
* SPDX-License-Identifier: Apache-2.0
5+
*/
6+
7+
#pragma once
8+
9+
#include "esp_err.h"
10+
#include "tinyusb.h"
11+
12+
#ifdef __cplusplus
13+
extern "C" {
14+
#endif
15+
16+
17+
void tinyusb_vbus_monitor_init(int vbus_io);
18+
19+
void tinyusb_vbus_monitor_deinit(void);
20+
21+
#ifdef __cplusplus
22+
}
23+
#endif
Lines changed: 107 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,107 @@
1+
/*
2+
* SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD
3+
*
4+
* SPDX-License-Identifier: Apache-2.0
5+
*/
6+
7+
#include <stdlib.h>
8+
// #include "freertos/FreeRTOS.h"
9+
// #include "freertos/task.h"
10+
#include "esp_log.h"
11+
#include "esp_check.h"
12+
#include "driver/gpio.h"
13+
#include "esp_timer.h"
14+
15+
#include "tinyusb.h"
16+
#include "sdkconfig.h"
17+
18+
const static char *TAG = "TinyUSB vbus monitor";
19+
20+
#define GPIO_NUM 20 /* TODO: make as argument */
21+
#define DEBOUNCE_DELAY_MS 250
22+
23+
static volatile bool vbus_enabled = false;
24+
esp_timer_handle_t vbus_debounce_timer = NULL;
25+
26+
static void vbus_io_cb(void *arg)
27+
{
28+
ESP_EARLY_LOGW(TAG, "VBUS IO interrupt");
29+
30+
if (gpio_get_level(GPIO_NUM)) {
31+
// ESP_EARLY_LOGI(TAG, "VBUS connected");
32+
vbus_enabled = true;
33+
} else { // Button pressed
34+
// ESP_EARLY_LOGI(TAG, "VBUS disconnected");
35+
vbus_enabled = false;
36+
}
37+
38+
// disable interrupts for a while to debounce
39+
gpio_intr_disable(GPIO_NUM);
40+
// enable debounce timer
41+
esp_timer_start_once(vbus_debounce_timer, DEBOUNCE_DELAY_MS * 1000);
42+
43+
}
44+
45+
static void vbus_debounce_timer_cb(void *arg)
46+
{
47+
(void) arg;
48+
if (gpio_get_level(GPIO_NUM) && vbus_enabled) {
49+
// VBUS connected
50+
ESP_EARLY_LOGI(TAG, "VBUS connected");
51+
}
52+
53+
if (!gpio_get_level(GPIO_NUM) && !vbus_enabled) {
54+
// VBUS disconnected
55+
ESP_EARLY_LOGI(TAG, "VBUS disconnected");
56+
}
57+
58+
ESP_EARLY_LOGI(TAG, "VBUS debounce timer expired");
59+
// re-enable GPIO interrupt
60+
gpio_intr_enable(GPIO_NUM);
61+
}
62+
63+
64+
void tinyusb_vbus_monitor_init(int vbus_io)
65+
{
66+
(void) vbus_io;
67+
#if (CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32S3)
68+
// For ESP32S2/S3, we MUX the BVALID signal
69+
const usb_phy_otg_io_conf_t otg_io_conf = USB_PHY_SELF_POWERED_DEVICE(config->phy.vbus_monitor_io);
70+
phy_conf.otg_io_conf = &otg_io_conf;
71+
#elif CONFIG_IDF_TARGET_ESP32P4
72+
ESP_LOGW(TAG, "Self-powered mode is supported via esp_gpio");
73+
74+
// Debounce timer
75+
const esp_timer_create_args_t vbus_timer_args = {
76+
.callback = &vbus_debounce_timer_cb,
77+
.arg = (void *) xTaskGetCurrentTaskHandle(),
78+
};
79+
ESP_ERROR_CHECK(esp_timer_create(&vbus_timer_args, &vbus_debounce_timer));
80+
81+
// Init gpio IRQ for VBUS monitoring
82+
const gpio_config_t vbus_pin = {
83+
.pin_bit_mask = BIT64(GPIO_NUM),
84+
.mode = GPIO_MODE_INPUT,
85+
.pull_down_en = GPIO_PULLDOWN_ENABLE,
86+
.intr_type = GPIO_INTR_ANYEDGE,
87+
};
88+
ESP_ERROR_CHECK(gpio_config(&vbus_pin));
89+
ESP_ERROR_CHECK(gpio_install_isr_service(ESP_INTR_FLAG_LOWMED));
90+
ESP_ERROR_CHECK(gpio_isr_handler_add(GPIO_NUM, vbus_io_cb, (void *) xTaskGetCurrentTaskHandle()));
91+
92+
93+
#else
94+
ESP_LOGW(TAG, "Self-powered mode is not supported on this chip, ignoring the setting");
95+
#endif // CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32S3
96+
}
97+
98+
void tinyusb_vbus_monitor_deinit(void)
99+
{
100+
#if (CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32S3)
101+
// For ESP32S2/S3, nothing to deinit
102+
#elif CONFIG_IDF_TARGET_ESP32P4
103+
// Deinit gpio IRQ for VBUS monitoring
104+
#else
105+
// Nothing to deinit
106+
#endif // CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32
107+
}

0 commit comments

Comments
 (0)