diff --git a/components/esp_rom/CMakeLists.txt b/components/esp_rom/CMakeLists.txt index 266dd5c2b1..20d49ff36d 100644 --- a/components/esp_rom/CMakeLists.txt +++ b/components/esp_rom/CMakeLists.txt @@ -2,7 +2,8 @@ idf_build_get_property(target IDF_TARGET) idf_component_register(SRCS "patches/esp_rom_crc.c" INCLUDE_DIRS include - PRIV_INCLUDE_DIRS "${target}") + PRIV_INCLUDE_DIRS "${target}" + PRIV_REQUIRES soc) if(BOOTLOADER_BUILD) set(scripts @@ -83,3 +84,7 @@ else() # Regular app build target_linker_script(${COMPONENT_LIB} INTERFACE "${scripts}") endif() + +if(target STREQUAL "esp32s2") + target_sources(${COMPONENT_LIB} PRIVATE "esp32s2/usb_descriptors.c") +endif() diff --git a/components/esp_rom/esp32s2/usb_descriptors.c b/components/esp_rom/esp32s2/usb_descriptors.c new file mode 100644 index 0000000000..a1098d11c4 --- /dev/null +++ b/components/esp_rom/esp32s2/usb_descriptors.c @@ -0,0 +1,75 @@ +// Copyright 2020 Espressif Systems (Shanghai) PTE LTD +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include +#include "esp32s2/rom/usb/usb_common.h" +#include "soc/soc.h" +#include "soc/efuse_reg.h" + +/* USB CDC descriptor. + * Note that we aren't using the one in ROM since it doesn't + * set "serial" to the MAC address. + * However overriding the descriptor is cheap - we can reuse most + * of its components from ROM. + */ + +/* This is not const, since the MAC address is only known at run time */ +static struct string_descriptor s_str_serial_descr = { + .bLength = 2 + 2 * 17, + .bDescriptorType = 0x03, + .bString={'0', '0', ':', '0', '0', ':', '0', '0', ':', '0', '0', ':', '0', '0', ':', '0', '0'} +}; + +static const struct rom_usb_descriptors s_acm_usb_descriptors_override = { + .device_descr = &general_device_descr, + .config_descr = { &acm_config_descr }, + .string_count = 4, + .string0_descr = &string0_descr, + .string_descrs = { + &str_manu_descr, + &str_prod_descr, + &s_str_serial_descr + } +}; + +static inline uint16_t nibble_to_hex_u16(uint8_t b) +{ + if (b < 0xa) { + return '0' + b; + } else { + return 'a' + b - 0xa; + } +} + +void rom_usb_cdc_set_descriptor_patch(void) +{ + /* Get the MAC address */ + const uint32_t mac0 = REG_GET_FIELD(EFUSE_RD_MAC_SPI_SYS_0_REG, EFUSE_MAC_0); + const uint32_t mac1 = REG_GET_FIELD(EFUSE_RD_MAC_SPI_SYS_1_REG, EFUSE_MAC_1); + uint8_t mac_bytes[6]; + memcpy(mac_bytes, &mac0, 4); + memcpy(mac_bytes + 4, &mac1, 2); + + /* Convert to UTF16 string */ + uint16_t* dst = s_str_serial_descr.bString; + for (int i = 0; i < 6; ++i) { + uint8_t b = mac_bytes[5 - i]; /* printing from the MSB */ + *dst++ = nibble_to_hex_u16(b >> 4); + *dst++ = nibble_to_hex_u16(b & 0xf); + dst++; + } + + /* Override the pointer to descriptors structure */ + rom_usb_curr_desc = &s_acm_usb_descriptors_override; +} diff --git a/components/esp_rom/include/esp32s2/rom/usb/usb_common.h b/components/esp_rom/include/esp32s2/rom/usb/usb_common.h index 1fc65d9eab..796a77bc00 100644 --- a/components/esp_rom/include/esp32s2/rom/usb/usb_common.h +++ b/components/esp_rom/include/esp32s2/rom/usb/usb_common.h @@ -238,6 +238,11 @@ extern const struct rom_usb_descriptors acm_usb_descriptors; extern const struct rom_usb_descriptors dfu_usb_descriptors; extern const struct rom_usb_descriptors *rom_usb_curr_desc; +/* ROM patch: set the ACM descriptor with the correct serial number. + * Only needed on ESP32-S2, on later chips the ROM descriptor is correct. + */ +void rom_usb_cdc_set_descriptor_patch(void); + #ifdef __cplusplus }