firmware for my Touchscreen E-Paper Input Module for Framework Laptop 16
1use core::fmt::{Display, Formatter};
2use crate::syscall;
3use crate::syscall::SyscallNumber;
4
5#[repr(usize)]
6#[derive(Copy, Clone, Debug, Eq, PartialEq)]
7#[cfg_attr(feature = "defmt", derive(defmt::Format))]
8pub enum InputSyscall {
9 NextEvent = 0,
10 SetTouchEnabled = 1,
11 HasEvent = 2,
12}
13
14impl TryFrom<usize> for InputSyscall {
15 type Error = ();
16
17 fn try_from(value: usize) -> Result<Self, Self::Error> {
18 match value {
19 x if x == InputSyscall::NextEvent as usize => Ok(InputSyscall::NextEvent),
20 x if x == InputSyscall::SetTouchEnabled as usize => Ok(InputSyscall::SetTouchEnabled),
21 x if x == InputSyscall::HasEvent as usize => Ok(InputSyscall::HasEvent),
22 _ => Err(()),
23 }
24 }
25}
26
27#[repr(C)]
28#[cfg_attr(feature = "defmt", derive(defmt::Format))]
29#[derive(Copy, Clone, Debug, Eq, PartialEq, serde::Serialize, serde::Deserialize)]
30pub enum Event {
31 Touch(TouchEvent),
32 RefreshFinished,
33}
34
35#[repr(u8)]
36#[cfg_attr(feature = "defmt", derive(defmt::Format))]
37#[derive(Copy, Clone, Debug, Eq, PartialEq, serde::Serialize, serde::Deserialize)]
38pub enum TouchEventType {
39 Down,
40 Up,
41 Move,
42}
43
44#[repr(C)]
45#[cfg_attr(feature = "defmt", derive(defmt::Format))]
46#[derive(Copy, Clone, Debug, Eq, PartialEq, serde::Serialize, serde::Deserialize)]
47pub struct TouchEvent {
48 pub ev_type: TouchEventType,
49 pub x: u16,
50 pub y: u16,
51}
52
53impl TouchEvent {
54 pub const fn new() -> Self {
55 Self {
56 ev_type: TouchEventType::Down,
57 x: u16::MAX,
58 y: u16::MAX,
59 }
60 }
61
62 #[cfg(feature = "embedded-graphics")]
63 pub fn eg_point(&self) -> embedded_graphics::prelude::Point {
64 embedded_graphics::prelude::Point::new(self.x as i32, self.y as i32)
65 }
66}
67
68impl Display for TouchEvent {
69 fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result {
70 let ty = match self.ev_type {
71 TouchEventType::Down => "Down",
72 TouchEventType::Up => "Up",
73 TouchEventType::Move => "Move",
74 };
75 write!(f, "{ty} @ ({}, {})", self.x, self.y)
76 }
77}
78
79#[repr(usize)]
80#[derive(Copy, Clone, Debug, Eq, PartialEq)]
81#[cfg_attr(feature = "defmt", derive(defmt::Format))]
82pub enum ScEventType {
83 NoEvent = 0,
84 TouchUp = 1,
85 TouchDown = 2,
86 TouchMove = 3,
87 RefreshFinished = 4,
88}
89
90impl TryFrom<usize> for ScEventType {
91 type Error = ();
92
93 fn try_from(value: usize) -> Result<Self, Self::Error> {
94 match value {
95 x if x == ScEventType::NoEvent as usize => Ok(ScEventType::NoEvent),
96 x if x == ScEventType::TouchUp as usize => Ok(ScEventType::TouchUp),
97 x if x == ScEventType::TouchDown as usize => Ok(ScEventType::TouchDown),
98 x if x == ScEventType::TouchMove as usize => Ok(ScEventType::TouchMove),
99 x if x == ScEventType::RefreshFinished as usize => Ok(ScEventType::RefreshFinished),
100 _ => Err(()),
101 }
102 }
103}
104
105pub fn next_event() -> Option<Event> {
106 let mut ev_type: usize;
107 let mut x: u16;
108 let mut y: u16;
109
110 unsafe {
111 syscall!(
112 SyscallNumber::Input,
113 out ev_type in InputSyscall::NextEvent,
114 out x,
115 out y,
116 );
117 }
118
119 match ScEventType::try_from(ev_type) {
120 Ok(ScEventType::NoEvent) => None,
121 Ok(ScEventType::TouchUp) => Some(Event::Touch(TouchEvent { ev_type: TouchEventType::Up, x, y })),
122 Ok(ScEventType::TouchDown) => Some(Event::Touch(TouchEvent { ev_type: TouchEventType::Down, x, y })),
123 Ok(ScEventType::TouchMove) => Some(Event::Touch(TouchEvent { ev_type: TouchEventType::Move, x, y })),
124 Ok(ScEventType::RefreshFinished) => Some(Event::RefreshFinished),
125 Err(_) => panic!("invalid touch event"),
126 }
127}
128
129pub fn set_touch_enabled(enabled: bool) {
130 unsafe {
131 syscall!(
132 SyscallNumber::Input,
133 in InputSyscall::SetTouchEnabled,
134 in enabled,
135 );
136 }
137}
138
139pub fn has_event() -> bool {
140 let mut has_event: usize;
141
142 unsafe {
143 syscall!(
144 SyscallNumber::Input,
145 out has_event in InputSyscall::HasEvent,
146 );
147 }
148
149 has_event != 0
150}