Pages: [1]   Go Down
Author Topic: Receiving more than one byte as response from SPI  (Read 712 times)
0 Members and 1 Guest are viewing this topic.
Offline Offline
Newbie
*
Karma: 0
Posts: 10
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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:
Code:
#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);
};
Logged

Global Moderator
Offline Offline
Brattain Member
*****
Karma: 499
Posts: 19070
Lua rocks!
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Normally each SPI.transfer returns one byte, so you call it 12 times, right? However I'm not an expert on the Due.

http://www.gammon.com.au/spi

Moving this to the Due section.
Logged


Offline Offline
Newbie
*
Karma: 0
Posts: 10
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

But calling SPI.transfer() 12 times means sending a command 12 times.... I only need to send it once!
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 8
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hi,

send your 8 bit command

Code:
Spi.transfer(CS_pin, command, SPI_CONTINUE);

and then for every byte (n) you want to read an other

Code:
byte_1 = SPI.transfer(CS_pin, 0x00, SPI_CONTINUE);
byte_2 = SPI.transfer(CS_pin, 0x00, SPI_CONTINUE);
...
byte_n = SPI.transfer(CS_pin, 0x00);

not tested, but with SPI diagram on page 17, it should work smiley
http://datasheets.maximintegrated.com/en/ds/MAX11040K-MAX11060.pdf

if you want to write more than one byte it works the same

I use it this way for 8/16/32 bit read & writes to AD5666 / MCP4261 and it works fine (if only one CS is used in the sketch).
[edit]Multiple usage of the predefined CS work now!
see http://forum.arduino.cc/index.php?topic=189682.0

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.
« Last Edit: September 24, 2013, 02:41:57 pm by MichaelBot » Logged

Global Moderator
Offline Offline
Brattain Member
*****
Karma: 499
Posts: 19070
Lua rocks!
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

But calling SPI.transfer() 12 times means sending a command 12 times.... I only need to send it once!

Read my link. SPI is always two-way transfer. Usually the receiving end will accept a NOP or similar.
Logged


Global Moderator
Offline Offline
Brattain Member
*****
Karma: 499
Posts: 19070
Lua rocks!
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

See this from the datasheet:



You can see that after the command DIN is low (in other words you are sending 0x00 bytes).
Logged


Canada
Offline Offline
Sr. Member
****
Karma: 13
Posts: 437
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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.
Logged

Electricity is really just organized lightning - George Carlin

Offline Offline
Newbie
*
Karma: 0
Posts: 10
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Got it, thanks very much for your answers!
Logged

Pages: [1]   Go Up
Jump to: