aboutsummaryrefslogtreecommitdiff
path: root/tests
diff options
context:
space:
mode:
authorCaleb Jamison <[email protected]>2023-08-14 16:50:57 -0400
committerDario Nieuwenhuis <[email protected]>2023-09-10 23:01:15 +0200
commit26e0823c3507a537d72fa5d6d7e97126314c0f0c (patch)
tree12336d61c85117019e4012531c89ffb64a12c5cc /tests
parentceca8b4336d8706a9e767c0d397182d02527d8cc (diff)
rp2040 I2cDevice
Move i2c to mod, split device and controller Remove mode generic: I don't think it's reasonable to use the i2c in device mode while blocking, so I'm cutting the generic.
Diffstat (limited to 'tests')
-rw-r--r--tests/rp/src/bin/i2c.rs215
1 files changed, 215 insertions, 0 deletions
diff --git a/tests/rp/src/bin/i2c.rs b/tests/rp/src/bin/i2c.rs
new file mode 100644
index 000000000..63dd00233
--- /dev/null
+++ b/tests/rp/src/bin/i2c.rs
@@ -0,0 +1,215 @@
1#![no_std]
2#![no_main]
3#![feature(type_alias_impl_trait)]
4
5use defmt::{assert_eq, info, panic, unwrap};
6use embassy_executor::Executor;
7use embassy_executor::_export::StaticCell;
8use embassy_rp::bind_interrupts;
9use embassy_rp::i2c::{self, Async, InterruptHandler};
10use embassy_rp::multicore::{spawn_core1, Stack};
11use embassy_rp::peripherals::{I2C0, I2C1};
12use embedded_hal_1::i2c::Operation;
13use embedded_hal_async::i2c::I2c;
14use {defmt_rtt as _, panic_probe as _, panic_probe as _, panic_probe as _};
15
16static mut CORE1_STACK: Stack<1024> = Stack::new();
17static EXECUTOR0: StaticCell<Executor> = StaticCell::new();
18static EXECUTOR1: StaticCell<Executor> = StaticCell::new();
19
20use crate::i2c::AbortReason;
21
22bind_interrupts!(struct Irqs {
23 I2C0_IRQ => InterruptHandler<I2C0>;
24 I2C1_IRQ => InterruptHandler<I2C1>;
25});
26
27const DEV_ADDR: u8 = 0x42;
28
29#[embassy_executor::task]
30async fn device_task(mut dev: i2c::I2cDevice<'static, I2C1>) -> ! {
31 info!("Device start");
32
33 let mut count = 0xD0;
34
35 loop {
36 let mut buf = [0u8; 128];
37 match dev.listen(&mut buf).await {
38 Ok(i2c::Command::GeneralCall(len)) => {
39 assert_eq!(buf[..len], [0xCA, 0x11], "recieving the general call failed");
40 info!("General Call - OK");
41 }
42 Ok(i2c::Command::Read) => {
43 loop {
44 //info!("Responding to read, count {}", count);
45 let a = dev.respond_to_read(&[count]).await;
46 //info!("x {}", a);
47 match a {
48 Ok(x) => match x {
49 i2c::ReadStatus::Done => break,
50 i2c::ReadStatus::NeedMoreBytes => count += 1,
51 i2c::ReadStatus::LeftoverBytes(x) => {
52 info!("tried to write {} extra bytes", x);
53 break;
54 }
55 },
56 Err(e) => match e {
57 embassy_rp::i2c::Error::Abort(AbortReason::Other(n)) => panic!("Other {:b}", n),
58 _ => panic!("{}", e),
59 },
60 }
61 }
62 count += 1;
63 }
64 Ok(i2c::Command::Write(len)) => match len {
65 1 => {
66 assert_eq!(buf[..len], [0xAA], "recieving a single byte failed");
67 info!("Single Byte Write - OK")
68 }
69 4 => {
70 assert_eq!(buf[..len], [0xAA, 0xBB, 0xCC, 0xDD], "recieving 4 bytes failed");
71 info!("4 Byte Write - OK")
72 }
73 32 => {
74 assert_eq!(
75 buf[..len],
76 [
77 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24,
78 25, 26, 27, 28, 29, 30, 31
79 ],
80 "recieving 32 bytes failed"
81 );
82 info!("32 Byte Write - OK")
83 }
84 _ => panic!("Invalid write length {}", len),
85 },
86 Ok(i2c::Command::WriteRead(len)) => {
87 info!("device recieved write read: {:x}", buf[..len]);
88 match buf[0] {
89 0xC2 => {
90 let resp_buff = [0xD1, 0xD2, 0xD3, 0xD4];
91 dev.respond_to_read(&resp_buff).await.unwrap();
92 }
93 0xC8 => {
94 let mut resp_buff = [0u8; 32];
95 for i in 0..32 {
96 resp_buff[i] = i as u8;
97 }
98 dev.respond_to_read(&resp_buff).await.unwrap();
99 }
100 x => panic!("Invalid Write Read {:x}", x),
101 }
102 }
103 Err(e) => match e {
104 embassy_rp::i2c::Error::Abort(AbortReason::Other(n)) => panic!("Other {:b}", n),
105 _ => panic!("{}", e),
106 },
107 }
108 }
109}
110
111#[embassy_executor::task]
112async fn controller_task(mut con: i2c::I2c<'static, I2C0, Async>) {
113 info!("Device start");
114
115 {
116 let buf = [0xCA, 0x11];
117 con.write(0u16, &buf).await.unwrap();
118 info!("Controler general call write");
119 embassy_futures::yield_now().await;
120 }
121
122 {
123 let mut buf = [0u8];
124 con.read(DEV_ADDR, &mut buf).await.unwrap();
125 assert_eq!(buf, [0xD0], "single byte read failed");
126 info!("single byte read - OK");
127 embassy_futures::yield_now().await;
128 }
129
130 {
131 let mut buf = [0u8; 4];
132 con.read(DEV_ADDR, &mut buf).await.unwrap();
133 assert_eq!(buf, [0xD1, 0xD2, 0xD3, 0xD4], "single byte read failed");
134 info!("4 byte read - OK");
135 embassy_futures::yield_now().await;
136 }
137
138 {
139 let buf = [0xAA];
140 con.write(DEV_ADDR, &buf).await.unwrap();
141 info!("Controler single byte write");
142 embassy_futures::yield_now().await;
143 }
144
145 {
146 let buf = [0xAA, 0xBB, 0xCC, 0xDD];
147 con.write(DEV_ADDR, &buf).await.unwrap();
148 info!("Controler 4 byte write");
149 embassy_futures::yield_now().await;
150 }
151
152 {
153 let mut buf = [0u8; 32];
154 for i in 0..32 {
155 buf[i] = i as u8;
156 }
157 con.write(DEV_ADDR, &buf).await.unwrap();
158 info!("Controler 32 byte write");
159 embassy_futures::yield_now().await;
160 }
161
162 {
163 let mut buf = [0u8; 4];
164 let mut ops = [Operation::Write(&[0xC2]), Operation::Read(&mut buf)];
165 con.transaction(DEV_ADDR, &mut ops).await.unwrap();
166 assert_eq!(buf, [0xD1, 0xD2, 0xD3, 0xD4], "write_read failed");
167 info!("write_read - OK");
168 embassy_futures::yield_now().await;
169 }
170
171 {
172 let mut buf = [0u8; 32];
173 let mut ops = [Operation::Write(&[0xC8]), Operation::Read(&mut buf)];
174 con.transaction(DEV_ADDR, &mut ops).await.unwrap();
175 assert_eq!(
176 buf,
177 [
178 0, 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,
179 28, 29, 30, 31
180 ],
181 "write_read of 32 bytes failed"
182 );
183 info!("large write_read - OK")
184 }
185
186 info!("Test OK");
187 cortex_m::asm::bkpt();
188}
189
190#[cortex_m_rt::entry]
191fn main() -> ! {
192 let p = embassy_rp::init(Default::default());
193 info!("Hello World!");
194
195 let d_sda = p.PIN_19;
196 let d_scl = p.PIN_18;
197 let mut config = i2c::DeviceConfig::default();
198 config.addr = DEV_ADDR as u16;
199 let device = i2c::I2cDevice::new(p.I2C1, d_sda, d_scl, Irqs, config);
200
201 spawn_core1(p.CORE1, unsafe { &mut CORE1_STACK }, move || {
202 let executor1 = EXECUTOR1.init(Executor::new());
203 executor1.run(|spawner| unwrap!(spawner.spawn(device_task(device))));
204 });
205
206 let executor0 = EXECUTOR0.init(Executor::new());
207
208 let c_sda = p.PIN_21;
209 let c_scl = p.PIN_20;
210 let mut config = i2c::Config::default();
211 config.frequency = 5_000;
212 let controller = i2c::I2c::new_async(p.I2C0, c_sda, c_scl, Irqs, config);
213
214 executor0.run(|spawner| unwrap!(spawner.spawn(controller_task(controller))));
215}