I got SPIE cleared to disable SPI interrupts.
The MSTR bit is still set so it's seemingly not an SS pin issue. (Unless CE pin on the AD725 does funky stuff when hblank is triggered)
I don't have an SD card plugged in, I'm SPI-ing into the void.
I can do SPI transfers fine if I completely disable interrupts during the SPI transfers. For obvious reasons I don't want to do that.
But if an unrelated timer interrupt happens between starting the transfer and reading the SPIF flag, the SPIF flag gets cleared even with SPI interrupts disabled.
That doesn't seem to be documented in the ATmega644 manual
Emphasis mine. It should only automatically clear it if the corresponding interrupt happens.SPIF is cleared by hardware when executing the
corresponding interrupt handling vector. Alternatively, the SPIF bit is cleared by first reading the
SPI Status Register with SPIF set, then accessing the SPI Data Register (SPDR).
I started messing with the code to diagnose why the transfers randomly stopped after a while so I added an extra long loop to force the issue to happen:
Code: Select all
SPDR = value;
for(;--timeout;){ //long 64K loop to have an interrupt happen between SPDR and SPSR check
++__vram_start[0];
asm volatile("nop" : : :"memory");
}
while(true){
byte s = SPSR;
++__vram_start[2];
if(s & 0x80){
break;
}
//...
Code: Select all
SPDR = value;
while(!(SPSR & 0x80));
return SPDR;
I can't find info on this behaviour.
Is that a CPU bug? Am I missing something else?
I guess I'll have to use a timer register instead and just assume the SPI transfer is done when the time runs out. Which is fine since I'm the master. It's not very pretty tho.