This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

TCA8418: Key in position "20" always also sends a key event "98". Why?

Part Number: TCA8418

I have a design that uses the TCA8418 to drive a 7x10 keyboard matrix. Whenever the key in ROW1 COL9 is pressed I get two key events: 20 and 98. I have confirmed these both result in a K_INT flag being set, it is not a GPI_INT flag for the "98" event. It is only with this key and it happens 100% of the time when the key is pressed. It doesn't happen for any other key in the matrix. I can't figure out why and am hoping someone can guide me in the right direction.

Here is the schematic for the keyboard matrix:

Here is what the net for ROW1 looks like on the PCB:

And for comparison what the net for ROW2 looks like:

While I'm using the Adafruit_TCA8418 library I have the issue even if I try and manually configure things by setting direct registry values bypassing the friendly methods provided by the library. Here is the initialization code: 

  _keyMatrix = new Adafruit_TCA8418();

  // Set up the matrix with the correct number of rows and columns.
  _keyMatrix->begin(TCA8418_DEFAULT_ADDR, &Wire);
  _keyMatrix->writeRegister(TCA8418_REG_KP_GPIO_1, 0b01111111); // Enable KP matrix for ROW0 through ROW6.
  _keyMatrix->writeRegister(TCA8418_REG_KP_GPIO_2, 0b11111111); // Enable KP matrix for COL0 through COL7.
  _keyMatrix->writeRegister(TCA8418_REG_KP_GPIO_3, 0b00000011); // Enable KP matrix for COL8 through COL9.

  // Attach the Arduino interrupt handler.
  pinMode(_interruptPin, INPUT_PULLUP);
  attachInterrupt(digitalPinToInterrupt(_interruptPin), _interruptHandler, CHANGE);

  // Flush any pending interrupts then enable interrupt sending
  _keyMatrix->flush();

  // Enable key interrupts interrupts
  uint8_t config = _keyMatrix->readRegister(TCA8418_REG_CFG);
  config |= TCA8418_REG_CFG_KE_IEN;
  _keyMatrix->writeRegister(TCA8418_REG_CFG, config);

  _currentState = DetectionState::WaitingForKey;
And here is the code for responding to the interrupts:
  // This flow comes from the TCA8418 datasheet, section 8.3.1.3: Key Event (FIFO) Reading.
  int keyEvent;

  // Step 1: Find out what caused the interrupt. Anything other than K_INT gets ignored.
  int interruptStatus = _keyMatrix->readRegister(TCA8418_REG_INT_STAT);
  if ((interruptStatus && INT_STAT_K_INT_BIT) != INT_STAT_K_INT_BIT)
  {
    _currentState = DetectionState::WaitingForKey;
    return;
  }

  // Step 2 in the data sheet, reading KEY_LCK_EC to get how many events
  // are stored doesn't seem necessary.

  // Step 3: Read the pending keys in the FIFO queue. When this returns 0
  // there are no events left in the queue.
  while (keyEvent = _keyMatrix->getEvent())
  {
    ReadKeyEvent(keyEvent);
  }

  // Step 5: Reset the interrupt flag.
  _keyMatrix->writeRegister(TCA8418_REG_INT_STAT, INT_STAT_K_INT_BIT);

  // Set the state machine back to waiting for key.
  _currentState = DetectionState::WaitingForKey;
The key event is parsed from the event like this:
I attached my logic analyzer directly to buttons 20, 19, and 30, and don't see any difference in the signals from button 20 compared to 19 and 30 (which do not exhibit this behaviour):
If necessary I can provide links to a GitHub repo with the entire PCB design and source code for the firmware.
Has anyone seen this issue before? Anyone have any idea what on earth could be causing it? I'm completely out of ideas.