Skip to content

Esp32s3 usbserial interface#5200

Merged
deadprogram merged 4 commits intotinygo-org:devfrom
dimajolkin:esp32s3-usbserial
Feb 17, 2026
Merged

Esp32s3 usbserial interface#5200
deadprogram merged 4 commits intotinygo-org:devfrom
dimajolkin:esp32s3-usbserial

Conversation

@dimajolkin
Copy link
Copy Markdown
Contributor

@dimajolkin dimajolkin commented Feb 15, 2026

The ability to output data directly to usbserial has been added to simplify development.
I changed the default serial to usb, it seems to be more convenient for these boards)

image

tested: esp32s3 & esp32s3-wroom1

@deadprogram
Copy link
Copy Markdown
Member

deadprogram commented Feb 16, 2026

Hello @dimajolkin thanks for another cool missing feature.

I was looking at the device files for the esp32c3 and noticed that the USB_DEVICE_Type is exactly the same for both the esp32c3 and esp32s3. Perhaps you would like to modify this PR so it can accommodate both processors?

What do you think?

@dimajolkin
Copy link
Copy Markdown
Contributor Author

I'll try to do something about it)

@deadprogram
Copy link
Copy Markdown
Member

I have both boards for testing! 😸

@dimajolkin
Copy link
Copy Markdown
Contributor Author

I have ESP32C3 and ESP32C6 for testing)

@dimajolkin
Copy link
Copy Markdown
Contributor Author

I don't know why I bought them, but they will come in handy)

@deadprogram
Copy link
Copy Markdown
Member

I also have a C6, so we have several of the most recent vintage processors.

@dimajolkin
Copy link
Copy Markdown
Contributor Author

I think it was a good idea to split it, it turned out nice)

@dimajolkin
Copy link
Copy Markdown
Contributor Author

I don't see support for the esp32c6 right now. Let's add issus to my account, I'll be able to add it. But only after the I2C implementation for the esp32s3 is it really necessary.

@deadprogram
Copy link
Copy Markdown
Member

Looking at the changed files, it really looks even more like the USB implementation from the c3 would "just work" on the s3. Also it has ReadByte() implementation.

Probably rolling them together into single file machine_esp32xx_usb.go or something like that would be the most efficient?

@dimajolkin
Copy link
Copy Markdown
Contributor Author

I think I know what you're talking about, I'll double-check.. I'll try to make a common implementation. Thanks for the review, I didn't notice)

@dimajolkin
Copy link
Copy Markdown
Contributor Author

It worked for both, which is nice. Although I definitely tested it and the basic implementation didn't work) A lot of time wasted))

@deadprogram
Copy link
Copy Markdown
Member

Good news: println() works exactly as expected on both s3 and c3. 🥳

Not as good news: seems like machine.InitSerial() is not getting called in the correct order, since machine.Serial is not getting initialized at the same time as it should be. That is not a new problem, the existing c3 implementation has that problem already.

You can see this in action by running the examples/echo which panics on the first call to the uart variable.

It would be great to also correct that problem now, if we can. 🔎

@deadprogram
Copy link
Copy Markdown
Member

I added this additional patch to your PR, and it appears to address that problem:

diff --git a/src/runtime/runtime_esp32c3.go b/src/runtime/runtime_esp32c3.go
index 013c9392..e61cb989 100644
--- a/src/runtime/runtime_esp32c3.go
+++ b/src/runtime/runtime_esp32c3.go
@@ -54,10 +54,6 @@ func main() {
        // Configure interrupt handler
        interruptInit()
 
-       // Initialize UART.
-       machine.USBCDC.Configure(machine.UARTConfig{})
-       machine.InitSerial()
-
        // Initialize main system timer used for time.Now.
        initTimer()
 
@@ -68,6 +64,10 @@ func main() {
        exit(0)
 }
 
+func init() {
+       machine.InitSerial()
+}
+
 func abort() {
        // lock up forever
        for {
diff --git a/src/runtime/runtime_esp32s3.go b/src/runtime/runtime_esp32s3.go
index ab0d85d7..581a4bfc 100644
--- a/src/runtime/runtime_esp32s3.go
+++ b/src/runtime/runtime_esp32s3.go
@@ -72,9 +72,6 @@ func main() {
                clearbss()
        }
 
-       // Initialize UART.
-       machine.InitSerial()
-
        // Initialize main system timer used for time.Now.
        initTimer()
 
@@ -85,6 +82,10 @@ func main() {
        exit(0)
 }
 
+func init() {
+       machine.InitSerial()
+}
+
 func abort() {
        // lock up forever
        print("abort called\n")

@dimajolkin
Copy link
Copy Markdown
Contributor Author

Yes! It's worked) Thanks!) Tested on esp32c3, esp32s3, esp32s3-wroom1

@deadprogram
Copy link
Copy Markdown
Member

Thanks again for working on this @dimajolkin now merging!

@deadprogram deadprogram merged commit 610dd19 into tinygo-org:dev Feb 17, 2026
19 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants