EmbeddedRelated.com
Forums
The 2024 Embedded Online Conference

16-bit SPI trying to read from 22-clock cycle ADC

Started by Bill September 8, 2009
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.

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
"Bill" <a@a.a> wrote in message 
news:5gnca5d000ql2jlabkd42od9tv1mcgr9b0@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
On Tue, 08 Sep 2009 09:11:13 -0500, Vladimir Vassilevsky
<nospam@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,
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.
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 ) 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.
Hi, I wrote a driver for the (similar ?) ad7705. It was driven by a int timer based state machine to sequence start of conversion, read result etc, over the 2 input channels. This was on a Dragonball (68k) and iirc, the spi port may have had a short queue to make life easier. There was no cs on the spi port, so an io port line was used for chip select. I do remember that the ads device was a little weird in terms of programming, and there are some 'hinted' at issues in the data sheet, but the results were fine. It was 2004, so would need to dig out the code, but would assume the pragmatic approach was taken. ie: just wrote / read as many bytes as were required to get at the device and masked off the unwanted stuff. It's far from an inelegant solution if implemented and documented properly... Regards, Chris
On Tue, 08 Sep 2009 17:23:27 +0200, Bill <a@a.a> wrote:

>On Tue, 08 Sep 2009 09:11:13 -0500, Vladimir Vassilevsky ><nospam@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.
I haven't done a lot of (er, any) looking but one processor that I'm using right now has a configuration register for its SPI peripheral to do 8 to 16 bits per transfer, so two 11-bit transfers would be easy enough to set up. NXP's LPC2119/2129. No DMA in this one, but (okay, I did a little looking) the LPC24xx chips support configurable transfer lengths and DMA on their SSP peripherals. -- Rich Webb Norfolk, VA
On Tue, 08 Sep 2009 11:23:38 -0400, Mel <mwilson@the-wire.com> wrote:


>You have Peripheral DMA Controller, use it.
I would gladly use it, but I don't think it is possible. DMA is not able neither to automatically change CSAAT (Chip Select Active After Transfer) configuration between 8-bit transactions 2 and 3, nor to bit bang CS to my needs. Best,
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 ) 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
If Englich is not yuor frist langwige, have someone else read if to you. See Bottom of page 10 again ! don
> 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.
>>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. > >I haven't done a lot of (er, any) looking but one processor that I'm >using right now has a configuration register for its SPI peripheral to >do 8 to 16 bits per transfer, so two 11-bit transfers would be easy >enough to set up. NXP's LPC2119/2129. No DMA in this one, but (okay, I >did a little looking) the LPC24xx chips support configurable transfer >lengths and DMA on their SSP peripherals.
No, no... the ADC cannot see CS going up and then again down between two transfers, because that would reset the conversion process. That means I have to bit bang CS or change CSAAT configuration (a bit that determines whether CS remains low after each transfer) between the two transfers. And, of course, no possible DMA. So, in other words, your LPC2119 cannot do that in one transfer, either, and I doubt that the DMA in the LPC24xx will be of any use, in this problem. Best,

The 2024 Embedded Online Conference