esp8266-hal icon indicating copy to clipboard operation
esp8266-hal copied to clipboard

changing baud rate of UART0

Open kcking opened this issue 5 years ago • 3 comments

Is it possible to set the baud rate of UART0? I am using a NodeMCU ESP8266EX and trying to send debug print statements back to my computer (read with the ArduinIDO Serial Monitor), but they are just showing up as invalid characters. I feel like this might be a baud rate issue but I tried every baud rate available in the serial monitor (including the likely suspects of 9600 and 115200).

If it's helpful here is my current program mostly copied from the blinky example. Thanks!

#![no_std]
#![no_main]

use xtensa_lx106_rt::entry;

use core::panic::PanicInfo;
use esp8266_hal::prelude::*;
use esp8266_hal::target::Peripherals;

#[entry]
fn main() -> ! {
    let dp = unsafe { Peripherals::steal() };
    let pins = dp.GPIO.split();
    let (mut timer1, _) = dp.TIMER.timers();

    let mut gpio1_uart = pins.gpio1.into_uart();
    let mut gpio3_uart = pins.gpio3.into_uart();
    let mut gpio2_uart = pins.gpio2.into_uart();

    use esp8266_hal::prelude::_embedded_hal_serial_Write;
    use embedded_hal::blocking::serial::write::Default;
    use esp8266_hal::uart::UART0Ext;
    use esp8266_hal::uart::UART1Ext;
    use core::fmt::Write;

    let mut serial = dp.UART0.serial(gpio1_uart, gpio3_uart);
    //let mut serial = dp.UART1.serial(gpio2_uart);

    loop {
        timer1.delay_ms(500);
        //led.toggle().unwrap();
        serial.write_str("hello_world\n").unwrap();
        // serial.flush();
    }
}

/// Basic panic handler - just loops
#[panic_handler]
fn panic(_info: &PanicInfo) -> ! {
    loop {}
}

kcking avatar Sep 04 '20 05:09 kcking

On boot, the bootloader will print some info to UART0 at a baudrate that is dependent on the frequency of the crystal oscillator used on your board, the most crystal is 26Mhz which will lead to a baud rate of 74880 during boot.

Once the board is booted the clock frequency is adjusted up to 80Mhz, assuming the 26Mhz crystal and the baud rate becomes 115200. If your board is not using the default 26Mhz crystal.

If your board is using a 40Mhz crystal, you'll need to use set_crystal_frequency to get the clock at the expected frequency.

If you're having trouble figuring out the crystal frequency you can also check if the timer delays behave as expected and aren't to slow/fast.

As for changing the baud rate, I'll probably look into it once I'm done yak shaving espflash.

icewind1991 avatar Sep 04 '20 16:09 icewind1991

Thanks for the detailed response!

I now realized the timers are definitely off. With the blinky example the light blinks exactly 2.5x faster than it should. This behavior remains consistent whether I call xtensa_lx106_rt::set_crystal_frequency(xtensa_lx106_rt::CrystalFrequency::Crystal26MHz); or xtensa_lx106_rt::set_crystal_frequency(xtensa_lx106_rt::CrystalFrequency::Crystal40MHz); at the start of main.

Any thoughts on what might be causing that?

kcking avatar Sep 04 '20 23:09 kcking

for reference, I was able to change the baud rate manually using:

let dp = Peripherals::take().unwrap();
dp.UART0.uart_clkdiv.write(|w| unsafe { w.uart_clkdiv().bits(80e6 as u32 / 115_200) });

I'm using the esp12s here, I think it has a 26Mhz cristal and boot up with 80 Mhz if you dont change anything during startup. (blinking with timer1 was also working with the correct frequency)

t-moe avatar Sep 13 '23 08:09 t-moe