I'm trying to send the byte 0x5A
(0b01011010
) on the serial output of an Arduino Due. My program is based on this example project, but I've stripped out all the unrelated parts:
#![feature(lang_items)]
#![no_std]
#![no_main]
extern crate sam3x;
pub mod rust_base;
use sam3x::*;
use sam3x::hal::peripherals::{Peripheral};
use sam3x::drivers::led::{Led};
use sam3x::hal::rtt::{init_timer, wait_ms};
use sam3x::hal::pmc;
use sam3x::hal::uart;
#[link_section=".vectors"]
pub static VECTOR_TABLE: VectorTable =
VectorTable {
reset_handler : start,
exceptions : [0; 14],
};
fn start() -> ! {
init_timer();
pmc::enable_peripheral_clock_0(Peripheral::PioC);
let led = Led::connect(Peripheral::PioB, 27).expect("Wrong pin for led.");
let tx = uart::Tx::init(uart::BR_9600);
let mut led_on = true;
led.on();
loop {
tx.write_byte(0b01011010);
wait_ms(250);
if led_on {
led.off()
} else {
led.on()
}
led_on = !led_on;
}
}
As you can see, all I do is send out the byte 0x5A
four times a second, with some LED blinking just to show the program is running.
My problem is that if I connect a serial terminal program with 9600-8N1 settings, I am not getting 0x5A
; instead, I am getting mostly 0xBA
, and sometimes a 0x9A
slips through.
Writing out the bits:
0101 1010 5A
1011 1010 BA
1001 1010 9A
Note that the lower nybble is always correct, which is why I don't think it's a serial communication setting issue; also, it's pretty clear from uart::Tx::init
's implementation that it defaults to no parity bits.
1 Answer 1
It seems this error is specific to the Rust ARM library I am using; quoting from https://github.com/klangner/sam3x/issues/9:
It looks that at bound rate=9600 the timer sends data with the speed of ~888. And then computer can't understand the output.
Based on this, I started playing around with the baud rate I pass to the library when initializing it, and using 11000 instead of 9600 empirically seems to work (i.e. I am seeing a steady stream of 0x5A
on my PC receiving at 9600).