David-OConnor / stm32-hal

This library provides access to STM32 peripherals in Rust.

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

GPIO_ASCR not used when setting ADC for L4x6 family

AShriki opened this issue · comments

Hi, great work on this crate! I noticed that the required GPIO_ASCR register (connects gpio to analog mux) for the l4x6 and few other specific MCUs is not currently used (see the reference manual, section 8.5.12).
I fixed it locally for L4x6 by changing
https://github.com/David-OConnor/stm32-hal/blob/main/src/gpio.rs#L52
to
#[derive(Copy, Clone, PartialEq)]
and adding

#[cfg(feature = "l4x6")]
if value == PinMode::Analog {
    set_field!(
        self.regs(),
        self.pin,
        ascr,
        asc,
        bit,
        true,
        [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15]
    );
} else {
    set_field!(
        self.regs(),
        self.pin,
        ascr,
        asc,
        bit,
        false,
        [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15]
    );
}

to
https://github.com/David-OConnor/stm32-hal/blob/main/src/gpio.rs#L786

Done, on repo. Instead of automatically setting as analog, added a l4x6-only method: connect_to_adc().

And... interesting! The feature-gating here is a bit more subtle than it seems: The issue lies in the PAC breaking out the L4 series as l4x6 etc, but per the RM:

For the ADC, DAC, OPAMP and COMP, configure the desired I/O in analog mode
in the GPIOx_MODER register and configure the required function in the ADC,
DAC, OPAMP, and COMP registers. For the ADC, it is necessary to configure the
GPIOx_ASCR register (only for STM32L47x/L48x)

So, this is only on L47x and L48x, and only when using with the ADC. (The register def also confirms it's an ADC-only thing). From a skim, it seems that the main (only?) 47x and 48x variants are 476, and 486, so I'm happy with the way you set this up! AFAIK, this functionality isn't included any other STM32 families; only those L4 variants.

Thanks! If you think that's interesting the L1 series takes a similar, but slightly different approach to adc muxing, but I didn't read into it too much.

In new release