Two touch controllers, one contact set: the glass's GT911 at 0x5D and a touch injector at 0x14 (testbench/touch-injector), merged into the frame the tracker sees. Pure C; the panel compiles the I/O around it in a build with RCBENCH_TOUCH_INJECTOR (the default), and the host suite tests it.
More...
|
|
#define | TOUCH_MERGE_GLASS_ADDR 0x5Du |
| | The glass's GT911 address; the GT911's first strap address.
|
|
#define | TOUCH_MERGE_INJECT_ADDR 0x14u |
| | The touch injector's address; the GT911's second strap address, which the glass latches instead when its INT line is low at the end of its reset.
|
| #define | TOUCH_MERGE_INJECT_PRODUCT "9INJ" |
| | The product ID the touch injector reports at 0x8140..0x8143: 4 ASCII bytes, no NUL.
|
|
#define | TOUCH_MERGE_INJECT_ID 0x80u |
| | Set in the track id of every injected contact.
|
|
#define | TOUCH_MERGE_FAIL_DROP 3u |
| | Failed injector reads in a row before its contacts are dropped.
|
|
#define | TOUCH_MERGE_RETRY_MS 100u |
| | Once dropped, the injector is asked again after this many ms.
|
|
#define | TOUCH_MERGE_DETACH_MS 1000u |
| | An injector with no good read for this many ms is detached.
|
|
#define | TOUCH_MERGE_PROBE_MS 1000u |
| | A detached injector is probed at most once in this many ms.
|
|
| bool | touch_merge_is_injector (const char *product_id) |
| | Whether product_id is the touch injector's.
|
| touch_role_t | touch_merge_role (uint16_t addr, bool glass_found, const char *product_id) |
| | The role of a controller that answered as a GT911 at start-up.
|
| touch_map_t | touch_merge_role_map (touch_role_t role, const touch_map_t *glass, const touch_map_t *inject, bool turned) |
| | The map for one report of a controller with role role.
|
| void | touch_merge_reset (touch_merge_t *m) |
| | Forget both sets: no contacts, the injector attached at 0ms.
|
| void | touch_merge_attach (touch_merge_t *m, uint32_t now_ms) |
| | Reset, with the injector attached and answering at now_ms.
|
| void | touch_merge_start (touch_merge_t *m, bool answered, uint32_t now_ms) |
| | The start-up look for the injector.
|
| bool | touch_merge_attached (const touch_merge_t *m) |
| | Whether the injector is attached: false once detached, until a probe.
|
| bool | touch_merge_expire (touch_merge_t *m, uint32_t now_ms) |
| | Detach the injector when its last good read is TOUCH_MERGE_DETACH_MS or more old. Detaching drops its contacts.
|
| bool | touch_merge_probe_due (const touch_merge_t *m, uint32_t now_ms) |
| | Whether a detached injector is due to be probed: TOUCH_MERGE_PROBE_MS after the detach and after every probe. Never for an absent one.
|
| bool | touch_merge_probe (touch_merge_t *m, bool answered, uint32_t now_ms) |
| | A detached injector was probed.
|
| void | touch_merge_glass (touch_merge_t *m, const touch_point_t *pts, int n) |
| | The glass reported a new contact set (0 points when every finger lifted). Injected contacts the frame no longer has room for are cut.
|
| bool | touch_merge_inject_due (const touch_merge_t *m, uint32_t now_ms) |
| | Whether the injector is due to be asked: on every poll while it answers, and every TOUCH_MERGE_RETRY_MS once it has failed TOUCH_MERGE_FAIL_DROP times in a row.
|
| bool | touch_merge_inject (touch_merge_t *m, const touch_point_t *pts, int n, bool fresh, uint32_t now_ms) |
| | The injector answered at now_ms.
|
| bool | touch_merge_inject_failed (touch_merge_t *m, uint32_t now_ms) |
| | An injector read failed.
|
| int | touch_merge_frame (const touch_merge_t *m, touch_point_t *out, int max) |
| | The merged set: the glass's contacts, then the injector's that are not cut, TOUCH_MAX_POINTS at most.
|
| int | touch_merge_mark_cut (const touch_merge_t *m, touch_event_t *evts, int n) |
| | Mark the UP of every cut injected contact TOUCH_FLAG_NO_TAP.
|
| static uint32_t | touch_merge_age (uint32_t glass_age_ms, uint32_t inject_age_ms) |
| | How old touch is: the older of the two sources' ages.
|
| static uint32_t | touch_merge_inject_age (bool attached, uint32_t ok_ms, uint32_t now_ms) |
| | The injector's share of touch age.
|
Two touch controllers, one contact set: the glass's GT911 at 0x5D and a touch injector at 0x14 (testbench/touch-injector), merged into the frame the tracker sees. Pure C; the panel compiles the I/O around it in a build with RCBENCH_TOUCH_INJECTOR (the default), and the host suite tests it.
Rules:
- The glass's contacts come first, unchanged. A frame holds at most TOUCH_MAX_POINTS contacts, so an injected contact is the one left out when the two together have more; a contact on the glass, STOP among them, never is.
- The injected contact left out is cut: the newest first, then the last in the injector's report. A cut contact stays out until the injector lifts it, so a finger lifting from the glass never brings it back as a new press. The UP the tracker makes for it carries TOUCH_FLAG_NO_TAP (touch_merge_mark_cut()): it did not lift, and only a control that stops what the bench drives acts on it.
- An injected contact's track id has TOUCH_MERGE_INJECT_ID set, so it never shares an id with a finger on the glass, whatever the two report and wherever they are: a finger and an injected contact on the same pixel are two contacts.
- A source with no new report keeps its last set.
- An injector that fails TOUCH_MERGE_FAIL_DROP reads in a row loses its contacts: the tracker then sends an UP for each, as for a finger the glass stops reporting. After that it is asked once every TOUCH_MERGE_RETRY_MS, so a dead injector costs the glass's poll at most one failed read in that time.
- Touch is as old as the older of the two sources (touch_merge_age()): an injector that stops answering is touch that stops answering, and the bench goes SAFE as it does for the glass.
- An injector with no good read for TOUCH_MERGE_DETACH_MS is detached (touch_merge_expire()): its contacts are dropped, it is no longer read, and its age no longer counts (touch_merge_inject_age()), so the glass alone decides how old touch is. By then touch has read as dead and the bench has disarmed; nothing arms again without a new arm.
- The injector is looked for once, at start-up (touch_merge_start()). One that does not answer then is absent until the next start: it is never read, probed or counted, whatever the bus does later, and the glass is the only touch.
- A detached injector is probed once every TOUCH_MERGE_PROBE_MS. The first probe it answers re-attaches it with no contacts and an age of 0 (touch_merge_probe()). Its age stays under TOUCH_MERGE_DETACH_MS whatever it does, so an injector that answers and falls silent by turns withholds touch for at most the span from touch reading as dead to the detach.
SPDX-License-Identifier: MIT
| #define TOUCH_MERGE_INJECT_PRODUCT "9INJ" |
The product ID the touch injector reports at 0x8140..0x8143: 4 ASCII bytes, no NUL.
A Goodix controller reports its part number there, digits with at most one trailing letter: "911" and a NUL on the GT911 the panel's glass carries, "9271", "917S". This ID has letters from its second byte on, so no glass reports it. '9' first keeps the GT911 driver's probe, which wants a '9' there, accepting it. testbench/touch-injector reports it (GT911_EMU_PRODUCT_ID).