Skip to content
New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

Add initializers for peripherals based on numbers #60

Merged
merged 6 commits into from
Dec 2, 2023
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
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 });
}
}