1use core::{I2CDevice, I2CMessage, I2CTransfer};
9use std::convert::TryFrom;
10use std::io;
11
12pub type I2CResult<T> = io::Result<T>;
14
15pub struct I2CRegisterMap {
17 registers: [u8; 0xFF],
18 offset: usize,
19}
20
21impl Default for I2CRegisterMap {
22 fn default() -> Self {
23 Self::new()
24 }
25}
26
27impl I2CRegisterMap {
28 pub fn new() -> I2CRegisterMap {
30 I2CRegisterMap {
31 registers: [0x00; 0xFF],
32 offset: 0,
33 }
34 }
35
36 pub fn write_regs(&mut self, offset: usize, data: &[u8]) {
38 println!("WRITE | 0x{:X} : {:?}", offset, data);
39 self.registers[offset..(data.len() + offset)].clone_from_slice(data);
40 }
41}
42
43impl I2CRegisterMap {
44 fn read(&mut self, data: &mut [u8]) -> I2CResult<()> {
46 let len = data.len();
47 data.clone_from_slice(&self.registers[self.offset..(self.offset + len)]);
48 println!(
49 "READ | 0x{:X} : {:?}",
50 isize::try_from(self.offset).unwrap_or(0xBAD)
51 - isize::try_from(data.len()).unwrap_or(0xBAD),
52 data
53 );
54 Ok(())
55 }
56
57 fn write(&mut self, data: &[u8]) -> I2CResult<()> {
59 let offset = data[0] as usize;
62 let remdata = &data[1..];
63 self.write_regs(offset, remdata);
64 self.offset = offset + remdata.len();
65 Ok(())
66 }
67}
68
69#[derive(Default)]
71pub struct MockI2CDevice {
72 pub regmap: I2CRegisterMap,
74}
75
76impl MockI2CDevice {
77 pub fn new() -> MockI2CDevice {
79 MockI2CDevice {
80 regmap: I2CRegisterMap::new(),
81 }
82 }
83}
84
85impl I2CDevice for MockI2CDevice {
86 type Error = io::Error;
87
88 fn read(&mut self, data: &mut [u8]) -> I2CResult<()> {
89 self.regmap.read(data)
90 }
91
92 fn write(&mut self, data: &[u8]) -> I2CResult<()> {
93 self.regmap.write(data)
94 }
95
96 fn smbus_write_quick(&mut self, _bit: bool) -> I2CResult<()> {
97 unimplemented!()
98 }
99
100 fn smbus_read_block_data(&mut self, _register: u8) -> I2CResult<Vec<u8>> {
101 unimplemented!()
102 }
103
104 fn smbus_write_block_data(&mut self, _register: u8, _values: &[u8]) -> I2CResult<()> {
105 unimplemented!()
106 }
107
108 fn smbus_process_block(&mut self, _register: u8, _values: &[u8]) -> I2CResult<Vec<u8>> {
109 unimplemented!()
110 }
111
112 fn smbus_read_i2c_block_data(&mut self, _register: u8, _len: u8) -> I2CResult<Vec<u8>> {
113 unimplemented!()
114 }
115
116 fn smbus_write_i2c_block_data(&mut self, _register: u8, _values: &[u8]) -> I2CResult<()> {
117 unimplemented!()
118 }
119}
120
121#[derive(Debug)]
122enum MessageType<'a> {
123 Write(&'a [u8]),
124 Read(&'a mut [u8]),
125}
126
127pub struct MockI2CMessage<'a> {
129 msg_type: MessageType<'a>,
130}
131
132impl<'a> I2CMessage<'a> for MockI2CMessage<'a> {
133 fn read(data: &'a mut [u8]) -> Self {
134 Self {
135 msg_type: MessageType::Read(data),
136 }
137 }
138
139 fn write(data: &'a [u8]) -> Self {
141 Self {
142 msg_type: MessageType::Write(data),
143 }
144 }
145}
146
147impl<'a> I2CTransfer<'a> for MockI2CDevice
148where
149 MockI2CDevice: I2CDevice,
150{
151 type Error = io::Error;
152 type Message = MockI2CMessage<'a>;
153
154 fn transfer(&mut self, messages: &'a mut [Self::Message]) -> Result<u32, Self::Error> {
156 for msg in messages.iter_mut() {
157 match &mut msg.msg_type {
158 MessageType::Read(data) => self.read(data)?,
159 MessageType::Write(data) => self.write(data)?,
160 }
161 }
162 Ok(messages.len() as u32)
163 }
164}
165
166#[cfg(test)]
167mod test {
168 use super::*;
169
170 #[test]
171 fn test_can_read_at_zero_offset() {
172 let mut mock_device = MockI2CDevice::new();
173 mock_device.regmap.write_regs(0x0, &[0x1u8; 4]);
174 mock_device.read(&mut [0x0u8; 4]).unwrap();
175 }
176}