Trying to configure a USART peripheral

Hi there, I'm new to Rust and trying to develop a simple embedded application for the STM32F3 board. I'm still trying to figure out how to read the Rust API documentation and I think this is mostly my issue. However, to be specific, I am trying to configure a USART peripheral for serial communication to a device. Here is the snippet of code that I am trying to compile:

let peripherals = stm32f3xx_hal::stm32::Peripherals::take().unwrap();
let mut rcc = peripherals.RCC.constrain();
let mut flash = peripherals.FLASH.constrain();
let clocks = rcc.cfgr.freeze(&mut flash.acr);

let mut gpioa = peripherals.GPIOA.split(&mut rcc.ahb);

let tx = gpioa.pa9;
let rx = gpioa.pa10;

let usart1 = stm32f3xx_hal::serial::Serial::usart1(
        peripherals.USART1,
        (tx, rx),
        115_200.bps(),
        clocks,
        &mut rcc.apb2,
    );

I am getting these compilation errors:

error[E0277] : the trait bound stm32f3xx_hal::gpio::Pin<Gpioa, typenum::uint::UInt<typenum::uint::UInt<typenum::uint::UInt<typenum::uint::UInt<typenum::uint::UTerm, typenum::bit::B1>, typenum::bit::B0>, typenum::bit::B0>, typenum::bit::B1>, Input>: TxPin<USART1> is not satisfied

error[E0277] : the trait bound stm32f3xx_hal::gpio::Pin<Gpioa, typenum::uint::UInt<typenum::uint::UInt<typenum::uint::UInt<typenum::uint::UInt<typenum::uint::UTerm, typenum::bit::B1>, typenum::bit::B0>, typenum::bit::B1>, typenum::bit::B0>, Input>: RxPin<USART1> is not satisfied

error[E0308] : mismatched types

--> hanger-buddy/src/main.rs:120:9
120 | 115_200.bps(),
| ^^^^^^^^^^^^^ expected struct Baud, found struct BitsPerSecond
= note : expected struct **Baud**
found struct **BitsPerSecond<{integer}>**

I'm trying to understand what stm32f3xx_hal::serial::Serial::usart1(..) method is requiring for the (Tx, Rx) and the baud rate as I think the other arguments I have set correctly.

I hate to just ask for the answer as I would rather be able to read the API document for the usart1 method and be able to figure it out, so maybe if anyone can explain what I am missing and then perhaps how that was arrived at by reading the API document. Thoughts?

Thank you!
Matt

Welcome! Please put your code and compiler diagnostics in code blocks (``` on the lines just before and just after); they're easier for everyone to read that way.

Edit: note those are backticks U+0060, not apostrophes U+0027—your latest edit is using apostrophes which is why it's still not rendering as desired. On my keyboard layout, backtick is on the same key as tilde ~, or you can copy-and-paste it from one of these posts.

Could you share what's in your Cargo.toml? Sometimes weird issues like these end up being caused by pulling in an unexpected version of a library, or two versions of the same library.

Thank you, sorry for not adhering to the code formatting rules. I should have read that first post!

Here's my cargo.toml file:

[package]
authors = [
"Matt Van Bergen mvanbergen@gmail.com",
]

edition = "2018"
name = "hanger-buddy"
version = "0.1.0"

[dependencies]
cortex-m = "0.7.2"
cortex-m-rt = "0.6.13"
embedded-time = "0.10.1"

[dependencies.stm32f3xx-hal]
git = "https://github.com/stm32-rs/stm32f3xx-hal.git"
features = ["stm32f303xc", "rt"]

[dependencies.lazy_static]
features = ["spin_no_std"]
version = "1.4.0"

1 Like

Ahh, okay, so you're using the bleeding-edge version of stm32f3xx-hal, right from the GitHub repo. Looking at their changelog, I see a couple of unreleased breaking changes that probably explain what you're running into:

If you're going to work with bleeding-edge stm32f3xx-hal then you should refer to the up-to-date docs, which you can build locally and open in your browser by running cargo doc -p stm32f3xx-hal --open. Note that your code might break without warning when you run cargo update after that repo merges a new pull request; in general I'd suggest using a released version from crates.io, e.g. stm32f3xx-hal = "0.6.1", in which case the documentation on https://docs.rs/stm32f3xx-hal will match what you're compiling against.

Thanks Cole. I updated my Cargo.toml to leverage version 0.6.1. I don't recall why I was getting the bleeding edge version of the stm32f3xx-hal. I made this change and that removed the error with the baud rate parameter. I still am having an issue with the "pins: (TX, RX)" parameters for the usart1 instantiation. I think I am not interpreting the docs for what is required for these parameters correctly.

The docs show this for the method signature:

pub fn usart1(
    usart: USART1,
    pins: (TX, RX),
    baud_rate: Bps,
    clocks: Clocks,
    apb: &mut APB2
) -> Self
where
    TX: TxPin<USART1>,
    RX: RxPin<USART1>, 

I'm trying to assign the gpioa pins 9 & 10 to tx and rx respectively but the compiler is saying that gpioa.pa9 does not implement the TxPin trait (same for gpioa.pa10 for the RxPin.

error[E0277] : the trait bound stm32f3xx_hal::gpio::gpioa::PA9<Input<Floating>>: TxPin<USART1> is not satisfied

--> hanger-buddy/src/main.rs:117:18

|

117 | let usart1 = stm32f3xx_hal::serial::Serial::usart1(

| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait TxPin<USART1> is not implemented for stm32f3xx_hal::gpio::gpioa::PA9<Input<Floating>>

|

= help : the following implementations were found:

<stm32f3xx_hal::gpio::gpioa::PA9<stm32f3xx_hal::gpio::AF7> as TxPin>

= note : required by Serial::<USART1, (TX, RX)>::usart1

error[E0277] : the trait bound stm32f3xx_hal::gpio::gpioa::PA10<Input<Floating>>: RxPin<USART1> is not satisfied

--> hanger-buddy/src/main.rs:117:18

|

117 | let usart1 = stm32f3xx_hal::serial::Serial::usart1(

| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait RxPin<USART1> is not implemented for stm32f3xx_hal::gpio::gpioa::PA10<Input<Floating>>

|

= help : the following implementations were found:

<stm32f3xx_hal::gpio::gpioa::PA10<stm32f3xx_hal::gpio::AF7> as RxPin>

= note : required by Serial::<USART1, (TX, RX)>::usart1

error : aborting due to 2 previous errors; 1 warning emitted

For more information about this error, try rustc --explain E0277.

I was not sure how I could leverage the documentation to figure out how to find what implements that Trait to satisfy the method.

Thanks again for any pointers, especially how to navigate the docs so I can be more self sufficient.

Matt

If you start out at the docs for the Serial::usart1 function, you can click on TxPin and RxPin in

where
    TX: TxPin<USART1>,
    RX: RxPin<USART1>,

to go to the docs page for each trait and see a list of implementors, e.g. here's the page for TxPin:

https://docs.rs/stm32f3xx-hal/0.6.1/stm32f3xx_hal/serial/trait.TxPin.html

Under "Implementors" you see:

impl TxPin<USART1> for PA9<AF7>

impl TxPin<USART1> for PB6<AF7>

impl TxPin<USART1> for PC4<AF7>

impl TxPin<USART1> for PE0<AF7>

So tx in your invocation will need to have one of those types, and similarly for RxPin and rx.

I got it to compile at least, but still working through a serial communication test using the user usb port on the STM32discovery board. I might post a separate question on this, but here's the two lines of code I used to get RxPin and TxPin instances.

let tx =  gpioa.pa9.into_af7(&mut gpioa.moder, &mut gpioa.afrh);
let rx =  gpioa.pa10.into_af7(&mut gpioa.moder, &mut gpioa.afrh); 

Note, I'm not entirely sure that I use the same method for both the tx and rx (i.e. gpio.pa10.into_af7(..)). I'll report back to confirm those two lines of code once I have it working.