Skip to content

Merge the two HALs #951

@thejpster

Description

@thejpster

When I wrote the RP2350 support, because I was in a private fork and because the RP2350 kept changing, it was easiest to copy-paste the rp2040-hal package as rp235x-hal and modify it. When the RP2350 support was re-added here, we kept that approach to save time.

However, on-going maintenance must now be duplicated across both HALs (like the UART baud-rate fix). As the chips are so similar, one HAL can probably cover both. Indeed, this is how Embassy's RP HAL works.

I was initially unsure if we could have both PACs (we still need those) as optional in the same crate, but I have a local example where I've convinced myself it can work.

I think the steps are:

  1. Create a new rp-hal folder/package in this repository
  2. Move the rp235x-hal code into rp-hal, marking the bits that don't work on RP2040 as #[cfg(not(feature = "rp2040"))].
  3. See below

We have two choices for step 3. Either:

  • Make rp235x-hal and rp2040-hal empty stubs which import and re-export rp-hal, but setting the appropriate cfg flags for you. People can continue to build existing programs without issue, picking up the new rp-hal code.

or

  • Deprecate rp235x-hal and rp2040-hal and tell people to move to rp-hal. People can continue to build existing programs without issue, but will be on unmaintained code unti they switch to rp-hal.

My local example rp-hal/Cargo.toml looks something like:

[package]
name = "rp-hal"
version = "0.1.0"
edition = "2021"

[dependencies]
critical-section = "1.2.0"
defmt = { version = "1.0", optional = true }
frunk = { version = "0.4.1", default-features = false }
nb = "1.1.0"
paste = "1.0"
rp2040-pac = { version = "0.6", optional = true, features = ["critical-section", "rt"] }
rp235x-pac = { version = "0.1", optional = true, features = ["critical-section", "rt"] }

[features]
rp2040 = ["dep:rp2040-pac"]
rp235x = ["dep:rp235x-pac"]
critical-section-impl = ["critical-section/restore-state-u8"]
defmt = ["dep:defmt"]

[target.'thumbv8m.main-none-eabihf'.dependencies]
cortex-m = "0.7.2"
cortex-m-rt = "0.7"

[target.'thumbv6m-none-eabi'.dependencies]
cortex-m = "0.7.2"
cortex-m-rt = "0.7"

[target.riscv32imac-unknown-none-elf.dependencies]
riscv = "0.11"
riscv-rt = "0.12"

The lib.rs is:

#![no_std]

#[cfg(feature = "rp2040")]
pub use rp2040_pac as pac;

#[cfg(feature = "rp235x")]
pub use rp235x_pac as pac;

#[cfg(any(feature = "rp2040", feature = "rp235x"))]
pub use pac::Peripherals;

pub mod arch;
pub mod critical_section_impl;
pub mod sio;
pub mod typelevel;

#[doc(hidden)]
pub use paste;

pub use sio::Sio;

Sadly rust-analyzer gets shirty when it can't see crate::Peripherals, which happens when neither feature is set. I don't know how to fix that, as cargo doesn't really place nicely with mutually exclusive feature flags.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions