Okay so here's the OLD code that I am running right now, and it's working with 10 nops:
00000624 <_Z10updateLEDsv>:
static unsigned long nextLEDFrameTime = 0;
uint8_t *thisLED;
uint8_t *lastLED;
if (time >= nextLEDFrameTime) { // If it is time for an LED update...
624: 20 91 c4 01 lds r18, 0x01C4
628: 30 91 c5 01 lds r19, 0x01C5
62c: 40 91 c6 01 lds r20, 0x01C6
630: 50 91 c7 01 lds r21, 0x01C7
634: 80 91 a4 02 lds r24, 0x02A4
638: 90 91 a5 02 lds r25, 0x02A5
63c: a0 91 a6 02 lds r26, 0x02A6
640: b0 91 a7 02 lds r27, 0x02A7
644: 28 17 cp r18, r24
646: 39 07 cpc r19, r25
648: 4a 07 cpc r20, r26
64a: 5b 07 cpc r21, r27
64c: 08 f4 brcc .+2 ; 0x650 <_Z10updateLEDsv+0x2c>
64e: 31 c0 rjmp .+98 ; 0x6b2 <_Z10updateLEDsv+0x8e>
//unsigned int time = micros();
thisLED = &LEDData[LEDMODULES*36]; // The first operation is to decrement this pointer, so the first time we write thisLED it will be array index LEDMODULES*36-1
lastLED = &LEDData[0];
cli(); // Halt interrupts.
650: f8 94 cli
652: ee e9 ldi r30, 0x9E ; 158
654: f2 e0 ldi r31, 0x02 ; 2
do {
SPDR = *--thisLED; WAIT;
656: 82 91 ld r24, -Z
658: 8e bd out 0x2e, r24 ; 46
65a: 00 00 nop
65c: 00 00 nop
65e: 00 00 nop
660: 00 00 nop
662: 00 00 nop
664: 00 00 nop
666: 00 00 nop
668: 00 00 nop
66a: 00 00 nop
66c: 00 00 nop
thisLED = &LEDData[LEDMODULES*36]; // The first operation is to decrement this pointer, so the first time we write thisLED it will be array index LEDMODULES*36-1
lastLED = &LEDData[0];
cli(); // Halt interrupts.
do {
66e: 82 e0 ldi r24, 0x02 ; 2
670: e6 35 cpi r30, 0x56 ; 86
672: f8 07 cpc r31, r24
674: 81 f7 brne .-32 ; 0x656 <_Z10updateLEDsv+0x32>
SPDR = *--thisLED; WAIT;
//while (!(SPSR & _BV(SPIF))); SPDR = *thisLED--; // Wait for transfer of byte over SPI bus to complete, then transfer *thisLED into SPDR register, and decrement address of *thisLED.
} while (thisLED != lastLED); // thisLED is decremented one last time before we hit the end of the loop, so after byte 0 transfers, the loop exits.
WAIT; // Wait for last byte to finish transfer.
676: 00 00 nop
678: 00 00 nop
67a: 00 00 nop
67c: 00 00 nop
67e: 00 00 nop
680: 00 00 nop
682: 00 00 nop
684: 00 00 nop
686: 00 00 nop
688: 00 00 nop
SPSR = SPSR & ~_BV(SPIF); // Clear transfer flag.
68a: 8d b5 in r24, 0x2d ; 45
68c: 8f 77 andi r24, 0x7F ; 127
68e: 8d bd out 0x2d, r24 ; 45
And here is the new code that requires 11:
000007da <_Z10updateLEDsv>:
*/
void updateLEDs() {
7da: af 92 push r10
7dc: bf 92 push r11
7de: cf 92 push r12
7e0: df 92 push r13
7e2: ef 92 push r14
7e4: ff 92 push r15
7e6: 0f 93 push r16
7e8: 1f 93 push r17
//uint8_t *lastLED;
byte *thisLED;
byte *lastLED;
if (time >= nextLEDFrameTime) { // If it is time for an LED update...
7ea: 20 91 c2 01 lds r18, 0x01C2
7ee: 30 91 c3 01 lds r19, 0x01C3
7f2: 40 91 c4 01 lds r20, 0x01C4
7f6: 50 91 c5 01 lds r21, 0x01C5
7fa: 80 91 5e 02 lds r24, 0x025E
7fe: 90 91 5f 02 lds r25, 0x025F
802: a0 91 60 02 lds r26, 0x0260
806: b0 91 61 02 lds r27, 0x0261
80a: 28 17 cp r18, r24
80c: 39 07 cpc r19, r25
80e: 4a 07 cpc r20, r26
810: 5b 07 cpc r21, r27
812: 08 f4 brcc .+2 ; 0x816 <_Z10updateLEDsv+0x3c>
814: 57 c0 rjmp .+174 ; 0x8c4 <_Z10updateLEDsv+0xea>
unsigned int time = micros();
816: 0e 94 0b 12 call 0x2416 ; 0x2416 <micros>
81a: 5b 01 movw r10, r22
81c: 6c 01 movw r12, r24
thisLED = &led::data[led::modules*36]; // The first operation is to decrement this pointer, so the first time we write thisLED it will be array index LEDMODULES*36-1
81e: 40 91 56 02 lds r20, 0x0256
822: 50 91 57 02 lds r21, 0x0257
826: 20 91 54 02 lds r18, 0x0254
82a: 30 91 55 02 lds r19, 0x0255
82e: 84 e2 ldi r24, 0x24 ; 36
830: 90 e0 ldi r25, 0x00 ; 0
832: 28 9f mul r18, r24
834: f0 01 movw r30, r0
836: 29 9f mul r18, r25
838: f0 0d add r31, r0
83a: 38 9f mul r19, r24
83c: f0 0d add r31, r0
83e: 11 24 eor r1, r1
840: e4 0f add r30, r20
842: f5 1f adc r31, r21
lastLED = &led::data[0];
cli(); // Halt interrupts.
844: f8 94 cli
do {
SPDR = *--thisLED; WAIT;
846: 82 91 ld r24, -Z 2
848: 8e bd out 0x2e, r24 ; 46 1
84a: 00 00 nop 1
84c: 00 00 nop 1
84e: 00 00 nop 1
850: 00 00 nop 1
852: 00 00 nop 1
854: 00 00 nop 1
856: 00 00 nop 1
858: 00 00 nop 1
85a: 00 00 nop 1
85c: 00 00 nop 1
85e: 00 00 nop 1
860: e4 17 cp r30, r20 1
862: f5 07 cpc r31, r21 1
864: 81 f7 brne .-32 ; 0x846 <_Z10updateLEDsv+0x6c> 1/2
SPDR = *--thisLED; WAIT;
} while (thisLED != lastLED); // thisLED is decremented one last time before we hit the end of the loop, so after byte 0 transfers, the loop exits.
WAIT; // Wait for last byte to finish transfer.
866: 00 00 nop 1
868: 00 00 nop 1
86a: 00 00 nop 1
86c: 00 00 nop 1
86e: 00 00 nop 1
870: 00 00 nop 1
872: 00 00 nop 1
874: 00 00 nop 1
876: 00 00 nop 1
878: 00 00 nop 1
87a: 00 00 nop 1
SPSR = SPSR & ~_BV(SPIF); // Clear transfer flag.
87c: 8d b5 in r24, 0x2d ; 45 1
87e: 8f 77 andi r24, 0x7F ; 127 1
880: 8d bd out 0x2d, r24 ; 45 1
Hm, I see one difference right off the bat. But I don't see how it could affect the loop. In the original code LEDMODULES was a constant. Now it is not. So there seems to be a lot more code to set up the pointers.