Skip to content

Commit e5e6bfc

Browse files
committed
Add i2c_write_block function
Signed-off-by: Daniel Schaefer <[email protected]>
1 parent ce83292 commit e5e6bfc

File tree

1 file changed

+47
-0
lines changed

1 file changed

+47
-0
lines changed

framework_lib/src/chromium_ec/i2c_passthrough.rs

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -121,6 +121,53 @@ pub fn i2c_read(
121121
})
122122
}
123123

124+
/* Write address and bytes in a single I2C transfer */
125+
pub fn i2c_write_block(
126+
ec: &CrosEc,
127+
i2c_port: u8,
128+
i2c_addr: u16,
129+
addr: u8,
130+
data: &[u8],
131+
) -> EcResult<EcI2cPassthruResponse> {
132+
trace!(
133+
" i2c_write(addr: {}, len: {}, data: {:?})",
134+
addr,
135+
data.len(),
136+
data
137+
);
138+
let addr_bytes = [addr];
139+
let messages = vec![EcParamsI2cPassthruMsg {
140+
addr_and_flags: i2c_addr,
141+
transfer_len: (addr_bytes.len() + data.len()) as u16,
142+
}];
143+
let msgs_len = size_of::<EcParamsI2cPassthruMsg>() * messages.len();
144+
let msgs_buffer: &[u8] = unsafe { util::any_vec_as_u8_slice(&messages) };
145+
146+
let params = EcParamsI2cPassthru {
147+
port: i2c_port,
148+
messages: messages.len() as u8,
149+
msg: [], // Messages are copied right after this struct
150+
};
151+
let params_len = size_of::<EcParamsI2cPassthru>();
152+
let params_buffer: &[u8] = unsafe { util::any_as_u8_slice(&params) };
153+
154+
let mut buffer: Vec<u8> = vec![0; params_len + msgs_len + addr_bytes.len() + data.len()];
155+
buffer[0..params_len].copy_from_slice(params_buffer);
156+
buffer[params_len..params_len + msgs_len].copy_from_slice(msgs_buffer);
157+
buffer[params_len + msgs_len..params_len + msgs_len + addr_bytes.len()]
158+
.copy_from_slice(&addr_bytes);
159+
buffer[params_len + msgs_len + addr_bytes.len()..].copy_from_slice(data);
160+
161+
let data = ec.send_command(EcCommands::I2cPassthrough as u16, 0, &buffer)?;
162+
let res: _EcI2cPassthruResponse = unsafe { std::ptr::read(data.as_ptr() as *const _) };
163+
util::assert_win_len(data.len(), size_of::<_EcI2cPassthruResponse>()); // No extra data other than the header
164+
debug_assert_eq!(res.messages as usize, messages.len());
165+
Ok(EcI2cPassthruResponse {
166+
i2c_status: res.i2c_status,
167+
data: vec![], // Writing doesn't return any data
168+
})
169+
}
170+
124171
pub fn i2c_write(
125172
ec: &CrosEc,
126173
i2c_port: u8,

0 commit comments

Comments
 (0)