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

LEDs: Expose presence #113

Merged
merged 5 commits into from
Aug 25, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 7 additions & 25 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ jobs:
with:
repository: RIOT-OS/RIOT
path: RIOT
# common steps end here
- name: Patch .cargo/config.toml to use current checkout
run: |
set -x
Expand All @@ -59,7 +60,6 @@ jobs:
cargo tree --manifest-path $MANIF
echo "::endgroup::"
done
# common steps end here

- name: Build the example
run: |
Expand Down Expand Up @@ -91,40 +91,22 @@ jobs:
board: [native, sltb001a, samr21-xpro, stk3700]
testdir: ${{ fromJSON(needs.enumerate-wrappers-tests.outputs.list) }}
steps:
# common steps start here
# common steps start here (kept in sync even though we wouldn't need to patch RIOT's .cargo/config.toml)
- name: Check out riot-wrappers
uses: actions/checkout@v3
- name: Check out RIOT
uses: actions/checkout@v3
with:
repository: RIOT-OS/RIOT
path: RIOT
- name: Patch .cargo/config.toml to use current checkout
# common steps end here

- name: Patch local .cargo/config.toml to use current checkout
run: |
set -x
cd RIOT
rm -f .cargo/config.toml
mkdir -p .cargo # Keep working if RIOT ever decides it doesn't need overrides any more
mkdir .cargo
echo '[patch.crates-io]' >> .cargo/config.toml
echo 'riot-wrappers = { path = "../", version = "*" }' >> .cargo/config.toml
echo 'riot-wrappers = { path = ".", version = "*" }' >> .cargo/config.toml
echo 'riot-sys = { git = "https://github.com/RIOT-OS/rust-riot-sys" }' >> .cargo/config.toml
- name: Pull cargo updates
# No sense in running this in parallel -- this will download the index
# and all relevant crates once, and after that, just make some notes in Cargo.lock
run: |
set -x
# It is important to cd in early, for otherwise the patch.crates-io
# will not catch on during the update
cd RIOT
for MANIF in $(find -name Cargo.toml)
do
echo "::group::Updating ${MANIF}"
cargo update -p riot-sys -p riot-wrappers --aggressive --manifest-path $MANIF
cargo fetch --manifest-path $MANIF
cargo tree --manifest-path $MANIF
echo "::endgroup::"
done
# common steps end here

- name: Build and run test
run: |
Expand Down
2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ embedded-hal-0-2 = { package = "embedded-hal", version = "0.2.4", features = ["u
embedded-hal = "1"
switch-hal = "0.4.0"
nb = "0.1.1"
riot-sys = "0.7.10"
riot-sys = "0.7.13"
num-traits = { version = "0.2", default-features = false }
mutex-trait = "0.2"

Expand Down
44 changes: 44 additions & 0 deletions src/led.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,57 @@ use core::convert::Infallible;
/// The preferred interface for turning a LED on and off is [switch_hal::OutputSwitch].
///
/// LEDs are accessible safely; any not implemented on a board are silently ignored.
#[derive(Debug)]
pub struct LED<const I: u8>(());

/// The indicated LED is not present on the current board.
#[derive(Debug)]
pub struct LedNotPresent;

impl<const I: u8> LED<I> {
#[deprecated(
note = "Use new_unchecked() to retain the behavior this function has always had; future versions of `.new()` will panic when used with a board that does not have that LED.",
since = "0.9.1"
)]
pub const fn new() -> Self {
Self::new_unchecked()
}

/// Accesses the LED numbered `I`.
///
/// It is not an error if this board does not have a LED with that number; the resulting struct
/// will be available but its methods have no effect.
pub const fn new_unchecked() -> Self {
assert!(I < 8, "RIOT only defines LED0..7");
Self(())
}

/// Accesses the LED numbered `I`.
///
/// An LED is returned if present on the board, which is known at build time.
pub const fn new_checked() -> Result<Self, LedNotPresent> {
if Self::is_present() {
Ok(Self(()))
} else {
Err(LedNotPresent)
}
}

const fn is_present() -> bool {
unsafe {
match I {
0 => riot_sys::macro_LED0_IS_PRESENT() != -1,
1 => riot_sys::macro_LED1_IS_PRESENT() != -1,
2 => riot_sys::macro_LED2_IS_PRESENT() != -1,
3 => riot_sys::macro_LED3_IS_PRESENT() != -1,
4 => riot_sys::macro_LED4_IS_PRESENT() != -1,
5 => riot_sys::macro_LED5_IS_PRESENT() != -1,
6 => riot_sys::macro_LED6_IS_PRESENT() != -1,
7 => riot_sys::macro_LED7_IS_PRESENT() != -1,
_ => panic!("RIOT only defines LED0..7"),
}
}
}
}

impl<const I: u8> switch_hal::OutputSwitch for LED<I> {
Expand Down
19 changes: 11 additions & 8 deletions tests/led/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,17 @@ use riot_wrappers::riot_main;
riot_main!(main);

fn main() {
let mut led0 = LED::<0>::new();
let mut led1 = LED::<1>::new();
let mut led2 = LED::<2>::new();
let mut led3 = LED::<3>::new();
let mut led4 = LED::<4>::new();
let mut led5 = LED::<5>::new();
let mut led6 = LED::<6>::new();
let mut led7 = LED::<7>::new();
// Using the `unchecked` methods because the loop rotates the blinking speeds through all LEDs
// anyway -- so every speed will be on every LED, and that's easier to express if the number of
// considered LEDs is constant.
let mut led0 = LED::<0>::new_unchecked();
let mut led1 = LED::<1>::new_unchecked();
let mut led2 = LED::<2>::new_unchecked();
let mut led3 = LED::<3>::new_unchecked();
let mut led4 = LED::<4>::new_unchecked();
let mut led5 = LED::<5>::new_unchecked();
let mut led6 = LED::<6>::new_unchecked();
let mut led7 = LED::<7>::new_unchecked();
let mut leds: [&mut dyn switch_hal::ToggleableOutputSwitch<Error = _>; 8] = [
&mut led0, &mut led1, &mut led2, &mut led3, &mut led4, &mut led5, &mut led6, &mut led7,
];
Expand Down
Loading