update ST7789 spi_display to new mipidsi/display-interface-spi

This commit is contained in:
Georges PALAUQUI 2023-07-16 17:15:22 +02:00
parent 66c2d8ed9f
commit d223ea6ca6
2 changed files with 11 additions and 149 deletions

View File

@ -36,7 +36,6 @@ futures = { version = "0.3.17", default-features = false, features = ["async-awa
mipidsi = { version = "0.7.1", git = "https://github.com/almindor/mipidsi.git" } mipidsi = { version = "0.7.1", git = "https://github.com/almindor/mipidsi.git" }
display-interface-spi = "0.4.1" display-interface-spi = "0.4.1"
embedded-graphics = "0.8.0" embedded-graphics = "0.8.0"
st7789 = "0.6.1"
display-interface = "0.4.1" display-interface = "0.4.1"
byte-slice-cast = { version = "1.2.0", default-features = false } byte-slice-cast = { version = "1.2.0", default-features = false }
smart-leds = "0.3.0" smart-leds = "0.3.0"

View File

@ -10,11 +10,12 @@
use core::cell::RefCell; use core::cell::RefCell;
use defmt::*; use defmt::*;
use display_interface_spi::SPIInterfaceNoCS;
use embassy_embedded_hal::shared_bus::blocking::spi::SpiDeviceWithConfig; use embassy_embedded_hal::shared_bus::blocking::spi::SpiDeviceWithConfig;
use embassy_executor::Spawner; use embassy_executor::Spawner;
use embassy_rp::gpio::{Level, Output}; use embassy_rp::gpio::{Level, Output};
use embassy_rp::spi; use embassy_rp::spi;
use embassy_rp::spi::{Blocking, Spi}; use embassy_rp::spi::Spi;
use embassy_sync::blocking_mutex::raw::NoopRawMutex; use embassy_sync::blocking_mutex::raw::NoopRawMutex;
use embassy_sync::blocking_mutex::Mutex; use embassy_sync::blocking_mutex::Mutex;
use embassy_time::Delay; use embassy_time::Delay;
@ -25,10 +26,9 @@ use embedded_graphics::pixelcolor::Rgb565;
use embedded_graphics::prelude::*; use embedded_graphics::prelude::*;
use embedded_graphics::primitives::{PrimitiveStyleBuilder, Rectangle}; use embedded_graphics::primitives::{PrimitiveStyleBuilder, Rectangle};
use embedded_graphics::text::Text; use embedded_graphics::text::Text;
use st7789::{Orientation, ST7789}; use mipidsi::{Builder, Orientation};
use {defmt_rtt as _, panic_probe as _}; use {defmt_rtt as _, panic_probe as _};
use crate::my_display_interface::SPIDeviceInterface;
use crate::touch::Touch; use crate::touch::Touch;
const DISPLAY_FREQ: u32 = 64_000_000; const DISPLAY_FREQ: u32 = 64_000_000;
@ -59,7 +59,7 @@ async fn main(_spawner: Spawner) {
touch_config.phase = spi::Phase::CaptureOnSecondTransition; touch_config.phase = spi::Phase::CaptureOnSecondTransition;
touch_config.polarity = spi::Polarity::IdleHigh; touch_config.polarity = spi::Polarity::IdleHigh;
let spi: Spi<'_, _, Blocking> = Spi::new_blocking(p.SPI1, clk, mosi, miso, touch_config.clone()); let spi = Spi::new_blocking(p.SPI1, clk, mosi, miso, touch_config.clone());
let spi_bus: Mutex<NoopRawMutex, _> = Mutex::new(RefCell::new(spi)); let spi_bus: Mutex<NoopRawMutex, _> = Mutex::new(RefCell::new(spi));
let display_spi = SpiDeviceWithConfig::new(&spi_bus, Output::new(display_cs, Level::High), display_config); let display_spi = SpiDeviceWithConfig::new(&spi_bus, Output::new(display_cs, Level::High), display_config);
@ -75,16 +75,14 @@ async fn main(_spawner: Spawner) {
let _bl = Output::new(bl, Level::High); let _bl = Output::new(bl, Level::High);
// display interface abstraction from SPI and DC // display interface abstraction from SPI and DC
let di = SPIDeviceInterface::new(display_spi, dcx); let di = SPIInterfaceNoCS::new(display_spi, dcx);
// create driver // Define the display from the display interface and initialize it
let mut display = ST7789::new(di, rst, 240, 320); let mut display = Builder::st7789(di)
.with_display_size(240, 240)
// initialize .with_orientation(Orientation::Landscape(true))
display.init(&mut Delay).unwrap(); .init(&mut Delay, Some(rst))
.unwrap();
// set default orientation
display.set_orientation(Orientation::Landscape).unwrap();
display.clear(Rgb565::BLACK).unwrap(); display.clear(Rgb565::BLACK).unwrap();
@ -176,138 +174,3 @@ mod touch {
} }
} }
} }
mod my_display_interface {
use display_interface::{DataFormat, DisplayError, WriteOnlyDataCommand};
use embedded_hal_1::digital::OutputPin;
use embedded_hal_1::spi::SpiDevice;
/// SPI display interface.
///
/// This combines the SPI peripheral and a data/command pin
pub struct SPIDeviceInterface<SPI, DC> {
spi: SPI,
dc: DC,
}
impl<SPI, DC> SPIDeviceInterface<SPI, DC>
where
SPI: SpiDevice,
DC: OutputPin,
{
/// Create new SPI interface for communciation with a display driver
pub fn new(spi: SPI, dc: DC) -> Self {
Self { spi, dc }
}
}
impl<SPI, DC> WriteOnlyDataCommand for SPIDeviceInterface<SPI, DC>
where
SPI: SpiDevice,
DC: OutputPin,
{
fn send_commands(&mut self, cmds: DataFormat<'_>) -> Result<(), DisplayError> {
// 1 = data, 0 = command
self.dc.set_low().map_err(|_| DisplayError::DCError)?;
send_u8(&mut self.spi, cmds).map_err(|_| DisplayError::BusWriteError)?;
Ok(())
}
fn send_data(&mut self, buf: DataFormat<'_>) -> Result<(), DisplayError> {
// 1 = data, 0 = command
self.dc.set_high().map_err(|_| DisplayError::DCError)?;
send_u8(&mut self.spi, buf).map_err(|_| DisplayError::BusWriteError)?;
Ok(())
}
}
fn send_u8<T: SpiDevice>(spi: &mut T, words: DataFormat<'_>) -> Result<(), T::Error> {
match words {
DataFormat::U8(slice) => spi.write(slice),
DataFormat::U16(slice) => {
use byte_slice_cast::*;
spi.write(slice.as_byte_slice())
}
DataFormat::U16LE(slice) => {
use byte_slice_cast::*;
for v in slice.as_mut() {
*v = v.to_le();
}
spi.write(slice.as_byte_slice())
}
DataFormat::U16BE(slice) => {
use byte_slice_cast::*;
for v in slice.as_mut() {
*v = v.to_be();
}
spi.write(slice.as_byte_slice())
}
DataFormat::U8Iter(iter) => {
let mut buf = [0; 32];
let mut i = 0;
for v in iter.into_iter() {
buf[i] = v;
i += 1;
if i == buf.len() {
spi.write(&buf)?;
i = 0;
}
}
if i > 0 {
spi.write(&buf[..i])?;
}
Ok(())
}
DataFormat::U16LEIter(iter) => {
use byte_slice_cast::*;
let mut buf = [0; 32];
let mut i = 0;
for v in iter.map(u16::to_le) {
buf[i] = v;
i += 1;
if i == buf.len() {
spi.write(&buf.as_byte_slice())?;
i = 0;
}
}
if i > 0 {
spi.write(&buf[..i].as_byte_slice())?;
}
Ok(())
}
DataFormat::U16BEIter(iter) => {
use byte_slice_cast::*;
let mut buf = [0; 64];
let mut i = 0;
let len = buf.len();
for v in iter.map(u16::to_be) {
buf[i] = v;
i += 1;
if i == len {
spi.write(&buf.as_byte_slice())?;
i = 0;
}
}
if i > 0 {
spi.write(&buf[..i].as_byte_slice())?;
}
Ok(())
}
_ => unimplemented!(),
}
}
}