Skip to content

Commit

Permalink
Merge branch 'fix/esp_tinyuf2_issues' into 'master'
Browse files Browse the repository at this point in the history
fix(esp_tinyuf2): usb mount && cpu dynimic frequency

Closes AEG-1677, AEG-1165, and AEGHB-632

See merge request ae_group/esp-iot-solution!1037
  • Loading branch information
leeebo committed Jun 25, 2024
2 parents 5080100 + 6bbab78 commit dd15770
Show file tree
Hide file tree
Showing 12 changed files with 166 additions and 55 deletions.
6 changes: 6 additions & 0 deletions components/usb/esp_tinyuf2/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
# ChangeLog

## v0.2.2 - 2024-06-19

* Fix usb may not be enumerated after switch from usb-serial-jtag to usb-otg
* Fix tinyusb debug issue if usb console is enabled
* Fix power management when frequency dynamic scaling is enabled

## v0.2.1 - 2024-04-22

* Fix build with latest ESP-IDF (USB Hal: Change name of usb_phy HAL files to usb_fsls_phy)
Expand Down
43 changes: 31 additions & 12 deletions components/usb/esp_tinyuf2/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,26 +1,45 @@
set(src_cdc)
set(inc_cdc)
idf_component_get_property(TUSB_PATH leeebo__tinyusb_src COMPONENT_DIR)
idf_component_get_property(DCD_CORE_INCLUDES leeebo__tinyusb_src DCD_CORE_INCLUDES)
idf_component_get_property(DCD_CORE_SRCS leeebo__tinyusb_src DCD_CORE_SRCS)
idf_component_get_property(TUSB_COMPILE_OPTIONS leeebo__tinyusb_src TUSB_COMPILE_OPTIONS)

message("TinyUSB path: ${TUSB_PATH}")
message("TinyUSB includes: ${DCD_CORE_INCLUDES}")
message("TinyUSB sources: ${DCD_CORE_SRCS}")
message("TinyUSB compile options: ${TUSB_COMPILE_OPTIONS}")

set(src_tusb
"${DCD_CORE_SRCS}"
"msc/msc.c"
"usb_descriptors.c"
"${TUSB_PATH}/src/class/cdc/cdc_device.c"
"${TUSB_PATH}/src/class/msc/msc_device.c"
)
set(inc_tusb "${DCD_CORE_INCLUDES}" "msc")

if(CONFIG_ENABLE_UF2_USB_CONSOLE)
set(src_cdc "cdc/cdc.c" "cdc/tusb_cdc_acm.c" "cdc/tusb_console.c" "cdc/vfs_tinyusb.c")
set(inc_cdc "cdc")
list(APPEND src_tusb "cdc/cdc.c" "cdc/tusb_cdc_acm.c" "cdc/tusb_console.c" "cdc/vfs_tinyusb.c")
list(APPEND inc_tusb "cdc")
endif()

idf_component_register(
SRCS
"uf2/board_flash.c"
"uf2/ghostfat.c"
"msc/msc.c"
"msc/usb_descriptors.c"
"esp_tinyuf2.c"
${src_cdc}
INCLUDE_DIRS "." "msc" ${inc_cdc}
${src_tusb}
INCLUDE_DIRS "." ${inc_tusb}
PRIV_INCLUDE_DIRS "private_include"
REQUIRES app_update
PRIV_REQUIRES usb nvs_flash vfs esp_ringbuf)
PRIV_REQUIRES usb nvs_flash vfs esp_ringbuf esp_pm)

idf_component_get_property(tusb_lib leeebo__tinyusb_src COMPONENT_LIB)
cmake_policy(SET CMP0079 NEW)
target_link_libraries(${tusb_lib} PRIVATE ${COMPONENT_LIB})
if(NOT CONFIG_TINYUSB_SOURCE_CODE_ONLY)
message(FATAL_ERROR "Please disable 'Build tinyusb as a static library' in menuconfig 'TinyUSB soucre'")
endif()

target_compile_options(${COMPONENT_LIB} PUBLIC
${TUSB_COMPILE_OPTIONS}
)

execute_process(COMMAND git -C ${IDF_PATH} describe --dirty --always --tags
OUTPUT_VARIABLE MY_IDF_VERSION
Expand Down
2 changes: 2 additions & 0 deletions components/usb/esp_tinyuf2/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,12 @@ menu "TinyUF2 Config"
config ENABLE_UF2_FLASHING
bool
default y if IDF_TARGET_ESP32S2 || IDF_TARGET_ESP32S3
select TINYUSB_SOURCE_CODE_ONLY
help
Enable UF2, only support ESP SoC with USB-OTG
config ENABLE_UF2_USB_CONSOLE
bool "Enable USB Console For log"
depends on ENABLE_UF2_FLASHING
default n
config UF2_DISK_SIZE_MB
int "USB Virtual Disk size(MB)"
Expand Down
18 changes: 18 additions & 0 deletions components/usb/esp_tinyuf2/cdc/tusb_cdc_acm.c
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
#include "tusb_cdc_acm.h"
#include "cdc.h"
#include "sdkconfig.h"
#include "esp_tinyuf2.h"

#define RX_UNREADBUF_SZ_DEFAULT 64 // buffer storing all unread RX data
#define MIN(x, y) (((x) < (y)) ? (x) : (y))
Expand Down Expand Up @@ -272,6 +273,12 @@ size_t tinyusb_cdcacm_write_queue_char(tinyusb_cdcacm_itf_t itf, char ch)
if (!get_acm(itf)) { // non-initialized
return 0;
}

if (esp_tinyuf2_current_state() < TINYUF2_STATE_MOUNTED) {
ESP_LOGD(TAG, "USB is not connected");
return 0;
}

return tud_cdc_n_write_char(itf, ch);
}

Expand All @@ -280,6 +287,12 @@ size_t tinyusb_cdcacm_write_queue(tinyusb_cdcacm_itf_t itf, const uint8_t *in_bu
if (!get_acm(itf)) { // non-initialized
return 0;
}

if (esp_tinyuf2_current_state() < TINYUF2_STATE_MOUNTED) {
ESP_LOGD(TAG, "USB is not connected");
return 0;
}

const uint32_t size_available = tud_cdc_n_write_available(itf);
return tud_cdc_n_write(itf, in_buf, MIN(in_size, size_available));
}
Expand All @@ -295,6 +308,11 @@ esp_err_t tinyusb_cdcacm_write_flush(tinyusb_cdcacm_itf_t itf, uint32_t timeout_
return ESP_FAIL;
}

if (esp_tinyuf2_current_state() < TINYUF2_STATE_MOUNTED) {
ESP_LOGD(TAG, "USB is not connected");
return ESP_ERR_INVALID_STATE;
}

if (!timeout_ticks) { // if no timeout - nonblocking mode
int res = tud_cdc_n_write_flush(itf);
if (!res) {
Expand Down
4 changes: 2 additions & 2 deletions components/usb/esp_tinyuf2/cdc/tusb_console.c
Original file line number Diff line number Diff line change
Expand Up @@ -99,14 +99,14 @@ static esp_err_t restore_std_streams(FILE **f_in, FILE **f_out, FILE **f_err)
esp_err_t esp_tusb_init_console(int cdc_intf)
{
/* Registering TUSB at VFS */
ESP_RETURN_ON_ERROR(esp_vfs_tusb_cdc_register(cdc_intf, NULL), TAG, "");
ESP_RETURN_ON_ERROR(esp_vfs_tusb_cdc_register(cdc_intf, VFS_TUSB_PATH_DEFAULT), TAG, "");
ESP_RETURN_ON_ERROR(redirect_std_streams_to(&con.in, &con.out, &con.err, VFS_TUSB_PATH_DEFAULT), TAG, "Failed to redirect STD streams");
return ESP_OK;
}

esp_err_t esp_tusb_deinit_console(int cdc_intf)
{
ESP_RETURN_ON_ERROR(restore_std_streams(&con.in, &con.out, &con.err), TAG, "Failed to restore STD streams");
esp_vfs_tusb_cdc_unregister(NULL);
esp_vfs_tusb_cdc_unregister(VFS_TUSB_PATH_DEFAULT);
return ESP_OK;
}
102 changes: 91 additions & 11 deletions components/usb/esp_tinyuf2/esp_tinyuf2.c
Original file line number Diff line number Diff line change
Expand Up @@ -7,25 +7,77 @@
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "esp_log.h"
#include "esp_pm.h"
#include "esp_rom_gpio.h"
#include "soc/soc_caps.h"
#include "soc/gpio_pins.h"
#include "soc/gpio_sig_map.h"
#include "soc/rtc_cntl_struct.h"
#include "tusb.h"
#include "esp_tinyuf2.h"
#include "esp_private/usb_phy.h"
#include "board_flash.h"
#include "uf2.h"

#if SOC_USB_SERIAL_JTAG_SUPPORTED
#include "soc/usb_serial_jtag_reg.h"
#endif

#ifdef CONFIG_ENABLE_UF2_USB_CONSOLE
#include "tusb_cdc_acm.h"
#include "tusb_console.h"
#endif

const static char* TAG = "TUF2";
static bool _if_init = false;
static tinyuf2_state_t _uf2_state = TINYUF2_STATE_NOT_INSTALLED;
static TaskHandle_t _task_handle = NULL;

#ifdef CONFIG_PM_ENABLE
static esp_pm_lock_handle_t pm_locks_cpu_max = NULL;
#endif

// Invoked when device is mounted
void tud_mount_cb(void)
{
#ifdef CONFIG_ENABLE_UF2_USB_CONSOLE
ESP_LOGI(TAG, "USB Mounted");
ESP_LOGI(TAG, "Enable USB console, log will be output to USB");
tinyusb_config_cdcacm_t acm_cfg = { 0 }; // the configuration uses default values
tusb_cdc_acm_init(&acm_cfg);
esp_tusb_init_console(TINYUSB_CDC_ACM_0);
#endif
_uf2_state = TINYUF2_STATE_MOUNTED;
ESP_LOGI(TAG, "USB Mounted");
}

// Invoked when device is unmounted
void tud_umount_cb(void)
{
#ifdef CONFIG_ENABLE_UF2_USB_CONSOLE
ESP_LOGI(TAG, "USB Unmounted");
esp_tusb_deinit_console(TINYUSB_CDC_ACM_0);
//todo: tusb_cdc_acm_deinit() is not implemented
#endif
_uf2_state = TINYUF2_STATE_INSTALLED;
ESP_LOGI(TAG, "USB Unmounted");
}

// Invoked when usb bus is suspended
// remote_wakeup_en : if host allows us to perform remote wakeup
// USB Specs: Within 7ms, device must draw an average current less than 2.5 mA from bus
void tud_suspend_cb(bool remote_wakeup_en)
{
_uf2_state = TINYUF2_STATE_INSTALLED;
ESP_LOGI(TAG, "USB Suspended");
}

// Invoked when usb bus is resumed
void tud_resume_cb(void)
{
_uf2_state = TINYUF2_STATE_MOUNTED;
ESP_LOGI(TAG, "USB Resumed");
}

// USB Device Driver task
static void _usb_otg_phy_init(bool enable)
{
Expand All @@ -40,6 +92,16 @@ static void _usb_otg_phy_init(bool enable)
phy_hdl = NULL;
}
if (enable) {
#if SOC_USB_SERIAL_JTAG_SUPPORTED
// due to the default usb function is usb-serial-jtag
// quick switch may cause the host not re-enumerate the device
// pull down DP to make host treat it as disconnect event
SET_PERI_REG_MASK(USB_SERIAL_JTAG_CONF0_REG, USB_SERIAL_JTAG_PAD_PULL_OVERRIDE);
CLEAR_PERI_REG_MASK(USB_SERIAL_JTAG_CONF0_REG, USB_SERIAL_JTAG_DP_PULLUP);
SET_PERI_REG_MASK(USB_SERIAL_JTAG_CONF0_REG, USB_SERIAL_JTAG_DP_PULLDOWN);
CLEAR_PERI_REG_MASK(USB_SERIAL_JTAG_CONF0_REG, USB_SERIAL_JTAG_DP_PULLDOWN);
vTaskDelay(pdMS_TO_TICKS(10));
#endif
// Configure USB OTG PHY
phy_conf.controller = USB_PHY_CTRL_OTG;
usb_new_phy(&phy_conf, &phy_hdl);
Expand All @@ -57,6 +119,7 @@ static void _usb_otg_phy_init(bool enable)
static void usb_device_task(void* param)
{
(void) param;
ulTaskNotifyTake(pdTRUE, portMAX_DELAY);
// RTOS forever loop
while (1) {
// put this thread to waiting state until there is new events
Expand All @@ -83,6 +146,10 @@ static void usbd_vbus_enable(bool enable)

static esp_err_t tinyusb_init()
{
#ifdef CONFIG_PM_ENABLE
esp_pm_lock_create(ESP_PM_CPU_FREQ_MAX, 0, "usb_otg", &pm_locks_cpu_max);
esp_pm_lock_acquire(pm_locks_cpu_max);
#endif
_usb_otg_phy_init(true);
// init device stack on configured roothub port
// This should be called after scheduler/kernel is started.
Expand Down Expand Up @@ -115,16 +182,19 @@ static esp_err_t tinyusb_deinit()
_task_handle = NULL;
tusb_teardown();
_usb_otg_phy_init(false);
#ifdef CONFIG_PM_ENABLE
esp_pm_lock_release(pm_locks_cpu_max);
esp_pm_lock_delete(pm_locks_cpu_max);
#endif
return ESP_OK;
}

esp_err_t esp_tinyuf2_install(tinyuf2_ota_config_t *ota_config, tinyuf2_nvs_config_t *nvs_config)
{
if (_if_init) {
if (_uf2_state != TINYUF2_STATE_NOT_INSTALLED) {
ESP_LOGE(TAG, "Tinyuf2 already installed");
return ESP_ERR_INVALID_STATE;
}
_if_init = true;

if (!(ota_config || nvs_config)) {
ESP_LOGE(TAG, "Invalid Parameter, config can’t be NULL");
Expand All @@ -148,27 +218,37 @@ esp_err_t esp_tinyuf2_install(tinyuf2_ota_config_t *ota_config, tinyuf2_nvs_conf

uf2_init();
tinyusb_init();
#ifdef CONFIG_ENABLE_UF2_USB_CONSOLE
ESP_LOGI(TAG, "Enable USB console, log will be output to USB");
tinyusb_config_cdcacm_t acm_cfg = { 0 }; // the configuration uses default values
tusb_cdc_acm_init(&acm_cfg);
esp_tusb_init_console(TINYUSB_CDC_ACM_0);
#endif

_uf2_state = TINYUF2_STATE_INSTALLED;
xTaskNotifyGive(_task_handle);
ESP_LOGI(TAG, "UF2 Updater install succeed, Version: %d.%d.%d", ESP_TINYUF2_VER_MAJOR, ESP_TINYUF2_VER_MINOR, ESP_TINYUF2_VER_PATCH);

return ESP_OK;
}

esp_err_t esp_tinyuf2_uninstall(void)
{
if (!_if_init) {
if (_uf2_state == TINYUF2_STATE_NOT_INSTALLED) {
ESP_LOGE(TAG, "Tinyuf2 not installed");
return ESP_ERR_INVALID_STATE;
}

#ifdef CONFIG_ENABLE_UF2_USB_CONSOLE
if (_uf2_state == TINYUF2_STATE_MOUNTED) {
esp_tusb_deinit_console(TINYUSB_CDC_ACM_0);
//todo: tusb_cdc_acm_deinit() is not implemented
}
#endif

tinyusb_deinit();
board_flash_deinit();
board_flash_nvs_deinit();
ESP_LOGI(TAG, "UF2 Updater uninstall succeed");
_if_init = false;
_uf2_state = TINYUF2_STATE_NOT_INSTALLED;
return ESP_OK;
}

tinyuf2_state_t esp_tinyuf2_current_state(void)
{
return _uf2_state;
}
13 changes: 13 additions & 0 deletions components/usb/esp_tinyuf2/esp_tinyuf2.h
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,12 @@ typedef struct {
nvs_modified_cb_t modified_cb; /*! user callback called after uf2 update complete */
} tinyuf2_nvs_config_t;

typedef enum {
TINYUF2_STATE_NOT_INSTALLED = 0,
TINYUF2_STATE_INSTALLED,
TINYUF2_STATE_MOUNTED,
} tinyuf2_state_t;

/**
* @brief Flashing app to specified partition through USB UF2 (Virtual USB Disk),
* and support operate NVS partition through USB UF2 CONFIG.ini file.
Expand All @@ -79,6 +85,13 @@ esp_err_t esp_tinyuf2_install(tinyuf2_ota_config_t *ota_config, tinyuf2_nvs_conf
*/
esp_err_t esp_tinyuf2_uninstall(void);

/**
* @brief Get tinyuf2 current state
*
* @return tinyuf2_state_t
*/
tinyuf2_state_t esp_tinyuf2_current_state(void);

#ifdef __cplusplus
}
#endif
Expand Down
4 changes: 2 additions & 2 deletions components/usb/esp_tinyuf2/idf_component.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
version: "0.2.1"
version: "0.2.2"
targets:
- esp32s2
- esp32s3
Expand All @@ -13,7 +13,7 @@ dependencies:
cmake_utilities: "0.*"
leeebo/esp-inih: "0.*"
leeebo/tinyusb_src:
version: "~0.0.3"
version: ">=0.16.0~5"

examples:
- path: ../../../examples/usb/device/usb_uf2_ota
Expand Down
Loading

0 comments on commit dd15770

Please sign in to comment.