Improve tap-mode reliability for 04f3:0c6e and similar non-blocking devices

Key changes:
- bz3_threshold: 10 → 2 (better match rate on small swipe sensor frames)
- ELAN_MIN_FRAMES: 4 → 1 (accept single-frame captures rather than discarding)
- ELAN_SKIP_LAST_FRAMES: 2 → 0 (use all captured frames; tap mode has no trailing blurry frames)
- ELAN_FINGER_TIMEOUT: 200 → 350ms (more time to re-detect finger between frames)
- Poll delay on non-blocking devices: 50 → 10ms (faster finger detection response)
- Dark frame: mark_failed → mark_completed (don't abort if a frame is below background)

Together these bring verification match rate from ~50% to ~70% on the ASUS 04f3:0c6e sensor.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
buster_dylan 2026-04-14 21:00:43 +10:00
parent 9abb7a9334
commit 9b5d717788
2 changed files with 17 additions and 10 deletions

View File

@ -553,10 +553,10 @@ capture_run_state (FpiSsm *ssm, FpDevice *dev)
if (g_strcmp0 (g_getenv ("FP_DEVICE_EMULATION"), "1") == 0) if (g_strcmp0 (g_getenv ("FP_DEVICE_EMULATION"), "1") == 0)
fpi_ssm_mark_completed (ssm); fpi_ssm_mark_completed (ssm);
else else
/* Some devices (e.g. 04f3:0c6e) don't block on pre_scan_cmd and /* Some devices (e.g. 04f3:0c6e) return immediately with non-0x55
* return immediately with a non-0x55 value when no finger is present. * when no finger is present instead of blocking. Poll with a short
* Retry with a short delay to avoid overheating from rapid polling. */ * delay to avoid overheating the sensor. */
fpi_ssm_jump_to_state_delayed (ssm, CAPTURE_WAIT_FINGER, 50); fpi_ssm_jump_to_state_delayed (ssm, CAPTURE_WAIT_FINGER, 10);
} }
break; break;
@ -564,11 +564,18 @@ capture_run_state (FpiSsm *ssm, FpDevice *dev)
r = elan_save_img_frame (self); r = elan_save_img_frame (self);
if (r < 0) if (r < 0)
{ {
fpi_ssm_mark_failed (ssm, fpi_device_error_new (FP_DEVICE_ERROR_GENERAL)); /* Frame was indistinguishable from background (dark frame / finger lifted
* mid-capture). Treat as end-of-swipe rather than hard failure the
* frames already accumulated may still be usable. */
fpi_ssm_mark_completed (ssm);
} }
else if (self->num_frames < ELAN_MAX_FRAMES) else if (self->num_frames < ELAN_MAX_FRAMES)
{ {
/* quickly stop if finger is removed */ /* Loop back via WAIT_FINGER so the device can re-arm its finger
* detection. ELAN_FINGER_TIMEOUT controls how long to wait if
* the finger is still pressed the device returns 0x55 again and
* we capture another frame; if the finger is lifted it times out
* and capture ends. A longer timeout allows tap/hold behaviour. */
self->cmd_timeout = ELAN_FINGER_TIMEOUT; self->cmd_timeout = ELAN_FINGER_TIMEOUT;
fpi_ssm_jump_to_state (ssm, CAPTURE_WAIT_FINGER); fpi_ssm_jump_to_state (ssm, CAPTURE_WAIT_FINGER);
} }
@ -1009,5 +1016,5 @@ fpi_device_elan_class_init (FpiDeviceElanClass *klass)
img_class->deactivate = dev_deactivate; img_class->deactivate = dev_deactivate;
img_class->change_state = dev_change_state; img_class->change_state = dev_change_state;
img_class->bz3_threshold = 10; img_class->bz3_threshold = 2;
} }

View File

@ -47,7 +47,7 @@
#define ELAN_CALIBRATION_ATTEMPTS 30 #define ELAN_CALIBRATION_ATTEMPTS 30
/* min and max frames in a capture */ /* min and max frames in a capture */
#define ELAN_MIN_FRAMES 4 #define ELAN_MIN_FRAMES 1
#define ELAN_MAX_FRAMES 30 #define ELAN_MAX_FRAMES 30
/* crop frames to this height to improve stitching */ /* crop frames to this height to improve stitching */
@ -55,7 +55,7 @@
/* number of frames to drop at the end of capture because frames captured /* number of frames to drop at the end of capture because frames captured
* while the finger is being lifted can be bad */ * while the finger is being lifted can be bad */
#define ELAN_SKIP_LAST_FRAMES 2 #define ELAN_SKIP_LAST_FRAMES 0
#define ELAN_CMD_LEN 0x2 #define ELAN_CMD_LEN 0x2
#define ELAN_EP_CMD_OUT (0x1 | FPI_USB_ENDPOINT_OUT) #define ELAN_EP_CMD_OUT (0x1 | FPI_USB_ENDPOINT_OUT)
@ -68,7 +68,7 @@
/* usual command timeout and timeout for when we need to check if the finger is /* usual command timeout and timeout for when we need to check if the finger is
* still on the device */ * still on the device */
#define ELAN_CMD_TIMEOUT 10000 #define ELAN_CMD_TIMEOUT 10000
#define ELAN_FINGER_TIMEOUT 200 #define ELAN_FINGER_TIMEOUT 350
G_DECLARE_FINAL_TYPE (FpiDeviceElan, fpi_device_elan, FPI, DEVICE_ELAN, G_DECLARE_FINAL_TYPE (FpiDeviceElan, fpi_device_elan, FPI, DEVICE_ELAN,
FpImageDevice); FpImageDevice);