Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

STM32G4: Setting the differential input mode for ADC channel 18 causes a panic #3625

Open
G-Levine opened this issue Dec 8, 2024 · 0 comments

Comments

@G-Levine
Copy link
Contributor

G-Levine commented Dec 8, 2024

The error:

`ERROR panicked at /Users/rael/.cargo/git/checkouts/stm32-data-generated-cb34dad5f3150296/15c2d08/stm32-metapac/src/chips/stm32g431vb/../../peripherals/adc_g4.rs:702:13:
assertion failed: n < 18usize
└─ panic_probe::print_defmt::print @ /Users/rael/.cargo/registry/src/index.crates.io-6f17d22bba15001f/panic-probe-0.3.2/src/lib.rs:104`

This is the assert that gets triggered: https://github.com/embassy-rs/stm32-data-generated/blob/15c2d08f1b0e5877c787bddb1f35a49cbe180f36/stm32-metapac/src/peripherals/adc_g4.rs#L702

Minimal code to reproduce:

#![no_std]
#![no_main]

use embassy_executor::Spawner;
use embassy_stm32::{
    adc::{Adc, AdcChannel},
    opamp::{OpAmp, OpAmpGain, OpAmpSpeed},
    peripherals,
};
use {defmt_rtt as _, panic_probe as _};

const OP_AMP_SPEED: OpAmpSpeed = OpAmpSpeed::HighSpeed;
const OP_AMP_GAIN: OpAmpGain = OpAmpGain::Mul16;

#[embassy_executor::main]
async fn main(_spawner: Spawner) {
    let mut config = embassy_stm32::Config::default();
    config.rcc.mux.adc12sel = embassy_stm32::rcc::mux::Adcsel::SYS;

    let mut p = embassy_stm32::init(config);

    let mut adc1 = Adc::new(p.ADC1);
    let mut adc2 = Adc::new(p.ADC2);

    let mut opamp3 = OpAmp::new(p.OPAMP3, OP_AMP_SPEED);

    let mut vrefint_channel = adc1.enable_vrefint().degrade_adc();
    let mut opamp3_adc_channel = opamp3.buffer_int(p.PB0, OP_AMP_GAIN).degrade_adc();

    adc1.set_differential(&mut vrefint_channel, true);
    adc2.set_differential(&mut opamp3_adc_channel, true);
}

Either of these calls to set_differential will cause the panic to happen (you can comment one out to see the behavior of the other one). Vrefint corresponds to channel 18 for ADC1, and OPAMP3's internal output corresponds to channel 18 for ADC2.

This appears to be an off-by-one bug -- the G4 actually has 19 channels per ADC, not 18 (see the screenshots below from the reference manual). The assumption of 18 channels seems to be present in more than one place in the code. Besides the assert statement in stm32-metapac/src/peripherals/adc_g4.rs linked above, here are a couple more examples that I found:

Screenshot 2024-12-07 at 8 55 54 PM Screenshot 2024-12-07 at 9 39 44 PM Screenshot 2024-12-07 at 9 39 38 PM
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant