Files
esphome/esphome/components/usb_cdc_acm/__init__.py
Keith Burzinski eda743ee48 [usb_cdc_acm] New component (#11687)
Co-authored-by: Jesse Hills <3060199+jesserockz@users.noreply.github.com>
Co-authored-by: pre-commit-ci-lite[bot] <117423508+pre-commit-ci-lite[bot]@users.noreply.github.com>
2025-12-08 09:50:23 -05:00

77 lines
2.5 KiB
Python

import esphome.codegen as cg
from esphome.components import esp32, uart
from esphome.components.esp32 import (
VARIANT_ESP32P4,
VARIANT_ESP32S2,
VARIANT_ESP32S3,
add_idf_sdkconfig_option,
)
import esphome.config_validation as cv
from esphome.const import CONF_ID, CONF_RX_BUFFER_SIZE, CONF_TX_BUFFER_SIZE
from esphome.types import ConfigType
CODEOWNERS = ["@kbx81"]
AUTO_LOAD = ["uart"]
DEPENDENCIES = ["tinyusb"]
CONF_INTERFACES = "interfaces"
usb_cdc_acm_ns = cg.esphome_ns.namespace("usb_cdc_acm")
USBCDCACMComponent = usb_cdc_acm_ns.class_("USBCDCACMComponent", cg.Component)
USBCDCACMInstance = usb_cdc_acm_ns.class_(
"USBCDCACMInstance", uart.UARTComponent, cg.Parented.template(USBCDCACMComponent)
)
# Schema for individual CDC ACM interface instances
INTERFACE_SCHEMA = cv.Schema(
{
cv.GenerateID(): cv.declare_id(USBCDCACMInstance),
}
)
# Main component schema
CONFIG_SCHEMA = cv.All(
cv.Schema(
{
cv.GenerateID(): cv.declare_id(USBCDCACMComponent),
cv.Optional(CONF_RX_BUFFER_SIZE, default=256): cv.All(
cv.validate_bytes, cv.uint16_t
),
cv.Optional(CONF_TX_BUFFER_SIZE, default=256): cv.All(
cv.validate_bytes, cv.uint16_t
),
cv.Optional(CONF_INTERFACES, default=[{}]): cv.All(
cv.ensure_list(INTERFACE_SCHEMA),
cv.Length(min=1, max=2), # At least 1, at most 2 interfaces
),
}
).extend(cv.COMPONENT_SCHEMA),
esp32.only_on_variant(
supported=[VARIANT_ESP32P4, VARIANT_ESP32S2, VARIANT_ESP32S3],
),
)
async def to_code(config: ConfigType) -> None:
var = cg.new_Pvariable(config[CONF_ID])
await cg.register_component(var, config)
# Create and register interface instances
for interface_index, interface_conf in enumerate(config[CONF_INTERFACES]):
interface = cg.new_Pvariable(interface_conf[CONF_ID])
await cg.register_parented(interface, var)
cg.add(interface.set_interface_number(interface_index))
cg.add(var.add_interface(interface))
# Configure TinyUSB with the correct number of CDC interfaces
num_interfaces = len(config[CONF_INTERFACES])
add_idf_sdkconfig_option("CONFIG_TINYUSB_CDC_ENABLED", True)
add_idf_sdkconfig_option("CONFIG_TINYUSB_CDC_COUNT", num_interfaces)
add_idf_sdkconfig_option(
"CONFIG_TINYUSB_CDC_RX_BUFSIZE", config[CONF_RX_BUFFER_SIZE]
)
add_idf_sdkconfig_option(
"CONFIG_TINYUSB_CDC_TX_BUFSIZE", config[CONF_TX_BUFFER_SIZE]
)