spi.transfer16() Arduino Due

Hey,

How do I call transfer16() for arduino due? I try to write it in my code but it doesnt seem to compile?

Thanks in advance.

post your code?
have you looked at the reference?

void dataWrite(unsigned int command, unsigned int address, uint16_t data, unsigned int suffix) {
  byte b1 = command;
  byte b2 = address << 4 | data >> 12; 
  byte b3 = data >> 4; 
  byte b4 =  (data << 4) >> 8 | suffix;

  
  SPI.transfer(ssDAC, b1,SPI_CONTINUE);
  SPI.transfer(ssDAC, b2,SPI_CONTINUE);
  SPI.transfer(ssDAC, b3,SPI_CONTINUE);
  SPI.transfer(ssDAC, b4,SPI_LAST);

}

This is how I am sending my data to my DAC which requires a 32 bit instruction. At the moment I am using the spi.transfer function to send 4 bytes seperately. I have heard that there is a 1us delay between two consecutive 1 byte transfers, i thought maybe if I use transfer16() i could save myself a few microseconds and just do two 16 bit transfers. I have tried to code transfer16() into my code but it doesnt recognise the function, as in the code doesent turn orange like the spi.transfer function does. I am using Arduino Due, I have read some reports that transfer16() can not be used on the Due, but I cant seem to find an real documentation to support that. Any ideas?

It compiles. Try this test code.

#include <SPI.h>

unsigned int testint = 0;

void setup() {
  // put your setup code here, to run once:
  SPI.begin();

  SPI.transfer16(testint);
  
}

void loop() {
  // put your main code here, to run repeatedly:

}

Thank you, I will try this as soon as possible and let you know.

Ok so I got the transfer16() function working with my original code, for some reason it doesnt perform as fast as sending 4 individual bytes. Not sure why that is, I thought that it would at least save me some time but it has actually made my program slower. Four single byte transfers were taking me 4 microseconds, now 2 16 bit transfers are taking me 5 microseconds. Anybody have any idea why this is?

This is my new code that is slower.

    uint16_t var1 = command << 8| address << 4 | data >> 12;
    uint16_t var2= data << 4 | suffix;
    SPI.transfer16(ssDAC,var1,SPI_CONTINUE);
    SPI.transfer16(ssDAC,var2,SPI_LAST);

This was my previous code that actually works faster.

 byte b1 = command;
  byte b2 = address << 4 | data >> 12; //4 address bits and 4 MSBs of data
  byte b3 = data >> 4; // middle 8 bits of data
  byte b4 =  data << 4 | suffix;
  
  SPI.transfer(ssDAC, b1,SPI_CONTINUE);
  SPI.transfer(ssDAC, b2,SPI_CONTINUE);
  SPI.transfer(ssDAC, b3,SPI_CONTINUE);
  SPI.transfer(ssDAC, b4,SPI_LAST);

Ok I have done some digging in the SPI library and I can see that the transfer16() function isnt actually a straight up 16 bit transfer, the function splits up the word again and sends it as 2 bytes, no wonder its slower! Any other way I can send 16 bits in a row?

uint16_t SPIClass::transfer16(byte _pin, uint16_t _data, SPITransferMode _mode) {
	union { uint16_t val; struct { uint8_t lsb; uint8_t msb; }; } t;
	uint32_t ch = BOARD_PIN_TO_SPI_CHANNEL(_pin);

	t.val = _data;

	if (bitOrder[ch] == LSBFIRST) {
		t.lsb = transfer(_pin, t.lsb, SPI_CONTINUE);
		t.msb = transfer(_pin, t.msb, _mode);
	} else {
		t.msb = transfer(_pin, t.msb, SPI_CONTINUE);
		t.lsb = transfer(_pin, t.lsb, _mode);
	}

	return t.val;
}

You can select the size of transfers from 8 to 16 bits thru SPI_CSR register (Sam3x datasheet page 704).

E.g. with this code, you can transfer 16 bits :

 SPI0->SPI_CSR[0] = SPI_CSR_CPOL           // CPOL=1/NCPHA=0 for MODE 3
                     | SPI_CSR_CSNAAT      // chip select remains low after transfer
                     | SPI_CSR_BITS_16_BIT // 16 bits per transfer
                     | SPI_CSR_SCBR(1);    // SPCK baudrate = MCK/SCBR

To really speed up SPI transfers, use Turbo Spi Library for DUE:

See this thread, reply #36:

https://forum.arduino.cc/index.php?topic=437243.30

I am planning to have 2 slaves on my spi bus, a DAC and an SD card, if i change the register to 16 bit transfers will that affect the sdfat library?