From 81e4f3005c826806ecae49f9a7fcfdab61cb5685 Mon Sep 17 00:00:00 2001 From: Daniel Schaefer Date: Thu, 4 Dec 2025 01:44:35 +0800 Subject: [PATCH] Add i2c_write_block function Signed-off-by: Daniel Schaefer --- .../src/chromium_ec/i2c_passthrough.rs | 47 +++++++++++++++++++ 1 file changed, 47 insertions(+) diff --git a/framework_lib/src/chromium_ec/i2c_passthrough.rs b/framework_lib/src/chromium_ec/i2c_passthrough.rs index d01aee86..6b0a0f00 100644 --- a/framework_lib/src/chromium_ec/i2c_passthrough.rs +++ b/framework_lib/src/chromium_ec/i2c_passthrough.rs @@ -121,6 +121,53 @@ pub fn i2c_read( }) } +/* Write address and bytes in a single I2C transfer */ +pub fn i2c_write_block( + ec: &CrosEc, + i2c_port: u8, + i2c_addr: u16, + addr: u8, + data: &[u8], +) -> EcResult { + trace!( + " i2c_write(addr: {}, len: {}, data: {:?})", + addr, + data.len(), + data + ); + let addr_bytes = [addr]; + let messages = vec![EcParamsI2cPassthruMsg { + addr_and_flags: i2c_addr, + transfer_len: (addr_bytes.len() + data.len()) as u16, + }]; + let msgs_len = size_of::() * messages.len(); + let msgs_buffer: &[u8] = unsafe { util::any_vec_as_u8_slice(&messages) }; + + let params = EcParamsI2cPassthru { + port: i2c_port, + messages: messages.len() as u8, + msg: [], // Messages are copied right after this struct + }; + let params_len = size_of::(); + let params_buffer: &[u8] = unsafe { util::any_as_u8_slice(¶ms) }; + + let mut buffer: Vec = vec![0; params_len + msgs_len + addr_bytes.len() + data.len()]; + buffer[0..params_len].copy_from_slice(params_buffer); + buffer[params_len..params_len + msgs_len].copy_from_slice(msgs_buffer); + buffer[params_len + msgs_len..params_len + msgs_len + addr_bytes.len()] + .copy_from_slice(&addr_bytes); + buffer[params_len + msgs_len + addr_bytes.len()..].copy_from_slice(data); + + let data = ec.send_command(EcCommands::I2cPassthrough as u16, 0, &buffer)?; + let res: _EcI2cPassthruResponse = unsafe { std::ptr::read(data.as_ptr() as *const _) }; + util::assert_win_len(data.len(), size_of::<_EcI2cPassthruResponse>()); // No extra data other than the header + debug_assert_eq!(res.messages as usize, messages.len()); + Ok(EcI2cPassthruResponse { + i2c_status: res.i2c_status, + data: vec![], // Writing doesn't return any data + }) +} + pub fn i2c_write( ec: &CrosEc, i2c_port: u8,