aboutsummaryrefslogtreecommitdiff
path: root/examples
diff options
context:
space:
mode:
authorGeorges Palauqui <[email protected]>2024-10-27 09:50:57 +0100
committerGeorges Palauqui <[email protected]>2024-10-27 09:50:57 +0100
commit66205fdd859b4c8607d0b6be9e4fcb27e8096493 (patch)
treeb1655fa4899c37bd28107270d39b149611697ef2 /examples
parentb31648f2e59a68748e1c0f1408d1658a2e5e6a08 (diff)
update spi_display example for rp
Diffstat (limited to 'examples')
-rw-r--r--examples/rp/Cargo.toml8
-rw-r--r--examples/rp/src/bin/spi_display.rs165
2 files changed, 19 insertions, 154 deletions
diff --git a/examples/rp/Cargo.toml b/examples/rp/Cargo.toml
index 6a2c99716..b55b20c63 100644
--- a/examples/rp/Cargo.toml
+++ b/examples/rp/Cargo.toml
@@ -37,10 +37,10 @@ cortex-m = { version = "0.7.6", features = ["inline-asm"] }
37cortex-m-rt = "0.7.0" 37cortex-m-rt = "0.7.0"
38critical-section = "1.1" 38critical-section = "1.1"
39panic-probe = { version = "0.3", features = ["print-defmt"] } 39panic-probe = { version = "0.3", features = ["print-defmt"] }
40display-interface-spi = "0.4.1" 40display-interface-spi = "0.5.0"
41embedded-graphics = "0.7.1" 41embedded-graphics = "0.8.1"
42st7789 = "0.6.1" 42mipidsi = "0.8.0"
43display-interface = "0.4.1" 43display-interface = "0.5.0"
44byte-slice-cast = { version = "1.2.0", default-features = false } 44byte-slice-cast = { version = "1.2.0", default-features = false }
45smart-leds = "0.4.0" 45smart-leds = "0.4.0"
46heapless = "0.8" 46heapless = "0.8"
diff --git a/examples/rp/src/bin/spi_display.rs b/examples/rp/src/bin/spi_display.rs
index e937b9d0a..dd114a4ae 100644
--- a/examples/rp/src/bin/spi_display.rs
+++ b/examples/rp/src/bin/spi_display.rs
@@ -9,11 +9,12 @@
9use core::cell::RefCell; 9use core::cell::RefCell;
10 10
11use defmt::*; 11use defmt::*;
12use display_interface_spi::SPIInterface;
12use embassy_embedded_hal::shared_bus::blocking::spi::SpiDeviceWithConfig; 13use embassy_embedded_hal::shared_bus::blocking::spi::SpiDeviceWithConfig;
13use embassy_executor::Spawner; 14use embassy_executor::Spawner;
14use embassy_rp::gpio::{Level, Output}; 15use embassy_rp::gpio::{Level, Output};
15use embassy_rp::spi; 16use embassy_rp::spi;
16use embassy_rp::spi::{Blocking, Spi}; 17use embassy_rp::spi::Spi;
17use embassy_sync::blocking_mutex::raw::NoopRawMutex; 18use embassy_sync::blocking_mutex::raw::NoopRawMutex;
18use embassy_sync::blocking_mutex::Mutex; 19use embassy_sync::blocking_mutex::Mutex;
19use embassy_time::Delay; 20use embassy_time::Delay;
@@ -24,10 +25,11 @@ use embedded_graphics::pixelcolor::Rgb565;
24use embedded_graphics::prelude::*; 25use embedded_graphics::prelude::*;
25use embedded_graphics::primitives::{PrimitiveStyleBuilder, Rectangle}; 26use embedded_graphics::primitives::{PrimitiveStyleBuilder, Rectangle};
26use embedded_graphics::text::Text; 27use embedded_graphics::text::Text;
27use st7789::{Orientation, ST7789}; 28use mipidsi::models::ST7789;
29use mipidsi::options::{Orientation, Rotation};
30use mipidsi::Builder;
28use {defmt_rtt as _, panic_probe as _}; 31use {defmt_rtt as _, panic_probe as _};
29 32
30use crate::my_display_interface::SPIDeviceInterface;
31use crate::touch::Touch; 33use crate::touch::Touch;
32 34
33const DISPLAY_FREQ: u32 = 64_000_000; 35const DISPLAY_FREQ: u32 = 64_000_000;
@@ -58,7 +60,7 @@ async fn main(_spawner: Spawner) {
58 touch_config.phase = spi::Phase::CaptureOnSecondTransition; 60 touch_config.phase = spi::Phase::CaptureOnSecondTransition;
59 touch_config.polarity = spi::Polarity::IdleHigh; 61 touch_config.polarity = spi::Polarity::IdleHigh;
60 62
61 let spi: Spi<'_, _, Blocking> = Spi::new_blocking(p.SPI1, clk, mosi, miso, touch_config.clone()); 63 let spi = Spi::new_blocking(p.SPI1, clk, mosi, miso, touch_config.clone());
62 let spi_bus: Mutex<NoopRawMutex, _> = Mutex::new(RefCell::new(spi)); 64 let spi_bus: Mutex<NoopRawMutex, _> = Mutex::new(RefCell::new(spi));
63 65
64 let display_spi = SpiDeviceWithConfig::new(&spi_bus, Output::new(display_cs, Level::High), display_config); 66 let display_spi = SpiDeviceWithConfig::new(&spi_bus, Output::new(display_cs, Level::High), display_config);
@@ -74,17 +76,15 @@ async fn main(_spawner: Spawner) {
74 let _bl = Output::new(bl, Level::High); 76 let _bl = Output::new(bl, Level::High);
75 77
76 // display interface abstraction from SPI and DC 78 // display interface abstraction from SPI and DC
77 let di = SPIDeviceInterface::new(display_spi, dcx); 79 let di = SPIInterface::new(display_spi, dcx);
78 80
79 // create driver 81 // Define the display from the display interface and initialize it
80 let mut display = ST7789::new(di, rst, 240, 320); 82 let mut display = Builder::new(ST7789, di)
81 83 .display_size(240, 320)
82 // initialize 84 .reset_pin(rst)
83 display.init(&mut Delay).unwrap(); 85 .orientation(Orientation::new().rotate(Rotation::Deg90))
84 86 .init(&mut Delay)
85 // set default orientation 87 .unwrap();
86 display.set_orientation(Orientation::Landscape).unwrap();
87
88 display.clear(Rgb565::BLACK).unwrap(); 88 display.clear(Rgb565::BLACK).unwrap();
89 89
90 let raw_image_data = ImageRawLE::new(include_bytes!("../../assets/ferris.raw"), 86); 90 let raw_image_data = ImageRawLE::new(include_bytes!("../../assets/ferris.raw"), 86);
@@ -175,138 +175,3 @@ mod touch {
175 } 175 }
176 } 176 }
177} 177}
178
179mod my_display_interface {
180 use display_interface::{DataFormat, DisplayError, WriteOnlyDataCommand};
181 use embedded_hal_1::digital::OutputPin;
182 use embedded_hal_1::spi::SpiDevice;
183
184 /// SPI display interface.
185 ///
186 /// This combines the SPI peripheral and a data/command pin
187 pub struct SPIDeviceInterface<SPI, DC> {
188 spi: SPI,
189 dc: DC,
190 }
191
192 impl<SPI, DC> SPIDeviceInterface<SPI, DC>
193 where
194 SPI: SpiDevice,
195 DC: OutputPin,
196 {
197 /// Create new SPI interface for communciation with a display driver
198 pub fn new(spi: SPI, dc: DC) -> Self {
199 Self { spi, dc }
200 }
201 }
202
203 impl<SPI, DC> WriteOnlyDataCommand for SPIDeviceInterface<SPI, DC>
204 where
205 SPI: SpiDevice,
206 DC: OutputPin,
207 {
208 fn send_commands(&mut self, cmds: DataFormat<'_>) -> Result<(), DisplayError> {
209 // 1 = data, 0 = command
210 self.dc.set_low().map_err(|_| DisplayError::DCError)?;
211
212 send_u8(&mut self.spi, cmds).map_err(|_| DisplayError::BusWriteError)?;
213 Ok(())
214 }
215
216 fn send_data(&mut self, buf: DataFormat<'_>) -> Result<(), DisplayError> {
217 // 1 = data, 0 = command
218 self.dc.set_high().map_err(|_| DisplayError::DCError)?;
219
220 send_u8(&mut self.spi, buf).map_err(|_| DisplayError::BusWriteError)?;
221 Ok(())
222 }
223 }
224
225 fn send_u8<T: SpiDevice>(spi: &mut T, words: DataFormat<'_>) -> Result<(), T::Error> {
226 match words {
227 DataFormat::U8(slice) => spi.write(slice),
228 DataFormat::U16(slice) => {
229 use byte_slice_cast::*;
230 spi.write(slice.as_byte_slice())
231 }
232 DataFormat::U16LE(slice) => {
233 use byte_slice_cast::*;
234 for v in slice.as_mut() {
235 *v = v.to_le();
236 }
237 spi.write(slice.as_byte_slice())
238 }
239 DataFormat::U16BE(slice) => {
240 use byte_slice_cast::*;
241 for v in slice.as_mut() {
242 *v = v.to_be();
243 }
244 spi.write(slice.as_byte_slice())
245 }
246 DataFormat::U8Iter(iter) => {
247 let mut buf = [0; 32];
248 let mut i = 0;
249
250 for v in iter.into_iter() {
251 buf[i] = v;
252 i += 1;
253
254 if i == buf.len() {
255 spi.write(&buf)?;
256 i = 0;
257 }
258 }
259
260 if i > 0 {
261 spi.write(&buf[..i])?;
262 }
263
264 Ok(())
265 }
266 DataFormat::U16LEIter(iter) => {
267 use byte_slice_cast::*;
268 let mut buf = [0; 32];
269 let mut i = 0;
270
271 for v in iter.map(u16::to_le) {
272 buf[i] = v;
273 i += 1;
274
275 if i == buf.len() {
276 spi.write(&buf.as_byte_slice())?;
277 i = 0;
278 }
279 }
280
281 if i > 0 {
282 spi.write(&buf[..i].as_byte_slice())?;
283 }
284
285 Ok(())
286 }
287 DataFormat::U16BEIter(iter) => {
288 use byte_slice_cast::*;
289 let mut buf = [0; 64];
290 let mut i = 0;
291 let len = buf.len();
292
293 for v in iter.map(u16::to_be) {
294 buf[i] = v;
295 i += 1;
296
297 if i == len {
298 spi.write(&buf.as_byte_slice())?;
299 i = 0;
300 }
301 }
302
303 if i > 0 {
304 spi.write(&buf[..i].as_byte_slice())?;
305 }
306
307 Ok(())
308 }
309 _ => unimplemented!(),
310 }
311 }
312}