Skip to content

Commit bde7532

Browse files
committed
cleaner battery command api
Signed-off-by: Daniel Schaefer <[email protected]>
1 parent bbf76d5 commit bde7532

File tree

2 files changed

+113
-47
lines changed

2 files changed

+113
-47
lines changed

framework_lib/src/battery.rs

Lines changed: 112 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -2,27 +2,30 @@
22
// driver/battery/smart.c
33
// include/battery_smart.h
44
use alloc::vec::Vec;
5-
use num_traits::FromPrimitive;
65

7-
use crate::chromium_ec::command::EcRequestRaw;
8-
use crate::chromium_ec::commands::{EcRequestGetGpuPcie, GpuVendor};
96
use crate::chromium_ec::i2c_passthrough::*;
107
use crate::chromium_ec::{CrosEc, EcResult};
11-
use crate::os_specific;
8+
//use crate::os_specific;
129

13-
#[repr(u8)]
10+
#[repr(u16)]
1411
enum SmartBatReg {
1512
Mode = 0x03,
1613
Temp = 0x08,
1714
ManufactureDate = 0x1B,
1815
SerialNum = 0x1C,
1916
CycleCount = 0x17,
17+
/// String
18+
ManufacturerName = 0x20,
2019
DeviceName = 0x21,
20+
Soh = 0x4F,
2121
}
2222

23-
#[repr(u8)]
23+
#[repr(u16)]
2424
/// ManufacturerAccess block
2525
/// Needs unseal
26+
/// On EC Console can read these with
27+
/// If CONFIG_CMD_BATT_MFG_ACCESS
28+
/// > mattmfgacc 0xBEEF 0x50 2
2629
enum ManufReg {
2730
SafetyAlert = 0x50,
2831
SafetyStatus = 0x51,
@@ -32,50 +35,113 @@ enum ManufReg {
3235
LifeTimeDataBlock3 = 0x62,
3336
}
3437

35-
// fn get_i16(ec: &CrosEC) ->
38+
pub struct SmartBattery {
39+
i2c_port: u8,
40+
i2c_addr: u16,
41+
}
42+
43+
impl SmartBattery {
44+
pub fn new() -> Self {
45+
SmartBattery {
46+
// Same on all our Nuvoton ECs
47+
i2c_port: 3,
48+
// 0x0B 7-bit, 0x016 8-bit address
49+
// Same for all our batteries, they use the same IC
50+
i2c_addr: 0x16,
51+
}
52+
}
3653

37-
pub fn dump_data(ec: &CrosEc) -> EcResult<Option<Vec<u8>>> {
38-
// I2C Port on the EC
39-
let i2c_port = 3;
40-
// 8-bit I2C address of the battery
41-
// EC passthrough needs 7-bit, so shift one over before sending to EC
42-
let i2c_addr = 0x0b << 1;
54+
fn read_bytes(&self, ec: &CrosEc, addr: u16, len: u16) -> EcResult<Vec<u8>> {
55+
let i2c_response = i2c_read(ec, self.i2c_port, self.i2c_addr >> 1, addr, len)?;
56+
i2c_response.is_successful()?;
57+
Ok(i2c_response.data)
58+
}
59+
fn read_i16(&self, ec: &CrosEc, addr: u16) -> EcResult<i16> {
60+
let i2c_response = i2c_read(ec, self.i2c_port, self.i2c_addr >> 1, addr, 0x02)?;
61+
i2c_response.is_successful()?;
62+
Ok(i16::from_le_bytes([
63+
i2c_response.data[1],
64+
i2c_response.data[1],
65+
]))
66+
}
67+
fn read_string(&self, ec: &CrosEc, addr: u16) -> EcResult<String> {
68+
let i2c_response = i2c_read(ec, self.i2c_port, self.i2c_addr >> 1, addr, 16)?;
69+
i2c_response.is_successful()?;
4370

44-
// Check mode
45-
let i2c_response = i2c_read(ec, i2c_port, i2c_addr >> 1, 0x03, 0x01)?;
46-
println!("Mode: {:?}", i2c_response.data);
47-
let i2c_response = i2c_read(ec, i2c_port, i2c_addr >> 1, 0x1c, 0x02)?;
48-
println!("Serial: {:X?}", i2c_response.data);
49-
let i2c_response = i2c_read(ec, i2c_port, i2c_addr >> 1, 0x08, 0x02)?;
50-
println!("Temp: {:X?}", i2c_response.data);
51-
let i2c_response = i2c_read(ec, i2c_port, i2c_addr >> 1, 0x17, 0x02)?;
52-
println!("Cycle Ct: {:?}", i2c_response.data);
53-
let i2c_response = i2c_read(ec, i2c_port, i2c_addr >> 1, 0x21, 0x08)?;
54-
// 0A 46 52 41 "FRAN...
55-
println!("Dev Name: {:X?}", i2c_response.data);
71+
// First byte is the returned string length
72+
let str_bytes = &i2c_response.data[1..=(i2c_response.data[0] as usize)];
73+
Ok(String::from_utf8_lossy(str_bytes).to_string())
74+
}
5675

57-
let i2c_response = i2c_read(ec, i2c_port, i2c_addr >> 1, 0x4F, 0x02)?;
58-
println!("SOH: {:?}", i2c_response.data);
76+
pub fn dump_data(&self, ec: &CrosEc) -> EcResult<()> {
77+
// Check mode
78+
println!(
79+
"Mode: {:?}",
80+
self.read_i16(ec, SmartBatReg::Mode as u16)?
81+
);
82+
println!(
83+
"Serial Num: {:04X?}",
84+
self.read_i16(ec, SmartBatReg::SerialNum as u16)?
85+
);
86+
println!(
87+
"Manuf Date: {:04X?}",
88+
self.read_i16(ec, SmartBatReg::ManufactureDate as u16)?
89+
);
90+
println!(
91+
"Temperature: {:?}",
92+
self.read_i16(ec, SmartBatReg::Temp as u16)?
93+
);
94+
println!(
95+
"Cycle Count: {:?}",
96+
self.read_i16(ec, SmartBatReg::CycleCount as u16)?
97+
);
98+
println!(
99+
"Device Name: {}",
100+
self.read_string(ec, SmartBatReg::DeviceName as u16)?
101+
);
102+
println!(
103+
"Manuf Name: {}",
104+
self.read_string(ec, SmartBatReg::ManufacturerName as u16)?
105+
);
106+
println!(
107+
"StateOfHealth: {:?}",
108+
self.read_i16(ec, SmartBatReg::Soh as u16)?
109+
);
59110

60-
// Need to unseal for access
61-
// SE [US] [FA]
62-
let i2c_response = i2c_read(ec, i2c_port, i2c_addr >> 1, 0x51, 0x02)?;
63-
println!("SafetyAlrt{:?}", i2c_response.data);
64-
let i2c_response = i2c_read(ec, i2c_port, i2c_addr >> 1, 0x53, 0x02)?;
65-
println!("SafetySts:{:?}", i2c_response.data);
66-
let i2c_response = i2c_read(ec, i2c_port, i2c_addr >> 1, 0x51, 0x02)?;
67-
println!("PFAlert: {:?}", i2c_response.data);
68-
let i2c_response = i2c_read(ec, i2c_port, i2c_addr >> 1, 0x53, 0x02)?;
69-
println!("PFStatus: {:?}", i2c_response.data);
70-
let i2c_response = i2c_read(ec, i2c_port, i2c_addr >> 1, 0x60, 0x02)?;
71-
println!("LifeTime1 {:?}", i2c_response.data);
72-
let i2c_response = i2c_read(ec, i2c_port, i2c_addr >> 1, 0x61, 0x02)?;
73-
println!("LifeTime2 {:?}", i2c_response.data);
74-
let i2c_response = i2c_read(ec, i2c_port, i2c_addr >> 1, 0x61, 0x02)?;
75-
println!("LifeTime3 {:?}", i2c_response.data);
111+
// Need to unseal for access
112+
// SE [US] [FA]
113+
println!(
114+
"Safety Alert: {:?}",
115+
self.read_i16(&ec, ManufReg::SafetyAlert as u16)?
116+
);
117+
println!(
118+
"Safety Status: {:?}",
119+
self.read_i16(&ec, ManufReg::SafetyStatus as u16)?
120+
);
121+
println!(
122+
"PFAlert: {:?}",
123+
self.read_i16(&ec, ManufReg::PFAlert as u16)?
124+
);
125+
println!(
126+
"PFStatus: {:?}",
127+
self.read_i16(&ec, ManufReg::SafetyAlert as u16)?
128+
);
129+
println!(
130+
"LifeTime1 {:X?}",
131+
self.read_bytes(ec, ManufReg::LifeTimeDataBlock1 as u16, 4)?
132+
);
133+
println!(
134+
"LifeTime2 {:X?}",
135+
self.read_bytes(ec, ManufReg::LifeTimeDataBlock2 as u16, 4)?
136+
);
137+
println!(
138+
"LifeTime3 {:X?}",
139+
self.read_bytes(ec, ManufReg::LifeTimeDataBlock3 as u16, 4)?
140+
);
76141

77-
// i2c_write(ec, i2c_port, (i2c_addr + 2) >> 1, 0x70, &[0x00])?;
78-
// os_specific::sleep(50_000);
142+
// i2c_write(ec, i2c_port, (i2c_addr + 2) >> 1, 0x70, &[0x00])?;
143+
// os_specific::sleep(50_000);
79144

80-
Ok(Some(i2c_response.data))
145+
Ok(())
146+
}
81147
}

framework_lib/src/power.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -536,7 +536,7 @@ pub fn is_standalone(ec: &CrosEc) -> bool {
536536
}
537537

538538
pub fn get_and_print_power_info(ec: &CrosEc) -> i32 {
539-
crate::battery::dump_data(ec);
539+
crate::battery::SmartBattery::new().dump_data(ec).unwrap();
540540
if let Some(power_info) = power_info(ec) {
541541
print_err_ref(&ec.get_charge_state(&power_info));
542542
print_battery_information(&power_info);

0 commit comments

Comments
 (0)