communication between AT90CAN128 and ADC over SPI interface

Go To Last Post
9 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hello,

I have to use the AT90CAN128 as the SPI master to communicate with the ADC ADS8344 of TI. The procedure is something like this: MCU sends a control byte to tell which channel should be measured and some configurations => MCU must generate 16 clocks to read back the data. The problem is, the clock can only be generated by sending a byte by MCU and this byte is interpreted as a control byte by the ADC. Has anyone any experiences? I would be very thankful if you could post some codes.

Thank you

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

The AVR SPI master is able to send SPI data in multiples of 8 bytes. The AVR SS pin is an output that your software makes active (low) at the start of the first byte SPI transfer, then is left active (low) through the second SPI transfer byte and is still left active (low) through the third SPI transfer byte. After the third SPI byte your software makes the SS output pin inactive (high). This gives you 24 clocks on the ADS8344 DCLK (AVR SCK) pin during the time period the ADS8344 CS (AVR SS) pin is active (low).

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Thank you for your reply.
The following words are taken from the data sheet of AT90CAN128:

Quote:
…writing a byte to the SPI Data Register starts the SPI clock generator, and the hardware shifts the eight bits into the Slave. After shifting one byte, the SPI clock generator stops, setting the end of transmission flag.

That means there are only 8 clocks available after writing one byte into SPDR, not as you said, man gets 24 successive clocks. That is my initial wish. I would like to have 24 successive clocks. Maybe I misunderstand you?

Thank you

Quote:

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

You must send two dummy bytes to read back the data, as Mike B said.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Yes, the AT90CAN128 SPI will only output 8 clock transitions for each byte written to SPDR.

What is important to the ADS8344 chip is how many clocks happen while the CS pin is active.

The AVR SS output pin makes the ADS8344 CS pin active (a low value).

You write to the AVR SPDR register. There is no useful data returned on the MISO input pin.

The ADS8344 CS pin remains active (still a low value, no change). You need to deal with the BUSY pin.

You write to the AVR SPDR register. The MISO input pin reads a zero bit for the BUSY then the most significant 7 bits of the ADS8344 return value (return bits 15 through 9).

The ADS8344 CS pin remains active (still a low value, no change).

You write to the AVR SPDR register. The MISO input pin reads the 8 bits of the ADS8344 return value (return bits 8 through 1).

After the SPI is done with the third byte, you either start another conversion or you finish with a 32 bit transfer. If you start another conversion while you send the command byte with the START bit set, the MISO input pin reads 1 last bit of the ADS8344 return value (return bit 0). You may continue with as many additional 24 bit SPI transfers until you want to stop. In order to stop you send a last zero SPI byte and the MISO input pin reads 1 last bit of the ADS8344 return value (return bit 0) as the first bit in the final 32 bit transfer.

Finally when you are done, the AVR SS output pin makes the ADS8344 CS pin inactive (a high value).

The CS input pin tells the ADS8344 to begin receiving SPI data and when to stop receiving. The AVR SPI using SPDR can only send 8 bits (one byte) at a time. Three successive AVR SPI bytes is 24 bits total, and four successive AVR SPI bytes is 32 bits total. The CS pin alone defines the start and the end of the SPI transfer no matter how many SPI bytes total are sent.

According to the data sheet the timing (table VI and table VII) looks a little messy. Of course the 16 bit return value from the ADC is skewed. The first return byte only has 7 of the ADC result bits. The second return has 8 of the ADC result bits and the last return has the last ADC return bit. You will probably have to reconstruct this 3 byte skewed value into a normal 2 byte 16 bit value inside the AVR.

The ADC timing is CS goes active, 24 bits, 24 bits, 24 bits, as many of these 24 bit cycles as you want finally a 32 bit final cycle and CS goes inactive.

If you only want a single conversion then CS goes active, a single 32 bit cycle and CS goes inactive.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hello,

Thank you for your reply.

I think Mike B must have done some work with there two devices.
I suppose the byte written into SPDR will not be recognized as a control byte if the START bit is set to Zero (dummy byte), right?

Do I have to connect a pin with BUSY?

ADS8344 supports internal and external clocks for conversion. Which one do you suggest?

Thanks a lot

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

senmeis wrote:
I suppose the byte written into SPDR will not be recognized as a control byte if the START bit is set to Zero (dummy byte), right?

That's not normally how SPI devices work (though I don't know this chip in particular) but in most the chip operates some kind of internal state machine in which it starts in the idle state until a byte arrives on its SI pin that is then interpreted as a control byte. If that control byte has 1 or 2 bytes of following parameter (such as an address or something) the chip switches to a "waiting for addr1" then "waiting for addr2" state after which it then enters a "ready to deliver result" state. While in this state it won't try to interpret anything that appears on SI but will simply use the SCK's to clock out the 8,16,24,whatever number of result bits - ignoring SI as it does so. After the delivery of the 8/16/24/? bits, having moved through various "deliver byte 2", "deliver byte 3"... states it will then return to the idle state to await the next command byte - only while it's in that state will it interpret the next received 8 bits as a control byte.

I'd be kind of surprised if the chip you are using is any different unless, during the deliver results state, it's willing to accept some kind of "abandon current command" control byte?

Cliff

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

senmeis wrote:
I think Mike B must have done some work with there two devices.
Only with the AVR SPI, not with the ADS8344. All I did was a quick read the ADS8344 data sheet, which I didn't want to read in depth because of the time it takes to completely learn a new part (a new part that I'm probably never going to use myself). I was simply trying to explain how to get the multiple byte SPI transfers to work, but when I looked at the ADS8344 data sheet I keep seeing that it is not as simple as most SPI interfaces.
senmeis wrote:
I suppose the byte written into SPDR will not be recognized as a control byte if the START bit is set to Zero (dummy byte), right?
Correct. The ADC command byte (with the START bit written to a one) only occurs in the first byte of every 3 byte (24 bit) SPI transfer or the first byte of a 4 byte (32 bit) SPI transfer. All other SPI bytes from the AVR (MOSI) have a zero bit value for all 8 bits.
senmeis wrote:
Do I have to connect a pin with BUSY?
I am not sure. My guess is you do have to read the BUSY pin with the AVR if you use the internal clock. However, the BUSY timing appears to be fixed such that you should know what the BUSY state delay is if you use the external clock (I could be wrong about this).
senmeis wrote:
ADS8344 supports internal and external clocks for conversion. Which one do you suggest?
I honestly can't say which one I would use. I would have to actually setup and use the ADS8344 to figure out which one has any possible advantages or disadvantages.

Cliff,

The ADS8344 is a strange chip. It appears that the ADC itself is clocked from the external SPI clock or from an internal clock. The internal clock appears to have some timing complexity issues with regard to the SPI clock. There also appears to be timing limits when using the SPI clock for the ADC external clock. What senmeis meant by the START bit is the first bit of every 8 bit MOSI SPI byte has a dedicated value in the ADS8344. If this bit is a one value then it indicates an ADS8344 command byte, with the command itself in the following 7 bits. According to the data sheet all other “non-command” MOSI SPI bytes from the master are all zero bits and only really provide a master clock for MISO data back to the AVR SPI master (also an ADC clock when external clock is set). I think this ADC clock arrangement may have something to do with the one bit skew in the 16 bit ADC return value, which is why this ADC requires an extra SPI byte to retrieve the last bit of the 16 bit result. The only “magic” I can see in the START bit, is after the first 24 SPI clocks you have a choice to send one last SPI byte with a zero value (ending the entire ADC cycle with a final 32 bit SPI cycle) or you may choose to start another 24 bit SPI cycle for a new conversion with the START bit set in the next SPI byte (the first of 3 SPI bytes). If you start a new 24 bit SPI conversion cycle you get this same choice at the end of each 24 bit SPI cycle (i.e. either send a last zero value SPI byte to end it or use the START bit in another 24 bit SPI conversion cycle). No matter what, the last SPI cycle is supposed to be a 4 byte (32 bit) cycle after which the SPI CS input pin is finally set inactive.

That last remaining single ADC conversion bit is extracted (AVR MISO) during the next command START bit (of a new 24 bit cycle) or during the first bit of the last zero byte (to finish a 32 bit cycle). The remaining 7 bits of the last zero byte (of a 32 bit cycle) are wasted padding that only fill out the SPI multiple of 8 bits transfer requirement.

It appears this ADC has no isolated command without any subsequent conversion (at least as far as I read the data sheet). Every 24 or 32 bit SPI cycle involves an ADC conversion. However, some command driven changes may invalidate the conversion from that command, even though you are stuck completing the invalid conversion anyway. My guess is this fixed command format is probably a byproduct of the ADC clocking methods.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hello,

I have tried to write some code to drive this ADC, but somehow it doesn't work.
The output is always 0. The code is below. Is the timing correct?

...
SPI_MasterInit();
/* one ADC measurement */	
PORTB &= 0xFE;	// set SS to low
// set command to ADS8344: start bit, channel 0, single ended and no power down
SPI_Master_Transmit_Receive(0x87);	
adc_data[2] = SPI_Master_Transmit_Receive(0x00);	// highst 7 bits
adc_data[1] = SPI_Master_Transmit_Receive(0x00);	// middle 8 bits
adc_data[0] = SPI_Master_Transmit_Receive(0x00);	// lowest 1 bit
PORTB |= 0x01;	// set SS to high
...

/*	SPI initialization */
void SPI_MasterInit(void)
{
	// set MOSI, SCK and SS as output
	DDRB = (1 << DDB2) | (1 << DDB1) | (1 << DDB0);
	//	Enable SPI, Master, set clock rate fck/16
	SPCR =(1<<SPE)|(1<<MSTR)|(1<<SPR1);
}

/*	SPI transmit and receive */
UINT8 SPI_Master_Transmit_Receive(UINT8 spi_data)
{
	SPDR = spi_data;
	while (!(SPSR & (1 << SPIF)));
	return SPDR;
}