#include "usb_cdc_log.h" #include #include #include "esp_check.h" #include "esp_log.h" #include "tinyusb.h" #include "tusb_cdc_acm.h" static const char *TAG = "usb_log"; static bool s_initialized; static bool s_host_ready; static vprintf_like_t s_prev_vprintf; static int usb_cdc_vprintf(const char *fmt, va_list args) { if (s_host_ready) { char buffer[256]; va_list args_copy; va_copy(args_copy, args); int len = vsnprintf(buffer, sizeof(buffer), fmt, args_copy); va_end(args_copy); if (len > 0) { if (len >= (int)sizeof(buffer)) { len = sizeof(buffer) - 1; } if (tinyusb_cdcacm_write_queue(TINYUSB_CDC_ACM_0, (const uint8_t *)buffer, len) == ESP_OK) { tinyusb_cdcacm_write_flush(TINYUSB_CDC_ACM_0, 0); } } return len; } if (s_prev_vprintf) { va_list args_copy; va_copy(args_copy, args); int ret = s_prev_vprintf(fmt, args_copy); va_end(args_copy); return ret; } return 0; } static void usb_cdc_line_state_changed_callback(int itf, cdcacm_event_t *event) { (void)itf; s_host_ready = event->line_state_changed_data.dtr; if (s_host_ready) { const char banner[] = "\r\nwatch-watch log over USB CDC\r\n"; tinyusb_cdcacm_write_queue(TINYUSB_CDC_ACM_0, (const uint8_t *)banner, sizeof(banner) - 1); tinyusb_cdcacm_write_flush(TINYUSB_CDC_ACM_0, 0); } } bool usb_cdc_log_ready(void) { return s_host_ready; } esp_err_t usb_cdc_log_init(void) { if (s_initialized) { return ESP_OK; } const tinyusb_config_t tusb_cfg = { .device_descriptor = NULL, .string_descriptor = NULL, .external_phy = false, #if (TUD_OPT_HIGH_SPEED) .fs_configuration_descriptor = NULL, .hs_configuration_descriptor = NULL, .qualifier_descriptor = NULL, #else .configuration_descriptor = NULL, #endif }; ESP_RETURN_ON_ERROR(tinyusb_driver_install(&tusb_cfg), TAG, "TinyUSB init failed"); const tinyusb_config_cdcacm_t acm_cfg = { .usb_dev = TINYUSB_USBDEV_0, .cdc_port = TINYUSB_CDC_ACM_0, .rx_unread_buf_sz = 64, .callback_rx = NULL, .callback_rx_wanted_char = NULL, .callback_line_state_changed = usb_cdc_line_state_changed_callback, .callback_line_coding_changed = NULL, }; ESP_RETURN_ON_ERROR(tusb_cdc_acm_init(&acm_cfg), TAG, "CDC init failed"); s_prev_vprintf = esp_log_set_vprintf(usb_cdc_vprintf); s_initialized = true; ESP_LOGI(TAG, "ESP_LOG перенаправлено в USB CDC"); return ESP_OK; }