From b276fddb32b51c640e7f59d90a6c74a6799da34b Mon Sep 17 00:00:00 2001 From: Daniel Schaefer Date: Mon, 30 Sep 2024 20:24:11 +0800 Subject: [PATCH 1/5] Add accelerometer support Signed-off-by: Daniel Schaefer --- framework_lib/src/power.rs | 63 ++++++++++++++++++++++++++++++++++---- 1 file changed, 57 insertions(+), 6 deletions(-) diff --git a/framework_lib/src/power.rs b/framework_lib/src/power.rs index b8477f63..760247c2 100644 --- a/framework_lib/src/power.rs +++ b/framework_lib/src/power.rs @@ -54,12 +54,13 @@ const EC_MEMMAP_BATT_SERIAL: u16 = 0x70; // Battery Serial Number String const EC_MEMMAP_BATT_TYPE: u16 = 0x78; // Battery Type String const EC_MEMMAP_ALS: u16 = 0x80; // ALS readings in lux (2 X 16 bits) // Unused 0x84 - 0x8f -const _EC_MEMMAP_ACC_STATUS: u16 = 0x90; // Accelerometer status (8 bits ) - // Unused 0x91 -const _EC_MEMMAP_ACC_DATA: u16 = 0x92; // Accelerometers data 0x92 - 0x9f - // 0x92: u16Lid Angle if available, LID_ANGLE_UNRELIABLE otherwise - // 0x94 - 0x99: u161st Accelerometer - // 0x9a - 0x9f: u162nd Accelerometer +const EC_MEMMAP_ACC_STATUS: u16 = 0x90; // Accelerometer status (8 bits ) + // Unused 0x91 +const EC_MEMMAP_ACC_DATA: u16 = 0x92; // Accelerometers data 0x92 - 0x9f + // 0x92: u16Lid Angle if available, LID_ANGLE_UNRELIABLE otherwise + // 0x94 - 0x99: u161st Accelerometer + // 0x9a - 0x9f: u162nd Accelerometer +const LID_ANGLE_UNRELIABLE: u16 = 500; const _EC_MEMMAP_GYRO_DATA: u16 = 0xa0; // Gyroscope data 0xa0 - 0xa5 // Unused 0xa6 - 0xdf @@ -163,6 +164,28 @@ impl From for ReducedPowerInfo { } } +#[derive(Debug)] +struct AccelData { + x: u16, + y: u16, + z: u16, +} +impl From> for AccelData { + fn from(t: Vec) -> Self { + Self { + x: u16::from_le_bytes([t[0], t[1]]), + y: u16::from_le_bytes([t[2], t[3]]), + z: u16::from_le_bytes([t[4], t[5]]), + } + } +} +impl fmt::Display for AccelData { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + write!(f, "X: {:>5} Y: {:>5}, Z: {:>5}", self.x, self.y, self.z) + } +} + + fn read_string(ec: &CrosEc, address: u16) -> String { let bytes = ec.read_memory(address, EC_MEMMAP_TEXT_MAX).unwrap(); String::from_utf8_lossy(bytes.as_slice()).replace(['\0'], "") @@ -200,6 +223,34 @@ pub fn get_als_reading(ec: &CrosEc) -> Option { pub fn print_sensors(ec: &CrosEc) { let als_int = get_als_reading(ec).unwrap(); println!("ALS: {:>4} Lux", als_int); + + // bit 4 = busy + // bit 7 = present + // #define EC_MEMMAP_ACC_STATUS_SAMPLE_ID_MASK 0x0f + let acc_status = ec.read_memory(EC_MEMMAP_ACC_STATUS, 0x01).unwrap()[0]; + // While busy, keep reading + + let lid_angle = ec.read_memory(EC_MEMMAP_ACC_DATA, 0x02).unwrap(); + let lid_angle = u16::from_le_bytes([lid_angle[0], lid_angle[1]]); + let accel_1 = ec.read_memory(EC_MEMMAP_ACC_DATA + 2, 0x06).unwrap(); + let accel_2 = ec.read_memory(EC_MEMMAP_ACC_DATA + 8, 0x06).unwrap(); + + println!("Accelerometers:"); + println!(" Status Bit: {} 0x{:X}", acc_status, acc_status); + println!(" Present: {}", (acc_status & 0x80) > 0); + println!(" Busy: {}", (acc_status & 0x8) > 0); + print!(" Lid Angle: "); + if lid_angle == LID_ANGLE_UNRELIABLE { + println!("Unreliable"); + } else { + println!("{} Deg", lid_angle); + } + println!(" Sensor 1: {}", AccelData::from(accel_1)); + println!(" Sensor 2: {}", AccelData::from(accel_2)); + // Accelerometers + // Lid Angle: 26 Deg + // Sensor 1: 00.00 X 00.00 Y 00.00 Z + // Sensor 2: 00.00 X 00.00 Y 00.00 Z } pub fn print_thermal(ec: &CrosEc) { From d46e7410b1b981f90d4d9872bcf382246c707dc3 Mon Sep 17 00:00:00 2001 From: Daniel Schaefer Date: Mon, 21 Oct 2024 13:35:11 +0800 Subject: [PATCH 2/5] power: AccelData values are i16 Not unsigned Signed-off-by: Daniel Schaefer --- framework_lib/src/power.rs | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/framework_lib/src/power.rs b/framework_lib/src/power.rs index 760247c2..1650ce16 100644 --- a/framework_lib/src/power.rs +++ b/framework_lib/src/power.rs @@ -164,18 +164,18 @@ impl From for ReducedPowerInfo { } } -#[derive(Debug)] -struct AccelData { - x: u16, - y: u16, - z: u16, +#[derive(Debug, Clone, PartialEq, Eq)] +pub struct AccelData { + pub x: i16, + pub y: i16, + pub z: i16, } impl From> for AccelData { fn from(t: Vec) -> Self { Self { - x: u16::from_le_bytes([t[0], t[1]]), - y: u16::from_le_bytes([t[2], t[3]]), - z: u16::from_le_bytes([t[4], t[5]]), + x: i16::from_le_bytes([t[0], t[1]]), + y: i16::from_le_bytes([t[2], t[3]]), + z: i16::from_le_bytes([t[4], t[5]]), } } } From 42c580377588b8a88513b8e54b7b57dedd7fb1c9 Mon Sep 17 00:00:00 2001 From: Daniel Schaefer Date: Mon, 21 Oct 2024 13:36:05 +0800 Subject: [PATCH 3/5] power: Add function to get accel data Signed-off-by: Daniel Schaefer --- framework_lib/src/power.rs | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/framework_lib/src/power.rs b/framework_lib/src/power.rs index 1650ce16..219d83bd 100644 --- a/framework_lib/src/power.rs +++ b/framework_lib/src/power.rs @@ -185,7 +185,6 @@ impl fmt::Display for AccelData { } } - fn read_string(ec: &CrosEc, address: u16) -> String { let bytes = ec.read_memory(address, EC_MEMMAP_TEXT_MAX).unwrap(); String::from_utf8_lossy(bytes.as_slice()).replace(['\0'], "") @@ -220,6 +219,25 @@ pub fn get_als_reading(ec: &CrosEc) -> Option { Some(u32::from_le_bytes([als[0], als[1], als[2], als[3]])) } +pub fn get_accel_data(ec: &CrosEc) -> (AccelData, AccelData, u16) { + // bit 4 = busy + // bit 7 = present + // #define EC_MEMMAP_ACC_STATUS_SAMPLE_ID_MASK 0x0f + let _acc_status = ec.read_memory(EC_MEMMAP_ACC_STATUS, 0x01).unwrap()[0]; + // While busy, keep reading + + let lid_angle = ec.read_memory(EC_MEMMAP_ACC_DATA, 0x02).unwrap(); + let lid_angle = u16::from_le_bytes([lid_angle[0], lid_angle[1]]); + let accel_1 = ec.read_memory(EC_MEMMAP_ACC_DATA + 2, 0x06).unwrap(); + let accel_2 = ec.read_memory(EC_MEMMAP_ACC_DATA + 8, 0x06).unwrap(); + + // TODO: Make sure we got a new sample + // println!(" Status Bit: {} 0x{:X}", acc_status, acc_status); + // println!(" Present: {}", (acc_status & 0x80) > 0); + // println!(" Busy: {}", (acc_status & 0x8) > 0); + (AccelData::from(accel_1), AccelData::from(accel_2), lid_angle) +} + pub fn print_sensors(ec: &CrosEc) { let als_int = get_als_reading(ec).unwrap(); println!("ALS: {:>4} Lux", als_int); From f2983542411c5f7cf42c0b8c1bc3269f6207c099 Mon Sep 17 00:00:00 2001 From: Daniel Schaefer Date: Mon, 21 Oct 2024 13:46:02 +0800 Subject: [PATCH 4/5] power: Properly encode AccelData/LidAngle Signed-off-by: Daniel Schaefer --- framework_lib/src/power.rs | 30 ++++++++++++++++++++++++++++-- 1 file changed, 28 insertions(+), 2 deletions(-) diff --git a/framework_lib/src/power.rs b/framework_lib/src/power.rs index 219d83bd..3f3e5aa0 100644 --- a/framework_lib/src/power.rs +++ b/framework_lib/src/power.rs @@ -185,6 +185,28 @@ impl fmt::Display for AccelData { } } +#[derive(Debug, Copy, Clone, PartialEq, Eq)] +pub enum LidAngle { + Angle(u16), + Unreliable, +} +impl From for LidAngle { + fn from(a: u16) -> Self { + match a { + LID_ANGLE_UNRELIABLE => Self::Unreliable, + _ => Self::Angle(a), + } + } +} +impl fmt::Display for LidAngle { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + match self { + Self::Angle(deg) => write!(f, "{}", deg), + Self::Unreliable => write!(f, "Unreliable"), + } + } +} + fn read_string(ec: &CrosEc, address: u16) -> String { let bytes = ec.read_memory(address, EC_MEMMAP_TEXT_MAX).unwrap(); String::from_utf8_lossy(bytes.as_slice()).replace(['\0'], "") @@ -219,7 +241,7 @@ pub fn get_als_reading(ec: &CrosEc) -> Option { Some(u32::from_le_bytes([als[0], als[1], als[2], als[3]])) } -pub fn get_accel_data(ec: &CrosEc) -> (AccelData, AccelData, u16) { +pub fn get_accel_data(ec: &CrosEc) -> (AccelData, AccelData, LidAngle) { // bit 4 = busy // bit 7 = present // #define EC_MEMMAP_ACC_STATUS_SAMPLE_ID_MASK 0x0f @@ -235,7 +257,11 @@ pub fn get_accel_data(ec: &CrosEc) -> (AccelData, AccelData, u16) { // println!(" Status Bit: {} 0x{:X}", acc_status, acc_status); // println!(" Present: {}", (acc_status & 0x80) > 0); // println!(" Busy: {}", (acc_status & 0x8) > 0); - (AccelData::from(accel_1), AccelData::from(accel_2), lid_angle) + ( + AccelData::from(accel_1), + AccelData::from(accel_2), + LidAngle::from(lid_angle), + ) } pub fn print_sensors(ec: &CrosEc) { From 742f2c82ef4937080254ecf79c7d6f8e045709c9 Mon Sep 17 00:00:00 2001 From: Daniel Schaefer Date: Wed, 5 Feb 2025 18:27:53 +0800 Subject: [PATCH 5/5] framework_lib: Print accelerometer data in G It can show from -2G up to 2G. Signed-off-by: Daniel Schaefer --- framework_lib/src/power.rs | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/framework_lib/src/power.rs b/framework_lib/src/power.rs index 3f3e5aa0..d69dda24 100644 --- a/framework_lib/src/power.rs +++ b/framework_lib/src/power.rs @@ -181,7 +181,11 @@ impl From> for AccelData { } impl fmt::Display for AccelData { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - write!(f, "X: {:>5} Y: {:>5}, Z: {:>5}", self.x, self.y, self.z) + let quarter: f32 = 0xFFFF as f32 / 4.0; + let x = (self.x as f32) / quarter; + let y = (self.y as f32) / quarter; + let z = (self.z as f32) / quarter; + write!(f, "X: {:.2}G Y: {:.2}G, Z: {:.2}G", x, y, z) } }