components/
screen.rs
1use capsules_extra::screen::Screen;
34use capsules_extra::screen_shared::ScreenShared;
35use core::mem::MaybeUninit;
36use kernel::capabilities;
37use kernel::component::Component;
38use kernel::create_capability;
39use kernel::hil;
40
41#[macro_export]
42macro_rules! screen_component_static {
43 ($s:literal $(,)?) => {{
44 let buffer = kernel::static_buf!([u8; $s]);
45 let screen = kernel::static_buf!(capsules_extra::screen::Screen);
46
47 (buffer, screen)
48 };};
49}
50
51pub type ScreenComponentType = capsules_extra::screen::Screen<'static>;
52
53pub struct ScreenComponent<const SCREEN_BUF_LEN: usize> {
54 board_kernel: &'static kernel::Kernel,
55 driver_num: usize,
56 screen: &'static dyn kernel::hil::screen::Screen<'static>,
57 screen_setup: Option<&'static dyn kernel::hil::screen::ScreenSetup<'static>>,
58}
59
60impl<const SCREEN_BUF_LEN: usize> ScreenComponent<SCREEN_BUF_LEN> {
61 pub fn new(
62 board_kernel: &'static kernel::Kernel,
63 driver_num: usize,
64 screen: &'static dyn kernel::hil::screen::Screen,
65 screen_setup: Option<&'static dyn kernel::hil::screen::ScreenSetup>,
66 ) -> ScreenComponent<SCREEN_BUF_LEN> {
67 ScreenComponent {
68 board_kernel,
69 driver_num,
70 screen,
71 screen_setup,
72 }
73 }
74}
75
76impl<const SCREEN_BUF_LEN: usize> Component for ScreenComponent<SCREEN_BUF_LEN> {
77 type StaticInput = (
78 &'static mut MaybeUninit<[u8; SCREEN_BUF_LEN]>,
79 &'static mut MaybeUninit<Screen<'static>>,
80 );
81 type Output = &'static Screen<'static>;
82
83 fn finalize(self, static_input: Self::StaticInput) -> Self::Output {
84 let grant_cap = create_capability!(capabilities::MemoryAllocationCapability);
85 let grant_screen = self.board_kernel.create_grant(self.driver_num, &grant_cap);
86
87 let buffer = static_input.0.write([0; SCREEN_BUF_LEN]);
88
89 let screen = static_input.1.write(Screen::new(
90 self.screen,
91 self.screen_setup,
92 buffer,
93 grant_screen,
94 ));
95
96 kernel::hil::screen::Screen::set_client(self.screen, screen);
97 if let Some(screen_setup) = self.screen_setup {
98 kernel::hil::screen::ScreenSetup::set_client(screen_setup, screen);
99 }
100
101 screen
102 }
103}
104
105#[macro_export]
106macro_rules! screen_shared_component_static {
107 ($s:literal, $S:ty $(,)?) => {{
108 let buffer = kernel::static_buf!([u8; $s]);
109 let screen = kernel::static_buf!(capsules_extra::screen_shared::ScreenShared<$S>);
110
111 (buffer, screen)
112 };};
113}
114
115pub type ScreenSharedComponentType<S> = capsules_extra::screen_shared::ScreenShared<'static, S>;
116
117pub struct ScreenSharedComponent<
118 const SCREEN_BUF_LEN: usize,
119 S: hil::screen::Screen<'static> + 'static,
120> {
121 board_kernel: &'static kernel::Kernel,
122 driver_num: usize,
123 screen: &'static S,
124 apps_regions: &'static [capsules_extra::screen_shared::AppScreenRegion],
125}
126
127impl<const SCREEN_BUF_LEN: usize, S: hil::screen::Screen<'static>>
128 ScreenSharedComponent<SCREEN_BUF_LEN, S>
129{
130 pub fn new(
131 board_kernel: &'static kernel::Kernel,
132 driver_num: usize,
133 screen: &'static S,
134 apps_regions: &'static [capsules_extra::screen_shared::AppScreenRegion],
135 ) -> ScreenSharedComponent<SCREEN_BUF_LEN, S> {
136 ScreenSharedComponent {
137 board_kernel,
138 driver_num,
139 screen,
140 apps_regions,
141 }
142 }
143}
144
145impl<const SCREEN_BUF_LEN: usize, S: hil::screen::Screen<'static>> Component
146 for ScreenSharedComponent<SCREEN_BUF_LEN, S>
147{
148 type StaticInput = (
149 &'static mut MaybeUninit<[u8; SCREEN_BUF_LEN]>,
150 &'static mut MaybeUninit<ScreenShared<'static, S>>,
151 );
152 type Output = &'static ScreenShared<'static, S>;
153
154 fn finalize(self, static_input: Self::StaticInput) -> Self::Output {
155 let grant_cap = create_capability!(capabilities::MemoryAllocationCapability);
156 let grant_screen = self.board_kernel.create_grant(self.driver_num, &grant_cap);
157
158 let buffer = static_input.0.write([0; SCREEN_BUF_LEN]);
159
160 let screen = static_input.1.write(ScreenShared::new(
161 self.screen,
162 grant_screen,
163 buffer,
164 self.apps_regions,
165 ));
166
167 kernel::hil::screen::Screen::set_client(self.screen, screen);
168
169 screen
170 }
171}