From c72d70b579ee50b5417d53e57ca97e3232ae8141 Mon Sep 17 00:00:00 2001 From: aburt2 <32888184+aburt2@users.noreply.github.com> Date: Wed, 29 Nov 2023 01:20:16 -0500 Subject: [PATCH 1/4] added basic support for USB CDC monitor for ESP32S3 devices --- puara.cpp | 96 +++++++++++++++++++++++++++++++++++++++++++++++++++++-- puara.h | 14 +++++++- 2 files changed, 106 insertions(+), 4 deletions(-) diff --git a/puara.cpp b/puara.cpp index 5ff56d3..0230f0d 100644 --- a/puara.cpp +++ b/puara.cpp @@ -1269,7 +1269,7 @@ void Puara::interpret_serial(void *pvParameters) { } } - void Puara::serial_monitor(void *pvParameters) { + void Puara::uart_monitor(void *pvParameters) { const int uart_num0 = 0; //UART port 0 uart_config_t uart_config0 = { .baud_rate = 115200, @@ -1301,10 +1301,100 @@ void Puara::interpret_serial(void *pvParameters) { } } + void Puara::jtag_monitor(void *pvParameters) { + // Setup USB CDC Monitor, code based on advanced example from ESP-IDF Repsitory + // https://github.com/espressif/esp-idf/blob/master/examples/system/console/advanced_usb_cdc/main/console_usb_example_main.c + + /* Disable buffering on stdin */ + setvbuf(stdin, NULL, _IONBF, 0); + + /* Minicom, screen, idf_monitor send CR when ENTER key is pressed */ + esp_vfs_dev_cdcacm_set_rx_line_endings(ESP_LINE_ENDINGS_CR); + /* Move the caret to the beginning of the next line on '\n' */ + esp_vfs_dev_cdcacm_set_tx_line_endings(ESP_LINE_ENDINGS_CRLF); + + /* Enable non-blocking mode on stdin and stdout */ + fcntl(fileno(stdout), F_SETFL, 0); + fcntl(fileno(stdin), F_SETFL, 0); + + /* Initialize the console */ + esp_console_config_t console_config = { + .max_cmdline_args = 8, + .max_cmdline_length = 256, + #if CONFIG_LOG_COLORS + .hint_color = atoi(LOG_COLOR_CYAN) + #endif + }; + ESP_ERROR_CHECK( esp_console_init(&console_config) ); + + /* Configure linenoise line completion library */ + /* Enable multiline editing. If not set, long commands will scroll within + * single line. + */ + linenoiseSetMultiLine(1); + + /* Tell linenoise where to get command completions and hints */ + linenoiseSetCompletionCallback(&esp_console_get_completion); + linenoiseSetHintsCallback((linenoiseHintsCallback*) &esp_console_get_hint); + + /* Set command history size */ + linenoiseHistorySetMaxLen(10); + + // Prompt + const char* prompt = LOG_COLOR_I CONFIG_IDF_TARGET "> " LOG_RESET_COLOR; + + // Register some common commands + register_system_sleep(); + register_restart(); + + // Register puara specific commands + // esp_console_cmd_register(); ping + // esp_console_cmd_register(); whatareyou + // esp_console_cmd_register(); sendconfig + // esp_console_cmd_register(); writeconfig + // esp_console_cmd_register(); readconfig + // esp_console_cmd_register(); sendsettings + // esp_console_cmd_register(); writesettings + // esp_console_cmd_register(); readsettings + + while(1) { + /* Get a line using linenoise. + * The line is returned when ENTER is pressed. + */ + char* line = linenoise(prompt); + if (line == NULL) { /* Ignore empty lines */ + continue; + } + /* Add the command to the history */ + linenoiseHistoryAdd(line); + + /* Try to run the command */ + int ret; + esp_err_t err = esp_console_run(line, &ret); + if (err == ESP_ERR_NOT_FOUND) { + printf("Unrecognized command\n"); + } else if (err == ESP_ERR_INVALID_ARG) { + // command was empty + } else if (err == ESP_OK && ret != ESP_OK) { + printf("Command returned non-zero error code: 0x%x (%s)\n", ret, esp_err_to_name(ret)); + } else if (err != ESP_OK) { + printf("Internal error: %s\n", esp_err_to_name(err)); + } + + /* linenoise allocates line buffer on the heap, so need to free it */ + linenoiseFree(line); + } + } + bool Puara::start_serial_listening() { //std::cout << "starting serial monitor \n"; - xTaskCreate(serial_monitor, "serial_monitor", 2048, NULL, 10, NULL); - xTaskCreate(interpret_serial, "interpret_serial", 4096, NULL, 10, NULL); + if (puara.module_monitor = UART) { + xTaskCreate(uart_monitor, "serial_monitor", 2048, NULL, 10, NULL); + xTaskCreate(interpret_serial, "interpret_serial", 4096, NULL, 10, NULL); + } else if (puara.module_monitor = JTAG) { + xTaskCreate(jtag_monitor, "serial_monitor", 2048, NULL, 10, NULL); + xTaskCreate(interpret_serial, "interpret_serial", 4096, NULL, 10, NULL); + } return 1; } diff --git a/puara.h b/puara.h index 0e49296..c9b7e3c 100644 --- a/puara.h +++ b/puara.h @@ -44,6 +44,8 @@ #include #include #include +#include "esp_console.h" +#include "linenoise/linenoise.h" class Puara { @@ -141,7 +143,8 @@ class Puara { static std::string serial_config_str; static std::string convertToString(char* a); static void interpret_serial(void *pvParameters); - static void serial_monitor(void *pvParameters); + static void uart_monitor(void *pvParameters); + static void jtag_monitor(void *pvParameters); static const int reboot_delay = 3000; static void reboot_with_delay(void *pvParameter); static std::string urlDecode(std::string text); @@ -181,6 +184,15 @@ class Puara { static std::string getVarText(std::string varName); static bool IP1_ready(); static bool IP2_ready(); + + // Monitor types + enum Monitors { + UART 0, + JTAG 1 + }; + + // Set default monitor as UART + module_monitor = UART; }; #endif \ No newline at end of file From 964b2ebd136e2bee8f455deb0178bd94bad89711 Mon Sep 17 00:00:00 2001 From: aburt2 <32888184+aburt2@users.noreply.github.com> Date: Wed, 29 Nov 2023 01:28:08 -0500 Subject: [PATCH 2/4] added usb monitor type as well --- puara.cpp | 3 +-- puara.h | 3 ++- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/puara.cpp b/puara.cpp index 0230f0d..3819ee8 100644 --- a/puara.cpp +++ b/puara.cpp @@ -1391,9 +1391,8 @@ void Puara::interpret_serial(void *pvParameters) { if (puara.module_monitor = UART) { xTaskCreate(uart_monitor, "serial_monitor", 2048, NULL, 10, NULL); xTaskCreate(interpret_serial, "interpret_serial", 4096, NULL, 10, NULL); - } else if (puara.module_monitor = JTAG) { + } else if ((puara.module_monitor = JTAG) || (puara.module_monitor = USB)) { xTaskCreate(jtag_monitor, "serial_monitor", 2048, NULL, 10, NULL); - xTaskCreate(interpret_serial, "interpret_serial", 4096, NULL, 10, NULL); } return 1; } diff --git a/puara.h b/puara.h index c9b7e3c..323be48 100644 --- a/puara.h +++ b/puara.h @@ -188,7 +188,8 @@ class Puara { // Monitor types enum Monitors { UART 0, - JTAG 1 + JTAG 1, + USB 2 }; // Set default monitor as UART From 97a36588942492136756cbc124430afdcca27346 Mon Sep 17 00:00:00 2001 From: aburt2 <32888184+aburt2@users.noreply.github.com> Date: Wed, 29 Nov 2023 17:01:08 -0500 Subject: [PATCH 3/4] fixed syntax errors, added jtag driver library --- puara.cpp | 139 ++++++++++++++++++++++-------------------------------- puara.h | 22 +++++---- 2 files changed, 69 insertions(+), 92 deletions(-) diff --git a/puara.cpp b/puara.cpp index 3819ee8..bc4eb10 100644 --- a/puara.cpp +++ b/puara.cpp @@ -81,11 +81,10 @@ char Puara::serial_data[PUARA_SERIAL_BUFSIZE]; int Puara::serial_data_length; std::string Puara::serial_data_str; std::string Puara::serial_data_str_buffer; - +int Puara::module_monitor = UART_MONITOR; const std::string Puara::data_start = "<<<"; const std::string Puara::data_end = ">>>"; - unsigned int Puara::get_version() { return version; }; @@ -94,7 +93,7 @@ void Puara::set_version(unsigned int user_version) { version = user_version; }; -void Puara::start() { +void Puara::start(Monitors monitor) { std::cout << "\n" << "**********************************************************\n" @@ -113,6 +112,8 @@ void Puara::start() { start_webserver(); start_mdns_service(dmiName, dmiName); wifi_scan(); + + module_monitor = monitor; // some delay added as start listening blocks the hw monitor std::cout << "Starting serial monitor..." << std::endl; @@ -1302,97 +1303,71 @@ void Puara::interpret_serial(void *pvParameters) { } void Puara::jtag_monitor(void *pvParameters) { - // Setup USB CDC Monitor, code based on advanced example from ESP-IDF Repsitory - // https://github.com/espressif/esp-idf/blob/master/examples/system/console/advanced_usb_cdc/main/console_usb_example_main.c - - /* Disable buffering on stdin */ - setvbuf(stdin, NULL, _IONBF, 0); - - /* Minicom, screen, idf_monitor send CR when ENTER key is pressed */ - esp_vfs_dev_cdcacm_set_rx_line_endings(ESP_LINE_ENDINGS_CR); - /* Move the caret to the beginning of the next line on '\n' */ - esp_vfs_dev_cdcacm_set_tx_line_endings(ESP_LINE_ENDINGS_CRLF); - - /* Enable non-blocking mode on stdin and stdout */ - fcntl(fileno(stdout), F_SETFL, 0); - fcntl(fileno(stdin), F_SETFL, 0); - - /* Initialize the console */ - esp_console_config_t console_config = { - .max_cmdline_args = 8, - .max_cmdline_length = 256, - #if CONFIG_LOG_COLORS - .hint_color = atoi(LOG_COLOR_CYAN) - #endif + // Setup jtag module for USB Serial reads + usb_serial_jtag_driver_config_t jtag_config { + .tx_buffer_size = 256, + .rx_buffer_size = 256, }; - ESP_ERROR_CHECK( esp_console_init(&console_config) ); - - /* Configure linenoise line completion library */ - /* Enable multiline editing. If not set, long commands will scroll within - * single line. - */ - linenoiseSetMultiLine(1); - - /* Tell linenoise where to get command completions and hints */ - linenoiseSetCompletionCallback(&esp_console_get_completion); - linenoiseSetHintsCallback((linenoiseHintsCallback*) &esp_console_get_hint); - - /* Set command history size */ - linenoiseHistorySetMaxLen(10); - - // Prompt - const char* prompt = LOG_COLOR_I CONFIG_IDF_TARGET "> " LOG_RESET_COLOR; - - // Register some common commands - register_system_sleep(); - register_restart(); - - // Register puara specific commands - // esp_console_cmd_register(); ping - // esp_console_cmd_register(); whatareyou - // esp_console_cmd_register(); sendconfig - // esp_console_cmd_register(); writeconfig - // esp_console_cmd_register(); readconfig - // esp_console_cmd_register(); sendsettings - // esp_console_cmd_register(); writesettings - // esp_console_cmd_register(); readsettings + + // Install jtag module + usb_serial_jtag_driver_install(&jtag_config); while(1) { - /* Get a line using linenoise. - * The line is returned when ENTER is pressed. - */ - char* line = linenoise(prompt); - if (line == NULL) { /* Ignore empty lines */ - continue; - } - /* Add the command to the history */ - linenoiseHistoryAdd(line); - - /* Try to run the command */ - int ret; - esp_err_t err = esp_console_run(line, &ret); - if (err == ESP_ERR_NOT_FOUND) { - printf("Unrecognized command\n"); - } else if (err == ESP_ERR_INVALID_ARG) { - // command was empty - } else if (err == ESP_OK && ret != ESP_OK) { - printf("Command returned non-zero error code: 0x%x (%s)\n", ret, esp_err_to_name(ret)); - } else if (err != ESP_OK) { - printf("Internal error: %s\n", esp_err_to_name(err)); + // serial_data_length = USBSerial.read(); + // Only read if connected to PC + serial_data_length = usb_serial_jtag_read_bytes(serial_data, PUARA_SERIAL_BUFSIZE, 500 / portTICK_RATE_MS); + if (serial_data_length > 0) { + serial_data_str = convertToString(serial_data); + // remove new line character at end + if (serial_data_str[serial_data_str.size() - 1] == '\n') + serial_data_str.erase(serial_data_str.size() - 1); + if (serial_data_str[serial_data_str.size() - 1] == '\r') + serial_data_str.erase(serial_data_str.size() - 1); + memset(serial_data, 0, sizeof serial_data); } - - /* linenoise allocates line buffer on the heap, so need to free it */ - linenoiseFree(line); } } + void Puara::usb_monitor(void *pvParameters) { + // // Setup usb module for USB reads + // const char *product_name = dmiName.c_str(); + // const char *manufacturer_name = author.c_str(); + + // tinyusb_device_config_t usb_config = { + // .vid = USB_ESPRESSIF_VID, + // .pid = 0x0002, + // .product_name = product_name, + // .manufacturer_name = manufacturer_name, + // .serial_number = product_name, + // .fw_version = version, + // .usb_version = 0x0200, + // .usb_class = TUSB_CLASS_MISC, + // .usb_subclass = MISC_SUBCLASS_COMMON, + // .usb_protocol = MISC_PROTOCOL_IAD, + // .usb_attributes = TUSB_DESC_CONFIG_ATT_SELF_POWERED, + // .usb_power_ma = 500, + // .webusb_enabled = false, + // .webusb_url = "espressif.github.io/arduino-esp32/webusb.html" + // }; + + // // Setup USB interface + // tinyusb_init(&usb_config); + // TODO: Read from USB interface + } + bool Puara::start_serial_listening() { //std::cout << "starting serial monitor \n"; - if (puara.module_monitor = UART) { + if (module_monitor = UART_MONITOR) { xTaskCreate(uart_monitor, "serial_monitor", 2048, NULL, 10, NULL); xTaskCreate(interpret_serial, "interpret_serial", 4096, NULL, 10, NULL); - } else if ((puara.module_monitor = JTAG) || (puara.module_monitor = USB)) { + } else if (module_monitor = JTAG_MONITOR) { xTaskCreate(jtag_monitor, "serial_monitor", 2048, NULL, 10, NULL); + xTaskCreate(interpret_serial, "interpret_serial", 4096, NULL, 10, NULL); + } else if (module_monitor = USB_MONITOR) { + xTaskCreate(usb_monitor, "serial_monitor", 2048, NULL, 10, NULL); + xTaskCreate(interpret_serial, "interpret_serial", 4096, NULL, 10, NULL); + } else { + std::cout << "Invalid Monitor Type" << std::endl; } return 1; } diff --git a/puara.h b/puara.h index 323be48..1544ea3 100644 --- a/puara.h +++ b/puara.h @@ -33,6 +33,7 @@ #include #include #include +#include // jtag module #include // The following libraries need to be included if using the espidf framework: @@ -45,7 +46,7 @@ #include #include #include "esp_console.h" -#include "linenoise/linenoise.h" +#include "esp32-hal-tinyusb.h" class Puara { @@ -145,12 +146,20 @@ class Puara { static void interpret_serial(void *pvParameters); static void uart_monitor(void *pvParameters); static void jtag_monitor(void *pvParameters); + static void usb_monitor(void *pvParameters); static const int reboot_delay = 3000; static void reboot_with_delay(void *pvParameter); static std::string urlDecode(std::string text); public: - static void start(); + // Monitor types + enum Monitors { + UART_MONITOR = 0, + JTAG_MONITOR = 1, + USB_MONITOR = 2 + }; + + static void start(Monitors monitor = UART_MONITOR); static void config_spiffs(); static httpd_handle_t start_webserver(void); static void stop_webserver(void); @@ -185,15 +194,8 @@ class Puara { static bool IP1_ready(); static bool IP2_ready(); - // Monitor types - enum Monitors { - UART 0, - JTAG 1, - USB 2 - }; - // Set default monitor as UART - module_monitor = UART; + static int module_monitor; }; #endif \ No newline at end of file From 203bc74e8515b8d96dd22f793334137fe135e559 Mon Sep 17 00:00:00 2001 From: aburt2 <32888184+aburt2@users.noreply.github.com> Date: Wed, 29 Nov 2023 17:03:22 -0500 Subject: [PATCH 4/4] add print out to show USB monitor support not yet implemented --- puara.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/puara.cpp b/puara.cpp index bc4eb10..1a0c991 100644 --- a/puara.cpp +++ b/puara.cpp @@ -1353,6 +1353,7 @@ void Puara::interpret_serial(void *pvParameters) { // // Setup USB interface // tinyusb_init(&usb_config); // TODO: Read from USB interface + std::cout << "USB OTG monitor not supported, use the USB Serial JTAG or UART interface" << std::endl; } bool Puara::start_serial_listening() {