1
0
mirror of https://github.com/esphome/esphome.git synced 2026-02-08 00:31:58 +00:00

[tinyusb] New component (#11678)

This commit is contained in:
Keith Burzinski
2025-11-03 18:29:30 -06:00
committed by GitHub
parent 266e4ae91f
commit 59326f137e
9 changed files with 192 additions and 0 deletions

View File

@@ -480,6 +480,7 @@ esphome/components/template/fan/* @ssieb
esphome/components/text/* @mauritskorse esphome/components/text/* @mauritskorse
esphome/components/thermostat/* @kbx81 esphome/components/thermostat/* @kbx81
esphome/components/time/* @esphome/core esphome/components/time/* @esphome/core
esphome/components/tinyusb/* @kbx81
esphome/components/tlc5947/* @rnauber esphome/components/tlc5947/* @rnauber
esphome/components/tlc5971/* @IJIJI esphome/components/tlc5971/* @IJIJI
esphome/components/tm1621/* @Philippe12 esphome/components/tm1621/* @Philippe12

View File

@@ -0,0 +1,60 @@
import esphome.codegen as cg
from esphome.components import esp32
from esphome.components.esp32 import add_idf_component, add_idf_sdkconfig_option
from esphome.components.esp32.const import (
VARIANT_ESP32P4,
VARIANT_ESP32S2,
VARIANT_ESP32S3,
)
import esphome.config_validation as cv
from esphome.const import CONF_ID
CODEOWNERS = ["@kbx81"]
CONFLICTS_WITH = ["usb_host"]
CONF_USB_LANG_ID = "usb_lang_id"
CONF_USB_MANUFACTURER_STR = "usb_manufacturer_str"
CONF_USB_PRODUCT_ID = "usb_product_id"
CONF_USB_PRODUCT_STR = "usb_product_str"
CONF_USB_SERIAL_STR = "usb_serial_str"
CONF_USB_VENDOR_ID = "usb_vendor_id"
tinyusb_ns = cg.esphome_ns.namespace("tinyusb")
TinyUSB = tinyusb_ns.class_("TinyUSB", cg.Component)
CONFIG_SCHEMA = cv.All(
cv.Schema(
{
cv.GenerateID(): cv.declare_id(TinyUSB),
cv.Optional(CONF_USB_PRODUCT_ID, default=0x4001): cv.uint16_t,
cv.Optional(CONF_USB_VENDOR_ID, default=0x303A): cv.uint16_t,
cv.Optional(CONF_USB_LANG_ID, default=0x0409): cv.uint16_t,
cv.Optional(CONF_USB_MANUFACTURER_STR, default="ESPHome"): cv.string,
cv.Optional(CONF_USB_PRODUCT_STR, default="ESPHome"): cv.string,
cv.Optional(CONF_USB_SERIAL_STR, default=""): cv.string,
}
).extend(cv.COMPONENT_SCHEMA),
esp32.only_on_variant(
supported=[VARIANT_ESP32P4, VARIANT_ESP32S2, VARIANT_ESP32S3],
),
)
async def to_code(config):
var = cg.new_Pvariable(config[CONF_ID])
await cg.register_component(var, config)
# Set USB device descriptor properties
cg.add(var.set_usb_desc_product_id(config[CONF_USB_PRODUCT_ID]))
cg.add(var.set_usb_desc_vendor_id(config[CONF_USB_VENDOR_ID]))
cg.add(var.set_usb_desc_lang_id(config[CONF_USB_LANG_ID]))
cg.add(var.set_usb_desc_manufacturer(config[CONF_USB_MANUFACTURER_STR]))
cg.add(var.set_usb_desc_product(config[CONF_USB_PRODUCT_STR]))
if config[CONF_USB_SERIAL_STR]:
cg.add(var.set_usb_desc_serial(config[CONF_USB_SERIAL_STR]))
add_idf_component(name="espressif/esp_tinyusb", ref="1.7.6~1")
add_idf_sdkconfig_option("CONFIG_TINYUSB_DESC_USE_ESPRESSIF_VID", False)
add_idf_sdkconfig_option("CONFIG_TINYUSB_DESC_USE_DEFAULT_PID", False)
add_idf_sdkconfig_option("CONFIG_TINYUSB_DESC_BCD_DEVICE", 0x0100)

View File

@@ -0,0 +1,44 @@
#if defined(USE_ESP32_VARIANT_ESP32P4) || defined(USE_ESP32_VARIANT_ESP32S2) || defined(USE_ESP32_VARIANT_ESP32S3)
#include "tinyusb_component.h"
#include "esphome/core/helpers.h"
#include "esphome/core/log.h"
namespace esphome::tinyusb {
static const char *TAG = "tinyusb";
void TinyUSB::setup() {
// Use the device's MAC address as its serial number if no serial number is defined
if (this->string_descriptor_[SERIAL_NUMBER] == nullptr) {
static char mac_addr_buf[13];
get_mac_address_into_buffer(mac_addr_buf);
this->string_descriptor_[SERIAL_NUMBER] = mac_addr_buf;
}
this->tusb_cfg_ = {
.descriptor = &this->usb_descriptor_,
.string_descriptor = this->string_descriptor_,
.string_descriptor_count = SIZE,
.external_phy = false,
};
esp_err_t result = tinyusb_driver_install(&this->tusb_cfg_);
if (result != ESP_OK) {
this->mark_failed();
}
}
void TinyUSB::dump_config() {
ESP_LOGCONFIG(TAG,
"TinyUSB:\n"
" Product ID: 0x%04X\n"
" Vendor ID: 0x%04X\n"
" Manufacturer: '%s'\n"
" Product: '%s'\n"
" Serial: '%s'\n",
this->usb_descriptor_.idProduct, this->usb_descriptor_.idVendor, this->string_descriptor_[MANUFACTURER],
this->string_descriptor_[PRODUCT], this->string_descriptor_[SERIAL_NUMBER]);
}
} // namespace esphome::tinyusb
#endif

View File

@@ -0,0 +1,72 @@
#pragma once
#if defined(USE_ESP32_VARIANT_ESP32P4) || defined(USE_ESP32_VARIANT_ESP32S2) || defined(USE_ESP32_VARIANT_ESP32S3)
#include "esphome/core/component.h"
#include "tinyusb.h"
#include "tusb.h"
namespace esphome::tinyusb {
enum USBDStringDescriptor : uint8_t {
LANGUAGE_ID = 0,
MANUFACTURER = 1,
PRODUCT = 2,
SERIAL_NUMBER = 3,
INTERFACE = 4,
TERMINATOR = 5,
SIZE = 6,
};
static const char *DEFAULT_USB_STR = "ESPHome";
class TinyUSB : public Component {
public:
void setup() override;
void dump_config() override;
float get_setup_priority() const override { return setup_priority::BUS; }
void set_usb_desc_product_id(uint16_t product_id) { this->usb_descriptor_.idProduct = product_id; }
void set_usb_desc_vendor_id(uint16_t vendor_id) { this->usb_descriptor_.idVendor = vendor_id; }
void set_usb_desc_lang_id(uint16_t lang_id) {
this->usb_desc_lang_id_[0] = lang_id & 0xFF;
this->usb_desc_lang_id_[1] = lang_id >> 8;
}
void set_usb_desc_manufacturer(const char *usb_desc_manufacturer) {
this->string_descriptor_[MANUFACTURER] = usb_desc_manufacturer;
}
void set_usb_desc_product(const char *usb_desc_product) { this->string_descriptor_[PRODUCT] = usb_desc_product; }
void set_usb_desc_serial(const char *usb_desc_serial) { this->string_descriptor_[SERIAL_NUMBER] = usb_desc_serial; }
protected:
char usb_desc_lang_id_[2] = {0x09, 0x04}; // defaults to english
const char *string_descriptor_[SIZE] = {
this->usb_desc_lang_id_, // 0: supported language is English (0x0409)
DEFAULT_USB_STR, // 1: Manufacturer
DEFAULT_USB_STR, // 2: Product
nullptr, // 3: Serial Number
nullptr, // 4: Interface
nullptr, // 5: Terminator
};
tinyusb_config_t tusb_cfg_{};
tusb_desc_device_t usb_descriptor_{
.bLength = sizeof(tusb_desc_device_t),
.bDescriptorType = TUSB_DESC_DEVICE,
.bcdUSB = 0x0200,
.bDeviceClass = TUSB_CLASS_MISC,
.bDeviceSubClass = MISC_SUBCLASS_COMMON,
.bDeviceProtocol = MISC_PROTOCOL_IAD,
.bMaxPacketSize0 = CFG_TUD_ENDPOINT0_SIZE,
.idVendor = 0x303A,
.idProduct = 0x4001,
.bcdDevice = CONFIG_TINYUSB_DESC_BCD_DEVICE,
.iManufacturer = 1,
.iProduct = 2,
.iSerialNumber = 3,
.bNumConfigurations = 1,
};
};
} // namespace esphome::tinyusb
#endif

View File

@@ -23,3 +23,7 @@ dependencies:
version: "2.0.0" version: "2.0.0"
rules: rules:
- if: "target in [esp32, esp32p4]" - if: "target in [esp32, esp32p4]"
espressif/esp_tinyusb:
version: "1.7.6~1"
rules:
- if: "target in [esp32s2, esp32s3, esp32p4]"

View File

@@ -0,0 +1,8 @@
tinyusb:
id: tinyusb_test
usb_lang_id: 0x0123
usb_manufacturer_str: ESPHomeTestManufacturer
usb_product_id: 0x1234
usb_product_str: ESPHomeTestProduct
usb_serial_str: ESPHomeTestSerialNumber
usb_vendor_id: 0x2345

View File

@@ -0,0 +1 @@
<<: !include common.yaml

View File

@@ -0,0 +1 @@
<<: !include common.yaml

View File

@@ -0,0 +1 @@
<<: !include common.yaml