Skip to content

Commit

Permalink
Merge #1986
Browse files Browse the repository at this point in the history
1986: Touch Panel HIL and ft6x06 driver r=bradjc a=alexandruradovici

### Pull Request Overview

This pull request adds:

* a HIL for touch panels with optional multi touch and gestures
* a driver for the ft6x06 touch panel


### Testing Strategy

This pull request was tested using the STM32F412g Discovery Kit.


### TODO or Help Wanted

This pull request still needs some feedback. 

Even tough the documentation for [ft6x06](http://www.tvielectronics.com/ocart/download/controller/FT6206.pdf) states that gestures should be recognized, my device does not seem to recognize them. I might be doing something wrong, any ideas would be helpful. The test setup is https://github.com/UPBIoT/tock/tree/touch.


### Documentation Updated

- [x] no updates are required.

### Formatting

- [x] Ran `make prepush`.


Co-authored-by: Alexandru Radovici <msg4alex@gmail.com>
  • Loading branch information
bors[bot] and alexandruradovici committed Jul 23, 2020
2 parents 2cf2de7 + 55d733f commit 2ce7b7b
Show file tree
Hide file tree
Showing 12 changed files with 960 additions and 202 deletions.
63 changes: 0 additions & 63 deletions boards/components/src/ft6206.rs

This file was deleted.

63 changes: 63 additions & 0 deletions boards/components/src/ft6x06.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
//! Components for the Ft6x06 Touch Panel.
//!
//! Usage
//! -----
//! ```rust
//! let ft6x06 = components::ft6x06::Ft6x06Component::new()
//! .finalize(components::ft6x06_i2c_component_helper!(mux_i2c));
//! ```
use capsules::ft6x06::Ft6x06;
use capsules::virtual_i2c::I2CDevice;
use core::mem::MaybeUninit;
use kernel::component::Component;
use kernel::hil::gpio;
use kernel::static_init_half;

// Setup static space for the objects.
#[macro_export]
macro_rules! ft6x06_i2c_component_helper {
($i2c_mux: expr) => {{
use capsules::ft6x06::Ft6x06;
use capsules::virtual_i2c::I2CDevice;
use core::mem::MaybeUninit;
let i2c = components::i2c::I2CComponent::new($i2c_mux, 0x38)
.finalize(components::i2c_component_helper!());
static mut ft6x06: MaybeUninit<Ft6x06<'static>> = MaybeUninit::uninit();
(&i2c, &mut ft6x06)
};};
}

pub struct Ft6x06Component {
interupt_pin: &'static dyn gpio::InterruptPin<'static>,
}

impl Ft6x06Component {
pub fn new(pin: &'static dyn gpio::InterruptPin) -> Ft6x06Component {
Ft6x06Component { interupt_pin: pin }
}
}

impl Component for Ft6x06Component {
type StaticInput = (
&'static I2CDevice<'static>,
&'static mut MaybeUninit<Ft6x06<'static>>,
);
type Output = &'static Ft6x06<'static>;

unsafe fn finalize(self, static_buffer: Self::StaticInput) -> Self::Output {
let ft6x06 = static_init_half!(
static_buffer.1,
Ft6x06<'static>,
Ft6x06::new(
static_buffer.0,
self.interupt_pin,
&mut capsules::ft6x06::BUFFER,
&mut capsules::ft6x06::EVENTS_BUFFER
)
);
static_buffer.0.set_client(ft6x06);
self.interupt_pin.set_client(ft6x06);

ft6x06
}
}
3 changes: 2 additions & 1 deletion boards/components/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ pub mod console;
pub mod crc;
pub mod debug_queue;
pub mod debug_writer;
pub mod ft6206;
pub mod ft6x06;
pub mod gpio;
pub mod hd44780;
pub mod hmac;
Expand All @@ -33,3 +33,4 @@ pub mod si7021;
pub mod spi;
pub mod st7735;
pub mod temperature;
pub mod touch;
126 changes: 126 additions & 0 deletions boards/components/src/touch.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,126 @@
//! Components for the Touch Panel.
//!
//! Usage
//! -----
//!
//! Touch
//!
//! ```rust
//! // Just Touch
//! let touch =
//! components::touch::TouchComponent::new(board_kernel, ts, None, Some(screen))
//! .finalize(());
//!
//! // With Gesture
//! let touch =
//! components::touch::TouchComponent::new(board_kernel, ts, Some(ts), Some(screen))
//! .finalize(());
//! ```
//!
//! Multi Touch
//!
//! ```rust
//! // Just Multi Touch
//! let touch =
//! components::touch::MultiTouchComponent::new(board_kernel, ts, None, Some(screen))
//! .finalize(());
//!
//! // With Gesture
//! let touch =
//! components::touch::MultiTouchComponent::new(board_kernel, ts, Some(ts), Some(screen))
//! .finalize(());
//! ```
use kernel::capabilities;
use kernel::component::Component;
use kernel::create_capability;
use kernel::static_init;

pub struct TouchComponent {
board_kernel: &'static kernel::Kernel,
touch: &'static dyn kernel::hil::touch::Touch<'static>,
gesture: Option<&'static dyn kernel::hil::touch::Gesture<'static>>,
screen: Option<&'static dyn kernel::hil::screen::Screen>,
}

impl TouchComponent {
pub fn new(
board_kernel: &'static kernel::Kernel,
touch: &'static dyn kernel::hil::touch::Touch<'static>,
gesture: Option<&'static dyn kernel::hil::touch::Gesture<'static>>,
screen: Option<&'static dyn kernel::hil::screen::Screen>,
) -> TouchComponent {
TouchComponent {
board_kernel: board_kernel,
touch: touch,
gesture: gesture,
screen: screen,
}
}
}

impl Component for TouchComponent {
type StaticInput = ();
type Output = &'static capsules::touch::Touch<'static>;

unsafe fn finalize(self, _static_input: Self::StaticInput) -> Self::Output {
let grant_cap = create_capability!(capabilities::MemoryAllocationCapability);
let grant_touch = self.board_kernel.create_grant(&grant_cap);

let touch = static_init!(
capsules::touch::Touch,
capsules::touch::Touch::new(Some(self.touch), None, self.screen, grant_touch)
);

kernel::hil::touch::Touch::set_client(self.touch, touch);
if let Some(gesture) = self.gesture {
kernel::hil::touch::Gesture::set_client(gesture, touch);
}

touch
}
}

pub struct MultiTouchComponent {
board_kernel: &'static kernel::Kernel,
multi_touch: &'static dyn kernel::hil::touch::MultiTouch<'static>,
gesture: Option<&'static dyn kernel::hil::touch::Gesture<'static>>,
screen: Option<&'static dyn kernel::hil::screen::Screen>,
}

impl MultiTouchComponent {
pub fn new(
board_kernel: &'static kernel::Kernel,
multi_touch: &'static dyn kernel::hil::touch::MultiTouch<'static>,
gesture: Option<&'static dyn kernel::hil::touch::Gesture<'static>>,
screen: Option<&'static dyn kernel::hil::screen::Screen>,
) -> MultiTouchComponent {
MultiTouchComponent {
board_kernel: board_kernel,
multi_touch: multi_touch,
gesture: gesture,
screen: screen,
}
}
}

impl Component for MultiTouchComponent {
type StaticInput = ();
type Output = &'static capsules::touch::Touch<'static>;

unsafe fn finalize(self, _static_input: Self::StaticInput) -> Self::Output {
let grant_cap = create_capability!(capabilities::MemoryAllocationCapability);
let grant_touch = self.board_kernel.create_grant(&grant_cap);

let touch = static_init!(
capsules::touch::Touch,
capsules::touch::Touch::new(None, Some(self.multi_touch), self.screen, grant_touch)
);

kernel::hil::touch::MultiTouch::set_client(self.multi_touch, touch);
if let Some(gesture) = self.gesture {
kernel::hil::touch::Gesture::set_client(gesture, touch);
}

touch
}
}
28 changes: 19 additions & 9 deletions boards/stm32f412gdiscovery/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -48,8 +48,9 @@ struct STM32F412GDiscovery {
VirtualMuxAlarm<'static, stm32f412g::tim2::Tim2<'static>>,
>,
gpio: &'static capsules::gpio::GPIO<'static, stm32f412g::gpio::Pin<'static>>,
ft6206: &'static capsules::ft6206::Ft6206<'static>,
adc: &'static capsules::adc::Adc<'static, stm32f412g::adc::Adc>,
ft6x06: &'static capsules::ft6x06::Ft6x06<'static>,
touch: &'static capsules::touch::Touch<'static>,
}

/// Mapping of integer syscalls to objects that implement syscalls.
Expand All @@ -65,8 +66,9 @@ impl Platform for STM32F412GDiscovery {
capsules::alarm::DRIVER_NUM => f(Some(self.alarm)),
kernel::ipc::DRIVER_NUM => f(Some(&self.ipc)),
capsules::gpio::DRIVER_NUM => f(Some(self.gpio)),
capsules::ft6206::DRIVER_NUM => f(Some(self.ft6206)),
capsules::adc::DRIVER_NUM => f(Some(self.adc)),
capsules::ft6x06::DRIVER_NUM => f(Some(self.ft6x06)),
capsules::touch::DRIVER_NUM => f(Some(self.touch)),
_ => f(None),
}
}
Expand Down Expand Up @@ -478,13 +480,20 @@ pub unsafe fn reset_handler() {
)
.finalize(components::i2c_mux_component_helper!());

let ft6206 = components::ft6206::Ft6206Component::new(
let ft6x06 = components::ft6x06::Ft6x06Component::new(
stm32f412g::gpio::PinId::PG05.get_pin().as_ref().unwrap(),
)
.finalize(components::ft6206_i2c_component_helper!(mux_i2c));
.finalize(components::ft6x06_i2c_component_helper!(mux_i2c));

ft6206.is_present();
let touch = components::touch::TouchComponent::new(board_kernel, ft6x06, Some(ft6x06), None)
.finalize(());

// Uncomment this for multi touch support
// let touch =
// components::touch::MultiTouchComponent::new(board_kernel, ft6x06, Some(ft6x06), None)
// .finalize(());

// ADC
let adc_channels = static_init!(
[&'static stm32f412g::adc::Channel; 6],
[
Expand All @@ -511,15 +520,16 @@ pub unsafe fn reset_handler() {
);
stm32f412g::adc::ADC1.set_client(adc);

let nucleo_f412g = STM32F412GDiscovery {
let stm32f412g = STM32F412GDiscovery {
console: console,
ipc: kernel::ipc::IPC::new(board_kernel, &memory_allocation_capability),
led: led,
button: button,
alarm: alarm,
gpio: gpio,
ft6206: ft6206,
adc: adc,
ft6x06: ft6x06,
touch: touch,
};

// // Optional kernel tests
Expand Down Expand Up @@ -572,9 +582,9 @@ pub unsafe fn reset_handler() {
});

board_kernel.kernel_loop(
&nucleo_f412g,
&stm32f412g,
chip,
Some(&nucleo_f412g.ipc),
Some(&stm32f412g.ipc),
&main_loop_capability,
);
}
5 changes: 3 additions & 2 deletions capsules/src/driver.rs
Original file line number Diff line number Diff line change
Expand Up @@ -63,10 +63,11 @@ pub enum NUM {
Nrf51822Serialization = 0x80004,
Hd44780 = 0x80005,
St7735 = 0x80006,
Ft6206 = 0x80007,
Ft6x06 = 0x80007,

// Misc
Buzzer = 0x90000,
Screen = 0x90001
Screen = 0x90001,
Touch = 0x90002
}
}

0 comments on commit 2ce7b7b

Please sign in to comment.