Reply by Nicholas Kinar●November 8, 20102010-11-08
>
> I think you may want to look at the AT91SAM9G45 instead of the
> AT91SAM9RL64.
> This part has dual SPI, and on top of that, each USART has a
> an SPI Master mode for a total of 6 SPI Masters.
> It also supports DDR-2 memories which will make the memory
> subsystem much cheaper than that of the SAM9RL64 which will have to use
> SDRAM.
>
> An alternative , probably better, is to use the SSC.
> This should allow you to use the daisy chain mode of the ADCs
> on a single serial interface with DMA support.
>
> The rising edge of the TX framesync is connected to CNV,
> The RX Framesync, can be connected to the SPI chip selects
>
>
> Best Regards
> Ulf Samuelsson
>
Thanks, Ulf; this is greatly appreciated, and I have to admit that the
AT91SAM9G45 part looks very interesting!
I also like the idea of daisy-chaining the ADCs and connecting them all
to the SSC bus.
Looking again at the AD7691 datasheet
(http://www.analog.com/static/imported-files/data_sheets/AD7691.pdf),
how might I wire up the daisy-chained ADCs to the SSC bus?
Pages 22-23 of the AD7691 datasheet shows the connections required for
daisy-chain mode. Taking into consideration your recommendation, I
think that the following pin mapping table would work.
TABLE:
Processor SSC bus ==> ADC
------------------------------
TX-FRAMESYNC ==> CNV
RX ==> SDO of last ADC
CLK ==> CLK
Could I use a GPIO as an interrupt (IRQ), as shown on page 23 of the
AD7691 datasheet?
How would I set up a Linux driver to take a sample at a 1 kHz rate? I
suppose that TX-FRAMESYNC would be toggled and then allowed to stay high
while the data would be read from the ADCs. The data would then be
transferred directly into memory using DMA.
Is there support for this type of operation in the Linux kernel? Is it
possible to read arbitrary-length words from the SSC bus?
Nicholas
Reply by Ulf Samuelsson●November 5, 20102010-11-05
2010-11-03 01:40, Nicholas Kinar skrev:
> Hello,
>
> I would like to interface five AD7691 18-bit ADCs to a Atmel ARM
> processor (AT91SAM9RL) running the Linux operating system. The processor
> will be clocked at a speed of ~200 MHz, and I would like to sample the
> ADCs at a rate of 10 kHz.
>
> The AD7691 ADC
> (http://www.analog.com/static/imported-files/data_sheets/AD7691.pdf) has
> a conversion pin CNV. A conversion is triggered by a rising pulse on
> this pin. The data is then read from each ADC using an SPI interface.
>
> The AT91SAM9RL processor has only one SPI bus without FIFO.
>
> What is the best way to do this using a Linux kernel driver? Two likely
> scenarios:
>
> (1) All ADCs are wired to the SPI bus, and each ADC has a /CS pin wired
> to the AT91SAM9RL processor. The AT91SAM9RL toggles the CNV pin so that
> the ADCs are read at a 10 kHz sampling rate. The AT91SAM9RL then selects
> each /CS pin of the five ADCs, and reads each slave in order.
>
> BUT, does writing a Linux kernel driver guarantee that the processor can
> toggle the CNV pin and then read the five ADCs in sequential order at a
> rate of 10kHz?
>
> (2) The AD7691 can be daisy chained. Would it be possible to daisy-chain
> all five ADCs and then read the data as a big (18 bit)(5) = 90 bit
> transfer?
>
> What type of kernel driver would be most appropriate, and what would be
> the best way to wire up the ADCs if I am to use a kernel driver for the
> AD7691 ADC running on a AT91SAM9RL Linux board?
>
> Nicholas
I think you may want to look at the AT91SAM9G45 instead of the AT91SAM9RL64.
This part has dual SPI, and on top of that, each USART has a
an SPI Master mode for a total of 6 SPI Masters.
It also supports DDR-2 memories which will make the memory
subsystem much cheaper than that of the SAM9RL64 which will have to use
SDRAM.
An alternative , probably better, is to use the SSC.
This should allow you to use the daisy chain mode of the ADCs
on a single serial interface with DMA support.
The rising edge of the TX framesync is connected to CNV,
The RX Framesync, can be connected to the SPI chip selects
Best Regards
Ulf Samuelsson
Reply by Nicholas Kinar●November 4, 20102010-11-04
>
> According to the AD7691 data sheet, there is no problem shifting more than
> 18 bits, so it should be possible to use h/w spi for shifting 3 bytes and
> then manipulate in s/w.
>
That sounds good, Robert; thank you for pointing this out in the context
of my application.
Nicholas
Reply by RockyG●November 4, 20102010-11-04
>
>>
>> I think an FPGA might be simpler if you absolutely need 18-bit
>> transfers. On a small micro, you could transfer 18 bits from
>> the ADC, but would only need to send two 8-bit bytes async
>> to the Linux machine if 16-bit resolution is adequate.
>>
>>
>> On one system where I used an MSP430 and two ADCs, I bypassed the
>> MSP430 hardware SPI, and connected each SPI output on the ADC to
>> a separate MSP430 input pin. I then used bit-banging on output
>> pins to clock both ADCs at once. After each clock, the input
>> port was read and the appropriate bit shifted into a data word
>> for each ADC. (Actually, for each ADC channel, since I was using
>> 4-channel ADCs and using more output pins to select the appropriate
>> channel.)
>>
>> While the bit-banging wasn't as fast as hardware SPI, it allowed
>> be to do whatever number of bits I required and collect pairs
>> of channels simultaneously. In your case, you would have to
>> bit-bang 18 clocks and roll in 5 data words, then set up a
According to the AD7691 data sheet, there is no problem shifting more than
18 bits, so it should be possible to use h/w spi for shifting 3 bytes and
then manipulate in s/w.
---------------------------------------
Posted through http://www.EmbeddedRelated.com
Reply by Nicholas Kinar●November 3, 20102010-11-03
>
> I think an FPGA might be simpler if you absolutely need 18-bit
> transfers. On a small micro, you could transfer 18 bits from
> the ADC, but would only need to send two 8-bit bytes async
> to the Linux machine if 16-bit resolution is adequate.
>
>
> On one system where I used an MSP430 and two ADCs, I bypassed the
> MSP430 hardware SPI, and connected each SPI output on the ADC to
> a separate MSP430 input pin. I then used bit-banging on output
> pins to clock both ADCs at once. After each clock, the input
> port was read and the appropriate bit shifted into a data word
> for each ADC. (Actually, for each ADC channel, since I was using
> 4-channel ADCs and using more output pins to select the appropriate
> channel.)
>
> While the bit-banging wasn't as fast as hardware SPI, it allowed
> be to do whatever number of bits I required and collect pairs
> of channels simultaneously. In your case, you would have to
> bit-bang 18 clocks and roll in 5 data words, then set up a
> DMA async serial output for 10 or 15 bytes once every
> 100microseconds.
>
> That could be challenging, even on a 25MHz MSP430. It should
> easily be possible on an FPGA if you are not worried about
> power consumption. I was running my whole 8 channels x 100Hz
> system on about 15-20mA at 3.3V. If you're running a Linux
> system, I doubt that a few hundred extra milliwatts are much
> of a problem!
>
> One think I always worry about with async transfers on Linux
> systems is the possibility of internal buffering delays--
> especially if there are hardware FIFOs on the UART ports.
> It may be that when you read the serial data has only a
> loose relationship to when the data actually arrived at
> the serial port. Not the best of conditions if you have
> to evaluate the data for real-time control---especially
> at high data rates.
>
>
Thanks, Mark; this makes a lot of sense to me, and I think that the best
way to do this would be to use a small uP such as the MSP430. For me,
this seems to be the best way to go, especially for the smaller sampling
rates that I am working with.
Nicholas
Reply by Mark Borgerson●November 3, 20102010-11-03
In article <4CD1862F.4010408@usask.ca>, n.kinar@usask.ca says...
>
> >>
> >> What type of kernel driver would be most appropriate, and what would be
> >> the best way to wire up the ADCs if I am to use a kernel driver for the
> >> AD7691 ADC running on a AT91SAM9RL Linux board?
> >>
> > The last time I faced a challenge like that, I put an MSP430 CPU in
> > between the ARM CPU and the ADC. The MSP430 handled all the ADC timng
> > and SPI transfers, and sent async serial packets to the ARM. However,
> > I didn't have quite as high a data rate. If you followed the
> > same method, you would need 10,000 x 5 x 3 bytes per second,
> > or 15,000 bytes/sec. To do that, you would need to use 230KB
> > async comms. OTOH, with the DMA capability of the ARM and good
> > LINUX serial port drivers, you wouldn't have to do any kernal
> > programming----just suck up the data from the serial port.
> >
>
> Thanks for your response, Mark! This sounds really interesting, and it
> is a very neat solution. So suppose that we have the following setup.
> The five ADCs are connected as SPI slaves to a small microcontoller
> master such as an ATmega. Each ADC has a separate /CS connected to the
> ATmega. The ATmega handles the sampling of data at a rate of 10 kHz.
> Each sample is simply sent over the serial port to the ARM. A
> user-space program is used to read the serial port.
>
> Alternately, perhaps a small FPGA could be used to read all of the ADCs
> at the same time. The FPGA might also be able to read the ADCs in
> daisy-chain mode. Then the FPGA could send the data over the serial
> port to the ARM.
>
> Could the ATmega or the FPGA be connected to a GPIO on the ARM chip, and
> after every sample, the GPIO could be toggled to send an interrupt? I
> am concerned about using synchronous transfers since I don't know if a
> Linux kernel driver could handle this. Async transfers seem to be a
> much better way to do this.
>
> Could the ATmega or the FPGA be connected to the ARM SPI bus, and the
> transfers sent in an synchronous fashion? I may have to write a kernel
> driver for this, but I don't know if the Linux kernel can handle the
> interrupt that quickly.
Linux kernal questions are way over my head.
>
> >
> > Do you think you'll be able to get true 18-bit resolution from
> > your ADC when it's directly connected to the CPU? If noise
> > limits to you 16 bits or less, you could cut the data transfer
> > requirements by 1/3 by using only the 16 MSBs. (It's generally
> > difficult to program 18-bit SPI transfers unless you have something
> > like the Moto Queued Serial Peripheral. Been there, done that---
> > it was never much fun.)
> >
>
> Sure, 16 MSBs would probably be good as well; I would have to experiment
> and see if this fits my data requirements. Could I do 18 bit transfers
> with a small micro such as the ATmega? IMHO, 18-bit transfers would
> probably be simpler with a FPGA.
I think an FPGA might be simpler if you absolutely need 18-bit
transfers. On a small micro, you could transfer 18 bits from
the ADC, but would only need to send two 8-bit bytes async
to the Linux machine if 16-bit resolution is adequate.
On one system where I used an MSP430 and two ADCs, I bypassed the
MSP430 hardware SPI, and connected each SPI output on the ADC to
a separate MSP430 input pin. I then used bit-banging on output
pins to clock both ADCs at once. After each clock, the input
port was read and the appropriate bit shifted into a data word
for each ADC. (Actually, for each ADC channel, since I was using
4-channel ADCs and using more output pins to select the appropriate
channel.)
While the bit-banging wasn't as fast as hardware SPI, it allowed
be to do whatever number of bits I required and collect pairs
of channels simultaneously. In your case, you would have to
bit-bang 18 clocks and roll in 5 data words, then set up a
DMA async serial output for 10 or 15 bytes once every
100microseconds.
That could be challenging, even on a 25MHz MSP430. It should
easily be possible on an FPGA if you are not worried about
power consumption. I was running my whole 8 channels x 100Hz
system on about 15-20mA at 3.3V. If you're running a Linux
system, I doubt that a few hundred extra milliwatts are much
of a problem!
One think I always worry about with async transfers on Linux
systems is the possibility of internal buffering delays--
especially if there are hardware FIFOs on the UART ports.
It may be that when you read the serial data has only a
loose relationship to when the data actually arrived at
the serial port. Not the best of conditions if you have
to evaluate the data for real-time control---especially
at high data rates.
Mark Borgerson
Reply by Nicholas Kinar●November 3, 20102010-11-03
>>
>> What type of kernel driver would be most appropriate, and what would be
>> the best way to wire up the ADCs if I am to use a kernel driver for the
>> AD7691 ADC running on a AT91SAM9RL Linux board?
>>
> The last time I faced a challenge like that, I put an MSP430 CPU in
> between the ARM CPU and the ADC. The MSP430 handled all the ADC timng
> and SPI transfers, and sent async serial packets to the ARM. However,
> I didn't have quite as high a data rate. If you followed the
> same method, you would need 10,000 x 5 x 3 bytes per second,
> or 15,000 bytes/sec. To do that, you would need to use 230KB
> async comms. OTOH, with the DMA capability of the ARM and good
> LINUX serial port drivers, you wouldn't have to do any kernal
> programming----just suck up the data from the serial port.
>
Thanks for your response, Mark! This sounds really interesting, and it
is a very neat solution. So suppose that we have the following setup.
The five ADCs are connected as SPI slaves to a small microcontoller
master such as an ATmega. Each ADC has a separate /CS connected to the
ATmega. The ATmega handles the sampling of data at a rate of 10 kHz.
Each sample is simply sent over the serial port to the ARM. A
user-space program is used to read the serial port.
Alternately, perhaps a small FPGA could be used to read all of the ADCs
at the same time. The FPGA might also be able to read the ADCs in
daisy-chain mode. Then the FPGA could send the data over the serial
port to the ARM.
Could the ATmega or the FPGA be connected to a GPIO on the ARM chip, and
after every sample, the GPIO could be toggled to send an interrupt? I
am concerned about using synchronous transfers since I don't know if a
Linux kernel driver could handle this. Async transfers seem to be a
much better way to do this.
Could the ATmega or the FPGA be connected to the ARM SPI bus, and the
transfers sent in an synchronous fashion? I may have to write a kernel
driver for this, but I don't know if the Linux kernel can handle the
interrupt that quickly.
>
> Do you think you'll be able to get true 18-bit resolution from
> your ADC when it's directly connected to the CPU? If noise
> limits to you 16 bits or less, you could cut the data transfer
> requirements by 1/3 by using only the 16 MSBs. (It's generally
> difficult to program 18-bit SPI transfers unless you have something
> like the Moto Queued Serial Peripheral. Been there, done that---
> it was never much fun.)
>
Sure, 16 MSBs would probably be good as well; I would have to experiment
and see if this fits my data requirements. Could I do 18 bit transfers
with a small micro such as the ATmega? IMHO, 18-bit transfers would
probably be simpler with a FPGA.
Thanks, Mark.
Reply by Mark Borgerson●November 3, 20102010-11-03
In article <4CD0AF87.3010608@usask.ca>, n.kinar@usask.ca says...
> Hello,
>
> I would like to interface five AD7691 18-bit ADCs to a Atmel ARM
> processor (AT91SAM9RL) running the Linux operating system. The
> processor will be clocked at a speed of ~200 MHz, and I would like to
> sample the ADCs at a rate of 10 kHz.
>
> The AD7691 ADC
> (http://www.analog.com/static/imported-files/data_sheets/AD7691.pdf) has
> a conversion pin CNV. A conversion is triggered by a rising pulse on
> this pin. The data is then read from each ADC using an SPI interface.
>
> The AT91SAM9RL processor has only one SPI bus without FIFO.
>
> What is the best way to do this using a Linux kernel driver? Two likely
> scenarios:
>
> (1) All ADCs are wired to the SPI bus, and each ADC has a /CS pin wired
> to the AT91SAM9RL processor. The AT91SAM9RL toggles the CNV pin so that
> the ADCs are read at a 10 kHz sampling rate. The AT91SAM9RL then
> selects each /CS pin of the five ADCs, and reads each slave in order.
>
> BUT, does writing a Linux kernel driver guarantee that the processor can
> toggle the CNV pin and then read the five ADCs in sequential order at a
> rate of 10kHz?
>
> (2) The AD7691 can be daisy chained. Would it be possible to
> daisy-chain all five ADCs and then read the data as a big (18 bit)(5) =
> 90 bit transfer?
>
> What type of kernel driver would be most appropriate, and what would be
> the best way to wire up the ADCs if I am to use a kernel driver for the
> AD7691 ADC running on a AT91SAM9RL Linux board?
>
The last time I faced a challenge like that, I put an MSP430 CPU in
between the ARM CPU and the ADC. The MSP430 handled all the ADC timng
and SPI transfers, and sent async serial packets to the ARM. However,
I didn't have quite as high a data rate. If you followed the
same method, you would need 10,000 x 5 x 3 bytes per second,
or 15,000 bytes/sec. To do that, you would need to use 230KB
async comms. OTOH, with the DMA capability of the ARM and good
LINUX serial port drivers, you wouldn't have to do any kernal
programming----just suck up the data from the serial port.
Do you think you'll be able to get true 18-bit resolution from
your ADC when it's directly connected to the CPU? If noise
limits to you 16 bits or less, you could cut the data transfer
requirements by 1/3 by using only the 16 MSBs. (It's generally
difficult to program 18-bit SPI transfers unless you have something
like the Moto Queued Serial Peripheral. Been there, done that---
it was never much fun.)
Mark Borgerson
Reply by Nicholas Kinar●November 3, 20102010-11-03
On 03/11/2010 1:59 AM, Stef wrote:
> In comp.arch.embedded,
> Clifford Heath<no@spam.please.net> wrote:
>> Nicholas Kinar wrote:
>>> I would like to interface five AD7691 18-bit ADCs to a Atmel ARM
>>> processor (AT91SAM9RL)
>>
>> Some of the ST ARM chips might be more suitable. They have double-buffered DMA.
>>
>> I suspect you're going to need that.
>
> The AT91SAM9RL has DMA as well. Each SPI channel has it's own PDC.
>
Thanks, Stef; DMA does indeed look like the way to go with these transfers.
Nicholas
Reply by Nicholas Kinar●November 3, 20102010-11-03
On 03/11/2010 8:02 AM, Clifford Heath wrote:
> Nicholas Kinar wrote:
>> I would like to interface five AD7691 18-bit ADCs to a Atmel ARM
>> processor (AT91SAM9RL)
>
> Some of the ST ARM chips might be more suitable. They have
> double-buffered DMA.
>
> I suspect you're going to need that.
Thanks, Clifford; I will take a look at the ST ARM parts: they look
interesting.
Nicholas