arduino / arduino/ArduinoCore-renesas

Upload to UNO R4 WiFi fails when "1200 bps touch" causes port change

Open
#73 5 comments 3 reactions 0 assignees View on GitHub
topic: code type: imperfection
Dominant language
C
Stars
193
Forks
112
PR merge metrics
No merged PRs in 30d

Description

### Describe the problem

The upload operation for the [**UNO R4 WiFi**](https://docs.arduino.cc/hardware/uno-r4-wifi) follows this sequence:

1. Perform a ["1200 bps touch"](https://arduino.github.io/arduino-cli/dev/platform-specification/#1200-bps-bootloader-reset) to put the board into the mode where it can be flashed.
1. Invoke the `bossac` command that flashes the binary to the board.

It is common for the address of the board port to change after the "1200 bps touch" step and so the Arduino development tools have a system for detecting the post-touch address and using that address when the upload command is generated from [the "pattern"](https://arduino.github.io/arduino-cli/dev/platform-specification/#tools) defined for the board in `platform.txt`. That system involves a post-touch wait to watch for the new port to appear before eventually timing out and resorting to the fallback behavior of using the original address to the upload pattern if no address change was detected. Since some boards will never produce a post-touch address change (meaning the post-touch wait step would only cause an unnecessary delay in the upload operation) it is possible to configure the board to skip the wait step by setting [the `upload.wait_for_upload_port` property](https://arduino.github.io/arduino-cli/dev/platform-specification/#1200-bps-bootloader-reset) to `false` in the board definition.

The assumption was made that the address of the **UNO R4 WiFi** board's port will never experience a post-touch address change, so its `upload.wait_for_upload_port` property is set to `false`

https://github.com/arduino/ArduinoCore-renesas/blob/f032b827fec8ae4d33e55aa0f92b906e76a51aa5/boards.txt#L149

However, the address can change under certain conditions. When the address does change, it causes the `bossac` command invocation to fail with a "`No device found on ...`" error because the original port address is used in the generated command instead of the post-touch address.

### To reproduce

#### Arduino IDE

1. Create a sketch with the following code:
```cpp
#include
void setup() {}
void loop() {}
```
1. Select the appropriate board and port for the **UNO R4 WiFi** from the Arduino IDE menus.
1. Select **Sketch > Upload** from the Arduino IDE menus.
1. Wait for the upload to complete successfully.
the upload should be successful as long as the board isn't already running a problematic sketch.
1. Select **Sketch > Upload** from the Arduino IDE menus.

🐛 The upload fails:

```text
Performing 1200-bps touch reset on serial port COM12
Cannot perform port reset: 1200-bps touch: opening port at 1200bps: Invalid serial port
"C:\Users\per\AppData\Local\Arduino15\packages\arduino\tools\bossac\1.9.1-arduino5/bossac" -d --port=COM12 -U -e -w "C:\Users\per\AppData\Local\arduino\sketches\ED9B99C5CD7EA51AB3A1480BECD9AEB6/sketch_sep13b.ino.bin" -R
No device found on COM10
Failed uploading: uploading error: exit status 1
```

#### Arduino CLI

##### Setup

```text
$ arduino-cli version

arduino-cli.exe Version: git-snapshot Commit: f66becdf Date: 2023-07-23T20:34:26Z

$ mkdir /tmp/HIDSketch

$ printf "#include \nvoid setup() {}\nvoid loop() {}\n" > "/tmp/HIDSketch/HIDSketch.ino"

$ arduino-cli compile --fqbn arduino:renesas_uno:unor4wifi /tmp/HIDSketch

[...]

Used library Version Path
HID C:\Users\per\AppData\Local\Arduino15\packages\arduino\hardware\renesas_uno\1.0.2\libraries\HID

Used platform Version Path
arduino:renesas_uno 1.0.2 C:\Users\per\AppData\Local\Arduino15\packages\arduino\hardware\renesas_uno\1.0.2

$ arduino-cli board list

Port Protocol Type Board Name FQBN Core
COM42 serial Serial Port (USB) Arduino UNO R4 WiFi arduino:renesas_uno:unor4wifi arduino:renesas_uno

$ arduino-cli upload --fqbn arduino:renesas_uno:unor4wifi --port COM42 --verbose /tmp/HIDSketch # Upload of the sketch is successful as long as the board is not already running a problematic sketch

Performing 1200-bps touch reset on serial port COM42
"C:\Users\per\AppData\Local\Arduino15\packages\arduino\tools\bossac\1.9.1-arduino5/bossac" -d --port=COM42 -U -e -w "C:\Users\per\AppData\Local\Temp\arduino\sketches\1F72A0DD582A60EAC64D21C07F93BFD9/HIDSketch.ino.bin" -R
Set binary mode
version()=Arduino Bootloader (SAM-BA extended) 2.0 [Arduino:IKXYZ]
Connected at 921600 baud
identifyChip()=nRF52840-QIAA
write(addr=0,size=0x34)
writeWord(addr=0x30,value=0x400)
writeWord(addr=0x20,value=0)
Erase flash
chipErase(addr=0)

Done in 0.001 seconds
Write 34604 bytes to flash (9 pages)
[ ] 0% (0/9 pages)write(addr=0x34,size=0x1000)
writeBuffer(scr_addr=0x34, dst_addr=0, size=0x1000)
[=== ] 11% (1/9 pages)write(addr=0x34,size=0x1000)
writeBuffer(scr_addr=0x34, dst_addr=0x1000, size=0x1000)
[====== ] 22% (2/9 pages)write(addr=0x34,size=0x1000)
writeBuffer(scr_addr=0x34, dst_addr=0x2000, size=0x1000)
[========== ] 33% (3/9 pages)write(addr=0x34,size=0x1000)
writeBuffer(scr_addr=0x34, dst_addr=0x3000, size=0x1000)
[============= ] 44% (4/9 pages)write(addr=0x34,size=0x1000)
writeBuffer(scr_addr=0x34, dst_addr=0x4000, size=0x1000)
[================ ] 55% (5/9 pages)write(addr=0x34,size=0x1000)
writeBuffer(scr_addr=0x34, dst_addr=0x5000, size=0x1000)
[==================== ] 66% (6/9 pages)write(addr=0x34,size=0x1000)
writeBuffer(scr_addr=0x34, dst_addr=0x6000, size=0x1000)
[======================= ] 77% (7/9 pages)write(addr=0x34,size=0x1000)
writeBuffer(scr_addr=0x34, dst_addr=0x7000, size=0x1000)
[========================== ] 88% (8/9 pages)write(addr=0x34,size=0x1000)
writeBuffer(scr_addr=0x34, dst_addr=0x8000, size=0x1000)
[==============================] 100% (9/9 pages)
Done in 2.238 seconds
reset()
```

##### Demo

```text
$ arduino-cli board list # The HID sketch causes the port address to change

Port Protocol Type Board Name FQBN Core
COM12 serial Serial Port (USB) Arduino UNO R4 WiFi arduino:renesas_uno:unor4wifi arduino:renesas_uno

$ arduino-cli upload --fqbn arduino:renesas_uno:unor4wifi --port COM12 --verbose /tmp/HIDSketch # Touch step fails and the bossac command runs with the wrong port

Performing 1200-bps touch reset on serial port COM12
Cannot perform port reset: TOUCH: error during reset: opening port at 1200bps: Invalid serial port
"C:\Users\per\AppData\Local\Arduino15\packages\arduino\tools\bossac\1.9.1-arduino5/bossac" -d --port=COM12 -U -e -w "C:\Users\per\AppData\Local\Temp\arduino\sketches\1F72A0DD582A60EAC64D21C07F93BFD9/HIDSketch.ino.bin" -R
No device found on COM12
Failed uploading: uploading error: exit status 1

$ arduino-cli board list # Even though the touch process failed, it did put the board into bootloader mode

Port Protocol Type Board Name FQBN Core
COM42 serial Serial Port (USB) Arduino UNO R4 WiFi arduino:renesas_uno:unor4wifi arduino:renesas_uno

$ arduino-cli upload --fqbn arduino:renesas_uno:unor4wifi --port COM42 /tmp/HIDSketch # The next upload succeeds because the board is in bootloader mode

Performing 1200-bps touch reset on serial port COM42
"C:\Users\per\AppData\Local\Arduino15\packages\arduino\tools\bossac\1.9.1-arduino5/bossac" -d --port=COM42 -U -e -w "C:\Users\per\AppData\Local\Temp\arduino\sketches\1F72A0DD582A60EAC64D21C07F93BFD9/HIDSketch.ino.bin" -R
Set binary mode
version()=Arduino Bootloader (SAM-BA extended) 2.0 [Arduino:IKXYZ]
Connected at 921600 baud
identifyChip()=nRF52840-QIAA
write(addr=0,size=0x34)
writeWord(addr=0x30,value=0x400)
writeWord(addr=0x20,value=0)
Erase flash
chipErase(addr=0)

Done in 0.001 seconds
Write 34604 bytes to flash (9 pages)
[ ] 0% (0/9 pages)write(addr=0x34,size=0x1000)
writeBuffer(scr_addr=0x34, dst_addr=0, size=0x1000)
[=== ] 11% (1/9 pages)write(addr=0x34,size=0x1000)
writeBuffer(scr_addr=0x34, dst_addr=0x1000, size=0x1000)
[====== ] 22% (2/9 pages)write(addr=0x34,size=0x1000)
writeBuffer(scr_addr=0x34, dst_addr=0x2000, size=0x1000)
[========== ] 33% (3/9 pages)write(addr=0x34,size=0x1000)
writeBuffer(scr_addr=0x34, dst_addr=0x3000, size=0x1000)
[============= ] 44% (4/9 pages)write(addr=0x34,size=0x1000)
writeBuffer(scr_addr=0x34, dst_addr=0x4000, size=0x1000)
[================ ] 55% (5/9 pages)write(addr=0x34,size=0x1000)
writeBuffer(scr_addr=0x34, dst_addr=0x5000, size=0x1000)
[==================== ] 66% (6/9 pages)write(addr=0x34,size=0x1000)
writeBuffer(scr_addr=0x34, dst_addr=0x6000, size=0x1000)
[======================= ] 77% (7/9 pages)write(addr=0x34,size=0x1000)
writeBuffer(scr_addr=0x34, dst_addr=0x7000, size=0x1000)
[========================== ] 88% (8/9 pages)write(addr=0x34,size=0x1000)
writeBuffer(scr_addr=0x34, dst_addr=0x8000, size=0x1000)
[==============================] 100% (9/9 pages)
Done in 2.238 seconds
reset()
```

### Expected behavior

Correct port address is always used in the upload command.

### Project version

#### Original report

e5ab69859d70dd7f4e6ed7769b027fc371cd613c

#### Last verified with

f032b827fec8ae4d33e55aa0f92b906e76a51aa5

["Bridge" firmware](https://github.com/arduino/uno-r4-wifi-usb-bridge) version: 0.5.2

### Operating system

- Windows
- Linux
- macOS

### Operating system version

- Windows 11
- Ubuntu 22.04
- macOS Ventura

### Additional context

For the sake of simplicity, I used the [the low level "**HID**" library](https://github.com/arduino/ArduinoCore-renesas/tree/main/libraries/HID) in the demonstration sketch, but that library is not commonly used directly in real world sketches. However, it is common to use the "[**Keyboard**](https://www.arduino.cc/reference/en/language/functions/usb/keyboard/)" or "[**Mouse**](https://www.arduino.cc/reference/en/language/functions/usb/mouse/)" libraries, which have a dependency on the "**HID**" library and are documented as supported for use with the **UNO R4 WiFi**:

https://docs.arduino.cc/tutorials/uno-r4-wifi/usb-hid

The fault will also occur when using either of those libraries in a sketch:

```cpp
#include
void setup() {}
void loop() {}
```

---

The distinctive "`Cannot perform port reset: TOUCH: error during reset: opening port at 1200bps: Invalid serial port`" error message shown in the upload output from the demo only occurs on Windows machines. On Linux and macOS machines, the "touch" doesn't produce an error message and the only error message is the ambiguous "`No device found on ...`".

---

Originally reported at https://forum.arduino.cc/t/failed-uploading-after-upload-usb-hid-example/1151778

#### Additional reports

- https://forum.arduino.cc/t/uploaded-sketch-with-hid-h-difficult-to-upload-new-sketch/1168847
- https://forum.arduino.cc/t/cannot-perform-port-reset-touch-error-during-reset-opening-port-at-1200bps-invalid-serial-port-uno-r4/1213771
- https://forum.arduino.cc/t/arduino-port-is-recognised-but-wont-upload/1343469
- https://forum.arduino.cc/t/error-uploading-sketch-to-uno-r4-wifi/1375527
- https://forum.arduino.cc/t/1200bps-invalid-serial-port-error-on-uno-r4-wifi/1399447

#### Workaround

1. Unplug the USB cable of the **UNO R4 WiFi** board from your computer.
1. Connect the **UNO R4 WiFi board** to your computer with the USB cable.
1. Press and release the button marked "**RESET**" on your **UNO R4 WiFi** board quickly twice.
You should now see the "**L**" LED pulsing.
1. Select the port of the **UNO R4 WiFi** board from Arduino IDE's **Tools > Port** menu.
❗ The double reset you did in step (3) can cause the port number of the board to change, so don't assume you already have the correct port selected.
1. Upload the sketch to the board as usual.

Contributor guide

No contributing guide indexed for this repository

Research direction

Start with the UNO R4 WiFi entry in boards.txt, especially the upload.wait_for_upload_port setting described in the issue. Reproduce with the HID sketch using arduino-cli upload and observe the port before and after the 1200-bps touch. Done means the upload command uses the post-touch port and the upload succeeds when the sketch changes the port address.

Written by the indexing model from the issue text.

Assessment

Domain
embedded-iot, tooling
Issue type
Bug
Difficulty
2/5
Estimated time
1-3 hours
Activity status
Stale
Clarity
Clearly specified
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.