rpi-hal 0.7.0

Hardware abstraction layer for bare-metal Raspberry Pi: BCM2836/BCM2837 (Pi 2, Pi 3), with preliminary BCM2711 (Pi 4) and BCM2835 (Pi 1, Pi Zero) support
Documentation
# Build/lint orchestration for rpi-hal. Target and -Zbuild-std=core are
# already pinned in .cargo/config.toml, so plain `cargo` invocations
# pick them up without repeating flags here.

.PHONY: build-bcm2837 build-bcm2711 build-bcm2835 examples fmt fmt-check clippy doc package pre-commit clean

# `bcm2837`/`bcm2711`/`bcm2835` (see Cargo.toml) are chip selection: none
# is a default feature, since there's no sensible default target chip, so
# every invocation below picks one explicitly.
build-bcm2837:
	cargo build --release --features bcm2837

# `bcm2711` is preliminary: no interrupt
# controller exists yet (`lic` is `cfg`'d out under this feature), which
# most examples depend on, so this only checks the library, not
# `--examples` -- a lightweight regression guard for the memory-map/PAC
# selection itself, not full example coverage.
build-bcm2711:
	cargo build --release --features bcm2711

# `bcm2835` (Pi 1, Pi Zero) is the only chip whose *target* differs too:
# ARMv6 rather than ARMv7-A, so it names `--target` here instead of taking
# the one `.cargo/config.toml` pins. `armv6-none-eabi` is a built-in rustc
# target but tier 3, so there is no precompiled `core` for it -- the
# `-Zbuild-std` already in `.cargo/config.toml` is what supplies one. It is
# deliberately *not* in `rust-toolchain.toml`'s `targets`: `rustup` would
# try to download a standard library that is not published, and fail.
#
# `--no-default-features` plus the two that *are* the defaults, rather
# than letting them default: the chip feature has to be named anyway, and
# spelling the whole set out keeps this line honest about what an ARMv6
# build covers as the port grows. `rt` is boot6.s, the vector table and
# the critical section; `mmu` is mmu32.rs's ARMv6 arm.
build-bcm2835:
	cargo build --release --target armv6-none-eabi --no-default-features --features bcm2835,rt,mmu

examples:
	cargo build --release --examples --features bcm2837
	# The multicore examples have required-features = ["multicore"], so a
	# plain --examples build skips them -- build them explicitly so they're
	# covered.
	cargo build --release --features bcm2837,multicore --example multicore_blink --example multicore_uart --example multicore_id
	# Likewise the integration-adapter examples are gated on their own
	# features (embedded-sdmmc, smoltcp) and skipped by a plain build.
	cargo build --release --features bcm2837,embedded-sdmmc,smoltcp --example sd_fat_read --example usb_ethernet_smoltcp --example bt_probe --example ble_advertise --example ble_scan
	# `resident-fat` gets its own line rather than joining the one above,
	# so the feature is compiled without `embedded-sdmmc` alongside it --
	# the two SD adapters are independent, and building them only together
	# would hide an item in one that had come to depend on the other.
	cargo build --release --features bcm2837,resident-fat --example sd_resident_fat_read --example sdhost_read
	# Same again for the v3d examples, gated on `v3d` (BCM2837-only).
	cargo build --release --features bcm2837,v3d --example v3d_probe --example gpu_cube
	# And the video decoder, gated on `mmal` (which pulls in `vchiq`) plus
	# `embedded-sdmmc` for the stream it plays off the card, and the audio
	# renderer on the same `mmal` stack.
	cargo build --release --features bcm2837,mmal,embedded-sdmmc --example h264_decode
	cargo build --release --features bcm2837,mmal --example hdmi_audio
	# And the interrupt-driven examples, gated on `async` -- the feature is
	# off by default, so a plain --examples build skips both.
	cargo build --release --features bcm2837,async --example usb_irq --example sd_async
	# And the ARMv6 examples, on their own target and feature set (see
	# `build-bcm2835`). Named rather than `--examples`, because that would
	# sweep in ones resting on hardware this chip doesn't have -- the ARM
	# generic timer, a second core. The list grows as the port does; these
	# are the ones the Pi Zero bring-up itself uses.
	cargo build --release --target armv6-none-eabi --no-default-features --features bcm2835,rt,mmu --example blink --example uart_hello --example uart_echo --example timer_hello --example atomics_check --example irq_timer_blink --example gpio_irq_button --example uart_rx_irq_echo
	# And the SDHOST example on ARMv6, which is where it matters most: a
	# Pi Zero W is the board with a card and a radio and one Arasan
	# controller between them. Its own line because it needs
	# `resident-fat` on top of the set above.
	cargo build --release --target armv6-none-eabi --no-default-features --features bcm2835,rt,mmu,resident-fat --example sdhost_read
	# And the fault reporter, gated on `fault-report`. Built on both
	# architectures because the handler is the one piece of this crate
	# with a genuinely separate implementation per architecture -- a
	# different entry stub, different fault registers, and a stack switch
	# on one of them and not the other.
	cargo build --release --features bcm2837,fault-report --example fault_report
	cargo build --release --target armv6-none-eabi --no-default-features --features bcm2835,rt,mmu,fault-report --example fault_report

fmt:
	cargo fmt

fmt-check:
	cargo fmt -- --check

clippy:
	cargo clippy --release --examples --features bcm2837 -- -D warnings
	# Same as `examples` above: without the feature, the multicore code
	# path (src/multicore.rs and the examples) isn't linted at all.
	cargo clippy --release --features bcm2837,multicore --example multicore_blink --example multicore_uart --example multicore_id -- -D warnings
	# Same again for the integration-adapter examples and their src-side
	# adapters, which a plain lint doesn't compile.
	cargo clippy --release --features bcm2837,embedded-sdmmc,smoltcp --example sd_fat_read --example usb_ethernet_smoltcp --example bt_probe --example ble_advertise --example ble_scan -- -D warnings
	# Separate line for the same reason as in `examples` above.
	cargo clippy --release --features bcm2837,resident-fat --example sd_resident_fat_read --example sdhost_read -- -D warnings
	# `mmu` without `rt`, which no other line here covers: every one of
	# them has `rt` on, and the code `mmu` compiles differs without it.
	# That gap let a dead-code warning ship -- `invalidate_block` is
	# reachable only from the `rt`-gated stack guard -- and it surfaced in
	# a *downstream* crate's doc build rather than here.
	cargo clippy --release --no-default-features --features bcm2837,mmu -- -D warnings
	# Library-only lint for BCM2711 -- see `build-bcm2711`'s comment on why
	# examples aren't included.
	cargo clippy --release --features bcm2711 -- -D warnings
	# And for BCM2835, on its own ARMv6 target -- see `build-bcm2835`'s
	# comment for why this one is narrower than the others, and
	# `examples`' for why the examples are named one by one.
	cargo clippy --release --target armv6-none-eabi --no-default-features --features bcm2835,rt,mmu --example blink --example uart_hello --example uart_echo --example timer_hello --example atomics_check --example irq_timer_blink --example gpio_irq_button --example uart_rx_irq_echo -- -D warnings
	# Same again for the SDHOST example -- see `examples` for why it is on
	# its own line.
	cargo clippy --release --target armv6-none-eabi --no-default-features --features bcm2835,rt,mmu,resident-fat --example sdhost_read -- -D warnings
	# Same again for the v3d examples, gated on `v3d` (BCM2837-only).
	cargo clippy --release --features bcm2837,v3d --example v3d_probe --example gpu_cube -- -D warnings
	# Same again for the fault reporter -- see `examples` for why it is
	# linted on both architectures.
	cargo clippy --release --features bcm2837,fault-report --example fault_report -- -D warnings
	cargo clippy --release --target armv6-none-eabi --no-default-features --features bcm2835,rt,mmu,fault-report --example fault_report -- -D warnings
	# And for the video decoder, the audio renderer, and the VCHIQ/MMAL
	# stack under them, gated on `mmal` -- none of which a plain lint
	# compiles either.
	cargo clippy --release --features bcm2837,mmal,embedded-sdmmc --example h264_decode -- -D warnings
	cargo clippy --release --features bcm2837,mmal --example hdmi_audio -- -D warnings
	# The `async` modules (gpio/uart/i2c/sd/usb `asynch.rs`) and the two
	# examples that drive them are compiled by none of the lines above --
	# the feature is off by default. Both examples poll their one future by
	# hand rather than pulling in an executor, which lives in
	# `rpi-hal-embassy` rather than here.
	cargo clippy --release --features bcm2837,async --examples -- -D warnings

# `-D warnings` is the whole point: a plain doc build almost never fails, so
# without it this catches nothing -- broken intra-doc links are the main
# reason to build docs here at all. Two builds, one per chip feature
# (`--all-features` would turn both on at once, which isn't a build anyone
# actually uses -- `pac` would resolve to whichever chip's `cfg` wins,
# silently documenting one chip's memory map while claiming to cover both),
# plus every other feature so the feature-gated modules (multicore,
# embedded-sdmmc, smoltcp, ...) are documented at all.
#
# One rustdoc quirk to know when a new module-header link fails here: a module
# documented *both* by an outer `///` on its `pub mod` line in lib.rs and by
# its own `//!` header has the two merged, and the merged text resolves
# intra-doc links in the declaration's scope -- the crate root -- where the
# module's own items aren't visible. So a bare `[`Sd::read_block`]` in sd.rs
# fails with "no item named `Sd` in scope" even though it reads as correct;
# qualifying the path (`[`read_block`](crate::sd::Sd::read_block)`) fixes it.
# Item-level docs are unaffected, which is why only module headers are hit.
#
# `--cfg docsrs` on the first build mirrors what docs.rs passes (see
# `[package.metadata.docs.rs]` in Cargo.toml), so the nightly-only `doc_cfg`
# path lib.rs gates behind that cfg is exercised here rather than first
# failing on the docs.rs builder after a release is already published.
doc:
	RUSTDOCFLAGS="-D warnings --cfg docsrs" cargo doc --no-deps --features bcm2837,multicore,async,embedded-sdmmc,resident-fat,smoltcp,v3d,mmal
	RUSTDOCFLAGS="-D warnings" cargo doc --no-deps --features bcm2711,multicore,async,embedded-sdmmc,resident-fat,smoltcp

# A chip feature is not optional here, and the reason is easy to trip over:
# `cargo package` and `cargo publish` finish by building the packaged tarball,
# and that verification build uses *default* features -- which select no chip,
# so `lib.rs`'s `compile_error!` fires and the publish aborts on a package that
# is actually fine. Naming a chip gives the verify step a configuration that
# exists. `cargo publish` takes the same flag when the time comes.
#
# Kept out of `pre-commit`: it reaches the network to update the crates.io
# index, which a local commit check shouldn't need.
#
# One thing this does not check, so it belongs in whatever runs the release:
# `CHANGELOG.md`'s top heading carries a literal `ReleaseDate` placeholder
# (the `cargo-release` convention) that has to become the actual date before
# publishing -- automatically if that tool is doing the release, by hand
# otherwise. `grep ReleaseDate CHANGELOG.md` is the check.
package:
	cargo package --features bcm2837

pre-commit: fmt clippy build-bcm2837 build-bcm2711 build-bcm2835 examples doc

clean:
	cargo clean