Skip to content

Commit 4aacb00

Browse files
committed
address
1 parent 2485858 commit 4aacb00

File tree

2 files changed

+138
-38
lines changed

2 files changed

+138
-38
lines changed

src/i2c.rs

Lines changed: 106 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,24 @@ mod hal_1;
1313

1414
pub mod dma;
1515

16+
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
17+
pub enum Address {
18+
Seven(u8),
19+
Ten(u16),
20+
}
21+
22+
impl From<u8> for Address {
23+
fn from(value: u8) -> Self {
24+
Self::Seven(value)
25+
}
26+
}
27+
28+
impl From<u16> for Address {
29+
fn from(value: u16) -> Self {
30+
Self::Ten(value)
31+
}
32+
}
33+
1634
#[derive(Debug, Eq, PartialEq)]
1735
pub enum DutyCycle {
1836
Ratio2to1,
@@ -286,9 +304,41 @@ impl<I2C: Instance> I2c<I2C> {
286304
Ok(sr1)
287305
}
288306

307+
/// Set up current address, we're trying to talk to
308+
#[inline(always)]
309+
fn set_address(&self, addr: Address, read: bool, first_transaction: bool) {
310+
match addr {
311+
Address::Seven(addr) => {
312+
self.i2c.dr().write(|w| unsafe {
313+
w.bits({
314+
let addr = u32::from(addr) << 1;
315+
if read {
316+
addr & 1
317+
} else {
318+
addr
319+
}
320+
})
321+
});
322+
}
323+
Address::Ten(addr) => {
324+
let [msbs, lsbs] = addr.to_be_bytes();
325+
let msbs = ((msbs & 0b11) << 1) & 0b11110000;
326+
let dr = self.i2c.dr();
327+
if first_transaction {
328+
dr.write(|w| unsafe { w.bits(u32::from(msbs)) });
329+
dr.write(|w| unsafe { w.bits(u32::from(lsbs)) });
330+
}
331+
if read {
332+
self.i2c.cr1().modify(|_, w| w.start().set_bit());
333+
dr.write(|w| unsafe { w.bits(u32::from(msbs & 1)) });
334+
}
335+
}
336+
}
337+
}
338+
289339
/// Sends START and Address for writing
290340
#[inline(always)]
291-
fn prepare_write(&self, addr: u8) -> Result<(), Error> {
341+
fn prepare_write(&self, addr: Address, first_transaction: bool) -> Result<(), Error> {
292342
// Wait until a previous STOP condition finishes. When the previous
293343
// STOP was generated inside an ISR (e.g. DMA interrupt handler),
294344
// the ISR returns without waiting for the STOP condition to finish.
@@ -313,10 +363,7 @@ impl<I2C: Instance> I2c<I2C> {
313363
}
314364
}
315365

316-
// Set up current address, we're trying to talk to
317-
self.i2c
318-
.dr()
319-
.write(|w| unsafe { w.bits(u32::from(addr) << 1) });
366+
self.set_address(addr, false, first_transaction);
320367

321368
// Wait until address was sent
322369
loop {
@@ -338,7 +385,7 @@ impl<I2C: Instance> I2c<I2C> {
338385
}
339386

340387
/// Sends START and Address for reading
341-
fn prepare_read(&self, addr: u8) -> Result<(), Error> {
388+
fn prepare_read(&self, addr: Address, first_transaction: bool) -> Result<(), Error> {
342389
// Wait until a previous STOP condition finishes. When the previous
343390
// STOP was generated inside an ISR (e.g. DMA interrupt handler),
344391
// the ISR returns without waiting for the STOP condition to finish.
@@ -361,10 +408,7 @@ impl<I2C: Instance> I2c<I2C> {
361408
sr2.msl().bit_is_clear() && sr2.busy().bit_is_clear()
362409
} {}
363410

364-
// Set up current address, we're trying to talk to
365-
self.i2c
366-
.dr()
367-
.write(|w| unsafe { w.bits((u32::from(addr) << 1) + 1) });
411+
self.set_address(addr, true, first_transaction);
368412

369413
// Wait until address was sent
370414
loop {
@@ -440,12 +484,22 @@ impl<I2C: Instance> I2c<I2C> {
440484
Ok(())
441485
}
442486

443-
pub fn read(&mut self, addr: u8, buffer: &mut [u8]) -> Result<(), Error> {
487+
pub fn read(&mut self, addr: impl Into<Address>, buffer: &mut [u8]) -> Result<(), Error> {
488+
self.read_inner(addr.into(), buffer, true)
489+
}
490+
491+
#[inline(always)]
492+
fn read_inner(
493+
&mut self,
494+
addr: Address,
495+
buffer: &mut [u8],
496+
first_transaction: bool,
497+
) -> Result<(), Error> {
444498
if buffer.is_empty() {
445499
return Err(Error::Overrun);
446500
}
447501

448-
self.prepare_read(addr)?;
502+
self.prepare_read(addr.into(), first_transaction)?;
449503
self.read_wo_prepare(buffer)
450504
}
451505

@@ -477,8 +531,8 @@ impl<I2C: Instance> I2c<I2C> {
477531
}
478532
}
479533

480-
pub fn write(&mut self, addr: u8, bytes: &[u8]) -> Result<(), Error> {
481-
self.prepare_write(addr)?;
534+
pub fn write(&mut self, addr: impl Into<Address>, bytes: &[u8]) -> Result<(), Error> {
535+
self.prepare_write(addr.into(), true)?;
482536
self.write_wo_prepare(bytes)
483537
}
484538

@@ -500,11 +554,11 @@ impl<I2C: Instance> I2c<I2C> {
500554
Ok(())
501555
}
502556

503-
pub fn write_iter<B>(&mut self, addr: u8, bytes: B) -> Result<(), Error>
557+
pub fn write_iter<B>(&mut self, addr: impl Into<Address>, bytes: B) -> Result<(), Error>
504558
where
505559
B: IntoIterator<Item = u8>,
506560
{
507-
self.prepare_write(addr)?;
561+
self.prepare_write(addr.into(), true)?;
508562
self.write_bytes(bytes.into_iter())?;
509563

510564
// Send a STOP condition
@@ -521,31 +575,44 @@ impl<I2C: Instance> I2c<I2C> {
521575
Ok(())
522576
}
523577

524-
pub fn write_read(&mut self, addr: u8, bytes: &[u8], buffer: &mut [u8]) -> Result<(), Error> {
525-
self.prepare_write(addr)?;
578+
pub fn write_read(
579+
&mut self,
580+
addr: impl Into<Address>,
581+
bytes: &[u8],
582+
buffer: &mut [u8],
583+
) -> Result<(), Error> {
584+
let addr = addr.into();
585+
self.prepare_write(addr, true)?;
526586
self.write_bytes(bytes.iter().cloned())?;
527-
self.read(addr, buffer)
587+
self.read_inner(addr, buffer, false)
528588
}
529589

530-
pub fn write_iter_read<B>(&mut self, addr: u8, bytes: B, buffer: &mut [u8]) -> Result<(), Error>
590+
pub fn write_iter_read<B>(
591+
&mut self,
592+
addr: impl Into<Address>,
593+
bytes: B,
594+
buffer: &mut [u8],
595+
) -> Result<(), Error>
531596
where
532597
B: IntoIterator<Item = u8>,
533598
{
534-
self.prepare_write(addr)?;
599+
let addr = addr.into();
600+
self.prepare_write(addr, true)?;
535601
self.write_bytes(bytes.into_iter())?;
536-
self.read(addr, buffer)
602+
self.read_inner(addr, buffer, false)
537603
}
538604

539605
pub fn transaction<'a>(
540606
&mut self,
541-
addr: u8,
607+
addr: impl Into<Address>,
542608
mut ops: impl Iterator<Item = Hal1Operation<'a>>,
543609
) -> Result<(), Error> {
610+
let addr = addr.into();
544611
if let Some(mut prev_op) = ops.next() {
545612
// 1. Generate Start for operation
546613
match &prev_op {
547-
Hal1Operation::Read(_) => self.prepare_read(addr)?,
548-
Hal1Operation::Write(_) => self.prepare_write(addr)?,
614+
Hal1Operation::Read(_) => self.prepare_read(addr, true)?,
615+
Hal1Operation::Write(_) => self.prepare_write(addr, true)?,
549616
};
550617

551618
for op in ops {
@@ -557,9 +624,11 @@ impl<I2C: Instance> I2c<I2C> {
557624
// 3. If operation changes type we must generate new start
558625
match (&prev_op, &op) {
559626
(Hal1Operation::Read(_), Hal1Operation::Write(_)) => {
560-
self.prepare_write(addr)?
627+
self.prepare_write(addr, false)?
628+
}
629+
(Hal1Operation::Write(_), Hal1Operation::Read(_)) => {
630+
self.prepare_read(addr, false)?
561631
}
562-
(Hal1Operation::Write(_), Hal1Operation::Read(_)) => self.prepare_read(addr)?,
563632
_ => {} // No changes if operation have not changed
564633
}
565634

@@ -579,19 +648,21 @@ impl<I2C: Instance> I2c<I2C> {
579648

580649
pub fn transaction_slice(
581650
&mut self,
582-
addr: u8,
651+
addr: impl Into<Address>,
583652
ops_slice: &mut [Hal1Operation<'_>],
584653
) -> Result<(), Error> {
654+
let addr = addr.into();
585655
transaction_impl!(self, addr, ops_slice, Hal1Operation);
586656
// Fallthrough is success
587657
Ok(())
588658
}
589659

590660
fn transaction_slice_hal_02(
591661
&mut self,
592-
addr: u8,
662+
addr: impl Into<Address>,
593663
ops_slice: &mut [Hal02Operation<'_>],
594664
) -> Result<(), Error> {
665+
let addr = addr.into();
595666
transaction_impl!(self, addr, ops_slice, Hal02Operation);
596667
// Fallthrough is success
597668
Ok(())
@@ -607,8 +678,8 @@ macro_rules! transaction_impl {
607678
if let Some(mut prev_op) = ops.next() {
608679
// 1. Generate Start for operation
609680
match &prev_op {
610-
$Operation::Read(_) => i2c.prepare_read(addr)?,
611-
$Operation::Write(_) => i2c.prepare_write(addr)?,
681+
$Operation::Read(_) => i2c.prepare_read(addr, true)?,
682+
$Operation::Write(_) => i2c.prepare_write(addr, true)?,
612683
};
613684

614685
for op in ops {
@@ -619,8 +690,10 @@ macro_rules! transaction_impl {
619690
};
620691
// 3. If operation changes type we must generate new start
621692
match (&prev_op, &op) {
622-
($Operation::Read(_), $Operation::Write(_)) => i2c.prepare_write(addr)?,
623-
($Operation::Write(_), $Operation::Read(_)) => i2c.prepare_read(addr)?,
693+
($Operation::Read(_), $Operation::Write(_)) => {
694+
i2c.prepare_write(addr, false)?
695+
}
696+
($Operation::Write(_), $Operation::Read(_)) => i2c.prepare_read(addr, false)?,
624697
_ => {} // No changes if operation have not changed
625698
}
626699

src/i2c/hal_1.rs

Lines changed: 32 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -18,20 +18,20 @@ impl<I2C: super::Instance> ErrorType for super::I2c<I2C> {
1818

1919
mod blocking {
2020
use super::super::{I2c, Instance};
21-
use embedded_hal::i2c::Operation;
21+
use embedded_hal::i2c::{Operation, SevenBitAddress, TenBitAddress};
2222

2323
impl<I2C: Instance> embedded_hal::i2c::I2c for I2c<I2C> {
24-
fn read(&mut self, addr: u8, buffer: &mut [u8]) -> Result<(), Self::Error> {
24+
fn read(&mut self, addr: SevenBitAddress, buffer: &mut [u8]) -> Result<(), Self::Error> {
2525
self.read(addr, buffer)
2626
}
2727

28-
fn write(&mut self, addr: u8, bytes: &[u8]) -> Result<(), Self::Error> {
28+
fn write(&mut self, addr: SevenBitAddress, bytes: &[u8]) -> Result<(), Self::Error> {
2929
self.write(addr, bytes)
3030
}
3131

3232
fn write_read(
3333
&mut self,
34-
addr: u8,
34+
addr: SevenBitAddress,
3535
bytes: &[u8],
3636
buffer: &mut [u8],
3737
) -> Result<(), Self::Error> {
@@ -40,7 +40,34 @@ mod blocking {
4040

4141
fn transaction(
4242
&mut self,
43-
addr: u8,
43+
addr: SevenBitAddress,
44+
operations: &mut [Operation<'_>],
45+
) -> Result<(), Self::Error> {
46+
self.transaction_slice(addr, operations)
47+
}
48+
}
49+
50+
impl<I2C: Instance> embedded_hal::i2c::I2c<TenBitAddress> for I2c<I2C> {
51+
fn read(&mut self, addr: TenBitAddress, buffer: &mut [u8]) -> Result<(), Self::Error> {
52+
self.read(addr, buffer)
53+
}
54+
55+
fn write(&mut self, addr: TenBitAddress, bytes: &[u8]) -> Result<(), Self::Error> {
56+
self.write(addr, bytes)
57+
}
58+
59+
fn write_read(
60+
&mut self,
61+
addr: TenBitAddress,
62+
bytes: &[u8],
63+
buffer: &mut [u8],
64+
) -> Result<(), Self::Error> {
65+
self.write_read(addr, bytes, buffer)
66+
}
67+
68+
fn transaction(
69+
&mut self,
70+
addr: TenBitAddress,
4471
operations: &mut [Operation<'_>],
4572
) -> Result<(), Self::Error> {
4673
self.transaction_slice(addr, operations)

0 commit comments

Comments
 (0)