atomvm / AtomVM

Tiny Erlang VM
https://www.atomvm.net
Apache License 2.0
1.42k stars 93 forks source link

Use on-chip usb interface for console I/O for the esp32 s2 #1190

Open schnef opened 2 weeks ago

schnef commented 2 weeks ago

The esp32 s2 has an on-chip usb interface used for flashing applications, among other things. For console I/O, UART0 is used. It would be very convenient if the USB interface is also used for console I/O because firstly it makes an external connection much easier and secondly because on development boards such as the wemos lolin s2 mini and pico, UART0 is not implemented on the pin headers. As far as I understood it should use softserial for the usb interface? The wemos s2 mini board uses the USB interface as described here

It concerns the development board wemos S2 mini Chip ESP32-S2FN4R2 Board schematics:

bettio commented 2 weeks ago

can you share any log (such as the bootloader log) or some more details about what are you doing and it is not working?

pguyot commented 1 week ago

I eventually got hold of this board. It is indeed very different from the other ESP32 boards I have. The USB device appears after RST and 0 buttons are pressed and released. This allows to flash AtomVM or use rebar atomvm esp32_flash. However, after the tool is used, the following message is printed:

WARNING: ESP32-S2FNR2 (revision v1.0) chip was placed into download mode using GPIO0.
esptool.py can not exit the download mode over USB. To run the app, reset the chip manually.
To suppress this note, set --after option to 'no_reset'.

(including when using rebar plugin).

I confirm it works as I was able to run blinky with onboard LED on GPIO 15. But when AtomVM is running, the device doesn't appear on the USB bus.

Based on the documentation and an esp-idf example, the following patch enables serial interface on the board:

diff --git a/src/platforms/esp32/main/main.c b/src/platforms/esp32/main/main.c
index 4f651b8b..5d206843 100644
--- a/src/platforms/esp32/main/main.c
+++ b/src/platforms/esp32/main/main.c
@@ -37,6 +37,10 @@
 #include <term.h>
 #include <utils.h>

+#include "tinyusb.h"
+#include "tusb_cdc_acm.h"
+#include "tusb_console.h"
+
 #include "esp32_sys.h"

 #define TAG "AtomVM"
@@ -60,6 +64,31 @@ void app_main()
 {
     esp32_sys_queue_init();

+    /* Setting TinyUSB up */
+    ESP_LOGI(TAG, "USB initialization");
+
+    const tinyusb_config_t tusb_cfg = {
+        .device_descriptor = NULL,
+        .string_descriptor = NULL,
+        .external_phy = false, // In the most cases you need to use a `false` value
+#if (TUD_OPT_HIGH_SPEED)
+        .fs_configuration_descriptor = NULL,
+        .hs_configuration_descriptor = NULL,
+        .qualifier_descriptor = NULL,
+#else
+        .configuration_descriptor = NULL,
+#endif // TUD_OPT_HIGH_SPEED
+    };
+
+    ESP_ERROR_CHECK(tinyusb_driver_install(&tusb_cfg));
+
+    tinyusb_config_cdcacm_t acm_cfg = { 0 }; // the configuration uses default values
+    ESP_ERROR_CHECK(tusb_cdc_acm_init(&acm_cfg));
+
+    ESP_LOGI(TAG, "USB initialization DONE");
+
+    esp_tusb_init_console(TINYUSB_CDC_ACM_0); // log to usb
+
     fprintf(stdout, "%s", ATOMVM_BANNER);
     ESP_LOGI(TAG, "Starting AtomVM revision " ATOMVM_VERSION);

It requires esp_tinyusb (idf.py add-dependency esp_tinyusb) and also to enable CDC in menu config. With this, I can get the output of blinky. However, there is no monitor and minicom doesn't connect fast enough to see AtomVM banner. The port appears as /dev/cu.usbmodem1234561 as opposed to /dev/cu.usbmodem01 for flashing.

@bettio I'm not sure what we should do with this board, though.

UncleGrumpy commented 1 week ago

Is there a way to delay the startup to allow serial connections like we do for the rp2040 port? Maybe we just add a cmake build option for usb-serial. There are bound to be other boards in the future that rely on or support serial usb.

UncleGrumpy commented 1 week ago

I don't think we necessarily need to add this to the release matrix, we should just support the option and refer this to the build instructions as a special circumstance.

schnef commented 1 week ago

That's fast! I really appreciate your efforts! This is uncharted territory for me and I am very happy that a solution has been found.

schnef commented 5 days ago

Is there any more clarity on whether and how the problem can be solved? Many of the esp32 s2 boards, especially the cheaper ones, use the on-chip usb interface. I (we) would be greatly helped if I can use the existing usb interface.