pub struct I2c<I2CX, SDA, SCL> { /* private fields */ }Expand description
A configured I²C master, owning the peripheral and its two pins.
Both lines are open-drain and need a pull-up.
Implementations§
Source§impl<I2CX, SDA, SCL> I2c<I2CX, SDA, SCL>
impl<I2CX, SDA, SCL> I2c<I2CX, SDA, SCL>
Sourcepub fn release(self, rcu: &mut Rcu) -> (I2CX, SDA, SCL)
pub fn release(self, rcu: &mut Rcu) -> (I2CX, SDA, SCL)
Waits for a requested STOP to reach the bus, then returns the peripheral and both pins, disabled, with its interrupts off and its clock stopped.
Source§impl<I2CX, SDA, SCL> I2c<I2CX, SDA, SCL>where
I2CX: Instance,
impl<I2CX, SDA, SCL> I2c<I2CX, SDA, SCL>where
I2CX: Instance,
Sourcepub fn is_busy(&self) -> bool
pub fn is_busy(&self) -> bool
Whether the bus is in use, by another master or by a transaction of this
one (I2CBSY).
Sourcepub fn sbsend(&self) -> bool
pub fn sbsend(&self) -> bool
START has gone out and the bus is waiting for the address (SBSEND).
Sourcepub fn addsend(&self) -> bool
pub fn addsend(&self) -> bool
The addressed device answered; the data phase opens on
clear_addsend (ADDSEND).
Sourcepub fn tbe(&self) -> bool
pub fn tbe(&self) -> bool
DATA will take the next byte (TBE).
True whenever nothing is queued, so a handler listening for it must stop once it has nothing left to send.
Sourcepub fn btc(&self) -> bool
pub fn btc(&self) -> bool
The byte behind the one in DATA has arrived whole, and the peripheral
holds SCL until software catches up (BTC).
Sourcepub fn wait_idle(&self)
pub fn wait_idle(&self)
Blocks until the bus is free.
Only the first START needs this: I2CBSY stays set while this master owns
the bus, so waiting again before a repeated START would wait forever.
Sourcepub fn write_start(&mut self)
pub fn write_start(&mut self)
Raises START, which goes out as soon as the bus is free.
On a bus this master already holds it is a repeated START, and the transaction continues without a STOP in between.
Sourcepub fn write_addr(&mut self, address: u8, read: bool)
pub fn write_addr(&mut self, address: u8, read: bool)
Puts the address into DATA with read as its direction bit.
Also the second half of clearing SBSEND, the first being the read of
STAT0 that observed it.
§Panics
If address does not fit in seven bits.
Sourcepub fn write_byte(&mut self, byte: u8)
pub fn write_byte(&mut self, byte: u8)
Puts one byte into DATA, which also clears TBE.
Sourcepub fn write_stop(&mut self)
pub fn write_stop(&mut self)
Releases the bus with a STOP condition.
Every path out of a transaction goes through here, failures included: a skipped STOP leaves the master holding SCL, and the bus never goes idle again.
Sourcepub fn clear_addsend(&mut self)
pub fn clear_addsend(&mut self)
Clears ADDSEND, which releases the bus into the data phase.
Goes down on a read of STAT0 then a read of STAT1, in that order;
skipping either leaves the transfer stalled.
Sourcepub fn set_acken(&mut self, ack: bool)
pub fn set_acken(&mut self, ack: bool)
Acknowledges or refuses the byte currently on the wire (ACKEN).
It governs the byte already being clocked in, so the NAK that ends a read
has to stand one byte early — before ADDSEND is cleared on a one-byte
read, and before the last BTC otherwise.
Sourcepub fn set_poap(&mut self, next: bool)
pub fn set_poap(&mut self, next: bool)
Moves the acknowledge one byte further along (POAP), for the two-byte
read where both bytes must be taken after the NAK is already placed.
Like ACKEN it must stand before the START that begins the read.
Sourcepub fn write(&mut self, address: u8, bytes: &[u8]) -> Result<(), Error>
pub fn write(&mut self, address: u8, bytes: &[u8]) -> Result<(), Error>
Writes bytes to the device at address, framed by START and STOP.
address is the plain 7-bit value from the datasheet; the direction bit
is appended here. Blocks until the last byte is out and acknowledged, so
the bus is idle on return.
§Errors
Error::NoAcknowledge if nothing answers the address — with
NoAcknowledgeSource::Address, which is how a bus scan finds devices —
or the device refuses a byte; Error::Bus or
Error::ArbitrationLoss on a bus fault.
§Panics
If address does not fit in seven bits (10-bit addressing is not
supported). Checked before the bus is touched.
Sourcepub fn write_read(
&mut self,
address: u8,
write: &[u8],
read: &mut [u8],
) -> Result<(), Error>
pub fn write_read( &mut self, address: u8, write: &[u8], read: &mut [u8], ) -> Result<(), Error>
Writes write, then reads into read, joined by a repeated START.
This is how a register-addressed device is read: the write phase moves its
pointer, the read phase takes what the pointer names. A
write then a read puts a STOP in between,
which some devices treat as the end of the register access.
An empty read degenerates to write, an empty write
to read.
§Errors
As for write, from either phase.
§Panics
If address does not fit in seven bits.
Sourcepub fn take_error(&mut self) -> Option<Error>
pub fn take_error(&mut self) -> Option<Error>
Returns the pending error, if any, and clears it.
The acknowledge for Event::Error: the flag is what holds the
interrupt request up, so a handler that skips this re-enters forever.
One error per call — with two pending, the second survives for the next.
A NACK reports NoAcknowledgeSource::Unknown, the phase it arrived in
being known only to whoever drives the transaction.
Sourcepub fn listen(&mut self, event: Event)
pub fn listen(&mut self, event: Event)
Raises an interrupt on event, which still has to be unmasked in the
NVIC.
Event::Byte raises EVIE along with BUFIE, so it covers
Event::Protocol too.
Sourcepub fn unlisten(&mut self, event: Event)
pub fn unlisten(&mut self, event: Event)
Stops raising an interrupt on event.
Event::Protocol takes BUFIE down with it: byte events cannot stand
on their own in hardware. Dropping only those is
unlisten(Event::Byte).
Sourcepub fn is_listening(&self, event: Event) -> bool
pub fn is_listening(&self, event: Event) -> bool
Whether event is being listened for.
Sourcepub fn start_write(
self,
address: u8,
buf: &'static [u8],
) -> WriteTransfer<I2CX, SDA, SCL>
pub fn start_write( self, address: u8, buf: &'static [u8], ) -> WriteTransfer<I2CX, SDA, SCL>
Starts a write of buf to address, to be driven by interrupts.
Takes the peripheral with it; both come back from
release. An empty buf still addresses the
device, which is how a bus scan probes for one. Blocks only until the bus
is free, then raises START and returns.
Arms the interrupts itself and keeps re-arming them as the phases change,
so listen beforehand is neither needed nor respected.
§Panics
If address does not fit in seven bits.
Sourcepub fn start_read(
self,
address: u8,
buf: &'static mut [u8],
) -> ReadTransfer<I2CX, SDA, SCL>
pub fn start_read( self, address: u8, buf: &'static mut [u8], ) -> ReadTransfer<I2CX, SDA, SCL>
Starts a read of buf.len() bytes from address, to be driven by
interrupts.
Takes the peripheral with it; both come back from
release. An empty buf finishes immediately
without touching the bus — a zero-byte read has no acknowledge to end on.
Blocks only until the bus is free, then raises START and returns.
Arms the interrupts itself and keeps re-arming them as the phases change,
so listen beforehand is neither needed nor respected.
§Panics
If address does not fit in seven bits.
Trait Implementations§
Source§impl<I2CX, SDA, SCL> I2c for I2c<I2CX, SDA, SCL>where
I2CX: Instance,
impl<I2CX, SDA, SCL> I2c for I2c<I2CX, SDA, SCL>where
I2CX: Instance,
Source§fn transaction(
&mut self,
address: u8,
operations: &mut [Operation<'_>],
) -> Result<(), Error>
fn transaction( &mut self, address: u8, operations: &mut [Operation<'_>], ) -> Result<(), Error>
Per the trait’s contract: neighbouring operations of the same direction join into one addressed phase, a change of direction inserts a repeated START, and only the end carries a STOP.
§Panics
If address does not fit in seven bits, or if a Read is followed by
further operations — ending a read early needs a repeated START in place
of its STOP, which the read sequences here do not express. [Write.., Read]
works.