David-OConnor / stm32-hal

This library provides access to STM32 peripherals in Rust.

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Power not enabled for GPIO on STM32F3xx?

ctamblyn opened this issue · comments

First of all, thanks for writing this awesome library!

While experimenting with this crate on an STM32F3 Discovery board, it didn't seem like the power was getting enabled for GPIO port E when creating a pin using Pin::new(...).

Here's a fairly minimised example of what I'm doing:

#![no_std]
#![no_main]

use panic_semihosting as _;

use cortex_m_rt::entry;
use stm32_hal2::gpio::{Pin, PinMode, Port};

#[entry]
fn main() -> ! {
    let mut led = Pin::new(Port::E, 9, PinMode::Output);
    led.set_high();

    loop {}
}

And this is my Cargo.toml:

[package]
name = "stm32-test"
version = "0.1.0"
edition = "2018"

[dependencies]
cortex-m-rt = "0.6.15"
cortex-m-semihosting = "0.3.5"
panic-semihosting = "0.5"

[dependencies.stm32-hal2]
version = "1.3.1"
features = ["f303", "f3rt"]

# this lets you use `cargo fix`!
[[bin]]
name = "stm32-test"
test = false
bench = false

[profile.dev]
opt-level = 1
codegen-units = 16
debug = true
lto = false

[profile.release]
opt-level = "s"     # optimize for size
codegen-units = 1   # better optimizations
debug = true        # symbols are nice and they don't increase the size on Flash
lto = true          # better optimizations

Running the above should cause the LED attached to pin PE9 to light up, but does not.

Poking around in the implementation of Pin::new(), I think the cause is the following bit of code:

pub fn new(port: Port, pin: u8, mode: PinMode) -> Self {
    // ... snip ...
                Port::E => {
                    cfg_if! {
                        if #[cfg(feature = "f3")] {
                            if rcc.ahbenr.read().iopeen().bit_is_clear() {
                                rcc_en_reset!(ahb1, iopa, rcc);
                            }
    // ... snip ...
}

If I'm understanding that correctly, it's writing to IOPAEN (enabling the clock for port A) when it should be writing to IOPEEN (section 9.4.6 of the reference manual). I think ports (other than A) are all similarly affected on the F3.

Good catch. It was broken for all ports. Fixed in latest commit.

Can confirm that the latest commit results in a nicely illuminated LED on my board :)

Sweet!