1#![no_std]
4
5use core::{array::TryFromSliceError, fmt::Debug};
6
7use bondrewd::Bitfields;
8use embedded_hal_async::{digital::Wait, i2c::I2c};
9
10const I2C_ADDR: u8 = 0x24;
12
13#[derive(Debug)]
15pub enum Error<E> {
16 BusError(E),
18 InvalidMessageLen(usize),
20 IOError,
22 NoDataAvailable,
24 TryFromSliceError,
26}
27
28impl<E> From<TryFromSliceError> for Error<E> {
29 fn from(_: TryFromSliceError) -> Self {
30 Self::TryFromSliceError
31 }
32}
33
34#[derive(Debug, Clone, Copy, PartialEq, Eq)]
36pub enum Event {
37 Touch {
39 report: TouchReport,
40 touches: (Option<TouchRecord>, Option<TouchRecord>),
41 },
42 Button(ButtonRecord),
44}
45
46#[derive(Debug, Clone, Copy, PartialEq, Eq, Bitfields)]
48#[bondrewd(default_endianness = "le")]
49pub struct TouchReport {
50 pub data_len: u16,
52 pub report_id: u8,
54 pub time_stamp: u16,
56 #[bondrewd(bit_length = 2)]
57 padding0: u8,
58 #[bondrewd(bit_length = 1)]
59 pub large_object: u8,
60 #[bondrewd(bit_length = 5)]
61 pub record_num: u8,
62 #[bondrewd(bit_length = 2)]
63 pub report_counter: u8,
64 #[bondrewd(bit_length = 3)]
65 padding1: u8,
66 #[bondrewd(bit_length = 3)]
67 pub noise_effect: u8,
68}
69
70#[derive(Debug, Clone, Copy, PartialEq, Eq, Bitfields)]
72#[bondrewd(default_endianness = "le")]
73pub struct TouchRecord {
74 #[bondrewd(bit_length = 5)]
75 padding0: u8,
76 #[bondrewd(bit_length = 3)]
77 pub touch_type: u8,
78 #[bondrewd(bit_length = 1)]
79 pub tip: u8,
80 #[bondrewd(bit_length = 2)]
81 pub event_id: u8,
82 #[bondrewd(bit_length = 5)]
83 pub touch_id: u8,
84 pub x: u16,
85 pub y: u16,
86 pub pressure: u8,
87 pub major_axis_length: u16,
88 pub orientation: u8,
89}
90
91#[derive(Debug, Clone, Copy, PartialEq, Eq, Bitfields)]
93#[bondrewd(default_endianness = "le")]
94pub struct ButtonRecord {
95 pub length: u16,
97 pub report_id: u8,
99 pub time_stamp: u16,
101 pub btn_val: u8,
103 pub btn_signal: [u16; 4],
105}
106
107pub struct TT21100<I2C, IRQ> {
109 i2c: I2C,
111 irq: IRQ,
113}
114
115impl<I2C, IRQ, E> TT21100<I2C, IRQ>
116where
117 I2C: I2c<Error = E>,
118 IRQ: Wait,
119 E: Debug,
120{
121 pub fn new(i2c: I2C, irq: IRQ) -> Self {
123 Self { i2c, irq }
124 }
125
126 pub async fn data_available(&mut self) -> Result<(), Error<E>> {
128 self.irq.wait_for_low().await.map_err(|_| Error::IOError)
129 }
130
131 pub async fn event(&mut self) -> Result<Event, Error<E>> {
135 let message_length = self.read_message_length().await?;
136
137 let mut data = [0u8; 32];
138 self.read_bytes(&mut data[0..][..message_length]).await?;
139
140 match message_length {
141 2 => Err(Error::NoDataAvailable),
142 7 | 17 | 27 => touch_event(&data[0..][..message_length]),
143 14 => button_event(&data[0..][..message_length]),
144 n => Err(Error::InvalidMessageLen(n)),
145 }
146 }
147
148 async fn read_message_length(&mut self) -> Result<usize, Error<E>> {
152 let mut buffer = [0u8; 2];
153 self.read_bytes(&mut buffer).await?;
154
155 let message_length = u16::from_le_bytes(buffer);
156
157 Ok(message_length as usize)
158 }
159
160 async fn read_bytes(&mut self, buffer: &mut [u8]) -> Result<(), Error<E>> {
161 self.i2c
162 .write_read(I2C_ADDR, &[], buffer)
163 .await
164 .map_err(|e| Error::BusError(e))
165 }
166}
167
168fn touch_event<E>(message: &[u8]) -> Result<Event, Error<E>>
169where
170 E: Debug,
171{
172 debug_assert!(message.len() == 7 || message.len() == 17 || message.len() == 27);
173
174 let report = message[0..][..7].try_into()?;
175 let report = TouchReport::from_bytes(report);
176
177 let record0 = if message.len() >= 17 {
178 let record = message[7..][..10].try_into()?;
179 let record = TouchRecord::from_bytes(record);
180
181 Some(record)
182 } else {
183 None
184 };
185
186 let record1 = if message.len() == 27 {
187 let record = message[17..][..10].try_into()?;
188 let record = TouchRecord::from_bytes(record);
189
190 Some(record)
191 } else {
192 None
193 };
194
195 Ok(Event::Touch {
196 report,
197 touches: (record0, record1),
198 })
199}
200
201fn button_event<E>(message: &[u8]) -> Result<Event, Error<E>>
202where
203 E: Debug,
204{
205 debug_assert_eq!(message.len(), 14);
206
207 let message = message.try_into()?;
208 let record = ButtonRecord::from_bytes(message);
209
210 Ok(Event::Button(record))
211}