#![no_std] #![no_main] use core::cell::RefCell; use defmt::info; use display_interface_spi::SPIInterface; use embassy_embedded_hal::shared_bus::blocking::spi::SpiDevice; use embassy_executor::Spawner; use embassy_nrf::{ bind_interrupts, gpio::{AnyPin, Level, Output, OutputDrive, Pin}, peripherals, spim::{self, Spim}, }; use embassy_sync::blocking_mutex::Mutex; use embassy_time::{Delay, Duration, Timer}; use embedded_hal::digital::OutputPin; use ili9341::Ili9341; use {defmt_rtt as _, panic_probe as _}; use embedded_graphics::{ mono_font::{ascii::FONT_6X10, MonoTextStyle}, pixelcolor::{BinaryColor, Rgb565}, prelude::*, primitives::{ Circle, PrimitiveStyle, PrimitiveStyleBuilder, Rectangle, StrokeAlignment, Triangle, }, text::{Alignment, Text}, }; // Setup interrupts bind_interrupts!(struct Irqs { // Setup interrupts for SPI (SERIAL3) UARTE3_SPIM3_SPIS3_TWIM3_TWIS3 => embassy_nrf::spim::InterruptHandler; }); #[embassy_executor::task] async fn blink(pin: AnyPin, blink_delay: Duration) -> ! { let mut led = Output::new(pin, Level::Low, OutputDrive::Standard); loop { led.set_high(); Timer::after(blink_delay).await; led.set_low(); Timer::after(blink_delay).await; } } #[embassy_executor::main] async fn main(spawner: Spawner) { // Initialize the nRF let p = embassy_nrf::init(Default::default()); // Spawn the blink task spawner .spawn(blink(p.P0_02.degrade(), Duration::from_millis(250))) .expect("Failed to start blink task"); // Get the pins for SPI let mosi = p.P0_13; let miso = p.P0_12; let sck = p.P0_30; let cs_pin = p.P0_31; // Create an SPI config let mut spim_config = spim::Config::default(); spim_config.frequency = spim::Frequency::M8; /////////////////////////////////////////// // Create a new SPI interface on the nrf // /////////////////////////////////////////// // Grab the SPI Master mode peripheral form the nRF60 let spim = embassy_nrf::spim::Spim::new(p.SERIAL3, Irqs, sck, miso, mosi, spim_config); // Use the SPI peripheral to create a shared bus let spi_bus: Mutex = Mutex::new(RefCell::new(spim)); // Setup the chip select as an output pin let chip_select = Output::new(cs_pin, Level::Low, OutputDrive::Standard); // Use the shared bus to create a SPI Device to use for the display let spi_display = SpiDevice::new(&spi_bus, chip_select); // Create a new SPI display interface let direction_control = Output::new(p.P0_20, Level::High, OutputDrive::Standard); let iface = SPIInterface::new(spi_display, direction_control); // Create a new display let display_reset = Output::new(p.P0_11, Level::High, OutputDrive::Standard); let display_orientation = ili9341::Orientation::Landscape; let display_size = ili9341::DisplaySize240x320; let mut display = Ili9341::new( iface, display_reset, &mut embassy_time::Delay, display_orientation, display_size, ) .unwrap(); display.clear(Rgb565::RED).unwrap(); // Create styles used by the drawing operations. let thin_stroke = PrimitiveStyle::with_stroke(Rgb565::WHITE, 1); let thick_stroke = PrimitiveStyle::with_stroke(Rgb565::WHITE, 3); let border_stroke = PrimitiveStyleBuilder::new() .stroke_color(Rgb565::WHITE) .stroke_width(3) .stroke_alignment(StrokeAlignment::Inside) .build(); let fill = PrimitiveStyle::with_fill(Rgb565::WHITE); let character_style = MonoTextStyle::new(&FONT_6X10, Rgb565::WHITE); let yoffset = 10; // Draw a 3px wide outline around the display. display .bounding_box() .into_styled(border_stroke) .draw(&mut display) .unwrap(); // Draw a triangle. Triangle::new( Point::new(16, 16 + yoffset), Point::new(16 + 16, 16 + yoffset), Point::new(16 + 8, yoffset), ) .into_styled(thin_stroke) .draw(&mut display) .unwrap(); // Draw a filled square Rectangle::new(Point::new(52, yoffset), Size::new(16, 16)) .into_styled(fill) .draw(&mut display) .unwrap(); // Draw a circle with a 3px wide stroke. Circle::new(Point::new(88, yoffset), 17) .into_styled(thick_stroke) .draw(&mut display) .unwrap(); // Draw centered text. let text = "embedded-graphics"; Text::with_alignment( text, display.bounding_box().center() + Point::new(0, 15), character_style, Alignment::Center, ) .draw(&mut display) .unwrap(); let mut led = Output::new(p.P0_03, Level::Low, OutputDrive::Standard); loop { info!("Going high!"); led.set_high(); Timer::after_millis(300).await; info!("Going low!"); led.set_low(); Timer::after_millis(300).await; } }