-1
\$\begingroup\$

I am trying to scan a key matrix that is 9 rows long. Currently my code is a bunch of if statements, one per row, and I would like it get it down to a small if loop. I don't think I can put PINB, PIND, etc in an array as that would just store the current contents of the PIN, right?

Here is the code I'm trying to condense:

static inline uint64_t Buttons_GetStatus(void)
{
  uint64_t currentStatus = 0;

  // Scan the matrix, one column at a time
  for (uint8_t column = 0x00; column < 0x06; column++)
  {
    PORTB |= COLUMNS_ALL;
    PORTB &= ~(0x01 << column);
    if (!(PINB & 0b01000000))
    {
      currentStatus |= matrix[0][column];
    }
    if (!(PINB & 0b10000000))
    {
      currentStatus |= matrix[1][column];
    }
    if (!(PIND & 0b00000001))
    {
      currentStatus |= matrix[2][column];
    }
    if (!(PIND & 0b00000010))
    {
      currentStatus |= matrix[3][column];
    }
    if (!(PIND & 0b00000100))
    {
      currentStatus |= matrix[4][column];
    }
    if (!(PIND & 0b00001000))
    {
      currentStatus |= matrix[5][column];
    }
    if (!(PIND & 0b00010000))
    {
      currentStatus |= matrix[6][column];
    }
    if (!(PIND & 0b00100000))
    {
      currentStatus |= matrix[7][column];
    }
    if (!(PIND & 0b01000000))
    { 
      currentStatus |= matrix[8][column];
    }
  }

  return currentStatus;
}

and I want it to look something like this:

static inline uint64_t Buttons_GetStatus(void)
{
  uint64_t currentStatus = 0;

  // Scan the matrix, one column at a time
  for (uint8_t column = 0x00; column < 0x06; column ++)
  {
    PORTB |= COLUMNS_ALL;
    PORTB &= ~(0x01 << column);
    for (int row = 0; row < 9; row++)
    {
      if (!(rows[row][PIN] & rows[row][BIT]))
      {
        currentStatus |= matrix[row][column];
      }
    }
  }

  return currentStatus;
}

In case it helps, I am working with an example from the LUFA library and this code is in my custom Buttons.h file for my board.

\$\endgroup\$
  • \$\begingroup\$ Note that if you are pushing wto buttons at the same time, the output will be the one with the highest row index; maybe it's what you want, but be sure about it \$\endgroup\$ – clabacchio Mar 20 '12 at 12:57
  • \$\begingroup\$ clabacchio - I am ORing all the pressed keys together, so I don't see why only the highest row index one will stick. My existing code (the top sections) performs exactly as I want, but I just thought the code could look better. AlexZam - Thanks for the answer. Are you suggesting I create a second loop for PINB? I had considered this, but I would still like to condense to one. I suppose I could store all 9 PIN states in a larger variable and loop through that. I will try these out when I get back to my dev hardware. \$\endgroup\$ – ben Mar 20 '12 at 17:52
1
\$\begingroup\$
pinVal = (PIND & 0b01111111);
for (int row = 0; row < 9; row++) {
  if (pinVal & 0x1) {
    currentStatus |= matrix[row+2][column];
  }
  pinVal = pinVal >> 1;
}

And then same for PINB.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.