|
1 | | -//! This example shows how to communicate asynchronous using i2c with external chip. |
2 | | -//! |
3 | | -//! It's using embassy's functions directly instead of traits from embedded_hal_async::i2c::I2c. |
4 | | -//! While most of i2c devices are addressed using 7 bits, an extension allows 10 bits too. |
5 | | -
|
6 | 1 | #![no_std] |
7 | 2 | #![no_main] |
8 | | -use embassy_rp::i2c::InterruptHandler; |
| 3 | + |
| 4 | +use embassy_rp::i2c::{I2c, InterruptHandler}; |
| 5 | +use embassy_rp::peripherals::I2C0; |
9 | 6 | use embassy_time::{Delay, Duration, Timer}; |
10 | 7 | use lcd_lcm1602_i2c::async_lcd::Lcd; |
11 | 8 | use {defmt_rtt as _, panic_probe as _}; |
12 | 9 |
|
13 | 10 | embassy_rp::bind_interrupts!(struct Irqs { |
14 | | - I2C0_IRQ => InterruptHandler<embassy_rp::peripherals::I2C0>; |
| 11 | + I2C0_IRQ => InterruptHandler<I2C0>; |
15 | 12 | }); |
16 | 13 |
|
17 | | -#[embassy_executor::main] |
18 | | -async fn main(_task_spawner: embassy_executor::Spawner) { |
19 | | - const LCD_ADDRESS: u8 = 0x26; |
20 | | - let p = embassy_rp::init(Default::default()); |
21 | | - let sda = p.PIN_0; |
22 | | - let scl = p.PIN_1; |
23 | | - let config = embassy_rp::i2c::Config::default(); |
24 | | - let mut bus = embassy_rp::i2c::I2c::new_async(p.I2C0, scl, sda, Irqs, config); |
25 | | - let mut delay = Delay; |
| 14 | +async fn init_lcd<'a>( |
| 15 | + bus: &'a mut I2c<'a, I2C0, embassy_rp::i2c::Async>, |
| 16 | + delay: &'a mut Delay, |
| 17 | +) -> Result<Lcd<'a, I2c<'a, I2C0, embassy_rp::i2c::Async>, Delay>, embassy_rp::i2c::Error> { |
| 18 | + const LCD_ADDRESS: u8 = 0x27; |
26 | 19 |
|
27 | | - let mut lcd_scr = Lcd::new(&mut bus, &mut delay) |
| 20 | + let lcd_scr = Lcd::new(bus, delay) |
28 | 21 | .with_address(LCD_ADDRESS) |
29 | 22 | .with_cursor_on(false) |
30 | 23 | .with_rows(2); |
31 | 24 |
|
32 | | - // Initialize the LCD |
33 | | - lcd_scr = lcd_scr.init().await.unwrap(); |
34 | | - lcd_scr.clear().await.unwrap(); |
| 25 | + let lcd_scr = lcd_scr.init().await.unwrap(); // `init` returns ownership |
| 26 | + Ok(lcd_scr) |
| 27 | +} |
35 | 28 |
|
36 | | - // Write a message to the LCD |
37 | | - lcd_scr.write_str("Hello Rust!").await.unwrap(); |
| 29 | +async fn lcd_display<'a>( |
| 30 | + lcd: &mut Lcd<'a, I2c<'a, I2C0, embassy_rp::i2c::Async>, Delay>, |
| 31 | + msg: &str, |
| 32 | +) { |
| 33 | + lcd.clear().await.unwrap(); |
| 34 | + lcd.write_str("Hello Rust!").await.unwrap(); |
38 | 35 |
|
39 | | - // Main loop: write messages with delays |
40 | | - loop { |
41 | | - lcd_scr.set_cursor(0, 0).await.unwrap(); // Move to the second line |
42 | | - lcd_scr.write_str("Async + LCD").await.unwrap(); |
| 36 | + lcd.set_cursor(1, 0).await.unwrap(); // Move to the second line |
| 37 | + lcd.write_str(msg).await.unwrap(); |
43 | 38 |
|
44 | | - Timer::after(Duration::from_secs(2)).await; |
| 39 | + Timer::after(Duration::from_secs(2)).await; |
| 40 | +} |
45 | 41 |
|
46 | | - lcd_scr.clear().await.unwrap(); |
47 | | - lcd_scr.write_str("Embassy Rocks!").await.unwrap(); |
| 42 | +#[embassy_executor::main] |
| 43 | +async fn main(_task_spawner: embassy_executor::Spawner) { |
| 44 | + let p = embassy_rp::init(Default::default()); |
48 | 45 |
|
49 | | - Timer::after(Duration::from_secs(2)).await; |
| 46 | + let mut bus = I2c::new_async( |
| 47 | + p.I2C0, |
| 48 | + p.PIN_1, |
| 49 | + p.PIN_0, |
| 50 | + Irqs, |
| 51 | + embassy_rp::i2c::Config::default(), |
| 52 | + ); |
| 53 | + let mut delay = Delay; |
| 54 | + |
| 55 | + // Initialize the LCD |
| 56 | + let mut lcd = init_lcd(&mut bus, &mut delay).await.unwrap(); |
| 57 | + |
| 58 | + // Display messages |
| 59 | + loop { |
| 60 | + lcd_display(&mut lcd, "Hello World!").await; |
50 | 61 | } |
51 | 62 | } |
0 commit comments