rust-embedded-community / ssd1306

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

ssd1306 with rtic 1.0.0 #164

Open pdgilbert opened 2 years ago

pdgilbert commented 2 years ago

(some relationship with #162.)

Description of the problem/feature request/other

I am trying to use ssd1306 with rtic v1.0.0 and am stuck on two errors. One is a trait problem with the draw method trying to write on the display

Click to expand ``` Compiling test-example v0.1.0 (/home/paul/githubClones/rust-integration-testing/dev-testing) error[E0599]: the method `draw` exists for struct `Text<'_, &mut embedded_graphics::mono_font::MonoTextStyle<'static, embedded_graphics::pixelcolor::BinaryColor>>`, but its trait bounds were not satisfied --> examples/zzdisplay_stuff_rtic.rs:123:15 | 123 | ).draw(&mut cx.local.display).unwrap(); | ^^^^ method cannot be called on `Text<'_, &mut embedded_graphics::mono_font::MonoTextStyle<'static, embedded_graphics::pixelcolor::BinaryColor>>` due to unsatisfied trait bounds | ::: /home/paul/.cargo/registry/src/github.com-1ecc6299db9ec823/embedded-graphics-0.7.1/src/text/text.rs:23:1 | 23 | pub struct Text<'a, S> { | ---------------------- | | | doesn't satisfy `<_ as Iterator>::Item = Pixel<_>` | doesn't satisfy `_: Iterator` | doesn't satisfy `_: embedded_graphics::Drawable` | doesn't satisfy `_: embedded_graphics::iterator::PixelIteratorExt<_>` | = note: the following trait bounds were not satisfied: `> as Iterator>::Item = Pixel<_>` which is required by `Text<'_, &mut embedded_graphics::mono_font::MonoTextStyle<'static, embedded_graphics::pixelcolor::BinaryColor>>: embedded_graphics::iterator::PixelIteratorExt<_>` `Text<'_, &mut embedded_graphics::mono_font::MonoTextStyle<'static, embedded_graphics::pixelcolor::BinaryColor>>: Iterator` which is required by `Text<'_, &mut embedded_graphics::mono_font::MonoTextStyle<'static, embedded_graphics::pixelcolor::BinaryColor>>: embedded_graphics::iterator::PixelIteratorExt<_>` `<&Text<'_, &mut embedded_graphics::mono_font::MonoTextStyle<'static, embedded_graphics::pixelcolor::BinaryColor>> as Iterator>::Item = Pixel<_>` which is required by `&Text<'_, &mut embedded_graphics::mono_font::MonoTextStyle<'static, embedded_graphics::pixelcolor::BinaryColor>>: embedded_graphics::iterator::PixelIteratorExt<_>` `&Text<'_, &mut embedded_graphics::mono_font::MonoTextStyle<'static, embedded_graphics::pixelcolor::BinaryColor>>: Iterator` which is required by `&Text<'_, &mut embedded_graphics::mono_font::MonoTextStyle<'static, embedded_graphics::pixelcolor::BinaryColor>>: embedded_graphics::iterator::PixelIteratorExt<_>` `&mut embedded_graphics::mono_font::MonoTextStyle<'static, embedded_graphics::pixelcolor::BinaryColor>: TextRenderer` which is required by `Text<'_, &mut embedded_graphics::mono_font::MonoTextStyle<'static, embedded_graphics::pixelcolor::BinaryColor>>: embedded_graphics::Drawable` `<&mut Text<'_, &mut embedded_graphics::mono_font::MonoTextStyle<'static, embedded_graphics::pixelcolor::BinaryColor>> as Iterator>::Item = Pixel<_>` which is required by `&mut Text<'_, &mut embedded_graphics::mono_font::MonoTextStyle<'static, embedded_graphics::pixelcolor::BinaryColor>>: embedded_graphics::iterator::PixelIteratorExt<_>` `&mut Text<'_, &mut embedded_graphics::mono_font::MonoTextStyle<'static, embedded_graphics::pixelcolor::BinaryColor>>: Iterator` which is required by `&mut Text<'_, &mut embedded_graphics::mono_font::MonoTextStyle<'static, embedded_graphics::pixelcolor::BinaryColor>>: embedded_graphics::iterator::PixelIteratorExt<_>` ```

The other is a problem with something not being thread safe.

Click to expand ``` error[E0277]: `(dyn GlyphMapping + 'static)` cannot be shared between threads safely --> examples/zzdisplay_stuff_rtic.rs:15:35 | 15 | #[cfg_attr(feature = "stm32f4xx", app(device = stm32f4xx_hal::pac, dispatchers = [TIM2, TIM3]))] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `(dyn GlyphMapping + 'static)` cannot be shared between threads safely | = help: within `MonoFont<'static>`, the trait `Sync` is not implemented for `(dyn GlyphMapping + 'static)` = note: required because it appears within the type `&'static (dyn GlyphMapping + 'static)` = note: required because it appears within the type `MonoFont<'static>` = note: required because of the requirements on the impl of `Send` for `&'static MonoFont<'static>` = note: required because it appears within the type `embedded_graphics::mono_font::MonoTextStyle<'static, embedded_graphics::pixelcolor::BinaryColor>` note: required by a bound in `assert_send` --> /home/paul/.cargo/registry/src/github.com-1ecc6299db9ec823/cortex-m-rtic-1.0.0/src/export.rs:107:8 | 107 | T: Send, | ^^^^ required by this bound in `assert_send` = note: this error originates in the attribute macro `app` (in Nightly builds, run with -Z macro-backtrace for more info) ```

I do have a similar non-rtic example working with stm32f4xx_hal , so this is an rtic specific problem.

Test case

Click to expand code ``` //! Display the word "stuff" on OLED with i2c. Using stm32f4xx_hal #![deny(unsafe_code)] #![no_std] #![no_main] #[cfg(debug_assertions)] use panic_semihosting as _; #[cfg(not(debug_assertions))] use panic_halt as _; use rtic::app; #[cfg_attr(feature = "stm32f4xx", app(device = stm32f4xx_hal::pac, dispatchers = [TIM2, TIM3]))] mod app { //use cortex_m_semihosting::{debug, hprintln}; use cortex_m_semihosting::{hprintln}; use core::fmt::Write; use embedded_graphics::{ mono_font::{iso_8859_1::FONT_10X20, MonoTextStyleBuilder, MonoTextStyle}, //FONT_6X10 FONT_8X13 pixelcolor::BinaryColor, prelude::*, text::{Baseline, Text}, }; use ssd1306::{mode::BufferedGraphicsMode, prelude::*, I2CDisplayInterface, Ssd1306}; use systick_monotonic::*; const MONOTICK: u32 = 100; const READ_INTERVAL: u64 = 10; // used as seconds use shared_bus::{I2cProxy}; use core::cell::RefCell; use cortex_m::interrupt::Mutex; use stm32f4xx_hal::{ gpio::{Alternate, OpenDrain, gpiob::{PB8, PB9, }, }, i2c::I2c, pac::{Peripherals, I2C1}, prelude::*, }; pub type I2c1Type = I2c>, PB9>)>; const MONOCLOCK: u32 = 16_000_000; //should be set for board not for HAL fn setup(dp: Peripherals) -> I2c1Type { 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 i2c = I2c::new(dp.I2C1, (scl, sda), 400.khz(), &clocks); i2c } #[monotonic(binds = SysTick, default = true)] type MyMono = Systick; #[init] fn init(cx: init::Context) -> (Shared, Local, init::Monotonics) { let mono = Systick::new(cx.core.SYST, MONOCLOCK); let i2c = setup(cx.device); let manager: &'static _ = shared_bus::new_cortexm!(I2c1Type = i2c).unwrap(); let interface = I2CDisplayInterface::new(manager.acquire_i2c()); let text_style = MonoTextStyleBuilder::new().font(&FONT_10X20).text_color(BinaryColor::On).build(); let mut display = Ssd1306::new(interface, DisplaySize128x64, DisplayRotation::Rotate0) .into_buffered_graphics_mode(); display.init().unwrap(); hprintln!("display.init",).unwrap(); Text::with_baseline("Display initialized ...", Point::zero(), text_style, Baseline::Top, ) .draw(&mut display).unwrap(); display_stuff::spawn().unwrap(); (Shared {}, Local { display, text_style }, init::Monotonics(mono)) } #[shared] struct Shared {} #[local] struct Local { display: Ssd1306>>>, ssd1306::prelude::DisplaySize128x64, BufferedGraphicsMode>, text_style: MonoTextStyle<'static, BinaryColor>, } #[task(shared = [], local = [display, text_style,], capacity=2)] fn display_stuff(cx: display_stuff::Context) { let mut lines: [heapless::String<32>; 1] = [ heapless::String::new(), ]; write!(lines[0], "stuff").unwrap(); cx.local.display.clear(); for i in 0..lines.len() { // start from 0 requires that the top is used for font baseline Text::with_baseline( &lines[i], Point::new(0, i as i32 * 12), //with font 6x10, 12 = 10 high + 2 space cx.local.text_style, Baseline::Top, ).draw(&mut cx.local.display).unwrap(); } cx.local.display.flush().unwrap(); display_stuff::spawn_after(READ_INTERVAL.secs()).unwrap(); } } ```
Click to expand Cargo.toml ``` [package] authors = ["Paul"] categories = ["embedded", "no-std"] description = "test example" keywords = ["driver", "i2c", "spi", "example"] license = "MIT OR Apache-2.0" name = "test-example" version = "0.1.0" edition = "2021" [dependencies] stm32f4xx-hal = { git = "https://github.com/stm32-rs/stm32f4xx-hal", optional = true } ssd1306 = { git = "https://github.com/jamwaffles/ssd1306" } cortex-m-rtic = ">=1.0" #cortex-m-rtic = { git = "https://github.com/rtic-rs/cortex-m-rtic" } systick-monotonic = {version = "1.0.0", optional = true } #systick-monotonic = { git = "https://github.com/rtic-rs/systick-monotonic.git", optional = true } #dwt-systick-monotonic = "1.0" # this seems to be needed for adc_dma_rtic fiddling embedded-hal = {version = "^0.2.4" } #embedded-hal = { version = "1.0.0-alpha.6,<1.0.0-alpha.7", package = "embedded-hal" } embedded-graphics = ">=0.7" #shared-bus = { version = "0.2.2", features = ["cortex-m"] } shared-bus = { git = "https://github.com/Rahix/shared-bus", features = ["cortex-m"] } heapless = "0.7" nb = ">=0.1.2" libm = "0.2" cortex-m = ">=0.7" cortex-m-rt = ">=0.7.0" cortex-m-semihosting = { version = "0.3.7" } panic-semihosting = { version = ">=0.5.2" } panic-reset = { version = ">=0.1.0" } panic-halt = { version = ">=0.2.0" } [features] stm32f4xx = ["stm32f4xx-hal/rt", "systick-monotonic"] stm32f411 = ["stm32f4xx-hal/stm32f411" ] ```
jamwaffles commented 2 years ago

Thanks for the detailed issue! I don't have much spare time at the moment but I'll look at reproducing your issue when I can :)

afternoon commented 1 year ago

I'm trying to do something similar to the above code. The problem seems to come from passing the embedded_graphics MonoFontStyle value as a resource, which isn't an issue with this crate.

A workaround is to build the text style in the task itself.

pdgilbert commented 1 year ago

Thanks @afternoon for pointing out this workaround. I have now re-enabled ssd1306 code in several examples and all are compiling. I'll get around to testing on hardware sometime soon.

snorkman88 commented 6 months ago

@pdgilbert I am also using the Blackpill board which is based on that STM32F411CEU6 and RTIC v2.0. Have you managed to make it work? Can you share a sample code?

pdgilbert commented 6 months ago

I have made this work with RTIC v1 (cortex-m-rtic = ">=1.0"). I have several examples at https://github.com/pdgilbert/rust-integration-testing. See directory examples/. I have just started playing withRTIC v2 but am running into problems compiling rtic with embedded-hal 1.0.0-rc.2. See https://github.com/rtic-rs/rtic/issues/862.

pdgilbert commented 6 months ago

I have now compiled examples using RTIC v2 and stm32f4xx_hal with both embedded-hal 1.0.0-rc2 and a fork using rc3. These are in the eh-1-rc2 and eh-1-rc3 branches at https://github.com/pdgilbert/rust-integration-testing. (See the CI testing in Actions.) I have also run tested one example on hardware. This all uses the stm32f4xx_hal dual support for embedded-hal 1.0.0 as well as an older version. That means user code and rtic can use embedded-hal 1.0.0 while ssd1306 uses embedded-hal 0.2.7. The tree for this is pretty ugly. I think it must be considered a transition solution and I look forward to an ssd1306 crate based on embedded-hal 1.0.0 .

pdgilbert commented 6 months ago

It seems likely that rtic v1.x.x will be abandoned with the release of embedded-hal 1.0.0. Users really should convert to rtic v2. (This needs to be emphasized given this old issue title "ssd1306 with rtic 1.0.0".)