Initial proof of concept
This commit is contained in:
9
examples/ads1256/.cargo/config.toml
Normal file
9
examples/ads1256/.cargo/config.toml
Normal file
@ -0,0 +1,9 @@
|
||||
[target.'cfg(all(target_arch = "arm", target_os = "none"))']
|
||||
# replace STM32F411CEUx with your chip as listed in `probe-rs chip list`
|
||||
runner = "probe-rs run --chip STM32F411CEUx"
|
||||
|
||||
[build]
|
||||
target = "thumbv7em-none-eabi"
|
||||
|
||||
[env]
|
||||
DEFMT_LOG = "trace"
|
37
examples/ads1256/Cargo.toml
Normal file
37
examples/ads1256/Cargo.toml
Normal file
@ -0,0 +1,37 @@
|
||||
[package]
|
||||
name = "ads1256-examples"
|
||||
description = "Examples using the ads1256."
|
||||
version.workspace = true
|
||||
edition.workspace = true
|
||||
repository.workspace = true
|
||||
readme.workspace = true
|
||||
license.workspace = true
|
||||
|
||||
[dependencies.ads1256]
|
||||
path = "../../drivers/ads1256/driver"
|
||||
[dependencies.physical]
|
||||
path = "../.."
|
||||
features = ["defmt"]
|
||||
[dependencies.defmt]
|
||||
workspace = true
|
||||
[dependencies.defmt-rtt]
|
||||
workspace = true
|
||||
[dependencies.cortex-m]
|
||||
workspace = true
|
||||
features = ["critical-section-single-core"]
|
||||
[dependencies.cortex-m-rt]
|
||||
workspace = true
|
||||
[dependencies.embassy-stm32]
|
||||
workspace = true
|
||||
features = ["stm32f411ce", "memory-x", "time", "exti", "time-driver-any"]
|
||||
[dependencies.embassy-executor]
|
||||
workspace = true
|
||||
[dependencies.embassy-futures]
|
||||
workspace = true
|
||||
[dependencies.embassy-time]
|
||||
workspace = true
|
||||
features = ["tick-hz-16_000_000"]
|
||||
[dependencies.panic-probe]
|
||||
workspace = true
|
||||
[dependencies]
|
||||
log = "0.4.20"
|
5
examples/ads1256/build.rs
Normal file
5
examples/ads1256/build.rs
Normal file
@ -0,0 +1,5 @@
|
||||
fn main() {
|
||||
println!("cargo:rustc-link-arg-bins=--nmagic");
|
||||
println!("cargo:rustc-link-arg-bins=-Tlink.x");
|
||||
println!("cargo:rustc-link-arg-bins=-Tdefmt.x");
|
||||
}
|
131
examples/ads1256/src/bin/adc.rs
Normal file
131
examples/ads1256/src/bin/adc.rs
Normal file
@ -0,0 +1,131 @@
|
||||
#![no_std]
|
||||
#![no_main]
|
||||
|
||||
use cortex_m::prelude::{_embedded_hal_blocking_delay_DelayMs, _embedded_hal_blocking_delay_DelayUs};
|
||||
use {defmt_rtt as _, panic_probe as _};
|
||||
|
||||
use {embassy_executor as executor, embassy_stm32 as stm32};
|
||||
|
||||
use ads1256::{
|
||||
AdControl, Ads1256, AutoCal, BitOrder, Buffer, ClockOut, Config, DState, DataRate, DigitalIo,
|
||||
DigitalIoDirection, DigitalIoState, DioDirection, Gain, Multiplexer, MuxInput, OutputPin, Sdcs,
|
||||
SpiBus, Status, Wait, BlockingDelay
|
||||
};
|
||||
use embassy_time::{Delay, Timer};
|
||||
use executor::Spawner;
|
||||
use physical::quantity::Quantity;
|
||||
use stm32::dma::NoDma;
|
||||
use stm32::exti::ExtiInput;
|
||||
use stm32::gpio::{Input, Level, Output, Pull, Speed};
|
||||
use stm32::spi::Spi;
|
||||
use stm32::time::Hertz;
|
||||
use stm32::{pac, spi};
|
||||
|
||||
use defmt::{debug, error, info, trace, unwrap};
|
||||
|
||||
const AUTOCAL_CONF: Config = Config {
|
||||
status: Status::setting(Buffer::Enabled, AutoCal::Enabled, BitOrder::MostSigFirst),
|
||||
multiplexer: Multiplexer::setting(MuxInput::AIn0, MuxInput::Common),
|
||||
ad_control: AdControl::setting(Gain::X2, Sdcs::Off, ClockOut::Off),
|
||||
data_rate: DataRate::Sps2_5,
|
||||
digital_io: DigitalIo::setting(DigitalIoState::default(), DigitalIoDirection::default()),
|
||||
};
|
||||
|
||||
const ADS1256_DELAY: ads1256::DefaultDelay<Delay> = ads1256::DefaultDelay::new(Delay);
|
||||
|
||||
#[embassy_executor::main]
|
||||
async fn main(spawner: Spawner) {
|
||||
unsafe {
|
||||
pac::FLASH.acr().modify(|v| {
|
||||
v.set_prften(true);
|
||||
v.set_icen(true);
|
||||
v.set_dcen(true);
|
||||
});
|
||||
}
|
||||
|
||||
let p = embassy_stm32::init(Default::default());
|
||||
|
||||
let mut spi_conf = spi::Config::default();
|
||||
spi_conf.mode = spi::MODE_1;
|
||||
spi_conf.bit_order = spi::BitOrder::MsbFirst;
|
||||
spi_conf.frequency = Hertz(ads1256::defaults::SPI_CLK_HZ);
|
||||
|
||||
let ads1256_data_ready = ExtiInput::new(Input::new(p.PA3, Pull::Up), p.EXTI3);
|
||||
let select_ads1256 = Output::new(p.PA1, Level::High, Speed::VeryHigh);
|
||||
|
||||
let mut spi = Spi::new(
|
||||
p.SPI1,
|
||||
p.PA5,
|
||||
p.PA7,
|
||||
p.PA6,
|
||||
NoDma,
|
||||
NoDma,
|
||||
spi_conf,
|
||||
);
|
||||
|
||||
let mut ads_1256 = Ads1256::new(ADS1256_DELAY, select_ads1256, ads1256_data_ready);
|
||||
// single_conversion(&mut spi, &mut ads_1256).await;
|
||||
// ads_1256.delayer.t11_1_delay();
|
||||
// read_continuous(&mut spi, &mut ads_1256).await;
|
||||
cycle_multiplexer(&mut spi, &mut ads_1256).await;
|
||||
}
|
||||
|
||||
async fn single_conversion<DelayerT: ads1256::BlockingDelay, SST: OutputPin, DrdyT: Wait>(
|
||||
spi: &mut impl SpiBus,
|
||||
ads_1256: &mut Ads1256<DelayerT, SST, DrdyT>,
|
||||
) {
|
||||
ads_1256.write_config(spi, AUTOCAL_CONF).unwrap();
|
||||
ads_1256.delayer.t11_1_delay();
|
||||
ads_1256.conversion_init(spi).unwrap();
|
||||
let data = ads_1256.cmd_read_data(spi).await.unwrap();
|
||||
info!("data: {}, volts: {}", data, data.to_voltage(AUTOCAL_CONF.ad_control.gain()).fmt(Some(5)));
|
||||
}
|
||||
|
||||
async fn read_continuous<DelayerT: ads1256::BlockingDelay, SST: OutputPin, DrdyT: Wait>(
|
||||
spi: &mut impl SpiBus,
|
||||
ads_1256: &mut Ads1256<DelayerT, SST, DrdyT>,
|
||||
) {
|
||||
ads_1256.write_config(spi, AUTOCAL_CONF).unwrap();
|
||||
ads_1256.delayer.t11_1_delay();
|
||||
ads_1256.start_rdatac(spi).await.unwrap();
|
||||
loop {
|
||||
let data = ads_1256.read_data(spi).await.unwrap();
|
||||
info!("data: {}, volts: {}", data, data.to_voltage(AUTOCAL_CONF.ad_control.gain()).fmt(Some(5)));
|
||||
}
|
||||
}
|
||||
|
||||
async fn cycle_multiplexer<DelayerT: ads1256::BlockingDelay, SST: OutputPin, DrdyT: Wait>(
|
||||
spi: &mut impl SpiBus,
|
||||
ads_1256: &mut Ads1256<DelayerT, SST, DrdyT>,
|
||||
) {
|
||||
const INPUT_1: Multiplexer = Multiplexer::setting(MuxInput::AIn1, MuxInput::Common);
|
||||
const INPUT_2: Multiplexer = Multiplexer::setting(MuxInput::AIn2, MuxInput::Common);
|
||||
const INPUT_3: Multiplexer = Multiplexer::setting(MuxInput::AIn3, MuxInput::Common);
|
||||
|
||||
let ad_control = AUTOCAL_CONF.ad_control;
|
||||
let status = AUTOCAL_CONF.status;
|
||||
|
||||
ads_1256.write_config(spi, AUTOCAL_CONF).unwrap();
|
||||
ads_1256.delayer.t11_1_delay();
|
||||
loop {
|
||||
let ad_control = ad_control.with_gain(Gain::X4);
|
||||
let data = ads_1256
|
||||
.autocal_convert(spi, INPUT_1, None, Some(ad_control.with_gain(Gain::X4)), None, false)
|
||||
.await
|
||||
.unwrap();
|
||||
info!("Input 1: data: {}, volts: {}", data, data.to_voltage(ad_control.gain()).fmt(Some(5)));
|
||||
let ad_control = ad_control.with_gain(Gain::X8);
|
||||
let data = ads_1256
|
||||
.autocal_convert(spi, INPUT_2, None, Some(ad_control.with_gain(Gain::X8)), None, false)
|
||||
.await
|
||||
.unwrap();
|
||||
info!("Input 2: data: {}, volts: {}", data, data.to_voltage(ad_control.gain()).fmt(Some(5)));
|
||||
let ad_control = ad_control.with_gain(Gain::X16);
|
||||
let data = ads_1256
|
||||
.autocal_convert(spi, INPUT_3, None, Some(ad_control.with_gain(Gain::X16)), None, false)
|
||||
.await
|
||||
.unwrap();
|
||||
info!("Input 3: data: {}, volts: {}", data, data.to_voltage(ad_control.gain()).fmt(Some(5)));
|
||||
}
|
||||
|
||||
}
|
180
examples/ads1256/src/bin/registers.rs
Normal file
180
examples/ads1256/src/bin/registers.rs
Normal file
@ -0,0 +1,180 @@
|
||||
#![no_std]
|
||||
#![no_main]
|
||||
|
||||
use cortex_m::prelude::_embedded_hal_blocking_delay_DelayUs;
|
||||
use {defmt_rtt as _, panic_probe as _};
|
||||
|
||||
use {embassy_executor as executor, embassy_stm32 as stm32};
|
||||
|
||||
use ads1256::{
|
||||
AdControl, Ads1256, AutoCal, BitOrder, Buffer, ClockOut, Config, DState, DataRate, DigitalIo,
|
||||
DigitalIoDirection, DigitalIoState, DioDirection, Gain, Multiplexer, MuxInput, OutputPin, Sdcs,
|
||||
SpiBus, Status, Wait,
|
||||
};
|
||||
use embassy_time::Delay;
|
||||
use executor::Spawner;
|
||||
use stm32::dma::NoDma;
|
||||
use stm32::exti::ExtiInput;
|
||||
use stm32::gpio::{Input, Level, Output, Pull, Speed};
|
||||
use stm32::spi::Spi;
|
||||
use stm32::time::Hertz;
|
||||
use stm32::{pac, spi};
|
||||
|
||||
use defmt::{debug, error, info, trace, unwrap};
|
||||
|
||||
const ADS1256_DELAY: ads1256::DefaultDelay<Delay> = ads1256::DefaultDelay::new(Delay);
|
||||
|
||||
#[embassy_executor::main]
|
||||
async fn main(spawner: Spawner) {
|
||||
unsafe {
|
||||
pac::FLASH.acr().modify(|v| {
|
||||
v.set_prften(true);
|
||||
v.set_icen(true);
|
||||
v.set_dcen(true);
|
||||
});
|
||||
}
|
||||
|
||||
let p = embassy_stm32::init(Default::default());
|
||||
|
||||
let mut spi_conf = spi::Config::default();
|
||||
spi_conf.mode = spi::MODE_1;
|
||||
spi_conf.bit_order = spi::BitOrder::MsbFirst;
|
||||
spi_conf.frequency = Hertz(ads1256::defaults::SPI_CLK_HZ);
|
||||
|
||||
let ads1256_data_ready = ExtiInput::new(Input::new(p.PA3, Pull::Up), p.EXTI3);
|
||||
let select_ads1256 = Output::new(p.PA1, Level::High, Speed::VeryHigh);
|
||||
|
||||
let mut spi = Spi::new(
|
||||
p.SPI1,
|
||||
p.PA5,
|
||||
p.PA7,
|
||||
p.PA6,
|
||||
NoDma,
|
||||
NoDma,
|
||||
spi_conf,
|
||||
);
|
||||
|
||||
let mut ads_1256 = Ads1256::new(ADS1256_DELAY, select_ads1256, ads1256_data_ready);
|
||||
// status(&mut spi, &mut ads_1256);
|
||||
// multiplexer(&mut spi, &mut ads_1256);
|
||||
// ad_control(&mut spi, &mut ads_1256);
|
||||
// data_rate(&mut spi, &mut ads_1256);
|
||||
// gpio(&mut spi, &mut ads_1256);
|
||||
config(&mut spi, &mut ads_1256);
|
||||
}
|
||||
|
||||
fn status<DelayerT: ads1256::BlockingDelay, SST: OutputPin, DrdyT: Wait>(
|
||||
spi: &mut impl SpiBus,
|
||||
ads_1256: &mut Ads1256<DelayerT, SST, DrdyT>,
|
||||
) {
|
||||
info!("Status register:");
|
||||
const STATUS_SETTING: Status =
|
||||
Status::setting(Buffer::Disabled, AutoCal::Disabled, BitOrder::MostSigFirst);
|
||||
ads_1256.write_status(spi, STATUS_SETTING).unwrap();
|
||||
let status = ads_1256.read_status(spi).unwrap();
|
||||
info!("ADS1256 starting status: {}", status);
|
||||
let new_status_setting = status.with_buffer(Buffer::Enabled);
|
||||
ads_1256.write_status(spi, new_status_setting).unwrap();
|
||||
let status = ads_1256.read_status(spi).unwrap();
|
||||
info!("ADS1256 new status: {}", status);
|
||||
}
|
||||
|
||||
fn multiplexer<DelayerT: ads1256::BlockingDelay, SST: OutputPin, DrdyT: Wait>(
|
||||
spi: &mut impl SpiBus,
|
||||
ads_1256: &mut Ads1256<DelayerT, SST, DrdyT>,
|
||||
) {
|
||||
info!("Multiplexer register:");
|
||||
const MULTIPLEXER_SETTING: Multiplexer = Multiplexer::setting(MuxInput::AIn0, MuxInput::Common);
|
||||
ads_1256
|
||||
.write_multiplexer(spi, MULTIPLEXER_SETTING)
|
||||
.unwrap();
|
||||
let multiplexer = ads_1256.read_multiplexer(spi).unwrap();
|
||||
info!("ADS1256 starting multiplexer: {}", multiplexer);
|
||||
let new_multiplexer_setting = multiplexer.with_positive(MuxInput::AIn1);
|
||||
ads_1256
|
||||
.write_multiplexer(spi, new_multiplexer_setting)
|
||||
.unwrap();
|
||||
let multiplexer = ads_1256.read_multiplexer(spi).unwrap();
|
||||
info!("ADS1256 new ad_control: {}", multiplexer);
|
||||
}
|
||||
|
||||
fn ad_control<DelayerT: ads1256::BlockingDelay, SST: OutputPin, DrdyT: Wait>(
|
||||
spi: &mut impl SpiBus,
|
||||
ads_1256: &mut Ads1256<DelayerT, SST, DrdyT>,
|
||||
) {
|
||||
info!("AD control register:");
|
||||
const AD_CONTROL_SETTING: AdControl = AdControl::setting(Gain::X64, Sdcs::Off, ClockOut::Off);
|
||||
ads_1256.write_ad_control(spi, AD_CONTROL_SETTING).unwrap();
|
||||
let ad_control = ads_1256.read_ad_control(spi).unwrap();
|
||||
info!("ADS1256 starting ad_control: {}", ad_control);
|
||||
let new_ad_control_setting = ad_control.with_gain(Gain::X1);
|
||||
ads_1256
|
||||
.write_ad_control(spi, new_ad_control_setting)
|
||||
.unwrap();
|
||||
let ad_control = ads_1256.read_ad_control(spi).unwrap();
|
||||
info!("ADS1256 new ad_control: {}", ad_control);
|
||||
}
|
||||
|
||||
fn data_rate<DelayerT: ads1256::BlockingDelay, SST: OutputPin, DrdyT: Wait>(
|
||||
spi: &mut impl SpiBus,
|
||||
ads_1256: &mut Ads1256<DelayerT, SST, DrdyT>,
|
||||
) {
|
||||
info!("Data rate register:");
|
||||
const DATA_RATE: DataRate = DataRate::Sps2_5;
|
||||
ads_1256.write_data_rate(spi, DATA_RATE).unwrap();
|
||||
let data_rate = ads_1256.read_data_rate(spi).unwrap();
|
||||
info!("ADS1256 starting data rate: {}", data_rate);
|
||||
ads_1256.write_data_rate(spi, DataRate::Sps60).unwrap();
|
||||
let data_rate = ads_1256.read_data_rate(spi).unwrap();
|
||||
info!("ADS1256 new data rate: {}", data_rate);
|
||||
}
|
||||
|
||||
fn gpio<DelayerT: ads1256::BlockingDelay, SST: OutputPin, DrdyT: Wait>(
|
||||
spi: &mut impl SpiBus,
|
||||
ads_1256: &mut Ads1256<DelayerT, SST, DrdyT>,
|
||||
) {
|
||||
info!("GPIO register:");
|
||||
const GPIO: DigitalIo = DigitalIo::setting(
|
||||
DigitalIoState::new(DState::Low, DState::Low, DState::Low, DState::Low),
|
||||
DigitalIoDirection::new(
|
||||
DioDirection::Output,
|
||||
DioDirection::Input,
|
||||
DioDirection::Input,
|
||||
DioDirection::Output,
|
||||
),
|
||||
);
|
||||
ads_1256.write_gpio(spi, GPIO).unwrap();
|
||||
let gpio = ads_1256.read_gpio(spi).unwrap();
|
||||
info!("ADS1256 starting gpio: {}", gpio);
|
||||
let new_gpio_setting = gpio.with_io3_state(DState::High);
|
||||
ads_1256.write_gpio(spi, new_gpio_setting).unwrap();
|
||||
let gpio = ads_1256.read_gpio(spi).unwrap();
|
||||
info!("ADS1256 new gpio: {}", gpio);
|
||||
}
|
||||
|
||||
fn config<DelayerT: ads1256::BlockingDelay, SST: OutputPin, DrdyT: Wait>(
|
||||
spi: &mut impl SpiBus,
|
||||
ads_1256: &mut Ads1256<DelayerT, SST, DrdyT>,
|
||||
) {
|
||||
info!("Config:");
|
||||
let config = ads_1256.read_config(spi).unwrap();
|
||||
info!("ADS1256 starting config: {}", config);
|
||||
const CONFIG: Config = Config {
|
||||
status: Status::setting(Buffer::Enabled, AutoCal::Enabled, BitOrder::MostSigFirst),
|
||||
multiplexer: Multiplexer::setting(MuxInput::AIn4, MuxInput::AIn5),
|
||||
ad_control: AdControl::setting(Gain::X16, Sdcs::Off, ClockOut::Off),
|
||||
data_rate: DataRate::Sps10,
|
||||
digital_io: DigitalIo::setting(
|
||||
DigitalIoState::new(DState::Low, DState::Low, DState::Low, DState::Low),
|
||||
DigitalIoDirection::new(
|
||||
DioDirection::Output,
|
||||
DioDirection::Input,
|
||||
DioDirection::Input,
|
||||
DioDirection::Input,
|
||||
),
|
||||
),
|
||||
};
|
||||
ads_1256.write_config(spi, CONFIG).unwrap();
|
||||
let config = ads_1256.read_config(spi).unwrap();
|
||||
info!("ADS1256 new config: {:#?}", config);
|
||||
}
|
Reference in New Issue
Block a user