I'm going to make a Maxim MAX11040K talk with a Arduino Due. The MAX11040K Is a 4 channel, 24bit ADC... as such, when I want to read the data register, the response will be 96bits long... in fact, the response will be a variable amount of bytes depending on which register I read from it, which may be a small problem - but not too large I think.
The problem is, for each command, the Due Extended SPI tutorial page seems to expect that I will receive only one byte as a response instead of 12 bytes. Reading the MAX11040K data sheet, I just send the 8bit command once, and then I will get back anywhere from 1 to 12 bytes back. Since using SPI_CONTINUE with SPI.transfer() implies that the command is sent one more time, I don't think that's a solution. Any ideas?
EDIT: This is what I have so far:
#include <SPI.h>
#include "customtypes.h"
#define ADC_CS 22
#define DAC_CS 23
#define ADC_READ 1
#define ADC_WRITE 0
#define ADC_SAMPLING-INSTANT-CONTROL-REG 0x40 //32bit
#define ADC_DATARATE-CONTROL-REG 0x50 //16bit
#define ADC_CONFIGURE-REG 0x60 //8bit
#define ADC_DATA-REG 0x70 //24*4bit
//the following pin numbers may change at any time
void setup() {
// put your setup code here, to run once:
Serial.begin(9600);
SPI.begin(ADC_CS);
SPI.begin(DAC_CS);
SPI.setClockDivider(2); //runs it at 42MHz
SPI.setBitOrder(MSBFIRST);
SPI.setDataMode(SPI_MODE0, DAC_CS); // page 29
SPI.setDataMode(SPI_MODE2, ADC_CS); // page 16
}
void loop() {
// put your main code here, to run repeatedly:
}
void dac_talk(int cmd, int number){
if(number > 131071 || number < -131072){
Serial.println("Value outside 17bit range!");
}
dacSPIframe command;
command.bitfield.value = number;
command.bitfield.cmd = cmd;
SPI.transfer(DAC_CS,command.bytes[2],SPI_CONTINUE);
SPI.transfer(DAC_CS,command.bytes[1],SPI_CONTINUE);
SPI.transfer(DAC_CS,command.bytes[0]);
};
void adc_read(byte address, byte resultcontainer[]){
byte command;
// if you want to read, add 128
command = command+0x80;
Serial.print("Sending this command to ADC: ");
Serial.print(command,BIN);
Serial.print("\n");
SPI.transfer(ADC_CS,command);
};
background:
with SPI_Continue the CS_pin keeps low
and every other transfer 8 bits of MISO are clocked in
so for your SPI slave it looks like one big command comming in
the last SPI.transfer without SPI_CONTINUE let the CS_pin go to high again.
From the data sheet, the minimum period for SCLK is 50ns which is 20 MHz frequency ... this means that the clock divisor would have to be at least 5 for 16.8 MHz. I would suggest using the default (4 MHz) until communication is established.
From my experience with SPI:
This would require using the DUE's port as an SPI Master. The master controls the SCLK, so in order to receive any information, you need to send information. The SCLK will toggle only 8 times for each byte sent out on the MOSI line. At the same time, 8 BITS of information will be received on the MISO line. You'll need to use SPI_CONTINUE with the transfer function in order to hold the CS line low. After each byte, you'll need to read the bits received, then continue this process until completed ... the last transfer call will not use SPI_CONTINUE so the CS line can go HIGH.
When in SPI master mode, there is no way to get clock pulses on SCLK unless data is sent on MOSI. Even if its not a command or useful information - in this case just consider it dummy data where its only purpose is to get another 8 SCLK pulses for each byte sent.