ws_oled_driver/
display.rs1use std::{thread::sleep, time::Duration};
2pub type Buffer = Vec<u8>;
3
4use anyhow::Result;
5use rppal::{
6 gpio::{Gpio, OutputPin},
7 spi::Spi,
8};
9
10const BUS_CLOCK_SPEED: u32 = 8_000_000;
11const RST_PIN: u8 = 25;
12const DC_PIN: u8 = 24;
13const CS_PIN: u8 = 8;
14const BL_PIN: u8 = 18;
15const WIDTH: u8 = 132;
16const HEIGHT: u8 = 64;
17
18#[derive(Debug)]
20pub enum Protocol {
21 SPI,
22 I2C,
23}
24
25#[derive(Debug)]
26pub struct Display {
27 pub width: u8,
28 pub height: u8,
29 pub dc_pin: OutputPin,
30 pub cs_pin: OutputPin,
31 pub rst_pin: OutputPin,
32 pub bl_pin: OutputPin,
33 pub protocol: Protocol,
34 pub bus: Spi,
35 pub memory: Buffer,
36}
37
38impl Display {
39 pub fn write_command(&mut self, byte: &[u8]) -> Result<()> {
42 match self.protocol {
43 Protocol::SPI => {
44 self.dc_pin.set_low();
45 self.spi_write_byte(byte)
46 }
47 Protocol::I2C => self.i2c_write_byte(byte),
48 }
49 }
50
51 pub fn write_data(&mut self, byte: &[u8]) -> Result<()> {
54 match self.protocol {
55 Protocol::SPI => {
56 self.dc_pin.set_high();
57 self.spi_write_byte(byte)
58 }
59 Protocol::I2C => self.i2c_write_byte(byte),
60 }
61 }
62
63 pub fn spi_write_byte(&mut self, byte: &[u8]) -> Result<()> {
65 self.bus.write(byte)?;
66
67 Ok(())
68 }
69
70 pub fn i2c_write_byte(&self, _byte: &[u8]) -> Result<()> {
72 Ok(())
74 }
75
76 pub fn reset(&mut self) -> Result<()> {
78 self.rst_pin.set_high();
79 sleep(Duration::from_millis(100));
80 self.rst_pin.set_low();
81 sleep(Duration::from_millis(100));
82 self.rst_pin.set_high();
83 sleep(Duration::from_millis(100));
84
85 Ok(())
86 }
87
88 pub fn render(&mut self) -> Result<()> {
92 for page in 0..8 {
93 self.write_command(&[0xB0 + page])?;
94 self.write_command(&[0x02])?;
95 self.write_command(&[0x10])?;
96 sleep(Duration::from_millis(10));
97 match self.protocol {
98 Protocol::I2C => todo!("implement i2c"),
99 Protocol::SPI => {
100 self.dc_pin.set_high();
101 for index in 0..=(self.width as usize) {
102 let byte = self.memory[index + self.width as usize * page as usize];
103 self.spi_write_byte(&[byte])?;
104 }
105 }
106 }
107 }
108
109 Ok(())
110 }
111
112 pub fn initialize(&mut self) -> Result<()> {
114 self.reset()?;
115 self.write_command(&[0xAE])?;
116 self.write_command(&[0x02])?;
117 self.write_command(&[0x10])?;
118 self.write_command(&[0x40])?;
119 self.write_command(&[0x81])?;
120 self.write_command(&[0xA0])?;
121 self.write_command(&[0xC0])?;
122 self.write_command(&[0xA6])?;
123 self.write_command(&[0xA8])?;
124 self.write_command(&[0x3F])?;
125 self.write_command(&[0xD3])?;
126 self.write_command(&[0x00])?;
127 self.write_command(&[0xd5])?;
128 self.write_command(&[0x80])?;
129 self.write_command(&[0xD9])?;
130 self.write_command(&[0xF1])?;
131 self.write_command(&[0xDA])?;
132 self.write_command(&[0x12])?;
133 self.write_command(&[0xDB])?;
134 self.write_command(&[0x40])?;
135 self.write_command(&[0x20])?;
136 self.write_command(&[0x02])?;
137 self.write_command(&[0xA4])?;
138 self.write_command(&[0xA6])?;
139 sleep(Duration::from_millis(100));
140 self.write_command(&[0xAF])?; Ok(())
142 }
143
144 pub fn new() -> Result<Self> {
146 let gpio = Gpio::new()?;
148 let rst_pin = gpio.get(RST_PIN)?.into_output();
149 let mut dc_pin = gpio.get(DC_PIN)?.into_output();
150 let mut cs_pin = gpio.get(CS_PIN)?.into_output();
151 let mut bl_pin = gpio.get(BL_PIN)?.into_output();
152
153 cs_pin.set_low();
154 bl_pin.set_high();
155 dc_pin.set_low();
156
157 let bus: Spi = Spi::new(
158 rppal::spi::Bus::Spi0,
159 rppal::spi::SlaveSelect::Ss0,
160 BUS_CLOCK_SPEED,
161 rppal::spi::Mode::Mode0,
162 )?;
163
164 Ok(Self {
165 width: WIDTH,
166 height: HEIGHT,
167 protocol: Protocol::SPI,
168 rst_pin,
169 dc_pin,
170 cs_pin,
171 bl_pin,
172 bus,
173 memory: vec![0; WIDTH as usize * HEIGHT as usize],
174 })
175 }
176}