Skip to content

Instantly share code, notes, and snippets.

@nguterresn
Created August 28, 2021 15:53
Show Gist options
  • Save nguterresn/499bfa8940deb7ed0c234aa60e208f52 to your computer and use it in GitHub Desktop.
Save nguterresn/499bfa8940deb7ed0c234aa60e208f52 to your computer and use it in GitHub Desktop.
Arduino Due Slave mode
#include <Arduino.h>
// Pinout https://www.theengineeringprojects.com/wp-content/uploads/2018/09/introduction-to-arduino-due-2-1.png
// With arduino macros https://github.com/manitou48/DUEZoo/blob/master/spislave.ino
// Good doc https://microchipdeveloper.com/32arm:sam-bare-metal-c-programming
// another good code about arduino due SPI slave https://github.com/MrScrith/arduino_due/blob/master/spi_slave.ino
// FUNCTIONS
void initSPI();
void enableOnReceiveDataInterrupt();
void disableOnReceiveDataInterrupt();
uint8_t readSPIData();
void writeSPIData(int data);
void waitUntilDataReceived();
void waitUntilDataSent();
void enableSPIPins();
void setup() {
Serial.begin(115200);
while (!Serial);
initSPI();
}
void loop() {
waitUntilDataReceived();
uint8_t dataReceived = readSPIData();
Serial.print(dataReceived);
}
void initSPI() {
// Sets MISO as OUTPUT
// NSS0 (PA28) is pin digital 10
pinMode(MISO, OUTPUT);
pinMode(MOSI, INPUT);
pinMode(SCK, INPUT);
pinMode(MISO, LOW);
// turn off SPI
REG_SPI0_CR = SPI_CR_SPIDIS;
// Write protection is disabled
REG_SPI0_WPMR &= ~(SPI_WPMR_WPEN);
// turn on periheral power (page 38) SPI0 and PIOA.
REG_PMC_PCER0 |= PMC_PCER0_PID24 | PMC_PCER0_PID11;
enableSPIPins();
// RESET SPI
// enable interrupt register
// Slave mode & mode fault detection is disabled
REG_SPI0_MR &= ~(SPI_MR_MSTR);
REG_SPI0_MR |= SPI_MR_MODFDIS;
// Select SPI MODE (NCPHA, CPOL) and number of bits (8 default)
REG_SPI0_CSR |= SPI_CSR_BITS_8_BIT | 0x02;
// turn on SPI
REG_SPI0_CR = SPI_CR_SPIEN;
}
void enableSPIPins() {
// 1: Disables the PIO from controlling the corresponding pin (enables peripheral control of the pin).
REG_PIOA_PDR |= PIO_PDR_P25 | PIO_PDR_P26 | PIO_PDR_P27 | PIO_PDR_P28;
}
void enableOnReceiveDataInterrupt() {
// Enable interrupt on receive data
REG_SPI0_IER |= SPI_IER_RDRF;
}
void disableOnReceiveDataInterrupt() {
// Disable interrupt on receive data
REG_SPI0_IDR |= SPI_IDR_RDRF;
}
uint8_t readSPIData() {
return REG_SPI0_RDR & 0xFF;
}
void writeSPIData(int data) {
REG_SPI0_TDR = data & 0xFF;
}
// We can either use this or an interruption.
// Interruption might be better since it is not blocking!
void waitUntilDataReceived() {
while ((REG_SPI0_SR & SPI_SR_RDRF) == 0);
}
void waitUntilDataSent() {
while ((REG_SPI0_SR & SPI_SR_TDRE) == 0);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment