1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123
//! Definitions for I²C peripherals. use crate::io; use core::fmt; use core::pin; use core::task; pub mod begin_read; pub mod begin_write; pub mod initialize; /// A peripheral that can perform I²C read operations. // TODO: this should maybe capture the lifetime of self and let it flow into Self::Read pub trait I2cRead: fmt::Debug { /// The common error type for I²C read operations. /// /// A single error type for all operations is enforced for simplicity. type Error; /// An object that can be used to complete the read operation. type Read: io::Read + Unpin; /// Polls the start of a read operation to completion. fn poll_begin_read( self: pin::Pin<&mut Self>, cx: &mut task::Context<'_>, addr: u8, ) -> task::Poll<Result<Self::Read, Self::Error>>; } /// Extension functions for instances of [`I2cRead`]. // TODO: this should maybe capture the lifetime of self and let it flow into Self::Read pub trait I2cReadExt: I2cRead { /// Initiates a read operation on the specified address. /// /// The returned object can be used to read the actual data from the address. The user must /// read the data until completion, or else it might leave this I²C peripheral in an incomplete /// state. fn begin_read(&mut self, address: u8) -> begin_read::BeginRead<Self> where Self: Unpin, { begin_read::begin_read(self, address) } } impl<'r, A> I2cReadExt for A where A: I2cRead {} /// A peripheral that can perform I²C write operations. pub trait I2cWrite: fmt::Debug { /// The common error type for I²C write operations. /// /// A single error type for all operations is enforced for simplicity. type Error; /// An object that can be used to complete the write operation. type Write: io::Write + Unpin; /// Polls the start of a write operation to completion. fn poll_begin_write( self: pin::Pin<&mut Self>, cx: &mut task::Context<'_>, addr: u8, ) -> task::Poll<Result<Self::Write, Self::Error>>; } /// Extension functions for instances of [`I2cWrite`]. pub trait I2cWriteExt: I2cWrite { /// Initiates a write operation on the specified address. /// /// The returned object can be used to write the actual data to the address. The user must call /// `shutdown` when done writing, or else it might leave this I²C peripheral in an incomplete /// state. For example, the I²C peripheral might decide to flush remaining data in the [`Drop`] /// implementation, which will be blocking. fn begin_write(&mut self, address: u8) -> begin_write::BeginWrite<Self> where Self: Unpin, { begin_write::begin_write(self, address) } } impl<A> I2cWriteExt for A where A: I2cWrite {} /// Defines a mapping for two GPIO pins that can be used to create an I²C bus. pub trait I2cBusMapping<SDA, SCL> { /// The common error type for I²C operations. /// /// A single error type for all operations is enforced for simplicity. type Error; /// The I²C bus that will be produced once initialization based off of this mapping succeeds. type Bus: I2cRead<Error = Self::Error> + I2cWrite<Error = Self::Error>; /// Polls the initialization operation to completion. fn poll_initialize( self: pin::Pin<&mut Self>, cx: &mut task::Context<'_>, sda: &mut SDA, scl: &mut SCL, ) -> task::Poll<Result<Self::Bus, Self::Error>> where Self: Sized; } /// Extension functions for instances of [`I2cBusMapping`]. pub trait I2cBusMappingExt<SDA, SCL>: I2cBusMapping<SDA, SCL> where SDA: Unpin, SCL: Unpin, { /// Initializes a new I²C bus based off of the two provided SDA (data) and SCL (clock) pins. fn initialize(self, sda: SDA, scl: SCL) -> initialize::Initialize<Self, SDA, SCL> where Self: Sized + Unpin, { initialize::initialize(self, sda, scl) } } impl<A, SDA, SCL> I2cBusMappingExt<SDA, SCL> for A where A: I2cBusMapping<SDA, SCL>, SDA: Unpin, SCL: Unpin, { }