Included lib for adg2128.

This commit is contained in:
2025-07-21 17:33:48 +02:00
parent ed49071ffa
commit 0c18664e48
5 changed files with 331 additions and 11 deletions

160
src/adg2128.rs Normal file
View File

@@ -0,0 +1,160 @@
use embassy_embedded_hal::shared_bus::blocking::i2c::I2cDevice;
use embassy_stm32::{i2c::I2c, mode::Blocking};
use embassy_sync::blocking_mutex::raw::NoopRawMutex;
use embedded_hal_1::i2c::I2c as _;
#[derive(Copy, Clone)]
#[allow(dead_code)]
pub enum SetX {
X0 = 0b0000,
X1,
X2,
X3,
X4,
X5,
X6 = 0b1000,
X7,
X8,
X9,
X10,
X11,
}
impl SetX{
pub fn from_u8(value: u8) -> Self {
const VARIANTS: [SetX; 12] = [
SetX::X0, SetX::X1, SetX::X2, SetX::X3,
SetX::X4, SetX::X5, SetX::X6, SetX::X7,
SetX::X8, SetX::X9, SetX::X10, SetX::X11,
];
*VARIANTS.get(value as usize).expect("Invalid value for SetX")
}
}
#[derive(Copy, Clone)]
#[allow(dead_code)]
pub enum SetY {
Y0 = 0b000,
Y1,
Y2,
Y3,
Y4,
Y5,
Y6,
Y7,
}
impl SetY {
pub fn from_u8(value: u8) -> Self {
const VARIANTS: [SetY; 8] = [
SetY::Y0, SetY::Y1, SetY::Y2, SetY::Y3,
SetY::Y4, SetY::Y5, SetY::Y6, SetY::Y7,
];
*VARIANTS.get(value as usize).expect("Invalid value for SetY")
}
}
#[derive(Copy, Clone)]
#[allow(dead_code)]
pub enum GetX {
X0 = 0b0011_0100,
X1 = 0b0011_1100,
X2 = 0b0111_0100,
X3 = 0b0111_1100,
X4 = 0b0011_0101,
X5 = 0b0011_1101,
X6 = 0b0111_0101,
X7 = 0b0111_1101,
X8 = 0b0011_0110,
X9 = 0b0011_1110,
X10 = 0b0111_0110,
X11 = 0b0111_1110,
}
impl GetX {
pub fn from_u8(value: u8) -> Self {
const VARIANTS: [GetX; 12] = [
GetX::X0, GetX::X1, GetX::X2, GetX::X3,
GetX::X4, GetX::X5, GetX::X6, GetX::X7,
GetX::X8, GetX::X9, GetX::X10, GetX::X11,
];
*VARIANTS.get(value as usize).expect("Invalid value for GetX")
}
}
#[allow(dead_code)]
pub enum State {
DISABLED = 0b0,
ENABLED = 0b1,
}
#[allow(dead_code)]
enum LDSW {
EN = 0b1,
DIS = 0b0,
}
pub struct ADG2128 {
i2c: I2cDevice<'static, NoopRawMutex, I2c<'static, Blocking>>,
address: u8,
states_xy: [u8; 12]
}
impl ADG2128 {
pub fn new(i2c: I2cDevice<'static, NoopRawMutex, I2c<'static, Blocking>>, address: u8) -> Self {
ADG2128 { i2c, address, states_xy: [0u8; 12]}
}
pub fn set(&mut self, io_1: SetX, io_2: SetY, state: State) {
let mut data = [0u8; 2];
data[0] = (state as u8) << 7 | (io_1 as u8) << 3 | (io_2 as u8);
data[1] = LDSW::EN as u8;
self.i2c.write(self.address, &data).unwrap()
}
pub fn get(&mut self, io: GetX) -> u8 {
let mut data_out = [0u8; 2];
let mut data_in = [0u8; 2];
data_out[0] = io as u8;
self.i2c.write_read(self.address, &mut data_out, &mut data_in).unwrap();
data_in[1]
}
pub fn get_all(&mut self) -> [u8; 12] {
let mut states_xy = [0u8; 12];
for (x_line, y_states) in states_xy.iter_mut().enumerate() {
let x_line_data = GetX::from_u8(x_line as u8);
*y_states = self.get(x_line_data);
}
self.states_xy.copy_from_slice(states_xy.as_slice());
states_xy
}
pub fn reset_all(&mut self) {
let states_xy = self.get_all();
// Find bits that are set
for (x_line, &state) in states_xy.iter().enumerate() {
if state == 0 {
continue; // Skip zero states early
}
for value in 0..8 {
if (state >> value) & 1 == 1 {
self.set(
SetX::from_u8(x_line as u8),
SetY::from_u8(value),
State::DISABLED,
);
}
}
}
}
}

88
src/electrodes.rs Normal file
View File

@@ -0,0 +1,88 @@
use embassy_embedded_hal::shared_bus::blocking::i2c::I2cDevice;
use embassy_stm32::{i2c, mode::Blocking};
use embassy_sync::blocking_mutex::NoopMutex;
use static_cell::StaticCell;
use core::cell::RefCell;
use crate::{ad5940, adg2128::{GetX, SetX, SetY, State, ADG2128}};
static I2C_BUS: StaticCell<NoopMutex<RefCell<i2c::I2c<'static, Blocking>>>> = StaticCell::new();
#[derive(Copy, Clone)]
#[allow(dead_code)]
pub enum Electrode {
E0, E1, E2, E3, E4, E5, E6, E7,
E8, E9, E10, E11, E12, E13, E14, E15,
E16, E17, E18, E19, E20, E21, E22, E23,
}
impl Electrode {
pub fn from_u8(value: u8) -> Self {
const VARIANTS: [Electrode; 24] = [
Electrode::E0, Electrode::E1, Electrode::E2, Electrode::E3,
Electrode::E4, Electrode::E5, Electrode::E6, Electrode::E7,
Electrode::E8, Electrode::E9, Electrode::E10, Electrode::E11,
Electrode::E12, Electrode::E13, Electrode::E14, Electrode::E15,
Electrode::E16, Electrode::E17, Electrode::E18, Electrode::E19,
Electrode::E20, Electrode::E21, Electrode::E22, Electrode::E23,
];
*VARIANTS.get(value as usize).expect("Invalid value for SetX")
}
}
#[derive(Copy, Clone)]
#[allow(dead_code)]
pub enum AD5940Pin {
CE0, RE0, SE0, DE0,
AIN0, AIN1, AIN2, AIN3,
}
pub struct Electrodes {
mux_1: ADG2128,
mux_2: ADG2128,
}
impl Electrodes {
pub fn new(i2c: i2c::I2c<'static, Blocking>) -> Self {
let i2c_bus = NoopMutex::new(RefCell::new(i2c));
let i2c_bus = I2C_BUS.init(i2c_bus);
Electrodes {
mux_1: ADG2128::new(I2cDevice::new(i2c_bus), 0b1110_000),
mux_2: ADG2128::new(I2cDevice::new(i2c_bus), 0b1110_001),
}
}
pub fn set(&mut self, electrode: Electrode, ad5940_pin: AD5940Pin, state: State) {
let electrode = electrode as u8;
let ad5940_pin = ad5940_pin as u8;
match electrode {
0..=11 => {
self.mux_1.set(SetX::from_u8(electrode), SetY::from_u8(ad5940_pin), state);
}
12..=23 => {
self.mux_2.set(SetX::from_u8(electrode-12), SetY::from_u8(ad5940_pin), state);
}
_ => panic!("Invalid electrode number"),
}
}
pub fn get(&mut self, io: Electrode) -> u8 {
let number = io as u8;
match number {
0..=11 => self.mux_1.get(GetX::from_u8(number)),
12..=23 => self.mux_2.get(GetX::from_u8(number-12)),
_ => panic!("Invalid electrode number"),
}
}
pub fn get_all(&mut self) -> ([u8; 12], [u8; 12]) {
(self.mux_1.get_all(), self.mux_2.get_all())
}
pub fn reset_all(&mut self) {
self.mux_1.reset_all();
self.mux_2.reset_all();
}
}

View File

@@ -4,13 +4,20 @@
use defmt::*;
use embassy_executor::Spawner;
use embassy_stm32::gpio::{Level, Output, Speed};
use embassy_stm32::{adc, spi, Config};
use embassy_stm32::{i2c, spi, Config};
use embassy_stm32::time::Hertz;
use embassy_time::Timer;
use {defmt_rtt as _, panic_probe as _};
mod ad5940;
use ad5940::AD5940;
mod adg2128;
use adg2128::State;
mod electrodes;
use electrodes::{Electrodes, Electrode, AD5940Pin};
mod ad5940_registers;
#[embassy_executor::main]
@@ -34,6 +41,7 @@ async fn main(_spawner: Spawner) {
// let mut led = Output::new(p.PA5, Level::High, Speed::Low);
// Set up SPI for AD5940
let cs = Output::new(p.PC9, Level::High, Speed::Low);
let spi = spi::Spi::new_blocking(
@@ -49,6 +57,21 @@ async fn main(_spawner: Spawner) {
ad5940.init_temperature().await.unwrap();
// Set up I2C for ADG2128
let i2c = i2c::I2c::new_blocking(
p.I2C1,
p.PB6,
p.PB7,
Hertz(400_000),
i2c::Config::default()
);
// Initialize electrodes
let mut electrodes = Electrodes::new(i2c);
electrodes.reset_all();
electrodes.set(Electrode::E11, AD5940Pin::CE0, State::ENABLED);
electrodes.set(Electrode::E12, AD5940Pin::RE0, State::ENABLED);
loop {
// Read chip id
// let chip_id = ad5940.get_chipid().await.unwrap();
@@ -58,6 +81,9 @@ async fn main(_spawner: Spawner) {
let temp = ad5940.get_temperature().await.unwrap();
info!("Temperature: {}°C", temp);
let result = electrodes.get_all();
info!("Electrodes states: {:?}", result);
// info!("high");
// led.set_high();
Timer::after_millis(500).await;