Hi all. I have a bit of a puzzle for you all.
The hardware background, in brief, is a 16x16 LED matrix with common anode columns sourced by mosfets controlled by individual IO pins. The rows are sunk by constant current output shift registers. The code below is part of a timer interrupt handler.
I am seeing strange behaviour from the IO pins controlling the column drivers. In the code below, column n-1 is being driven high a few instructions before column n is driven low. For some unknown reason, the behaviour of the actual pins has the transition of column n-1 delayed significantly - it looks like what I'd expect if the digitalWrite instruction for "lastColumn" were at the end of the block.
Got any ideas? I'm stumped.
// Blank row
digitalWrite(OE, HIGH); // (active low)
// Send row data via SPI
const int bitplaneOffset = gBitplane * BITPLANE_SIZE;
const int columnOffset = gColumn * 2;
// Red first
spi.write(pFrontBuffer[bitplaneOffset + columnOffset + 1]);
spi.write(pFrontBuffer[bitplaneOffset + columnOffset]);
// Then green
spi.write(pFrontBuffer[HALFPLANE_SIZE + bitplaneOffset + columnOffset + 1]);
spi.write(pFrontBuffer[HALFPLANE_SIZE + bitplaneOffset + columnOffset]);
// Wait for data to arrive.
NOP
NOP
NOP
NOP
// Extinguish last column driver
int lastColumn = gColumn - 1;
if(lastColumn < 0)
lastColumn = Constants::FrameWidth-1;
digitalWrite(colPins[lastColumn], HIGH); // (active low) <-------- write here...
// Latch row data
digitalWrite(LE, HIGH);
digitalWrite(LE, LOW);
// Light the current column
digitalWrite(colPins[gColumn], LOW); // (active low)
// Re-enable row drivers
digitalWrite(OE, LOW); // (active low)
<-------- pin changes here