Skip to content
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

Drop custom Peripherals structs and RawPeripheral newtype wrapper #152

Merged
merged 7 commits into from
Mar 3, 2021

Conversation

Rahix
Copy link
Owner

@Rahix Rahix commented Mar 3, 2021

Sadly it seems this approach is not going to work well, so we will have to follow a different route. Already, the following problems are showing prominently:

  • With a custom Peripherals struct, we need to manually add fields for all peripherals of all MCUs we support. This is not going to scale well.
  • Because each Peripherals will look differently, this is going to look very confusing.

Going back to the svd2rust generated Peripherals only, we also have to drop the RawPeripheral newtype. I tried different solutions here and just dropping it entirely does seem to be the best looking. Instead, I added a special type-parameter in avr-hal-generic with the sole purpose of circumventing the orphan rule which seems to work out quite nicely. See commit 9c33514 for details.

It seems the approach of defining a custom `Peripherals` struct does not
scale well: We'd need to replicate all the fields from the respective
MCUs `Peripherals` struct to provide a usable API.  But doing so would
be a huge effort.

Instead, look for a design where the custom `Peripherals` is not needed.

As a first step, convert the `Pins` initialization to a macro-based
approach.  A `pins!()` macro is provided which moves the relevant fields
out of the `Peripherals` struct.  This must be a macro because it must
happen as part of the `main()` function where the `Peripherals` instance
can linger in its partially moved state.
Also drop the custom `Peripherals` struct which is found in the
`arduino-hal`.  Provide the same `pins!()` macro here as well, just with
board pins instead of MCU pins.
Use the new pins initialization which is based on a macro in all blink
examples.
Because HAL crates neither own the `UsartOps` trait nor the `USARTn`
instance, they are not allowed to implement it for the type.  However,
the orphan rules allow us to deal with this by adding a generic
parameter to `UsartOps` which is local to the HAL crate.

The new `H` parameter serves exactly this purpose and nothing more.
A HAL should define a type and use it for `H` in all HAL
implementations.  Ideally, it should also export type-aliases for all
types from `avr-hal-generic` with the `H` parameter already substituted.
`UsartOps` is no longer meant to be implemented on newtype-wrappers and
as such the .0 field accessor is now superfluous.

This partially reverts commit 9c33514 ("generic: usart: Introduce
a type-parameter for orphan circumvention").
Drop the RawPeripheral() wrapper type and instead use a marker called
`Atmega` to deal with the orphan rule.  Update macro invocations to fit
with the new design in avr-hal-generic.
Use the new `pins!()` macro.
@Rahix Rahix added hal-api API design for the different components of avr-hal hal-generic Related to MCU generic parts of avr-hal labels Mar 3, 2021
@Rahix Rahix added this to the New APIs milestone Mar 3, 2021
@Rahix Rahix marked this pull request as ready for review March 3, 2021 14:03
@Rahix Rahix merged commit 5b7921e into next Mar 3, 2021
@Rahix Rahix deleted the no-custom-peripherals-structs branch March 3, 2021 14:05
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
hal-api API design for the different components of avr-hal hal-generic Related to MCU generic parts of avr-hal
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

1 participant