rust-embedded-community / ssd1306

SSD1306 OLED driver
Apache License 2.0
282 stars 69 forks source link

Yet another `DrawTarget` is not implemented for `Ssd1306<SPIInterface<Spi... #187

Closed axoulc closed 1 year ago

axoulc commented 1 year ago

Description of the problem

I'm trying to print "Hello Rust!" on my oled in buffered graphics mode wich already work with a C program. I found other user with the same problem #186 but my font is configured with BinaryColor. I hope that someone can helps me !!

Test case

Code

#![deny(unsafe_code)]
#![no_std]
#![no_main]

use cortex_m_rt::entry;
use display_interface_spi::SPIInterface;
use embedded_graphics::{
    mono_font::{ascii::FONT_6X10, MonoTextStyleBuilder},
    pixelcolor::BinaryColor,
    prelude::*,
    text::{Baseline, Text},
};
use panic_halt as _;
use ssd1306::{prelude::*, Ssd1306};
use stm32f1xx_hal::{
    pac,
    prelude::*,
    spi::{Mode, Phase, Polarity, Spi},
    timer::Timer,
};

#[entry]
fn main() -> ! {
    let cp = cortex_m::Peripherals::take().unwrap();
    let dp = pac::Peripherals::take().unwrap();
    let mut flash = dp.FLASH.constrain();
    let rcc = dp.RCC.constrain();
    let clocks = rcc
        .cfgr
        .use_hse(8.MHz())
        .sysclk(72.MHz())
        .pclk1(36.MHz())
        .freeze(&mut flash.acr);

    let mut afio = dp.AFIO.constrain();
    let mut gpioa = dp.GPIOA.split();
    let mut gpiob = dp.GPIOB.split();

    // SPI1
    let sck = gpioa.pa5.into_alternate_push_pull(&mut gpioa.crl);
    let miso = gpioa.pa6;
    let mosi = gpioa.pa7.into_alternate_push_pull(&mut gpioa.crl);
    let cs = gpioa.pa4.into_push_pull_output(&mut gpioa.crl);
    let mut rst = gpiob.pb9.into_push_pull_output(&mut gpiob.crh);
    let dc = gpiob.pb8.into_push_pull_output(&mut gpiob.crh);

    let mut delay = Timer::syst(cp.SYST, &clocks).delay();

    let spi = Spi::spi1(
        dp.SPI1,
        (sck, miso, mosi),
        &mut afio.mapr,
        Mode {
            polarity: Polarity::IdleLow,
            phase: Phase::CaptureOnFirstTransition,
        },
        8.MHz(),
        clocks,
    );

    let interface = SPIInterface::new(spi, dc, cs);
    let mut display = Ssd1306::new(interface, DisplaySize128x64, DisplayRotation::Rotate0)
        .into_buffered_graphics_mode();

    display.reset(&mut rst, &mut delay).unwrap();
    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 {}
}

Error

error[E0277]: the trait bound `Ssd1306<SPIInterface<Spi<stm32f1xx_hal::pac::SPI1, Spi1NoRemap, (stm32f1xx_hal::gpio::Pin<'A', 5, stm32f1xx_hal::gpio::Alternate>, stm32f1xx_hal::gpio::Pin<'A', 6>, stm32f1xx_hal::gpio::Pin<'A', 7, stm32f1xx_hal::gpio::Alternate>), u8>, stm32f1xx_hal::gpio::Pin<'B', 8, stm32f1xx_hal::gpio::Output>, stm32f1xx_hal::gpio::Pin<'A', 4, stm32f1xx_hal::gpio::Output>>, ssd1306::prelude::DisplaySize128x64, BufferedGraphicsMode<ssd1306::prelude::DisplaySize128x64>>: DrawTarget` is not satisfied
   --> src/main.rs:78:15
    |
78  |         .draw(&mut display)
    |          ---- ^^^^^^^^^^^^ the trait `DrawTarget` is not implemented for `Ssd1306<SPIInterface<Spi<stm32f1xx_hal::pac::SPI1, Spi1NoRemap, (stm32f1xx_hal::gpio::Pin<'A', 5, stm32f1xx_hal::gpio::Alternate>, stm32f1xx_hal::gpio::Pin<'A', 6>, stm32f1xx_hal::gpio::Pin<'A', 7, stm32f1xx_hal::gpio::Alternate>), u8>, stm32f1xx_hal::gpio::Pin<'B', 8, stm32f1xx_hal::gpio::Output>, stm32f1xx_hal::gpio::Pin<'A', 4, stm32f1xx_hal::gpio::Output>>, ssd1306::prelude::DisplaySize128x64, BufferedGraphicsMode<ssd1306::prelude::DisplaySize128x64>>`
    |          |
    |          required by a bound introduced by this call
    |
    = help: the following other types implement trait `DrawTarget`:
              Clipped<'_, T>
              ColorConverted<'_, T, C>
              Cropped<'_, T>
              Framebuffer<C, RawU1, BO, WIDTH, HEIGHT, N>
              Framebuffer<C, RawU16, BigEndian, WIDTH, HEIGHT, N>
              Framebuffer<C, RawU16, LittleEndian, WIDTH, HEIGHT, N>
              Framebuffer<C, RawU2, BO, WIDTH, HEIGHT, N>
              Framebuffer<C, RawU24, BigEndian, WIDTH, HEIGHT, N>
            and 10 others
note: required by a bound in `embedded_graphics::Drawable::draw`
   --> /home/axel-popos/.cargo/registry/src/github.com-1ecc6299db9ec823/embedded-graphics-core-0.4.0/src/drawable.rs:106:12
    |
106 |         D: DrawTarget<Color = Self::Color>;
    |            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `Drawable::draw`

For more information about this error, try `rustc --explain E0277`.
Hidan0 commented 1 year ago

I'm experiencing the same issue with 0.7.1, I fixed it by using the git version.

Cargo.tom

[dependencies]
ssd1306 = { git = "https://github.com/jamwaffles/ssd1306.git", branch = "master" }

I think the problem is compatibility with the version of embedded-graphics, so going back from 0.8.0 to 0.7.1 might be another solution.

axoulc commented 1 year ago

Thanks for your answer !!

I tried but now I have the same problem as #165

error:` linking with `rust-lld` failed: exit status: 1

@Hidan0 Did you have the same problem ?

Hidan0 commented 1 year ago

No I do not, mine is compiling just fine.

This issue could be related to the combination of the crate and the HAL that You're using. As I said, with esp-rs hal, everything is compiling.

Hidan0 commented 1 year ago

The newly released version 1.8.0, does not throw the compile error.

@axoulc You could see if it works with this version and doesn't throw the linking error.

axoulc commented 1 year ago

Yes it works but when I compile it in release mode !

Hidan0 commented 1 year ago

I am also compiling it in release mode, I forgot to mention it... I'm glad that now it is working