Skip to content

Instantly share code, notes, and snippets.

@pingud98
Created July 30, 2018 19:32
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save pingud98/0fcfe07e7a1613dc53dae3d1a32ed660 to your computer and use it in GitHub Desktop.
Save pingud98/0fcfe07e7a1613dc53dae3d1a32ed660 to your computer and use it in GitHub Desktop.
Arduino DUE SPI Master and Slave example
#include <SPI.h>
/* Cosmic Pi SPI test routines - Master version, slave is commented out below. Runs on an Arduino DUE,
* Pinouts:
* MOSI - MOSI
* MISO - MISO
* SCK - SCK
* Pin 10 - Pin 10 (SS)
* GND - GND
* 5V - 5V
*
* The slave echoes the master byte in the next (16 bit) transmission.
SPI COMMUNICATION TRANSACTION LIST OF COMMANDS
WRITE OPERATIONS (FOR EACH WRITE, SLAVE MUST SEND BACK THE VALUE IT RECEIVES)
01 WRITE MSB(16 high bits) HV1_DUTY_CYCLE
02 WRITE LSB(16 low bits) HV1_DUTY_CYCLE
03 WRITE MSB(16 high bits) HV2_DUTY_CYCLE
04 WRITE LSB(16 low bits) HV2_DUTY_CYCLE
05 WRITE 16 bits LED_DUTY_CYCLE
READ OPERATIONS (FOR EACH READ, SLAVE MUST SEND BACK THE VALUE OF THE RELATED REGISTER)
06 READ MSB(16 high bits) HV1_DUTY_CYCLE
07 READ LSB(16 low bits) HV1_DUTY_CYCLE
08 READ MSB(16 high bits) HV2_DUTY_CYCLE
09 READ LSB(16 low bits) HV2_DUTY_CYCLE
10 READ 16 bits LED_DUTY_CYCLE
11 WRITE STATUS
11 READ STATUS
*/
byte CMD=1;
unsigned int duty_cycle_LED = 81;
unsigned int duty_cycle_channel_A = 100000;
unsigned int duty_cycle_channel_B = 200000;
unsigned int MSB;
unsigned int LSB;
//unsigned int response = 0;
unsigned int answer = 0;
byte PSU_parametrized = 0;
void setup() {
pinMode(SS, OUTPUT);
SPI.begin();
SPI.setBitOrder(MSBFIRST);
//SPI.setClockDivider(SPI_CLOCK_DIV128 );
Serial.begin(9600);
//delay(500);
}
void loop() {
// WRITE OPERATIONS
Serial.println("******************* WRTTE OPERATIONS *************************");
/********************* HV1 DUTY CYCLE *********************************/
delay(20);
//MSB
MSB = duty_cycle_channel_A >> 16;
spi_exchange(1);
spi_exchange(MSB);
//LSB
LSB = duty_cycle_channel_A & 0x0000FFFF;
spi_exchange(1);
spi_exchange(LSB);
/********************* HV2 DUTY CYCLE *********************************/
//MSB
MSB = duty_cycle_channel_B >> 16;
spi_exchange(3);
spi_exchange(MSB);
//LSB
LSB = duty_cycle_channel_B & 0x0000FFFF;
spi_exchange(4);
spi_exchange(LSB);
/********************* LED DUTY CYCLE *********************************/
spi_exchange(5);
spi_exchange(duty_cycle_LED);
// READ OPERATIONS
Serial.println("******************* READ OPERATIONS *************************");
/********************* HV1 DUTY CYCLE *********************************/
//MSB
spi_exchange(6);
spi_exchange(255);
//LSB
CMD=7;
spi_exchange(CMD);
spi_exchange(255);
/********************* HV2 DUTY CYCLE *********************************/
//MSB
CMD=8;
spi_exchange(CMD);
spi_exchange(255);
//LSB
CMD=9;
spi_exchange(CMD);
spi_exchange(255);
/********************* LED DUTY CYCLE *********************************/
CMD=10;
spi_exchange(CMD);
spi_exchange(255);
/********* STATUS *******/
// WRITE
CMD=11;
spi_exchange(CMD);
spi_exchange(11);
// READ
CMD=12;
spi_exchange(CMD);
spi_exchange(255);
delay(4000);
}
int spi_exchange(int data){
digitalWrite(SS, LOW);
int response = SPI.transfer16(data);
Serial.println("Master send command:" + String(data) + " Slave reply:" + String(response));
digitalWrite(SS, HIGH);
delay(20);
return response;
}
/*Arduino SPI slave test code that I found on https://github.com/manitou48/DUEZoo/blob/master/spislave.ino
* Nice one Manitou, it worked first time
#include <SPI.h>
// assumes MSB
static BitOrder bitOrder = MSBFIRST;
void slaveBegin(uint8_t _pin) {
SPI.begin(_pin);
REG_SPI0_CR = SPI_CR_SWRST; // reset SPI
REG_SPI0_CR = SPI_CR_SPIEN; // enable SPI
REG_SPI0_MR = SPI_MR_MODFDIS; // slave and no modefault
REG_SPI0_CSR = SPI_MODE0; // DLYBCT=0, DLYBS=0, SCBR=0, 8 bit transfer
}
byte transfer(uint8_t _pin, uint8_t _data) {
// Reverse bit order
if (bitOrder == LSBFIRST)
_data = __REV(__RBIT(_data));
uint32_t d = _data;
while ((REG_SPI0_SR & SPI_SR_TDRE) == 0) ;
REG_SPI0_TDR = d;
while ((REG_SPI0_SR & SPI_SR_RDRF) == 0) ;
d = REG_SPI0_RDR;
// Reverse bit order
if (bitOrder == LSBFIRST)
d = __REV(__RBIT(d));
return d & 0xFF;
}
#define PRREG(x) Serial.print(#x" 0x"); Serial.println(x,HEX)
void prregs() {
Serial.begin(9600);
while(!Serial);
PRREG(REG_SPI0_MR);
PRREG(REG_SPI0_CSR);
PRREG(REG_SPI0_SR);
}
#define SS 10
void setup() {
slaveBegin(SS);
prregs(); // debug
}
void loop() {
byte in;
static byte out=0x83;
in = transfer(SS, out);
out = in;
}
*/
@melvenis
Copy link

melvenis commented May 22, 2019

Hello, I've seen similar setups to your Slave and I continually get hung up on the 2nd to last line of code:, the "in = transfer(SS,out);" line. When it calls the transfer function it always hangs up on this line: while ((REG_SPI0_SR & SPI_SR_RDRF) == 0) ; because this returns a value of 0, but passes the first while loop above.

I've been looking through examples of DUE as slave for several hours and cannot find another example or figure out why this line hangs me up but works for others. Do you have any suggestions?
Thanks

@Maaz-Sansare
Copy link

Maaz-Sansare commented Jun 9, 2022

Hello, thanks for sharing .
SPI.transfer16( ) is to send 16 frame size if someone wants to try it for frame size 8 then use SPI.transfer ( ).
I used Arduino due , nano and lpc1768 as a slave

Thanks

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment