aboutsummaryrefslogtreecommitdiff
path: root/examples
diff options
context:
space:
mode:
authorJeremy Fitzhardinge <[email protected]>2022-09-28 09:35:19 -0700
committerJeremy Fitzhardinge <[email protected]>2022-10-01 13:43:37 -0700
commit1ee4bb22deb19e93a7c68e04875889e3e4e31c29 (patch)
tree9ad2db208382396a964e6de0b6afa273b0424f5e /examples
parent5e2c52ee5b6fcc5b50589fd2590657e3f1083bff (diff)
embassy-rp i2c: async (non-blocking) example
Simple example exercising an mcp23017 GPIO expander, configured on RP2040 GPIOs 14+15 (i2c1) with 8 inputs and 8 outputs. Input bit 0 controls whether to display a mcp23017 register dump.
Diffstat (limited to 'examples')
-rw-r--r--examples/rp/src/bin/i2c_async.rs102
1 files changed, 102 insertions, 0 deletions
diff --git a/examples/rp/src/bin/i2c_async.rs b/examples/rp/src/bin/i2c_async.rs
new file mode 100644
index 000000000..d1a2e3cd7
--- /dev/null
+++ b/examples/rp/src/bin/i2c_async.rs
@@ -0,0 +1,102 @@
1#![no_std]
2#![no_main]
3#![feature(type_alias_impl_trait)]
4
5use defmt::*;
6use embassy_executor::Spawner;
7use embassy_rp::i2c::{self, Config};
8use embassy_rp::interrupt;
9use embassy_time::{Duration, Timer};
10use embedded_hal_async::i2c::I2c;
11use {defmt_rtt as _, panic_probe as _};
12
13#[allow(dead_code)]
14mod mcp23017 {
15 pub const ADDR: u8 = 0x20; // default addr
16
17 macro_rules! mcpregs {
18 ($($name:ident : $val:expr),* $(,)?) => {
19 $(
20 pub const $name: u8 = $val;
21 )*
22
23 pub fn regname(reg: u8) -> &'static str {
24 match reg {
25 $(
26 $val => stringify!($name),
27 )*
28 _ => panic!("bad reg"),
29 }
30 }
31 }
32 }
33
34 // These are correct for IOCON.BANK=0
35 mcpregs! {
36 IODIRA: 0x00,
37 IPOLA: 0x02,
38 GPINTENA: 0x04,
39 DEFVALA: 0x06,
40 INTCONA: 0x08,
41 IOCONA: 0x0A,
42 GPPUA: 0x0C,
43 INTFA: 0x0E,
44 INTCAPA: 0x10,
45 GPIOA: 0x12,
46 OLATA: 0x14,
47 IODIRB: 0x01,
48 IPOLB: 0x03,
49 GPINTENB: 0x05,
50 DEFVALB: 0x07,
51 INTCONB: 0x09,
52 IOCONB: 0x0B,
53 GPPUB: 0x0D,
54 INTFB: 0x0F,
55 INTCAPB: 0x11,
56 GPIOB: 0x13,
57 OLATB: 0x15,
58 }
59}
60
61#[embassy_executor::main]
62async fn main(_spawner: Spawner) {
63 let p = embassy_rp::init(Default::default());
64
65 let sda = p.PIN_14;
66 let scl = p.PIN_15;
67 let irq = interrupt::take!(I2C1_IRQ);
68
69 info!("set up i2c ");
70 let mut i2c = i2c::I2c::new_async(p.I2C1, scl, sda, irq, Config::default());
71
72 use mcp23017::*;
73
74 info!("init mcp23017 config for IxpandO");
75 // init - a outputs, b inputs
76 i2c.write(ADDR, &[IODIRA, 0x00]).await.unwrap();
77 i2c.write(ADDR, &[IODIRB, 0xff]).await.unwrap();
78 i2c.write(ADDR, &[GPPUB, 0xff]).await.unwrap(); // pullups
79
80 let mut val = 1;
81 loop {
82 let mut portb = [0];
83
84 i2c.write_read(mcp23017::ADDR, &[GPIOB], &mut portb).await.unwrap();
85 info!("portb = {:02x}", portb[0]);
86 i2c.write(mcp23017::ADDR, &[GPIOA, val | portb[0]]).await.unwrap();
87 val = val.rotate_left(1);
88
89 // get a register dump
90 info!("getting register dump");
91 let mut regs = [0; 22];
92 i2c.write_read(ADDR, &[0], &mut regs).await.unwrap();
93 // always get the regdump but only display it if portb'0 is set
94 if portb[0] & 1 != 0 {
95 for (idx, reg) in regs.into_iter().enumerate() {
96 info!("{} => {:02x}", regname(idx as u8), reg);
97 }
98 }
99
100 Timer::after(Duration::from_millis(100)).await;
101 }
102}