Skip to content

embedded-hal v1.0.0 and embedded-hal-bus #205

@pdgilbert

Description

@pdgilbert

I am using @bugadani 's ehal1 fork of ssd1306 to make some examples work with embedded-hal-1.0.0. One of my main problems has been using ssd1306 with shared-bus. (see stm32-rs/stm32f4xx-hal#722 (comment)). @rursprung pointed out that embedded-hal-bus is a replacement for shared-bus, but so far I have not been able to get the trait formulation and other pieces correct. I am not sure if this is just my newbie understanding, or if something is needed in ssd1306. The documentaion is written for HAL and crate developers, not for naive users. (I need a working example.)

With a local fork of @bugadani 's ehal1 I have modified example/text_i2c.rs and added a few lines to Cargo.toml.

Click to expand modified examples/text_i2c.rs
//! Print "Hello world!" with "Hello rust!" underneath. Uses the `embedded_graphics` crate to draw
//! the text with a 6x10 pixel font.
//!
//! This example is for the STM32F103 "Blue Pill" board and others using I2C1.
//!
//! Wiring connections are as follows for a CRIUS-branded display:
//!
//! ```
//!      Display -> Blue Pill
//! (black)  GND -> GND
//! (red)    +5V -> VCC
//! (yellow) SDA -> PB9
//! (green)  SCL -> PB8
//! ```
//!
//! Build on a Black Pill with 
//!   cargo build --target thumbv7em-none-eabihf --features stm32f4xx-hal --example  text_i2c
//! Build on stm32h742 with 
//!   cargo build --target thumbv7em-none-eabihf --features stm32h7xx-hal --example  text_i2c


#![no_std]
#![no_main]

use cortex_m_rt::{entry, exception, ExceptionFrame};
use embedded_graphics::{
    mono_font::{ascii::FONT_6X10, MonoTextStyleBuilder},
    pixelcolor::BinaryColor,
    prelude::*,
    text::{Baseline, Text},
};
use panic_halt as _;
use ssd1306::{prelude::*, I2CDisplayInterface, Ssd1306};


#[cfg(feature = "stm32f4xx-hal")]
use stm32f4xx_hal as hal;

#[cfg(feature = "stm32h7xx-hal")]
use stm32h7xx_hal as hal;

use hal::{
    i2c::I2c,
    prelude::*,
    pac::{Peripherals, I2C1},
    pac,
};


//use embedded_hal_bus::*;  
//use embedded_hal_bus::i2c;
//use embedded_hal::i2c::I2c;
//use embedded_hal_bus::i2c::I2c;
//use embedded_hal_async::i2c::I2c;
//use embedded_hal::i2c::{I2c, ErrorType as I2cErrorType, SevenBitAddress, TenBitAddress, Operation, Error as I2cError, };


#[cfg(feature = "stm32f4xx-hal")]
fn setup(dp:Peripherals) -> I2c<I2C1> {
    let rcc = dp.RCC.constrain();
    let clocks = rcc.cfgr.freeze();
    let gpiob = dp.GPIOB.split();

    let scl = gpiob.pb8.into_alternate_open_drain(); 
    let sda = gpiob.pb9.into_alternate_open_drain(); 

    let r = I2c::new(dp.I2C1, (scl, sda), 400.kHz(), &clocks);
    r
}


#[cfg(feature = "stm32h7xx-hal")]
fn setup(dp:Peripherals) -> I2c<I2C1> {
    let pwr = dp.PWR.constrain();
    let vos = pwr.freeze();
    let rcc = dp.RCC.constrain();
    let ccdr = rcc.sys_ck(160.MHz()).freeze(vos, &dp.SYSCFG);
    let clocks = ccdr.clocks;

    let gpiob = dp.GPIOB.split(ccdr.peripheral.GPIOB);

    let scl = gpiob.pb8.into_alternate().set_open_drain();
    let sda = gpiob.pb9.into_alternate().set_open_drain(); 

    let r = dp.I2C1.i2c((scl, sda), 400.kHz(), ccdr.peripheral.I2C1, &clocks);
    r
}

#[entry]
fn main() -> ! {
    let dp = pac::Peripherals::take().unwrap();
   
    let r = setup(dp);
    
    let interface = I2CDisplayInterface::new(r);
    //  need address and ErrorType
    //pub trait I2c<A: AddressMode = SevenBitAddress>: ErrorType {

    let mut display = Ssd1306::new(interface, DisplaySize128x64, DisplayRotation::Rotate0)
        .into_buffered_graphics_mode();
    display.init().unwrap();

    let text_style = MonoTextStyleBuilder::new()
        .font(&FONT_6X10)
        .text_color(BinaryColor::On)
        .build();

    Text::with_baseline("Hello world!", Point::zero(), text_style, Baseline::Top)
        .draw(&mut display)
        .unwrap();

    Text::with_baseline("Hello Rust!", Point::new(0, 16), text_style, Baseline::Top)
        .draw(&mut display)
        .unwrap();

    display.flush().unwrap();

    loop {}
}

#[exception]
unsafe fn HardFault(ef: &ExceptionFrame) -> ! {
    panic!("{:#?}", ef);
}

Click to expand Cargo.toml diff
29a30,34
> # Used by text_i2c examples
> embedded-hal-bus = { git = "https://github.com/rust-embedded/embedded-hal/" }
> stm32f4xx-hal = { git = "https://github.com/rursprung/stm32f4xx-hal", features = [ "rt", "stm32f401" ], optional = true, branch = "update-to-eh-1"  } 
> stm32h7xx-hal = { git = "https://github.com/stm32-rs/stm32h7xx-hal",  features = [ "rt", "stm32h742" ], optional = true, branch = "eh-v1.0"}
> 

Without trying to share the bus, the code compiles in ssd1306 with both stm32f4xx-hal and stm32h7xx-hal using

cargo build --target thumbv7em-none-eabihf --features stm32f4xx-hal --example  text_i2c
cargo build --target thumbv7em-none-eabihf --features stm32h7xx-hal --example  text_i2c

When I try to make changes for sharing the bus (see https://crates.io/crates/embedded-hal-bus and https://github.com/rust-embedded/embedded-hal/blob/master/docs/migrating-from-0.2-to-1.0.md#error-type-bounds ) I cannot get the correct formulation or the proper trait. Commented out in the code are many of the lines I think I need, but I have not had any success with a very large number of attempts. Suggestions would be appreciated.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions