From 9bbad6700b3b17ad4fe9709f1d4138cd17111b48 Mon Sep 17 00:00:00 2001 From: Dima Jolkin Date: Sun, 15 Feb 2026 21:11:41 +0200 Subject: [PATCH] esp32s3-usbserial: added usbserial printing --- src/machine/machine_esp32s3.go | 88 +++++++++++++++++++++++++++++++++- src/runtime/runtime_esp32s3.go | 4 ++ targets/esp32s3.json | 2 +- 3 files changed, 92 insertions(+), 2 deletions(-) diff --git a/src/machine/machine_esp32s3.go b/src/machine/machine_esp32s3.go index 65261bd3c..9c2bd9001 100644 --- a/src/machine/machine_esp32s3.go +++ b/src/machine/machine_esp32s3.go @@ -309,4 +309,90 @@ func (uart *UART) writeByte(b byte) error { func (uart *UART) flush() {} -// TODO: SPI +// USB Serial/JTAG Controller for ESP32-S3 +type USB_DEVICE struct { + Bus *esp.USB_DEVICE_Type +} + +var ( + _USBCDC = &USB_DEVICE{ + Bus: esp.USB_DEVICE, + } + + USBCDC Serialer = _USBCDC +) + +func initUSB() { + USBCDC.Configure(UARTConfig{BaudRate: 115200}) +} + +type Serialer interface { + WriteByte(c byte) error + Write(data []byte) (n int, err error) + Configure(config UARTConfig) error + Buffered() int + ReadByte() (byte, error) + DTR() bool + RTS() bool +} + +func (usbdev *USB_DEVICE) Configure(config UARTConfig) error { + return nil +} + +func (usbdev *USB_DEVICE) WriteByte(c byte) error { + // Host is connected - wait for TX FIFO space with reasonable timeout + timeout := 10000 // Generous timeout for connected host + for usbdev.Bus.GetEP1_CONF_SERIAL_IN_EP_DATA_FREE() == 0 && timeout > 0 { + timeout-- + } + + // Even with host connected, don't hang forever + if timeout == 0 { + return nil + } + + // Write byte to USB Serial/JTAG endpoint + usbdev.Bus.SetEP1_RDWR_BYTE(uint32(c)) + + // Trigger transmission + usbdev.Bus.SetEP1_CONF_WR_DONE(1) + + return nil +} + +func (usbdev *USB_DEVICE) Write(data []byte) (n int, err error) { + for _, c := range data { + err = usbdev.WriteByte(c) + if err != nil { + return n, err + } + n++ + } + return n, nil +} + +func (usbdev *USB_DEVICE) ReadByte() (byte, error) { + // TODO: Implement USB Serial/JTAG input reading + return 0, errors.New("ReadByte not implemented") +} + +func (usbdev *USB_DEVICE) Buffered() int { + // Return number of bytes available to read + return int(usbdev.Bus.GetEP1_CONF_SERIAL_OUT_EP_DATA_AVAIL()) +} + +func (usbdev *USB_DEVICE) DTR() bool { + // Data Terminal Ready - not applicable for USB Serial/JTAG + return false +} + +func (usbdev *USB_DEVICE) RTS() bool { + // Request To Send - not applicable for USB Serial/JTAG + return false +} + +func (usbdev *USB_DEVICE) flush() { + // Force transmission of any buffered data + usbdev.Bus.SetEP1_CONF_WR_DONE(1) +} diff --git a/src/runtime/runtime_esp32s3.go b/src/runtime/runtime_esp32s3.go index 5a612d6df..ab0d85d73 100644 --- a/src/runtime/runtime_esp32s3.go +++ b/src/runtime/runtime_esp32s3.go @@ -4,6 +4,7 @@ package runtime import ( "device/esp" + "machine" ) // This is the function called on startup after the flash (IROM/DROM) is @@ -71,6 +72,9 @@ func main() { clearbss() } + // Initialize UART. + machine.InitSerial() + // Initialize main system timer used for time.Now. initTimer() diff --git a/targets/esp32s3.json b/targets/esp32s3.json index f245b82ab..051cc8542 100644 --- a/targets/esp32s3.json +++ b/targets/esp32s3.json @@ -4,7 +4,7 @@ "features": "+atomctl,+bool,+clamps,+coprocessor,+debug,+density,+div32,+esp32s3,+exception,+fp,+highpriinterrupts,+interrupt,+loop,+mac16,+memctl,+minmax,+miscsr,+mul32,+mul32high,+nsa,+prid,+regprotect,+rvector,+s32c1i,+sext,+threadptr,+timerint,+windowed", "build-tags": ["esp32s3", "esp"], "scheduler": "tasks", - "serial": "uart", + "serial": "usb", "linker": "ld.lld", "default-stack-size": 2048, "rtlib": "compiler-rt",