Skip to content

Commit

Permalink
Add initializers for peripherals based on numbers
Browse files Browse the repository at this point in the history
Merges: RIOT-OS#60
  • Loading branch information
chrysn authored Dec 2, 2023
2 parents f0eb8d2 + d52daa9 commit 15341d0
Show file tree
Hide file tree
Showing 6 changed files with 94 additions and 9 deletions.
12 changes: 12 additions & 0 deletions src/adc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,25 @@ impl ADCLine {
/// Initialize an ADC line and get it as a handle. This is declared as unsafe as it may only
/// be called once. (A safe abstraction would need to check which RIOT devices have been
/// initialized already).
///
/// This being unsafe is inconsistent with other subsystem wrappers that chose to not declare
/// this unsafe; that inconsistency is tracked in
/// <https://github.com/RIOT-OS/rust-riot-wrappers/issues/59> and so far unresolved.
pub unsafe fn init(line: riot_sys::adc_t) -> Result<Self, i32> {
let success = riot_sys::adc_init(line);
match success {
0 => Ok(ADCLine(line)),
e => Err(e),
}
}

/// Initialize an ADC line identified by the line number it is assigned on the board
///
/// Safety: See [init]
pub unsafe fn from_number(line: u32) -> Result<Self, i32> {
let line = riot_sys::macro_ADC_LINE(line);
Self::init(line)
}
}

/// A configured representation of the single operating-system level ADC that RIOT exposes via its
Expand Down
18 changes: 10 additions & 8 deletions src/gpio.rs
Original file line number Diff line number Diff line change
Expand Up @@ -85,14 +85,16 @@ impl GPIO {
}
}

// using a generic GPIO_PIN is probably best done by making GPIO_INIT a static inline (given
// it's already fixed to types at tests/periph_gpio/main.c)
// /// Create a GPIO out of thin air
// #[cfg(riot_module_nrf5x_common_periph)]
// pub unsafe fn new(port: u8, pin: u8) -> Self {
// // EXPANDED cpu/nrf5x_common/include/periph_cpu_common.h:50
// GPIO(((port << 5) | pin).into())
// }
/// Create a GPIO from its port and pin numbers
///
/// ```
/// let pin_c8 = GPIO::from_port_and_pin(3, 8);
/// ```
///
/// See [from_c] for safety constraints.
pub fn from_port_and_pin(port: u32, pin: u32) -> Option<Self> {
Self::from_c(unsafe { riot_sys::macro_GPIO_PIN(port, pin) })
}

pub fn configure_as_output(
self,
Expand Down
13 changes: 12 additions & 1 deletion src/spi.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ use riot_sys::{
spi_transfer_bytes,
};

pub struct SPIDevice(pub spi_t);
pub struct SPIDevice(#[deprecated(note = "Use constructor instead")] pub spi_t);

pub struct AcquiredSPI<'a> {
device: &'a mut SPIDevice,
Expand All @@ -24,6 +24,17 @@ impl<'a> Drop for AcquiredSPI<'a> {
}

impl SPIDevice {
/// Create an SPI device from an `spi_t`
pub fn from_c(bus: spi_t) -> Self {
Self(bus)
}

/// Create an SPI device from the number it is assigned on the board
pub fn from_number(bus: u32) -> Self {
let bus = unsafe { riot_sys::macro_SPI_DEV(bus) };
Self::from_c(bus)
}

pub fn acquire<'a>(
&'a mut self,
cs: spi_cs_t,
Expand Down
17 changes: 17 additions & 0 deletions tests/gpio/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
[package]
name = "riot-wrappers-test-gpio"
version = "0.1.0"
authors = ["Christian Amsüss <chrysn@fsfe.org>"]
edition = "2021"
publish = false

[lib]
crate-type = ["staticlib"]

[profile.release]
panic = "abort"

[dependencies]
riot-wrappers = { version = "*", features = [ "set_panic_handler", "panic_handler_format" ] }
riot-sys = "*"
embedded-hal = "0.2.4"
8 changes: 8 additions & 0 deletions tests/gpio/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
# name of your application
APPLICATION = riot-wrappers-test-gpio
APPLICATION_RUST_MODULE = riot_wrappers_test_gpio
BASELIBS += $(APPLICATION_RUST_MODULE).module
FEATURES_REQUIRED += rust_target
FEATURES_REQUIRED += periph_gpio

include $(RIOTBASE)/Makefile.include
35 changes: 35 additions & 0 deletions tests/gpio/src/lib.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
#![no_std]

use riot_wrappers::gpio::{InputMode, OutputMode, GPIO};
use riot_wrappers::println;
use riot_wrappers::riot_main;

use embedded_hal::digital::v2::{InputPin, OutputPin, PinState};

riot_main!(main);

fn main() {
let (out_port, out_pin, in_port, in_pin, in_mode) = match riot_wrappers::BOARD {
// Won't work -- currently, native GPIO don't do anything (but let's not panic already)
"native" => (0, 0, 0, 1, InputMode::In),
// 0.17 is LED1, 0.13 is button 1
"nrf52dk" => (0, 17, 0, 13, InputMode::InPullUp),

// Better safe than drive pins that were not supposed to be driven
_ => panic!("For this board, no GPIO pins were deemed safe to reconfigure."),
};
let mut p_out = GPIO::from_port_and_pin(out_port, out_pin)
.expect("Out pin does not exist")
.configure_as_output(OutputMode::Out)
.expect("Out pin could not be configured");
let p_in = GPIO::from_port_and_pin(in_port, in_pin)
.expect("In pin does not exist")
.configure_as_input(in_mode)
.expect("In pin could not be configured");

loop {
let value = p_in.is_high().unwrap();
println!("Read GPIO value {}, writing it to the out port", value);
p_out.set_state(if value { PinState::High } else { PinState::Low });
}
}

0 comments on commit 15341d0

Please sign in to comment.