diff --git a/src/machine/machine_esp32_usb.go b/src/machine/machine_esp32_usb.go new file mode 100644 index 000000000..6f40a48fc --- /dev/null +++ b/src/machine/machine_esp32_usb.go @@ -0,0 +1,45 @@ +//go:build esp32s3 || esp32c3 + +package machine + +import ( + "device/esp" +) + +type USB_DEVICE struct { + Bus *esp.USB_DEVICE_Type +} + +var ( + _USBCDC = &USB_DEVICE{ + Bus: esp.USB_DEVICE, + } + + USBCDC Serialer = _USBCDC +) + +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) Buffered() int { + return int(usbdev.Bus.GetEP1_CONF_SERIAL_OUT_EP_DATA_AVAIL()) +} + +func (usbdev *USB_DEVICE) DTR() bool { + return false +} + +func (usbdev *USB_DEVICE) RTS() bool { + return false +} diff --git a/src/machine/machine_esp32c3.go b/src/machine/machine_esp32c3.go index eb2a18b5e..f413a8c14 100644 --- a/src/machine/machine_esp32c3.go +++ b/src/machine/machine_esp32c3.go @@ -509,102 +509,6 @@ func (uart *UART) writeByte(b byte) error { func (uart *UART) flush() {} -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 initUSB() { - // nothing to do here -} - -// USB Serial/JTAG Controller -// See esp32-c3_technical_reference_manual_en.pdf -// pg. 736 -type USB_DEVICE struct { - Bus *esp.USB_DEVICE_Type -} - -var ( - _USBCDC = &USB_DEVICE{ - Bus: esp.USB_DEVICE, - } - - USBCDC Serialer = _USBCDC -) - -var ( - errUSBWrongSize = errors.New("USB: invalid write size") - errUSBCouldNotWriteAllData = errors.New("USB: could not write all data") - errUSBBufferEmpty = errors.New("USB: read buffer empty") -) - -func (usbdev *USB_DEVICE) Configure(config UARTConfig) error { - return nil -} - -func (usbdev *USB_DEVICE) WriteByte(c byte) error { - if usbdev.Bus.GetEP1_CONF_SERIAL_IN_EP_DATA_FREE() == 0 { - return errUSBCouldNotWriteAllData - } - - usbdev.Bus.SetEP1_RDWR_BYTE(uint32(c)) - usbdev.flush() - - return nil -} - -func (usbdev *USB_DEVICE) Write(data []byte) (n int, err error) { - if len(data) == 0 || len(data) > 64 { - return 0, errUSBWrongSize - } - - for i, c := range data { - if usbdev.Bus.GetEP1_CONF_SERIAL_IN_EP_DATA_FREE() == 0 { - if i > 0 { - usbdev.flush() - } - - return i, errUSBCouldNotWriteAllData - } - usbdev.Bus.SetEP1_RDWR_BYTE(uint32(c)) - } - - usbdev.flush() - return len(data), nil -} - -func (usbdev *USB_DEVICE) Buffered() int { - return int(usbdev.Bus.GetEP1_CONF_SERIAL_OUT_EP_DATA_AVAIL()) -} - -func (usbdev *USB_DEVICE) ReadByte() (byte, error) { - if usbdev.Bus.GetEP1_CONF_SERIAL_OUT_EP_DATA_AVAIL() != 0 { - return byte(usbdev.Bus.GetEP1_RDWR_BYTE()), nil - } - - return 0, nil -} - -func (usbdev *USB_DEVICE) DTR() bool { - return false -} - -func (usbdev *USB_DEVICE) RTS() bool { - return false -} - -func (usbdev *USB_DEVICE) flush() { - usbdev.Bus.SetEP1_CONF_WR_DONE(1) - for usbdev.Bus.GetEP1_CONF_SERIAL_IN_EP_DATA_FREE() == 0 { - } -} - // GetRNG returns 32-bit random numbers using the ESP32-C3 true random number generator, // Random numbers are generated based on the thermal noise in the system and the // asynchronous clock mismatch. diff --git a/src/machine/machine_esp32c3_usb.go b/src/machine/machine_esp32c3_usb.go new file mode 100644 index 000000000..730967312 --- /dev/null +++ b/src/machine/machine_esp32c3_usb.go @@ -0,0 +1,52 @@ +//go:build esp32c3 + +package machine + +import "errors" + +var ( + errUSBWrongSize = errors.New("USB: invalid write size") + errUSBCouldNotWriteAllData = errors.New("USB: could not write all data") + errUSBBufferEmpty = errors.New("USB: read buffer empty") +) + +func initUSB() {} + +func (usbdev *USB_DEVICE) WriteByte(c byte) error { + if usbdev.Bus.GetEP1_CONF_SERIAL_IN_EP_DATA_FREE() == 0 { + return errUSBCouldNotWriteAllData + } + usbdev.Bus.SetEP1_RDWR_BYTE(uint32(c)) + usbdev.flush() + return nil +} + +func (usbdev *USB_DEVICE) Write(data []byte) (n int, err error) { + if len(data) == 0 || len(data) > 64 { + return 0, errUSBWrongSize + } + for i, c := range data { + if usbdev.Bus.GetEP1_CONF_SERIAL_IN_EP_DATA_FREE() == 0 { + if i > 0 { + usbdev.flush() + } + return i, errUSBCouldNotWriteAllData + } + usbdev.Bus.SetEP1_RDWR_BYTE(uint32(c)) + } + usbdev.flush() + return len(data), nil +} + +func (usbdev *USB_DEVICE) ReadByte() (byte, error) { + if usbdev.Bus.GetEP1_CONF_SERIAL_OUT_EP_DATA_AVAIL() != 0 { + return byte(usbdev.Bus.GetEP1_RDWR_BYTE()), nil + } + return 0, nil +} + +func (usbdev *USB_DEVICE) flush() { + usbdev.Bus.SetEP1_CONF_WR_DONE(1) + for usbdev.Bus.GetEP1_CONF_SERIAL_IN_EP_DATA_FREE() == 0 { + } +} diff --git a/src/machine/machine_esp32s3.go b/src/machine/machine_esp32s3.go index 9c2bd9001..f3ac520d2 100644 --- a/src/machine/machine_esp32s3.go +++ b/src/machine/machine_esp32s3.go @@ -308,91 +308,3 @@ func (uart *UART) writeByte(b byte) error { } func (uart *UART) flush() {} - -// 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/machine/machine_esp32s3_usb.go b/src/machine/machine_esp32s3_usb.go new file mode 100644 index 000000000..c9bfbe7ed --- /dev/null +++ b/src/machine/machine_esp32s3_usb.go @@ -0,0 +1,41 @@ +//go:build esp32s3 + +package machine + +import "errors" + +func initUSB() { + USBCDC.Configure(UARTConfig{BaudRate: 115200}) +} + +func (usbdev *USB_DEVICE) WriteByte(c byte) error { + timeout := 10000 + for usbdev.Bus.GetEP1_CONF_SERIAL_IN_EP_DATA_FREE() == 0 && timeout > 0 { + timeout-- + } + if timeout == 0 { + return nil + } + usbdev.Bus.SetEP1_RDWR_BYTE(uint32(c)) + 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) { + return 0, errors.New("ReadByte not implemented") +} + +func (usbdev *USB_DEVICE) flush() { + usbdev.Bus.SetEP1_CONF_WR_DONE(1) +}