Skip to content

FIX pwm release logic and split logic #10

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

Open
wants to merge 1 commit into
base: main
Choose a base branch
from

Conversation

hamlet-lee
Copy link
Contributor

This approach uses the release() @gpgreen mentioned earlier in #8

This PR remove the split() and replace it with channels() which returns mutable references to channels.

This ensures the lifetime of the returned mutable reference doesn't exceed that of PwmHz.

This PR also changed stuff which release() function's returned, to support reconstruct a PwmHz again.

I have tested this approach on my embedded device, it works.

@gpgreen
Could you please review and confirm if this solution is acceptable?

@gpgreen
Copy link
Contributor

gpgreen commented Jun 20, 2025

Thanks for the work, I hope my answer doesn't discourage you.

The advantage of using 'split', is that it allows use of the individual channel in different processes/tasks/threads, and yet ensure that there is no conflict in the hardware. Returning the reference doesn't allow you to use the channel that way without wrapping it up with a mutex or similar construct. However, you could already do that by not calling split and using the methods on the timer with the channel number argument, with the timer wrapped. So I don't see that your solution is better than what is already available.

I can think of several ways of fixing the release/split conundrum correctly. There are probably more, I am not a rust expert.

  1. add 'unsafe' to the 'release' method, and return the channels as the original pins also. This would require some macro work to do the pin conversion. The method is then commented to say that the channels must be stopped in their processes/tasks/threads before release can be called. This leaves it up to the user to make sure it is safe to call release.
  2. Track the channels in the timer using an Option for each. Split would then replace the channel with None, which trackes whether the timer and channel are in the same process. Then add methods to return the channel and repopulate the Option. Now you can verify that all channels are present, they can be stopped and returned in the release.
  3. What I believe is the best way, is to have separate types for the timer with the channels, and the timer that is split, changing the type as the channels are split off, or collected back. The release method would then only be on the collected type. This is somewhat similar to 2, but more canonical Rust, and easier to follow as a user.

All of these are significant work, and would require macro work probably, which is why I haven't already done them.

Right now the api is broken, the way to fix it temporarily is to remove the release method, as it can't be used safely.

@gpgreen
Copy link
Contributor

gpgreen commented Jun 20, 2025

I haven't removed the release method yet, because you are working on the code. If/when you are done, and you didn't remove it or fix it, then I'll do that.

@gpgreen
Copy link
Contributor

gpgreen commented Jun 20, 2025

I just realized maybe you didn't see the channel number methods, see pwm.rs starting at line 436 for what I mean

@hamlet-lee
Copy link
Contributor Author

What do you mean by "macro work"?
Is it used to map PwmChannels to original pins?

In this PR I have done some workaround: keep the original pins in struct, and return it back when release.
May this way work for temporary?

@gpgreen
Copy link
Contributor

gpgreen commented Jun 24, 2025

The macros that turn the pin into a channel can be used to reverse the process, then we don't have to store both in the struct

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