Skip to content

Instantly share code, notes, and snippets.

@Gkiokan
Created March 8, 2026 15:15
Show Gist options
  • Select an option

  • Save Gkiokan/8aefe4cdb439e4bf2c6c6fda1f7857db to your computer and use it in GitHub Desktop.

Select an option

Save Gkiokan/8aefe4cdb439e4bf2c6c6fda1f7857db to your computer and use it in GitHub Desktop.
pa5x ribbon controll board debugg
[FOUND] I2C device found at address 0x0B
@Gkiokan
Copy link
Copy Markdown
Author

Gkiokan commented Mar 8, 2026

Wiring Map: ESP32 to Korg Ribbon

Ribbon Pin (CN6) Name ESP32 GPIO Description
Pin 1 nc  nc  nc
Pin 2 nc  nc  nc
Pin 3 SWD_DATA nc Programming data line (Currently unused for I2C).
Pin 4 XRES GPIO 4 Hardware Reset. Pulled LOW to reset, HIGH to run.
Pin 5 SWD_CLK nc Programming clock line. (Currently unused).
Pin 6 PANEL_INT GPIO 18 Interrupt. Ribbon pulls this LOW when it has data.
Pin 7 SCL GPIO 22 I2C Clock line (requires a pull-up resistor).
Pin 8 GND GND Common ground reference.
Pin 9 SDA GPIO 21 I2C Data line (requires a pull-up resistor).
Pin 10 +3.3V 3.3V Power supply for the PSoC 4.

@Gkiokan
Copy link
Copy Markdown
Author

Gkiokan commented Mar 8, 2026

Analyzing the HEX file for the CY8C4146 has revealed the exact "Lock" mechanism. Korg’s firmware is using a classic EZI2C (Easy I2C) buffer with a strict Read/Write boundary.

Discovery 1: The "Identity" Header

In the hex data, I found the sequence at the very beginning of the data segment:
0D F0 7E 02 10 B1 05 04 ...
This corresponds exactly to what you are seeing in Registers 00-07 in your serial monitor. This isn't just a heartbeat; it's the chip's Product ID Header.

Discovery 2: The Command Gate (Reg 0x08)

The logic surrounding the I2C interrupt shows a branch that checks Register 0x08.

In your dump, Reg [08] is 24 (0x18).

In the firmware code, there is a comparison: if a master writes to this register, the chip evaluates a "State Machine."

The "Magic" Write: The code suggests that sending a specific bitmask to Reg 08 is what tells the PSoC to stop the internal "Demo Loop" and start the CapSense scanning engine.

Discovery 3: The Write Boundary

The EZI2C component in this chip is configured with a boundary at 0x08.

Registers 00-07: Read-Only (System Info).

Registers 08-15: Read/Write (Control & Configuration).

Registers 16-31: Read-Only (Live Sensor Data).

The "Unlock" Solution

To break the loop, you must write a specific "Enable" command to the control registers. Based on the hex analysis, the chip expects a "Sensing Start" bit.

@Gkiokan
Copy link
Copy Markdown
Author

Gkiokan commented Mar 9, 2026

cn6 pin at ribbon / esp pin
10 - 3.3v
8 GND - GND
4 XRES_RIBBON - GPIO 4
9 SDA - SDA 21
7 SCL - SCL 22
6 PANEL_INT - 18

@Gkiokan
Copy link
Copy Markdown
Author

Gkiokan commented Mar 9, 2026

SDA Pull-up: Connect one resistor between CN6 Pin 9 (GPIO 21) and 3.3V (CN6 Pin 10).

SCL Pull-up: Connect the second resistor between CN6 Pin 7 (GPIO 22) and 3.3V (CN6 Pin 10).

@Gkiokan
Copy link
Copy Markdown
Author

Gkiokan commented Mar 9, 2026

02:13:18.658 -> Status: Mode=00, Watchdog=00
02:13:18.658 -> ---------------------------------------------------------
02:13:19.145 -> 0x00 | 0D F0 7E 02 10 E1 05 04 | 18 00 02 00 E8 F7 00 00
02:13:19.145 -> 0x10 | 00 00 00 00 00 00 00 00 | 00 00 00 00 00 00 00 00
02:13:19.145 -> Status: Mode=18, Watchdog=E1
02:13:19.177 -> ---------------------------------------------------------
02:13:19.667 -> 0x00 | 00 00 00 00 00 00 00 00 | 00 00 00 00 00 00 00 00
02:13:19.667 -> 0x10 | 00 00 00 00 00 00 00 00 | 00 00 00 00 00 00 00 00
02:13:19.667 -> Status: Mode=00, Watchdog=00
02:13:19.667 -> ---------------------------------------------------------
02:13:20.189 -> 0x00 | 0D F0 7E 02 10 F1 05 04 | 18 00 02 00 F8 F7 00 00
02:13:20.189 -> 0x10 | 00 00 00 00 00 00 00 00 | 00 00 00 00 00 00 00 00
02:13:20.189 -> Status: Mode=18, Watchdog=F1
02:13:20.189 -> ---------------------------------------------------------
02:13:20.712 -> 0x00 | 00 00 00 00 00 00 00 00 | 00 00 00 00 00 00 00 00
02:13:20.712 -> 0x10 | 00 00 00 00 00 00 00 00 | 00 00 00 00 00 00 00 00
02:13:20.712 -> Status: Mode=00, Watchdog=00
02:13:20.712 -> ---------------------------------------------------------
02:13:21.198 -> 0x00 | 0D F0 7E 02 10 01 05 04 | 18 00 02 00 08 F7 00 00
02:13:21.198 -> 0x10 | 00 00 00 00 00 00 00 00 | 00 00 00 00 00 00 00 00
02:13:21.231 -> Status: Mode=18, Watchdog=01
02:13:21.231 -> ---------------------------------------------------------
02:13:21.716 -> 0x00 | 00 00 00 00 00 00 00 00 | 00 00 00 00 00 00 00 00
02:13:21.716 -> 0x10 | 00 00 00 00 00 00 00 00 | 00 00 00 00 00 00 00 00
02:13:21.716 -> Status: Mode=00, Watchdog=00
02:13:21.748 -> ---------------------------------------------------------
02:13:22.233 -> 0x00 | 0D F0 7E 02 10 11 05 04 | 18 00 02 00 18 F7 00 00
02:13:22.233 -> 0x10 | 00 00 00 00 00 00 00 00 | 00 00 00 00 00 00 00 00
02:13:22.233 -> Status: Mode=18, Watchdog=11
02:13:22.233 -> ---------------------------------------------------------
02:13:22.751 -> 0x00 | 00 00 00 00 00 00 00 00 | 00 00 00 00 00 00 00 00
02:13:22.751 -> 0x10 | 00 00 00 00 00 00 00 00 | 00 00 00 00 00 00 00 00
02:13:22.751 -> Status: Mode=00, Watchdog=00
02:13:22.751 -> ---------------------------------------------------------
02:13:23.271 -> 0x00 | 0D F0 7E 02 10 21 05 04 | 18 00 02 00 28 F7 00 00
02:13:23.271 -> 0x10 | 00 00 00 00 00 00 00 00 | 00 00 00 00 00 00 00 00
02:13:23.271 -> Status: Mode=18, Watchdog=21
02:13:23.271 -> ---------------------------------------------------------

@Gkiokan
Copy link
Copy Markdown
Author

Gkiokan commented Mar 9, 2026


/* WARNING: Globals starting with '_' overlap smaller symbols at the same address */

undefined4 FUN_00000c24(int param_1)

{
  undefined2 uVar1;
  short sVar2;
  undefined2 uVar3;
  short sVar4;
  bool bVar5;
  undefined4 *puVar6;
  char cVar7;
  undefined1 uVar8;
  short sVar9;
  int iVar10;
  int *piVar11;
  undefined4 uVar12;
  byte bVar13;
  int extraout_r1;
  int extraout_r1_00;
  uint extraout_r1_01;
  uint uVar14;
  byte bVar15;
  int iVar16;
  ushort uVar17;
  int *piVar18;
  uint uVar19;
  int iVar20;
  uint uVar21;
  code *pcVar22;
  code *pcVar23;
  uint uVar24;
  int iVar25;
  ushort *puVar26;
  undefined1 *puVar27;
  undefined1 *puVar28;
  uint uVar29;
  uint uVar30;
  byte *pbVar31;
  ushort uVar32;
  undefined2 uStack_44;
  int *piStack_40;
  undefined4 uStack_30;
  undefined1 uStack_2c;
  
  *DAT_00000f9c = *DAT_00000f9c | 1;
  piVar18 = DAT_00000fd8;
  iVar10 = DAT_00000fd4;
  iVar25 = DAT_00000fd0;
  iVar16 = DAT_00000fcc;
  cVar7 = *(char *)(param_1 + DAT_00000fa0);
  if (cVar7 == '\0') {
    *(undefined1 *)(param_1 + DAT_00000fcc) = *DAT_00000fe0;
    *(undefined1 *)(param_1 + DAT_00000fd0) = 0;
    iVar16 = DAT_00000fd4;
    *(undefined1 *)(param_1 + DAT_00000fd4) = 2;
    *(undefined1 *)(param_1 + iVar16 + 1) = 0;
    piVar11 = (int *)*piVar18;
    if (*(code **)(*piVar11 + 0x14) != DAT_00000fdc) {
      piVar11 = (int *)FUN_0000161a();
    }
    if (((uint)(piVar11[3] - piVar11[4]) < (uint)piVar11[2]) &&
       (3 < (uint)(piVar11[2] - (piVar11[3] - piVar11[4])))) {
      iVar16 = *piVar18;
      if ((*(uint *)(iVar16 + 8) <= (uint)(*(int *)(iVar16 + 0xc) - *(int *)(iVar16 + 0x10))) ||
         ((uint)(*(int *)(iVar16 + 8) - (*(int *)(iVar16 + 0xc) - *(int *)(iVar16 + 0x10))) < 4)) {
        do {
                    /* WARNING: Do nothing block with infinite loop */
        } while( true );
      }
      uVar19 = *(uint *)(iVar16 + 0xc);
      *(undefined1 *)(*(int *)(iVar16 + 0x18) + (uVar19 & *(uint *)(iVar16 + 0x14))) =
           *(undefined1 *)(param_1 + DAT_00000fcc);
      *(undefined1 *)(*(int *)(iVar16 + 0x18) + (uVar19 + 1 & *(uint *)(iVar16 + 0x14))) =
           *(undefined1 *)(param_1 + DAT_00000fd0);
      *(undefined1 *)(*(int *)(iVar16 + 0x18) + (uVar19 + 2 & *(uint *)(iVar16 + 0x14))) =
           *(undefined1 *)(param_1 + DAT_00000fd4);
      *(undefined1 *)(*(int *)(iVar16 + 0x18) + (uVar19 + 3 & *(uint *)(iVar16 + 0x14))) =
           *(undefined1 *)(param_1 + 0x238);
      *(uint *)(iVar16 + 0xc) = uVar19 + 4;
    }
    *(undefined1 *)(param_1 + DAT_00000fe4) = 1;
    *(undefined1 *)(param_1 + DAT_00000fa0) = 1;
    return 0;
  }
  if (cVar7 == '\x01') {
    cVar7 = *(char *)(param_1 + DAT_00000fe4);
    do {
      if (cVar7 == '\0') {
        *(undefined2 *)(param_1 + DAT_00000fe8) = 0;
        *(undefined1 *)(param_1 + DAT_00000fa0) = 2;
        return 0;
      }
      *(undefined1 *)(param_1 + iVar16) = 4;
      *(undefined1 *)(param_1 + iVar25) = 8;
      *(undefined1 *)(param_1 + iVar10) = 0;
      piVar11 = (int *)piVar18[1];
      if (*(code **)(*piVar11 + 0x14) == DAT_00000fdc) {
        if ((uint)piVar11[2] <= (uint)(piVar11[3] - piVar11[4])) {
          cVar7 = *(char *)(param_1 + DAT_00000fa0);
          goto LAB_00000c54;
        }
        uVar19 = piVar11[2] - (piVar11[3] - piVar11[4]);
      }
      else {
        uVar19 = (**(code **)(*piVar11 + 0x14))();
      }
      if (uVar19 < 3) {
        FUN_00001a1a();
      }
      iVar20 = piVar18[1];
      if ((*(uint *)(iVar20 + 8) <= (uint)(*(int *)(iVar20 + 0xc) - *(int *)(iVar20 + 0x10))) ||
         ((uint)(*(int *)(iVar20 + 8) - (*(int *)(iVar20 + 0xc) - *(int *)(iVar20 + 0x10))) < 3)) {
        do {
                    /* WARNING: Do nothing block with infinite loop */
        } while( true );
      }
      uVar19 = *(uint *)(iVar20 + 0xc);
      *(undefined1 *)(*(int *)(iVar20 + 0x18) + (uVar19 & *(uint *)(iVar20 + 0x14))) =
           *(undefined1 *)(param_1 + iVar16);
      *(undefined1 *)(*(int *)(iVar20 + 0x18) + (uVar19 + 1 & *(uint *)(iVar20 + 0x14))) =
           *(undefined1 *)(param_1 + iVar25);
      *(undefined1 *)(*(int *)(iVar20 + 0x18) + (uVar19 + 2 & *(uint *)(iVar20 + 0x14))) =
           *(undefined1 *)(param_1 + iVar10);
      *(uint *)(iVar20 + 0xc) = uVar19 + 3;
      cVar7 = *(char *)(param_1 + DAT_00000fe4) + -1;
      *(char *)(param_1 + DAT_00000fe4) = cVar7;
    } while( true );
  }
  if (cVar7 == '\x02') {
    if (*(ushort *)(param_1 + DAT_00001000) < 0x32) {
      *(ushort *)(param_1 + DAT_00001000) = *(ushort *)(param_1 + DAT_00001000) + 1;
      return 0;
    }
    *(undefined2 *)(param_1 + DAT_00001000) = 0;
    FUN_0000595c();
    iVar16 = DAT_0000171c;
    if (-1 < *(int *)(DAT_0000171c + 0xc) << 0x18) goto LAB_000015e4;
    do {
      do {
        *(undefined1 *)(param_1 + DAT_00001720) = 3;
        FUN_00000c5e();
LAB_000015e4:
      } while (((*(uint *)(iVar16 + 0xc) & 0x10000) != 0) || ((*(uint *)(iVar16 + 0x10) & 1) == 0));
      FUN_000055ac(0);
      *DAT_00001724 = 0;
      if (((*(uint *)(iVar16 + 0xc) & 0x10000) == 0) && (*DAT_00001728 == '\x01')) {
        FUN_0000517c();
      }
    } while( true );
  }
LAB_00000c54:
  pcVar22 = _DAT_0000170c;
  puVar6 = DAT_00000fa8;
  iVar16 = DAT_00000fa4;
  if (cVar7 != '\x03') {
LAB_00000eb6:
    if (cVar7 != '\x04') {
      return 0;
    }
LAB_00000d4c:
    piVar18 = DAT_00000fd8;
    piVar11 = (int *)DAT_00000fd8[1];
    if (*(code **)(*piVar11 + 0x14) == DAT_00000fdc) {
      uVar19 = 0;
      if ((uint)(piVar11[3] - piVar11[4]) < (uint)piVar11[2]) {
        uVar19 = piVar11[2] - (piVar11[3] - piVar11[4]);
      }
    }
    else {
      uVar19 = (**(code **)(*piVar11 + 0x14))(piVar11);
    }
    uVar29 = (uint)*(byte *)(param_1 + DAT_00000fac);
    if (uVar29 <= uVar19) {
      iVar16 = piVar18[1];
      iVar25 = DAT_00000fcc + param_1;
      uVar19 = 0;
      if ((uint)(*(int *)(iVar16 + 0xc) - *(int *)(iVar16 + 0x10)) < *(uint *)(iVar16 + 8)) {
        FUN_00001744();
        iVar16 = extraout_r1;
      }
      if (uVar19 < uVar29) {
        FUN_00001740();
        iVar16 = extraout_r1_00;
      }
      iVar10 = 0;
      uStack_30 = *(uint *)(iVar16 + 0xc);
      if (uVar29 != 0) {
        do {
          uVar19 = uStack_30 + 1;
          puVar27 = (undefined1 *)(iVar25 + iVar10);
          iVar10 = iVar10 + 1;
          *(undefined1 *)(*(int *)(iVar16 + 0x18) + (*(uint *)(iVar16 + 0x14) & uStack_30)) =
               *puVar27;
          uStack_30 = uVar19;
        } while (iVar10 < (int)uVar29);
      }
      *(uint *)(iVar16 + 0xc) = uStack_30;
      *(undefined1 *)(param_1 + DAT_00000fa0) = 3;
    }
    return 0;
  }
  piVar18 = (int *)*DAT_00000fa8;
  if ((char)piVar18[7] != '\0') {
    uVar19 = piVar18[3] - piVar18[4];
    if ((uVar19 & 0xffff) != 0) {
      uStack_44 = (undefined2)uVar19;
      if ((uVar19 & 0xffff) == 0) {
        puVar28 = &DAT_20000c20;
        uRam20000c2e = uStack_44;
        iRam20000c28 = param_1 + 0x29;
        uRam20000c2c = uStack_44;
      }
      else {
        puVar27 = (undefined1 *)(param_1 + 0x29);
        while( true ) {
          uVar29 = uStack_30;
          if (*(code **)(*piVar18 + 0x10) == pcVar22) {
            uStack_30 = uStack_30 & 0xffffff00;
            uVar8 = 0;
            if (piVar18[3] != piVar18[4]) {
              uStack_30 = CONCAT31(SUB43(uVar29,1),1);
              uVar8 = *(undefined1 *)(piVar18[6] + (piVar18[4] & piVar18[5]));
              piVar18[4] = piVar18[4] + 1;
            }
            *puVar27 = uVar8;
            puVar28 = _DAT_00001710;
          }
          else {
            uVar8 = (**(code **)(*piVar18 + 0x10))(piVar18,&uStack_30);
            *puVar27 = uVar8;
            puVar28 = _DAT_00001710;
          }
          _DAT_00001710 = puVar28;
          if ((undefined1 *)((uVar19 & 0xffff) + 0x29 + param_1) == puVar27 + 1) break;
          puVar27 = puVar27 + 1;
          piVar18 = (int *)*puVar6;
        }
        *(undefined2 *)(puVar28 + 0xc) = 0;
        *(undefined1 **)(puVar28 + 8) = (undefined1 *)(param_1 + 0x29);
        *(undefined2 *)(puVar28 + 0xe) = uStack_44;
      }
      iVar10 = param_1 + 0x29;
      uVar19 = 0;
      iVar25 = iVar16;
LAB_00001490:
      pbVar31 = (byte *)(iVar10 + uVar19);
      bVar13 = *pbVar31 >> 6;
      puVar28[0x1c] = bVar13;
      uVar29 = (int)(uint)*pbVar31 >> 5 & 1;
      puVar28[0x1e] = (char)uVar29;
      uVar21 = (int)(uint)*pbVar31 >> 4 & 1;
      uVar8 = (undefined1)uVar21;
      puVar28[0x1d] = uVar8;
      uVar14 = *pbVar31 & 0xf;
      puVar28[0x1f] = (char)uVar14;
      if (uVar29 == 1) {
        uVar29 = uVar19 + 1 & 0xffff;
        sVar4 = (short)(uVar19 + 1);
        *(short *)(puVar28 + 0xc) = sVar4;
        uVar32 = (ushort)*(byte *)(iVar10 + uVar29);
        *(ushort *)(puVar28 + 0x20) = (ushort)*(byte *)(iVar10 + uVar29);
        pcVar22 = _DAT_00001714;
        piVar18 = *(int **)(uVar14 * 4 + *(int *)(puVar28 + 4));
        if (piVar18 != (int *)0x0) {
          uVar17 = uVar32;
          if (uVar32 != 0) {
            do {
              if (uVar32 == uVar17) {
                puVar28[0x2c] = bVar13;
                puVar28[0x2d] = puVar28[0x1d];
              }
              *(short *)(puVar28 + 0xc) = (short)(uVar29 + 1);
              puVar28[0x24] = *(undefined1 *)(iVar10 + (uVar29 + 1 & 0xffff));
              if (bVar13 == 0) {
                *(short *)(puVar28 + 0xc) = (short)(uVar29 + 2);
                puVar28[0x2e] = *(undefined1 *)(iVar10 + (uVar29 + 2 & 0xffff));
                pcVar23 = *(code **)(*piVar18 + 8);
                if (pcVar23 != pcVar22) goto LAB_00001584;
LAB_00001518:
                if (puVar28[0x2d] == '\x01') {
                  *(undefined1 **)(*(int *)piVar18[1] + 4) = puVar28 + 0x24;
                  piStack_40 = *(int **)piVar18[1];
                }
                else if (puVar28[0x2d] == '\0') {
                  *(undefined1 **)(*(int *)piVar18[2] + 4) = puVar28 + 0x24;
                  piStack_40 = *(int **)piVar18[2];
                }
                (**(code **)(*piStack_40 + 8))();
              }
              else {
                if (bVar13 == 1) {
                  *(short *)(puVar28 + 0xc) = (short)(uVar29 + 2);
                  puVar28[0x2e] = *(undefined1 *)(iVar10 + (uVar29 + 2 & 0xffff));
                  *(short *)(puVar28 + 0xc) = (short)(uVar29 + 3);
                  puVar28[0x2f] = *(undefined1 *)(iVar10 + (uVar29 + 3 & 0xffff));
                }
                else if (bVar13 == 2) {
                  *(short *)(puVar28 + 0xc) = (short)(uVar29 + 2);
                  puVar28[0x2e] = *(undefined1 *)(iVar10 + (uVar29 + 2 & 0xffff));
                  *(short *)(puVar28 + 0xc) = (short)(uVar29 + 3);
                  puVar28[0x2f] = *(undefined1 *)(iVar10 + (uVar29 + 3 & 0xffff));
                  *(short *)(puVar28 + 0xc) = (short)(uVar29 + 4);
                  puVar28[0x30] = *(undefined1 *)(iVar10 + (uVar29 + 4 & 0xffff));
                }
                pcVar23 = *(code **)(*piVar18 + 8);
                if (pcVar23 == pcVar22) goto LAB_00001518;
LAB_00001584:
                piVar11 = (int *)(*pcVar23)(piVar18,_DAT_00001718);
                (**(code **)(*piVar11 + 8))();
              }
              uVar32 = uVar32 - 1;
              if (uVar32 == 0) goto LAB_00001594;
              bVar13 = puVar28[0x1c];
              iVar10 = *(int *)(puVar28 + 8);
              uVar29 = (uint)*(ushort *)(puVar28 + 0xc);
              uVar17 = *(ushort *)(puVar28 + 0x20);
            } while( true );
          }
          goto LAB_00001480;
        }
        sVar2 = *(short *)(puVar28 + 0x20);
        sVar9 = sVar2;
        if (bVar13 == 2) {
          do {
            if (sVar9 == sVar2) {
              puVar28[0x2c] = 2;
              puVar28[0x2d] = uVar8;
            }
            *(short *)(puVar28 + 0xc) = (short)(uVar29 + 1);
            sVar9 = sVar9 + -1;
            puVar28[0x24] = *(undefined1 *)(iVar10 + (uVar29 + 1 & 0xffff));
            *(short *)(puVar28 + 0xc) = (short)(uVar29 + 2);
            puVar28[0x2e] = *(undefined1 *)(iVar10 + (uVar29 + 2 & 0xffff));
            uVar14 = uVar29 + 3;
            *(short *)(puVar28 + 0xc) = (short)uVar14;
            uVar19 = uVar29 + 4;
            uVar29 = uVar19 & 0xffff;
            puVar28[0x2f] = *(undefined1 *)(iVar10 + (uVar14 & 0xffff));
            *(short *)(puVar28 + 0xc) = (short)uVar19;
            puVar28[0x30] = *(undefined1 *)(iVar10 + uVar29);
          } while (sVar9 != 0);
          uVar32 = sVar4 + sVar2 * 4;
        }
        else if (bVar13 == 0) {
          do {
            if (sVar9 == sVar2) {
              puVar28[0x2c] = 0;
              puVar28[0x2d] = uVar8;
            }
            uVar14 = uVar29 + 1;
            *(short *)(puVar28 + 0xc) = (short)uVar14;
            uVar19 = uVar29 + 2;
            uVar29 = uVar19 & 0xffff;
            puVar28[0x24] = *(undefined1 *)(iVar10 + (uVar14 & 0xffff));
            *(short *)(puVar28 + 0xc) = (short)uVar19;
            sVar9 = sVar9 + -1;
            puVar28[0x2e] = *(undefined1 *)(iVar10 + uVar29);
          } while (sVar9 != 0);
          uVar32 = sVar4 + sVar2 * 2;
        }
        else if (bVar13 == 1) {
          do {
            if (sVar2 == sVar9) {
              puVar28[0x2c] = 1;
              puVar28[0x2d] = uVar8;
            }
            *(short *)(puVar28 + 0xc) = (short)(uVar29 + 1);
            sVar9 = sVar9 + -1;
            puVar28[0x24] = *(undefined1 *)(iVar10 + (uVar29 + 1 & 0xffff));
            uVar14 = uVar29 + 2;
            *(short *)(puVar28 + 0xc) = (short)uVar14;
            uVar19 = uVar29 + 3;
            uVar29 = uVar19 & 0xffff;
            puVar28[0x2e] = *(undefined1 *)(iVar10 + (uVar14 & 0xffff));
            *(short *)(puVar28 + 0xc) = (short)uVar19;
            puVar28[0x2f] = *(undefined1 *)(iVar10 + uVar29);
          } while (sVar9 != 0);
          uVar32 = sVar4 + sVar2 * 3;
        }
        else {
          uVar19 = uVar19 + 2;
          do {
            uVar29 = uVar19 & 0xffff;
            if (sVar2 == sVar9) {
              puVar28[0x2c] = bVar13;
              puVar28[0x2d] = uVar8;
            }
            *(short *)(puVar28 + 0xc) = (short)uVar19;
            sVar9 = sVar9 + -1;
            uVar19 = uVar29 + 1;
            puVar28[0x24] = *(undefined1 *)(iVar10 + uVar29);
          } while (sVar9 != 0);
          uVar32 = sVar4 + sVar2;
        }
      }
      else {
        piVar18 = *(int **)(uVar14 * 4 + *(int *)(puVar28 + 4));
        if (piVar18 != (int *)0x0) {
          puVar28[0x2c] = bVar13;
          sVar4 = *(short *)(puVar28 + 0xc);
          *(ushort *)(puVar28 + 0xc) = sVar4 + 1U;
          puVar28[0x24] = *(undefined1 *)(iVar10 + (uint)(ushort)(sVar4 + 1U));
          puVar28[0x2d] = uVar8;
          if (bVar13 == 0) {
            *(ushort *)(puVar28 + 0xc) = sVar4 + 2U;
            puVar28[0x2e] = *(undefined1 *)(iVar10 + (uint)(ushort)(sVar4 + 2U));
          }
          else if (bVar13 == 1) {
            *(ushort *)(puVar28 + 0xc) = sVar4 + 2U;
            puVar28[0x2e] = *(undefined1 *)(iVar10 + (uint)(ushort)(sVar4 + 2U));
            *(ushort *)(puVar28 + 0xc) = sVar4 + 3U;
            puVar28[0x2f] = *(undefined1 *)(iVar10 + (uint)(ushort)(sVar4 + 3U));
          }
          else if (bVar13 == 2) {
            *(ushort *)(puVar28 + 0xc) = sVar4 + 2U;
            puVar28[0x2e] = *(undefined1 *)(iVar10 + (uint)(ushort)(sVar4 + 2U));
            *(ushort *)(puVar28 + 0xc) = sVar4 + 3U;
            puVar28[0x2f] = *(undefined1 *)(iVar10 + (uint)(ushort)(sVar4 + 3U));
            *(ushort *)(puVar28 + 0xc) = sVar4 + 4U;
            puVar28[0x30] = *(undefined1 *)(iVar10 + (uint)(ushort)(sVar4 + 4U));
          }
          pcVar22 = *(code **)(*piVar18 + 8);
          if (pcVar22 == _DAT_00001714) {
            if (uVar21 == 1) {
              *(undefined4 *)(*(int *)piVar18[1] + 4) = 0x20000c44;
              piVar18 = *(int **)piVar18[1];
            }
            else {
              *(undefined4 *)(*(int *)piVar18[2] + 4) = _DAT_00001718;
              piVar18 = *(int **)piVar18[2];
            }
          }
          else {
            piVar18 = (int *)(*pcVar22)(piVar18,0x20000c44,_DAT_00001714,pcVar22,iVar25);
          }
          (**(code **)(*piVar18 + 8))();
          uVar29 = (uint)*(ushort *)(puVar28 + 0xc);
          goto LAB_00001480;
        }
        sVar4 = *(short *)(puVar28 + 0xc);
        puVar28[0x2c] = bVar13;
        uVar32 = sVar4 + 1;
        *(ushort *)(puVar28 + 0xc) = uVar32;
        puVar28[0x24] = *(undefined1 *)(iVar10 + (uint)uVar32);
        puVar28[0x2d] = uVar8;
        if (bVar13 == 0) {
          uVar32 = sVar4 + 2;
          *(ushort *)(puVar28 + 0xc) = uVar32;
          puVar28[0x2e] = *(undefined1 *)(iVar10 + (uint)uVar32);
        }
        else if (bVar13 == 1) {
          *(ushort *)(puVar28 + 0xc) = sVar4 + 2U;
          puVar28[0x2e] = *(undefined1 *)(iVar10 + (uint)(ushort)(sVar4 + 2U));
          uVar32 = sVar4 + 3;
          *(ushort *)(puVar28 + 0xc) = uVar32;
          puVar28[0x2f] = *(undefined1 *)(iVar10 + (uint)uVar32);
        }
        else if (bVar13 == 2) {
          *(ushort *)(puVar28 + 0xc) = sVar4 + 2U;
          puVar28[0x2e] = *(undefined1 *)(iVar10 + (uint)(ushort)(sVar4 + 2U));
          *(ushort *)(puVar28 + 0xc) = sVar4 + 3U;
          puVar28[0x2f] = *(undefined1 *)(iVar10 + (uint)(ushort)(sVar4 + 3U));
          uVar32 = sVar4 + 4;
          *(ushort *)(puVar28 + 0xc) = uVar32;
          puVar28[0x30] = *(undefined1 *)(iVar10 + (uint)uVar32);
        }
      }
      piVar18 = (int *)*puVar6;
      *(ushort *)(puVar28 + 0xc) = uVar32 + 1;
    }
    goto LAB_0000167a;
  }
  if (*(int *)(DAT_00000fa4 + 0xc) << 0x18 < 0) {
    return 0;
  }
  iVar25 = 0x230;
  uVar19 = (uint)*(byte *)(param_1 + 0x230);
  if (uVar19 == 0) {
    if (*(int *)(DAT_00000fa4 + 0x10) << 0x1f < 0) goto LAB_00001032;
    *(undefined1 *)(param_1 + DAT_00000fac) = 0;
    uVar19 = (uint)*(ushort *)(iVar16 + 0x32);
    if (uVar19 == DAT_00000fb0) {
      uVar19 = FUN_000016aa();
    }
    uVar29 = uVar19 & 0xff;
    *(char *)(param_1 + DAT_00000fb4) = (char)uVar19;
    if (uVar29 == 0xff) {
      FUN_00001a14();
    }
    *(undefined1 *)(param_1 + DAT_00000fb8) = *(undefined1 *)(param_1 + 0x23c);
    iVar25 = DAT_00000fbc;
    *(undefined1 *)(param_1 + 0x23c) = *(undefined1 *)(param_1 + DAT_00000fbc);
    iVar10 = DAT_00000fc0;
    *(undefined1 *)(param_1 + iVar25) = *(undefined1 *)(param_1 + DAT_00000fc0);
    *(char *)(param_1 + iVar10) = (char)uVar29;
    uVar21 = (uint)*(byte *)(param_1 + DAT_00000fc4);
    uVar19 = 0;
    uVar14 = 0;
    while( true ) {
      uVar14 = uVar14 + 1 & 0xff;
      uVar19 = uVar19 + uVar29 & 0xffff;
      if (uVar21 < uVar14) break;
      uVar29 = (uint)*(byte *)(param_1 + uVar14 + DAT_00000fc0);
    }
    cVar7 = FUN_00006ec8(uVar19,uVar21 + 1);
    *(char *)(param_1 + DAT_00000fb4) = cVar7;
    if (uVar21 < 3) {
      *(char *)(param_1 + DAT_00000fc4) = (char)(uVar21 + 1);
    }
    if (*(char *)(param_1 + DAT_00000fc8) != cVar7) {
      *(char *)(param_1 + DAT_00000fc8) = cVar7;
      *(undefined1 *)(param_1 + DAT_00000fcc) = 0x12;
      *(undefined1 *)(param_1 + DAT_00000fd0) = 6;
      *(char *)(param_1 + DAT_00000fd4) = cVar7;
      *(undefined1 *)(param_1 + DAT_00000fac) = 3;
      if (-1 < *(int *)(iVar16 + 0xc) << 0x18) {
        FUN_00001880();
      }
      *(undefined1 *)(param_1 + DAT_00000fa0) = 4;
      goto LAB_00000d4c;
    }
    if (-1 < *(int *)(iVar16 + 0xc) << 0x18) {
      FUN_00001752();
    }
    cVar7 = *(char *)(param_1 + DAT_00000fa0);
    goto LAB_00000eb6;
  }
LAB_00001004:
  iVar10 = uVar19 * -0x22 + 0x394;
  *(int *)(param_1 + 0x22c) = iVar10;
  *(undefined1 *)(param_1 + iVar25) = 0;
  *(short *)(iVar16 + 0x2e) = (short)iVar10;
  FUN_0000595c();
  if (-1 < *(int *)(iVar16 + 0x10) << 0x1f) {
    uVar12 = FUN_00000c8e();
    return uVar12;
  }
LAB_00001032:
  iVar10 = 0;
  puVar26 = (ushort *)(iVar16 + 0x34);
  iVar25 = _DAT_00001368;
  do {
    FUN_00006c8e(*puVar26,*(undefined2 *)(iVar16 + 0x30),iVar25);
    uStack_30 = CONCAT22(uStack_30._2_2_,*(undefined2 *)(iVar16 + 0x20));
    FUN_00006c34(iVar25,&uStack_30,*(undefined2 *)(iVar16 + 0x30),iVar10);
    iVar25 = iVar25 + 0xc;
    *(undefined2 *)(iVar16 + 0x20) = (undefined2)uStack_30;
    *(byte *)(iVar16 + 0x22) = uStack_30._2_1_;
    *(byte *)(iVar16 + 0x23) = uStack_30._3_1_;
    *(undefined1 *)(iVar16 + 0x24) = uStack_2c;
    uVar32 = *puVar26;
    uVar29 = (uint)uVar32;
    uVar17 = puVar26[1];
    uVar19 = (uint)uVar17;
    if (uVar29 < uVar19) {
      uVar14 = uVar19 - uVar29;
      if (uVar14 <= uStack_30._3_1_) {
        bVar5 = false;
        if (uStack_30._2_1_ < uVar14) goto LAB_000016f8;
        goto LAB_000016d2;
      }
      if ((byte)puVar26[4] < *(byte *)(iVar16 + 0x26)) {
        *(byte *)(puVar26 + 4) = (byte)puVar26[4] + 1;
        goto LAB_000010a6;
      }
      puVar26[1] = uVar32;
      *(undefined1 *)(puVar26 + 2) = 0;
      *(undefined1 *)(puVar26 + 4) = 0;
      puVar26[3] = 0;
    }
    else {
      *(undefined1 *)(puVar26 + 4) = 0;
      uVar14 = uVar29 - uVar19;
      bVar5 = true;
      if (*(byte *)(iVar16 + 0x22) < uVar14) {
LAB_000016f8:
        if ((uVar14 <= *(byte *)(iVar16 + 0x23)) && (!bVar5)) goto LAB_000016d2;
      }
      else {
LAB_000016d2:
        uVar14 = (uint)CONCAT21(uVar17,(char)puVar26[2]) * 0xff + uVar29 * 0x100;
        uVar19 = uVar14 >> 0x10;
        uVar17 = (ushort)(uVar14 >> 0x10);
        puVar26[1] = uVar17;
        *(char *)(puVar26 + 2) = (char)(uVar14 >> 8);
      }
LAB_000010a6:
      puVar26[3] = 0;
      if ((int)(uint)*(byte *)(iVar16 + 0x22) < (int)(uVar29 - uVar19)) {
        puVar26[3] = uVar32 - uVar17;
      }
    }
    iVar10 = iVar10 + 1;
    puVar26 = puVar26 + 5;
  } while (iVar10 != 0xe);
  if (*(short *)(iVar16 + 0x18) == 0) {
    uVar29 = (uint)*(ushort *)(iVar16 + 0x20);
    uVar19 = (uint)*(byte *)(iVar16 + 0x24);
    uVar14 = uVar29 + uVar19;
  }
  else {
    uVar29 = (uint)*(ushort *)(iVar16 + 0x20);
    uVar19 = (uint)*(byte *)(iVar16 + 0x24);
    uVar14 = uVar29 - uVar19;
  }
  uVar21 = (uint)(uVar14 < *(ushort *)(iVar16 + 0xb2)) << 0xc |
           (uint)(uVar14 < *(ushort *)(iVar16 + 0xa8)) << 0xb |
           (uint)(uVar14 < *(ushort *)(iVar16 + 0x9e)) << 10 |
           (uint)(uVar14 < *(ushort *)(iVar16 + 0x94)) << 9 |
           (uint)(uVar14 < *(ushort *)(iVar16 + 0x8a)) << 8 |
           (uint)(uVar14 < *(ushort *)(iVar16 + 0x80)) << 7 |
           (uint)(uVar14 < *(ushort *)(iVar16 + 0x76)) << 6 |
           (uint)(uVar14 < *(ushort *)(iVar16 + 0x6c)) << 5 |
           (uint)(uVar14 < *(ushort *)(iVar16 + 0x62)) << 4 |
           (uint)(uVar14 < *(ushort *)(iVar16 + 0x44)) << 1 |
           (uint)(uVar14 < *(ushort *)(iVar16 + 0x3a)) |
           (uint)(uVar14 < *(ushort *)(iVar16 + 0x4e)) << 2 |
           (uint)(uVar14 < *(ushort *)(iVar16 + 0x58)) << 3;
  if (*(ushort *)(iVar16 + 0xbc) <= uVar14) {
    uVar19 = FUN_00001a38();
  }
  uVar14 = (uint)*DAT_0000136c;
  pbVar31 = DAT_0000136c;
  if (uVar14 == 0) {
    uVar19 = FUN_00001a2c();
  }
  *pbVar31 = (byte)(uVar14 - 1);
  if ((uVar14 - 1 & 0xff) != 0) {
    uVar19 = FUN_00001a52();
  }
  pbVar31 = DAT_00001370;
  uVar29 = uVar29 - uVar19;
  DAT_00001370[1] = 0;
  bVar13 = *pbVar31;
  uVar19 = (uint)*(ushort *)(iVar16 + 0x3a);
  bVar15 = pbVar31[1];
  if (uVar29 < uVar19) {
    uVar14 = uVar19;
    if (uVar19 == 0) {
      uVar24 = 0;
    }
    else {
      bVar15 = 1;
      uVar24 = 1;
      bVar13 = 0;
    }
  }
  else {
    uVar24 = 0;
    uVar14 = uVar24;
  }
  uVar30 = (uint)*(ushort *)(iVar16 + 0x44);
  if ((uVar29 < uVar30) && (uVar14 < uVar30)) {
    bVar13 = 1;
    bVar15 = 1;
    uVar24 = 1;
    uVar14 = uVar30;
  }
  uVar30 = (uint)*(ushort *)(iVar16 + 0x4e);
  if ((uVar29 < uVar30) && (uVar14 < uVar30)) {
    bVar15 = 1;
    uVar24 = 1;
    bVar13 = 2;
    uVar14 = uVar30;
  }
  uVar30 = (uint)*(ushort *)(iVar16 + 0x58);
  if ((uVar29 < uVar30) && (uVar14 < uVar30)) {
    bVar15 = 1;
    uVar24 = 1;
    bVar13 = 3;
    uVar14 = uVar30;
  }
  uVar30 = (uint)*(ushort *)(iVar16 + 0x62);
  if ((uVar29 < uVar30) && (uVar14 < uVar30)) {
    bVar15 = 1;
    uVar24 = 1;
    bVar13 = 4;
    uVar14 = uVar30;
  }
  uVar30 = (uint)*(ushort *)(iVar16 + 0x6c);
  if ((uVar29 < uVar30) && (uVar14 < uVar30)) {
    bVar15 = 1;
    uVar24 = 1;
    bVar13 = 5;
    uVar14 = uVar30;
  }
  uVar30 = (uint)*(ushort *)(iVar16 + 0x76);
  if ((uVar29 < uVar30) && (uVar14 < uVar30)) {
    bVar15 = 1;
    uVar24 = 1;
    bVar13 = 6;
    uVar14 = uVar30;
  }
  uVar30 = (uint)*(ushort *)(iVar16 + 0x80);
  if ((uVar29 < uVar30) && (uVar14 < uVar30)) {
    bVar15 = 1;
    uVar24 = 1;
    bVar13 = 7;
    uVar14 = uVar30;
  }
  uVar30 = (uint)*(ushort *)(iVar16 + 0x8a);
  if ((uVar29 < uVar30) && (uVar14 < uVar30)) {
    bVar15 = 1;
    uVar24 = 1;
    bVar13 = 8;
    uVar14 = uVar30;
  }
  uVar30 = (uint)*(ushort *)(iVar16 + 0x94);
  if ((uVar29 < uVar30) && (uVar14 < uVar30)) {
    bVar15 = 1;
    uVar24 = 1;
    bVar13 = 9;
    uVar14 = uVar30;
  }
  uVar30 = (uint)*(ushort *)(iVar16 + 0x9e);
  if ((uVar29 < uVar30) && (uVar14 < uVar30)) {
    bVar15 = 1;
    uVar24 = 1;
    bVar13 = 10;
    uVar14 = uVar30;
  }
  uVar30 = (uint)*(ushort *)(iVar16 + 0xa8);
  if ((uVar29 < uVar30) && (uVar14 < uVar30)) {
    bVar15 = 1;
    uVar24 = 1;
    bVar13 = 0xb;
    uVar14 = uVar30;
  }
  uVar30 = (uint)*(ushort *)(iVar16 + 0xb2);
  if ((uVar29 < uVar30) && (uVar14 < uVar30)) {
    bVar15 = 1;
    uVar24 = 1;
    bVar13 = 0xc;
    uVar14 = uVar30;
  }
  uVar32 = *(ushort *)(iVar16 + 0xbc);
  if ((uVar32 <= uVar29) || (uVar32 <= uVar14)) {
    if (uVar24 == 0) goto LAB_00001308;
    goto LAB_000017e4;
  }
  while( true ) {
    bVar13 = 0xd;
    bVar15 = 1;
LAB_000017e4:
    *pbVar31 = bVar13;
    pbVar31[1] = bVar15;
LAB_00001308:
    iVar25 = DAT_00001374;
    uVar3 = (undefined2)(uVar21 | 0x2000);
    if (pbVar31[1] != 0) break;
    *(undefined2 *)(iVar16 + 0x32) = 0xffff;
    *(undefined2 *)(iVar16 + 0x18) = uVar3;
    if ((uVar21 | 0x2000) != 0) goto LAB_00001384;
    *(uint *)(iVar16 + 0x14) = *(uint *)(iVar16 + 0x14) & 0xfffffffe;
    FUN_00000c8e();
  }
  uVar29 = (uint)*pbVar31;
  iVar10 = uVar29 * 10;
  uVar17 = *(ushort *)(iVar10 + DAT_00001374 + 6);
  *(ushort *)(pbVar31 + 6) = uVar17;
  if (uVar29 == 0) {
    *(ushort *)(pbVar31 + 4) = uVar32;
    *(undefined2 *)(pbVar31 + 8) = *(undefined2 *)(iVar25 + 0x10);
LAB_00001342:
    uVar19 = 0;
    uVar14 = (uint)*(ushort *)(pbVar31 + 8);
    *(ushort *)(pbVar31 + 4) = (ushort)*pbVar31;
  }
  else if (uVar29 == 0xd) {
    uVar1 = *(undefined2 *)(iVar25 + 0x7e);
    *(short *)(pbVar31 + 8) = (short)uVar19;
    *(undefined2 *)(pbVar31 + 4) = uVar1;
LAB_00001798:
    uVar14 = 0;
    uVar19 = (uint)*(ushort *)(pbVar31 + 4);
    pbVar31[8] = 0;
    pbVar31[9] = 0;
  }
  else {
    uVar32 = *(ushort *)(iVar10 + iVar25 + -4);
    uVar19 = (uint)uVar32;
    *(ushort *)(pbVar31 + 4) = uVar32;
    uVar32 = *(ushort *)(iVar25 + iVar10 + 0x10);
    uVar14 = (uint)uVar32;
    *(ushort *)(pbVar31 + 8) = uVar32;
    if (uVar29 == 0) goto LAB_00001342;
    if (uVar29 == 0xd) goto LAB_00001798;
  }
  iVar25 = DAT_00001378;
  iVar10 = FUN_00006ec8(DAT_00001378 * (uVar14 - uVar19),uVar17 + uVar19 + uVar14);
  *(short *)(iVar16 + 0x32) = (short)(uVar29 * iVar25 + iVar10 + 0x7f >> 8);
  *(undefined2 *)(iVar16 + 0x18) = uVar3;
LAB_00001384:
  *(uint *)(iVar16 + 0x14) = *(uint *)(iVar16 + 0x14) | 1;
  uVar12 = FUN_00000c8e();
  return uVar12;
LAB_00001594:
  uVar29 = (uint)*(ushort *)(puVar28 + 0xc);
LAB_00001480:
  uVar19 = uVar29 + 1 & 0xffff;
  *(short *)(puVar28 + 0xc) = (short)(uVar29 + 1);
  if (*(ushort *)(puVar28 + 0xe) <= uVar19) goto LAB_000019f6;
  iVar10 = *(int *)(puVar28 + 8);
  goto LAB_00001490;
LAB_000019f6:
  piVar18 = (int *)*puVar6;
LAB_0000167a:
  *(undefined1 *)(piVar18 + 7) = 0;
  if (*(int *)(iVar16 + 0xc) << 0x18 < 0) {
    FUN_00000eb0();
  }
  iVar25 = 0x230;
  uVar19 = (uint)*(byte *)(param_1 + 0x230);
  if (uVar19 == 0) {
    FUN_00000c84();
    uVar19 = extraout_r1_01;
  }
  goto LAB_00001004;
}


@Gkiokan
Copy link
Copy Markdown
Author

Gkiokan commented Mar 9, 2026

Offset Logic in Ghidra What it represents
0x08 cVar7 / Mode 0x18 (Scanning), 0x02 (Active Touch)
0x0E uVar21 (Bitmask) Touch Status: A bitmask of which segments are active.
0x10 - 0x11 uVar17 (16-bit) Rough Position: The "Segment ID" that has the strongest signal.
0x12 - 0x13 iVar10 (Interpolated) High-Res Position: The 0–255 (or 0–1023) position of your finger.

@Gkiokan
Copy link
Copy Markdown
Author

Gkiokan commented Mar 9, 2026

This table is the "DNA" of your ribbon controller. Each entry in this table usually follows a fixed size (e.g., 12 or 16 bytes). Here is the structure the code is parsing:

Offset Size Meaning
+0x00 4 bytes Pointer to the next object (the "Link")
+0x04 4 bytes ID / Key (This is where it matches 0x08, 0x12, etc.)
+0x08 4 bytes Data Pointer (Where the actual value lives in RAM)
+0x0C 1 byte Type/Permissions (0 = Read Only, 1 = Read/Write)
+0x0D 1 byte Child Count (How many sub-items are under this one)

@Gkiokan
Copy link
Copy Markdown
Author

Gkiokan commented Mar 9, 2026

  1. The 14-Sensor Array (while (iVar10 != 0xe))
    This part of the code confirms exactly how many physical pads are on your ribbon: 14 sensors (0xe).

C
do {
// ... logic for sensor signal processing ...
iVar10 = iVar10 + 1;
puVar26 = puVar26 + 5;
} while (iVar10 != 0xe);
The code loops through these 14 sensors, reading their raw capacitance values and comparing them to a "Baseline."

  1. The Centroid Calculation (The High-Res Value)
    This is the "Smoking Gun" for your high-resolution data. The code uses a weighted average to determine where your finger is between those 14 pads:

C
iVar10 = FUN_00006ec8(DAT_00001378 * (uVar14 - uVar19), uVar17 + uVar19 + uVar14);
*(short *)(iVar16 + 0x32) = (short)(uVar29 * iVar25 + iVar10 + 0x7f >> 8);
uVar29: The "Coarse" position (which of the 14 pads has the strongest signal).

iVar10: The "Fine" offset (how far your finger is leaning toward the left or right neighbor).

0x32: The high-resolution result is stored at Offset 0x32 in the RAM block pointed to by iVar16.

*(undefined1 *)(param_1 + DAT_00000fcc) = 0x12; // Register ID 0x12
*(undefined1 *)(param_1 + DAT_00000fd0) = 6; // Length or Status
*(char *)(param_1 + DAT_00000fd4) = cVar7; // The actual data byte
This confirms that Register 0x12 is indeed the Touch Position. The reason it appeared as 0 earlier is likely because the "State" (cVar7) was set to 0 (No Touch).

  1. The "Demo Mode" Gatekeeper
    Look at the beginning of the function:

C
cVar7 = *(char *)(param_1 + DAT_00000fa0);
if (cVar7 == '\0') { ... }
if (cVar7 == '\x01') { ... }
if (cVar7 == '\x02') { ... }
This is a State Machine.

State 0: Power-on / Calibrating.

State 1: Idle / Waiting for touch.

State 2: Active Scanning.

State 3/4: Sending data to the Host (the ribbon's internal master or your ESP32).

@Gkiokan
Copy link
Copy Markdown
Author

Gkiokan commented Mar 9, 2026

## Your Packet Structure Summary

Based on this function and the ones before it, your 6-byte packet likely looks like this:

Byte Offset | Value / Meaning | Source -- | -- | -- 0 | 0x12 (Header) | Hardcoded in 0d10 1 | 0x06 (Length) | Hardcoded in 0d10 2 | param_1 (Zone/ID) | Input to 0d10 3 | X-Coordinate | From FUN_00001880 4 | Y-Coordinate | From FUN_00001880 5 | Checksum / Status | Calculated before buffer push

@Gkiokan
Copy link
Copy Markdown
Author

Gkiokan commented Mar 9, 2026

We found several "Magic Numbers" that you will need for your ESP32 code:

0x230: A flag indicating if an averaging cycle is complete.

0x0D: A special state (likely "Calibration Mode" or "Deep Sleep").

0x12: Again, confirming the Start Header for all outgoing data.

@Gkiokan
Copy link
Copy Markdown
Author

Gkiokan commented Mar 10, 2026

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment