The original complaint:
"If I don't wait a lot of LEDs are turning on that were supposed to be off and the ones I want on are off (most of the time). Looks a bit random."
And clues:
a. "EDIT2: Even with the slowest SCK (12Mhz/128) it did not work without a wait. So I guess I keep it at prescaler 16 and wait 10us..."
b. "A (hi-lo) pulse after the spi transfer of 12 bytes is done. No delay in between."
From HC4094 datasheet
here:
"The data of each stage of the shift register is provided with a latch, which latches data on the negative going transition of the STROBE input signal. When the STROBE input is held high, data propagates through the latch to a 3-state output buffer. This buffer is enabled when OUTPUT ENABLE input is taken high."
Therefore:
a. If LED_OE=LOW, then the output goes Hi-Z. So, the code must keep LED_OE=HIGH most of the time.
b. While LED_STROBE=HIGH, any input changes flows through the latches. At the moment LED_STROBE=LOW the outputs are frozen.
So, while you're clocking out serial data LED_STROBE must be kept LOW, otherwise you'll see blink'nlights during the transmission.
Now, 12MHz/128=93.75KHz. Time to transmit 12 bytes=(1/93750 * 12 * 8 )=1.024ms
Confirm that the post-transmission delay is actually 10us.
Maybe you mean 10 milliseconds?I'm thinking you're continuously sending a stream (visible to the outputs) and without a 10 millisecond delay (a delay >> than the transmit time), it's going to look like a blur.
Pseudo code:
main() {
LED_OE = HIGH;
while(1) { // loop forever
// do some stuff here.
// send/receive LED/switch state
LED_STROBE = LOW;
for (int i = 0; i < 12; i++) {
SPDR = sdata[i]; // Start the transmission
while (!(SPSR & (1<<SPIF))); // Wait until the end of the transmission
rdata[i] = SPDR; // Save the received byte
}
LED_STROBE = HIGH;
LED_STROBE = LOW;
// do other stuff here.
}
}