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