-
Notifications
You must be signed in to change notification settings - Fork 363
RMT: Use new Encoder trait for Tx data #4604
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
base: main
Are you sure you want to change the base?
Conversation
in anticipation of adding another, user-visible type which will be named RmtWriter This type is private, so no changelog or migration guide entry required.
which was probably of little value, anyway, and also in preparation for adding more sophisticated Encoder data types
…writer.state read-only
Previously, we stored &mut dyn Encoder and dynamically dispatched the Encoder::encode method. Now, we store &mut dyn EncoderExt and dynamically dispatch EncoderExt::write with the expectation that Encoder::encode should be inlined in EncoderExt::write (which is the only caller, and its Encoder implementations in esp-hal are also marked as #[inline(always)]). This might allow for small optimizations, since the RmtWriter type will typically not need to be constructed on the stack, but can be kept in registers.
to ensure that the Encoder-related refactoring didn't break anything
&mut dyn EncoderExt is a fat pointer to the data and the vtable (likely in flash), but we only need a single entry of the vtable. Thus, implement our own pointer type, which will avoids the indirection via the vtable.
|
Would you mind granting me HIL access here? Thanks! |
NonNull::from_mut is new in 1.89
| #[derive(Clone, Debug)] | ||
| pub struct IterEncoder<D> | ||
| where | ||
| D: Iterator<Item = PulseCode>, | ||
| { | ||
| data: D, | ||
| } | ||
|
|
||
| // If the input data was not exhausted, update offset as | ||
| // | ||
| // | initial | offset | max_count | new offset | | ||
| // | ------- + ----------- + ----------- + ----------- | | ||
| // | true | 0 | memsize | 0 | | ||
| // | false | 0 | memsize / 2 | memsize / 2 | | ||
| // | false | memsize / 2 | memsize / 2 | 0 | | ||
| // | ||
| // Otherwise, the new position is invalid but the new slice is empty and we won't use the | ||
| // offset again. In either case, the unsigned subtraction will not underflow. | ||
| self.offset = memsize as u16 - max_count as u16 - self.offset; | ||
|
|
||
| // The panic can never trigger since count <= data.len()! | ||
| data.split_off(..count).unwrap(); | ||
| if data.is_empty() { | ||
| self.state = WriterState::Done; | ||
| impl<D> IterEncoder<D> | ||
| where | ||
| D: Iterator<Item = PulseCode>, | ||
| { | ||
| /// Create a new instance that transmits the provided `data`. | ||
| pub fn new(data: impl IntoIterator<IntoIter = D>) -> Self { | ||
| Self { | ||
| data: data.into_iter(), | ||
| } | ||
| } | ||
| } |
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.
Do you actually need anything more than this? Copying from a slice, or converting from a bitstream can both be expressed as an iterator. Wouldn't it be better to not introduce a whole subsystem for something that could be formulated in user code with common enough Rust machinery?
b04afae to
36c5264
Compare
[HIL trust list]Trusted users for this PR (click to expand) |
|
Author @wisp3rwind was trusted for this PR via the |
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-packagescommand to ensure that all changed code is formatted correctly.CHANGELOG.mdin the proper section.Extra:
Pull Request Details 📖
This changes the input data type for RMT Tx methods from
&[PulseCode]to&mut impl EncoderwhereEncoderis conceptually similar toIterator<Item = PulseCode>, but allows for more efficient code in many cases.... (TODO: add more details on how I got here)
Cf. also the IDF encoder type: https://docs.espressif.com/projects/esp-idf/en/latest/esp32c3/api-reference/peripherals/rmt.html#rmt-rmt-encoder
Testing
HIL tests, incl. new ones.
Closes #1768