Compare commits

...

17 Commits
v0.3.0 ... main

Author SHA1 Message Date
Robin Müller bdd804f88b
lets try without cross..
Rust/vorago-reb1/pipeline/head This commit looks good Details
2022-09-27 20:55:20 +02:00
Robin Müller f4cd3b704b
typo
Rust/vorago-reb1/pipeline/head This commit looks good Details
2022-09-27 20:51:37 +02:00
Robin Müller 7e2bb8618e
bump dependencies
Rust/vorago-reb1/pipeline/head This commit looks good Details
2022-09-13 10:58:54 +02:00
Robin Müller 6931432dcd
add eq auto-derive
Rust/vorago-reb1/pipeline/head This commit looks good Details
2022-09-13 10:47:23 +02:00
Robin Müller 742a53d63a
cargo fmt
Rust/vorago-reb1/pipeline/head This commit looks good Details
2022-06-18 22:33:00 +02:00
Robin Müller 3304410a64
update links in README
Rust/vorago-reb1/pipeline/head This commit looks good Details
2022-06-18 22:30:58 +02:00
Robin Müller 37629f2ba1
small form change and CHANGELOG
Rust/vorago-reb1/pipeline/head This commit looks good Details
2022-06-18 22:29:55 +02:00
Robin Müller bffba52fa5
update manifest file and deps 2022-06-18 22:26:36 +02:00
Robin Müller ab439ac35d
clippy fix 2022-06-18 22:16:31 +02:00
Robin Müller 1eb7deeb9f Merge pull request 'bump to v0.3.2, update HAL dependency' (#4) from hal-update into main
Rust/vorago-reb1/pipeline/head This commit looks good Details
Reviewed-on: #4
2021-12-21 00:00:50 +01:00
Robin Müller 2195a9f678 bump to v0.3.2, update HAL dependency
Rust/vorago-reb1/pipeline/head This commit looks good Details
Rust/vorago-reb1/pipeline/pr-main This commit looks good Details
- Adapted code accordingly
2021-12-20 23:55:03 +01:00
Robin Müller 2f503ac3b1
update blinky led example, bump HAL dependency
Rust/vorago-reb1/pipeline/head There was a failure building this commit Details
2021-12-18 15:00:54 +01:00
Robin Müller 0c5a5efea0
added port mux feature
Rust/vorago-reb1/pipeline/head This commit looks good Details
2021-12-16 11:27:10 +01:00
Robin Müller a901e4fcac Merge pull request 'Extended ADC library' (#3) from update-adc-code into main
Rust/vorago-reb1/pipeline/head This commit looks good Details
Reviewed-on: #3
2021-12-14 14:34:17 +01:00
Robin Müller 3025ec70ab
update changelog
Rust/vorago-reb1/pipeline/head Build queued... Details
Rust/vorago-reb1/pipeline/pr-main Build queued... Details
2021-12-14 14:34:03 +01:00
Robin Müller 403407547d Extended ADC library
Rust/vorago-reb1/pipeline/head This commit looks good Details
Rust/vorago-reb1/pipeline/pr-main This commit looks good Details
- MAX116xx-10bit ADC library extended significantly
- Added even more examples with wakeup delay as well
2021-12-14 14:28:23 +01:00
Robin Müller 850bd08eae
simplified CI
Rust/vorago-reb1/pipeline/head This commit looks good Details
2021-12-13 21:46:44 +01:00
13 changed files with 297 additions and 216 deletions

View File

@ -16,14 +16,11 @@ 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 --target thumbv6m-none-eabi args: --examples
fmt: fmt:
name: Rustfmt name: Rustfmt
@ -55,9 +52,8 @@ 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: --target thumbv6m-none-eabi -- -D warnings args: -- -D warnings
ci: ci:
if: ${{ success() }} if: ${{ success() }}

View File

@ -8,6 +8,21 @@ 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,32 +1,38 @@
[package] [package]
name = "vorago-reb1" name = "vorago-reb1"
version = "0.3.0" version = "0.4.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://github.com/robamu/vorago-reb1-rs" homepage = "https://egit.irs.uni-stuttgart.de/rust/vorago-reb1"
repository = "https://github.com/robamu/vorago-reb1-rs" repository = "https://egit.irs.uni-stuttgart.de/rust/vorago-reb1"
license = "MIT OR Apache-2.0" license = "Apache-2.0"
keywords = ["no-std", "reb1", "cortex-m", "vorago", "va108xx"] keywords = ["no-std", "reb1", "cortex-m", "vorago", "va108xx"]
categories = ["embedded", "no-std", "hardware-support"] categories = ["aerospace", "embedded", "no-std", "hardware-support"]
[dependencies] [dependencies]
cortex-m = "0.7.3" cortex-m = "0.7"
cortex-m-rt = "0.7.0" cortex-m-rt = "0.7"
embedded-hal = "0.2.6" embedded-hal = "0.2.7"
dummy-pin = "0.1.1" dummy-pin = "0.1"
max116xx-10bit = "0.1.0" max116xx-10bit = "0.2"
[dependencies.va108xx-hal] [dependencies.va108xx-hal]
version = "0.4.2" version = "0.5"
features = ["rt"] features = ["rt"]
[features] [features]
rt = ["va108xx-hal/rt"] rt = ["va108xx-hal/rt"]
[dev-dependencies] [dev-dependencies]
cortex-m-rtic = "0.6.0-rc.4" cortex-m-rtic = "1.1"
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.0.0" nb = "1"
[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/robamu-org/vorago-reb1-rs/actions/workflows/ci.yml/badge.svg)](https://github.com/robamu-org/vorago-reb1-rs/actions/workflows/ci.yml) [![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)
[![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://github.com/robamu-org/va108xx-hal-rs). The BSP builds on top of the [HAL crate for VA108xx devices](https://egit.irs.uni-stuttgart.de/rust/va108xx-hal).
## Building ## Building
@ -58,8 +58,9 @@ 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 flash the board is a The REB1 board features an on-board JTAG, so all that is required to debug the board is a
Micro-USB cable and an Micro-USB cable.
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,11 +3,7 @@
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::{ use va108xx_hal::{pac, prelude::*, timer::set_up_ms_delay_provider};
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]
@ -15,14 +11,7 @@ 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 tim0 = set_up_ms_timer( let mut delay = set_up_ms_delay_provider(&mut dp.SYSCONFIG, 50.mhz(), dp.TIM0);
&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);
} }
@ -34,11 +23,6 @@ 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); delay.delay_ms(500_u16);
} }
} }
#[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::{self, interrupt}, pac,
prelude::*, prelude::*,
spi::{Spi, SpiConfig, TransferConfig}, spi::{Spi, SpiConfig, TransferConfig},
timer::{default_ms_irq_handler, set_up_ms_timer, Delay}, timer::set_up_ms_delay_provider,
}; };
const READ_MASK: u8 = 1 << 7; const READ_MASK: u8 = 1 << 7;
@ -28,18 +28,7 @@ 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 tim0 = set_up_ms_timer( let mut delay = set_up_ms_delay_provider(&mut dp.SYSCONFIG, 50.mhz(), dp.TIM0);
&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) = (
@ -78,12 +67,7 @@ fn main() -> ! {
.expect("Enabling measurement mode failed"); .expect("Enabling measurement mode failed");
loop { loop {
delay.delay_ms(500); delay.delay_ms(500_u16);
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}, timer::{default_ms_irq_handler, set_up_ms_timer, IrqCfg},
}; };
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),
&mut dp.IRQSEL, Some(&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,
&mut dp.IRQSEL, Some(&mut dp.IRQSEL),
50.mhz().into(), 50.mhz(),
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,8 +75,6 @@ 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));
@ -85,13 +83,6 @@ 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::{self, interrupt}, pac,
prelude::*, prelude::*,
time::Hertz, time::Hertz,
timer::{default_ms_irq_handler, set_up_ms_timer}, timer::{default_ms_irq_handler, set_up_ms_timer, IrqCfg},
}; };
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),
&mut dp.IRQSEL, Some(&mut dp.IRQSEL),
pac::interrupt::OC15,
); );
if mode == PressMode::Toggle { if mode == PressMode::Toggle {
@ -80,14 +80,6 @@ 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(),
@ -96,8 +88,13 @@ mod app {
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 set_up_ms_timer(
unmask_irqs(); IrqCfg::new(pac::Interrupt::OC0, true, true),
&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())
} }
@ -128,13 +125,6 @@ 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]");
@ -145,11 +135,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' {
if val == '0' { return if val == '0' {
return PressMode::Toggle; PressMode::Toggle
} else { } else {
return PressMode::Keep; 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::*}; use va108xx_hal::{gpio::pins::PinsA, pac, prelude::*, timer::set_up_ms_delay_provider};
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,23 +64,24 @@ 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();
cortex_m::asm::delay(5_000_000); delay.delay_ms(200_u16);
led1.set_high().ok(); led1.set_high().ok();
led2.set_high().ok(); led2.set_high().ok();
led3.set_high().ok(); led3.set_high().ok();
cortex_m::asm::delay(5_000_000); delay.delay_ms(200_u16);
} }
loop { loop {
led1.toggle().ok(); led1.toggle().ok();
cortex_m::asm::delay(5_000_000); delay.delay_ms(200_u16);
led2.toggle().ok(); led2.toggle().ok();
cortex_m::asm::delay(5_000_000); delay.delay_ms(200_u16);
led3.toggle().ok(); led3.toggle().ok();
cortex_m::asm::delay(5_000_000); delay.delay_ms(200_u16);
} }
} }
LibType::Bsp => { LibType::Bsp => {
@ -90,22 +91,21 @@ 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();
} }
cortex_m::asm::delay(5_000_000); delay.delay_ms(200_u16);
} }
// Now use a wave pattern // Now use a wave pattern
loop { loop {
leds[0].toggle(); for led in leds.iter_mut() {
cortex_m::asm::delay(5_000_000); led.toggle();
leds[1].toggle(); delay.delay_ms(200_u16);
cortex_m::asm::delay(5_000_000); }
leds[2].toggle();
cortex_m::asm::delay(5_000_000);
} }
} }
} }

View File

@ -2,28 +2,31 @@
#![no_main] #![no_main]
#![no_std] #![no_std]
use core::panic;
use cortex_m_rt::entry; use cortex_m_rt::entry;
use embedded_hal::spi; use embedded_hal::{blocking::delay::DelayUs, 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}, timer::{default_ms_irq_handler, set_up_ms_timer, Delay, IrqCfg},
utility::{port_mux, Funsel, PortSel},
}; };
use vorago_reb1::max11619::{ use vorago_reb1::max11619::{
max11619_externally_clocked, max11619_internally_clocked, EocPin, AN2_CHANNEL, max11619_externally_clocked_no_wakeup, max11619_externally_clocked_with_wakeup,
POTENTIOMETER_CHANNEL, max11619_internally_clocked, EocPin, AN2_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)]
@ -31,10 +34,18 @@ 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() -> ! {
@ -43,11 +54,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,
&mut dp.IRQSEL, Some(&mut dp.IRQSEL),
50.mhz().into(), 50.mhz(),
dp.TIM0, dp.TIM0,
interrupt::OC0,
); );
let delay = Delay::new(tim0); let delay = Delay::new(tim0);
unsafe { unsafe {
@ -62,6 +73,12 @@ 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
@ -89,6 +106,10 @@ 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);
}
} }
} }
@ -97,9 +118,17 @@ 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(spi) let mut adc = max11619_externally_clocked_no_wakeup(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 {
@ -108,50 +137,36 @@ 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 = match adc.read_single_channel(&mut cmd_buf, POTENTIOMETER_CHANNEL) { let pot_val = adc
Ok(pot_val) => pot_val, .read_single_channel(&mut cmd_buf, POTENTIOMETER_CHANNEL)
_ => { .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];
match adc.read_multiple_channels_0_to_n( 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,
) { )
Ok(_) => { .expect("Multi-Channel read failed");
rprintln!("Multi channel read from 0 to 3:"); print_res_buf(&res_buf);
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];
match adc.read_multiple_channels_n_to_highest( 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,
) { )
Ok(_) => { .expect("Multi-Channel read failed");
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 => {
panic!("Multi-Channel read failed"); rprintln!("Scanning and averaging not possible for externally clocked mode");
}
}
} }
} }
counter += 1; counter += 1;
@ -159,22 +174,122 @@ fn spi_example_externally_clocked(spi: SpiBase<SPIB>, mut delay: Delay) -> ! {
} }
} }
fn spi_example_internally_clocked(spi: SpiBase<SPIB>, mut delay: Delay, mut eoc_pin: EocPin) -> ! { fn spi_example_externally_clocked_with_delay(
let mut adc = max11619_internally_clocked(spi).expect("Creaintg MAX116xx device failed"); spi: SpiBase<SPIB>,
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"),
};
let pot_val = match nb::block!(adc.get_single_channel(&mut eoc_pin)) { match READ_MODE {
Ok(pot_val) => pot_val, ReadMode::Single => {
_ => panic!("Reading single channel value failed"), rprintln!("Reading single potentiometer channel");
}; let pot_val = adc
rprintln!("\tPotentiometer value: {}", pot_val); .read_single_channel(&mut cmd_buf, POTENTIOMETER_CHANNEL, &mut delay_us)
.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,6 +8,7 @@ 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 {
@ -28,30 +29,28 @@ 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: &mut pac::IRQSEL, irqsel: Option<&mut pac::IRQSEL>,
irq: pac::interrupt,
) -> Self { ) -> Self {
self.button = self.button.interrupt_edge(edge_type, syscfg, irqsel, irq); self.button = self
.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: &mut pac::IRQSEL, irqsel: Option<&mut pac::IRQSEL>,
irq: pac::interrupt,
) -> Self { ) -> Self {
self.button = self.button.interrupt_level(level, syscfg, irqsel, irq); self.button = self.button.interrupt_level(level, irq_cfg, syscfg, irqsel);
self self
} }

View File

@ -4,24 +4,20 @@
//! //!
//! - [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, Max11619, Error, ExternallyClocked, InternallyClockedInternallyTimedSerialInterface, Max116xx10Bit,
Max116xx10Bit, RefMode, WithoutWakeupDelay, Max116xx10BitEocExt, VoltageRefMode, WithWakeupDelay, WithoutWakeupDelay,
}; };
use va108xx_hal::gpio::{Floating, Input, Pin, PA14}; use va108xx_hal::gpio::{Floating, Input, Pin, PA14};
pub type Max11619ExternallyClocked<SPI> = pub type Max11619ExternallyClockedNoWakeup<SPI> =
Max116xx10Bit<SPI, DummyPin, Max11619, ExternallyClocked, WithoutWakeupDelay>; Max116xx10Bit<SPI, DummyPin, ExternallyClocked, WithoutWakeupDelay>;
pub type Max11619InternallyClocked<SPI> = Max116xx10Bit< pub type Max11619ExternallyClockedWithWakeup<SPI> =
SPI, Max116xx10Bit<SPI, DummyPin, ExternallyClocked, WithWakeupDelay>;
DummyPin, pub type Max11619InternallyClocked<SPI, EOC> =
Max11619, Max116xx10BitEocExt<SPI, DummyPin, EOC, InternallyClockedInternallyTimedSerialInterface>;
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;
@ -29,37 +25,42 @@ 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<SpiE, SPI>( pub fn max11619_externally_clocked_no_wakeup<SpiE, SPI>(
spi: SPI, spi: SPI,
) -> Result<Max11619ExternallyClocked<SPI>, Error<SpiE, Infallible>> ) -> Result<Max11619ExternallyClockedNoWakeup<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 adc: Max116xx10Bit<SPI, DummyPin, Max11619, ExternallyClocked, WithoutWakeupDelay> = let mut adc = Max116xx10Bit::max11619(spi, DummyPin::new_low())?;
Max116xx10Bit::new( adc.reset(false)?;
spi, adc.setup()?;
DummyPin::new_low(), Ok(adc)
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,
) -> Result<Max11619InternallyClocked<SPI>, Error<SpiE, Infallible>> eoc: EocPin,
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 adc: Max116xx10Bit< let mut adc = Max116xx10Bit::max11619(spi, DummyPin::new_low())?
SPI, .into_int_clkd_int_timed_through_ser_if_without_wakeup(v_ref, eoc)?;
DummyPin, adc.reset(false)?;
Max11619, adc.setup()?;
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, Debug, Copy, Clone)] #[derive(PartialEq, Eq, Debug, Copy, Clone)]
pub enum RegAddresses { pub enum RegAddresses {
Temperature = 0x00, Temperature = 0x00,
Configuration = 0x01, Configuration = 0x01,
@ -67,15 +67,14 @@ 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; let temp_celcius: f32 = if ((adc_code >> 11) & 0x01) == 0 {
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
temp_celcius = adc_code as f32 / 16.0; 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
temp_celcius = (adc_code - 4096) as f32 / 16.0; (adc_code - 4096) as f32 / 16.0
} };
Ok(temp_celcius) Ok(temp_celcius)
} }
} }