esp-rs/esp-idf-hal

SPI Driver apparently not working as expected

igorgsouza opened this issue · 1 comments

I'm attempting to communicate between my esp32 and an ili9341 via SPI, however it seems none of the commands I send actually do anything. After testing a 'demo' code without the std I'm being led to believe there is something

The following is the current code using the std:

use std::time::Duration;

use display_interface_spi::SPIInterface;
use embedded_graphics::{pixelcolor::Rgb565, prelude::*};
use esp_idf_hal::{
    delay::Ets,
    gpio::PinDriver,
    peripherals::Peripherals,
    spi::{config::*, SpiDeviceDriver, SpiDriver, SpiDriverConfig, SPI2},
};
use esp_idf_sys as _;

use mipidsi::Builder;

fn main() -> anyhow::Result<(), Box<dyn std::error::Error>> {
    esp_idf_hal::sys::link_patches();

    let peripherals: Peripherals = Peripherals::take()?;

    let mut delay = Ets;

    let dc = PinDriver::input_output_od(peripherals.pins.gpio2)?;
    let mut rst = PinDriver::input_output_od(peripherals.pins.gpio4)?;
    rst.set_high()?;

    let sck = peripherals.pins.gpio18;
    let miso = peripherals.pins.gpio19;
    let mosi = peripherals.pins.gpio23;
    let cs = peripherals.pins.gpio15;

    let spi = SpiDriver::new::<SPI2>(
        peripherals.spi2,
        sck,
        mosi,
        Some(miso),
        &SpiDriverConfig::new(),
    )?;

    let spi_device = SpiDeviceDriver::new(spi, Some(cs), &Config::new())?;

    let di = SPIInterface::new(spi_device, dc);

    let mut display = Builder::new(mipidsi::models::ILI9341Rgb565, di)
        .reset_pin(rst)
        .init(&mut delay)
        .unwrap();

    display.clear(Rgb565::BLACK).unwrap();

    loop {
        std::thread::sleep(Duration::from_millis(100));
    }
}

with non-std I have:

#![no_std]
#![no_main]

use embedded_hal_bus::spi::ExclusiveDevice;
use esp_backtrace as _;
use hal::{
    clock::ClockControl,
    delay::Delay,
    gpio::{IO, NO_PIN},
    peripherals::Peripherals,
    prelude::*,
    rtc_cntl::Rtc,
    spi::{master::Spi, SpiMode},
    timer::TimerGroup,
};

use embedded_graphics::{pixelcolor::Rgb565, prelude::*};

use display_interface_spi::SPIInterface;

use mipidsi::{models::ILI9341Rgb565, Builder};

use fugit::RateExtU32;

#[entry]
fn main() -> ! {
    let peripherals = Peripherals::take();
    let system = peripherals.SYSTEM.split();
    let clocks = ClockControl::boot_defaults(system.clock_control).freeze();
    let io = IO::new(peripherals.GPIO, peripherals.IO_MUX);

    let mut rtc = Rtc::new(peripherals.LPWR, None);
    let timer_group0 = TimerGroup::new(peripherals.TIMG0, &clocks, None);
    let mut wdt0 = timer_group0.wdt;
    let timer_group1 = TimerGroup::new(peripherals.TIMG1, &clocks, None);
    let mut wdt1 = timer_group1.wdt;
    rtc.rwdt.disable();
    wdt0.disable();
    wdt1.disable();

    let mut delay = Delay::new(&clocks);

    let dc = io.pins.gpio2.into_push_pull_output();
    let mut rst = io.pins.gpio4.into_push_pull_output();
    rst.set_high();

    let sck = io.pins.gpio18;
    let miso = io.pins.gpio19;
    let mosi = io.pins.gpio23;
    let cs = io.pins.gpio15;

    let spi = Spi::new(peripherals.SPI2, 1.MHz(), SpiMode::Mode0, &clocks).with_pins(
        Some(sck),
        Some(mosi),
        Some(miso),
        NO_PIN,
    );

    let spi_device = ExclusiveDevice::new_no_delay(spi, cs.into_push_pull_output()).unwrap();

    let di = SPIInterface::new(spi_device, dc);

    let mut display = Builder::new(ILI9341Rgb565, di)
        .reset_pin(rst)
        .init(&mut delay)
        .unwrap();

    display.clear(Rgb565::BLUE).unwrap();

    loop {
    }
}

The non-std code works as expected, which makes me beliece there is a mistake in the SpiDeviceDriver and SpiDriver objects, however after reading all the docs I could I did not find the mistake in my implementation, therefore I am wondering if there is a bug in those classes.

Closing it, it was my mistake, the dc and rst pin were input_output_od and should only be output.