Skip to content

Commit d501301

Browse files
committed
i2c nack type
1 parent 4ea569f commit d501301

File tree

6 files changed

+74
-30
lines changed

6 files changed

+74
-30
lines changed

src/fmpi2c.rs

+13-14
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
use core::ops::Deref;
22

3-
use crate::gpio::{Const, OpenDrain, PinA, SetAlternate};
4-
use crate::i2c::{Error, Scl, Sda};
3+
use crate::i2c::{Error, Pins};
54
use crate::pac::{fmpi2c1, FMPI2C1, RCC};
65
use crate::rcc::{Enable, Reset};
76
use crate::time::{Hertz, U32Ext};
@@ -66,12 +65,11 @@ where
6665
}
6766
}
6867

69-
impl<SCL, SDA, const SCLA: u8, const SDAA: u8> FMPI2c<FMPI2C1, (SCL, SDA)>
68+
impl<PINS> FMPI2c<FMPI2C1, PINS>
7069
where
71-
SCL: PinA<Scl, FMPI2C1, A = Const<SCLA>> + SetAlternate<OpenDrain, SCLA>,
72-
SDA: PinA<Sda, FMPI2C1, A = Const<SDAA>> + SetAlternate<OpenDrain, SDAA>,
70+
PINS: Pins<FMPI2C1>,
7371
{
74-
pub fn new<M: Into<FmpMode>>(i2c: FMPI2C1, mut pins: (SCL, SDA), mode: M) -> Self {
72+
pub fn new<M: Into<FmpMode>>(i2c: FMPI2C1, mut pins: PINS, mode: M) -> Self {
7573
unsafe {
7674
// NOTE(unsafe) this reference will only be used for atomic writes with no side effects.
7775
let rcc = &(*RCC::ptr());
@@ -83,17 +81,15 @@ where
8381
rcc.dckcfgr2.modify(|_, w| w.fmpi2c1sel().hsi());
8482
}
8583

86-
pins.0.set_alt_mode();
87-
pins.1.set_alt_mode();
84+
pins.set_alt_mode();
8885

8986
let i2c = FMPI2c { i2c, pins };
9087
i2c.i2c_init(mode);
9188
i2c
9289
}
9390

94-
pub fn release(mut self) -> (FMPI2C1, (SCL, SDA)) {
95-
self.pins.0.restore_mode();
96-
self.pins.1.restore_mode();
91+
pub fn release(mut self) -> (FMPI2C1, PINS) {
92+
self.pins.restore_mode();
9793

9894
(self.i2c, self.pins)
9995
}
@@ -180,21 +176,24 @@ where
180176
// Wait until we're ready for sending
181177
while {
182178
let isr = self.i2c.isr.read();
183-
self.check_and_clear_error_flags(&isr)?;
179+
self.check_and_clear_error_flags(&isr)
180+
.map_err(Error::nack_addr)?;
184181
isr.txis().bit_is_clear()
185182
} {}
186183

187184
// Push out a byte of data
188185
self.i2c.txdr.write(|w| unsafe { w.bits(u32::from(byte)) });
189186

190-
self.check_and_clear_error_flags(&self.i2c.isr.read())?;
187+
self.check_and_clear_error_flags(&self.i2c.isr.read())
188+
.map_err(Error::nack_data)?;
191189
Ok(())
192190
}
193191

194192
fn recv_byte(&self) -> Result<u8, Error> {
195193
while {
196194
let isr = self.i2c.isr.read();
197-
self.check_and_clear_error_flags(&isr)?;
195+
self.check_and_clear_error_flags(&isr)
196+
.map_err(Error::nack_data)?;
198197
isr.rxne().bit_is_clear()
199198
} {}
200199

src/fmpi2c/hal_02.rs

+10-5
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,8 @@ mod blocking {
2828
// Wait until the transmit buffer is empty and there hasn't been any error condition
2929
while {
3030
let isr = self.i2c.isr.read();
31-
self.check_and_clear_error_flags(&isr)?;
31+
self.check_and_clear_error_flags(&isr)
32+
.map_err(Error::nack_addr)?;
3233
isr.txis().bit_is_clear() && isr.tc().bit_is_clear()
3334
} {}
3435

@@ -40,7 +41,8 @@ mod blocking {
4041
// Wait until data was sent
4142
while {
4243
let isr = self.i2c.isr.read();
43-
self.check_and_clear_error_flags(&isr)?;
44+
self.check_and_clear_error_flags(&isr)
45+
.map_err(Error::nack_data)?;
4446
isr.tc().bit_is_clear()
4547
} {}
4648

@@ -66,7 +68,8 @@ mod blocking {
6668
}
6769

6870
// Check and clear flags if they somehow ended up set
69-
self.check_and_clear_error_flags(&self.i2c.isr.read())?;
71+
self.check_and_clear_error_flags(&self.i2c.isr.read())
72+
.map_err(Error::nack_data)?;
7073

7174
Ok(())
7275
}
@@ -101,7 +104,8 @@ mod blocking {
101104
}
102105

103106
// Check and clear flags if they somehow ended up set
104-
self.check_and_clear_error_flags(&self.i2c.isr.read())?;
107+
self.check_and_clear_error_flags(&self.i2c.isr.read())
108+
.map_err(Error::nack_data)?;
105109

106110
Ok(())
107111
}
@@ -135,7 +139,8 @@ mod blocking {
135139
}
136140

137141
// Check and clear flags if they somehow ended up set
138-
self.check_and_clear_error_flags(&self.i2c.isr.read())?;
142+
self.check_and_clear_error_flags(&self.i2c.isr.read())
143+
.map_err(Error::nack_data)?;
139144

140145
Ok(())
141146
}

src/fmpi2c/hal_1.rs

+10-5
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,8 @@ mod blocking {
2828
// Wait until the transmit buffer is empty and there hasn't been any error condition
2929
while {
3030
let isr = self.i2c.isr.read();
31-
self.check_and_clear_error_flags(&isr)?;
31+
self.check_and_clear_error_flags(&isr)
32+
.map_err(Error::nack_addr)?;
3233
isr.txis().bit_is_clear() && isr.tc().bit_is_clear()
3334
} {}
3435

@@ -40,7 +41,8 @@ mod blocking {
4041
// Wait until data was sent
4142
while {
4243
let isr = self.i2c.isr.read();
43-
self.check_and_clear_error_flags(&isr)?;
44+
self.check_and_clear_error_flags(&isr)
45+
.map_err(Error::nack_data)?;
4446
isr.tc().bit_is_clear()
4547
} {}
4648

@@ -66,7 +68,8 @@ mod blocking {
6668
}
6769

6870
// Check and clear flags if they somehow ended up set
69-
self.check_and_clear_error_flags(&self.i2c.isr.read())?;
71+
self.check_and_clear_error_flags(&self.i2c.isr.read())
72+
.map_err(Error::nack_data)?;
7073

7174
Ok(())
7275
}
@@ -101,7 +104,8 @@ mod blocking {
101104
}
102105

103106
// Check and clear flags if they somehow ended up set
104-
self.check_and_clear_error_flags(&self.i2c.isr.read())?;
107+
self.check_and_clear_error_flags(&self.i2c.isr.read())
108+
.map_err(Error::nack_data)?;
105109

106110
Ok(())
107111
}
@@ -135,7 +139,8 @@ mod blocking {
135139
}
136140

137141
// Check and clear flags if they somehow ended up set
138-
self.check_and_clear_error_flags(&self.i2c.isr.read())?;
142+
self.check_and_clear_error_flags(&self.i2c.isr.read())
143+
.map_err(Error::nack_data)?;
139144

140145
Ok(())
141146
}

src/i2c.rs

+35-4
Original file line numberDiff line numberDiff line change
@@ -108,9 +108,12 @@ where
108108
}
109109

110110
#[derive(Debug, Eq, PartialEq, Copy, Clone)]
111+
#[non_exhaustive]
111112
pub enum Error {
112113
OVERRUN,
113114
NACK,
115+
NACK_ADDR,
116+
NACK_DATA,
114117
TIMEOUT,
115118
// Note: The BUS error type is not currently returned, but is maintained for backwards
116119
// compatibility.
@@ -119,6 +122,21 @@ pub enum Error {
119122
ARBITRATION,
120123
}
121124

125+
impl Error {
126+
pub(crate) fn nack_addr(self) -> Self {
127+
match self {
128+
Error::NACK => Error::NACK_ADDR,
129+
e => e,
130+
}
131+
}
132+
pub(crate) fn nack_data(self) -> Self {
133+
match self {
134+
Error::NACK => Error::NACK_DATA,
135+
e => e,
136+
}
137+
}
138+
}
139+
122140
pub trait Instance: crate::Sealed + Deref<Target = i2c1::RegisterBlock> + Enable + Reset {}
123141

124142
impl Instance for I2C1 {}
@@ -302,7 +320,9 @@ where
302320
// Wait until address was sent
303321
loop {
304322
// Check for any I2C errors. If a NACK occurs, the ADDR bit will never be set.
305-
let sr1 = self.check_and_clear_error_flags()?;
323+
let sr1 = self
324+
.check_and_clear_error_flags()
325+
.map_err(Error::nack_addr)?;
306326

307327
// Wait for the address to be acknowledged
308328
if sr1.addr().bit_is_set() {
@@ -325,22 +345,33 @@ where
325345
fn send_byte(&self, byte: u8) -> Result<(), Error> {
326346
// Wait until we're ready for sending
327347
// Check for any I2C errors. If a NACK occurs, the ADDR bit will never be set.
328-
while self.check_and_clear_error_flags()?.tx_e().bit_is_clear() {}
348+
while self
349+
.check_and_clear_error_flags()
350+
.map_err(Error::nack_addr)?
351+
.tx_e()
352+
.bit_is_clear()
353+
{}
329354

330355
// Push out a byte of data
331356
self.i2c.dr.write(|w| unsafe { w.bits(u32::from(byte)) });
332357

333358
// Wait until byte is transferred
334359
// Check for any potential error conditions.
335-
while self.check_and_clear_error_flags()?.btf().bit_is_clear() {}
360+
while self
361+
.check_and_clear_error_flags()
362+
.map_err(Error::nack_data)?
363+
.btf()
364+
.bit_is_clear()
365+
{}
336366

337367
Ok(())
338368
}
339369

340370
fn recv_byte(&self) -> Result<u8, Error> {
341371
loop {
342372
// Check for any potential error conditions.
343-
self.check_and_clear_error_flags()?;
373+
self.check_and_clear_error_flags()
374+
.map_err(Error::nack_data)?;
344375

345376
if self.i2c.sr1.read().rx_ne().bit_is_set() {
346377
break;

src/i2c/hal_02.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -115,7 +115,8 @@ mod blocking {
115115

116116
// Wait until address was sent
117117
loop {
118-
self.check_and_clear_error_flags()?;
118+
self.check_and_clear_error_flags()
119+
.map_err(Error::nack_addr)?;
119120
if self.i2c.sr1.read().addr().bit_is_set() {
120121
break;
121122
}

src/i2c/hal_1.rs

+4-1
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@ impl Error for super::Error {
66
Self::OVERRUN => ErrorKind::Overrun,
77
Self::BUS => ErrorKind::Bus,
88
Self::ARBITRATION => ErrorKind::ArbitrationLoss,
9+
Self::NACK_ADDR => ErrorKind::NoAcknowledge(NoAcknowledgeSource::Address),
10+
Self::NACK_DATA => ErrorKind::NoAcknowledge(NoAcknowledgeSource::Data),
911
Self::NACK => ErrorKind::NoAcknowledge(NoAcknowledgeSource::Unknown),
1012
Self::CRC | Self::TIMEOUT => ErrorKind::Other,
1113
}
@@ -129,7 +131,8 @@ mod blocking {
129131

130132
// Wait until address was sent
131133
loop {
132-
self.check_and_clear_error_flags()?;
134+
self.check_and_clear_error_flags()
135+
.map_err(Error::nack_addr)?;
133136
if self.i2c.sr1.read().addr().bit_is_set() {
134137
break;
135138
}

0 commit comments

Comments
 (0)