aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCaleb Jamison <[email protected]>2023-09-09 18:25:23 -0400
committerDario Nieuwenhuis <[email protected]>2023-09-10 23:01:15 +0200
commit2d9f50addc5f509f5549e69f594c382cebe739e6 (patch)
tree41861a3120a578dcfa744b6777ec5b592cd63c97
parent18da91e2529b7973d0476e5c239709b3851db14b (diff)
I2c slave take 2
refactored to split modules renamed to match upstream docs slight improvement to slave error handling
-rw-r--r--embassy-rp/src/i2c/i2c.rs155
-rw-r--r--embassy-rp/src/i2c_slave.rs326
-rw-r--r--embassy-rp/src/lib.rs1
-rw-r--r--tests/rp/src/bin/i2c.rs33
4 files changed, 497 insertions, 18 deletions
diff --git a/embassy-rp/src/i2c/i2c.rs b/embassy-rp/src/i2c/i2c.rs
index 13124dd81..facc7185f 100644
--- a/embassy-rp/src/i2c/i2c.rs
+++ b/embassy-rp/src/i2c/i2c.rs
@@ -11,7 +11,38 @@ use super::{
11use crate::gpio::sealed::Pin; 11use crate::gpio::sealed::Pin;
12use crate::gpio::AnyPin; 12use crate::gpio::AnyPin;
13use crate::interrupt::typelevel::{Binding, Interrupt}; 13use crate::interrupt::typelevel::{Binding, Interrupt};
14use crate::{pac, Peripheral}; 14use crate::{interrupt, pac, peripherals, Peripheral};
15
16/// I2C error abort reason
17#[derive(Debug)]
18#[cfg_attr(feature = "defmt", derive(defmt::Format))]
19pub enum AbortReason {
20 /// A bus operation was not acknowledged, e.g. due to the addressed device
21 /// not being available on the bus or the device not being ready to process
22 /// requests at the moment
23 NoAcknowledge,
24 /// The arbitration was lost, e.g. electrical problems with the clock signal
25 ArbitrationLoss,
26 /// Transmit ended with data still in fifo
27 TxNotEmpty(u16),
28 Other(u32),
29}
30
31/// I2C error
32#[derive(Debug)]
33#[cfg_attr(feature = "defmt", derive(defmt::Format))]
34pub enum Error {
35 /// I2C abort with error
36 Abort(AbortReason),
37 /// User passed in a read buffer that was 0 length
38 InvalidReadBufferLength,
39 /// User passed in a write buffer that was 0 length
40 InvalidWriteBufferLength,
41 /// Target i2c address is out of range
42 AddressOutOfRange(u16),
43 /// Target i2c address is reserved
44 AddressReserved(u16),
45}
15 46
16#[non_exhaustive] 47#[non_exhaustive]
17#[derive(Copy, Clone)] 48#[derive(Copy, Clone)]
@@ -26,6 +57,8 @@ impl Default for Config {
26 } 57 }
27} 58}
28 59
60pub const FIFO_SIZE: u8 = 16;
61
29pub struct I2c<'d, T: Instance, M: Mode> { 62pub struct I2c<'d, T: Instance, M: Mode> {
30 phantom: PhantomData<(&'d mut T, M)>, 63 phantom: PhantomData<(&'d mut T, M)>,
31} 64}
@@ -696,3 +729,123 @@ mod nightly {
696 } 729 }
697 } 730 }
698} 731}
732<<<<<<< HEAD:embassy-rp/src/i2c/i2c.rs
733=======
734
735pub fn i2c_reserved_addr(addr: u16) -> bool {
736 ((addr & 0x78) == 0 || (addr & 0x78) == 0x78) && addr != 0
737}
738
739mod sealed {
740 use embassy_sync::waitqueue::AtomicWaker;
741
742 use crate::interrupt;
743
744 pub trait Instance {
745 const TX_DREQ: u8;
746 const RX_DREQ: u8;
747
748 type Interrupt: interrupt::typelevel::Interrupt;
749
750 fn regs() -> crate::pac::i2c::I2c;
751 fn reset() -> crate::pac::resets::regs::Peripherals;
752 fn waker() -> &'static AtomicWaker;
753 }
754
755 pub trait Mode {}
756
757 pub trait SdaPin<T: Instance> {}
758 pub trait SclPin<T: Instance> {}
759}
760
761pub trait Mode: sealed::Mode {}
762
763macro_rules! impl_mode {
764 ($name:ident) => {
765 impl sealed::Mode for $name {}
766 impl Mode for $name {}
767 };
768}
769
770pub struct Blocking;
771pub struct Async;
772
773impl_mode!(Blocking);
774impl_mode!(Async);
775
776pub trait Instance: sealed::Instance {}
777
778macro_rules! impl_instance {
779 ($type:ident, $irq:ident, $reset:ident, $tx_dreq:expr, $rx_dreq:expr) => {
780 impl sealed::Instance for peripherals::$type {
781 const TX_DREQ: u8 = $tx_dreq;
782 const RX_DREQ: u8 = $rx_dreq;
783
784 type Interrupt = crate::interrupt::typelevel::$irq;
785
786 #[inline]
787 fn regs() -> pac::i2c::I2c {
788 pac::$type
789 }
790
791 #[inline]
792 fn reset() -> pac::resets::regs::Peripherals {
793 let mut ret = pac::resets::regs::Peripherals::default();
794 ret.$reset(true);
795 ret
796 }
797
798 #[inline]
799 fn waker() -> &'static AtomicWaker {
800 static WAKER: AtomicWaker = AtomicWaker::new();
801
802 &WAKER
803 }
804 }
805 impl Instance for peripherals::$type {}
806 };
807}
808
809impl_instance!(I2C0, I2C0_IRQ, set_i2c0, 32, 33);
810impl_instance!(I2C1, I2C1_IRQ, set_i2c1, 34, 35);
811
812pub trait SdaPin<T: Instance>: sealed::SdaPin<T> + crate::gpio::Pin {}
813pub trait SclPin<T: Instance>: sealed::SclPin<T> + crate::gpio::Pin {}
814
815macro_rules! impl_pin {
816 ($pin:ident, $instance:ident, $function:ident) => {
817 impl sealed::$function<peripherals::$instance> for peripherals::$pin {}
818 impl $function<peripherals::$instance> for peripherals::$pin {}
819 };
820}
821
822impl_pin!(PIN_0, I2C0, SdaPin);
823impl_pin!(PIN_1, I2C0, SclPin);
824impl_pin!(PIN_2, I2C1, SdaPin);
825impl_pin!(PIN_3, I2C1, SclPin);
826impl_pin!(PIN_4, I2C0, SdaPin);
827impl_pin!(PIN_5, I2C0, SclPin);
828impl_pin!(PIN_6, I2C1, SdaPin);
829impl_pin!(PIN_7, I2C1, SclPin);
830impl_pin!(PIN_8, I2C0, SdaPin);
831impl_pin!(PIN_9, I2C0, SclPin);
832impl_pin!(PIN_10, I2C1, SdaPin);
833impl_pin!(PIN_11, I2C1, SclPin);
834impl_pin!(PIN_12, I2C0, SdaPin);
835impl_pin!(PIN_13, I2C0, SclPin);
836impl_pin!(PIN_14, I2C1, SdaPin);
837impl_pin!(PIN_15, I2C1, SclPin);
838impl_pin!(PIN_16, I2C0, SdaPin);
839impl_pin!(PIN_17, I2C0, SclPin);
840impl_pin!(PIN_18, I2C1, SdaPin);
841impl_pin!(PIN_19, I2C1, SclPin);
842impl_pin!(PIN_20, I2C0, SdaPin);
843impl_pin!(PIN_21, I2C0, SclPin);
844impl_pin!(PIN_22, I2C1, SdaPin);
845impl_pin!(PIN_23, I2C1, SclPin);
846impl_pin!(PIN_24, I2C0, SdaPin);
847impl_pin!(PIN_25, I2C0, SclPin);
848impl_pin!(PIN_26, I2C1, SdaPin);
849impl_pin!(PIN_27, I2C1, SclPin);
850impl_pin!(PIN_28, I2C0, SdaPin);
851impl_pin!(PIN_29, I2C0, SclPin);
diff --git a/embassy-rp/src/i2c_slave.rs b/embassy-rp/src/i2c_slave.rs
new file mode 100644
index 000000000..a65250116
--- /dev/null
+++ b/embassy-rp/src/i2c_slave.rs
@@ -0,0 +1,326 @@
1use core::future;
2use core::marker::PhantomData;
3use core::task::Poll;
4
5use embassy_hal_internal::into_ref;
6use pac::i2c;
7
8use crate::i2c::{i2c_reserved_addr, AbortReason, Instance, InterruptHandler, SclPin, SdaPin, FIFO_SIZE};
9use crate::interrupt::typelevel::{Binding, Interrupt};
10use crate::{pac, Peripheral};
11
12/// I2C error
13#[derive(Debug)]
14#[cfg_attr(feature = "defmt", derive(defmt::Format))]
15#[non_exhaustive]
16pub enum Error {
17 /// I2C abort with error
18 Abort(AbortReason),
19 /// User passed in a response buffer that was 0 length
20 InvalidResponseBufferLength,
21}
22
23/// Received command
24#[derive(Debug, Copy, Clone, Eq, PartialEq)]
25#[cfg_attr(feature = "defmt", derive(defmt::Format))]
26pub enum Command {
27 /// General Call
28 GeneralCall(usize),
29 /// Read
30 Read,
31 /// Write+read
32 WriteRead(usize),
33 /// Write
34 Write(usize),
35}
36
37/// Possible responses to responding to a read
38#[derive(Debug, Copy, Clone, Eq, PartialEq)]
39#[cfg_attr(feature = "defmt", derive(defmt::Format))]
40pub enum ReadStatus {
41 /// Transaction Complete, controller naked our last byte
42 Done,
43 /// Transaction Incomplete, controller trying to read more bytes than were provided
44 NeedMoreBytes,
45 /// Transaction Complere, but controller stopped reading bytes before we ran out
46 LeftoverBytes(u16),
47}
48
49/// Slave Configuration
50#[non_exhaustive]
51#[derive(Copy, Clone)]
52#[cfg_attr(feature = "defmt", derive(defmt::Format))]
53pub struct Config {
54 /// Target Address
55 pub addr: u16,
56}
57
58impl Default for Config {
59 fn default() -> Self {
60 Self { addr: 0x55 }
61 }
62}
63
64pub struct I2cSlave<'d, T: Instance> {
65 phantom: PhantomData<&'d mut T>,
66}
67
68impl<'d, T: Instance> I2cSlave<'d, T> {
69 pub fn new(
70 _peri: impl Peripheral<P = T> + 'd,
71 scl: impl Peripheral<P = impl SclPin<T>> + 'd,
72 sda: impl Peripheral<P = impl SdaPin<T>> + 'd,
73 _irq: impl Binding<T::Interrupt, InterruptHandler<T>>,
74 config: Config,
75 ) -> Self {
76 into_ref!(_peri, scl, sda);
77
78 assert!(!i2c_reserved_addr(config.addr));
79 assert!(config.addr != 0);
80
81 let p = T::regs();
82
83 let reset = T::reset();
84 crate::reset::reset(reset);
85 crate::reset::unreset_wait(reset);
86
87 p.ic_enable().write(|w| w.set_enable(false));
88
89 p.ic_sar().write(|w| w.set_ic_sar(config.addr));
90 p.ic_con().modify(|w| {
91 w.set_master_mode(false);
92 w.set_ic_slave_disable(false);
93 w.set_tx_empty_ctrl(true);
94 });
95
96 // Set FIFO watermarks to 1 to make things simpler. This is encoded
97 // by a register value of 0. Rx watermark should never change, but Tx watermark will be
98 // adjusted in operation.
99 p.ic_tx_tl().write(|w| w.set_tx_tl(0));
100 p.ic_rx_tl().write(|w| w.set_rx_tl(0));
101
102 // Configure SCL & SDA pins
103 scl.gpio().ctrl().write(|w| w.set_funcsel(3));
104 sda.gpio().ctrl().write(|w| w.set_funcsel(3));
105
106 scl.pad_ctrl().write(|w| {
107 w.set_schmitt(true);
108 w.set_ie(true);
109 w.set_od(false);
110 w.set_pue(true);
111 w.set_pde(false);
112 });
113 sda.pad_ctrl().write(|w| {
114 w.set_schmitt(true);
115 w.set_ie(true);
116 w.set_od(false);
117 w.set_pue(true);
118 w.set_pde(false);
119 });
120
121 // Clear interrupts
122 p.ic_clr_intr().read();
123
124 // Enable I2C block
125 p.ic_enable().write(|w| w.set_enable(true));
126
127 // mask everything initially
128 p.ic_intr_mask().write_value(i2c::regs::IcIntrMask(0));
129 T::Interrupt::unpend();
130 unsafe { T::Interrupt::enable() };
131
132 Self { phantom: PhantomData }
133 }
134
135 /// Calls `f` to check if we are ready or not.
136 /// If not, `g` is called once the waker is set (to eg enable the required interrupts).
137 #[inline(always)]
138 async fn wait_on<F, U, G>(&mut self, mut f: F, mut g: G) -> U
139 where
140 F: FnMut(&mut Self) -> Poll<U>,
141 G: FnMut(&mut Self),
142 {
143 future::poll_fn(|cx| {
144 let r = f(self);
145
146 trace!("intr p: {:013b}", T::regs().ic_raw_intr_stat().read().0);
147
148 if r.is_pending() {
149 T::waker().register(cx.waker());
150 g(self);
151 }
152
153 r
154 })
155 .await
156 }
157
158 #[inline(always)]
159 fn drain_fifo(&mut self, buffer: &mut [u8], offset: usize) -> usize {
160 let p = T::regs();
161 let len = p.ic_rxflr().read().rxflr() as usize;
162 let end = offset + len;
163 for i in offset..end {
164 buffer[i] = p.ic_data_cmd().read().dat();
165 }
166 end
167 }
168
169 #[inline(always)]
170 fn write_to_fifo(&mut self, buffer: &[u8]) {
171 let p = T::regs();
172 for byte in buffer {
173 p.ic_data_cmd().write(|w| w.set_dat(*byte));
174 }
175 }
176
177 /// Wait asynchronously for commands from an I2C master.
178 /// `buffer` is provided in case master does a 'write' and is unused for 'read'.
179 pub async fn listen(&mut self, buffer: &mut [u8]) -> Result<Command, Error> {
180 let p = T::regs();
181
182 p.ic_clr_intr().read();
183 // set rx fifo watermark to 1 byte
184 p.ic_rx_tl().write(|w| w.set_rx_tl(0));
185
186 let mut len = 0;
187 let ret = self
188 .wait_on(
189 |me| {
190 let stat = p.ic_raw_intr_stat().read();
191 if p.ic_rxflr().read().rxflr() > 0 {
192 len = me.drain_fifo(buffer, len);
193 // we're recieving data, set rx fifo watermark to 12 bytes to reduce interrupt noise
194 p.ic_rx_tl().write(|w| w.set_rx_tl(11));
195 }
196
197 if stat.restart_det() && stat.rd_req() {
198 Poll::Ready(Ok(Command::WriteRead(len)))
199 } else if stat.gen_call() && stat.stop_det() && len > 0 {
200 Poll::Ready(Ok(Command::GeneralCall(len)))
201 } else if stat.stop_det() {
202 Poll::Ready(Ok(Command::Write(len)))
203 } else if stat.rd_req() {
204 Poll::Ready(Ok(Command::Read))
205 } else {
206 Poll::Pending
207 }
208 },
209 |_me| {
210 p.ic_intr_mask().modify(|w| {
211 w.set_m_stop_det(true);
212 w.set_m_restart_det(true);
213 w.set_m_gen_call(true);
214 w.set_m_rd_req(true);
215 w.set_m_rx_full(true);
216 });
217 },
218 )
219 .await;
220
221 p.ic_clr_intr().read();
222
223 ret
224 }
225
226 /// Respond to an I2C master READ command, asynchronously.
227 pub async fn respond_to_read(&mut self, buffer: &[u8]) -> Result<ReadStatus, Error> {
228 let p = T::regs();
229
230 if buffer.len() == 0 {
231 return Err(Error::InvalidResponseBufferLength);
232 }
233
234 let mut chunks = buffer.chunks(FIFO_SIZE as usize);
235
236 let ret = self
237 .wait_on(
238 |me| {
239 if let Err(abort_reason) = me.read_and_clear_abort_reason() {
240 if let Error::Abort(AbortReason::TxNotEmpty(bytes)) = abort_reason {
241 return Poll::Ready(Ok(ReadStatus::LeftoverBytes(bytes)));
242 } else {
243 return Poll::Ready(Err(abort_reason));
244 }
245 }
246
247 if let Some(chunk) = chunks.next() {
248 me.write_to_fifo(chunk);
249
250 Poll::Pending
251 } else {
252 let stat = p.ic_raw_intr_stat().read();
253
254 if stat.rx_done() && stat.stop_det() {
255 Poll::Ready(Ok(ReadStatus::Done))
256 } else if stat.rd_req() {
257 Poll::Ready(Ok(ReadStatus::NeedMoreBytes))
258 } else {
259 Poll::Pending
260 }
261 }
262 },
263 |_me| {
264 p.ic_intr_mask().modify(|w| {
265 w.set_m_stop_det(true);
266 w.set_m_rx_done(true);
267 w.set_m_tx_empty(true);
268 w.set_m_tx_abrt(true);
269 })
270 },
271 )
272 .await;
273
274 p.ic_clr_intr().read();
275
276 ret
277 }
278
279 /// Respond to reads with the fill byte until the controller stops asking
280 pub async fn respond_till_stop(&mut self, fill: u8) -> Result<(), Error> {
281 loop {
282 match self.respond_to_read(&[fill]).await {
283 Ok(ReadStatus::NeedMoreBytes) => (),
284 Ok(_) => break Ok(()),
285 Err(e) => break Err(e),
286 }
287 }
288 }
289
290 #[inline(always)]
291 fn read_and_clear_abort_reason(&mut self) -> Result<(), Error> {
292 let p = T::regs();
293 let mut abort_reason = p.ic_tx_abrt_source().read();
294
295 // Mask off fifo flush count
296 let tx_flush_cnt = abort_reason.tx_flush_cnt();
297 abort_reason.set_tx_flush_cnt(0);
298
299 // Mask off master_dis
300 abort_reason.set_abrt_master_dis(false);
301
302 if abort_reason.0 != 0 {
303 // Note clearing the abort flag also clears the reason, and this
304 // instance of flag is clear-on-read! Note also the
305 // IC_CLR_TX_ABRT register always reads as 0.
306 p.ic_clr_tx_abrt().read();
307
308 let reason = if abort_reason.abrt_7b_addr_noack()
309 | abort_reason.abrt_10addr1_noack()
310 | abort_reason.abrt_10addr2_noack()
311 {
312 AbortReason::NoAcknowledge
313 } else if abort_reason.arb_lost() {
314 AbortReason::ArbitrationLoss
315 } else if abort_reason.abrt_slvflush_txfifo() {
316 AbortReason::TxNotEmpty(tx_flush_cnt)
317 } else {
318 AbortReason::Other(abort_reason.0)
319 };
320
321 Err(Error::Abort(reason))
322 } else {
323 Ok(())
324 }
325 }
326}
diff --git a/embassy-rp/src/lib.rs b/embassy-rp/src/lib.rs
index 49bd3533e..2a1bca4b9 100644
--- a/embassy-rp/src/lib.rs
+++ b/embassy-rp/src/lib.rs
@@ -16,6 +16,7 @@ pub mod flash;
16mod float; 16mod float;
17pub mod gpio; 17pub mod gpio;
18pub mod i2c; 18pub mod i2c;
19pub mod i2c_slave;
19pub mod multicore; 20pub mod multicore;
20pub mod pwm; 21pub mod pwm;
21mod reset; 22mod reset;
diff --git a/tests/rp/src/bin/i2c.rs b/tests/rp/src/bin/i2c.rs
index 63dd00233..a6cf48afe 100644
--- a/tests/rp/src/bin/i2c.rs
+++ b/tests/rp/src/bin/i2c.rs
@@ -5,10 +5,9 @@
5use defmt::{assert_eq, info, panic, unwrap}; 5use defmt::{assert_eq, info, panic, unwrap};
6use embassy_executor::Executor; 6use embassy_executor::Executor;
7use embassy_executor::_export::StaticCell; 7use embassy_executor::_export::StaticCell;
8use embassy_rp::bind_interrupts;
9use embassy_rp::i2c::{self, Async, InterruptHandler};
10use embassy_rp::multicore::{spawn_core1, Stack}; 8use embassy_rp::multicore::{spawn_core1, Stack};
11use embassy_rp::peripherals::{I2C0, I2C1}; 9use embassy_rp::peripherals::{I2C0, I2C1};
10use embassy_rp::{bind_interrupts, i2c, i2c_slave};
12use embedded_hal_1::i2c::Operation; 11use embedded_hal_1::i2c::Operation;
13use embedded_hal_async::i2c::I2c; 12use embedded_hal_async::i2c::I2c;
14use {defmt_rtt as _, panic_probe as _, panic_probe as _, panic_probe as _}; 13use {defmt_rtt as _, panic_probe as _, panic_probe as _, panic_probe as _};
@@ -20,14 +19,14 @@ static EXECUTOR1: StaticCell<Executor> = StaticCell::new();
20use crate::i2c::AbortReason; 19use crate::i2c::AbortReason;
21 20
22bind_interrupts!(struct Irqs { 21bind_interrupts!(struct Irqs {
23 I2C0_IRQ => InterruptHandler<I2C0>; 22 I2C0_IRQ => i2c::InterruptHandler<I2C0>;
24 I2C1_IRQ => InterruptHandler<I2C1>; 23 I2C1_IRQ => i2c::InterruptHandler<I2C1>;
25}); 24});
26 25
27const DEV_ADDR: u8 = 0x42; 26const DEV_ADDR: u8 = 0x42;
28 27
29#[embassy_executor::task] 28#[embassy_executor::task]
30async fn device_task(mut dev: i2c::I2cDevice<'static, I2C1>) -> ! { 29async fn device_task(mut dev: i2c_slave::I2cSlave<'static, I2C1>) -> ! {
31 info!("Device start"); 30 info!("Device start");
32 31
33 let mut count = 0xD0; 32 let mut count = 0xD0;
@@ -35,33 +34,33 @@ async fn device_task(mut dev: i2c::I2cDevice<'static, I2C1>) -> ! {
35 loop { 34 loop {
36 let mut buf = [0u8; 128]; 35 let mut buf = [0u8; 128];
37 match dev.listen(&mut buf).await { 36 match dev.listen(&mut buf).await {
38 Ok(i2c::Command::GeneralCall(len)) => { 37 Ok(i2c_slave::Command::GeneralCall(len)) => {
39 assert_eq!(buf[..len], [0xCA, 0x11], "recieving the general call failed"); 38 assert_eq!(buf[..len], [0xCA, 0x11], "recieving the general call failed");
40 info!("General Call - OK"); 39 info!("General Call - OK");
41 } 40 }
42 Ok(i2c::Command::Read) => { 41 Ok(i2c_slave::Command::Read) => {
43 loop { 42 loop {
44 //info!("Responding to read, count {}", count); 43 //info!("Responding to read, count {}", count);
45 let a = dev.respond_to_read(&[count]).await; 44 let a = dev.respond_to_read(&[count]).await;
46 //info!("x {}", a); 45 //info!("x {}", a);
47 match a { 46 match a {
48 Ok(x) => match x { 47 Ok(x) => match x {
49 i2c::ReadStatus::Done => break, 48 i2c_slave::ReadStatus::Done => break,
50 i2c::ReadStatus::NeedMoreBytes => count += 1, 49 i2c_slave::ReadStatus::NeedMoreBytes => count += 1,
51 i2c::ReadStatus::LeftoverBytes(x) => { 50 i2c_slave::ReadStatus::LeftoverBytes(x) => {
52 info!("tried to write {} extra bytes", x); 51 info!("tried to write {} extra bytes", x);
53 break; 52 break;
54 } 53 }
55 }, 54 },
56 Err(e) => match e { 55 Err(e) => match e {
57 embassy_rp::i2c::Error::Abort(AbortReason::Other(n)) => panic!("Other {:b}", n), 56 embassy_rp::i2c_slave::Error::Abort(AbortReason::Other(n)) => panic!("Other {:b}", n),
58 _ => panic!("{}", e), 57 _ => panic!("{}", e),
59 }, 58 },
60 } 59 }
61 } 60 }
62 count += 1; 61 count += 1;
63 } 62 }
64 Ok(i2c::Command::Write(len)) => match len { 63 Ok(i2c_slave::Command::Write(len)) => match len {
65 1 => { 64 1 => {
66 assert_eq!(buf[..len], [0xAA], "recieving a single byte failed"); 65 assert_eq!(buf[..len], [0xAA], "recieving a single byte failed");
67 info!("Single Byte Write - OK") 66 info!("Single Byte Write - OK")
@@ -83,7 +82,7 @@ async fn device_task(mut dev: i2c::I2cDevice<'static, I2C1>) -> ! {
83 } 82 }
84 _ => panic!("Invalid write length {}", len), 83 _ => panic!("Invalid write length {}", len),
85 }, 84 },
86 Ok(i2c::Command::WriteRead(len)) => { 85 Ok(i2c_slave::Command::WriteRead(len)) => {
87 info!("device recieved write read: {:x}", buf[..len]); 86 info!("device recieved write read: {:x}", buf[..len]);
88 match buf[0] { 87 match buf[0] {
89 0xC2 => { 88 0xC2 => {
@@ -101,7 +100,7 @@ async fn device_task(mut dev: i2c::I2cDevice<'static, I2C1>) -> ! {
101 } 100 }
102 } 101 }
103 Err(e) => match e { 102 Err(e) => match e {
104 embassy_rp::i2c::Error::Abort(AbortReason::Other(n)) => panic!("Other {:b}", n), 103 embassy_rp::i2c_slave::Error::Abort(AbortReason::Other(n)) => panic!("Other {:b}", n),
105 _ => panic!("{}", e), 104 _ => panic!("{}", e),
106 }, 105 },
107 } 106 }
@@ -109,7 +108,7 @@ async fn device_task(mut dev: i2c::I2cDevice<'static, I2C1>) -> ! {
109} 108}
110 109
111#[embassy_executor::task] 110#[embassy_executor::task]
112async fn controller_task(mut con: i2c::I2c<'static, I2C0, Async>) { 111async fn controller_task(mut con: i2c::I2c<'static, I2C0, i2c::Async>) {
113 info!("Device start"); 112 info!("Device start");
114 113
115 { 114 {
@@ -194,9 +193,9 @@ fn main() -> ! {
194 193
195 let d_sda = p.PIN_19; 194 let d_sda = p.PIN_19;
196 let d_scl = p.PIN_18; 195 let d_scl = p.PIN_18;
197 let mut config = i2c::DeviceConfig::default(); 196 let mut config = i2c_slave::Config::default();
198 config.addr = DEV_ADDR as u16; 197 config.addr = DEV_ADDR as u16;
199 let device = i2c::I2cDevice::new(p.I2C1, d_sda, d_scl, Irqs, config); 198 let device = i2c_slave::I2cSlave::new(p.I2C1, d_sda, d_scl, Irqs, config);
200 199
201 spawn_core1(p.CORE1, unsafe { &mut CORE1_STACK }, move || { 200 spawn_core1(p.CORE1, unsafe { &mut CORE1_STACK }, move || {
202 let executor1 = EXECUTOR1.init(Executor::new()); 201 let executor1 = EXECUTOR1.init(Executor::new());