1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
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;
}
|