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

Add support for ESP internal temperature sensor #337

Merged
merged 21 commits into from
Sep 9, 2024
Merged

Add support for ESP internal temperature sensor #337

merged 21 commits into from
Sep 9, 2024

Conversation

GamerBene19
Copy link
Contributor

What the title says. Currently very much WIP. PR created to help give feedback.

Closes #333

@GamerBene19
Copy link
Contributor Author

@Vollbrecht FYI

src/temp_sensor.rs Outdated Show resolved Hide resolved
src/temp_sensor.rs Outdated Show resolved Hide resolved
src/temp_sensor.rs Outdated Show resolved Hide resolved
src/temp_sensor.rs Outdated Show resolved Hide resolved
Cargo.toml Outdated Show resolved Hide resolved
Copy link
Collaborator

@Vollbrecht Vollbrecht left a comment

Choose a reason for hiding this comment

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

i added some comments, piece by piece we will get there.

@Vollbrecht
Copy link
Collaborator

The interesting point is when you start implement the callback functions provided by the driver. It should allow you to setup a callback on certain temperature condition. In our crate terminology we call it a subscribe, if you want to peak in other drivers how similar things are handled.

src/temp_sensor.rs Outdated Show resolved Hide resolved
src/temp_sensor.rs Outdated Show resolved Hide resolved
@Vollbrecht
Copy link
Collaborator

since it seams to work with the flags we are now using in esp-idf-sys. We could also change it here. Rustcompiler give us the flag as esp_idf_soc_temp_sensor_supported.

@Vollbrecht
Copy link
Collaborator

If you are unsure how to proceed now to get the rest of the exposed api integrated, we can wrap it up here and i can integrate the rest ontop of it, or if you feel advantageous we can go deeper getting the callbacks to work with the api.
I am not sure whats your background so i leave it up to you.

@GamerBene19
Copy link
Contributor Author

GamerBene19 commented Nov 20, 2023

since it seams to work with the flags we are now using in esp-idf-sys. We could also change it here. Rustcompiler give us the flag as esp_idf_soc_temp_sensor_supported.

Would that then be #[cfg(esp_idf_soc_temp_sensor_supported)]?

If you are unsure how to proceed now to get the rest of the exposed api integrated, we can wrap it up here and i can integrate the rest ontop of it, or if you feel advantageous we can go deeper getting the callbacks to work with the api. I am not sure whats your background so i leave it up to you.

If you don't mind me asking questions and it perhaps taking a bit longer then if you would do it yourself, I would like to try it. If I find out it's too much work we can still only merge my basic support in the future.

@jwhitlark
Copy link

jwhitlark commented Jun 12, 2024

Is there any further progress on this? I’m having problems with a chip overheating and would like to quantify the problem better. Usable basic support would be helpful, if other work is paused. I’d be happy to help out, although I’m new enough to this stuff I don’t know how much use I’d be.

@lu-zero
Copy link
Contributor

lu-zero commented Sep 8, 2024

Since I cannot update the PR myself I opened a rebase of it.

@GamerBene19
Copy link
Contributor Author

Is there any further progress on this? I’m having problems with a chip overheating and would like to quantify the problem better. Usable basic support would be helpful, if other work is paused. I’d be happy to help out, although I’m new enough to this stuff I don’t know how much use I’d be.

Sorry for the late reply, I forgot to answer back then.

As from my side: I might find some time to work on this in the next few weeks, but I likely need some time to get back into it (which repo of esp-rs does what, what is still missing, ...) and some more help (see question above). If someone else wants to do it instead, feel free :)

I'm pinging @ivmarkov too since he was asking about the state of the PR that @lu-zero opened.

@lu-zero
Copy link
Contributor

lu-zero commented Sep 8, 2024

I spent a bit of time to try to get it to at least pass the CI, I guess the remaining bits is to wire in the Peripheral and figure out if there are remaining failures.

@ivmarkov
Copy link
Collaborator

ivmarkov commented Sep 8, 2024

I spent a bit of time to try to get it to at least pass the CI, I guess the remaining bits is to wire in the Peripheral and figure out if there are remaining failures.

I'm pretty sure we can finish the driver still today or so. It is so simple, that it needs an extra couple of hours at most. And I'll assist of course. :) What I can't help with is putting my own time to test it, but I'm hopeful you can do that.

@GamerBene19
Copy link
Contributor Author

I'm pretty sure we can finish the driver still today or so.

I'm back at home and have a few hours free time this evening. I'll try to address (some of) the remaining issues.

@lu-zero Do you mind if I cherry-pick your commits into my branch/this PR?

@GamerBene19
Copy link
Contributor Author

since it seams to work with the flags we are now using in esp-idf-sys. We could also change it here. Rustcompiler give us the flag as esp_idf_soc_temp_sensor_supported.

Would that then be #[cfg(esp_idf_soc_temp_sensor_supported)]?

Can (and should) we use this flag instead of #[cfg(all(not(esp32)))]?

@GamerBene19
Copy link
Contributor Author

@ivmarkov Regarding the peripheral, I've

  • added crate::impl_peripheral!(TempSensor); in temp_sensor.rs
  • added
    #[cfg(all(not(esp32), esp_idf_version_major = "5"))]
    pub temp_sensor: temp_sensor::TempSensor,
    
    to Peripherals struct
    and
    #[cfg(all(not(esp32), esp_idf_version_major = "5"))]
    temp_sensor: temp_sensor::TempSensor::new(),
    
    to it's impl
  • Adjusted the function signature of the driver constructor to be
    impl<'d> TempSensorDriver {
    pub fn new(
        config: &TempSensorConfig,
        temp_periph: impl Peripheral<P = TempSensor> + 'd,
        _p: PhantomData<&'d mut ()>,
    ) -> Result<Self, EspError>
    

What do I do with temp_periph now? Do I even need to use it, or can I simply prefix it with _?

@ivmarkov
Copy link
Collaborator

ivmarkov commented Sep 9, 2024

@ivmarkov Regarding the peripheral, I've

  • added crate::impl_peripheral!(TempSensor); in temp_sensor.rs

  • added

    #[cfg(all(not(esp32), esp_idf_version_major = "5"))]
    pub temp_sensor: temp_sensor::TempSensor,
    

    to Peripherals struct
    and

    #[cfg(all(not(esp32), esp_idf_version_major = "5"))]
    temp_sensor: temp_sensor::TempSensor::new(),
    

    to it's impl

  • Adjusted the function signature of the driver constructor to be

    impl<'d> TempSensorDriver {
    pub fn new(
        config: &TempSensorConfig,
        temp_periph: impl Peripheral<P = TempSensor> + 'd,
        _p: PhantomData<&'d mut ()>,
    ) -> Result<Self, EspError>
    

What do I do with temp_periph now? Do I even need to use it, or can I simply prefix it with _?

It should be instead:

impl<'d> TempSensorDriver<'d> {
pub fn new(
    config: &TempSensorConfig,
    _sensor: impl Peripheral<P = TempSensor> + 'd,
) -> Result<Self, EspError>

Notice:

  • That the driver is now lifetimed by 'd. And it should be
     pub struct TempSensorDriver<'d> {
         ptr: ...
         _p: PhantomData<&'d mut ()>,
     }
  • The removal of _p from the constructor function. The _p is just a zero-sized trick so that the driver "remembers" that it might get the peripheral by &'d mut (i.e. the peripheral - when passed by &mut stays mutably borrowed until the driver is dropped)

Also, you need to initialize the _p in TempSensorDriver simply with ... PhantomData. No need to pass the PhantomData instance on constructor, as already mentioned above. That's an internal driver detail/trick.

@ivmarkov
Copy link
Collaborator

ivmarkov commented Sep 9, 2024

Also - and if it is not clear - the 'p time becomes simply 'static if you - rather than passing the peripheral by &mut pass it by moving, i.e. TempSensorDriver::new(peripherals.temp_sensor). The type of this expression is TempSensorDriver<'static>, so the 'p lifetime does not hurt the "straightforward" use case. Of course, with the "straightforward" use case, you can no longer re-use the peripheral once the driver is dropped. That's why the "other" use case exists, where you pass the peripheral by &mut...

src/temp_sensor.rs Outdated Show resolved Hide resolved
@ivmarkov
Copy link
Collaborator

ivmarkov commented Sep 9, 2024

@GamerBene19 @lu-zero Once you feel this is ready (should be, once you address the non-panicing behavior of the dtor), please un-draft it so that we can see if it builds OK.

Post-merge I might implement the usual subscribe / subscribe_nonstatic dance as well as its more ergonomic wait async variant, so that folks don't have to constantly poll the sensor in a loop so as to detect when the device starts to over-heat...

@GamerBene19 GamerBene19 marked this pull request as ready for review September 9, 2024 13:19
@GamerBene19
Copy link
Contributor Author

since it seams to work with the flags we are now using in esp-idf-sys. We could also change it here. Rustcompiler give us the flag as esp_idf_soc_temp_sensor_supported.

Would that then be #[cfg(esp_idf_soc_temp_sensor_supported)]?

Can (and should) we use this flag instead of #[cfg(all(not(esp32)))]?

@ivmarkov Do you have an opinion here?

@ivmarkov
Copy link
Collaborator

ivmarkov commented Sep 9, 2024

@GamerBene19 Oh one more thing:

unsafe impl<'d> Send for TempSensorDriver<'d> {}

This is necessary so that you can create the driver in one thread and then send it to another (as long as the periph is not mutably borrowed, but owned by the driver). Sending the driver should be completely safe (even if the driver is not thread-safe) so why not?

@ivmarkov
Copy link
Collaborator

ivmarkov commented Sep 9, 2024

since it seams to work with the flags we are now using in esp-idf-sys. We could also change it here. Rustcompiler give us the flag as esp_idf_soc_temp_sensor_supported.

Would that then be #[cfg(esp_idf_soc_temp_sensor_supported)]?

Can (and should) we use this flag instead of #[cfg(all(not(esp32)))]?

@ivmarkov Do you have an opinion here?

First of all a small nit: #[cfg(all(not(esp32)))] should be just #[cfg(not(esp32))] or else Clippy might kick-in.
With that said, either the above ^^^ or #[cfg(esp_idf_soc_temp_sensor_supported)] would work, up to you. Though I'm surprised that the soc flags are exposed. We are only supposed to support CONFIG_ ESP IDF entries (and only boolean ones) as Rust #[cfg]s; not sure how the _SOC_ stuff sneaked in, but yes, why not given that it is in there?

@ivmarkov
Copy link
Collaborator

ivmarkov commented Sep 9, 2024

@GamerBene19 @lu-zero I guess from your side this is ready for merge?

@lu-zero
Copy link
Contributor

lu-zero commented Sep 9, 2024

I'm happy with what is done and since I have access to this branch I can close my PR in favor of this one.

@GamerBene19
Copy link
Contributor Author

@GamerBene19 @lu-zero I guess from your side this is ready for merge?

Unfortunately I currently don't have a functioning ESP with which I could test this code. I think it should work given that there were no "real" changes to the logic, but I think it makes sense to test it before merging.

Also I'd like to try using #[cfg(esp_idf_soc_temp_sensor_supported)] as it is more future proof, I've just pushed a commit to try it out.

@ivmarkov
Copy link
Collaborator

ivmarkov commented Sep 9, 2024

@GamerBene19 @lu-zero I guess from your side this is ready for merge?

Unfortunately I currently don't have a functioning ESP with which I could test this code. I think it should work given that there were no "real" changes to the logic, but I think it makes sense to test it before merging.

Also I'd like to try using #[cfg(esp_idf_soc_temp_sensor_supported)] as it is more future proof, I've just pushed a commit to try it out.

@lu-zero Can you check the PR on an MCU?

@lu-zero
Copy link
Contributor

lu-zero commented Sep 9, 2024

Checked and seems working at least on the c3 and c6, added an example while at it. Shall we keep or remove the get_kelvin and get_fahrenheit?

@lu-zero
Copy link
Contributor

lu-zero commented Sep 9, 2024

Not sure why I cannot really push on the branch but here is the example used https://github.com/GamerBene19/esp-idf-hal/pull/1

@ivmarkov
Copy link
Collaborator

ivmarkov commented Sep 9, 2024

Checked and seems working at least on the c3 and c6, added an example while at it. Shall we keep or remove the get_kelvin and get_fahrenheit?

Ah, keep them - not so important.

Can't see the example in the PR though?

@GamerBene19
Copy link
Contributor Author

Not sure why I cannot really push on the branch

As far as I can tell you should be able to, you have collaborator access and I don't see an option to explicitly grant you write permissions.

Can't see the example in the PR though?

It's here now

@ivmarkov
Copy link
Collaborator

ivmarkov commented Sep 9, 2024

Not sure why I cannot really push on the branch

As far as I can tell you should be able to, you have collaborator access and I don't see an option to explicitly grant you write permissions.

Can't see the example in the PR though?

It's here now

Ah, CI failed. Look at the other examples as to how to build the example only for certain mcus.

@lu-zero
Copy link
Contributor

lu-zero commented Sep 9, 2024

Github does not let me push to that branch... @GamerBene19 pick the amended commit from lu-zero@9ce159f

@lu-zero
Copy link
Contributor

lu-zero commented Sep 9, 2024

Sorry, pick the patch again, forgot to move the use inside the main.

@ivmarkov
Copy link
Collaborator

ivmarkov commented Sep 9, 2024

Thank you both! Merging.

@ivmarkov ivmarkov merged commit a619f13 into esp-rs:master Sep 9, 2024
10 checks passed
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.

Missing support for internal temperature sensor
5 participants