I have been struggling with getting SPI to work on the Nano Every off and on for several weeks. Yesterday, I finally got it working. I was not able to find anything through google search that solved my SPI problem, but in going through all the posts I learned a great deal about the Nano, the Nano Every, and SPI in general. My solution for SPI on the Nano Every finally came from the ATmega4809 datasheet (surprise!) and a lot of trial and error.
Here are the key items I discovered:
– The ATmega328 register emulation for the Nano Every does not seem to work for SPI. Also, the register names and command structure for the ATmega4809 are very different from the ATmega328.
– The SPI pin assignments in the Nano Every Pinout diagram show connections to PORTE pins 0-3 of the ATmega4809 for MOSI, MISO, and SCK, respectively. There is no pin designated for SS in the diagram. HOWEVER, by default, the 4809 does not use those pins for SPI. It uses PORTA pins 4-7 for MOSI, MISO, SCK, and SS. These pins are not even connected on the Nano Every.
– Fortunately, the 4809 port multiplexer can re-map the SPI signals to an alternate set of pins that match the Nano Every pin connections and labels:
PORTMUX.TWISPIROUTEA = PORTMUX_SPI0_ALT2_gc;
– After remapping, the SS signal is on pin D8 of the Nano Every.
– I also discovered that the datasheet is wrong about the behavior of the SPI interrupt flag. The flag does NOT clear automatically when the ISR is called, as stated in the datasheet. The flag has to be cleared by the software. Further, clearing the flag is done by writing a 1 to the SPI interrupt flags register, not by writing a 0 to the register. I discovered this by trial and error, but Tom Almy found it back in 2020. The following command will clear the flag:
SPI0.INTFLAGS = SPI_IF_bm;
– Finally, the SPI interrupt service routine vector for the Nano Every is
ISR(SPI0_INT_vect)
I hope this information is useful.