cryptnox-pos 1.0.0
Standalone USDC payment terminal firmware (ESP32 + Cryptnox smart card)
Loading...
Searching...
No Matches
touch_cal.h File Reference

Touch arithmetic: two-point calibration, and the second-contact guard. More...

#include <stdbool.h>
#include <stdint.h>
Include dependency graph for touch_cal.h:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Classes

struct  touch_cal_t
struct  touch_jump_t

Macros

#define TOUCH_CAL_MIN_SPAN   500
 Solve the edge-to-edge raw range from two corner taps.
#define TOUCH_CAL_RAW_MAX   4095
#define TOUCH_JUMP_MAX_PX   25
 Second-contact guard: hold the first finger's point while two are down.
#define TOUCH_Z_STEP_PCT   30

Functions

static uint16_t touch_cal_clamp (int32_t v)
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)
static bool touch_jump_second_contact (const touch_jump_t *st, int16_t z, int16_t x, int16_t y)
static void touch_jump_filter (touch_jump_t *st, bool pressed, int16_t z, int16_t *x, int16_t *y)

Detailed Description

Touch arithmetic: two-point calibration, and the second-contact guard.

Header-only, and separate from ui.cpp for one reason: this is the part that can be wrong without looking wrong. A resistive panel calibrated from two corners is a pair of linear maps, and the sum of the work is extrapolating each captured target out to its edge of the glass — arithmetic a host test can check, in a file that does not need Arduino and LVGL to compile. The jump filter at the bottom is here for the same reason.

Two points, not four. The map ui.cpp applies is linear per axis, so a four-corner routine would be averaging away a tilt the map cannot express anyway.

Definition in file touch_cal.h.

Macro Definition Documentation

◆ TOUCH_CAL_MIN_SPAN

#define TOUCH_CAL_MIN_SPAN   500

Solve the edge-to-edge raw range from two corner taps.

The targets sit inset pixels in from the top-left and bottom-right corners of a w x h panel; r0 and r1 are the raw counts captured at each. Both axes are extended past their target by the same inset, at the counts-per-pixel the two taps imply.

Parameters
r0x,r0yRaw counts at the top-left target.
r1x,r1yRaw counts at the bottom-right target.
insetTarget centre, in pixels from each corner.
w,hPanel size in pixels.
[out]outFilled only on success.
Returns
false — and out untouched — when an axis spans less than TOUCH_CAL_MIN_SPAN counts between the two taps. That is a stuck panel, a mirrored axis this map cannot express, or two taps on the same spot; storing any of them makes the panel untappable, including the screen that would fix it.

Definition at line 59 of file touch_cal.h.

Referenced by touch_cal_from_corners().

◆ TOUCH_CAL_RAW_MAX

#define TOUCH_CAL_RAW_MAX   4095

Full scale of the XPT2046's 12-bit converter.

Definition at line 61 of file touch_cal.h.

Referenced by touch_cal_clamp().

◆ TOUCH_JUMP_MAX_PX

#define TOUCH_JUMP_MAX_PX   25

Second-contact guard: hold the first finger's point while two are down.

The XPT2046 returns ONE point per read. Two fingers do not read as two touches — they read as a single sample somewhere on the line between them, pulled toward whichever presses harder. LVGL then does what it does for any press that slides: it re-targets, and the widget under that midpoint takes the click. An operator resting a thumb on the glass while tapping therefore lands the tap halfway between thumb and finger — a wrong digit, or Charge.

Two signals, because position alone is not enough. The reported point lands midway between the contacts, so its jump is only HALF their separation: a thumb one key away from the finger moves the sample a dozen pixels, which no distance threshold can tell from a finger rolling under its own tap. Pressure does not care how far apart they are — a second contact is a second resistive path in parallel, so z steps up the moment it lands, and by the same amount whether the fingers are 10px or 100px apart.

  • z rises TOUCH_Z_STEP_PCT above the lightest press seen so far, or
  • the point jumps more than TOUCH_JUMP_MAX_PX, which no finger can cross in one read period.

Either one holds x and y at the last accepted point — the first finger's — until the panel is back to one touch.

Over-triggering is close to free, which is what lets the pressure test be blunt: one finger simply bearing down harder also steps z, and all that happens is a point that was not moving stops being allowed to move.

Only safe where nothing legitimately jumps — a screen of taps. A slider drag or a flicked list crosses far more than this in one period and must not go through here.

Parameters
stFilter state; zero-initialise once, then leave alone.
pressedWhether the panel reports a touch this read.
zRaw XPT2046 pressure for this read; ignored when 0, so a caller with no pressure to offer still gets the distance test.
[in,out]x,yScreen coordinates, held back on a second contact.

Definition at line 135 of file touch_cal.h.

Referenced by touch_jump_second_contact().

◆ TOUCH_Z_STEP_PCT

#define TOUCH_Z_STEP_PCT   30

Definition at line 147 of file touch_cal.h.

Referenced by touch_jump_second_contact().

Function Documentation

◆ touch_cal_clamp()

uint16_t touch_cal_clamp ( int32_t v)
inlinestatic

Definition at line 68 of file touch_cal.h.

References TOUCH_CAL_RAW_MAX.

Referenced by touch_cal_from_corners().

◆ touch_cal_from_corners()

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 )
inlinestatic

◆ touch_jump_filter()

void touch_jump_filter ( touch_jump_t * st,
bool pressed,
int16_t z,
int16_t * x,
int16_t * y )
inlinestatic

◆ touch_jump_second_contact()

bool touch_jump_second_contact ( const touch_jump_t * st,
int16_t z,
int16_t x,
int16_t y )
inlinestatic