-
Notifications
You must be signed in to change notification settings - Fork 221
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
[WIP} introduce overflow interrupt handing for led #2155
base: main
Are you sure you want to change the base?
Conversation
@bugadani Additionally, while reviewing the Thank you for your time and assistance. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for bearing with me, I can at least understand this PR :) However, I still have some concerns, one of which is related to the PR, the other one isn't necessarily.
esp-hal/src/ledc/mod.rs
Outdated
.timer(0) | ||
.conf() | ||
.modify(|_, w| w.para_up().set_bit()); | ||
} | ||
|
||
/// Return a new timer | ||
pub fn get_timer<S: TimerSpeed>(&self, number: timer::Number) -> Timer<'d, S> { | ||
Timer::new(self.ledc, number) | ||
pub fn get_timer<S: TimerSpeed>(&self, number: timer::Number) -> Timer<S> { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So, I guess this isn't new, but I can get any number of references to the same timer, then I can configure that timer in different ways. If that is intentional, creating a Timer shouldn't even need the Ledc object. If that is not intentional, this will somehow need to be prevented.
And if you're touching this code, please remove the get_
prefix from the function name.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
To address the issue of "getting any number of references to the same timer," would it make sense to take an approach similar to what is used in Rmt
? The following code is taken from rmt.rs
:
pub struct Rmt<'d, M>
where
M: crate::Mode,
{
_peripheral: PeripheralRef<'d, crate::peripherals::RMT>,
/// RMT Channel 0.
pub channel0: ChannelCreator<M, 0>,
/// RMT Channel 1.
pub channel1: ChannelCreator<M, 1>,
/// RMT Channel 2.
pub channel2: ChannelCreator<M, 2>,
/// RMT Channel 3.
pub channel3: ChannelCreator<M, 3>,
phantom: PhantomData<M>,
}
In this approach, we construct the channels and timers in advance and ensure they are moved. However, this would require a significant refactoring, so it might be better to address this in a separate PR.
Regarding the removal of the get_
prefix from the function name, as I reintroduced the lifetime, so I the function signature remains the same in this PR, which is why I haven't removed the prefix here.
esp-hal/src/ledc/timer.rs
Outdated
} | ||
|
||
/// Timer struct | ||
pub struct Timer<'a, S: TimerSpeed> { | ||
ledc: &'a crate::peripherals::ledc::RegisterBlock, | ||
pub struct Timer<S: TimerSpeed> { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I am not sure but I think we don't want the Timer
s to potentially survive our use of LEDC
. If the user takes a Timer, drops Ledc, reinitializes it and grabs the same Timer, we'll end up in a bad spot.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you for pointing this out. I have reintroduced the lifetime parameter for the timer.
Can you clarify, please? |
Technically, you need to use a critical section (or better, esp_hal::lock) if it is possible to modify a register from multiple places. Essentially in every case where a type is |
Thank you for your response. To clarify my previous message, I followed the structure of the
However, the key difference between the two is that esp-hal/esp-hal/src/pcnt/unit.rs Lines 310 to 311 in 45806df
This allows My question is: Is there any other way to solve this problem more elegantly? |
I don't see a good solution here short of rewriting the whole driver. Which we will need to do, it doesn't look like the best designed driver to me... Regardless, let's accept that the situation is not ideal. You can require This gets us to a place where a timer can be configured and be made accessible. Next, I don't think With these two changes, I think the example has a chance of working, with a structure like this:
It's incorrect (you can reconfigure the timer while you have active channels) but that's the best I can come up with, given what we have. |
Yes - this driver is known to be the ugly duckling |
I guess this is blocked for now, so added the label; if this is incorrect please feel free to remove it. |
Thank you for your contribution!
We appreciate the time and effort you've put into this pull request.
To help us review it efficiently, please ensure you've gone through the following checklist:
Submission Checklist 📝
cargo xtask fmt-packages
command to ensure that all changed code is formatted correctly.CHANGELOG.md
in the proper section.Extra:
Pull Request Details 📖
Description
This patch refactors the
ledc
(LED PWM Controller) module, simplifying the code by removing direct references toRegisterBlock
. This change eliminates the need for a lifetime specifier in certain structs, making the code more flexible and easier to maintain.Additionally, new functionality has been added to support overflow counter management and overflow interrupt handling for channels on specific chips like ESP32S3.
Key changes include:
An example (
ledc_pulse_counting.rs
) has been added, showcasing how to generate a PWM signal with a predefined number of pulses and handle the overflow interrupt.Testing
Currently,
ledc_pulse_counting.rs
cannot compile due to thread safe issues.I tested the code after applying a workaround in
ledc_pulse_counting.rs
. It works fine on my esp32s3.