diff options
Diffstat (limited to 'src/bin/example/display.rs')
| -rw-r--r-- | src/bin/example/display.rs | 89 |
1 files changed, 89 insertions, 0 deletions
diff --git a/src/bin/example/display.rs b/src/bin/example/display.rs new file mode 100644 index 0000000..5830254 --- /dev/null +++ b/src/bin/example/display.rs @@ -0,0 +1,89 @@ +use defmt::info; +use display_interface_spi::SpiInterface; +use embassy_nrf::gpio::{AnyPin, Level, Output, OutputDrive}; +use embassy_nrf::{interrupt::typelevel::Binding, spim, Peri}; +use embassy_time::Timer; +use embedded_graphics::{ + framebuffer::{buffer_size, Framebuffer}, + pixelcolor::{raw::LittleEndian, Gray4}, +}; +use embedded_hal_bus::spi::ExclusiveDevice; +use ssd1322::{DisplayAsync, PixelCoord}; + +type SPIDevice<'t> = ExclusiveDevice<spim::Spim<'t>, Output<'t>, embassy_time::Delay>; + +type Display<'t> = DisplayAsync<SpiInterface<SPIDevice<'t>, Output<'t>>>; + +pub struct Pins<'t> { + pub ven: Peri<'t, AnyPin>, + pub rst: Peri<'t, AnyPin>, + pub sck: Peri<'t, AnyPin>, + pub sdo: Peri<'t, AnyPin>, + pub cs: Peri<'t, AnyPin>, + pub dc: Peri<'t, AnyPin>, +} + +pub async fn init<T: spim::Instance>( + spi_instance: Peri<'static, T>, + irq_binding: impl Binding<T::Interrupt, spim::InterruptHandler<T>> + 'static, + pins: Pins<'static>, +) -> Display<'static> { + Output::new(pins.ven, Level::High, OutputDrive::Standard).persist(); + + let mut out_rst = Output::new(pins.rst, Level::Low, OutputDrive::Standard); + Timer::after_millis(2).await; + out_rst.set_high(); + Timer::after_millis(2).await; + + let out_cs = Output::new(pins.cs, Level::High, OutputDrive::Standard); + let out_dc = Output::new(pins.dc, Level::High, OutputDrive::Standard); + + let mut spi_config = spim::Config::default(); + spi_config.frequency = spim::Frequency::M8; + let spi_bus = spim::Spim::new_txonly(spi_instance, irq_binding, pins.sck, pins.sdo, spi_config); + let spi_dev = ExclusiveDevice::new(spi_bus, out_cs, embassy_time::Delay).unwrap(); + let spi_iface = SpiInterface::new(spi_dev, out_dc); + + let mut display = DisplayAsync::new(spi_iface, PixelCoord(256, 64), PixelCoord(0x1C * 4, 0)); + + info!("initializing display"); + display + .init( + ssd1322::ConfigAsync::new( + ssd1322::ComScanDirection::RowZeroLast, + ssd1322::ComLayout::Progressive, + ) + .column_remap(ssd1322::command::ColumnRemap::Reverse) + .clock_fosc_divset(9, 1) + .display_enhancements(true, true) + .contrast_current(0x7f) + .phase_lengths(5, 15) + .precharge_voltage(0x1f) + .com_deselect_voltage(0x04), + ) + .await + .unwrap(); + + display +} + +#[embassy_executor::task] +pub async fn task(mut display: Display<'static>) { + let mut fb = + Framebuffer::<Gray4, _, LittleEndian, 128, 64, { buffer_size::<Gray4>(128, 64) }>::new(); + + info!("display task starting"); + t114_meshcore_example::display_task(&mut fb, async |fb| { + display + .region(PixelCoord(0, 0), PixelCoord(256, 64)) + .unwrap() + .draw_packed(fb.data().iter().flat_map(|n| { + let upper = n & 0xf0; + let lower = n & 0x0f; + [upper | (upper >> 4), lower | (lower << 4)] + })) + .await + .unwrap(); + }) + .await; +} |
