tinygo icon indicating copy to clipboard operation
tinygo copied to clipboard

No Serial Port After Flashing Leonardo on Linux

Open jdoklovic opened this issue 2 years ago • 7 comments

I have an Arduino Leonardo and I have not been able to get it to run a tinygo program successfully.

I'm using arch-based Manjaro linux.

After lots of trial and error, I can build the project with tinygo and flash it with the latest source build of avrdude using the new -r flag to send a reset using 1200 baud.

No matter what I do, after a successful flash of the tinygo binary, the arduino serial port is gone and I can never get it back. I have used the reset button, I have unplugged/replugged the device, I have rebooted, but the serial port ttyACM0 never comes back.

The only thing I can do is re-flash it with a C++ hex. I can do this using the same avrdude command (with a different hex path) while pressing the reset button. This is what leads me to believe it's a tinygo issue and not an avrdude/flash issue

Not sure what to do at this point.

The tinygo code is:

//go:build arduino_leonardo

package main

import (
	"machine"
	"time"
)

// Take input from a machine pin
func main() {

	button := machine.D2
	button.Configure(machine.PinConfig{Mode: machine.PinInput})

	for {
		if button.Get() {
			println("button ^") // pew pew pew!
		} else {
			println("button v")
		}
		time.Sleep(time.Millisecond * 10)
	}
}

The build command:

tinygo build -o=./main.hex -target=arduino-leonardo -tags "avr baremetal linux arm atmega32u4 avr5 arduino_leonardo tinygo math_big_pure_go gc.conservative scheduler.none serial.none"

The avrdude flash output:

/usr/local/bin/avrdude -v -V -p m32u4 -c avr109 -P "/dev/ttyACM0" -D -U "flash:w:/home/jonathan/data/tinygotest/main.hex:i" -r                                              ✔ 

avrdude: Version 7.2-20240104 (03d786e8)
         Copyright the AVRDUDE authors;
         see https://github.com/avrdudes/avrdude/blob/main/AUTHORS

         System wide configuration file is /usr/local/etc/avrdude.conf
         User configuration file is /home/$USER/.avrduderc
         User configuration file does not exist or is not a regular file, skipping

avrdude: touching serial port /dev/ttyACM0 at 1200 baud
avrdude: waiting for new port...
avrdude: new port /dev/ttyACM0 discovered
 750 ms: using new port /dev/ttyACM0
         Using port            : /dev/ttyACM0
         Using programmer      : avr109
         AVR Part              : ATmega32U4
         Programming modes     : ISP, HVPP, JTAG, SPM
         Programmer Type       : butterfly
         Description           : Atmel for bootloader using AppNote AVR109
connecting to programmer: .
Programmer id    = CATERIN; type = S
Software version = 1.0; no hardware version given
programmer supports auto addr increment
programmer supports buffered memory access with buffersize=128 bytes
avrdude: devcode selected: 0x44
avrdude: AVR device initialized and ready to accept instructions
avrdude: device signature = 0x1e9587 (probably m32u4)

avrdude: processing -U flash:w:/home/$USER/data/tinygotest/main.hex:i
avrdude: reading input file /home/$USER/data/tinygotest/main.hex for flash
         with 768 bytes in 1 section within [0, 0x2ff]
         using 6 pages and 0 pad bytes
avrdude: writing 768 bytes flash ...
Writing | ################################################## | 100% 0.06 s 
avrdude: 768 bytes of flash written

avrdude done.  Thank you.

jdoklovic avatar Jan 05 '24 01:01 jdoklovic

$ tinygo env 
GOOS="linux"
GOARCH="amd64"
GOROOT="/usr/local/go"
GOPATH="/home/$USER/go"
GOCACHE="/home/$USER/.cache/tinygo"
CGO_ENABLED="1"
TINYGOROOT="/usr/lib/tinygo"

jdoklovic avatar Jan 05 '24 01:01 jdoklovic

It's probably the same issue as the following. The reason is that TinyGo does not have an implementation for USB Device of ATmega32u4 .

https://x.com/nobonobo/status/1723857164941336854?s=20

sago35 avatar Jan 05 '24 22:01 sago35

After some searching, I discovered that the tinyogo src for the leonardo board uses a NullSerial for machine.Serial, however, the Leonardo uses a virtual CDC (unlike other arduinos). Maybe the leonardo need the ability to compile with -serial=usb ?

I'm not sure how to get that to work though.

Here are some excerpts from: https://docs.arduino.cc/retired/getting-started-guides/ArduinoLeonardoMicro

Serial re-enumeration on reset. Since the boards do not have a dedicated chip to handle serial communication, it means that the serial port is virtual -- it's a software routine, both on your operating system, and on the board itself. Just as your computer creates an instance of the serial port driver when you plug in any Arduino, the Leonardo/Micro creates a serial instance whenever it runs its bootloader. The board is an instance of USB's Connected Device Class (CDC) driver.

This means that every time you reset the board, the USB serial connection will be broken and re-established. The board will disappear from the list of serial ports, and the list will re-enumerate. Any program that has an open serial connection to the Leonardo will lose its connection. This is in contrast to the Arduino Uno, with which you can reset the main processor (the ATmega328P) without closing the USB connection (which is maintained by the secondary ATmega8U2 or ATmega16U2 processor). This difference has implications for driver installation, uploading, and communication; these are discussed below.

jdoklovic avatar Jan 05 '24 22:01 jdoklovic

@sago35 I think we came to the same conclusion. There's no serial usb support in tinygo for the ATmega32u4, which basically means Leonardo support doesn't work in tinygo.

There's some CDC stuff in the Arduino core code, but I don't know enough about C++ or how tinygo implements the CDC stuff to be able to PR this or anything.

for reference: https://github.com/arduino/ArduinoCore-avr/blob/63092126a406402022f943ac048fa195ed7e944b/cores/arduino/USBCore.cpp#L73

jdoklovic avatar Jan 05 '24 22:01 jdoklovic

Basically, you would need to create an ATmega32u4 version of the following source code. I don't have an ATmega32u4, so it would be difficult for me to work on this.

https://github.com/tinygo-org/tinygo/blob/v0.30.0/src/machine/machine_rp2040_usb.go

sago35 avatar Jan 05 '24 22:01 sago35

Yeah, that's a little beyond my comprehension of how the board works.

jdoklovic avatar Jan 05 '24 23:01 jdoklovic

I don't have an ATmega32u4, so it would be difficult for me to work on this.

I could send you one ;)

jdoklovic avatar Jan 07 '24 00:01 jdoklovic