mirror of
https://github.com/embassy-rs/embassy.git
synced 2024-11-25 08:12:30 +00:00
add second example fo SPI display on RP
This commit is contained in:
parent
5b07507709
commit
fb004fb6e2
@ -45,6 +45,7 @@ byte-slice-cast = { version = "1.2.0", default-features = false }
|
|||||||
smart-leds = "0.4.0"
|
smart-leds = "0.4.0"
|
||||||
heapless = "0.8"
|
heapless = "0.8"
|
||||||
usbd-hid = "0.8.1"
|
usbd-hid = "0.8.1"
|
||||||
|
rand_core = "0.6.4"
|
||||||
|
|
||||||
embedded-hal-1 = { package = "embedded-hal", version = "1.0" }
|
embedded-hal-1 = { package = "embedded-hal", version = "1.0" }
|
||||||
embedded-hal-async = "1.0"
|
embedded-hal-async = "1.0"
|
||||||
|
126
examples/rp/src/bin/spi_gc9a01.rs
Normal file
126
examples/rp/src/bin/spi_gc9a01.rs
Normal file
@ -0,0 +1,126 @@
|
|||||||
|
//! This example shows how to use SPI (Serial Peripheral Interface) in the RP2040 chip.
|
||||||
|
//!
|
||||||
|
//! Example written for a display using the GC9A01 chip. Possibly the Waveshare RP2040-LCD-1.28
|
||||||
|
//! (https://www.waveshare.com/wiki/RP2040-LCD-1.28)
|
||||||
|
|
||||||
|
#![no_std]
|
||||||
|
#![no_main]
|
||||||
|
|
||||||
|
use core::cell::RefCell;
|
||||||
|
|
||||||
|
use defmt::*;
|
||||||
|
use display_interface_spi::SPIInterface;
|
||||||
|
use embassy_embedded_hal::shared_bus::blocking::spi::SpiDeviceWithConfig;
|
||||||
|
use embassy_executor::Spawner;
|
||||||
|
use embassy_rp::clocks::RoscRng;
|
||||||
|
use embassy_rp::gpio::{Level, Output};
|
||||||
|
use embassy_rp::spi;
|
||||||
|
use embassy_rp::spi::{Blocking, Spi};
|
||||||
|
use embassy_sync::blocking_mutex::raw::NoopRawMutex;
|
||||||
|
use embassy_sync::blocking_mutex::Mutex;
|
||||||
|
use embassy_time::{Delay, Duration, Timer};
|
||||||
|
use embedded_graphics::image::{Image, ImageRawLE};
|
||||||
|
use embedded_graphics::pixelcolor::Rgb565;
|
||||||
|
use embedded_graphics::prelude::*;
|
||||||
|
use embedded_graphics::primitives::{PrimitiveStyleBuilder, Rectangle};
|
||||||
|
use mipidsi::models::GC9A01;
|
||||||
|
use mipidsi::options::{ColorOrder, ColorInversion};
|
||||||
|
use mipidsi::Builder;
|
||||||
|
use rand_core::RngCore;
|
||||||
|
use {defmt_rtt as _, panic_probe as _};
|
||||||
|
|
||||||
|
const DISPLAY_FREQ: u32 = 64_000_000;
|
||||||
|
const LCD_X_RES: i32 = 240;
|
||||||
|
const LCD_Y_RES: i32 = 240;
|
||||||
|
const FERRIS_WIDTH: u32 = 86;
|
||||||
|
const FERRIS_HEIGHT: u32 = 64;
|
||||||
|
|
||||||
|
#[embassy_executor::main]
|
||||||
|
async fn main(_spawner: Spawner) {
|
||||||
|
let p = embassy_rp::init(Default::default());
|
||||||
|
let mut rng = RoscRng;
|
||||||
|
|
||||||
|
info!("Hello World!");
|
||||||
|
|
||||||
|
let bl = p.PIN_25;
|
||||||
|
let rst = p.PIN_12;
|
||||||
|
let display_cs = p.PIN_9;
|
||||||
|
let dcx = p.PIN_8;
|
||||||
|
let mosi = p.PIN_11;
|
||||||
|
let clk = p.PIN_10;
|
||||||
|
|
||||||
|
// create SPI
|
||||||
|
let mut display_config = spi::Config::default();
|
||||||
|
display_config.frequency = DISPLAY_FREQ;
|
||||||
|
display_config.phase = spi::Phase::CaptureOnSecondTransition;
|
||||||
|
display_config.polarity = spi::Polarity::IdleHigh;
|
||||||
|
|
||||||
|
let spi: Spi<'_, _, Blocking> = Spi::new_blocking_txonly(p.SPI1, clk, mosi, display_config.clone());
|
||||||
|
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 dcx = Output::new(dcx, Level::Low);
|
||||||
|
let rst = Output::new(rst, Level::Low);
|
||||||
|
// dcx: 0 = command, 1 = data
|
||||||
|
|
||||||
|
// Enable LCD backlight
|
||||||
|
let _bl = Output::new(bl, Level::High);
|
||||||
|
|
||||||
|
// display interface abstraction from SPI and DC
|
||||||
|
let di = SPIInterface::new(display_spi, dcx);
|
||||||
|
|
||||||
|
// Define the display from the display interface and initialize it
|
||||||
|
let mut display = Builder::new(GC9A01, di)
|
||||||
|
.display_size(240, 240)
|
||||||
|
.reset_pin(rst)
|
||||||
|
.color_order(ColorOrder::Bgr)
|
||||||
|
.invert_colors(ColorInversion::Inverted)
|
||||||
|
.init(&mut Delay)
|
||||||
|
.unwrap();
|
||||||
|
display.clear(Rgb565::BLACK).unwrap();
|
||||||
|
|
||||||
|
let raw_image_data = ImageRawLE::new(include_bytes!("../../assets/ferris.raw"), FERRIS_WIDTH);
|
||||||
|
let mut ferris = Image::new(&raw_image_data, Point::zero());
|
||||||
|
|
||||||
|
let r = rng.next_u32();
|
||||||
|
let mut delta = Point {
|
||||||
|
x: ((r % 10) + 5) as i32,
|
||||||
|
y: (((r >> 8) % 10) + 5) as i32,
|
||||||
|
};
|
||||||
|
loop {
|
||||||
|
// Move Ferris
|
||||||
|
let bb = ferris.bounding_box();
|
||||||
|
let tl = bb.top_left;
|
||||||
|
let br = bb.bottom_right().unwrap();
|
||||||
|
if tl.x < 0 || br.x > LCD_X_RES {
|
||||||
|
delta.x = -delta.x;
|
||||||
|
}
|
||||||
|
if tl.y < 0 || br.y > LCD_Y_RES {
|
||||||
|
delta.y = -delta.y;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Erase ghosting
|
||||||
|
let style = PrimitiveStyleBuilder::new().fill_color(Rgb565::BLACK).build();
|
||||||
|
let mut off = Point { x: 0, y: 0 };
|
||||||
|
if delta.x < 0 {
|
||||||
|
off.x = FERRIS_WIDTH as i32;
|
||||||
|
}
|
||||||
|
Rectangle::new(tl + off, Size::new(delta.x as u32, FERRIS_HEIGHT))
|
||||||
|
.into_styled(style)
|
||||||
|
.draw(&mut display)
|
||||||
|
.unwrap();
|
||||||
|
off = Point { x: 0, y: 0 };
|
||||||
|
if delta.y < 0 {
|
||||||
|
off.y = FERRIS_HEIGHT as i32;
|
||||||
|
}
|
||||||
|
Rectangle::new(tl + off, Size::new(FERRIS_WIDTH, delta.y as u32))
|
||||||
|
.into_styled(style)
|
||||||
|
.draw(&mut display)
|
||||||
|
.unwrap();
|
||||||
|
// Translate Ferris
|
||||||
|
ferris.translate_mut(delta);
|
||||||
|
// Display the image
|
||||||
|
ferris.draw(&mut display).unwrap();
|
||||||
|
Timer::after(Duration::from_millis(50)).await;
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user