Hi!
I am trying to configure my Nano Every as a SPI slave.
Unfortunately, this is not really straighforward, and some registers have to be set (same as with Uno and Mega basically..)
Here is the code I used. Also, I had Unfortunately, it isnt working and I am not getting any interrupts when sending from my master microcontroller. I already tested the communication with an Uno and a Mega.
#include <Arduino.h>
//#include <SPI.h>
#include <avr/interrupt.h>
/* Globals */
bool spiMessageToBePrinted = false;
uint8_t buf [100];
volatile byte pos = 1;
volatile boolean process_it = false;
volatile byte interruptCounter = 0;
volatile byte messageSize = 0;
bool isStringMessage = true;
void setup() {
Serial.begin(115200); // opens and configures the USB serial port for baudrate 115200
Serial.println("Arduino: SPI Communication setup");
// have to send on master in, *slave out*
//PORTE.DIR &= ~PIN0_bm; /* Set MOSI pin direction to input */
//PORTE.DIR |= PIN1_bm; /* Set MISO pin direction to output */
//PORTE.DIR &= ~PIN2_bm; /* Set SCK pin direction to input */
//PORTB.DIR &= ~PIN1_bm; /* Set SS pin direction to input */
// turn on SPI in slave mode
SPI0.CTRLA = SPI_DORD_bm /* LSB is transmitted first */
| SPI_ENABLE_bm /* Enable module */
& (~SPI_MASTER_bm); /* SPI module in Slave mode */
SPI0.INTCTRL = SPI_IE_bm; /* SPI Interrupt enable */
Serial.println("SPI registers on ATmega4809 were set: ");
Serial.print("SPI0_CTRLA: ");
Serial.println(SPI0_CTRLA, DEC);
Serial.print("SPI0_CTRLB: ");
Serial.println(SPI0_CTRLB, DEC);
Serial.print("SPI0_INTCRTL: ");
Serial.println(SPI0_INTCTRL, DEC);
Serial.print("SPI0_INTFLAGS: ");
Serial.println(SPI0_INTFLAGS, DEC);
Serial.print("SPI0_DATA: ");
Serial.println(SPI0_DATA, DEC);
sei();
//Serial.println(MISO);
//Serial.println(SS);
//Serial.println(MOSI);
//Serial.println(SCK);
pinMode(MISO, OUTPUT);
pinMode(MOSI, INPUT);
pinMode(SCK, INPUT);
pinMode(SS, INPUT);
// turn on interrupts
}
void loop() {
interruptCounter = 0;
if (process_it) {
if(isStringMessage){
Serial.print((char *)buf);
}
else {
Serial.println("SPI: packet received");
buf [pos] = 0;
Serial.println("SPI: Received data:");
for(int i=0; i < messageSize ; i++) {
Serial.println(buf[i],DEC);
}
}
process_it = false;
pos = 0;
} // end of flag set
}
// SPI interrupt routine
ISR(SPI0_INT_vect) {
byte c = SPI0_DATA;
// Echo Reply
SPI0_DATA = c;
//Serial.println((char)c);
//interruptCounter ++;
// add to buffer if room
if (pos < sizeof(buf)) {
buf [pos++] = c;
if ((char)buf[pos-1] == '\n' and (char)buf[pos-2] == '\r' and process_it == false) {
process_it = true;
buf[pos] = '\0';
messageSize = pos;
pos = 0;
}
}
SPI0.INTFLAGS = SPI_IF_bm; /* Clear the Interrupt flag by writing 1 */
} // end of room available
It would be great if someone could try out that code. Maybe you can see a mistake.
I will test this with an Arduino Master later. Also I am wondering why the SPI slave configuration has not been properly added to the SPI library yet. Thanks a lot in advance for any help!
Cheers