Nano Every SPI quirks and solutions

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.

1 Like

It looks like you do something wrong. I have a project which supports, between others, a Nano Every board. I didnt remember any special settings to work with SPI on the board.

There are more than one support package exist for Nano Every. Which one you used in your tests? By the way, the package should include a basic SPI using example, isn't it?

This is in the official Arduino core:

#define SPI_MUX       (PORTMUX_SPI0_ALT2_gc)
#define PIN_SPI_MISO  (12)
#define PIN_SPI_SCK   (13)
#define PIN_SPI_MOSI  (11)
#define PIN_SPI_SS    (8)

On a Windows system:
C:\Users\yourUsername\AppData\Local\Arduino15\packages\arduino\hardware\megaavr\1.8.8\variants\nona4809\pins_arduino.h

I have also encounter exactly the similar dilemma that SPI not work properly when Arduino was treated as slave. It seems that SPI example provided in Arduino Cloud is not compatible with Nano Every board. I found this blog helpful and will try if this method solve the problem.

There is a good discussion of how to implement an SPI Slave on a Nano Every here

https://github.com/MCUdude/MegaCoreX/issues/138

1 Like

Thank you for your advise! Already solved according to the blogger's notes.

PORTMUX.TWISPIROUTEA = PORTMUX_SPI0_ALT2_gc;

@xinzz It's not clear what your issue is/was?

Are you trying to run SPI with the Nano Every as master or slave?

Are you using the Arduino IDE?

Are you using a board package? Arduino megaavr core or MegaCoreX? Or something else?
The board packages all should have some well defined pin mappings for SPI.