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