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

[RSDK-10188] esp-idf v5 ADC APIs #449

Open
wants to merge 3 commits into
base: RSDK-8990-platform-modernization
Choose a base branch
from

Conversation

mattjperez
Copy link
Member

The main differences:

  1. AdcChannelDriver is initialized with an AdcDriver, example
  2. The `attenuation setting is passed as an struct input to the configuration instead of as a type parameter when initializing the channel driver.
  3. Removed the Arc<Mutex<>> from the struct entirely

@mattjperez mattjperez requested a review from a team as a code owner March 25, 2025 22:07
@mattjperez mattjperez changed the base branch from main to RSDK-8990-platform-modernization March 25, 2025 22:07
Copy link
Member

@npmenard npmenard left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done with first pass

unsafe { ADC1::new() },
&Config::new().calibration(true),
)?));
let adc1 = AdcDriver::new(unsafe { ADC1::new() })?;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

not sure how this would work, you would be configuring the adc for each analog reader so if you have more than one can we actually instantiate more that one ADC?

Copy link
Member Author

@mattjperez mattjperez Mar 27, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this was porting the same logic from the previous implementation, however we determined a few things:

  1. the previous implementation was wrong, initializing ADC1 multiple times
  2. the previous implementation still allowed for multiple adc pins to be configured without user-observable 'error',
  3. the new ADC1 does not 'appear' to cause any issues when initialized more than once, however
  4. the new AdcDriver will give a recoverable error if you try to initialize multiple with the same ADC (ex ADC1)
    I've since moved the AdcDriver init to outside of the map and wrapped in an Arc. Confirmed that multiple adc pins come up when configured.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

as a follow-up, we should probably either:
a. store the board Peripherals in our Esp32Board struct
b. store initialized Arc<Driver>s in our board

let adc1 = AdcDriver::new(unsafe { ADC1::new() })?;
let config = AdcChannelConfig {
attenuation: DB_11,
calibration: Calibration::Line,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What does that do and why do we set it to line?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

previously we did &Config::new().calibration(true). The Calibration enum has three variants: None, Line, Curve according to the source code. However, only None and Line are available to our build. So I used Line to in place of the previous calibration(true).

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

make sense 👌

pub struct Esp32AnalogReader<'a, const A: u32, T: ADCPin> {
channel: AdcChannelDriver<'a, A, T>,
driver: Arc<Mutex<AdcDriver<'a, T::Adc>>>,
pub struct Esp32AnalogReader<'a, T: ADCPin, M: Borrow<AdcDriver<'a, T::Adc>>> {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't like the increase of complexity of types parameters, is there a way we can make it more readable. Like storing only the driver and building the channel on each read? Is building a channel expensive?

Copy link
Member Author

@mattjperez mattjperez Mar 27, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think that may actually make the type even more complex.

At the very least the new input parameters would either need to be:

  1. (name: String, driver: AdcDriver<'d, T::Adc>, pin: impl Peripheral<P = T> + 'd, config: AdcChannelConfig) if we want to create the AdcChannelDriver on-demand
  2. (name: String, adc: impl Adc, pin: impl Peripheral<P = T> + 'd, config: AdcChannelConfig) if we want to handle both the AdcDriver and AdcChannelDriver initialization in the Esp32AnalogReader.

with the struct holding the proper generics for whichever route we go (storing the pin, adc, adcdriver, etc)

&Config::new().calibration(true),
)?));
let adc1 = AdcDriver::new(unsafe { ADC1::new() })?;
let config = AdcChannelConfig {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

that's new and cool might be a candidate for config

@mattjperez mattjperez requested a review from npmenard March 27, 2025 18:47
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

Successfully merging this pull request may close these issues.

2 participants