From b4933d9106fd319f5d1be6bdcaa994f903741fef Mon Sep 17 00:00:00 2001
From: zdmx <hi@zdmx.me>
Date: Mon, 14 Aug 2023 19:40:08 +0200
Subject: [PATCH] Partially fix captouch

---
 ad7147/src/device.rs   | 10 ++++----
 ad7147/src/driver.rs   | 57 +++++++++++++++++++++++++++++++-----------
 ad7147/src/stage.rs    | 16 ++++++++++--
 src/flow3r/captouch.rs | 17 ++++++++-----
 4 files changed, 73 insertions(+), 27 deletions(-)

diff --git a/ad7147/src/device.rs b/ad7147/src/device.rs
index c382677..e73a612 100644
--- a/ad7147/src/device.rs
+++ b/ad7147/src/device.rs
@@ -406,13 +406,13 @@ impl Default for AmbientCompensationControl {
     fn default() -> Self {
         Self {
             fast_filter_skip: Default::default(),
-            full_power_proximity_disable: 3,
-            low_power_proximity_disable: 2,
-            power_down_timeout: PowerDownTimeout::Factor2,
+            full_power_proximity_disable: 0,
+            low_power_proximity_disable: 0,
+            power_down_timeout: PowerDownTimeout::Factor1_25,
             forced_calibration: false,
             conversion_reset: false,
-            proximity_recalibration_level: 25,
-            proximity_detection_rate: 4,
+            proximity_recalibration_level: 64,
+            proximity_detection_rate: 1,
             slow_filter_update_level: 0,
             full_power_proximity_recalibration: 50,
             low_power_proximity_recalibration: 2,
diff --git a/ad7147/src/driver.rs b/ad7147/src/driver.rs
index 336ff17..3278428 100644
--- a/ad7147/src/driver.rs
+++ b/ad7147/src/driver.rs
@@ -1,4 +1,4 @@
-use byte_slice_cast::{AsByteSlice, AsMutByteSlice};
+use byte_slice_cast::AsByteSlice;
 use embedded_hal_1::delay::DelayUs;
 use embedded_hal::blocking::i2c::{Write, WriteRead};
 use esp_println::println;
@@ -11,6 +11,10 @@ use crate::{
     interrupt::InterruptStatus,
 };
 
+const STAGE_CONVERSION_RESULT_REGISTER: u16 = 0x0B;
+const STAGE_COMPLETED_INTERRUPT_RESULT_REGISTER: u16 = 0x08;
+const DEVICE_ID_REGISTER: u16 = 0x17;
+
 pub struct Uninit;
 pub struct Initialized;
 
@@ -49,22 +53,22 @@ where
             let data_idx = (i * 8) + 1;
             data[data_idx..data_idx + 8].copy_from_slice(&stage.to_reg_value());
         }
-        println!("writing to device: {:x?}", data);
-        self.i2c.write(self.address, data.as_byte_slice())?;
+        println!("writing to device: addr: {:016b} stage0: {:016b}, stage0: {:016b}", data[0], data[1], data[2]);
+        self.i2c.write(self.address, to_be_array(data).as_byte_slice())?;
 
         let mut data = [0u16; 9];
         data[0] = 0x000;
         data[1..9].copy_from_slice(&configuration.0.to_reg_value_for_init());
-        println!("writing to device: {:x?}", data);
-        self.i2c.write(self.address, data.as_byte_slice())?;
+        println!("writing to device: addr: {:016b} pwr_cfg: {:016b}, stage_cal: {:016b}, amb_comp_1: {:016b}, amb_comp_2: {:016b}, amb_comp_3: {:016b}, stage_low_int: {:016b}, stage_high_int: {:016b}, stage_complete_int: {:016b}", data[0], data[1], data[2], data[3], data[4], data[5],  data[6], data[7], data[8]);
+        self.i2c.write(self.address, to_be_array(data).as_byte_slice())?;
 
         delay.delay_ms(100);
 
         let mut data = [0u16; 2];
         data[0] = CalibrationEnable::REGISTER;
         data[1] = configuration.0.calibration_enable.to_reg_value();
-        println!("writing to device: {:x?}", data);
-        self.i2c.write(self.address, data.as_byte_slice())?;
+        println!("writing to device: addr: {:016b} stage_cal: {:016b}", data[0], data[1]);
+        self.i2c.write(self.address, to_be_array(data).as_byte_slice())?;
 
         Ok(Ad7147 {
             i2c: self.i2c,
@@ -80,19 +84,26 @@ where
     I2C: WriteRead<Error = E> + Write<Error = E>,
 {
     pub fn read_all_stages(&mut self) -> Result<[u16; S], E> {
-        let mut result = [0u16; S];
+        let mut result = [0u8; 12*2];
         self.i2c
-            .write_read(self.address, &[0x00B], result.as_mut_byte_slice())?;
+            .write_read(self.address, to_be_array([STAGE_CONVERSION_RESULT_REGISTER]).as_byte_slice(), &mut result)?;
         println!("read from device {:x?}", result);
-        Ok(result)
+        Ok(to_le_u16_array(&result))
     }
 
     pub fn read_interrupt_registers(&mut self) -> Result<InterruptStatus, E> {
-        let mut data = [0u16; 3];
+        let mut data = [0u8; 6];
         self.i2c
-            .write_read(self.address, &[0x008], data.as_mut_byte_slice())?;
+            .write_read(self.address, to_be_array([STAGE_COMPLETED_INTERRUPT_RESULT_REGISTER]).as_byte_slice(), &mut data)?;
         println!("read from device {:x?}", data);
-        Ok(InterruptStatus::from_registers(data))
+        Ok(InterruptStatus::from_registers(to_le_u16_array(&data)))
+    }
+
+    pub fn read_device_id(&mut self) -> Result<u16, E> {
+        let mut data = [0u8; 2];
+        self.i2c
+            .write_read(self.address, to_be_array([DEVICE_ID_REGISTER]).as_byte_slice(), &mut data)?;
+        Ok(u16::from_be_bytes(data))
     }
 
     pub fn reset(&mut self) -> Result<(), E> {
@@ -101,6 +112,24 @@ where
         let mut data = [0u16; 4];
         data[0] = AmbientCompensationControl::REGISTER;
         data[1..8].copy_from_slice(&acc_reg.to_reg_value());
-        self.i2c.write(self.address, data.as_byte_slice())
+        self.i2c.write(self.address, to_be_array(data).as_byte_slice())
+    }
+}
+
+
+fn to_be_array<const N: usize>(data: [u16;N]) -> [u16;N] {
+    let mut result = [0u16;N];
+    for (i, word) in data.into_iter().enumerate() {
+        result[i] = word.to_be();
     }
+    result
 }
+
+fn to_le_u16_array<const N: usize>(data: &[u8]) -> [u16;N] {
+    let mut result = [0u16;N];
+    for i in 0..N {
+        let (int_bytes, _) = data[i*2..].split_at(core::mem::size_of::<u16>());
+        result[i] = u16::from_be_bytes(int_bytes.try_into().unwrap());
+    }
+    result
+}
\ No newline at end of file
diff --git a/ad7147/src/stage.rs b/ad7147/src/stage.rs
index fc051a1..e393760 100644
--- a/ad7147/src/stage.rs
+++ b/ad7147/src/stage.rs
@@ -72,6 +72,16 @@ impl StageConfigurationBuilder {
         self
     }
 
+    pub fn pos_afe_offset(mut self, offset: u8) -> StageConfigurationBuilder {
+        self.configuration.afe_offset_configuration.pos_afe_offset = offset;
+        self
+    }
+
+    pub fn neg_afe_offset(mut self, offset: u8) -> StageConfigurationBuilder {
+        self.configuration.afe_offset_configuration.neg_afe_offset = offset;
+        self
+    }
+
     pub fn build(mut self) -> StageConfiguration {
         if self.input_connections.len() > 1 {
             self.configuration.input_configuration =
@@ -138,7 +148,8 @@ impl InputMode {
                 panic!("Input mode cannot be left unconfigured")
             }
             InputMode::SingleEnded(conn) => {
-                res |= (conn.cdc as u32) << (conn.cin as u32);
+                res |= 0xFFFFFFFF >> 4;
+                res &= ((conn.cdc as u32) << (conn.cin as u32)) | !(0b11 << (conn.cin as u32));
                 res |= if conn.cdc == CdcInput::Positive {
                     0b01
                 } else {
@@ -146,8 +157,9 @@ impl InputMode {
                 } << 28;
             }
             InputMode::Differential(conns) => {
+                res |= 0xFFFFFFFF >> 4;
                 for conn in conns {
-                    res |= (conn.cdc as u32) << (conn.cin as u32);
+                    res &= ((conn.cdc as u32) << (conn.cin as u32)) | !(0b11 << (conn.cin as u32));
                 }
                 res |= 0b11 << 28;
             }
diff --git a/src/flow3r/captouch.rs b/src/flow3r/captouch.rs
index 3b55001..ac57e16 100644
--- a/src/flow3r/captouch.rs
+++ b/src/flow3r/captouch.rs
@@ -3,13 +3,13 @@ use ad7147::{
     stage::{CapInput, CdcInput, InputConnection},
     Ad7147, DeviceConfiguration, Initialized, StageConfiguration,
 };
-use embassy_time::Delay;
+use embassy_time::{Delay, Duration, Timer};
 use embedded_hal_async::digital::Wait;
 use esp_println::println;
 use hal::{
     gpio::{Gpio16, Unknown},
     i2c::I2C,
-    peripherals::I2C0,
+    peripherals::I2C0, prelude::_esp_hal_gpio_InputPin,
 };
 use shared_bus::{I2cProxy, XtensaMutex};
 
@@ -24,8 +24,6 @@ fn init_captouch(
     let ad7147 = Ad7147::new(i2c, 0b00101100);
     let config = DeviceConfiguration::builder()
         .decimation(DecimationFactor::Factor64)
-        .cdc_bias_current(ad7147::device::CdcBias::Plus35Percent)
-        .power_mode(ad7147::device::PowerMode::Low)
         .stages([StageConfiguration::builder()
             .calibration_enabled(true)
             .conversion_complete_interrupt_enabled(true)
@@ -44,18 +42,25 @@ pub async fn captouch_controller(
     i2c: I2cProxy<'static, XtensaMutex<I2C<'static, I2C0>>>,
     cap_b_int: Gpio16<Unknown>,
 ) -> ! {
+    let mut cap_b_int = cap_b_int.into_pull_up_input();
     let mut ad7147 = init_captouch(i2c).unwrap();
-    let mut bottom_interrupt = cap_b_int.into_pull_up_input();
+
+    let device_id = ad7147.read_device_id().unwrap();
+    println!("captouch device id: {:016b}", device_id);
 
     let ints = ad7147.read_interrupt_registers().unwrap();
     println!("ints: {:?}", ints);
 
+    println!("int pin: {}", cap_b_int.is_input_high());
     println!("initialized captouch");
     loop {
-        bottom_interrupt.wait_for_low().await.unwrap();
+        println!("int pin: {}", cap_b_int.is_input_high());
+        // cap_b_int.wait_for_low().await.unwrap();
+        println!("captouch interrupt");
         let ints = ad7147.read_interrupt_registers().unwrap();
         println!("ints: {:?}", ints);
         let measurement = ad7147.read_all_stages().unwrap();
         println!("{}", measurement[0]);
+        Timer::after(Duration::from_secs(10)).await;
     }
 }
-- 
GitLab