From: Bill on
Hi,

I'm trying to pull out data from the ADS8320 (a 16-bit ADC by Analog
Devices. See bottom of page 10 in
http://focus.ti.com/lit/ds/symlink/ads8320.pdf ) using the SPI in an
AT91SAM7S256. The problem is that the ADC needs 6 extra clock cycles
to sample the analog signal, before the 16 cycles that will output
each of the conversion result bits. So, a complete ADC cycle involves
a minimum of 22 clock cycles. Now, the SPI in the AT91SAM7 (and, as
far as I've seen, in all other MCUs), cannot generate more than 16
clock cycles within one CS activation.

How am I supposed to do this, in an elegant way? Of course I could bit
bang those lines, but I hate doing that, because it adds load to the
CPU, and doesn't take advantage of the SPI and DMA.

The AT91SAM7S256 allows holding the CS low until a new device is
addressed, so I could initiate two 11-bit readings in a row (in such a
way that the ADC would think it is a single CS assertion with 22 clock
cycles inside), and discard the bits with no information, but that's
still ugly to me. It would use the SPI, but not the DMA, and the two
readings would be different (the first one should hold CS low. The
second one should leave it high), which is kind of non-homogeneous.

Any more elegant ideas?

Thank you.
From: Vladimir Vassilevsky on


Bill wrote:

> Hi,
>
> I'm trying to pull out data from the ADS8320 (a 16-bit ADC by Analog
> Devices.
^^^^^^^^^^^^^^^^^^^^^^

> See bottom of page 10 in
> http://focus.ti.com/lit/ds/symlink/ads8320.pdf )
^^^^^^^^^^^^^^^^^^^^^

LOL

> using the SPI in an
> AT91SAM7S256. The problem is that the ADC needs 6 extra clock cycles
> to sample the analog signal, before the 16 cycles that will output
> each of the conversion result bits. So, a complete ADC cycle involves
> a minimum of 22 clock cycles. Now, the SPI in the AT91SAM7 (and, as
> far as I've seen, in all other MCUs), cannot generate more than 16
> clock cycles within one CS activation.
>
> How am I supposed to do this, in an elegant way?

Generate transactions by SPI, but control the CS signal as GPIO.
I.e. assert the CS, read the required number of bits by SPI, deassert
the CS.


Vladimir Vassilevsky
DSP and Mixed Signal Design Consultant
http://www.abvolt.com
From: MK on

"Bill" <a(a)a.a> wrote in message
news:5gnca5d000ql2jlabkd42od9tv1mcgr9b0(a)4ax.com...
> Hi,
>
> I'm trying to pull out data from the ADS8320 (a 16-bit ADC by Analog
> Devices. See bottom of page 10 in
> http://focus.ti.com/lit/ds/symlink/ads8320.pdf ) using the SPI in an
> AT91SAM7S256. The problem is that the ADC needs 6 extra clock cycles
> to sample the analog signal, before the 16 cycles that will output
> each of the conversion result bits. So, a complete ADC cycle involves
> a minimum of 22 clock cycles. Now, the SPI in the AT91SAM7 (and, as
> far as I've seen, in all other MCUs), cannot generate more than 16
> clock cycles within one CS activation.
>
> How am I supposed to do this, in an elegant way? Of course I could bit
> bang those lines, but I hate doing that, because it adds load to the
> CPU, and doesn't take advantage of the SPI and DMA.
>
> The AT91SAM7S256 allows holding the CS low until a new device is
> addressed, so I could initiate two 11-bit readings in a row (in such a
> way that the ADC would think it is a single CS assertion with 22 clock
> cycles inside), and discard the bits with no information, but that's
> still ugly to me. It would use the SPI, but not the DMA, and the two
> readings would be different (the first one should hold CS low. The
> second one should leave it high), which is kind of non-homogeneous.
>
> Any more elegant ideas?
>
> Thank you.

Hello Bill,

On my web site you can find a VHDL model of the ADS8320 - which won't help
you much with using the SAM. In the end I didn't use an FPGA on that project
but I bit banged the ADS8320 from a micro. (It was so long ago that have
forgotten which one !)

Can you get anywhere by doing what TI hint at and do 3 times 8 bit SPI
transfers for each sample ?

Michael Kellett

www.mkesc.co.uk


From: Bill on
On Tue, 08 Sep 2009 09:11:13 -0500, Vladimir Vassilevsky
<nospam(a)nowhere.com> wrote:


>> I'm trying to pull out data from the ADS8320 (a 16-bit ADC by Analog
>> Devices.
>^^^^^^^^^^^^^^^^^^^^^^
>
>> See bottom of page 10 in
>> http://focus.ti.com/lit/ds/symlink/ads8320.pdf )
>^^^^^^^^^^^^^^^^^^^^^
>
>LOL

:-) Sorry. TI. I'm using other Analog Devices ICs.

>Generate transactions by SPI, but control the CS signal as GPIO.
>I.e. assert the CS, read the required number of bits by SPI, deassert
>the CS.

But still, bye bye DMA.


I'm very curious... what were the guys at TI (and at some other
companies) thinking when they designed this ADC with SPI interface?
Which SPI hardware were they thinking would be able to pull out data
in one transaction? Does anyone know of an MCU with SPI hardware able
to do this? Amazing.

Best,
From: Mel on
Bill wrote:
> I'm trying to pull out data from the ADS8320 (a 16-bit ADC by Analog
> Devices. See bottom of page 10 in
> http://focus.ti.com/lit/ds/symlink/ads8320.pdf ) using the SPI in an
> AT91SAM7S256. [ ... ]
> How am I supposed to do this, in an elegant way? Of course I could bit
> bang those lines, but I hate doing that, because it adds load to the
> CPU, and doesn't take advantage of the SPI and DMA.

You have Peripheral DMA Controller, use it. This is for a Microchip ADC,
but the three-byte transfer might resemble your problem. The method on the
ADC side was written up in the MCP3008 datasheet. Code fragment:


inline void poll_mcp3008 (int pad)
{
// Mode-register bits to select each of the MCP3008s, with MSTR bit
set
...
static const int modecsbits[4] = {0x000F0001 ^ (1 << (16+0))
, 0x000F0001 ^ (1 <<
(16+1))
, 0x000F0001 ^ (1 <<
(16+2))
, 0x000F0001 ^ (1 <<
(16+3))
};
// set SPI_MR(PCS) to select the pad
AT91C_BASE_SPI->SPI_MR = modecsbits[(pad >> 3) & 3];
// prime buffer with a start bit, 'single' bit, and channel number
pan_buf[0] = 1; // start bit
pan_buf[1] = 0x80 | ((pad & 7) << 4); // 'single' bit, channel
number,
2 pad bits and space for high 2 bits of value
pan_buf[2] = 0; // pad space where
low 8
bits of value will appear
// start a conversion
SPI_RwBuffer (AT91C_BASE_SPI, pan_buf, sizeof pan_buf);
}


And the SPI-RwBuffer added to the spi library routines (based on the other
SPI routines):


unsigned char SPI_RwBuffer(AT91S_SPI *spi,
void *buffer,
unsigned int length)
{
// Check if the first bank is free
if (spi->SPI_RCR == 0) {
// set up to overlay the write buffer with incoming data ..
spi->SPI_RPR = (unsigned int) buffer;
spi->SPI_RCR = length;
spi->SPI_TPR = (unsigned int) buffer;
spi->SPI_TCR = length;
spi->SPI_PTCR = AT91C_PDC_RXTEN | AT91C_PDC_TXTEN;
return 1;
}
// Check if second bank is free
else if (spi->SPI_RNCR == 0) {

spi->SPI_RNPR = (unsigned int) buffer;
spi->SPI_RNCR = length;
spi->SPI_TNPR = (unsigned int) buffer;
spi->SPI_TNCR = length;
return 1;
}

// No free bank
return 0;
}


In this case the data from the MCP3008 overlays the buffer that contained
the tranmitted request. It doesn't have to be this way, but it was easy to
implement. SPI device interrupts when the full 3 bytes have been
transferred both ways.


Mel.