Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Serial port setup: baud_rate/8/N/1 doesn't work when uploading examples to Arduino Uno rev2 #67

Closed
kosciej opened this issue Aug 31, 2020 · 12 comments
Labels
bug Something isn't working

Comments

@kosciej
Copy link

kosciej commented Aug 31, 2020

I'm getting gibberish on serial port.
I've uploaded examples to my Arduino Uno rev2 board via cargo +nightly run --example uno-serial and cargo +nightly run --example uno-adc. I've played with several baud_rates (switched uno-serial.rs example from 57600 to 9600). I cannot get the correct setup to retrieve the data. The upload process is correct and other examples (uno-blink.rs) are working correctly.

Also, code from Arduino IDE behaves correctly in terms of Serial port communication.

@Rahix
Copy link
Owner

Rahix commented Aug 31, 2020

I don't have any immediate idea what might be wrong ... Here's a few questions, maybe we can narrow it down a bit?

  • Do the TX and RX leds show any activity? Especially, does TX indicate that the program is sending data as it should?
  • What program are you using to connect to the serial console on your host?
  • Modify the serial example to continously send some data, then cycle through baudrates on your host. Do you, at any point, see either the output or some gibberish?

@Rahix
Copy link
Owner

Rahix commented Aug 31, 2020

I'm getting gibberish on serial port.

Ugh, reading is hard; just noticed this ... In that case, this is most likely a baudrate mismatch of some sort. What program are you using on the host to read from the serial console?

@kosciej
Copy link
Author

kosciej commented Aug 31, 2020

Thanks! You are right, there were baud rate mismatch. I was able to RX/TX correctly at 19200, despite setting baud rate in code to 9600. With the rate in the code 57600, I was able to connect at 115200. So basically it was always doubled rate. When I've submitted the issue, I've tried only lower baud rates, so wasn't able to find correct one.

I believe there is some issue causing this. I'm happy to help fix it, but need some pointers where to look at.

@Rahix
Copy link
Owner

Rahix commented Sep 1, 2020

Hm, I think I found something: Please flash a test program, power off the arduino entirely, turn it back on and try again. Will this lead to using the correct baudrate?

Could you also try adding the following patch?

diff --git a/avr-hal-generic/src/serial.rs b/avr-hal-generic/src/serial.rs
index 280f92da1cf1..677ba3841d91 100644
--- a/avr-hal-generic/src/serial.rs
+++ b/avr-hal-generic/src/serial.rs
@@ -57,6 +57,8 @@ macro_rules! impl_usart {
                 let brr = CLOCK::FREQ / (16 * baud) - 1;
                 self.p.[<ubrr $n>].write(|w| unsafe { w.bits(brr as u16) });
 
+                self.p.[<ucsr $n a>].reset();
+
                 // Enable receiver and transmitter but leave interrupts disabled.
                 self.p.[<ucsr $n b>].write(|w| w
                     .[<txen $n>]().set_bit()

If any of the above helps, here's what I suspect: Arduino firmware sets the U2Xn bit in its serial driver which doubles the configured baudrate. This bit isn't currently cleared in avr-hal because it should be disabled by default. But maybe in some weird circumstances it might have stayed enabled (or was set by the bootloader?) so you got the behavior you observed. The above patch would fix this by properly disabling the bit every time.

@Rahix Rahix added the bug Something isn't working label Sep 1, 2020
@Rahix
Copy link
Owner

Rahix commented Sep 1, 2020

Reading into this a bit more, it seems we might want to enable U2Xn as well:

You should be aware that the Arduino software sets the U2X bit, so the correct UBRR value is 16. This results in a "closer" 115200bps bit rate (2.1% off), which is why it was done. If you use 8 without UX2 set, you'll get 3.7% error IN THE OTHER DIRECTION. The combined error is more than the ~5% that Async can easily tolerate.

(Arduino Forum)


Additionally, the above post links to this workaround in Arduino Core:

  // hardcoded exception for 57600 for compatibility with the bootloader
  // shipped with the Duemilanove and previous boards and the firmware
  // on the 8U2 on the Uno and Mega 2560. Also, The baud_setting cannot
  // be > 4095, so switch back to non-u2x mode if the baud rate is too
  // low.
  if (((F_CPU == 16000000UL) && (baud == 57600)) || (baud_setting >4095))
  {
    *_ucsra = 0;
    baud_setting = (F_CPU / 8 / baud - 1) / 2;
  }

Not sure if we should add that ... It is specific to arduino boards and might be entirely wrong for non-arduino usecases. OTOH without it, we might see more baudrate mismatch problems.

@kosciej
Copy link
Author

kosciej commented Sep 1, 2020

Please flash a test program, power off the arduino entirely, turn it back on and try again. Will this lead to using the correct baudrate?

I've trurned it off, wait 10+ seconds, and plugged it back. It didn't help.

If any of the above helps, here's what I suspect: Arduino firmware sets the U2Xn bit in its serial driver which doubles the configured baudrate.

Looks like this is the case. I've applied the path you provided and it works as expected.

@kosciej
Copy link
Author

kosciej commented Sep 1, 2020

Additionally, the above post links to this workaround in Arduino Core

This workaround is exactly for 8U2 serial chip which I have on Arduino Uno rev2. Nowadays, most common is rev3, which have different chip.

@Rahix
Copy link
Owner

Rahix commented Sep 1, 2020

Looks like this is the case. I've applied the path you provided and it works as expected.

Great to hear, I'll apply this patch properly this evening (hopefully)!

This workaround is exactly for 8U2 serial chip which I have on Arduino Uno rev2. Nowadays, most common is rev3, which have different chip.

Okay, maybe you can do some tests to see how unstable our current settings are? E.g. if you try using 115200 baud, does it work reliably?

@kosciej
Copy link
Author

kosciej commented Sep 1, 2020

115200 with patch applied is totally unreliable, I receive broken data.
57600 with patch applied is reliable, can send and read data.
115200 without patch (57600 set in the code, 2*57600 = 115200 in terminal) is reliable, I can send and read received data.

@Rahix
Copy link
Owner

Rahix commented Sep 1, 2020

Ok, at least that's in line with what I'd expect after reading about the Arduino implementation ...

@Rahix
Copy link
Owner

Rahix commented Sep 2, 2020

I've pushed commit 7caed3a ("generic: serial: Fix U2Xn not being reset") to fix your original problem. I'd keep this issue open, though, for discussing the other baudrate mismatch topics ...

@Rahix
Copy link
Owner

Rahix commented Oct 4, 2020

Let's close this issue here and continue the baudrate topic in #80 where I've started to outline possible solutions.

@Rahix Rahix closed this as completed Oct 4, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

2 participants