components/
ft6x06.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 Ft6x06 Touch Panel.
6//!
7//! Usage
8//! -----
9//! ```rust
10//! let ft6x06 = components::ft6x06::Ft6x06Component::new(
11//!    i2c_mux,
12//!    0x38,
13//!    base_peripherals.gpio_ports.get_pin(stm32f412g::gpio::PinId::PG05).unwrap()
14//! )
15//!    .finalize(components::ft6x06_component_static!(mux_i2c));
16//! ```
17
18use capsules_core::virtualizers::virtual_i2c::{I2CDevice, MuxI2C};
19use capsules_extra::ft6x06::Ft6x06;
20use capsules_extra::ft6x06::NO_TOUCH;
21use core::mem::MaybeUninit;
22use kernel::component::Component;
23use kernel::hil::gpio;
24use kernel::hil::i2c;
25
26// Setup static space for the objects.
27#[macro_export]
28macro_rules! ft6x06_component_static {
29    ($I:ty $(,)?) => {{
30        let i2c_device =
31            kernel::static_buf!(capsules_core::virtualizers::virtual_i2c::I2CDevice<$I>);
32        let buffer = kernel::static_buf!([u8; 17]);
33        let events_buffer = kernel::static_buf!([kernel::hil::touch::TouchEvent; 2]);
34        let ft6x06 = kernel::static_buf!(
35            capsules_extra::ft6x06::Ft6x06<
36                'static,
37                capsules_core::virtualizers::virtual_i2c::I2CDevice<$I>,
38            >
39        );
40
41        (i2c_device, ft6x06, buffer, events_buffer)
42    };};
43}
44
45pub struct Ft6x06Component<I: 'static + i2c::I2CMaster<'static>> {
46    i2c_mux: &'static MuxI2C<'static, I>,
47    i2c_address: u8,
48    interrupt_pin: &'static dyn gpio::InterruptPin<'static>,
49}
50
51impl<I: 'static + i2c::I2CMaster<'static>> Ft6x06Component<I> {
52    pub fn new(
53        i2c_mux: &'static MuxI2C<'static, I>,
54        i2c_address: u8,
55        pin: &'static dyn gpio::InterruptPin,
56    ) -> Ft6x06Component<I> {
57        Ft6x06Component {
58            i2c_mux,
59            i2c_address,
60            interrupt_pin: pin,
61        }
62    }
63}
64
65impl<I: 'static + i2c::I2CMaster<'static>> Component for Ft6x06Component<I> {
66    type StaticInput = (
67        &'static mut MaybeUninit<I2CDevice<'static, I>>,
68        &'static mut MaybeUninit<Ft6x06<'static, I2CDevice<'static, I>>>,
69        &'static mut MaybeUninit<[u8; 17]>,
70        &'static mut MaybeUninit<[kernel::hil::touch::TouchEvent; 2]>,
71    );
72    type Output = &'static Ft6x06<'static, I2CDevice<'static, I>>;
73
74    fn finalize(self, static_buffer: Self::StaticInput) -> Self::Output {
75        let ft6x06_i2c = static_buffer
76            .0
77            .write(I2CDevice::new(self.i2c_mux, self.i2c_address));
78
79        let buffer = static_buffer.2.write([0; 17]);
80        let events_buffer = static_buffer.3.write([NO_TOUCH, NO_TOUCH]);
81
82        let ft6x06 = static_buffer.1.write(Ft6x06::new(
83            ft6x06_i2c,
84            self.interrupt_pin,
85            buffer,
86            events_buffer,
87        ));
88        ft6x06_i2c.set_client(ft6x06);
89        self.interrupt_pin.set_client(ft6x06);
90
91        ft6x06
92    }
93}