Performing 16 Bit SPI message with Adafruit Feather M4

Hello Arduino Community,

I'm trying to program an Adafruit Feather M4 to send 16-bit SPI messages to an SPI slave, using Arduino's SPI.h functionality. I had thought the solution was to use SPI.transfer16(), however, this produces two 8-bit messages rather than one 16-bit message. Is there a simple solution to this that will allow me to send 16 consecutive bits?

Any advice is appreciated!
Thank you!

Are you sure the hardware is capable of doing this? Here's what the function from SPI.cpp looks like (board type was set to Feather M4 Express), it suggests perhaps not:

uint16_t SPIClass::transfer16(uint16_t data) {
  union { uint16_t val; struct { uint8_t lsb; uint8_t msb; }; } t;

  t.val = data;

  if (_p_sercom->getDataOrderSPI() == LSB_FIRST) {
    t.lsb = transfer(t.lsb);
    t.msb = transfer(t.msb);
  } else {
    t.msb = transfer(t.msb);
    t.lsb = transfer(t.lsb);
  }

  return t.val;
}

So, I'd recommend reading the processor's datasheet to see if it can actually do a 16-bit transfer in one shot. If it can, it looks like you'll have to code it yourself.

Hello gfvalvo,

Thank you for your reply. I've been looking at the datasheet, but I'm a bit new to this level of technical difficulty. What would I look up in order to see if a 16-bit transfer is possible? I found this info in the datasheet regarding a a 32-bit extension for SPI, but it may not be what I'm looking for:

"35.6.3.8 32-bit Extension
For better system bus utilization, 32-bit data receive and transmit can be enabled by writing to the Data 32-bit bit field
in the Control C register (CTRLC.DATA32B=1). When enabled, write and read transaction to/from the DATA register
are 32 bit in size.
If frames are not multiples of 4 Bytes, the Length Counter (LENGTH.LEN) and Length Enable (LENGTH.LENEN)
must be configured before data transfer begins. LENGTH.LEN must be enabled only when CTRLC.DATA32B is
enabled.
The figure below shows the order of transmit and receive when using 32-bit mode. Bytes are transmitted or received
and stored in order from 0 to 3.
Only 8-bit character size is supported."

Is this information helpful? If so, where would I start for coding my own 16-bit SPI? If not, what information would I be looking for in the datasheet?

ealtabe1:
Thank you for your reply. I've been looking at the datasheet, but I'm a bit new to this level of technical difficulty.

Well, then you picked a pretty complex device for your first jump into working at this level. I've have not used this chip as I do most work with boards in the Teensy 3.x family.

Maybe your first step should be to reassess your requirements and determine if what you're asking for is really necessary and why.

About all I can advise is to read the SPI chapter in detail. Then trace through the SPI library for this chip in your your Arduino IDE installation and see how it works with the low-level SPI peripheral registers to determine what modifications would be required.

I guess my main confusion is, in what capacity is the standard SPI protocol supposed to work if it doesn't work with any devices that require more than messages longer than 8-bit? I would imagine that the amount of devices that need messages longer than 8-bit far surpass the amount that need exactly 8 bits, unless i'm misunderstanding something.

For clarity, this is exactly what the documentation of the slave i'm using says:

"On this device, an SPI bus is used to set device configurations, operating parameters, and read out
diagnostic information. The SPI operates in slave mode and connects to a master controller. The SPI input data
(SDI) word consists of a 16-bit word, with a 5-bit command and 11 bits of data. The SPI output data (SDO) word
consists of 11-bit register data. The first 5 bits are don’t care bits."

Is there a reason a standard SPI setup wouldn't be capable of meeting these requirements?

All I can tell you is that the processor's capabilities are spelled out in its documentation. Read the datasheet and any errata. Another resource would be Microchip's user forums.

I don't understand why your slave device wouldn't work with two 8-bit transfers forming a 16-bit transfer. Post a link for its full datasheet.