From d8d92c192896cca5fd6476181a16361b47374af1 Mon Sep 17 00:00:00 2001 From: Peter Marcisovsky Date: Mon, 3 Jun 2024 11:05:46 +0200 Subject: [PATCH] refactor(examples): Refactor rx callbacks in USB device examples with CDC device - cdcacm_write_queue and cdcacm_write_flush moved from rx callback to main task - received data from rx callback are handled by freerots queues --- .../main/tusb_composite_main.c | 71 ++++++++++++++++--- .../main/tusb_serial_device_main.c | 71 ++++++++++++++++--- 2 files changed, 122 insertions(+), 20 deletions(-) diff --git a/examples/peripherals/usb/device/tusb_composite_msc_serialdevice/main/tusb_composite_main.c b/examples/peripherals/usb/device/tusb_composite_msc_serialdevice/main/tusb_composite_main.c index f1c8b4723e..87474afb66 100644 --- a/examples/peripherals/usb/device/tusb_composite_msc_serialdevice/main/tusb_composite_main.c +++ b/examples/peripherals/usb/device/tusb_composite_msc_serialdevice/main/tusb_composite_main.c @@ -16,27 +16,56 @@ #define BASE_PATH "/usb" // base path to mount the partition static const char *TAG = "example_main"; -static uint8_t buf[CONFIG_TINYUSB_CDC_RX_BUFSIZE + 1]; +static uint8_t rx_buf[CONFIG_TINYUSB_CDC_RX_BUFSIZE + 1]; +/** + * @brief Application Queue + */ +static QueueHandle_t app_queue; +typedef struct { + uint8_t buf[CONFIG_TINYUSB_CDC_RX_BUFSIZE + 1]; // Data buffer + size_t buf_len; // Number of bytes received + uint8_t itf; // Index of CDC device interface +} app_message_t; + +/** + * @brief CDC device RX callback + * + * CDC device signals, that new data were received + * + * @param[in] itf CDC device index + * @param[in] event CDC event type + */ void tinyusb_cdc_rx_callback(int itf, cdcacm_event_t *event) { /* initialization */ size_t rx_size = 0; /* read */ - esp_err_t ret = tinyusb_cdcacm_read(itf, buf, CONFIG_TINYUSB_CDC_RX_BUFSIZE, &rx_size); + esp_err_t ret = tinyusb_cdcacm_read(itf, rx_buf, CONFIG_TINYUSB_CDC_RX_BUFSIZE, &rx_size); if (ret == ESP_OK) { - ESP_LOGI(TAG, "Data from channel %d:", itf); - ESP_LOG_BUFFER_HEXDUMP(TAG, buf, rx_size, ESP_LOG_INFO); - } else { - ESP_LOGE(TAG, "Read error"); - } - /* write back */ - tinyusb_cdcacm_write_queue(itf, buf, rx_size); - tinyusb_cdcacm_write_flush(itf, 0); + app_message_t tx_msg = { + .buf_len = rx_size, + .itf = itf, + }; + + /* Copy received message to application queue buffer */ + memcpy(tx_msg.buf, rx_buf, rx_size); + xQueueSend(app_queue, &tx_msg, 0); + } else { + ESP_LOGE(TAG, "Read Error"); + } } +/** + * @brief CDC device line change callback + * + * CDC device signals, that the DTR, RTS states changed + * + * @param[in] itf CDC device index + * @param[in] event CDC event type + */ void tinyusb_cdc_line_state_changed_callback(int itf, cdcacm_event_t *event) { int dtr = event->line_state_changed_data.dtr; @@ -107,6 +136,11 @@ static esp_err_t storage_init_spiflash(wl_handle_t *wl_handle) void app_main(void) { + // Create FreeRTOS primitives + app_queue = xQueueCreate(5, sizeof(app_message_t)); + assert(app_queue); + app_message_t msg; + ESP_LOGI(TAG, "Initializing storage..."); static wl_handle_t wl_handle = WL_INVALID_HANDLE; @@ -153,4 +187,21 @@ void app_main(void) &tinyusb_cdc_line_state_changed_callback)); ESP_LOGI(TAG, "USB Composite initialization DONE"); + while (1) { + if (xQueueReceive(app_queue, &msg, portMAX_DELAY)) { + if (msg.buf_len) { + + /* Print received data*/ + ESP_LOGI(TAG, "Data from channel %d:", msg.itf); + ESP_LOG_BUFFER_HEXDUMP(TAG, msg.buf, msg.buf_len, ESP_LOG_INFO); + + /* write back */ + tinyusb_cdcacm_write_queue(msg.itf, msg.buf, msg.buf_len); + esp_err_t err = tinyusb_cdcacm_write_flush(msg.itf, 0); + if (err != ESP_OK) { + ESP_LOGE(TAG, "CDC ACM write flush error: %s", esp_err_to_name(err)); + } + } + } + } } diff --git a/examples/peripherals/usb/device/tusb_serial_device/main/tusb_serial_device_main.c b/examples/peripherals/usb/device/tusb_serial_device/main/tusb_serial_device_main.c index 93fc49f086..cc111189f7 100644 --- a/examples/peripherals/usb/device/tusb_serial_device/main/tusb_serial_device_main.c +++ b/examples/peripherals/usb/device/tusb_serial_device/main/tusb_serial_device_main.c @@ -8,32 +8,61 @@ #include "esp_log.h" #include "freertos/FreeRTOS.h" #include "freertos/task.h" +#include "freertos/queue.h" #include "tinyusb.h" #include "tusb_cdc_acm.h" #include "sdkconfig.h" static const char *TAG = "example"; -static uint8_t buf[CONFIG_TINYUSB_CDC_RX_BUFSIZE + 1]; +static uint8_t rx_buf[CONFIG_TINYUSB_CDC_RX_BUFSIZE + 1]; +/** + * @brief Application Queue + */ +static QueueHandle_t app_queue; +typedef struct { + uint8_t buf[CONFIG_TINYUSB_CDC_RX_BUFSIZE + 1]; // Data buffer + size_t buf_len; // Number of bytes received + uint8_t itf; // Index of CDC device interface +} app_message_t; + +/** + * @brief CDC device RX callback + * + * CDC device signals, that new data were received + * + * @param[in] itf CDC device index + * @param[in] event CDC event type + */ void tinyusb_cdc_rx_callback(int itf, cdcacm_event_t *event) { /* initialization */ size_t rx_size = 0; /* read */ - esp_err_t ret = tinyusb_cdcacm_read(itf, buf, CONFIG_TINYUSB_CDC_RX_BUFSIZE, &rx_size); + esp_err_t ret = tinyusb_cdcacm_read(itf, rx_buf, CONFIG_TINYUSB_CDC_RX_BUFSIZE, &rx_size); if (ret == ESP_OK) { - ESP_LOGI(TAG, "Data from channel %d:", itf); - ESP_LOG_BUFFER_HEXDUMP(TAG, buf, rx_size, ESP_LOG_INFO); - } else { - ESP_LOGE(TAG, "Read error"); - } - /* write back */ - tinyusb_cdcacm_write_queue(itf, buf, rx_size); - tinyusb_cdcacm_write_flush(itf, 0); + app_message_t tx_msg = { + .buf_len = rx_size, + .itf = itf, + }; + + memcpy(tx_msg.buf, rx_buf, rx_size); + xQueueSend(app_queue, &tx_msg, 0); + } else { + ESP_LOGE(TAG, "Read Error"); + } } +/** + * @brief CDC device line change callback + * + * CDC device signals, that the DTR, RTS states changed + * + * @param[in] itf CDC device index + * @param[in] event CDC event type + */ void tinyusb_cdc_line_state_changed_callback(int itf, cdcacm_event_t *event) { int dtr = event->line_state_changed_data.dtr; @@ -43,6 +72,11 @@ void tinyusb_cdc_line_state_changed_callback(int itf, cdcacm_event_t *event) void app_main(void) { + // Create FreeRTOS primitives + app_queue = xQueueCreate(5, sizeof(app_message_t)); + assert(app_queue); + app_message_t msg; + ESP_LOGI(TAG, "USB initialization"); const tinyusb_config_t tusb_cfg = { .device_descriptor = NULL, @@ -86,4 +120,21 @@ void app_main(void) #endif ESP_LOGI(TAG, "USB initialization DONE"); + while (1) { + if (xQueueReceive(app_queue, &msg, portMAX_DELAY)) { + if (msg.buf_len) { + + /* Print received data*/ + ESP_LOGI(TAG, "Data from channel %d:", msg.itf); + ESP_LOG_BUFFER_HEXDUMP(TAG, msg.buf, msg.buf_len, ESP_LOG_INFO); + + /* write back */ + tinyusb_cdcacm_write_queue(msg.itf, msg.buf, msg.buf_len); + esp_err_t err = tinyusb_cdcacm_write_flush(msg.itf, 0); + if (err != ESP_OK) { + ESP_LOGE(TAG, "CDC ACM write flush error: %s", esp_err_to_name(err)); + } + } + } + } }