32bit SPI Help

I'm sure there's a good article to reference out there, but I just haven't found it.

I'm trying to interface with an AD5065, AD5065 Datasheet and Product Info | Analog Devices, and am having trouble communicating via SPI to the chip.

Can anyone suggest a guide to sending 32bits via SPI? Or even best way to do so guides? Thanks for your help. I understand how the arduino SPI lines work and how the 5065 expects to receive, I'm just not sure exactly what to send in the SPI.transfer(); lines.

Need to do 4 transfers, 1 byte at a time.
Maybe something like this:
[cod]
SPI.transfer (yourData>>24); // upper byte
SPI.transfer ((yourData & 0x00FF0000) >>16); //second-high byte
SPI.transfer ((yourData & 0x0000FF00) >>8); // second-low byte
SPI.transfer (yourData & 0x000000FF ); // low byte

Check the data sheet, compare order of your data to the order needed.

Thanks for the quick reply. Is this a property of the arduino that I missed somewhere? Or is this just how this should be done? Sorry for my confusion, and thanks for the help.

The spi converts 8 bits loaded in to the spi output register in to serial on the MOSI line the spi lib just makes things easy for you and its fast it will only wait if the last transfer has not completed. After loading the register it just checks the spi input register for a transfer and then returns.

Mark

Much more efficient, though perhaps more confusing would be:

  typedef union {
    unsigned long data;
    unsigned char array[sizeof(unsigned long)];
  } Converter;
  Converter theBytes = {yourData};
  SPI.transfer (theBytes.array[0]); // upper byte
  SPI.transfer (theBytes.array[1]); //second-high byte
  SPI.transfer (theBytes.array[2]); // second-low byte
  SPI.transfer (theBytes.array[3]); // low byte

SPI library is an arduino thing, documented in the Reference page - think you need to look at Serial page, its listed there.

The other manipulations, that's just regular c/c++ code type stuff as far as I know.

Not listed in both is the need to typically bring the slave select signal low before the transfers and then high after.

SPI is 8-bit in general, AFAIK. That's not strictly an Arduino thing. Transferring 32-bit data just requires splitting it into 8-bit sections and sending them one at a time, which is what the code CrossRoads posted does.

BTW, there's a typo in the mask on the second line, where the data was shifted right 16 bits:

 SPI.transfer (yourData>>24); // upper byte
SPI.transfer ((yourData & 0x00FF0000) >>16); //second-high byte  *** TYPO WAS HERE ***
SPI.transfer ((yourData & 0x0000FF00) >>8); // second-low byte
SPI.transfer (yourData & 0x000000FF ); // low byte

Also, I think it's worth noting that Tom's solution should be used carefully. You have to understand that not all platforms store numbers the same way (see: endianness). While it's unlikely you'll take Arduino code and try to compile it directly on another platform, if one used this code pattern to transfer data between two different platforms, it might work correctly on one end, and not on the other. You should understand that using a union (or, e.g., bitfields, or memcpy) to provide raw access to memory is not a portable way to split integers. Nothing wrong with that, just be aware of the limitations and proceed accordingly.

Thanks for the help.

I'm working through the commands. I do have a question regarding the timing of the arduino (I'm using an Uno).

The spec sheet shows the max time between the clock's last falling edge to the slave select's rising edge is 30ns (see p5 symbol t7). I'm measuring that difference to actually be 5us. Is there a way to shorten this timing or get around it?

Use direct port manipulation to bring it high faster:

PORTD = PORTD & B11111011; // clear PORTD bit 2
...
SPI.transfer(last Byte);
PIND = 0x00000100; // write a 1 to toggle the state of Port D, but 2 for instance

mkuhr:
The spec sheet shows the max time between the clock's last falling edge to the slave select's rising edge is 30ns (see p5 symbol t7). I'm measuring that difference to actually be 5us. Is there a way to shorten this timing or get around it?

That's the max time it requires to avoid internal race conditions. It's not the max time allowed. In general, you can hold slave select as long as you want. Although one might argue it's good practice not to, to avoid inadvertent data input due to noise, coupling with other signals, or cycling the SPI pins for some other purpose. Also some devices may have a "write mode" and "latch mode" where the IC does not do its thing while SS is asserted.

If you'd like to reduce that delay to decrease the time it takes to complete a transfer, by all means -- optimizing the port I/O is a great way to start. Otherwise, don't sweat it.

Glad I misread it! Thanks for the information. I feel comfortable communicating with the chip through SPI now. All that's left is formatting the information so it transfers correctly, which should be easier. Thanks for the help!