diff --git a/.github/workflows/buildtest.yml b/.github/workflows/buildtest.yml index 89fb631e..bba6f9e7 100644 --- a/.github/workflows/buildtest.yml +++ b/.github/workflows/buildtest.yml @@ -37,7 +37,7 @@ jobs: # update` is much faster the second time (so a parallel execution may # still be faster but uses 3x the resources) run: | - export BOARDS='native sltb001a samr21-xpro' + export BOARDS='native sltb001a samr21-xpro stk3700' DIRS='examples/rust-hello-world examples/rust-gcoap tests/rust_minimal' # It appears that there has to be output before :: commands really catch on echo "Building ${DIRS} on ${BOARDS}" @@ -56,7 +56,7 @@ jobs: echo "::echo ::off" - name: Build tests run: | - export BOARDS='native sltb001a samr21-xpro' + export BOARDS='native sltb001a samr21-xpro stk3700' DIRS=$(echo tests/*/) export RIOTBASE=$(pwd)/RIOT # It appears that there has to be output before :: commands really catch on diff --git a/src/dac.rs b/src/dac.rs new file mode 100644 index 00000000..651a232d --- /dev/null +++ b/src/dac.rs @@ -0,0 +1,65 @@ +use riot_sys::dac_t; + +#[derive(Debug)] +pub struct DACLine { + line: dac_t, +} + +#[derive(Debug)] +#[non_exhaustive] +pub enum DACError { + /// The given dac_t line did not exist + NoLine, + /// An unknown error did occur + Unknown, +} + +impl DACLine { + /// Creates and intializes a new [`DACLine`]. + /// + /// The `index` indicates which dac device from the current board should be used. + /// For information on how many such devices are available for this board please + /// refer to its RIOT documentation. + /// + /// Returns an Error if the given line does not exist + /// on the board. + pub fn new(index: usize) -> Result { + let line = unsafe { riot_sys::macro_DAC_LINE(index as u32) }; + let res = unsafe { riot_sys::dac_init(line) } as i32; + + const DAC_OK: i32 = riot_sys::DAC_OK as i32; + const DAC_NOLINE: i32 = riot_sys::DAC_NOLINE as i32; + + match res { + DAC_OK => Ok(DACLine { line }), + DAC_NOLINE => Err(DACError::NoLine), + _ => Err(DACError::Unknown), + } + } + + /// Builds a [`DACLine`] from an already initialized [`dac_t`]. + /// + /// Providing a not initialized [`dac_t`] results in undefined behavior. + pub unsafe fn new_without_init(line: dac_t) -> Self { + DACLine { line } + } + + /// Writes the given value to this [`DACLine`] + /// + /// The `value` is internally scaled to the underlying + /// dac device so that the maximum voltage output + /// is always equivalent to [`u16::MAX`] + pub fn set(&mut self, value: u16) { + unsafe { riot_sys::dac_set(self.line, value) } + } + + /// Turns the [`DACLine`] on after `DACLine::power_off` + pub fn power_on(&mut self) { + unsafe { riot_sys::dac_poweron(self.line) } + } + + /// Turns the [`DACLine`] off + pub fn power_off(&mut self) { + unsafe { riot_sys::dac_poweroff(self.line) } + } +} diff --git a/src/lib.rs b/src/lib.rs index 9837ab5a..08e93f65 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -118,6 +118,9 @@ pub mod spi; #[cfg(riot_module_periph_adc)] pub mod adc; +#[cfg(riot_module_periph_dac)] +pub mod dac; + #[cfg(riot_module_ztimer)] pub mod ztimer; diff --git a/tests/dac/Cargo.toml b/tests/dac/Cargo.toml new file mode 100644 index 00000000..f4e0ef37 --- /dev/null +++ b/tests/dac/Cargo.toml @@ -0,0 +1,19 @@ +[package] +name = "riot-wrappers-test-dac" +version = "0.1.0" +authors = ["Christian Amsüss "] +edition = "2021" +publish = false + +[lib] +crate-type = ["staticlib"] + +[profile.release] +panic = "abort" + +[dependencies] +riot-wrappers = { version = "*", features = [ "set_panic_handler" ] } +riot-sys = "*" + +[patch.crates-io] +riot-sys = { git = "https://github.com/RIOT-OS/rust-riot-sys" } diff --git a/tests/dac/Makefile b/tests/dac/Makefile new file mode 100644 index 00000000..3e39f4c3 --- /dev/null +++ b/tests/dac/Makefile @@ -0,0 +1,14 @@ +# name of your application +APPLICATION = riot-wrappers-test-dac +APPLICATION_RUST_MODULE = riot_wrappers_test_dac +BASELIBS += $(APPLICATION_RUST_MODULE).module +FEATURES_REQUIRED += rust_target +FEATURES_REQUIRED += periph_dac + +# Of these boards it is known that DAC0 may be driven arbitrarily because it's +# just a pin on the extension header. (It's probably true for most boards, but +# so far nobody guarantees that. Just add your board here if your DAC0 pin is +# good to use). +BOARD_WHITELIST = stk3700 + +include $(RIOTBASE)/Makefile.include diff --git a/tests/dac/src/lib.rs b/tests/dac/src/lib.rs new file mode 100644 index 00000000..12c5247b --- /dev/null +++ b/tests/dac/src/lib.rs @@ -0,0 +1,11 @@ +#![no_std] + +use riot_wrappers::dac; +use riot_wrappers::riot_main; + +riot_main!(main); + +fn main() { + let mut dac = dac::DACLine::new(0).unwrap(); + dac.set(655); // 1% of maximum value +}