cryptnox-pos
1.0.0
Standalone USDC payment terminal firmware (ESP32 + Cryptnox smart card)
Toggle main menu visibility
Loading...
Searching...
No Matches
touch_cal.h
Go to the documentation of this file.
1
/*
2
* SPDX-License-Identifier: LGPL-3.0-or-later
3
* Copyright (c) 2026 Cryptnox SA
4
*/
5
21
22
#ifndef TOUCH_CAL_H
23
#define TOUCH_CAL_H
24
25
#include <stdbool.h>
26
#include <stdint.h>
27
28
#ifdef __cplusplus
29
extern
"C"
{
30
#endif
31
33
typedef
struct
{
34
uint16_t
x_min
;
35
uint16_t
x_max
;
36
uint16_t
y_min
;
37
uint16_t
y_max
;
38
}
touch_cal_t
;
39
59
#define TOUCH_CAL_MIN_SPAN 500
61
#define TOUCH_CAL_RAW_MAX 4095
62
63
/* Extrapolating past a target that was tapped near the edge of the converter's
64
* range lands outside it. Clamped rather than rejected: the tap itself was
65
* fine, and a raw count the hardware can never report is simply an edge the
66
* finger can never reach. Unsigned underflow is the reason this exists at all —
67
* a -261 stored as 65275 inverts the axis. */
68
static
inline
uint16_t
touch_cal_clamp
(int32_t v)
69
{
70
if
(v < 0) {
return
0U; }
71
if
(v >
TOUCH_CAL_RAW_MAX
) {
return
(uint16_t)
TOUCH_CAL_RAW_MAX
; }
72
return
(uint16_t)v;
73
}
74
75
static
inline
bool
touch_cal_from_corners
(int16_t r0x, int16_t r0y,
76
int16_t r1x, int16_t r1y,
77
int16_t inset, int16_t w, int16_t h,
78
touch_cal_t
*out)
79
{
80
const
int32_t span_x = (int32_t)(w - 1 - inset) - (int32_t)inset;
81
const
int32_t span_y = (int32_t)(h - 1 - inset) - (int32_t)inset;
82
const
int32_t dx = (int32_t)r1x - (int32_t)r0x;
83
const
int32_t dy = (int32_t)r1y - (int32_t)r0y;
84
85
if
((out == NULL) || (span_x <= 0) || (span_y <= 0)) {
return
false
; }
86
if
((dx <
TOUCH_CAL_MIN_SPAN
) || (dy <
TOUCH_CAL_MIN_SPAN
)) {
return
false
; }
87
88
out->
x_min
=
touch_cal_clamp
((int32_t)r0x - ((dx * inset) / span_x));
89
out->
x_max
=
touch_cal_clamp
((int32_t)r1x + ((dx * inset) / span_x));
90
out->
y_min
=
touch_cal_clamp
((int32_t)r0y - ((dy * inset) / span_y));
91
out->
y_max
=
touch_cal_clamp
((int32_t)r1y + ((dy * inset) / span_y));
92
return
true
;
93
}
94
135
#define TOUCH_JUMP_MAX_PX 25
136
137
/* How far z must rise above the lightest press of this touch to count as a
138
* second contact. A knob, deliberately: z is contact area and force as much as
139
* finger count, it differs between panels, and the only honest way to set it is
140
* to watch the "second contact:" line ui.cpp logs under a real thumb. Too low
141
* freezes hard taps, which costs nothing; too high lets the thumb through, which
142
* is the bug. Err low.
143
*
144
* 30 because the bench said so: on the CYD this was written against, z idles
145
* around 1900-2000 under one finger and a second contact stepped it 43% — which
146
* the 50 this started at sat just above, and missed. */
147
#define TOUCH_Z_STEP_PCT 30
148
150
typedef
struct
{
151
int16_t
x
;
152
int16_t
y
;
153
int16_t
z_min
;
154
bool
have
;
155
}
touch_jump_t
;
156
157
static
inline
bool
touch_jump_second_contact
(
const
touch_jump_t
*st,
158
int16_t z, int16_t x, int16_t y)
159
{
160
const
int32_t dx = (int32_t)x - (int32_t)st->
x
;
161
const
int32_t dy = (int32_t)y - (int32_t)st->
y
;
162
163
if
((z > 0) && (st->
z_min
> 0)) {
164
const
int32_t step = (int32_t)st->
z_min
+
165
(((int32_t)st->
z_min
*
TOUCH_Z_STEP_PCT
) / 100);
166
if
((int32_t)z > step) {
return
true
; }
167
}
168
return
((dx * dx) + (dy * dy)) >
169
((int32_t)
TOUCH_JUMP_MAX_PX
* (int32_t)
TOUCH_JUMP_MAX_PX
);
170
}
171
172
static
inline
void
touch_jump_filter
(
touch_jump_t
*st,
bool
pressed,
173
int16_t z, int16_t *x, int16_t *y)
174
{
175
if
(!pressed) { st->
have
=
false
;
return
; }
176
177
if
(st->
have
) {
178
if
(
touch_jump_second_contact
(st, z, *x, *y)) {
179
*x = st->
x
;
/* hold the first finger's point */
180
*y = st->
y
;
181
return
;
182
}
183
/* Track the lightest press, not the first: an operator who lands heavy
184
* and eases off would otherwise set a bar their own thumb fits under. */
185
if
((z > 0) && (z < st->z_min)) { st->
z_min
= z; }
186
}
else
{
187
st->
z_min
= z;
188
}
189
190
st->
x
= *x;
191
st->
y
= *y;
192
st->
have
=
true
;
193
}
194
195
#ifdef __cplusplus
196
}
197
#endif
198
199
#endif
/* TOUCH_CAL_H */
touch_cal_t
Definition
touch_cal.h:33
touch_cal_t::y_max
uint16_t y_max
Definition
touch_cal.h:37
touch_cal_t::x_min
uint16_t x_min
Definition
touch_cal.h:34
touch_cal_t::x_max
uint16_t x_max
Definition
touch_cal.h:35
touch_cal_t::y_min
uint16_t y_min
Definition
touch_cal.h:36
touch_jump_t
Definition
touch_cal.h:150
touch_jump_t::y
int16_t y
Definition
touch_cal.h:152
touch_jump_t::z_min
int16_t z_min
Definition
touch_cal.h:153
touch_jump_t::x
int16_t x
Definition
touch_cal.h:151
touch_jump_t::have
bool have
Definition
touch_cal.h:154
touch_cal_clamp
static uint16_t touch_cal_clamp(int32_t v)
Definition
touch_cal.h:68
TOUCH_CAL_MIN_SPAN
#define TOUCH_CAL_MIN_SPAN
Solve the edge-to-edge raw range from two corner taps.
Definition
touch_cal.h:59
TOUCH_CAL_RAW_MAX
#define TOUCH_CAL_RAW_MAX
Definition
touch_cal.h:61
touch_jump_filter
static void touch_jump_filter(touch_jump_t *st, bool pressed, int16_t z, int16_t *x, int16_t *y)
Definition
touch_cal.h:172
TOUCH_JUMP_MAX_PX
#define TOUCH_JUMP_MAX_PX
Second-contact guard: hold the first finger's point while two are down.
Definition
touch_cal.h:135
touch_cal_from_corners
static bool touch_cal_from_corners(int16_t r0x, int16_t r0y, int16_t r1x, int16_t r1y, int16_t inset, int16_t w, int16_t h, touch_cal_t *out)
Definition
touch_cal.h:75
TOUCH_Z_STEP_PCT
#define TOUCH_Z_STEP_PCT
Definition
touch_cal.h:147
touch_jump_second_contact
static bool touch_jump_second_contact(const touch_jump_t *st, int16_t z, int16_t x, int16_t y)
Definition
touch_cal.h:157
main
touch_cal.h
Generated by
1.17.0