1extern crate i2c_linux_sys;
31extern crate tokio;
32extern crate tokio_threadpool;
33#[macro_use]
34extern crate bitflags;
35#[macro_use]
36extern crate smallvec;
37
38use i2c_linux_sys::{
39 Flags, I2C_FUNC_10BIT_ADDR, I2C_FUNC_I2C, I2C_FUNC_NOSTART, I2C_FUNC_PROTOCOL_MANGLING,
40 I2C_FUNC_SLAVE, I2C_FUNC_SMBUS_BLOCK_DATA, I2C_FUNC_SMBUS_BLOCK_PROC_CALL, I2C_FUNC_SMBUS_BYTE,
41 I2C_FUNC_SMBUS_BYTE_DATA, I2C_FUNC_SMBUS_EMUL, I2C_FUNC_SMBUS_HOST_NOTIFY,
42 I2C_FUNC_SMBUS_I2C_BLOCK, I2C_FUNC_SMBUS_PEC, I2C_FUNC_SMBUS_PROC_CALL, I2C_FUNC_SMBUS_QUICK,
43 I2C_FUNC_SMBUS_READ_BLOCK_DATA, I2C_FUNC_SMBUS_READ_BYTE, I2C_FUNC_SMBUS_READ_BYTE_DATA,
44 I2C_FUNC_SMBUS_READ_I2C_BLOCK, I2C_FUNC_SMBUS_READ_WORD_DATA, I2C_FUNC_SMBUS_WORD_DATA,
45 I2C_FUNC_SMBUS_WRITE_BLOCK_DATA, I2C_FUNC_SMBUS_WRITE_BYTE, I2C_FUNC_SMBUS_WRITE_BYTE_DATA,
46 I2C_FUNC_SMBUS_WRITE_I2C_BLOCK, I2C_FUNC_SMBUS_WRITE_WORD_DATA, I2C_M_IGNORE_NAK,
47 I2C_M_NO_RD_ACK, I2C_M_NOSTART, I2C_M_RD, I2C_M_RECV_LEN, I2C_M_REV_DIR_ADDR, I2C_M_STOP,
48 I2C_RDWR_IOCTL_MAX_MSGS, I2C_SMBUS_BLOCK_MAX, i2c_get_functionality, i2c_msg, i2c_pec,
49 i2c_rdwr, i2c_set_retries, i2c_set_slave_address, i2c_set_slave_address_10bit,
50 i2c_set_timeout_ms, i2c_smbus_block_process_call, i2c_smbus_process_call,
51 i2c_smbus_read_block_data, i2c_smbus_read_byte, i2c_smbus_read_byte_data,
52 i2c_smbus_read_i2c_block_data, i2c_smbus_read_word_data, i2c_smbus_write_block_data,
53 i2c_smbus_write_byte, i2c_smbus_write_byte_data, i2c_smbus_write_i2c_block_data,
54 i2c_smbus_write_quick, i2c_smbus_write_word_data,
55};
56use smallvec::{Array, SmallVec};
57use tokio::prelude::{Async::*, *};
58
59use std::fs::{File, OpenOptions};
60use std::io::{
61 self,
62 ErrorKind::{UnexpectedEof, WouldBlock},
63 Read,
64};
65use std::mem::{MaybeUninit, transmute};
66use std::os::unix::io::{AsRawFd, IntoRawFd, RawFd};
67use std::path::Path;
68use std::time::Duration;
69
70pub mod prelude {
82 pub use super::{Functionality, Master, Message, MessageFlags, TEN_BIT};
83 pub use smallvec::SmallVec;
84 pub use std::time::Duration;
85 pub use tokio::prelude::*;
86}
87
88pub struct Message<A>
89where
90 A: Array<Item = u8> + Send + 'static,
91{
92 pub address: u16,
93 pub data: SmallVec<A>,
94 pub flags: MessageFlags,
95}
96
97impl<A> Message<A>
98where
99 A: Array<Item = u8> + Send + 'static,
100{
101 pub const fn is_read(&self) -> bool {
102 self.flags.contains(MessageFlags::READ)
103 }
104 pub const fn is_write(&self) -> bool {
105 !self.is_read()
106 }
107 fn as_i2c_msg(&mut self) -> i2c_msg {
108 let mut flags = Flags::from_bits_truncate(self.flags.bits());
109 if is_ten_bit(self.address) {
110 flags.insert(Flags::TEN);
111 }
112 i2c_msg {
113 addr: to_address(self.address),
114 flags,
115 len: u16::try_from(self.data.len()).expect("too large message data"),
116 buf: self.data.as_mut_ptr(),
117 }
118 }
119}
120
121bitflags! {
122 pub struct Functionality: u32 {
123 const I2C = I2C_FUNC_I2C;
124 const TEN_BIT_ADDR = I2C_FUNC_10BIT_ADDR;
125 const PROTOCOL_MANGLING = I2C_FUNC_PROTOCOL_MANGLING;
126 const SMBUS_PEC = I2C_FUNC_SMBUS_PEC;
127 const NO_START = I2C_FUNC_NOSTART;
128 const SLAVE = I2C_FUNC_SLAVE;
129 const SMBUS_BLOCK_PROC_CALL = I2C_FUNC_SMBUS_BLOCK_PROC_CALL;
130 const SMBUS_QUICK = I2C_FUNC_SMBUS_QUICK;
131 const SMBUS_READ_BYTE = I2C_FUNC_SMBUS_READ_BYTE;
132 const SMBUS_WRITE_BYTE = I2C_FUNC_SMBUS_WRITE_BYTE;
133 const SMBUS_READ_BYTE_DATA = I2C_FUNC_SMBUS_READ_BYTE_DATA;
134 const SMBUS_WRITE_BYTE_DATA = I2C_FUNC_SMBUS_WRITE_BYTE_DATA;
135 const SMBUS_READ_WORD_DATA = I2C_FUNC_SMBUS_READ_WORD_DATA;
136 const SMBUS_WRITE_WORD_DATA = I2C_FUNC_SMBUS_WRITE_WORD_DATA;
137 const SMBUS_PROC_CALL = I2C_FUNC_SMBUS_PROC_CALL;
138 const SMBUS_READ_BLOCK_DATA = I2C_FUNC_SMBUS_READ_BLOCK_DATA;
139 const SMBUS_WRITE_BLOCK_DATA = I2C_FUNC_SMBUS_WRITE_BLOCK_DATA;
140 const SMBUS_READ_I2C_BLOCK = I2C_FUNC_SMBUS_READ_I2C_BLOCK;
141 const SMBUS_WRITE_I2C_BLOCK = I2C_FUNC_SMBUS_WRITE_I2C_BLOCK;
142 const SMBUS_HOST_NOTIFY = I2C_FUNC_SMBUS_HOST_NOTIFY;
143 const SMBUS_BYTE = I2C_FUNC_SMBUS_BYTE;
144 const SMBUS_BYTE_DATA = I2C_FUNC_SMBUS_BYTE_DATA;
145 const SMBUS_WORD_DATA = I2C_FUNC_SMBUS_WORD_DATA;
146 const SMBUS_BLOCK_DATA = I2C_FUNC_SMBUS_BLOCK_DATA;
147 const SMBUS_I2C_BLOCK = I2C_FUNC_SMBUS_I2C_BLOCK;
148 const SMBUS_EMUL = I2C_FUNC_SMBUS_EMUL;
149 }
150}
151
152bitflags! {
153 #[derive(Default)]
154 pub struct MessageFlags: u16 {
155 const READ = I2C_M_RD;
156 const EXACT = EXACT;
157 const RECEIVE_LEN = I2C_M_RECV_LEN;
158 const NACK = I2C_M_NO_RD_ACK;
159 const IGNORE_NACK = I2C_M_IGNORE_NAK;
160 const REVERSE_RW = I2C_M_REV_DIR_ADDR;
161 const NO_START = I2C_M_NOSTART;
162 const STOP = I2C_M_STOP;
163 }
164}
165
166const EXACT: u16 = 0x0100;
167
168impl From<Functionality> for MessageFlags {
169 fn from(functionality: Functionality) -> Self {
170 let mut flags = Self::READ | Self::EXACT | Self::RECEIVE_LEN;
171 if functionality.contains(Functionality::PROTOCOL_MANGLING) {
172 flags.insert(Self::NACK);
173 flags.insert(Self::IGNORE_NACK);
174 flags.insert(Self::REVERSE_RW);
175 flags.insert(Self::STOP);
176 }
177 if functionality.contains(Functionality::NO_START) {
178 flags.insert(Self::NO_START);
179 }
180 flags
181 }
182}
183
184pub const TEN_BIT: u16 = 0xa000;
185
186const fn is_ten_bit(address: u16) -> bool {
187 address & TEN_BIT == TEN_BIT
188}
189
190const fn to_address(address: u16) -> u16 {
191 address & !TEN_BIT
192}
193
194pub struct Master<F>
195where
196 F: AsRawFd + Send + 'static,
197{
198 bus: F,
199 address: Option<u16>,
200 functionality: Functionality,
201}
202
203impl<F> Master<F>
204where
205 F: AsRawFd + Send + 'static,
206{
207 pub fn into_inner(self) -> F {
208 self.bus
209 }
210 pub const fn inner_ref(&self) -> &F {
211 &self.bus
212 }
213 pub const fn inner_mut(&mut self) -> &mut F {
214 &mut self.bus
215 }
216}
217
218impl<F> AsRawFd for Master<F>
219where
220 F: AsRawFd + Send + 'static,
221{
222 fn as_raw_fd(&self) -> RawFd {
223 self.bus.as_raw_fd()
224 }
225}
226
227impl<F> IntoRawFd for Master<F>
228where
229 F: AsRawFd + IntoRawFd + Send + 'static,
230{
231 fn into_raw_fd(self) -> RawFd {
232 self.bus.into_raw_fd()
233 }
234}
235
236impl Master<File> {
237 pub fn from_path<P>(path: P) -> impl Future<Item = Self, Error = io::Error> + Send + 'static
238 where
239 P: AsRef<Path> + Send + 'static,
240 {
241 FromPathFuture { path: Some(path) }
242 }
243}
244
245impl<F> Master<F>
246where
247 F: AsRawFd + Send + 'static,
248{
249 pub fn set_retries(
250 self,
251 retries: usize,
252 ) -> impl Future<Item = Self, Error = io::Error> + Send + 'static {
253 SetRetriesFuture {
254 item: Some(self),
255 retries,
256 }
257 }
258 pub fn set_timeout(
259 self,
260 duration: Duration,
261 ) -> impl Future<Item = Self, Error = io::Error> + Send + 'static {
262 SetTimeoutFuture {
263 item: Some(self),
264 duration,
265 }
266 }
267 pub fn set_slave_address(
268 self,
269 address: u16,
270 ) -> impl Future<Item = Self, Error = io::Error> + Send + 'static {
271 SetSlaveAddressFuture {
272 item: Some(self),
273 address,
274 }
275 }
276 pub const fn functionality(&self) -> Functionality {
277 self.functionality
278 }
279 pub fn transfer_flags(&self) -> MessageFlags {
280 self.functionality.into()
281 }
282 pub fn transfer<A, M>(
286 self,
287 messages: SmallVec<M>,
288 ) -> impl Future<Item = (SmallVec<M>, Self), Error = io::Error> + Send + 'static
289 where
290 A: Array<Item = u8> + Send + 'static,
291 M: Array<Item = Message<A>> + Send + 'static,
292 {
293 assert!(messages.len() <= I2C_RDWR_IOCTL_MAX_MSGS);
294 TransferFuture {
295 item: Some((messages, self)),
296 }
297 }
298 pub fn transfers<A, M, T>(
302 self,
303 transfers: SmallVec<T>,
304 ) -> impl Future<Item = (SmallVec<T>, Self), Error = io::Error> + Send + 'static
305 where
306 A: Array<Item = u8> + Send + 'static,
307 M: Array<Item = Message<A>> + Send + 'static,
308 T: Array<Item = SmallVec<M>> + Send + 'static,
309 {
310 transfers
311 .iter()
312 .for_each(|messages| assert!(messages.len() <= I2C_RDWR_IOCTL_MAX_MSGS));
313 TransfersFuture {
314 item: Some((transfers, self)),
315 }
316 }
317 pub fn read_block_data<A>(
318 self,
319 command: u8,
320 data: SmallVec<A>,
321 exact: bool,
322 ) -> impl Future<Item = (SmallVec<A>, Self), Error = io::Error> + Send + 'static
323 where
324 A: Array<Item = u8> + Send + 'static,
325 {
326 ReadBlockDataFuture {
327 item: Some((data, self)),
328 command,
329 exact,
330 }
331 }
332 pub fn write_block_data<A>(
333 self,
334 command: u8,
335 data: SmallVec<A>,
336 ) -> impl Future<Item = Self, Error = io::Error> + Send + 'static
337 where
338 A: Array<Item = u8> + Send + 'static,
339 {
340 WriteBlockDataFuture {
341 item: Some((data, self)),
342 command,
343 }
344 }
345}
346
347impl<F> Master<F>
348where
349 F: AsRawFd + Read + Send + 'static,
350{
351 pub fn read<A>(
352 self,
353 data: SmallVec<A>,
354 exact: bool,
355 ) -> impl Future<Item = (SmallVec<A>, Self), Error = io::Error> + Send + 'static
356 where
357 A: Array<Item = u8> + Send + 'static,
358 {
359 ReadFuture {
360 item: Some((data, self)),
361 exact,
362 }
363 }
364}
365
366impl<F> Master<F>
367where
368 F: AsRawFd + Write + Send + 'static,
369{
370 pub fn write<A>(
371 self,
372 data: SmallVec<A>,
373 exact: bool,
374 ) -> impl Future<Item = (SmallVec<A>, Self), Error = io::Error> + Send + 'static
375 where
376 A: Array<Item = u8> + Send + 'static,
377 {
378 WriteFuture {
379 item: Some((data, self)),
380 exact,
381 }
382 }
383}
384
385impl<F> Master<F>
386where
387 F: AsRawFd + Send + 'static,
388{
389 pub fn smbus_set_pec(
398 self,
399 pec: bool,
400 ) -> impl Future<Item = Self, Error = io::Error> + Send + 'static {
401 SmbusSetPecFuture {
402 item: Some(self),
403 pec,
404 }
405 }
406 pub fn smbus_write_bit(
414 self,
415 bit: bool,
416 ) -> impl Future<Item = Self, Error = io::Error> + Send + 'static {
417 SmbusWriteBitFuture {
418 item: Some(self),
419 bit,
420 }
421 }
422 pub fn smbus_read_byte(
428 self,
429 ) -> impl Future<Item = (u8, Self), Error = io::Error> + Send + 'static {
430 SmbusReadByteFuture { item: Some(self) }
431 }
432 pub fn smbus_write_byte(
438 self,
439 byte: u8,
440 ) -> impl Future<Item = Self, Error = io::Error> + Send + 'static {
441 SmbusWriteByteFuture {
442 item: Some(self),
443 byte,
444 }
445 }
446 pub fn smbus_read_byte_data<A>(
453 self,
454 command: u8,
455 ) -> impl Future<Item = (u8, Self), Error = io::Error> + Send + 'static {
456 SmbusReadByteDataFuture {
457 item: Some(self),
458 command,
459 }
460 }
461 pub fn smbus_write_byte_data(
467 self,
468 command: u8,
469 data: u8,
470 ) -> impl Future<Item = Self, Error = io::Error> + Send + 'static {
471 SmbusWriteByteDataFuture {
472 item: Some(self),
473 command,
474 data,
475 }
476 }
477 pub fn smbus_read_word_data(
486 self,
487 command: u8,
488 ) -> impl Future<Item = (u16, Self), Error = io::Error> + Send + 'static {
489 SmbusReadWordDataFuture {
490 item: Some(self),
491 command,
492 }
493 }
494 pub fn smbus_write_word_data(
502 self,
503 command: u8,
504 data: u16,
505 ) -> impl Future<Item = Self, Error = io::Error> + Send + 'static {
506 SmbusWriteWordDataFuture {
507 item: Some(self),
508 command,
509 data,
510 }
511 }
512 pub fn smbus_process_call(
522 self,
523 command: u8,
524 data: u16,
525 ) -> impl Future<Item = (u16, Self), Error = io::Error> + Send + 'static {
526 SmbusProcessCallFuture {
527 item: Some(self),
528 command,
529 data,
530 }
531 }
532 pub fn smbus_read_block_data<A>(
542 self,
543 command: u8,
544 data: SmallVec<A>,
545 exact: bool,
546 ) -> impl Future<Item = (SmallVec<A>, Self), Error = io::Error> + Send + 'static
547 where
548 A: Array<Item = u8> + Send + 'static,
549 {
550 SmbusReadBlockDataFuture {
551 item: Some((data, self)),
552 command,
553 exact,
554 }
555 }
556 pub fn smbus_write_block_data<A>(
566 self,
567 command: u8,
568 data: SmallVec<A>,
569 ) -> impl Future<Item = Self, Error = io::Error> + Send + 'static
570 where
571 A: Array<Item = u8> + Send + 'static,
572 {
573 SmbusWriteBlockDataFuture {
574 item: Some((data, self)),
575 command,
576 }
577 }
578 pub fn smbus_block_process_call<A, B>(
592 self,
593 command: u8,
594 write_data: SmallVec<A>,
595 read_data: SmallVec<B>,
596 exact: bool,
597 ) -> impl Future<Item = (SmallVec<B>, Self), Error = io::Error> + Send + 'static
598 where
599 A: Array<Item = u8> + Send + 'static,
600 B: Array<Item = u8> + Send + 'static,
601 {
602 SmbusBlockProcessCallFuture {
603 item: Some((write_data, read_data, self)),
604 command,
605 exact,
606 }
607 }
608}
609
610struct FromPathFuture<P>
611where
612 P: AsRef<Path> + Send + 'static,
613{
614 path: Option<P>,
615}
616
617impl<P> Future for FromPathFuture<P>
618where
619 P: AsRef<Path> + Send + 'static,
620{
621 type Item = Master<File>;
622 type Error = io::Error;
623
624 fn poll(&mut self) -> Poll<Self::Item, Self::Error> {
625 let path = self.path.take().expect(ERR_RESOLVED);
626 if let Ready(master) = blocking_io(|| {
627 let bus = OpenOptions::new().read(true).write(true).open(&path)?;
628 let bits = i2c_get_functionality(bus.as_raw_fd())?.bits();
629 Ok(Master {
630 bus,
631 address: None,
632 functionality: Functionality::from_bits_truncate(bits),
633 })
634 })? {
635 Ok(Ready(master))
636 } else {
637 self.path = Some(path);
638 Ok(NotReady)
639 }
640 }
641}
642
643struct SetRetriesFuture<F>
644where
645 F: AsRawFd + Send + 'static,
646{
647 item: Option<Master<F>>,
648 retries: usize,
649}
650
651impl<F> Future for SetRetriesFuture<F>
652where
653 F: AsRawFd + Send + 'static,
654{
655 type Item = Master<F>;
656 type Error = io::Error;
657
658 fn poll(&mut self) -> Poll<Self::Item, Self::Error> {
659 let master = self.item.take().expect(ERR_RESOLVED);
660 if blocking_io(|| i2c_set_retries(master.as_raw_fd(), self.retries))? == Ready(()) {
661 Ok(Ready(master))
662 } else {
663 self.item = Some(master);
664 Ok(NotReady)
665 }
666 }
667}
668
669struct SetTimeoutFuture<F>
670where
671 F: AsRawFd + Send + 'static,
672{
673 item: Option<Master<F>>,
674 duration: Duration,
675}
676
677impl<F> Future for SetTimeoutFuture<F>
678where
679 F: AsRawFd + Send + 'static,
680{
681 type Item = Master<F>;
682 type Error = io::Error;
683
684 fn poll(&mut self) -> Poll<Self::Item, Self::Error> {
685 let master = self.item.take().expect(ERR_RESOLVED);
686 if blocking_io(|| {
687 let duration = usize::try_from(self.duration.as_millis()).expect("too large duration");
688 i2c_set_timeout_ms(master.as_raw_fd(), duration)
689 })? == Ready(())
690 {
691 Ok(Ready(master))
692 } else {
693 self.item = Some(master);
694 Ok(NotReady)
695 }
696 }
697}
698
699struct SetSlaveAddressFuture<F>
700where
701 F: AsRawFd + Send + 'static,
702{
703 item: Option<Master<F>>,
704 address: u16,
705}
706
707impl<F> Future for SetSlaveAddressFuture<F>
708where
709 F: AsRawFd + Send + 'static,
710{
711 type Item = Master<F>;
712 type Error = io::Error;
713
714 fn poll(&mut self) -> Poll<Self::Item, Self::Error> {
715 let master = self.item.take().expect(ERR_RESOLVED);
716 if blocking_io(|| {
717 let address = to_address(self.address);
718 let ten_bit = is_ten_bit(self.address);
719 if master.address.is_some_and(is_ten_bit) != ten_bit {
720 i2c_set_slave_address_10bit(master.as_raw_fd(), ten_bit)?;
721 }
722 if master.address.map(to_address) != Some(address) {
723 i2c_set_slave_address(master.as_raw_fd(), address, false)?;
724 }
725 Ok(())
726 })? == Ready(())
727 {
728 Ok(Ready(master))
729 } else {
730 self.item = Some(master);
731 Ok(NotReady)
732 }
733 }
734}
735
736struct TransferFuture<F, A, M>
737where
738 F: AsRawFd + Send + 'static,
739 A: Array<Item = u8> + Send + 'static,
740 M: Array<Item = Message<A>>,
741{
742 item: Option<(SmallVec<M>, Master<F>)>,
743}
744
745impl<F, A, M> Future for TransferFuture<F, A, M>
746where
747 F: AsRawFd + Send + 'static,
748 A: Array<Item = u8> + Send + 'static,
749 M: Array<Item = Message<A>>,
750{
751 type Item = (SmallVec<M>, Master<F>);
752 type Error = io::Error;
753
754 fn poll(&mut self) -> Poll<Self::Item, Self::Error> {
755 let (mut messages, master) = self.item.take().expect(ERR_RESOLVED);
756 if blocking_io(|| i2c_transfer(master.as_raw_fd(), &mut messages))? == Ready(()) {
757 Ok(Ready((messages, master)))
758 } else {
759 self.item = Some((messages, master));
760 Ok(NotReady)
761 }
762 }
763}
764
765struct TransfersFuture<F, A, M, T>
766where
767 F: AsRawFd + Send + 'static,
768 A: Array<Item = u8> + Send + 'static,
769 M: Array<Item = Message<A>>,
770 T: Array<Item = SmallVec<M>>,
771{
772 item: Option<(SmallVec<T>, Master<F>)>,
773}
774
775impl<F, A, M, T> Future for TransfersFuture<F, A, M, T>
776where
777 F: AsRawFd + Send + 'static,
778 A: Array<Item = u8> + Send + 'static,
779 M: Array<Item = Message<A>>,
780 T: Array<Item = SmallVec<M>>,
781{
782 type Item = (SmallVec<T>, Master<F>);
783 type Error = io::Error;
784
785 fn poll(&mut self) -> Poll<Self::Item, Self::Error> {
786 let (mut transfers, master) = self.item.take().expect(ERR_RESOLVED);
787 if blocking_io(|| {
788 transfers
789 .iter_mut()
790 .try_for_each(|messages| i2c_transfer(master.as_raw_fd(), messages))
791 })? == Ready(())
792 {
793 Ok(Ready((transfers, master)))
794 } else {
795 self.item = Some((transfers, master));
796 Ok(NotReady)
797 }
798 }
799}
800
801struct ReadBlockDataFuture<F, A>
802where
803 F: AsRawFd + Send + 'static,
804 A: Array<Item = u8> + Send + 'static,
805{
806 item: Option<(SmallVec<A>, Master<F>)>,
807 command: u8,
808 exact: bool,
809}
810
811impl<F, A> Future for ReadBlockDataFuture<F, A>
812where
813 F: AsRawFd + Send + 'static,
814 A: Array<Item = u8> + Send + 'static,
815{
816 type Item = (SmallVec<A>, Master<F>);
817 type Error = io::Error;
818
819 fn poll(&mut self) -> Poll<Self::Item, Self::Error> {
820 let (mut data, master) = self.item.take().expect(ERR_RESOLVED);
821 if blocking_io(|| {
822 let functionality = master.functionality;
823 if functionality.contains(Functionality::I2C)
824 && (!functionality.contains(Functionality::SMBUS_READ_I2C_BLOCK)
825 || data.len() > I2C_SMBUS_BLOCK_MAX)
826 {
827 if let Some(address) = master.address {
828 let mut messages = SmallVec::<[Message<A>; 2]>::from_buf([
829 Message {
830 address,
831 data: smallvec![self.command],
832 flags: MessageFlags::empty(),
833 },
834 Message {
835 address,
836 data: data.clone(), flags: MessageFlags::READ,
838 },
839 ]);
840 i2c_transfer(master.as_raw_fd(), &mut messages)?;
841 data = messages.swap_remove(1).data;
842 Ok(())
843 } else {
844 Err(io::Error::other("No slave address set"))
845 }
846 } else {
847 data.truncate(I2C_SMBUS_BLOCK_MAX);
848 i2c_smbus_read_i2c_block_data(master.as_raw_fd(), self.command, &mut data).and_then(
849 |len| {
850 if self.exact && len != data.len() {
851 Err(UnexpectedEof.into())
852 } else {
853 data.truncate(len);
854 Ok(())
855 }
856 },
857 )
858 }
859 })? == Ready(())
860 {
861 Ok(Ready((data, master)))
862 } else {
863 self.item = Some((data, master));
864 Ok(NotReady)
865 }
866 }
867}
868
869struct WriteBlockDataFuture<F, A>
870where
871 F: AsRawFd + Send + 'static,
872 A: Array<Item = u8> + Send + 'static,
873{
874 item: Option<(SmallVec<A>, Master<F>)>,
875 command: u8,
876}
877
878impl<F, A> Future for WriteBlockDataFuture<F, A>
879where
880 F: AsRawFd + Send + 'static,
881 A: Array<Item = u8> + Send + 'static,
882{
883 type Item = Master<F>;
884 type Error = io::Error;
885
886 fn poll(&mut self) -> Poll<Self::Item, Self::Error> {
887 type Messages<A> = SmallVec<[Message<A>; 1]>;
888 let (data, master) = self.item.take().expect(ERR_RESOLVED);
889 if blocking_io(|| {
890 let functionality = master.functionality;
891 if functionality.contains(Functionality::I2C)
892 && (!functionality.contains(Functionality::SMBUS_READ_I2C_BLOCK)
893 || data.len() > I2C_SMBUS_BLOCK_MAX)
894 {
895 if let Some(address) = master.address {
896 if functionality.contains(Functionality::NO_START) {
897 type Messages<A> = SmallVec<[Message<A>; 2]>;
898 let mut messages = Messages::from_buf([
899 Message {
900 address,
901 data: smallvec![self.command],
902 flags: MessageFlags::empty(),
903 },
904 Message {
905 address,
906 data: data.clone(), flags: MessageFlags::NO_START,
908 },
909 ]);
910 i2c_transfer(master.as_raw_fd(), &mut messages)?;
911 } else {
912 let mut command_data = SmallVec::<A>::new();
913 command_data.push(self.command);
914 command_data.copy_from_slice(&data);
915 let mut messages = Messages::from_buf([Message {
916 address,
917 data: command_data,
918 flags: MessageFlags::empty(),
919 }]);
920 i2c_transfer(master.as_raw_fd(), &mut messages)?;
921 }
922 Ok(())
923 } else {
924 Err(io::Error::new(
925 io::ErrorKind::InvalidInput,
926 "No slave address set",
927 ))
928 }
929 } else {
930 i2c_smbus_write_i2c_block_data(master.as_raw_fd(), self.command, &data)
931 }
932 })? == Ready(())
933 {
934 Ok(Ready(master))
935 } else {
936 self.item = Some((data, master));
937 Ok(NotReady)
938 }
939 }
940}
941
942fn i2c_transfer<A, M>(fd: RawFd, messages: &mut SmallVec<M>) -> io::Result<()>
943where
944 A: Array<Item = u8> + Send + 'static,
945 M: Array<Item = Message<A>>,
946{
947 let mut msgs = [MaybeUninit::<i2c_msg>::uninit(); I2C_RDWR_IOCTL_MAX_MSGS];
948 msgs.iter_mut()
949 .zip(messages.iter_mut())
950 .for_each(|(msg, message)| {
951 msg.write(message.as_i2c_msg());
952 });
953 let mut msgs = unsafe {
954 transmute::<
955 [MaybeUninit<i2c_msg>; I2C_RDWR_IOCTL_MAX_MSGS],
956 [i2c_msg; I2C_RDWR_IOCTL_MAX_MSGS],
957 >(msgs)
958 };
959 unsafe { i2c_rdwr(fd, &mut msgs[..messages.len()])? };
960 msgs.iter()
961 .zip(messages.iter_mut())
962 .try_for_each(|(msg, message)| {
963 if message
964 .flags
965 .contains(MessageFlags::READ | MessageFlags::EXACT)
966 && msg.len as usize != message.data.len()
967 {
968 Err(UnexpectedEof.into())
969 } else {
970 message.data.truncate(msg.len as usize);
971 Ok(())
972 }
973 })
974}
975
976struct ReadFuture<F, A>
977where
978 F: AsRawFd + Read + Send + 'static,
979 A: Array<Item = u8> + Send + 'static,
980{
981 item: Option<(SmallVec<A>, Master<F>)>,
982 exact: bool,
983}
984
985impl<F, A> Future for ReadFuture<F, A>
986where
987 F: AsRawFd + Read + Send + 'static,
988 A: Array<Item = u8> + Send + 'static,
989{
990 type Item = (SmallVec<A>, Master<F>);
991 type Error = io::Error;
992
993 fn poll(&mut self) -> Poll<Self::Item, Self::Error> {
994 let (mut data, mut master) = self.item.take().expect(ERR_RESOLVED);
995 if blocking_io(|| {
996 master.bus.read(&mut data).and_then(|len| {
997 if self.exact && len != data.len() {
998 Err(UnexpectedEof.into())
999 } else {
1000 data.truncate(len);
1001 Ok(())
1002 }
1003 })
1004 })? == Ready(())
1005 {
1006 Ok(Ready((data, master)))
1007 } else {
1008 self.item = Some((data, master));
1009 Ok(NotReady)
1010 }
1011 }
1012}
1013
1014struct WriteFuture<F, A>
1015where
1016 F: AsRawFd + Write + Send + 'static,
1017 A: Array<Item = u8> + Send + 'static,
1018{
1019 item: Option<(SmallVec<A>, Master<F>)>,
1020 exact: bool,
1021}
1022
1023impl<F, A> Future for WriteFuture<F, A>
1024where
1025 F: AsRawFd + Write + Send + 'static,
1026 A: Array<Item = u8> + Send + 'static,
1027{
1028 type Item = (SmallVec<A>, Master<F>);
1029 type Error = io::Error;
1030
1031 fn poll(&mut self) -> Poll<Self::Item, Self::Error> {
1032 let (mut data, mut master) = self.item.take().expect(ERR_RESOLVED);
1033 if blocking_io(|| {
1034 master.bus.write(data.as_mut_slice()).and_then(|len| {
1035 if self.exact && len != data.len() {
1036 Err(UnexpectedEof.into())
1037 } else {
1038 data.drain(..len).for_each(drop);
1039 Ok(())
1040 }
1041 })
1042 })? == Ready(())
1043 {
1044 Ok(Ready((data, master)))
1045 } else {
1046 self.item = Some((data, master));
1047 Ok(NotReady)
1048 }
1049 }
1050}
1051
1052struct SmbusSetPecFuture<F>
1053where
1054 F: AsRawFd + Send + 'static,
1055{
1056 item: Option<Master<F>>,
1057 pec: bool,
1058}
1059
1060impl<F> Future for SmbusSetPecFuture<F>
1061where
1062 F: AsRawFd + Send + 'static,
1063{
1064 type Item = Master<F>;
1065 type Error = io::Error;
1066
1067 fn poll(&mut self) -> Poll<Self::Item, Self::Error> {
1068 let master = self.item.take().expect(ERR_RESOLVED);
1069 if blocking_io(|| i2c_pec(master.as_raw_fd(), self.pec))? == Ready(()) {
1070 Ok(Ready(master))
1071 } else {
1072 self.item = Some(master);
1073 Ok(NotReady)
1074 }
1075 }
1076}
1077
1078struct SmbusWriteBitFuture<F>
1079where
1080 F: AsRawFd + Send + 'static,
1081{
1082 item: Option<Master<F>>,
1083 bit: bool,
1084}
1085
1086impl<F> Future for SmbusWriteBitFuture<F>
1087where
1088 F: AsRawFd + Send + 'static,
1089{
1090 type Item = Master<F>;
1091 type Error = io::Error;
1092
1093 fn poll(&mut self) -> Poll<Self::Item, Self::Error> {
1094 let master = self.item.take().expect(ERR_RESOLVED);
1095 if blocking_io(|| {
1096 i2c_smbus_write_quick(
1097 master.as_raw_fd(),
1098 if self.bit {
1099 i2c_linux_sys::SmbusReadWrite::Read
1100 } else {
1101 i2c_linux_sys::SmbusReadWrite::Write
1102 },
1103 )
1104 })? == Ready(())
1105 {
1106 Ok(Ready(master))
1107 } else {
1108 self.item = Some(master);
1109 Ok(NotReady)
1110 }
1111 }
1112}
1113
1114struct SmbusReadByteFuture<F>
1115where
1116 F: AsRawFd + Send + 'static,
1117{
1118 item: Option<Master<F>>,
1119}
1120
1121impl<F> Future for SmbusReadByteFuture<F>
1122where
1123 F: AsRawFd + Send + 'static,
1124{
1125 type Item = (u8, Master<F>);
1126 type Error = io::Error;
1127
1128 fn poll(&mut self) -> Poll<Self::Item, Self::Error> {
1129 let master = self.item.take().expect(ERR_RESOLVED);
1130 if let Ready(byte) = blocking_io(|| i2c_smbus_read_byte(master.as_raw_fd()))? {
1131 Ok(Ready((byte, master)))
1132 } else {
1133 self.item = Some(master);
1134 Ok(NotReady)
1135 }
1136 }
1137}
1138
1139struct SmbusWriteByteFuture<F>
1140where
1141 F: AsRawFd + Send + 'static,
1142{
1143 item: Option<Master<F>>,
1144 byte: u8,
1145}
1146
1147impl<F> Future for SmbusWriteByteFuture<F>
1148where
1149 F: AsRawFd + Send + 'static,
1150{
1151 type Item = Master<F>;
1152 type Error = io::Error;
1153
1154 fn poll(&mut self) -> Poll<Self::Item, Self::Error> {
1155 let master = self.item.take().expect(ERR_RESOLVED);
1156 if blocking_io(|| i2c_smbus_write_byte(master.as_raw_fd(), self.byte))? == Ready(()) {
1157 Ok(Ready(master))
1158 } else {
1159 self.item = Some(master);
1160 Ok(NotReady)
1161 }
1162 }
1163}
1164
1165struct SmbusReadByteDataFuture<F>
1166where
1167 F: AsRawFd + Send + 'static,
1168{
1169 item: Option<Master<F>>,
1170 command: u8,
1171}
1172
1173impl<F> Future for SmbusReadByteDataFuture<F>
1174where
1175 F: AsRawFd + Send + 'static,
1176{
1177 type Item = (u8, Master<F>);
1178 type Error = io::Error;
1179
1180 fn poll(&mut self) -> Poll<Self::Item, Self::Error> {
1181 let master = self.item.take().expect(ERR_RESOLVED);
1182 if let Ready(data) =
1183 blocking_io(|| i2c_smbus_read_byte_data(master.as_raw_fd(), self.command))?
1184 {
1185 Ok(Ready((data, master)))
1186 } else {
1187 self.item = Some(master);
1188 Ok(NotReady)
1189 }
1190 }
1191}
1192
1193struct SmbusWriteByteDataFuture<F>
1194where
1195 F: AsRawFd + Send + 'static,
1196{
1197 item: Option<Master<F>>,
1198 command: u8,
1199 data: u8,
1200}
1201
1202impl<F> Future for SmbusWriteByteDataFuture<F>
1203where
1204 F: AsRawFd + Send + 'static,
1205{
1206 type Item = Master<F>;
1207 type Error = io::Error;
1208
1209 fn poll(&mut self) -> Poll<Self::Item, Self::Error> {
1210 let master = self.item.take().expect(ERR_RESOLVED);
1211 if blocking_io(|| i2c_smbus_write_byte_data(master.as_raw_fd(), self.command, self.data))?
1212 == Ready(())
1213 {
1214 Ok(Ready(master))
1215 } else {
1216 self.item = Some(master);
1217 Ok(NotReady)
1218 }
1219 }
1220}
1221
1222struct SmbusReadWordDataFuture<F>
1223where
1224 F: AsRawFd + Send + 'static,
1225{
1226 item: Option<Master<F>>,
1227 command: u8,
1228}
1229
1230impl<F> Future for SmbusReadWordDataFuture<F>
1231where
1232 F: AsRawFd + Send + 'static,
1233{
1234 type Item = (u16, Master<F>);
1235 type Error = io::Error;
1236
1237 fn poll(&mut self) -> Poll<Self::Item, Self::Error> {
1238 let master = self.item.take().expect(ERR_RESOLVED);
1239 if let Ready(data) =
1240 blocking_io(|| i2c_smbus_read_word_data(master.as_raw_fd(), self.command))?
1241 {
1242 Ok(Ready((data, master)))
1243 } else {
1244 self.item = Some(master);
1245 Ok(NotReady)
1246 }
1247 }
1248}
1249
1250struct SmbusWriteWordDataFuture<F>
1251where
1252 F: AsRawFd + Send + 'static,
1253{
1254 item: Option<Master<F>>,
1255 command: u8,
1256 data: u16,
1257}
1258
1259impl<F> Future for SmbusWriteWordDataFuture<F>
1260where
1261 F: AsRawFd + Send + 'static,
1262{
1263 type Item = Master<F>;
1264 type Error = io::Error;
1265
1266 fn poll(&mut self) -> Poll<Self::Item, Self::Error> {
1267 let master = self.item.take().expect(ERR_RESOLVED);
1268 if blocking_io(|| i2c_smbus_write_word_data(master.as_raw_fd(), self.command, self.data))?
1269 == Ready(())
1270 {
1271 Ok(Ready(master))
1272 } else {
1273 self.item = Some(master);
1274 Ok(NotReady)
1275 }
1276 }
1277}
1278
1279struct SmbusProcessCallFuture<F>
1280where
1281 F: AsRawFd + Send + 'static,
1282{
1283 item: Option<Master<F>>,
1284 command: u8,
1285 data: u16,
1286}
1287
1288impl<F> Future for SmbusProcessCallFuture<F>
1289where
1290 F: AsRawFd + Send + 'static,
1291{
1292 type Item = (u16, Master<F>);
1293 type Error = io::Error;
1294
1295 fn poll(&mut self) -> Poll<Self::Item, Self::Error> {
1296 let master = self.item.take().expect(ERR_RESOLVED);
1297 if let Ready(data) =
1298 blocking_io(|| i2c_smbus_process_call(master.as_raw_fd(), self.command, self.data))?
1299 {
1300 Ok(Ready((data, master)))
1301 } else {
1302 self.item = Some(master);
1303 Ok(NotReady)
1304 }
1305 }
1306}
1307
1308struct SmbusReadBlockDataFuture<F, A>
1309where
1310 F: AsRawFd + Send + 'static,
1311 A: Array<Item = u8> + Send + 'static,
1312{
1313 item: Option<(SmallVec<A>, Master<F>)>,
1314 command: u8,
1315 exact: bool,
1316}
1317
1318impl<F, A> Future for SmbusReadBlockDataFuture<F, A>
1319where
1320 F: AsRawFd + Send + 'static,
1321 A: Array<Item = u8> + Send + 'static,
1322{
1323 type Item = (SmallVec<A>, Master<F>);
1324 type Error = io::Error;
1325
1326 fn poll(&mut self) -> Poll<Self::Item, Self::Error> {
1327 let (mut data, master) = self.item.take().expect(ERR_RESOLVED);
1328 if blocking_io(|| {
1329 data.truncate(I2C_SMBUS_BLOCK_MAX);
1330 i2c_smbus_read_block_data(master.as_raw_fd(), self.command, &mut data).and_then(|len| {
1331 if self.exact && len != data.len() {
1332 Err(UnexpectedEof.into())
1333 } else {
1334 data.truncate(len);
1335 Ok(())
1336 }
1337 })
1338 })? == Ready(())
1339 {
1340 Ok(Ready((data, master)))
1341 } else {
1342 self.item = Some((data, master));
1343 Ok(NotReady)
1344 }
1345 }
1346}
1347
1348struct SmbusWriteBlockDataFuture<F, A>
1349where
1350 F: AsRawFd + Send + 'static,
1351 A: Array<Item = u8> + Send + 'static,
1352{
1353 item: Option<(SmallVec<A>, Master<F>)>,
1354 command: u8,
1355}
1356
1357impl<F, A> Future for SmbusWriteBlockDataFuture<F, A>
1358where
1359 F: AsRawFd + Send + 'static,
1360 A: Array<Item = u8> + Send + 'static,
1361{
1362 type Item = Master<F>;
1363 type Error = io::Error;
1364
1365 fn poll(&mut self) -> Poll<Self::Item, Self::Error> {
1366 let (data, master) = self.item.take().expect(ERR_RESOLVED);
1367 if blocking_io(|| i2c_smbus_write_block_data(master.as_raw_fd(), self.command, &data))?
1368 == Ready(())
1369 {
1370 Ok(Ready(master))
1371 } else {
1372 self.item = Some((data, master));
1373 Ok(NotReady)
1374 }
1375 }
1376}
1377
1378struct SmbusBlockProcessCallFuture<F, A, B>
1379where
1380 F: AsRawFd + Send + 'static,
1381 A: Array<Item = u8> + Send + 'static,
1382 B: Array<Item = u8> + Send + 'static,
1383{
1384 item: Option<(SmallVec<A>, SmallVec<B>, Master<F>)>,
1385 command: u8,
1386 exact: bool,
1387}
1388
1389impl<F, A, B> Future for SmbusBlockProcessCallFuture<F, A, B>
1390where
1391 F: AsRawFd + Send + 'static,
1392 A: Array<Item = u8> + Send + 'static,
1393 B: Array<Item = u8> + Send + 'static,
1394{
1395 type Item = (SmallVec<B>, Master<F>);
1396 type Error = io::Error;
1397
1398 fn poll(&mut self) -> Poll<Self::Item, Self::Error> {
1399 let (write_data, mut read_data, master) = self.item.take().expect(ERR_RESOLVED);
1400 if blocking_io(|| {
1401 read_data.truncate(I2C_SMBUS_BLOCK_MAX);
1402 i2c_smbus_block_process_call(
1403 master.as_raw_fd(),
1404 self.command,
1405 &write_data,
1406 &mut read_data,
1407 )
1408 .and_then(|len| {
1409 if self.exact && len != read_data.len() {
1410 Err(UnexpectedEof.into())
1411 } else {
1412 read_data.truncate(len);
1413 Ok(())
1414 }
1415 })
1416 })? == Ready(())
1417 {
1418 Ok(Ready((read_data, master)))
1419 } else {
1420 self.item = Some((write_data, read_data, master));
1421 Ok(NotReady)
1422 }
1423 }
1424}
1425
1426fn blocking_io<F, T>(f: F) -> Poll<T, io::Error>
1427where
1428 F: FnOnce() -> io::Result<T>,
1429{
1430 match tokio_threadpool::blocking(f) {
1431 Ok(Ready(Ok(ok))) => Ok(ok.into()),
1432 Ok(Ready(Err(err))) => match err.kind() {
1433 WouldBlock => Ok(NotReady),
1434 _ => Err(err),
1435 },
1436 Ok(NotReady) => Ok(NotReady),
1437 Err(err) => Err(io::Error::other(err)),
1438 }
1439}
1440
1441const ERR_RESOLVED: &str = "I²C Future already resolved";