-
Notifications
You must be signed in to change notification settings - Fork 33
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
Cleanup IOMUXC feature #75
Changes from all commits
bfac5ef
86d330c
88c735b
ba9614a
df6e75f
a510149
906895b
b573249
1f2c62a
6d5b4f5
6ff4795
345272d
250848d
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -5,5 +5,4 @@ members = [ | |
|
||
"imxrt-iomuxc", | ||
"imxrt-iomuxc/imxrt-iomuxc-build", | ||
"imxrt-iomuxc/imxrt106x-iomuxc", | ||
] |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -7,9 +7,112 @@ | |
- `steal()` the top-level `Peripherals` object. The `steal()` method lets users use the `imxrt_hal` | ||
as an RTIC device. | ||
- DMA `Memcpy` may support interrupt handling | ||
- A new interface for pad configuration, supported by the `imxrt-iomuxc` crate family. See the Changed | ||
section for migration information. | ||
|
||
### Changed | ||
|
||
- **BREAKING** The pad configuration interface has simplified. Users will use the | ||
interface exposed by the `imxrt-iomuxc` crate family. This section describes how you might | ||
update your 0.3 (and earlier) code for the new interface. | ||
|
||
- *Naming*: the `IOMUXC` instance exposes pads with a new naming convention. Previously, member | ||
accessed resembled | ||
|
||
```rust | ||
let peripherals = imxrt_hal::Peripherals::take().unwrap(); | ||
peripherals.iomuxc.gpio_ad_b1_02; | ||
``` | ||
|
||
Now, IOMUXC member access resembles | ||
|
||
```rust | ||
peripherals.iomuxc.ad_b1.p02 | ||
``` | ||
|
||
Generally, remove the "`gpio_`" prefix, and replace the second underscore with member access and | ||
a "`p`" symbol. | ||
|
||
- *Pad Types*: The interface simplifies the pad types, removing the alternate type state. | ||
Usages resembling | ||
|
||
```rust | ||
use imxrt_hal as hal; | ||
|
||
type MyPin = hal::iomuxc::gpio::GPIO_AD_B0_12<hal::iomuxc::Alt5>; | ||
``` | ||
|
||
can be simply expressed as | ||
|
||
```rust | ||
type MyPin = hal::iomuxc::ad_b0::AD_B0_12; | ||
``` | ||
|
||
Note the stuttering convention of `pad_group::pad_group_offset` to reference pad types. | ||
|
||
- *No alternate transition*: there are no `altX()` methods. Usage resembling | ||
|
||
```rust | ||
let mut uart = uarts.uart2.init( | ||
peripherals.iomuxc.gpio_ad_b1_02.alt2(), | ||
peripherals.iomuxc.gpio_ad_b1_03.alt2(), | ||
BAUD, | ||
).unwrap() | ||
``` | ||
|
||
should drop the `altX()` calls (after renaming the pads). | ||
|
||
```rust | ||
let mut uart = uarts.uart2.init( | ||
peripherals.iomuxc.ad_b1.p02, | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is a really nice API now, I really like the way this call looks with the changes made here |
||
peripherals.iomuxc.ad_b1.p03, | ||
BAUD, | ||
).unwrap(); | ||
``` | ||
|
||
- *Type Tags*: all custom type-level constants, like `imxrt_hal::uart::module::_1` are now | ||
`typenum` constants. There are no peripheral-specific constants. Usage resembling | ||
|
||
```rust | ||
use imxrt_hal::uart; | ||
|
||
type MyTX = uart::Tx<uart::module::_3>; | ||
``` | ||
|
||
should update to | ||
|
||
```rust | ||
use imxrt_hal::uart; | ||
use imxrt_hal::iomuxc; | ||
|
||
type MyTX = uart::Tx<iomuxc::consts::U3>; | ||
``` | ||
|
||
- *GPIO*: the new IOMUXC driver results in a simpler GPIO interface. There is now a single GPIO | ||
type that wraps an IOMUXC pad. Any GPIO type, like | ||
|
||
```rust | ||
use imxrt_hal as hal; | ||
|
||
type HardwareFlag = hal::gpio::GPIO1IO26<hal::gpio::GPIO1, hal::gpio::Output>; | ||
``` | ||
|
||
should change to | ||
|
||
```rust | ||
type HardwareFlag = hal::gpio::GPIO<hal::iomuxc::ad_b1::AD_B1_10, hal::gpio::Output>; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. And again here, the resulting type and API is much nicer now There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Not sure what I was thinking when putting together the previous GPIO types 😛they were gnarly! There's still more gnarly HAL code I need to rethink... |
||
``` | ||
|
||
The new GPIO types expose a no-return `toggle()` method, which shadows an embedded_hal | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I suppose there's a reason we don't need to return here, its because its effectively infallible correct? Very nice if so |
||
trait method. If you notice compilation issues surrounding `toggle()`, try removing | ||
`unwrap()` calls: | ||
|
||
```rust | ||
led.toggle().unwrap() // Old | ||
led.toggle() // New | ||
``` | ||
Or, qualify that the `ToggleableOutputPin` trait method should be called. | ||
|
||
- **BREAKING** The HAL's `"rtfm"` feature is changed to `"rtic"`, reflecting the framework's | ||
new name. Users who are relying on the `"rtfm"` feature should now use the `"rtic"` feature. | ||
- **BREAKING** The `dma::{Config, ConfigBuilder}` types are gone. This affects the `dma::Peripheral` | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,6 +1,6 @@ | ||
# imxrt-iomuxc | ||
|
||
An experimental set of crates for i.MX RT pad configuration and resource management. | ||
i.MX RT pad definitions and pin configuration. | ||
|
||
## Goals | ||
|
||
|
@@ -14,32 +14,114 @@ An experimental set of crates for i.MX RT pad configuration and resource managem | |
|
||
## Structure | ||
|
||
- `imxrt-iomuxc`, the root crate, defines a set of traits that are implemented | ||
- `imxrt-iomuxc` defines a set of traits that are implemented | ||
on pads. The traits specify that a pad may be used for a certain function, | ||
such as a UART transfer pin or an I2C clock pin. The root crate also provides | ||
common functions to configure pads. `imxrt-iomuxc` is used in crates that need | ||
to treat pads as resources. | ||
- `imxrt106x-iomuxc` provides an implementation of the `imxrt-iomuxc` traits. It | ||
identifies the 106x pads that may be used for UART, SPI, I2C, PWM, etc. It uses | ||
`imxrt-iomuxc-build` to generate pads at compile time. When it comes time to | ||
support other i.MX RT processor variants, we add a new crate, and implement the | ||
pads there. | ||
to treat pads as resources. Without any feature flags, the `imxrt-iomuxc` provides | ||
the general pin configuration interface. There are no processor-specific APIs in | ||
the default build. | ||
- `imxrt-iomuxc` feature flags, like `imxrt106x`, enable processor-specific pad | ||
definitions and pin implementations. | ||
- `imxrt-iomuxc-build` provides **build-time** support for defining pads. It's | ||
used by implementation crates to simply generate all of the pads. It implements | ||
simple, common functionality across implementation crates family. | ||
used to simply generate all of the pads. It also implements simple, common | ||
functionality across pads, like GPIO pin traits. | ||
|
||
## Users | ||
|
||
i.MX RT HAL designers, or advanced driver designers, want to treat pads as resources. | ||
They want to create strongly-typed, infallible interfaces that ensure a pad supports | ||
a capability. These users depend on the traits defined by `imxrt-iomuxc` to create | ||
their driver interfaces. These drivers will accept pads across all i.MX RT chip variants. | ||
These designers *do not* enable any `imxrt-iomuxc` feature flags. | ||
|
||
i.MX RT HAL implementers want an API to specify their pads' capabilities. These users | ||
create a device-specific crate, like `imxrt106x-iomuxc`, to implement pads. To simplify | ||
pad implementation, these users use the build-time support crate. As we build support | ||
for more i.MX RT processors, we can know that these pads will plug-and-play with driver | ||
interfaces that accept pads. | ||
When users are ready to run their code on hardware, they enable a feature in the | ||
`imxrt-iomuxc` crate that describes their i.MX RT variant. Users who want to generalize | ||
their code for different i.MX RT variants enable more feature flags. | ||
|
||
## Comparison to Variant-Specific IOMUXC Crates | ||
|
||
A previous approach separated the `imxrt-iomuxc` interface and implementations | ||
across crates. Rather than having an `imxrt106x` feature in a single `imxrt-iomuxc` | ||
crate, we had separate crates, named like `imxrt106x-iomuxc`, that implemented the | ||
`imxrt-iomuxc` interfaces. We decided to use feature flags after realizing it was | ||
not only easier to maintain, but also equivalent to the multi-crate approach. This | ||
section compares the maintenance and equivalence of the two approaches. | ||
|
||
### Easier to maintain | ||
|
||
A single crate with feature flags is easier to maintain than an interface crate with | ||
separate implementation crates: | ||
|
||
- The interface crate does not need to support "public but internal" APIs. We signaled | ||
these APIs behind `#[doc(hidden)]` attributes on public types. When using features, | ||
these APIs are truly private. The approach reduces the documentation burden, since | ||
we do not need to identify which APIs are truly public, and which APIs are internal. | ||
- It's easier to release and version a single crate than multiple crates. We don't need | ||
to plan an approach for releasing separate interface and implementation crates. Users | ||
do not need to be concerned with our versioning and release strategy. | ||
- It's easier to document and study. We may generate documentation for the interface | ||
and all implementations simply using `cargo doc --all-features`. It's easier to link | ||
documentation across the implementations and the interface. | ||
|
||
### Equivalence | ||
|
||
A single crate with feature flags is equivalent to an interface crate and separate | ||
implementation crates. Consider a user who wants to use the IOMUXC pin configuration | ||
interfaces. That user would depend on `imxrt-iomuxc`, regardless of the approach. | ||
|
||
Now, consider a user who wants to use their code on an i.MX RT 106x processor variant. | ||
Under the old approach, that user would include the `imxrt106x-iomuxc` crate, which | ||
includes the `imxrt-iomuxc` crate: | ||
|
||
```toml | ||
[dependencies] | ||
imxrt106x-iomuxc = "0.1" | ||
# imxrt-iomuxc = "0.1" - implicit dependency | ||
``` | ||
|
||
When using feature flags, the user enables the `imxrt106x` feature: | ||
|
||
```toml | ||
[dependencies] | ||
imxrt106x-iomuxc = { version = "0.1", features = ["imxrt106x"] } | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I believe this should be imxrt-iomuxc |
||
``` | ||
|
||
Both approaches result in the same changes to the dependency graph: the graph now includes code | ||
for i.MX RT 106x processor pads. | ||
|
||
Since features are additive, users who want to support more processors enable more feature flags. | ||
This would have translated to the user explicitly including more crates: | ||
|
||
```toml | ||
[dependencies] | ||
imxrt106x-iomuxc = { version = "0.1", features = ["imxrt102x", "imxrt106x"] } | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I believe this is now imxrt-ioxmuc correct? |
||
|
||
# Equivalent: | ||
|
||
[dependencies] | ||
imxrt102x-iomuxc = "0.1" | ||
imxrt106x-iomuxc = "0.1" | ||
# imxrt-iomuxc = "0.1" - implicit dependency | ||
``` | ||
|
||
Depending on the release strategy, the user would need to maintain the version for all | ||
implementation crates. The feature-flag approach requires a single version, which may | ||
make it easier for the user. | ||
|
||
### Discussion | ||
|
||
Since the approaches are equivalent, the change has no effect on a split i.MX RT HAL. An | ||
`imxrt-hal[-common]` crate would depend on the `imxrt-iomuxc` crate without feature flags. | ||
Then, a processor-specific HAL would depend on `imxrt-iomuxc` with the appropriate feature | ||
flag. We achive the goals of a split HAL, as users are unconcerned with feature flags. | ||
|
||
We realize that this approach perpetuates the need for feature flags. However, | ||
the `imxrt-iomuxc` crate is a much lower-level interface than the HAL crates; it's equivalent | ||
to a RAL crate or PAC. The `imxrt-iomuxc` crate is intended for HAL developers, not HAL users. | ||
HAL developers cannot escape feature flags, since using RALs and PACs already necessitates feature | ||
flags. By adopting a single `imxrt-iomuxc` crate with feature flags, HAL developers continue to use | ||
feature flags to support the i.MX RT variants. | ||
|
||
## License | ||
|
||
|
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.
Is this right now, since you've removed the imxrt106x-iomuxc crate?