1#![deny(missing_docs)]
2#![doc(html_root_url = "http://arcnmx.github.io/i2c-linux-rs/")]
3
4#[macro_use]
28extern crate bitflags;
29extern crate resize_slice;
30extern crate i2c_linux_sys as i2c;
31#[cfg(feature = "i2c")]
32extern crate i2c as i2c_gen;
33#[cfg(feature = "udev")]
34extern crate udev;
35
36use std::time::Duration;
37use std::path::Path;
38use std::os::unix::io::{AsRawFd, IntoRawFd, FromRawFd, RawFd};
39use std::io::{self, Read, Write};
40use std::fs::{File, OpenOptions};
41use std::{mem, cmp, iter};
42use resize_slice::ResizeSlice;
43
44pub use i2c::{SmbusReadWrite as ReadWrite, Functionality};
45
46#[cfg(feature = "udev")]
47mod enumerate;
48
49#[cfg(feature = "udev")]
50pub use enumerate::Enumerator;
51
52#[cfg(feature = "i2c")]
53mod i2c_impl;
54
55pub enum Message<'a> {
57 Read {
59 address: u16,
61 data: &'a mut [u8],
63 flags: ReadFlags,
65 },
66 Write {
68 address: u16,
70 data: &'a [u8],
72 flags: WriteFlags,
74 },
75}
76
77impl<'a> Message<'a> {
78 pub fn len(&self) -> usize {
80 match *self {
81 Message::Read { ref data, .. } => data.len(),
82 Message::Write { ref data, .. } => data.len(),
83 }
84 }
85
86 pub fn address(&self) -> u16 {
88 match *self {
89 Message::Read { address, .. } => address,
90 Message::Write { address, .. } => address,
91 }
92 }
93}
94
95bitflags! {
96 #[derive(Default)]
98 pub struct ReadFlags: u16 {
99 const TENBIT_ADDR = i2c::I2C_M_TEN;
101 const RECEIVE_LEN = i2c::I2C_M_RECV_LEN;
103 const NACK = i2c::I2C_M_NO_RD_ACK;
107 const REVERSE_RW = i2c::I2C_M_REV_DIR_ADDR;
111 const NO_START = i2c::I2C_M_NOSTART;
119 const STOP = i2c::I2C_M_STOP;
123 }
124}
125
126bitflags! {
127 #[derive(Default)]
129 pub struct WriteFlags: u16 {
130 const TENBIT_ADDR = i2c::I2C_M_TEN;
132 const IGNORE_NACK = i2c::I2C_M_IGNORE_NAK;
136 const REVERSE_RW = i2c::I2C_M_REV_DIR_ADDR;
140 const NO_START = i2c::I2C_M_NOSTART;
148 const STOP = i2c::I2C_M_STOP;
152 }
153}
154
155pub struct I2c<I> {
157 inner: I,
158 address: Option<u16>,
159 address_10bit: bool,
160 functionality: Option<Functionality>,
161}
162
163impl I2c<File> {
164 pub fn from_path<P: AsRef<Path>>(p: P) -> io::Result<Self> {
166 OpenOptions::new().read(true).write(true)
167 .open(p).map(Self::new)
168 }
169}
170
171impl<I> I2c<I> {
172 pub fn new(device: I) -> Self {
174 I2c {
175 inner: device,
176 address: None,
177 address_10bit: false,
178 functionality: None,
179 }
180 }
181
182 pub fn into_inner(self) -> I {
184 self.inner
185 }
186
187 pub fn inner_ref(&self) -> &I {
189 &self.inner
190 }
191
192 pub fn inner_mut(&mut self) -> &mut I {
194 &mut self.inner
195 }
196}
197
198impl<I: AsRawFd> AsRawFd for I2c<I> {
199 fn as_raw_fd(&self) -> RawFd {
200 self.inner.as_raw_fd()
201 }
202}
203
204impl<I: IntoRawFd> IntoRawFd for I2c<I> {
205 fn into_raw_fd(self) -> RawFd {
206 self.inner.into_raw_fd()
207 }
208}
209
210impl FromRawFd for I2c<File> {
211 unsafe fn from_raw_fd(fd: RawFd) -> Self {
212 Self::new(File::from_raw_fd(fd))
213 }
214}
215
216impl<I: AsRawFd> I2c<I> {
218 fn update_functionality(&mut self) -> Option<Functionality> {
219 if let Some(func) = self.functionality.clone() {
220 Some(func)
221 } else {
222 let functionality = self.i2c_functionality().ok();
223 self.functionality = functionality.clone();
224 functionality
225 }
226 }
227
228 pub fn i2c_set_retries(&self, value: usize) -> io::Result<()> {
230 i2c::i2c_set_retries(self.as_raw_fd(), value)
231 }
232
233 pub fn i2c_set_timeout(&self, duration: Duration) -> io::Result<()> {
235 let value = duration.as_secs() as usize * 1000 + duration.subsec_nanos() as usize / 1000000;
236 i2c::i2c_set_timeout_ms(self.as_raw_fd(), value as _)
237 }
238
239 pub fn smbus_set_slave_address(&mut self, address: u16, tenbit: bool) -> io::Result<()> {
241 if let Some(func) = self.update_functionality() {
242 if func.contains(Functionality::TENBIT_ADDR) || tenbit {
243 i2c::i2c_set_slave_address_10bit(self.as_raw_fd(), tenbit)?;
244 }
245 }
246
247 let res = i2c::i2c_set_slave_address(self.as_raw_fd(), address, false);
248
249 if res.is_ok() {
250 self.address = Some(address);
251 self.address_10bit = tenbit;
252 }
253
254 res
255 }
256
257 pub fn smbus_set_pec(&self, pec: bool) -> io::Result<()> {
259 i2c::i2c_pec(self.as_raw_fd(), pec)
260 }
261
262 pub fn i2c_functionality(&self) -> io::Result<Functionality> {
265 i2c::i2c_get_functionality(self.as_raw_fd())
266 }
267
268 pub fn i2c_transfer_flags(&self) -> io::Result<(ReadFlags, WriteFlags)> {
271 let func = self.i2c_functionality()?;
272 let (mut read, mut write) = (ReadFlags::empty(), WriteFlags::empty());
273 if func.contains(Functionality::PROTOCOL_MANGLING) {
274 read.set(ReadFlags::NACK, true);
275 read.set(ReadFlags::REVERSE_RW, true);
276 read.set(ReadFlags::STOP, true);
277 write.set(WriteFlags::IGNORE_NACK, true);
278 write.set(WriteFlags::REVERSE_RW, true);
279 write.set(WriteFlags::STOP, true);
280 }
281 if func.contains(Functionality::NO_START) {
282 read.set(ReadFlags::NO_START, true);
283 write.set(WriteFlags::NO_START, true);
284 }
285 if func.contains(Functionality::TENBIT_ADDR) {
286 read.set(ReadFlags::TENBIT_ADDR, true);
287 write.set(WriteFlags::TENBIT_ADDR, true);
288 }
289 Ok((read, write))
290 }
291
292 pub fn i2c_transfer(&mut self, messages: &mut [Message]) -> io::Result<()> {
297 let mut message_buffer: [i2c::i2c_msg; i2c::I2C_RDWR_IOCTL_MAX_MSGS] = unsafe {
298 mem::uninitialized()
299 };
300 assert!(messages.len() <= message_buffer.len());
301
302 message_buffer.iter_mut().zip(messages.iter_mut())
303 .for_each(|(out, msg)| *out = match *msg {
304 Message::Read { address, ref mut data, flags } => i2c::i2c_msg {
305 addr: address,
306 flags: i2c::Flags::from_bits_truncate(flags.bits()) | i2c::Flags::RD,
307 len: data.len() as _,
308 buf: data.as_mut_ptr(),
309 },
310 Message::Write { address, ref data, flags } => i2c::i2c_msg {
311 addr: address,
312 flags: i2c::Flags::from_bits_truncate(flags.bits()),
313 len: data.len() as _,
314 buf: data.as_ptr() as *mut _,
315 },
316 });
317
318 let res = unsafe {
319 i2c::i2c_rdwr(self.as_raw_fd(), &mut message_buffer[..messages.len()])?;
320 };
321
322 message_buffer.iter().zip(messages.iter_mut())
323 .for_each(|(msg, out)| match *out {
324 Message::Read { ref mut data, .. } => data.resize_to(msg.len as usize),
325 Message::Write { .. } => (),
326 });
327
328 Ok(res)
329 }
330
331 pub fn smbus_write_quick(&mut self, value: ReadWrite) -> io::Result<()> {
333 i2c::i2c_smbus_write_quick(self.as_raw_fd(), value)
334 }
335
336 pub fn smbus_read_byte(&mut self) -> io::Result<u8> {
342 i2c::i2c_smbus_read_byte(self.as_raw_fd())
343 }
344
345 pub fn smbus_write_byte(&mut self, value: u8) -> io::Result<()> {
347 i2c::i2c_smbus_write_byte(self.as_raw_fd(), value)
348 }
349
350 pub fn smbus_read_byte_data(&mut self, command: u8) -> io::Result<u8> {
352 i2c::i2c_smbus_read_byte_data(self.as_raw_fd(), command)
353 }
354
355 pub fn smbus_write_byte_data(&mut self, command: u8, value: u8) -> io::Result<()> {
357 i2c::i2c_smbus_write_byte_data(self.as_raw_fd(), command, value)
358 }
359
360 pub fn smbus_read_word_data(&mut self, command: u8) -> io::Result<u16> {
362 i2c::i2c_smbus_read_word_data(self.as_raw_fd(), command)
363 }
364
365 pub fn smbus_write_word_data(&mut self, command: u8, value: u16) -> io::Result<()> {
367 i2c::i2c_smbus_write_word_data(self.as_raw_fd(), command, value)
368 }
369
370 pub fn smbus_process_call(&mut self, command: u8, value: u16) -> io::Result<u16> {
373 i2c::i2c_smbus_process_call(self.as_raw_fd(), command, value)
374 }
375
376 pub fn smbus_read_block_data(&mut self, command: u8, value: &mut [u8]) -> io::Result<usize> {
380 let len = cmp::min(value.len(), i2c::I2C_SMBUS_BLOCK_MAX);
381 i2c::i2c_smbus_read_block_data(self.as_raw_fd(), command, &mut value[..len])
382 }
383
384 pub fn smbus_write_block_data(&mut self, command: u8, value: &[u8]) -> io::Result<()> {
386 i2c::i2c_smbus_write_block_data(self.as_raw_fd(), command, value)
387 }
388
389 pub fn smbus_block_process_call(&mut self, command: u8, write: &[u8], read: &mut [u8]) -> io::Result<usize> {
394 let read_len = cmp::min(read.len(), i2c::I2C_SMBUS_BLOCK_MAX);
395 i2c::i2c_smbus_block_process_call(self.as_raw_fd(), command, write, &mut read[..read_len])
396 }
397
398 pub fn i2c_read_block_data(&mut self, command: u8, value: &mut [u8]) -> io::Result<usize> {
406 if let Some(func) = self.update_functionality() {
408 if !func.contains(Functionality::SMBUS_READ_I2C_BLOCK) || value.len() > i2c::I2C_SMBUS_BLOCK_MAX {
409 if func.contains(Functionality::I2C) {
410 if let Some(address) = self.address {
411 let mut msgs = [
412 Message::Write {
413 address: address,
414 data: &[command],
415 flags: if self.address_10bit { WriteFlags::TENBIT_ADDR } else { WriteFlags::default() },
416 },
417 Message::Read {
418 address: address,
419 data: value,
420 flags: if self.address_10bit { ReadFlags::TENBIT_ADDR } else { ReadFlags::default() },
421 },
422 ];
423 return self.i2c_transfer(&mut msgs)
424 .map(|_| msgs[1].len())
425 }
426 }
427 }
428 }
429
430 let len = cmp::min(value.len(), i2c::I2C_SMBUS_BLOCK_MAX);
431 i2c::i2c_smbus_read_i2c_block_data(self.as_raw_fd(), command, &mut value[..len])
432 }
433
434 pub fn i2c_write_block_data(&mut self, command: u8, value: &[u8]) -> io::Result<()> {
440 if let Some(func) = self.update_functionality() {
442 if !func.contains(Functionality::SMBUS_WRITE_I2C_BLOCK) || value.len() > i2c::I2C_SMBUS_BLOCK_MAX {
443 if func.contains(Functionality::I2C) {
444 if let Some(address) = self.address {
445 let flags = if self.address_10bit { WriteFlags::TENBIT_ADDR } else { WriteFlags::default() };
446 return if func.contains(Functionality::NO_START) {
447 self.i2c_transfer(&mut [
448 Message::Write {
449 address: address,
450 data: &[command],
451 flags: flags,
452 },
453 Message::Write {
454 address: address,
455 data: value,
456 flags: flags | WriteFlags::NO_START,
457 },
458 ])
459 } else {
460 self.i2c_transfer(&mut [
461 Message::Write {
462 address: address,
463 data: &iter::once(command).chain(value.iter().cloned()).collect::<Vec<_>>(),
464 flags: flags,
465 },
466 ])
467 }
468 } else {
469 }
471 }
472 }
473 }
474
475 i2c::i2c_smbus_write_i2c_block_data(self.as_raw_fd(), command, value)
476 }
477}
478
479impl<I: Read> Read for I2c<I> {
480 fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
481 self.inner.read(buf)
482 }
483}
484
485impl<I: Write> Write for I2c<I> {
486 fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
487 self.inner.write(buf)
488 }
489
490 fn flush(&mut self) -> io::Result<()> {
491 self.inner.flush()
492 }
493}