Closed lll9p closed 3 years ago
I believe you're missing a type in the definition of DISP
:
use display_interface_i2c::I2CInterface;
type Display = ssd1306::mode::graphics::GraphicsMode<
I2CInterface<
stm32f1xx_hal::i2c::BlockingI2c<
stm32f1xx_hal::pac::I2C1,
(
stm32f1xx_hal::gpio::gpiob::PB8<stm32f1xx_hal::gpio::Alternate<OpenDrain>>,
stm32f1xx_hal::gpio::gpiob::PB9<stm32f1xx_hal::gpio::Alternate<OpenDrain>>,
),
>,
>,
>;
The display mode structs don't take a raw interface anymore - they're wrapped in implementors of the display_interface crate like display-interface-i2c.
I haven't tested this on hardware, but it does compile. You'll need to add the display_interface_i2c
crate to your Cargo.toml
if you haven't already.
Thank you for your reply! @jamwaffles
Follow your description, I make a minimal example about it.
The codes below does compile.
// #![deny(unsafe_code)]
#![allow(unused)]
#![no_main]
#![no_std]
use panic_halt as _;
use crate::hal::{
gpio::OpenDrain,
i2c::{BlockingI2c, DutyCycle, Mode},
prelude::*,
};
use core::{
cell::{Cell, RefCell},
fmt::Write,
};
use cortex_m::interrupt::{free, Mutex};
use cortex_m_rt::{entry, exception, ExceptionFrame};
use display_interface_i2c::I2CInterface;
use embedded_graphics::{
fonts::{Font6x12, Font6x6, Font6x8, Font8x16, Text},
pixelcolor::BinaryColor,
prelude::*,
style::TextStyleBuilder,
};
use ssd1306::{prelude::*, Builder, I2CDIBuilder};
use stm32f1xx_hal as hal;
type DISP = ssd1306::mode::graphics::GraphicsMode<
I2CInterface<
stm32f1xx_hal::i2c::BlockingI2c<
stm32f1xx_hal::pac::I2C1,
(
stm32f1xx_hal::gpio::gpiob::PB8<stm32f1xx_hal::gpio::Alternate<OpenDrain>>,
stm32f1xx_hal::gpio::gpiob::PB9<stm32f1xx_hal::gpio::Alternate<OpenDrain>>,
),
>,
>,
>;
// static _DISP: Mutex<RefCell<Option<DISP>>> = Mutex::new(RefCell::new(None));
#[entry]
fn main() -> ! {
let device = stm32f1::stm32f103::Peripherals::take().unwrap();
let mut core = cortex_m::peripheral::Peripherals::take().unwrap();
core.DCB.enable_trace();
core.DWT.enable_cycle_counter();
let mut flash = device.FLASH.constrain();
let mut rcc = device.RCC.constrain();
let clocks = rcc.cfgr.sysclk(32.mhz()).freeze(&mut flash.acr);
// Prepare the alternate function I/O registers
let mut afio = device.AFIO.constrain(&mut rcc.apb2);
let mut gpioa = device.GPIOA.split(&mut rcc.apb2);
let mut gpiob = device.GPIOB.split(&mut rcc.apb2);
// I2C Config
let scl = gpiob.pb8.into_alternate_open_drain(&mut gpiob.crh);
let sda = gpiob.pb9.into_alternate_open_drain(&mut gpiob.crh);
let i2c = BlockingI2c::i2c1(
device.I2C1,
(scl, sda),
&mut afio.mapr,
Mode::Fast {
frequency: 400_000.hz(),
duty_cycle: DutyCycle::Ratio2to1,
},
clocks,
&mut rcc.apb1,
1000,
10,
1000,
1000,
);
let interface = I2CDIBuilder::new().init(i2c);
let mut disp: GraphicsMode<_> = Builder::new().connect(interface).into();
disp.init().unwrap();
// make Mutexes
// free(|cs| {
// _DISP.borrow(cs).replace(Some(disp));
// });
loop {}
}
But after I changed
let mut disp: GraphicsMode<_> = Builder::new().connect(interface).into();
to
let mut disp: DISP = Builder::new().connect(interface).into();
And the code dosent compile, how do I fix this? Thanks again!
Hm... that's strange. The error I get is this:
|
81 | let mut disp: DISP = Builder::new().connect(interface).into();
| ^^^^ the trait `ssd1306::mode::displaymode::DisplayModeTrait<impl display_interface::WriteOnlyDataCommand, ssd1306::displaysize::DisplaySize128x64>` is not implemented for `ssd1306::mode::graphics::GraphicsMode<display_interface_i2c::I2CInterface<stm32f1xx_hal::i2c::BlockingI2c<stm32f1::stm32f103::I2C1, (stm32f1xx_hal::gpio::gpiob::PB8<stm32f1xx_hal::gpio::Alternate<stm32f1xx_hal::gpio::OpenDrain>>, stm32f1xx_hal::gpio::gpiob::PB9<stm32f1xx_hal::gpio::Alternate<stm32f1xx_hal::gpio::OpenDrain>>)>>>`
|
= help: the following implementations were found:
<ssd1306::mode::graphics::GraphicsMode<DI, DSIZE> as ssd1306::mode::displaymode::DisplayModeTrait<DI, DSIZE>>
Is that the same as yours? I'm not sure how to fix this, but in the meantime I think it's fine to just do let mut disp: GraphicsMode<_> = Builder::new().connect(interface).into();
. What's stopping you doing that?
@therealprof Any ideas here? I don't think it's related to the display-interface
crates but might be worth checking.
It seems auto-coercion doesn't work with impl type
returns.
After this change it seems to work:
diff --git a/src/builder.rs b/src/builder.rs
index 79794c2..87e7f7c 100644
--- a/src/builder.rs
+++ b/src/builder.rs
@@ -160,7 +160,7 @@ impl I2CDIBuilder {
/// Finish the builder and return an initialised display interface for further use
///
/// This method consumes the builder and must come last in the method call chain
- pub fn init<I: hal::blocking::i2c::Write>(self, i2c: I) -> impl WriteOnlyDataCommand {
+ pub fn init<I: hal::blocking::i2c::Write>(self, i2c: I) -> display_interface_i2c::I2CInterface<I> {
display_interface_i2c::I2CInterface::new(i2c, self.i2c_addr, 0x40)
}
}
@jamwaffles @therealprof
Yes, it is impl type
issue, after changing code in builder, example code work as expect, thank you.
Funny overlap, just issued a PR with that change. ;)
Thanks for confirming.
ssd1306
in use (if applicable): Master branch of github.Description of the problem/feature request/other
Can not determin type of display interface, I want to use display in critical sections, But not working, what can I do about it ,Thanks!
......
......
Compile appears errors.