11use super :: { Button , Eeprom , Keyboard , NetTx , StatusLed } ;
2- use display_interface:: { DataFormat , DisplayError , WriteOnlyDataCommand } ;
2+ use core:: cell:: RefCell ;
3+ use embassy_embedded_hal:: shared_bus:: blocking:: spi:: SpiDevice ;
34use embassy_stm32:: {
45 bind_interrupts,
56 exti:: ExtiInput ,
67 gpio:: { Input , Level , Output , Pull , Speed } ,
78 i2c:: { mode:: Master , I2c } ,
89 mode:: { Async , Blocking } ,
910 peripherals,
10- spi:: { Spi , Word } ,
11+ spi:: Spi ,
1112 usart:: { self , UartRx , UartTx } ,
1213} ;
14+ use embassy_sync:: blocking_mutex:: { raw:: NoopRawMutex , NoopMutex } ;
1315use embassy_time:: Delay ;
1416use embedded_graphics:: { pixelcolor:: Rgb565 , prelude:: * } ;
15- use ili9341:: { Ili9341 , Orientation } ;
17+ use mipidsi:: {
18+ interface:: SpiInterface ,
19+ models:: ILI9341Rgb565 ,
20+ options:: { ColorOrder , Orientation } ,
21+ Builder , Display ,
22+ } ;
23+ use static_cell:: StaticCell ;
1624use ui_app:: { Led , Outputs } ;
1725
18- struct DisplayData {
19- // These fields are not used, but we need to keep them alive so that the chip select output is
20- // held low and the backlight output is held high.
21- _chip_select : Output < ' static > ,
22- _backlight : Output < ' static > ,
23-
24- data_command : Output < ' static > ,
25- spi : Spi < ' static , Blocking > ,
26- }
27-
28- impl DisplayData {
29- fn new (
30- mut backlight : Output < ' static > ,
31- mut chip_select : Output < ' static > ,
32- data_command : Output < ' static > ,
33- spi : Spi < ' static , Blocking > ,
34- ) -> Self {
35- backlight. set_high ( ) ;
36- chip_select. set_low ( ) ;
37-
38- Self {
39- _backlight : backlight,
40- _chip_select : chip_select,
41- data_command,
42- spi,
43- }
44- }
45-
46- fn write ( & mut self , data : DataFormat < ' _ > ) -> Result < ( ) , DisplayError > {
47- use DataFormat :: * ;
48- match data {
49- U8 ( slice) => self . write_slice ( slice) ,
50- U16 ( slice) => self . write_slice ( slice) ,
51- U16BE ( slice) => self . write_slice ( slice) ,
52- U16LE ( slice) => self . write_slice ( slice) ,
53- U8Iter ( iter) => self . write_iter ( iter) ,
54- U16BEIter ( iter) => self . write_iter ( iter) ,
55- U16LEIter ( iter) => self . write_iter ( iter) ,
56- _ => unreachable ! ( ) ,
57- }
58- }
59-
60- fn write_slice < W : Word > ( & mut self , data : & [ W ] ) -> Result < ( ) , DisplayError > {
61- self . spi . blocking_write ( data) . unwrap ( ) ;
62- Ok ( ( ) )
63- }
64-
65- fn write_iter < W : Word > (
66- & mut self ,
67- iter : & mut dyn Iterator < Item = W > ,
68- ) -> Result < ( ) , DisplayError > {
69- // 1kb of render buffer
70- const CHUNK_SIZE : usize = 512 ;
71-
72- // XXX(RLB) Very C-style iteration, could probably write this in a way that would optimize
73- // better.
74- let mut data = [ W :: default ( ) ; CHUNK_SIZE ] ;
75- let mut n = 0 ;
76- for ( i, x) in iter. enumerate ( ) {
77- data[ i % CHUNK_SIZE ] = x;
78- n += 1 ;
79-
80- if n > 0 && n % CHUNK_SIZE == 0 {
81- self . spi . blocking_write ( & data) . unwrap ( ) ;
82- n = 0 ;
83- }
84- }
85-
86- self . spi . blocking_write ( & data[ ..n] ) . unwrap ( ) ;
87- Ok ( ( ) )
88- }
89- }
90-
91- impl WriteOnlyDataCommand for DisplayData {
92- fn send_commands ( & mut self , cmd : DataFormat < ' _ > ) -> Result < ( ) , DisplayError > {
93- self . data_command . set_low ( ) ;
94- self . write ( cmd)
95- }
96-
97- fn send_data ( & mut self , buf : DataFormat < ' _ > ) -> Result < ( ) , DisplayError > {
98- self . data_command . set_high ( ) ;
99- self . write ( buf)
100- }
101- }
26+ type DisplaySpiDevice = SpiDevice < ' static , NoopRawMutex , Spi < ' static , Blocking > , Output < ' static > > ;
27+ type DisplaySpiInterface = SpiInterface < ' static , DisplaySpiDevice , Output < ' static > > ;
10228
10329pub struct Board {
10430 status_led : StatusLed ,
105- screen : Ili9341 < DisplayData , Output < ' static > > ,
31+ screen : Display < DisplaySpiInterface , ILI9341Rgb565 , Output < ' static > > ,
10632 net_tx : NetTx < UartTx < ' static , Async > > ,
10733 i2c : I2c < ' static , Blocking , Master > ,
10834 pub button_a : Option < Button > ,
10935 pub button_b : Option < Button > ,
11036 pub keyboard : Option < Keyboard > ,
11137 pub net_rx : Option < UartRx < ' static , Async > > ,
38+
39+ // This field isn't used, but is held to keep the pin low instead of floating
40+ #[ allow( dead_code) ]
41+ backlight : Output < ' static > ,
11242}
11343
11444bind_interrupts ! ( struct Irqs {
@@ -179,6 +109,9 @@ impl Board {
179109 let keyboard = Keyboard :: new ( cols, rows) ;
180110
181111 // Screen
112+ static SPI_BUS : StaticCell < NoopMutex < RefCell < Spi < ' static , Blocking > > > > = StaticCell :: new ( ) ;
113+ let display_buffer = cortex_m:: singleton!( : [ u8 ; 512 ] = [ 0 ; 512 ] ) . unwrap ( ) ;
114+
182115 let chip_select = Output :: new ( p. PB8 , Level :: Low , Speed :: Low ) ;
183116 let data_command = Output :: new ( p. PB9 , Level :: Low , Speed :: Low ) ;
184117 let reset = Output :: new ( p. PC13 , Level :: Low , Speed :: Low ) ;
@@ -193,15 +126,17 @@ impl Board {
193126 config
194127 } ;
195128 let spi = Spi :: new_blocking_txonly ( p. SPI1 , p. PA5 , p. PA7 , config) ;
196-
197- let screen = Ili9341 :: new (
198- DisplayData :: new ( backlight, chip_select, data_command, spi) ,
199- reset,
200- & mut Delay ,
201- Orientation :: Portrait ,
202- ili9341:: DisplaySize240x320 ,
203- )
204- . unwrap ( ) ;
129+ let spi_bus = NoopMutex :: new ( RefCell :: new ( spi) ) ;
130+ let spi_bus = SPI_BUS . init ( spi_bus) ;
131+ let spi_dev = SpiDevice :: new ( spi_bus, chip_select) ;
132+ let spi_if = SpiInterface :: new ( spi_dev, data_command, display_buffer) ;
133+
134+ let screen = Builder :: new ( ILI9341Rgb565 , spi_if)
135+ . reset_pin ( reset)
136+ . orientation ( Orientation :: new ( ) . flip_horizontal ( ) )
137+ . color_order ( ColorOrder :: Bgr )
138+ . init ( & mut Delay )
139+ . unwrap ( ) ;
205140
206141 // NET UART
207142 let net_uart = {
@@ -230,6 +165,7 @@ impl Board {
230165 button_b : Some ( button_b) ,
231166 keyboard : Some ( keyboard) ,
232167 net_rx : Some ( net_rx) ,
168+ backlight,
233169 }
234170 }
235171}
0 commit comments