diff options
| author | Curly <[email protected]> | 2025-02-23 07:33:58 -0800 |
|---|---|---|
| committer | Curly <[email protected]> | 2025-02-23 07:33:58 -0800 |
| commit | 3932835998802fc3abf7cce4f736e072858ebfd1 (patch) | |
| tree | 5dd714b99bc74a03556c58809237c88691c293bb /examples/rp235x/src/bin/i2c_slave.rs | |
| parent | c3c67db93e627a4fafe5e1a1123e5cbb4abafe47 (diff) | |
rename `rp23` (?) folder to `rp235x`; fix `ci.sh` to use `rp235x` folder
Diffstat (limited to 'examples/rp235x/src/bin/i2c_slave.rs')
| -rw-r--r-- | examples/rp235x/src/bin/i2c_slave.rs | 117 |
1 files changed, 117 insertions, 0 deletions
diff --git a/examples/rp235x/src/bin/i2c_slave.rs b/examples/rp235x/src/bin/i2c_slave.rs new file mode 100644 index 000000000..9fffb4646 --- /dev/null +++ b/examples/rp235x/src/bin/i2c_slave.rs | |||
| @@ -0,0 +1,117 @@ | |||
| 1 | //! This example shows how to use the 2040 as an i2c slave. | ||
| 2 | #![no_std] | ||
| 3 | #![no_main] | ||
| 4 | |||
| 5 | use defmt::*; | ||
| 6 | use embassy_executor::Spawner; | ||
| 7 | use embassy_rp::peripherals::{I2C0, I2C1}; | ||
| 8 | use embassy_rp::{bind_interrupts, i2c, i2c_slave}; | ||
| 9 | use embassy_time::Timer; | ||
| 10 | use embedded_hal_async::i2c::I2c; | ||
| 11 | use {defmt_rtt as _, panic_probe as _}; | ||
| 12 | |||
| 13 | bind_interrupts!(struct Irqs { | ||
| 14 | I2C0_IRQ => i2c::InterruptHandler<I2C0>; | ||
| 15 | I2C1_IRQ => i2c::InterruptHandler<I2C1>; | ||
| 16 | }); | ||
| 17 | |||
| 18 | const DEV_ADDR: u8 = 0x42; | ||
| 19 | |||
| 20 | #[embassy_executor::task] | ||
| 21 | async fn device_task(mut dev: i2c_slave::I2cSlave<'static, I2C1>) -> ! { | ||
| 22 | info!("Device start"); | ||
| 23 | |||
| 24 | let mut state = 0; | ||
| 25 | |||
| 26 | loop { | ||
| 27 | let mut buf = [0u8; 128]; | ||
| 28 | match dev.listen(&mut buf).await { | ||
| 29 | Ok(i2c_slave::Command::GeneralCall(len)) => info!("Device received general call write: {}", buf[..len]), | ||
| 30 | Ok(i2c_slave::Command::Read) => loop { | ||
| 31 | match dev.respond_to_read(&[state]).await { | ||
| 32 | Ok(x) => match x { | ||
| 33 | i2c_slave::ReadStatus::Done => break, | ||
| 34 | i2c_slave::ReadStatus::NeedMoreBytes => (), | ||
| 35 | i2c_slave::ReadStatus::LeftoverBytes(x) => { | ||
| 36 | info!("tried to write {} extra bytes", x); | ||
| 37 | break; | ||
| 38 | } | ||
| 39 | }, | ||
| 40 | Err(e) => error!("error while responding {}", e), | ||
| 41 | } | ||
| 42 | }, | ||
| 43 | Ok(i2c_slave::Command::Write(len)) => info!("Device received write: {}", buf[..len]), | ||
| 44 | Ok(i2c_slave::Command::WriteRead(len)) => { | ||
| 45 | info!("device received write read: {:x}", buf[..len]); | ||
| 46 | match buf[0] { | ||
| 47 | // Set the state | ||
| 48 | 0xC2 => { | ||
| 49 | state = buf[1]; | ||
| 50 | match dev.respond_and_fill(&[state], 0x00).await { | ||
| 51 | Ok(read_status) => info!("response read status {}", read_status), | ||
| 52 | Err(e) => error!("error while responding {}", e), | ||
| 53 | } | ||
| 54 | } | ||
| 55 | // Reset State | ||
| 56 | 0xC8 => { | ||
| 57 | state = 0; | ||
| 58 | match dev.respond_and_fill(&[state], 0x00).await { | ||
| 59 | Ok(read_status) => info!("response read status {}", read_status), | ||
| 60 | Err(e) => error!("error while responding {}", e), | ||
| 61 | } | ||
| 62 | } | ||
| 63 | x => error!("Invalid Write Read {:x}", x), | ||
| 64 | } | ||
| 65 | } | ||
| 66 | Err(e) => error!("{}", e), | ||
| 67 | } | ||
| 68 | } | ||
| 69 | } | ||
| 70 | |||
| 71 | #[embassy_executor::task] | ||
| 72 | async fn controller_task(mut con: i2c::I2c<'static, I2C0, i2c::Async>) { | ||
| 73 | info!("Controller start"); | ||
| 74 | |||
| 75 | loop { | ||
| 76 | let mut resp_buff = [0u8; 2]; | ||
| 77 | for i in 0..10 { | ||
| 78 | match con.write_read(DEV_ADDR, &[0xC2, i], &mut resp_buff).await { | ||
| 79 | Ok(_) => info!("write_read response: {}", resp_buff), | ||
| 80 | Err(e) => error!("Error writing {}", e), | ||
| 81 | } | ||
| 82 | |||
| 83 | Timer::after_millis(100).await; | ||
| 84 | } | ||
| 85 | match con.read(DEV_ADDR, &mut resp_buff).await { | ||
| 86 | Ok(_) => info!("read response: {}", resp_buff), | ||
| 87 | Err(e) => error!("Error writing {}", e), | ||
| 88 | } | ||
| 89 | match con.write_read(DEV_ADDR, &[0xC8], &mut resp_buff).await { | ||
| 90 | Ok(_) => info!("write_read response: {}", resp_buff), | ||
| 91 | Err(e) => error!("Error writing {}", e), | ||
| 92 | } | ||
| 93 | Timer::after_millis(100).await; | ||
| 94 | } | ||
| 95 | } | ||
| 96 | |||
| 97 | #[embassy_executor::main] | ||
| 98 | async fn main(spawner: Spawner) { | ||
| 99 | let p = embassy_rp::init(Default::default()); | ||
| 100 | info!("Hello World!"); | ||
| 101 | |||
| 102 | let d_sda = p.PIN_3; | ||
| 103 | let d_scl = p.PIN_2; | ||
| 104 | let mut config = i2c_slave::Config::default(); | ||
| 105 | config.addr = DEV_ADDR as u16; | ||
| 106 | let device = i2c_slave::I2cSlave::new(p.I2C1, d_sda, d_scl, Irqs, config); | ||
| 107 | |||
| 108 | unwrap!(spawner.spawn(device_task(device))); | ||
| 109 | |||
| 110 | let c_sda = p.PIN_1; | ||
| 111 | let c_scl = p.PIN_0; | ||
| 112 | let mut config = i2c::Config::default(); | ||
| 113 | config.frequency = 1_000_000; | ||
| 114 | let controller = i2c::I2c::new_async(p.I2C0, c_sda, c_scl, Irqs, config); | ||
| 115 | |||
| 116 | unwrap!(spawner.spawn(controller_task(controller))); | ||
| 117 | } | ||
