# Loop across ports (avr)

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.

• 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 – clabacchio Mar 20 '12 at 12:57
• 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. – ben Mar 20 '12 at 17:52

pinVal = (PIND & 0b01111111);

And then same for PINB.