aboutsummaryrefslogtreecommitdiffstats
path: root/src/bin/example/display.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/bin/example/display.rs')
-rw-r--r--src/bin/example/display.rs89
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;
+}