components/
touch.rs

1// Licensed under the Apache License, Version 2.0 or the MIT License.
2// SPDX-License-Identifier: Apache-2.0 OR MIT
3// Copyright Tock Contributors 2022.
4
5//! Components for the Touch Panel.
6//!
7//! Usage
8//! -----
9//!
10//! Touch
11//!
12//! ```rust
13//! // Just Touch
14//! let touch =
15//!     components::touch::TouchComponent::new(board_kernel, ts, None, Some(screen))
16//!         .finalize(components::touch_component_static!());
17//!
18//! // With Gesture
19//! let touch =
20//!     components::touch::TouchComponent::new(board_kernel, ts, Some(ts), Some(screen))
21//!         .finalize(components::touch_component_static!());
22//! ```
23//!
24//! Multi Touch
25//!
26//! ```rust
27//! // Just Multi Touch
28//! let touch =
29//!     components::touch::MultiTouchComponent::new(board_kernel, ts, None, Some(screen))
30//!         .finalize(components::touch_component_static!());
31//!
32//! // With Gesture
33//! let touch =
34//!     components::touch::MultiTouchComponent::new(board_kernel, ts, Some(ts), Some(screen))
35//!         .finalize(components::touch_component_static!());
36//! ```
37use capsules_extra::touch::Touch;
38use core::mem::MaybeUninit;
39use kernel::capabilities;
40use kernel::component::Component;
41use kernel::create_capability;
42
43#[macro_export]
44macro_rules! touch_component_static {
45    () => {{
46        kernel::static_buf!(capsules_extra::touch::Touch<'static>)
47    };};
48}
49
50pub struct TouchComponent {
51    board_kernel: &'static kernel::Kernel,
52    driver_num: usize,
53    touch: &'static dyn kernel::hil::touch::Touch<'static>,
54    gesture: Option<&'static dyn kernel::hil::touch::Gesture<'static>>,
55    screen: Option<&'static dyn kernel::hil::screen::Screen<'static>>,
56}
57
58impl TouchComponent {
59    pub fn new(
60        board_kernel: &'static kernel::Kernel,
61        driver_num: usize,
62        touch: &'static dyn kernel::hil::touch::Touch<'static>,
63        gesture: Option<&'static dyn kernel::hil::touch::Gesture<'static>>,
64        screen: Option<&'static dyn kernel::hil::screen::Screen<'static>>,
65    ) -> TouchComponent {
66        TouchComponent {
67            board_kernel,
68            driver_num,
69            touch,
70            gesture,
71            screen,
72        }
73    }
74}
75
76impl Component for TouchComponent {
77    type StaticInput = &'static mut MaybeUninit<Touch<'static>>;
78    type Output = &'static capsules_extra::touch::Touch<'static>;
79
80    fn finalize(self, static_input: Self::StaticInput) -> Self::Output {
81        let grant_cap = create_capability!(capabilities::MemoryAllocationCapability);
82        let grant_touch = self.board_kernel.create_grant(self.driver_num, &grant_cap);
83
84        let touch = static_input.write(capsules_extra::touch::Touch::new(
85            Some(self.touch),
86            None,
87            self.screen,
88            grant_touch,
89        ));
90
91        kernel::hil::touch::Touch::set_client(self.touch, touch);
92        if let Some(gesture) = self.gesture {
93            kernel::hil::touch::Gesture::set_client(gesture, touch);
94        }
95
96        touch
97    }
98}
99
100pub struct MultiTouchComponent {
101    board_kernel: &'static kernel::Kernel,
102    driver_num: usize,
103    multi_touch: &'static dyn kernel::hil::touch::MultiTouch<'static>,
104    gesture: Option<&'static dyn kernel::hil::touch::Gesture<'static>>,
105    screen: Option<&'static dyn kernel::hil::screen::Screen<'static>>,
106}
107
108impl MultiTouchComponent {
109    pub fn new(
110        board_kernel: &'static kernel::Kernel,
111        driver_num: usize,
112        multi_touch: &'static dyn kernel::hil::touch::MultiTouch<'static>,
113        gesture: Option<&'static dyn kernel::hil::touch::Gesture<'static>>,
114        screen: Option<&'static dyn kernel::hil::screen::Screen>,
115    ) -> MultiTouchComponent {
116        MultiTouchComponent {
117            board_kernel,
118            driver_num,
119            multi_touch,
120            gesture,
121            screen,
122        }
123    }
124}
125
126impl Component for MultiTouchComponent {
127    type StaticInput = &'static mut MaybeUninit<Touch<'static>>;
128    type Output = &'static capsules_extra::touch::Touch<'static>;
129
130    fn finalize(self, static_input: Self::StaticInput) -> Self::Output {
131        let grant_cap = create_capability!(capabilities::MemoryAllocationCapability);
132        let grant_touch = self.board_kernel.create_grant(self.driver_num, &grant_cap);
133
134        let touch = static_input.write(capsules_extra::touch::Touch::new(
135            None,
136            Some(self.multi_touch),
137            self.screen,
138            grant_touch,
139        ));
140
141        kernel::hil::touch::MultiTouch::set_client(self.multi_touch, touch);
142        if let Some(gesture) = self.gesture {
143            kernel::hil::touch::Gesture::set_client(gesture, touch);
144        }
145
146        touch
147    }
148}