Benedikt ca04263b7b
RMT: Make PulseCode a newtype rather than an extension trait (#3884)
* RMT: make PulseCode a newtype rather than an extension trait on u32

This has several advantages:
- the meaning of `u32` used as pulse code becomes more explicit
- it allows using `PulseCode` methods in `const` context (which is otherwise
  not possible because Rust does not presently support associated const
  fn in traits).
- it allows providing custom `defmt::Format` and `core::fmt::Debug` impls
  for `PulseCode`, greatly helping with debugging

I have taken the liberty to implement `core::fmt::Debug` in a slightly
non-standard way: The most natural implementation would probably use a
struct-style output like

  PulseCode { length1: 42, level1: Level::High, length2: 24, level2: Level::Low }

However, that is very lengthy and not really human-readable anymore when
dealing with an array of `PulseCode`s. Thus, this uses the more compact format

  PulseCode(H 42, L 24)

This provides `u32: From<PulseCode>` and `PulseCode: From<u32>` impls and
converts rx and tx methods to accept `impl Into<PulseCode>` and
`impl From<PulseCode>`, respectively.
This should help to reduce how much user code needs to change (but replacing
`u32` type annotations with `PulseCode` will be required).

By applying `#[repr(transparent)]` to `struct PulseCode`, it is
guaranteed to match the layout of `u32` such that accessing the hardware
buffer via `*mut PulseCode` pointers is valid.

* RMT: Address review on PulseCode refactor, further refine the interface a bit

- introduce Level::const_from and Level::const_into
- pre-compute a few more shifts and masks (this is unlikely to affect
  generated code, since the compiler would have const propagated them
  anyway, but it helps to keep the PulseCode impl more readable)
- improve docstrings
- remove PulseCode::empty in favor of PulseCode::default, keep
  PulseCode::end_marker for now (but it's not completely clear that this
  interface is optimal; see also the FIXME note on adding a variant of
  this methods that supports settings levels and length1)
- make PulseCode::new_unchecked pub and shuffle it around in the code so
  that it doesn't show up first in the docs
- factor out PulseCode::symbolX methods for internal use in debug
  formatting
- sprinkle a few more #[inline] to be totally sure that this really adds
  no overhead over having plain u32
- convert methods receivers from &self to self given that PulseCode is
  Copy (which probably doesn't matter much since all these methods
  should always be inlined)
- remove PulseCode::as_u32() and make the tuple field pub: There's no
  safety implication of marking this pub, and field access still
  provides a const-compatible way to obtain the wrapped value
2025-08-08 07:51:49 +00:00
..
2025-08-05 07:25:39 +00:00
2025-07-21 15:10:35 +00:00
2025-06-02 11:12:44 +00:00
2025-07-21 15:10:35 +00:00
2025-07-17 12:23:51 +00:00
2025-06-13 13:42:09 +00:00
2025-06-13 13:56:52 +00:00
2025-07-21 15:10:35 +00:00