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
This commit is contained in:
Peter Marcisovsky 2024-06-03 11:05:46 +02:00
parent 55d4de5129
commit d8d92c1928
2 changed files with 122 additions and 20 deletions

View File

@ -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));
}
}
}
}
}

View File

@ -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));
}
}
}
}
}