@@ -7,7 +7,7 @@ pub use self::color::Color;
77pub use self :: init:: init;
88pub use self :: stdout:: init as init_stdout;
99
10- use core:: { fmt, ptr } ;
10+ use core:: fmt;
1111use stm32f7:: stm32f7x6:: LTDC ;
1212
1313#[ macro_use]
@@ -29,26 +29,31 @@ pub const LAYER_2_OCTETS_PER_PIXEL: usize = 2;
2929/// The length of the layer 1 buffer in bytes.
3030pub const LAYER_2_LENGTH : usize = HEIGHT * WIDTH * LAYER_2_OCTETS_PER_PIXEL ;
3131
32- /// Start address of the SDRAM where the framebuffers live.
33- pub const SDRAM_START : usize = 0xC000_0000 ;
34- /// Start address of the layer 1 framebuffer.
35- pub const LAYER_1_START : usize = SDRAM_START ;
36- /// Start address of the layer 2 framebuffer.
37- pub const LAYER_2_START : usize = SDRAM_START + LAYER_1_LENGTH ;
38-
3932/// Represents the LCD and provides methods to access both layers.
4033pub struct Lcd < ' a > {
4134 controller : & ' a mut LTDC ,
42- layer_1_in_use : bool ,
43- layer_2_in_use : bool ,
35+
36+ /// A layer with RGB + alpha value
37+ ///
38+ /// Use `.take()` to get an owned version of this layer.
39+ pub layer_1 : Option < Layer < FramebufferArgb8888 > > ,
40+
41+ /// A layer with alpha + color lookup table index
42+ ///
43+ /// Use `.take()` to get an owned version of this layer.
44+ pub layer_2 : Option < Layer < FramebufferAl88 > > ,
4445}
4546
4647impl < ' a > Lcd < ' a > {
47- fn new ( ltdc : & ' a mut LTDC ) -> Self {
48+ fn new (
49+ ltdc : & ' a mut LTDC ,
50+ layer_1 : & ' static mut [ volatile:: Volatile < u8 > ] ,
51+ layer_2 : & ' static mut [ volatile:: Volatile < u8 > ] ,
52+ ) -> Self {
4853 Self {
4954 controller : ltdc,
50- layer_1_in_use : false ,
51- layer_2_in_use : false ,
55+ layer_1 : Some ( Layer { framebuffer : FramebufferArgb8888 :: new ( layer_1 ) } ) ,
56+ layer_2 : Some ( Layer { framebuffer : FramebufferAl88 :: new ( layer_2 ) } ) ,
5257 }
5358 }
5459
@@ -71,26 +76,8 @@ impl<'a> Lcd<'a> {
7176 } ) ;
7277 }
7378
74- /// Returns a reference to layer 1.
75- pub fn layer_1 ( & mut self ) -> Option < Layer < FramebufferArgb8888 > > {
76- if self . layer_1_in_use {
77- None
78- } else {
79- Some ( Layer {
80- framebuffer : FramebufferArgb8888 :: new ( LAYER_1_START ) ,
81- } )
82- }
83- }
84-
85- /// Returns a reference to layer 2.
86- pub fn layer_2 ( & mut self ) -> Option < Layer < FramebufferAl88 > > {
87- if self . layer_2_in_use {
88- None
89- } else {
90- Some ( Layer {
91- framebuffer : FramebufferAl88 :: new ( LAYER_2_START ) ,
92- } )
93- }
79+ fn reload_shadow_registers ( & mut self ) {
80+ self . controller . srcr . modify ( |_, w| w. imr ( ) . set_bit ( ) ) ; // IMMEDIATE_RELOAD
9481 }
9582}
9683
@@ -104,20 +91,23 @@ pub trait Framebuffer {
10491///
10592/// It uses 8bits for alpha, red, green, and black respectively, totaling in 32bits per pixel.
10693pub struct FramebufferArgb8888 {
107- base_addr : usize ,
94+ mem : & ' static mut [ volatile :: Volatile < u8 > ] ,
10895}
10996
11097impl FramebufferArgb8888 {
111- const fn new ( base_addr : usize ) -> Self {
112- Self { base_addr }
98+ fn new ( mem : & ' static mut [ volatile :: Volatile < u8 > ] ) -> Self {
99+ Self { mem }
113100 }
114101}
115102
116103impl Framebuffer for FramebufferArgb8888 {
117104 fn set_pixel ( & mut self , x : usize , y : usize , color : Color ) {
118105 let pixel = y * WIDTH + x;
119- let pixel_ptr = ( self . base_addr + pixel * LAYER_1_OCTETS_PER_PIXEL ) as * mut u32 ;
120- unsafe { ptr:: write_volatile ( pixel_ptr, color. to_argb8888 ( ) ) } ;
106+ let pixel_idx = pixel * LAYER_1_OCTETS_PER_PIXEL ;
107+ self . mem [ pixel_idx] . write ( color. alpha ) ;
108+ self . mem [ pixel_idx + 1 ] . write ( color. red ) ;
109+ self . mem [ pixel_idx + 2 ] . write ( color. green ) ;
110+ self . mem [ pixel_idx + 3 ] . write ( color. blue ) ;
121111 }
122112}
123113
@@ -126,20 +116,21 @@ impl Framebuffer for FramebufferArgb8888 {
126116/// There are 8bits for the alpha channel and 8 bits for specifying a color using a
127117/// lookup table. Thus, each pixel is represented by 16bits.
128118pub struct FramebufferAl88 {
129- base_addr : usize ,
119+ mem : & ' static mut [ volatile :: Volatile < u8 > ] ,
130120}
131121
132122impl FramebufferAl88 {
133- const fn new ( base_addr : usize ) -> Self {
134- Self { base_addr }
123+ fn new ( mem : & ' static mut [ volatile :: Volatile < u8 > ] ) -> Self {
124+ Self { mem }
135125 }
136126}
137127
138128impl Framebuffer for FramebufferAl88 {
139129 fn set_pixel ( & mut self , x : usize , y : usize , color : Color ) {
140130 let pixel = y * WIDTH + x;
141- let pixel_ptr = ( self . base_addr + pixel * LAYER_2_OCTETS_PER_PIXEL ) as * mut u16 ;
142- unsafe { ptr:: write_volatile ( pixel_ptr, u16:: from ( color. alpha ) << 8 | u16:: from ( color. red ) ) } ;
131+ let pixel_idx = pixel * LAYER_2_OCTETS_PER_PIXEL ;
132+ self . mem [ pixel_idx] . write ( color. alpha ) ;
133+ self . mem [ pixel_idx + 1 ] . write ( color. red ) ;
143134 }
144135}
145136
0 commit comments