Compare commits

..

No commits in common. "main" and "v0.3.0" have entirely different histories.
main ... v0.3.0

13 changed files with 216 additions and 297 deletions

View File

@ -16,11 +16,14 @@ jobs:
override: true override: true
- uses: actions-rs/cargo@v1 - uses: actions-rs/cargo@v1
with: with:
use-cross: true
command: check command: check
args: --target thumbv6m-none-eabi
- uses: actions-rs/cargo@v1 - uses: actions-rs/cargo@v1
with: with:
use-cross: true
command: check command: check
args: --examples args: --examples --target thumbv6m-none-eabi
fmt: fmt:
name: Rustfmt name: Rustfmt
@ -52,8 +55,9 @@ jobs:
- run: rustup component add clippy - run: rustup component add clippy
- uses: actions-rs/cargo@v1 - uses: actions-rs/cargo@v1
with: with:
use-cross: true
command: clippy command: clippy
args: -- -D warnings args: --target thumbv6m-none-eabi -- -D warnings
ci: ci:
if: ${{ success() }} if: ${{ success() }}

View File

@ -8,21 +8,6 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
## [unreleased] ## [unreleased]
## [v0.4.0]
- Update manifest file to have correct links and license
- Update some dependencies
- `cortex-m-rtic` (dev-depencency) to 1.1.2
- Other dependencies: Only revision has changed
## [v0.3.2]
- Bump HAL dependency to v0.5.0. Changed API, especially for IRQ handling
## [v0.3.1]
- Updated ADC code and dependency
## [v0.3.0] ## [v0.3.0]
- Completed baseline features to support all sensors on the REB1 sevice - Completed baseline features to support all sensors on the REB1 sevice

View File

@ -1,38 +1,32 @@
[package] [package]
name = "vorago-reb1" name = "vorago-reb1"
version = "0.4.0" version = "0.3.0"
authors = ["Robin Mueller <robin.mueller.m@gmail.com>"] authors = ["Robin Mueller <robin.mueller.m@gmail.com>"]
edition = "2021" edition = "2021"
description = "Board Support Crate for the Vorago REB1 development board" description = "Board Support Crate for the Vorago REB1 development board"
homepage = "https://egit.irs.uni-stuttgart.de/rust/vorago-reb1" homepage = "https://github.com/robamu/vorago-reb1-rs"
repository = "https://egit.irs.uni-stuttgart.de/rust/vorago-reb1" repository = "https://github.com/robamu/vorago-reb1-rs"
license = "Apache-2.0" license = "MIT OR Apache-2.0"
keywords = ["no-std", "reb1", "cortex-m", "vorago", "va108xx"] keywords = ["no-std", "reb1", "cortex-m", "vorago", "va108xx"]
categories = ["aerospace", "embedded", "no-std", "hardware-support"] categories = ["embedded", "no-std", "hardware-support"]
[dependencies] [dependencies]
cortex-m = "0.7" cortex-m = "0.7.3"
cortex-m-rt = "0.7" cortex-m-rt = "0.7.0"
embedded-hal = "0.2.7" embedded-hal = "0.2.6"
dummy-pin = "0.1" dummy-pin = "0.1.1"
max116xx-10bit = "0.2" max116xx-10bit = "0.1.0"
[dependencies.va108xx-hal] [dependencies.va108xx-hal]
version = "0.5" version = "0.4.2"
features = ["rt"] features = ["rt"]
[features] [features]
rt = ["va108xx-hal/rt"] rt = ["va108xx-hal/rt"]
[dev-dependencies] [dev-dependencies]
cortex-m-rtic = "1.1" cortex-m-rtic = "0.6.0-rc.4"
panic-rtt-target = { version = "0.1", features = ["cortex-m"] }
rtt-target = { version = "0.3", features = ["cortex-m"] }
panic-halt = "0.2" panic-halt = "0.2"
nb = "1" nb = "1.0.0"
[dev-dependencies.rtt-target]
version = "0.3"
features = ["cortex-m"]
[dev-dependencies.panic-rtt-target]
version = "0.1"
features = ["cortex-m"]

View File

@ -1,5 +1,5 @@
[![Crates.io](https://img.shields.io/crates/v/vorago-reb1)](https://crates.io/crates/vorago-reb1) [![Crates.io](https://img.shields.io/crates/v/vorago-reb1)](https://crates.io/crates/vorago-reb1)
[![ci](https://github.com/us-irs/vorago-reb1-rs/actions/workflows/ci.yml/badge.svg)](https://github.com/us-irs/vorago-reb1-rs/actions/workflows/ci.yml) [![ci](https://github.com/robamu-org/vorago-reb1-rs/actions/workflows/ci.yml/badge.svg)](https://github.com/robamu-org/vorago-reb1-rs/actions/workflows/ci.yml)
[![docs.rs](https://img.shields.io/docsrs/vorago-reb1)](https://docs.rs/vorago-reb1) [![docs.rs](https://img.shields.io/docsrs/vorago-reb1)](https://docs.rs/vorago-reb1)
# Rust BSP for the Vorago REB1 development board # Rust BSP for the Vorago REB1 development board
@ -7,7 +7,7 @@
This is the Rust **B**oard **S**upport **P**ackage crate for the Vorago REB1 development board. This is the Rust **B**oard **S**upport **P**ackage crate for the Vorago REB1 development board.
Its aim is to provide drivers for the board features of the REB1 board Its aim is to provide drivers for the board features of the REB1 board
The BSP builds on top of the [HAL crate for VA108xx devices](https://egit.irs.uni-stuttgart.de/rust/va108xx-hal). The BSP builds on top of the [HAL crate for VA108xx devices](https://github.com/robamu-org/va108xx-hal-rs).
## Building ## Building
@ -58,9 +58,8 @@ A `jlink.gdb` file is provided to allow flashing of the board from the command l
## Debugging with VS Code ## Debugging with VS Code
The REB1 board features an on-board JTAG, so all that is required to debug the board is a The REB1 board features an on-board JTAG, so all that is required to flash the board is a
Micro-USB cable. Micro-USB cable and an
You can debug applications on the REB1 board with a graphical user interface using VS Code with You can debug applications on the REB1 board with a graphical user interface using VS Code with
the [`Cortex-Debug` plugin](https://marketplace.visualstudio.com/items?itemName=marus25.cortex-debug). the [`Cortex-Debug` plugin](https://marketplace.visualstudio.com/items?itemName=marus25.cortex-debug).

View File

@ -3,7 +3,11 @@
use cortex_m_rt::entry; use cortex_m_rt::entry;
use panic_rtt_target as _; use panic_rtt_target as _;
use rtt_target::{rprintln, rtt_init_print}; use rtt_target::{rprintln, rtt_init_print};
use va108xx_hal::{pac, prelude::*, timer::set_up_ms_delay_provider}; use va108xx_hal::{
pac::{self, interrupt},
prelude::*,
timer::{default_ms_irq_handler, set_up_ms_timer, Delay},
};
use vorago_reb1::temp_sensor::Adt75TempSensor; use vorago_reb1::temp_sensor::Adt75TempSensor;
#[entry] #[entry]
@ -11,7 +15,14 @@ fn main() -> ! {
rtt_init_print!(); rtt_init_print!();
rprintln!("-- Vorago Temperature Sensor and I2C Example --"); rprintln!("-- Vorago Temperature Sensor and I2C Example --");
let mut dp = pac::Peripherals::take().unwrap(); let mut dp = pac::Peripherals::take().unwrap();
let mut delay = set_up_ms_delay_provider(&mut dp.SYSCONFIG, 50.mhz(), dp.TIM0); let tim0 = set_up_ms_timer(
&mut dp.SYSCONFIG,
&mut dp.IRQSEL,
50.mhz().into(),
dp.TIM0,
interrupt::OC0,
);
let mut delay = Delay::new(tim0);
unsafe { unsafe {
cortex_m::peripheral::NVIC::unmask(pac::Interrupt::OC0); cortex_m::peripheral::NVIC::unmask(pac::Interrupt::OC0);
} }
@ -23,6 +34,11 @@ fn main() -> ! {
.read_temperature() .read_temperature()
.expect("Failed reading temperature"); .expect("Failed reading temperature");
rprintln!("Temperature in Celcius: {}", temp); rprintln!("Temperature in Celcius: {}", temp);
delay.delay_ms(500_u16); delay.delay_ms(500);
} }
} }
#[interrupt]
fn OC0() {
default_ms_irq_handler();
}

View File

@ -10,10 +10,10 @@ use panic_rtt_target as _;
use rtt_target::{rprintln, rtt_init_print}; use rtt_target::{rprintln, rtt_init_print};
use va108xx_hal::{ use va108xx_hal::{
gpio::PinsA, gpio::PinsA,
pac, pac::{self, interrupt},
prelude::*, prelude::*,
spi::{Spi, SpiConfig, TransferConfig}, spi::{Spi, SpiConfig, TransferConfig},
timer::set_up_ms_delay_provider, timer::{default_ms_irq_handler, set_up_ms_timer, Delay},
}; };
const READ_MASK: u8 = 1 << 7; const READ_MASK: u8 = 1 << 7;
@ -28,7 +28,18 @@ fn main() -> ! {
rtt_init_print!(); rtt_init_print!();
rprintln!("-- Vorago Accelerometer Example --"); rprintln!("-- Vorago Accelerometer Example --");
let mut dp = pac::Peripherals::take().unwrap(); let mut dp = pac::Peripherals::take().unwrap();
let mut delay = set_up_ms_delay_provider(&mut dp.SYSCONFIG, 50.mhz(), dp.TIM0); let tim0 = set_up_ms_timer(
&mut dp.SYSCONFIG,
&mut dp.IRQSEL,
50.mhz().into(),
dp.TIM0,
interrupt::OC0,
);
let mut delay = Delay::new(tim0);
unsafe {
cortex_m::peripheral::NVIC::unmask(pac::Interrupt::OC0);
}
let pinsa = PinsA::new(&mut dp.SYSCONFIG, None, dp.PORTA); let pinsa = PinsA::new(&mut dp.SYSCONFIG, None, dp.PORTA);
let spi_cfg = SpiConfig::default(); let spi_cfg = SpiConfig::default();
let (sck, mosi, miso) = ( let (sck, mosi, miso) = (
@ -67,7 +78,12 @@ fn main() -> ! {
.expect("Enabling measurement mode failed"); .expect("Enabling measurement mode failed");
loop { loop {
delay.delay_ms(500_u16); delay.delay_ms(500);
unimplemented!("Not implemented for now, is not populated on the board.."); unimplemented!("Not implemented for now, is not populated on the board..");
} }
} }
#[interrupt]
fn OC0() {
default_ms_irq_handler();
}

View File

@ -14,7 +14,7 @@ use va108xx_hal::{
pac::{self, interrupt}, pac::{self, interrupt},
prelude::*, prelude::*,
time::Hertz, time::Hertz,
timer::{default_ms_irq_handler, set_up_ms_timer, IrqCfg}, timer::{default_ms_irq_handler, set_up_ms_timer},
}; };
use vorago_reb1::button::Button; use vorago_reb1::button::Button;
use vorago_reb1::leds::Leds; use vorago_reb1::leds::Leds;
@ -45,9 +45,9 @@ fn main() -> ! {
// Configure an edge interrupt on the button and route it to interrupt vector 15 // Configure an edge interrupt on the button and route it to interrupt vector 15
let mut button = Button::new(pinsa.pa11.into_floating_input()).edge_irq( let mut button = Button::new(pinsa.pa11.into_floating_input()).edge_irq(
edge_irq, edge_irq,
IrqCfg::new(pac::interrupt::OC15, true, true),
Some(&mut dp.SYSCONFIG), Some(&mut dp.SYSCONFIG),
Some(&mut dp.IRQSEL), &mut dp.IRQSEL,
pac::interrupt::OC15,
); );
if PRESS_MODE == PressMode::Toggle { if PRESS_MODE == PressMode::Toggle {
@ -61,11 +61,11 @@ fn main() -> ! {
} }
set_up_ms_timer( set_up_ms_timer(
IrqCfg::new(pac::Interrupt::OC0, true, true),
&mut dp.SYSCONFIG, &mut dp.SYSCONFIG,
Some(&mut dp.IRQSEL), &mut dp.IRQSEL,
50.mhz(), 50.mhz().into(),
dp.TIM0, dp.TIM0,
interrupt::OC0,
); );
let mut leds = Leds::new( let mut leds = Leds::new(
pinsa.pa10.into_push_pull_output(), pinsa.pa10.into_push_pull_output(),
@ -75,6 +75,8 @@ fn main() -> ! {
for led in leds.iter_mut() { for led in leds.iter_mut() {
led.off(); led.off();
} }
// Activate the IRQs so the processors sees them as well
unmask_irqs();
// Make both button and LEDs accessible from the IRQ handler as well // Make both button and LEDs accessible from the IRQ handler as well
cortex_m::interrupt::free(|cs| { cortex_m::interrupt::free(|cs| {
LEDS.borrow(cs).replace(Some(leds)); LEDS.borrow(cs).replace(Some(leds));
@ -83,6 +85,13 @@ fn main() -> ! {
loop {} loop {}
} }
fn unmask_irqs() {
unsafe {
cortex_m::peripheral::NVIC::unmask(pac::Interrupt::OC0);
cortex_m::peripheral::NVIC::unmask(pac::Interrupt::OC15);
}
}
#[interrupt] #[interrupt]
fn OC0() { fn OC0() {
default_ms_irq_handler(); default_ms_irq_handler();

View File

@ -9,10 +9,10 @@ mod app {
use va108xx_hal::{ use va108xx_hal::{
clock::{set_clk_div_register, FilterClkSel}, clock::{set_clk_div_register, FilterClkSel},
gpio::{FilterType, InterruptEdge, PinsA}, gpio::{FilterType, InterruptEdge, PinsA},
pac, pac::{self, interrupt},
prelude::*, prelude::*,
time::Hertz, time::Hertz,
timer::{default_ms_irq_handler, set_up_ms_timer, IrqCfg}, timer::{default_ms_irq_handler, set_up_ms_timer},
}; };
use vorago_reb1::button::Button; use vorago_reb1::button::Button;
use vorago_reb1::leds::Leds; use vorago_reb1::leds::Leds;
@ -66,9 +66,9 @@ mod app {
// Configure an edge interrupt on the button and route it to interrupt vector 15 // Configure an edge interrupt on the button and route it to interrupt vector 15
let mut button = Button::new(pinsa.pa11.into_floating_input()).edge_irq( let mut button = Button::new(pinsa.pa11.into_floating_input()).edge_irq(
edge_irq, edge_irq,
IrqCfg::new(pac::interrupt::OC15, true, true),
Some(&mut dp.SYSCONFIG), Some(&mut dp.SYSCONFIG),
Some(&mut dp.IRQSEL), &mut dp.IRQSEL,
pac::interrupt::OC15,
); );
if mode == PressMode::Toggle { if mode == PressMode::Toggle {
@ -80,6 +80,14 @@ mod app {
Hertz::from(50.khz()).0, Hertz::from(50.khz()).0,
); );
} }
set_up_ms_timer(
&mut dp.SYSCONFIG,
&mut dp.IRQSEL,
50.mhz().into(),
dp.TIM0,
interrupt::OC0,
);
let mut leds = Leds::new( let mut leds = Leds::new(
pinsa.pa10.into_push_pull_output(), pinsa.pa10.into_push_pull_output(),
pinsa.pa7.into_push_pull_output(), pinsa.pa7.into_push_pull_output(),
@ -88,13 +96,8 @@ mod app {
for led in leds.iter_mut() { for led in leds.iter_mut() {
led.off(); led.off();
} }
set_up_ms_timer( // Activate the IRQs so the processors sees them as well
IrqCfg::new(pac::Interrupt::OC0, true, true), unmask_irqs();
&mut dp.SYSCONFIG,
Some(&mut dp.IRQSEL),
50.mhz(),
dp.TIM0,
);
(Shared {}, Local { leds, button, mode }, init::Monotonics()) (Shared {}, Local { leds, button, mode }, init::Monotonics())
} }
@ -125,6 +128,13 @@ mod app {
default_ms_irq_handler(); default_ms_irq_handler();
} }
fn unmask_irqs() {
unsafe {
cortex_m::peripheral::NVIC::unmask(pac::Interrupt::OC0);
cortex_m::peripheral::NVIC::unmask(pac::Interrupt::OC15);
}
}
fn prompt_mode(mut down_channel: rtt_target::DownChannel) -> PressMode { fn prompt_mode(mut down_channel: rtt_target::DownChannel) -> PressMode {
rprintln!("Using prompt mode"); rprintln!("Using prompt mode");
rprintln!("Please enter the mode [0: Toggle, 1: Keep]"); rprintln!("Please enter the mode [0: Toggle, 1: Keep]");
@ -135,11 +145,11 @@ mod app {
for i in 0..read { for i in 0..read {
let val = read_buf[i] as char; let val = read_buf[i] as char;
if val == '0' || val == '1' { if val == '0' || val == '1' {
return if val == '0' { if val == '0' {
PressMode::Toggle return PressMode::Toggle;
} else { } else {
PressMode::Keep return PressMode::Keep;
}; }
} }
} }
} }

View File

@ -9,7 +9,7 @@
use cortex_m_rt::entry; use cortex_m_rt::entry;
use embedded_hal::digital::v2::ToggleableOutputPin; use embedded_hal::digital::v2::ToggleableOutputPin;
use panic_halt as _; use panic_halt as _;
use va108xx_hal::{gpio::pins::PinsA, pac, prelude::*, timer::set_up_ms_delay_provider}; use va108xx_hal::{gpio::pins::PinsA, pac, prelude::*};
use vorago_reb1::leds::Leds; use vorago_reb1::leds::Leds;
// REB LED pin definitions. All on port A // REB LED pin definitions. All on port A
@ -64,24 +64,23 @@ fn main() -> ! {
let mut led1 = pins.pa10.into_push_pull_output(); let mut led1 = pins.pa10.into_push_pull_output();
let mut led2 = pins.pa7.into_push_pull_output(); let mut led2 = pins.pa7.into_push_pull_output();
let mut led3 = pins.pa6.into_push_pull_output(); let mut led3 = pins.pa6.into_push_pull_output();
let mut delay = set_up_ms_delay_provider(&mut dp.SYSCONFIG, 50.mhz(), dp.TIM0);
for _ in 0..10 { for _ in 0..10 {
led1.set_low().ok(); led1.set_low().ok();
led2.set_low().ok(); led2.set_low().ok();
led3.set_low().ok(); led3.set_low().ok();
delay.delay_ms(200_u16); cortex_m::asm::delay(5_000_000);
led1.set_high().ok(); led1.set_high().ok();
led2.set_high().ok(); led2.set_high().ok();
led3.set_high().ok(); led3.set_high().ok();
delay.delay_ms(200_u16); cortex_m::asm::delay(5_000_000);
} }
loop { loop {
led1.toggle().ok(); led1.toggle().ok();
delay.delay_ms(200_u16); cortex_m::asm::delay(5_000_000);
led2.toggle().ok(); led2.toggle().ok();
delay.delay_ms(200_u16); cortex_m::asm::delay(5_000_000);
led3.toggle().ok(); led3.toggle().ok();
delay.delay_ms(200_u16); cortex_m::asm::delay(5_000_000);
} }
} }
LibType::Bsp => { LibType::Bsp => {
@ -91,21 +90,22 @@ fn main() -> ! {
pinsa.pa7.into_push_pull_output(), pinsa.pa7.into_push_pull_output(),
pinsa.pa6.into_push_pull_output(), pinsa.pa6.into_push_pull_output(),
); );
let mut delay = set_up_ms_delay_provider(&mut dp.SYSCONFIG, 50.mhz(), dp.TIM0);
loop { loop {
for _ in 0..10 { for _ in 0..10 {
// Blink all LEDs quickly // Blink all LEDs quickly
for led in leds.iter_mut() { for led in leds.iter_mut() {
led.toggle(); led.toggle();
} }
delay.delay_ms(200_u16); cortex_m::asm::delay(5_000_000);
} }
// Now use a wave pattern // Now use a wave pattern
loop { loop {
for led in leds.iter_mut() { leds[0].toggle();
led.toggle(); cortex_m::asm::delay(5_000_000);
delay.delay_ms(200_u16); leds[1].toggle();
} cortex_m::asm::delay(5_000_000);
leds[2].toggle();
cortex_m::asm::delay(5_000_000);
} }
} }
} }

View File

@ -2,31 +2,28 @@
#![no_main] #![no_main]
#![no_std] #![no_std]
use core::panic;
use cortex_m_rt::entry; use cortex_m_rt::entry;
use embedded_hal::{blocking::delay::DelayUs, spi}; use embedded_hal::spi;
use max116xx_10bit::VoltageRefMode;
use max116xx_10bit::{AveragingConversions, AveragingResults};
use panic_rtt_target as _; use panic_rtt_target as _;
use rtt_target::{rprintln, rtt_init_print}; use rtt_target::{rprintln, rtt_init_print};
use va108xx_hal::timer::CountDownTimer;
use va108xx_hal::{ use va108xx_hal::{
gpio::PinsA, gpio::PinsA,
pac::{self, interrupt, SPIB}, pac::{self, interrupt, SPIB},
prelude::*, prelude::*,
spi::{Spi, SpiBase, SpiConfig, TransferConfig}, spi::{Spi, SpiBase, SpiConfig, TransferConfig},
timer::{default_ms_irq_handler, set_up_ms_timer, Delay, IrqCfg}, timer::{default_ms_irq_handler, set_up_ms_timer, Delay},
utility::{port_mux, Funsel, PortSel},
}; };
use vorago_reb1::max11619::{ use vorago_reb1::max11619::{
max11619_externally_clocked_no_wakeup, max11619_externally_clocked_with_wakeup, max11619_externally_clocked, max11619_internally_clocked, EocPin, AN2_CHANNEL,
max11619_internally_clocked, EocPin, AN2_CHANNEL, POTENTIOMETER_CHANNEL, POTENTIOMETER_CHANNEL,
}; };
#[derive(Debug, PartialEq, Copy, Clone)] #[derive(Debug, PartialEq, Copy, Clone)]
pub enum ExampleMode { pub enum ExampleMode {
UsingEoc, UsingEoc,
NotUsingEoc, NotUsingEoc,
NotUsingEocWithDelay,
} }
#[derive(Debug, PartialEq, Copy, Clone)] #[derive(Debug, PartialEq, Copy, Clone)]
@ -34,18 +31,10 @@ pub enum ReadMode {
Single, Single,
Multiple, Multiple,
MultipleNToHighest, MultipleNToHighest,
AverageN,
}
#[derive(Debug, PartialEq, Copy, Clone)]
pub enum MuxMode {
None,
PortB19to17,
} }
const EXAMPLE_MODE: ExampleMode = ExampleMode::NotUsingEoc; const EXAMPLE_MODE: ExampleMode = ExampleMode::NotUsingEoc;
const READ_MODE: ReadMode = ReadMode::Multiple; const READ_MODE: ReadMode = ReadMode::Multiple;
const MUX_MODE: MuxMode = MuxMode::None;
#[entry] #[entry]
fn main() -> ! { fn main() -> ! {
@ -54,11 +43,11 @@ fn main() -> ! {
let mut dp = pac::Peripherals::take().unwrap(); let mut dp = pac::Peripherals::take().unwrap();
let tim0 = set_up_ms_timer( let tim0 = set_up_ms_timer(
IrqCfg::new(pac::Interrupt::OC0, true, true),
&mut dp.SYSCONFIG, &mut dp.SYSCONFIG,
Some(&mut dp.IRQSEL), &mut dp.IRQSEL,
50.mhz(), 50.mhz().into(),
dp.TIM0, dp.TIM0,
interrupt::OC0,
); );
let delay = Delay::new(tim0); let delay = Delay::new(tim0);
unsafe { unsafe {
@ -73,12 +62,6 @@ fn main() -> ! {
pinsa.pa18.into_funsel_2(), pinsa.pa18.into_funsel_2(),
); );
if MUX_MODE == MuxMode::PortB19to17 {
port_mux(&mut dp.IOCONFIG, PortSel::PortB, 19, Funsel::Funsel1).ok();
port_mux(&mut dp.IOCONFIG, PortSel::PortB, 18, Funsel::Funsel1).ok();
port_mux(&mut dp.IOCONFIG, PortSel::PortB, 17, Funsel::Funsel1).ok();
port_mux(&mut dp.IOCONFIG, PortSel::PortB, 16, Funsel::Funsel1).ok();
}
// Set the accelerometer chip select low in case the board slot is populated // Set the accelerometer chip select low in case the board slot is populated
let mut accel_cs = pinsa.pa16.into_push_pull_output(); let mut accel_cs = pinsa.pa16.into_push_pull_output();
accel_cs accel_cs
@ -106,10 +89,6 @@ fn main() -> ! {
ExampleMode::UsingEoc => { ExampleMode::UsingEoc => {
spi_example_internally_clocked(spi, delay, pinsa.pa14.into_floating_input()); spi_example_internally_clocked(spi, delay, pinsa.pa14.into_floating_input());
} }
ExampleMode::NotUsingEocWithDelay => {
let delay_us = CountDownTimer::new(&mut dp.SYSCONFIG, 50.mhz(), dp.TIM2);
spi_example_externally_clocked_with_delay(spi, delay, delay_us);
}
} }
} }
@ -118,17 +97,9 @@ fn OC0() {
default_ms_irq_handler(); default_ms_irq_handler();
} }
/// Use the SPI clock as the conversion clock
fn spi_example_externally_clocked(spi: SpiBase<SPIB>, mut delay: Delay) -> ! { fn spi_example_externally_clocked(spi: SpiBase<SPIB>, mut delay: Delay) -> ! {
let mut adc = max11619_externally_clocked_no_wakeup(spi) let mut adc = max11619_externally_clocked(spi)
.expect("Creating externally clocked MAX11619 device failed"); .expect("Creating externally clocked MAX11619 device failed");
if READ_MODE == ReadMode::AverageN {
adc.averaging(
AveragingConversions::FourConversions,
AveragingResults::FourResults,
)
.expect("Error setting up averaging register");
}
let mut cmd_buf: [u8; 32] = [0; 32]; let mut cmd_buf: [u8; 32] = [0; 32];
let mut counter = 0; let mut counter = 0;
loop { loop {
@ -137,36 +108,50 @@ fn spi_example_externally_clocked(spi: SpiBase<SPIB>, mut delay: Delay) -> ! {
match READ_MODE { match READ_MODE {
ReadMode::Single => { ReadMode::Single => {
rprintln!("Reading single potentiometer channel"); rprintln!("Reading single potentiometer channel");
let pot_val = adc let pot_val = match adc.read_single_channel(&mut cmd_buf, POTENTIOMETER_CHANNEL) {
.read_single_channel(&mut cmd_buf, POTENTIOMETER_CHANNEL) Ok(pot_val) => pot_val,
.expect("Creating externally clocked MAX11619 ADC failed"); _ => {
panic!("Creating externally clocked MAX11619 ADC failed");
}
};
rprintln!("Single channel read:"); rprintln!("Single channel read:");
rprintln!("\tPotentiometer value: {}", pot_val); rprintln!("\tPotentiometer value: {}", pot_val);
} }
ReadMode::Multiple => { ReadMode::Multiple => {
let mut res_buf: [u16; 4] = [0; 4]; let mut res_buf: [u16; 4] = [0; 4];
adc.read_multiple_channels_0_to_n( match adc.read_multiple_channels_0_to_n(
&mut cmd_buf, &mut cmd_buf,
&mut res_buf.iter_mut(), &mut res_buf.iter_mut(),
POTENTIOMETER_CHANNEL, POTENTIOMETER_CHANNEL,
) ) {
.expect("Multi-Channel read failed"); Ok(_) => {
print_res_buf(&res_buf); rprintln!("Multi channel read from 0 to 3:");
rprintln!("\tAN0 value: {}", res_buf[0]);
rprintln!("\tAN1 value: {}", res_buf[1]);
rprintln!("\tAN2 value: {}", res_buf[2]);
rprintln!("\tAN3 / Potentiometer value: {}", res_buf[3]);
}
_ => {
panic!("Multi-Channel read failed");
}
}
} }
ReadMode::MultipleNToHighest => { ReadMode::MultipleNToHighest => {
let mut res_buf: [u16; 2] = [0; 2]; let mut res_buf: [u16; 2] = [0; 2];
adc.read_multiple_channels_n_to_highest( match adc.read_multiple_channels_n_to_highest(
&mut cmd_buf, &mut cmd_buf,
&mut res_buf.iter_mut(), &mut res_buf.iter_mut(),
AN2_CHANNEL, AN2_CHANNEL,
) ) {
.expect("Multi-Channel read failed"); Ok(_) => {
rprintln!("Multi channel read from 2 to 3:"); rprintln!("Multi channel read from 2 to 3:");
rprintln!("\tAN2 value: {}", res_buf[0]); rprintln!("\tAN2 value: {}", res_buf[0]);
rprintln!("\tAN3 / Potentiometer value: {}", res_buf[1]); rprintln!("\tAN3 / Potentiometer value: {}", res_buf[1]);
} }
ReadMode::AverageN => { _ => {
rprintln!("Scanning and averaging not possible for externally clocked mode"); panic!("Multi-Channel read failed");
}
}
} }
} }
counter += 1; counter += 1;
@ -174,122 +159,22 @@ fn spi_example_externally_clocked(spi: SpiBase<SPIB>, mut delay: Delay) -> ! {
} }
} }
fn spi_example_externally_clocked_with_delay( fn spi_example_internally_clocked(spi: SpiBase<SPIB>, mut delay: Delay, mut eoc_pin: EocPin) -> ! {
spi: SpiBase<SPIB>, let mut adc = max11619_internally_clocked(spi).expect("Creaintg MAX116xx device failed");
mut delay: Delay,
mut delay_us: impl DelayUs<u8>,
) -> ! {
let mut adc =
max11619_externally_clocked_with_wakeup(spi).expect("Creating MAX116xx device failed");
let mut cmd_buf: [u8; 32] = [0; 32];
let mut counter = 0; let mut counter = 0;
loop { loop {
rprintln!("-- Measurement {} --", counter); rprintln!("-- Measurement {} --", counter);
match adc.request_single_channel(POTENTIOMETER_CHANNEL) {
Ok(_) => (),
_ => panic!("Requesting single channel value failed"),
};
match READ_MODE { let pot_val = match nb::block!(adc.get_single_channel(&mut eoc_pin)) {
ReadMode::Single => { Ok(pot_val) => pot_val,
rprintln!("Reading single potentiometer channel"); _ => panic!("Reading single channel value failed"),
let pot_val = adc };
.read_single_channel(&mut cmd_buf, POTENTIOMETER_CHANNEL, &mut delay_us) rprintln!("\tPotentiometer value: {}", pot_val);
.expect("Creating externally clocked MAX11619 ADC failed");
rprintln!("Single channel read:");
rprintln!("\tPotentiometer value: {}", pot_val);
}
ReadMode::Multiple => {
let mut res_buf: [u16; 4] = [0; 4];
adc.read_multiple_channels_0_to_n(
&mut cmd_buf,
&mut res_buf.iter_mut(),
POTENTIOMETER_CHANNEL,
&mut delay_us,
)
.expect("Multi-Channel read failed");
print_res_buf(&res_buf);
}
ReadMode::MultipleNToHighest => {
let mut res_buf: [u16; 2] = [0; 2];
adc.read_multiple_channels_n_to_highest(
&mut cmd_buf,
&mut res_buf.iter_mut(),
AN2_CHANNEL,
&mut delay_us,
)
.expect("Multi-Channel read failed");
rprintln!("Multi channel read from 2 to 3:");
rprintln!("\tAN2 value: {}", res_buf[0]);
rprintln!("\tAN3 / Potentiometer value: {}", res_buf[1]);
}
ReadMode::AverageN => {
rprintln!("Scanning and averaging not possible for externally clocked mode");
}
}
counter += 1; counter += 1;
delay.delay_ms(500); delay.delay_ms(500);
} }
} }
/// This function uses the EOC pin to determine whether the conversion finished
fn spi_example_internally_clocked(spi: SpiBase<SPIB>, mut delay: Delay, eoc_pin: EocPin) -> ! {
let mut adc = max11619_internally_clocked(
spi,
eoc_pin,
VoltageRefMode::ExternalSingleEndedNoWakeupDelay,
)
.expect("Creating MAX116xx device failed");
let mut counter = 0;
loop {
rprintln!("-- Measurement {} --", counter);
match READ_MODE {
ReadMode::Single => {
adc.request_single_channel(POTENTIOMETER_CHANNEL)
.expect("Requesting single channel value failed");
let pot_val = nb::block!(adc.get_single_channel())
.expect("Reading single channel value failed");
rprintln!("\tPotentiometer value: {}", pot_val);
}
ReadMode::Multiple => {
adc.request_multiple_channels_0_to_n(POTENTIOMETER_CHANNEL)
.expect("Requesting single channel value failed");
let mut res_buf: [u16; 4] = [0; 4];
nb::block!(adc.get_multi_channel(&mut res_buf.iter_mut()))
.expect("Requesting multiple channel values failed");
print_res_buf(&res_buf);
}
ReadMode::MultipleNToHighest => {
adc.request_multiple_channels_n_to_highest(AN2_CHANNEL)
.expect("Requesting single channel value failed");
let mut res_buf: [u16; 4] = [0; 4];
nb::block!(adc.get_multi_channel(&mut res_buf.iter_mut()))
.expect("Requesting multiple channel values failed");
rprintln!("Multi channel read from 2 to 3:");
rprintln!("\tAN2 value: {}", res_buf[0]);
rprintln!("\tAN3 / Potentiometer value: {}", res_buf[1]);
}
ReadMode::AverageN => {
adc.request_channel_n_repeatedly(POTENTIOMETER_CHANNEL)
.expect("Reading channel multiple times failed");
let mut res_buf: [u16; 16] = [0; 16];
nb::block!(adc.get_multi_channel(&mut res_buf.iter_mut()))
.expect("Requesting multiple channel values failed");
rprintln!("Reading potentiometer 4 times");
rprintln!("\tValue 0: {}", res_buf[0]);
rprintln!("\tValue 1: {}", res_buf[1]);
rprintln!("\tValue 2: {}", res_buf[2]);
rprintln!("\tValue 3: {}", res_buf[3]);
}
}
counter += 1;
delay.delay_ms(500);
}
}
fn print_res_buf(buf: &[u16; 4]) {
rprintln!("Multi channel read from 0 to 3:");
rprintln!("\tAN0 value: {}", buf[0]);
rprintln!("\tAN1 value: {}", buf[1]);
rprintln!("\tAN2 value: {}", buf[2]);
rprintln!("\tAN3 / Potentiometer value: {}", buf[3]);
}

View File

@ -8,7 +8,6 @@ use va108xx_hal::{
gpio::{FilterClkSel, FilterType, InputFloating, InterruptEdge, InterruptLevel, Pin, PA11}, gpio::{FilterClkSel, FilterType, InputFloating, InterruptEdge, InterruptLevel, Pin, PA11},
pac, pac,
prelude::*, prelude::*,
utility::IrqCfg,
}; };
pub struct Button { pub struct Button {
@ -29,28 +28,30 @@ impl Button {
} }
/// Configures an IRQ on edge. /// Configures an IRQ on edge.
///
/// Please note that you still have to unpend the Cortex-M interrupt yourself
pub fn edge_irq( pub fn edge_irq(
mut self, mut self,
edge_type: InterruptEdge, edge_type: InterruptEdge,
irq_cfg: IrqCfg,
syscfg: Option<&mut pac::SYSCONFIG>, syscfg: Option<&mut pac::SYSCONFIG>,
irqsel: Option<&mut pac::IRQSEL>, irqsel: &mut pac::IRQSEL,
irq: pac::interrupt,
) -> Self { ) -> Self {
self.button = self self.button = self.button.interrupt_edge(edge_type, syscfg, irqsel, irq);
.button
.interrupt_edge(edge_type, irq_cfg, syscfg, irqsel);
self self
} }
/// Configures an IRQ on level. /// Configures an IRQ on level.
///
/// Please note that you still have to unpend the Cortex-M interrupt yourself
pub fn level_irq( pub fn level_irq(
mut self, mut self,
level: InterruptLevel, level: InterruptLevel,
irq_cfg: IrqCfg,
syscfg: Option<&mut pac::SYSCONFIG>, syscfg: Option<&mut pac::SYSCONFIG>,
irqsel: Option<&mut pac::IRQSEL>, irqsel: &mut pac::IRQSEL,
irq: pac::interrupt,
) -> Self { ) -> Self {
self.button = self.button.interrupt_level(level, irq_cfg, syscfg, irqsel); self.button = self.button.interrupt_level(level, syscfg, irqsel, irq);
self self
} }

View File

@ -4,20 +4,24 @@
//! //!
//! - [ADC example](https://egit.irs.uni-stuttgart.de/rust/vorago-reb1/src/branch/main/examples/max11619-adc.rs) //! - [ADC example](https://egit.irs.uni-stuttgart.de/rust/vorago-reb1/src/branch/main/examples/max11619-adc.rs)
use core::convert::Infallible; use core::convert::Infallible;
use dummy_pin::DummyPin; use dummy_pin::DummyPin;
use embedded_hal::{blocking::spi::Transfer, spi::FullDuplex}; use embedded_hal::{blocking::spi::Transfer, spi::FullDuplex};
use max116xx_10bit::{ use max116xx_10bit::{
Error, ExternallyClocked, InternallyClockedInternallyTimedSerialInterface, Max116xx10Bit, Error, ExternallyClocked, InternallyClockedInternallyTimedSerialInterface, Max11619,
Max116xx10BitEocExt, VoltageRefMode, WithWakeupDelay, WithoutWakeupDelay, Max116xx10Bit, RefMode, WithoutWakeupDelay,
}; };
use va108xx_hal::gpio::{Floating, Input, Pin, PA14}; use va108xx_hal::gpio::{Floating, Input, Pin, PA14};
pub type Max11619ExternallyClockedNoWakeup<SPI> = pub type Max11619ExternallyClocked<SPI> =
Max116xx10Bit<SPI, DummyPin, ExternallyClocked, WithoutWakeupDelay>; Max116xx10Bit<SPI, DummyPin, Max11619, ExternallyClocked, WithoutWakeupDelay>;
pub type Max11619ExternallyClockedWithWakeup<SPI> = pub type Max11619InternallyClocked<SPI> = Max116xx10Bit<
Max116xx10Bit<SPI, DummyPin, ExternallyClocked, WithWakeupDelay>; SPI,
pub type Max11619InternallyClocked<SPI, EOC> = DummyPin,
Max116xx10BitEocExt<SPI, DummyPin, EOC, InternallyClockedInternallyTimedSerialInterface>; Max11619,
InternallyClockedInternallyTimedSerialInterface,
WithoutWakeupDelay,
>;
pub type EocPin = Pin<PA14, Input<Floating>>; pub type EocPin = Pin<PA14, Input<Floating>>;
pub const AN0_CHANNEL: u8 = 0; pub const AN0_CHANNEL: u8 = 0;
@ -25,42 +29,37 @@ pub const AN1_CHANNEL: u8 = 1;
pub const AN2_CHANNEL: u8 = 2; pub const AN2_CHANNEL: u8 = 2;
pub const POTENTIOMETER_CHANNEL: u8 = 3; pub const POTENTIOMETER_CHANNEL: u8 = 3;
pub fn max11619_externally_clocked_no_wakeup<SpiE, SPI>( pub fn max11619_externally_clocked<SpiE, SPI>(
spi: SPI, spi: SPI,
) -> Result<Max11619ExternallyClockedNoWakeup<SPI>, Error<SpiE, Infallible>> ) -> Result<Max11619ExternallyClocked<SPI>, Error<SpiE, Infallible>>
where where
SPI: Transfer<u8, Error = SpiE> + FullDuplex<u8, Error = SpiE>, SPI: Transfer<u8, Error = SpiE> + FullDuplex<u8, Error = SpiE>,
{ {
let mut adc = Max116xx10Bit::max11619(spi, DummyPin::new_low())?; let adc: Max116xx10Bit<SPI, DummyPin, Max11619, ExternallyClocked, WithoutWakeupDelay> =
adc.reset(false)?; Max116xx10Bit::new(
adc.setup()?; spi,
Ok(adc) DummyPin::new_low(),
} RefMode::ExternalSingleEndedNoWakeupDelay,
)?;
pub fn max11619_externally_clocked_with_wakeup<SpiE, SPI>(
spi: SPI,
) -> Result<Max11619ExternallyClockedWithWakeup<SPI>, Error<SpiE, Infallible>>
where
SPI: Transfer<u8, Error = SpiE> + FullDuplex<u8, Error = SpiE>,
{
let mut adc = Max116xx10Bit::max11619(spi, DummyPin::new_low())?
.into_ext_clkd_with_int_ref_wakeup_delay();
adc.reset(false)?;
adc.setup()?;
Ok(adc) Ok(adc)
} }
pub fn max11619_internally_clocked<SpiE, SPI>( pub fn max11619_internally_clocked<SpiE, SPI>(
spi: SPI, spi: SPI,
eoc: EocPin, ) -> Result<Max11619InternallyClocked<SPI>, Error<SpiE, Infallible>>
v_ref: VoltageRefMode,
) -> Result<Max11619InternallyClocked<SPI, EocPin>, Error<SpiE, Infallible>>
where where
SPI: Transfer<u8, Error = SpiE> + FullDuplex<u8, Error = SpiE>, SPI: Transfer<u8, Error = SpiE> + FullDuplex<u8, Error = SpiE>,
{ {
let mut adc = Max116xx10Bit::max11619(spi, DummyPin::new_low())? let adc: Max116xx10Bit<
.into_int_clkd_int_timed_through_ser_if_without_wakeup(v_ref, eoc)?; SPI,
adc.reset(false)?; DummyPin,
adc.setup()?; Max11619,
InternallyClockedInternallyTimedSerialInterface,
WithoutWakeupDelay,
> = Max116xx10Bit::new(
spi,
DummyPin::new_low(),
RefMode::ExternalSingleEndedNoWakeupDelay,
)?;
Ok(adc) Ok(adc)
} }

View File

@ -21,7 +21,7 @@ pub struct Adt75TempSensor {
current_reg: RegAddresses, current_reg: RegAddresses,
} }
#[derive(PartialEq, Eq, Debug, Copy, Clone)] #[derive(PartialEq, Debug, Copy, Clone)]
pub enum RegAddresses { pub enum RegAddresses {
Temperature = 0x00, Temperature = 0x00,
Configuration = 0x01, Configuration = 0x01,
@ -67,14 +67,15 @@ impl Adt75TempSensor {
let mut reply: [u8; 2] = [0; 2]; let mut reply: [u8; 2] = [0; 2];
self.sensor_if.read(ADT75_I2C_ADDR, &mut reply)?; self.sensor_if.read(ADT75_I2C_ADDR, &mut reply)?;
let adc_code = (((reply[0] as u16) << 8) | reply[1] as u16) >> 4; let adc_code = (((reply[0] as u16) << 8) | reply[1] as u16) >> 4;
let temp_celcius: f32 = if ((adc_code >> 11) & 0x01) == 0 { let temp_celcius: f32;
if ((adc_code >> 11) & 0x01) == 0 {
// Sign bit not set, positiv value // Sign bit not set, positiv value
// Divide ADC code by 16 according to datasheet // Divide ADC code by 16 according to datasheet
adc_code as f32 / 16.0 temp_celcius = adc_code as f32 / 16.0;
} else { } else {
// Calculation for negative values, assuming all 12 bits are used // Calculation for negative values, assuming all 12 bits are used
(adc_code - 4096) as f32 / 16.0 temp_celcius = (adc_code - 4096) as f32 / 16.0;
}; }
Ok(temp_celcius) Ok(temp_celcius)
} }
} }