From c3f374cdc7d19e28834aef06dadfe5cd6efd110d Mon Sep 17 00:00:00 2001 From: Clement_B Date: Fri, 31 Jan 2025 11:41:18 +0100 Subject: [PATCH] finish usb uart lib --- .vscode/settings.json | 56 ++++++++++++++- lib/SerialUSBHost/include/SerialUSBHost.h | 30 ++++++-- lib/SerialUSBHost/src/SerialUSBHost.cpp | 83 +++++++++++++---------- src/main.cpp | 45 +----------- 4 files changed, 130 insertions(+), 84 deletions(-) diff --git a/.vscode/settings.json b/.vscode/settings.json index c6b368b..21dac9a 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -1,6 +1,60 @@ { "files.associations": { "memory": "cpp", - "vector": "cpp" + "vector": "cpp", + "array": "cpp", + "atomic": "cpp", + "bit": "cpp", + "*.tcc": "cpp", + "cctype": "cpp", + "clocale": "cpp", + "cmath": "cpp", + "compare": "cpp", + "concepts": "cpp", + "condition_variable": "cpp", + "cstdarg": "cpp", + "cstddef": "cpp", + "cstdint": "cpp", + "cstdio": "cpp", + "cstdlib": "cpp", + "cstring": "cpp", + "ctime": "cpp", + "cwchar": "cpp", + "cwctype": "cpp", + "deque": "cpp", + "map": "cpp", + "set": "cpp", + "string": "cpp", + "unordered_map": "cpp", + "exception": "cpp", + "algorithm": "cpp", + "functional": "cpp", + "iterator": "cpp", + "memory_resource": "cpp", + "numeric": "cpp", + "random": "cpp", + "ratio": "cpp", + "string_view": "cpp", + "system_error": "cpp", + "tuple": "cpp", + "type_traits": "cpp", + "utility": "cpp", + "initializer_list": "cpp", + "iosfwd": "cpp", + "iostream": "cpp", + "istream": "cpp", + "limits": "cpp", + "mutex": "cpp", + "new": "cpp", + "numbers": "cpp", + "ostream": "cpp", + "semaphore": "cpp", + "sstream": "cpp", + "stdexcept": "cpp", + "stop_token": "cpp", + "streambuf": "cpp", + "thread": "cpp", + "cinttypes": "cpp", + "typeinfo": "cpp" } } \ No newline at end of file diff --git a/lib/SerialUSBHost/include/SerialUSBHost.h b/lib/SerialUSBHost/include/SerialUSBHost.h index 8448097..1d9605e 100644 --- a/lib/SerialUSBHost/include/SerialUSBHost.h +++ b/lib/SerialUSBHost/include/SerialUSBHost.h @@ -23,20 +23,40 @@ public: SerialUSBHost() = delete; static void init(uint32_t baudrate, uint8_t stop_bits, uint8_t parity, uint8_t dataBits); + +private: + /** + * @brief Device event callback + * + * Apart from handling device disconnection it doesn't do anything useful + * + * @param[in] event Device event type and data + * @param[in] user_ctx Argument we passed to the device open function + */ static void handle_event(const cdc_acm_host_dev_event_data_t *event, void *user_ctx); + + /** + * @brief Data received callback + * + * Just pass received data to stdout + * + * @param[in] data Pointer to received data + * @param[in] data_len Length of received data in bytes + * @param[in] arg Argument we passed to the device open function + * @return + * true: We have processed the received data + * false: We expect more data + */ static bool handle_rx(const uint8_t *data, size_t data_len, void *arg); - static void takeSem();//XXX - - static cdc_acm_host_device_config_t* getDevConfig(); - static cdc_acm_line_coding_t* getLineCoding(); -private: /** * @brief USB Host library handling task * * @param arg unused but required for task */ static void usb_lib_task(void* arg); + static void mainTask(void* arg); + }; diff --git a/lib/SerialUSBHost/src/SerialUSBHost.cpp b/lib/SerialUSBHost/src/SerialUSBHost.cpp index 8030f91..edb8f6d 100644 --- a/lib/SerialUSBHost/src/SerialUSBHost.cpp +++ b/lib/SerialUSBHost/src/SerialUSBHost.cpp @@ -18,35 +18,16 @@ static cdc_acm_line_coding_t line_coding; static const char *TAG = "VCP example"; -/** - * @brief Data received callback - * - * Just pass received data to stdout - * - * @param[in] data Pointer to received data - * @param[in] data_len Length of received data in bytes - * @param[in] arg Argument we passed to the device open function - * @return - * true: We have processed the received data - * false: We expect more data - */ bool SerialUSBHost::handle_rx(const uint8_t *data, size_t data_len, void *arg) { //ESP_LOGI("USB_HANDLE", "Recivend data !!"); - printf("%.*s", data_len, data); + printf("%.*s", data_len, data); //BUG remouve debug return true; } -/** - * @brief Device event callback - * - * Apart from handling device disconnection it doesn't do anything useful - * - * @param[in] event Device event type and data - * @param[in] user_ctx Argument we passed to the device open function - */ void SerialUSBHost::handle_event(const cdc_acm_host_dev_event_data_t *event, void *user_ctx) { + static const char *TAG = "handle_event"; switch (event->type) { case CDC_ACM_HOST_ERROR: ESP_LOGE(TAG, "CDC-ACM error has occurred, err_no = %d", event->data.error); @@ -64,7 +45,7 @@ void SerialUSBHost::handle_event(const cdc_acm_host_dev_event_data_t *event, voi } void SerialUSBHost::usb_lib_task(void* arg) { - const String TAG = "SerialUSBHost_usb_lib_task"; + static const char *TAG = "SerialUSBHost_usb_lib_task"; while (1) { // Start handling system events uint32_t event_flags; @@ -73,19 +54,19 @@ void SerialUSBHost::usb_lib_task(void* arg) { ESP_ERROR_CHECK(usb_host_device_free_all()); } if (event_flags & USB_HOST_LIB_EVENT_FLAGS_ALL_FREE) { - ESP_LOGI(TAG.c_str(), "USB: All devices freed"); + ESP_LOGI(TAG, "USB: All devices freed"); // Continue handling USB events to allow device reconnection } } } void SerialUSBHost::init(uint32_t baudrate, uint8_t stop_bits, uint8_t parity, uint8_t dataBits) { - const String TAG = "SerialUSBHost_constructor"; + static const char *TAG = "SerialUSBHost_constructor"; device_disconnected_sem = xSemaphoreCreateBinary(); assert(device_disconnected_sem); // Install USB Host driver. Should only be called once in entire application - ESP_LOGI(TAG.c_str(), "Installing USB Host"); + ESP_LOGI(TAG, "Installing USB Host"); const usb_host_config_t host_config = { .skip_phy_setup = false, .intr_flags = ESP_INTR_FLAG_LEVEL1, @@ -97,7 +78,7 @@ void SerialUSBHost::init(uint32_t baudrate, uint8_t stop_bits, uint8_t parity, u BaseType_t task_created = xTaskCreate(SerialUSBHost::usb_lib_task, "usb_lib", 4096, NULL, 10, NULL); assert(task_created == pdTRUE); - ESP_LOGI(TAG.c_str(), "Installing CDC-ACM driver"); + ESP_LOGI(TAG, "Installing CDC-ACM driver"); ESP_ERROR_CHECK(cdc_acm_host_install(NULL)); // Register VCP drivers to VCP service @@ -105,21 +86,53 @@ void SerialUSBHost::init(uint32_t baudrate, uint8_t stop_bits, uint8_t parity, u esp_usb::VCP::register_driver(); esp_usb::VCP::register_driver(); - line_coding.dwDTERate = baudrate; line_coding.bCharFormat = stop_bits; line_coding.bParityType = parity; line_coding.bDataBits = dataBits; + + BaseType_t mainTask = xTaskCreate(SerialUSBHost::mainTask, "main usb task", 4096, NULL, 5, NULL); + assert(mainTask == pdTRUE); } -void SerialUSBHost::takeSem() {//XXX - xSemaphoreTake(device_disconnected_sem, portMAX_DELAY); +void SerialUSBHost::mainTask(void* arg) { + while (1) + { + // You don't need to know the device's VID and PID. Just plug in any device and the VCP service will load correct (already registered) driver for the device + ESP_LOGI(TAG, "Opening any VCP device..."); + auto vcp = std::unique_ptr(esp_usb::VCP::open(&dev_config)); + + if (vcp == nullptr) { + ESP_LOGI(TAG, "Failed to open VCP device"); + return; + // continue; + } + vTaskDelay(10); + + ESP_LOGI(TAG, "Setting up line coding"); + + ESP_ERROR_CHECK(vcp->line_coding_set(&line_coding)); + + /* + Now the USB-to-UART converter is configured and receiving data. + You can use standard CDC-ACM API to interact with it. E.g. + + ESP_ERROR_CHECK(vcp->set_control_line_state(false, true)); + ESP_ERROR_CHECK(vcp->tx_blocking((uint8_t *)"Test string", 12)); + */ + + // Send some dummy data + ESP_LOGI(TAG, "Sending data through CdcAcmDevice"); + uint8_t data[] = "test_string"; + ESP_ERROR_CHECK(vcp->tx_blocking(data, sizeof(data))); + ESP_ERROR_CHECK(vcp->set_control_line_state(true, true)); + + // We are done. Wait for device disconnection and start over + ESP_LOGI(TAG, "Done. You can reconnect the VCP device to run again."); + + xSemaphoreTake(device_disconnected_sem, portMAX_DELAY); + } } -cdc_acm_host_device_config_t* SerialUSBHost::getDevConfig() { - return &dev_config; -} -cdc_acm_line_coding_t* SerialUSBHost::getLineCoding() { - return &line_coding; -} +//TODO: faire une fontion pour savoir si un usb est connecter diff --git a/src/main.cpp b/src/main.cpp index d6b1c77..86e7ce5 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1,60 +1,19 @@ #include "Arduino.h" -#include -#include - - #include "SerialUSBHost.h" -using namespace esp_usb; - // Change these values to match your needs #define EXAMPLE_BAUDRATE (115200) #define EXAMPLE_STOP_BITS (0) // 0: 1 stopbit, 1: 1.5 stopbits, 2: 2 stopbits #define EXAMPLE_PARITY (0) // 0: None, 1: Odd, 2: Even, 3: Mark, 4: Space #define EXAMPLE_DATA_BITS (8) -static const char *TAG = "VCP example"; - +static const char *TAG = "MAIN"; void setup() { SerialUSBHost::init(EXAMPLE_BAUDRATE, EXAMPLE_STOP_BITS, EXAMPLE_PARITY, EXAMPLE_DATA_BITS); } - void loop() { - - // You don't need to know the device's VID and PID. Just plug in any device and the VCP service will load correct (already registered) driver for the device - ESP_LOGI(TAG, "Opening any VCP device..."); - auto vcp = std::unique_ptr(VCP::open(SerialUSBHost::getDevConfig())); - - if (vcp == nullptr) { - ESP_LOGI(TAG, "Failed to open VCP device"); - return; - // continue; - } - vTaskDelay(10); - - ESP_LOGI(TAG, "Setting up line coding"); - - ESP_ERROR_CHECK(vcp->line_coding_set(SerialUSBHost::getLineCoding())); - - /* - Now the USB-to-UART converter is configured and receiving data. - You can use standard CDC-ACM API to interact with it. E.g. - - ESP_ERROR_CHECK(vcp->set_control_line_state(false, true)); - ESP_ERROR_CHECK(vcp->tx_blocking((uint8_t *)"Test string", 12)); - */ - - // Send some dummy data - ESP_LOGI(TAG, "Sending data through CdcAcmDevice"); - uint8_t data[] = "test_string"; - ESP_ERROR_CHECK(vcp->tx_blocking(data, sizeof(data))); - ESP_ERROR_CHECK(vcp->set_control_line_state(true, true)); - - // We are done. Wait for device disconnection and start over - ESP_LOGI(TAG, "Done. You can reconnect the VCP device to run again."); - - SerialUSBHost::takeSem(); + vTaskDelay(pdMS_TO_TICKS(10)); }