aboutsummaryrefslogtreecommitdiff
path: root/examples
diff options
context:
space:
mode:
authorJames Munns <[email protected]>2024-07-18 15:11:54 +0000
committerGitHub <[email protected]>2024-07-18 15:11:54 +0000
commit2766993099b6604739ae25724aa2f6a9877d9902 (patch)
treea4b80bc17476d163da89599ae049eaa9ce304178 /examples
parent5e625f274ac567fcbb37ba797629c6b3d33fad2b (diff)
parentaf9c7379f99b309a99b0b573ebfb8ea1bebecaf9 (diff)
Merge pull request #3159 from kalkyl/shared-bus
Add example for shared I2C and SPI buses
Diffstat (limited to 'examples')
-rw-r--r--examples/rp/src/bin/shared_bus.rs115
1 files changed, 115 insertions, 0 deletions
diff --git a/examples/rp/src/bin/shared_bus.rs b/examples/rp/src/bin/shared_bus.rs
new file mode 100644
index 000000000..c6cb5d64c
--- /dev/null
+++ b/examples/rp/src/bin/shared_bus.rs
@@ -0,0 +1,115 @@
1//! This example shows how to share (async) I2C and SPI buses between multiple devices.
2
3#![no_std]
4#![no_main]
5
6use defmt::*;
7use embassy_embedded_hal::shared_bus::asynch::i2c::I2cDevice;
8use embassy_embedded_hal::shared_bus::asynch::spi::SpiDevice;
9use embassy_executor::Spawner;
10use embassy_rp::bind_interrupts;
11use embassy_rp::gpio::{AnyPin, Level, Output};
12use embassy_rp::i2c::{self, I2c, InterruptHandler};
13use embassy_rp::peripherals::{I2C1, SPI1};
14use embassy_rp::spi::{self, Spi};
15use embassy_sync::blocking_mutex::raw::NoopRawMutex;
16use embassy_sync::mutex::Mutex;
17use embassy_time::Timer;
18use static_cell::StaticCell;
19use {defmt_rtt as _, panic_probe as _};
20
21type Spi1Bus = Mutex<NoopRawMutex, Spi<'static, SPI1, spi::Async>>;
22type I2c1Bus = Mutex<NoopRawMutex, I2c<'static, I2C1, i2c::Async>>;
23
24bind_interrupts!(struct Irqs {
25 I2C1_IRQ => InterruptHandler<I2C1>;
26});
27
28#[embassy_executor::main]
29async fn main(spawner: Spawner) {
30 let p = embassy_rp::init(Default::default());
31 info!("Here we go!");
32
33 // Shared I2C bus
34 let i2c = I2c::new_async(p.I2C1, p.PIN_15, p.PIN_14, Irqs, i2c::Config::default());
35 static I2C_BUS: StaticCell<I2c1Bus> = StaticCell::new();
36 let i2c_bus = I2C_BUS.init(Mutex::new(i2c));
37
38 spawner.must_spawn(i2c_task_a(i2c_bus));
39 spawner.must_spawn(i2c_task_b(i2c_bus));
40
41 // Shared SPI bus
42 let spi_cfg = spi::Config::default();
43 let spi = Spi::new(p.SPI1, p.PIN_10, p.PIN_11, p.PIN_12, p.DMA_CH0, p.DMA_CH1, spi_cfg);
44 static SPI_BUS: StaticCell<Spi1Bus> = StaticCell::new();
45 let spi_bus = SPI_BUS.init(Mutex::new(spi));
46
47 // Chip select pins for the SPI devices
48 let cs_a = Output::new(AnyPin::from(p.PIN_0), Level::High);
49 let cs_b = Output::new(AnyPin::from(p.PIN_1), Level::High);
50
51 spawner.must_spawn(spi_task_a(spi_bus, cs_a));
52 spawner.must_spawn(spi_task_b(spi_bus, cs_b));
53}
54
55#[embassy_executor::task]
56async fn i2c_task_a(i2c_bus: &'static I2c1Bus) {
57 let i2c_dev = I2cDevice::new(i2c_bus);
58 let _sensor = DummyI2cDeviceDriver::new(i2c_dev, 0xC0);
59 loop {
60 info!("i2c task A");
61 Timer::after_secs(1).await;
62 }
63}
64
65#[embassy_executor::task]
66async fn i2c_task_b(i2c_bus: &'static I2c1Bus) {
67 let i2c_dev = I2cDevice::new(i2c_bus);
68 let _sensor = DummyI2cDeviceDriver::new(i2c_dev, 0xDE);
69 loop {
70 info!("i2c task B");
71 Timer::after_secs(1).await;
72 }
73}
74
75#[embassy_executor::task]
76async fn spi_task_a(spi_bus: &'static Spi1Bus, cs: Output<'static>) {
77 let spi_dev = SpiDevice::new(spi_bus, cs);
78 let _sensor = DummySpiDeviceDriver::new(spi_dev);
79 loop {
80 info!("spi task A");
81 Timer::after_secs(1).await;
82 }
83}
84
85#[embassy_executor::task]
86async fn spi_task_b(spi_bus: &'static Spi1Bus, cs: Output<'static>) {
87 let spi_dev = SpiDevice::new(spi_bus, cs);
88 let _sensor = DummySpiDeviceDriver::new(spi_dev);
89 loop {
90 info!("spi task B");
91 Timer::after_secs(1).await;
92 }
93}
94
95// Dummy I2C device driver, using `embedded-hal-async`
96struct DummyI2cDeviceDriver<I2C: embedded_hal_async::i2c::I2c> {
97 _i2c: I2C,
98}
99
100impl<I2C: embedded_hal_async::i2c::I2c> DummyI2cDeviceDriver<I2C> {
101 fn new(i2c_dev: I2C, _address: u8) -> Self {
102 Self { _i2c: i2c_dev }
103 }
104}
105
106// Dummy SPI device driver, using `embedded-hal-async`
107struct DummySpiDeviceDriver<SPI: embedded_hal_async::spi::SpiDevice> {
108 _spi: SPI,
109}
110
111impl<SPI: embedded_hal_async::spi::SpiDevice> DummySpiDeviceDriver<SPI> {
112 fn new(spi_dev: SPI) -> Self {
113 Self { _spi: spi_dev }
114 }
115}