Spi instance is of type unknown, although its parameters should be ok? What am I doing wrong?

Hello, I am trying to set up an spi connection to drive an oled with ssd1315. In order to do that I need to create an spi instance, which I need to pass to an ssd1315::interface::SpiDisplayInterface.

When I create the spi instance and I check its type, I get unknown ... :frowning: I don't know what I am doing wrong. This is even before I am passing it to the ssd1315::interface.

#![no_std]
#![no_main]
#![allow(unused_variables)]
// #![allow(unused_imports)]

use esp_backtrace as _;
use esp_hal::{
    clock::ClockControl,
    delay::Delay,
    gpio::{Io, Level, OutputOpenDrain, Pull, NO_PIN},
    peripherals::Peripherals,
    prelude::*,
    spi::master::Spi,
    spi::SpiMode,
    system::SystemControl,
};

use ssd1315::interface::SpiDisplayInterface;

#[entry]
fn main() -> ! {
    let peripherals = Peripherals::take();
    let system = SystemControl::new(peripherals.SYSTEM);

    let clocks = ClockControl::max(system.clock_control).freeze();
    // let delay = Delay::new(&clocks);

    let io = Io::new(peripherals.GPIO, peripherals.IO_MUX);

    esp_println::logger::init_logger_from_env();

    // mosi gpio11
    // miso gpio13
    // sck gpio12
    // ss gpio10

    let mosi = io.pins.gpio11; // sda = mosi gpio11
    let sdc = io.pins.gpio12; // sdc = sclk / clock
    let dc = OutputOpenDrain::new(io.pins.gpio3, Level::Low, Pull::Down);
    let cs = io.pins.gpio10;

    let spi = Spi::new(peripherals.SPI2, 100.kHz(), SpiMode::Mode0, &clocks).with_pins(
        Some(sdc),
        Some(mosi),
        NO_PIN,
        Some(cs),
    );

    let interface = SpiDisplayInterface::new_interface(spi, dc);

    loop {
        log::info!("Hello world!");
    }
}

Don't trust the IDE. Does it compile?

2 Likes

No. @paramagnetic I get embedded_hal::spi::SpiDevice is not satisfied.

error[E0277]: the trait bound `esp_hal::spi::master::Spi<'_, esp_hal::peripherals::SPI2, FullDuplexMode>: embedded_hal::spi::SpiDevice` is not satisfied
  --> src/main.rs:49:56
   |
49 |     let interface = SpiDisplayInterface::new_interface(spi, dc);
   |                     ---------------------------------- ^^^ the trait `embedded_hal::spi::SpiDevice` is not implemented for `esp_hal::spi::master::Spi<'_, esp_hal::peripherals::SPI2, FullDuplexMode>`
   |                     |
   |                     required by a bound introduced by this call
   |
   = help: the trait `embedded_hal::spi::SpiDevice<Word>` is implemented for `&mut T`
note: required by a bound in `SpiDisplayInterface::new_interface`
  --> /home/alex/.cargo/registry/src/index.crates.io-6f17d22bba15001f/ssd1315-0.2.0/src/interface.rs:32:29
   |
32 |     pub fn new_interface<S: SpiDevice, DC: OutputPin>(spi: S, dc: DC) -> SPIInterface<S, DC> {
   |                             ^^^^^^^^^ required by this bound in `SpiDisplayInterface::new_interface`

When I do a type_of_val(spi) I get the following:

the type of spi: esp_hal::spi::master::Spi<esp_hal::soc::implementation::peripherals::peripherals::SPI2, esp_hal::spi::FullDuplexMode>

But when I look at the dependencies I see that the esp_hal I am using, is using embedded_hal 0.2.7, and the ssd1315 is using embedded_hal 1.0.0. So therefore I won't be able to use this I assume?

Is there a work-around? Or should I rewrite the ssd1315 using the embedded_had 0.2.7, until the esp_hal is upgraded to use the newer embedded_hal?

Is there a way to bypass the esp_hal's limitation?

Thank you.

Alex

you are experiencing semver incompatibility

as i see it, there are only three possibilities:

  1. make your code use the old version
  2. make the library use the new version (try forking it, bumping the version, and running the unit tests, there's a chance it Just Works if none of the breaking changes actually affected it)
  3. use a newtype wrapper to implement the old traits on the new type (last resort, not reccomended, extremely hacky, will require obscure cargo features)
2 Likes

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.