Multi-channel ADC and the DMA

Started by alex3d_p July 18, 2005
Hi all,

I am using the MSP430 to sample 4 analog signals sequentially and
would like to use the DMA to automate ADC data collection. I set up
the ADC to sample the 4 pins as a sequence. I then would like to setup
the DMA to collect these 4 words and put them into a buffer of 256
words and notify me when it is done. I have been trying all different
combinations of ADC and DMA settings and I have not been able to get
anything to work. Here are the ways I have tried:

 Set the DMA to single transfers (256 times). Here I was hoping the
DMA would wrap around on the EOS bit in the ADC. Of course this does
not work.

 I set the DMA to do block transfers, but since the blocks are small I
get interrupts every 4 words.

 Finally, I tried to use two DMA channels, and a intermediate memory
location as a buffer. One DMA channel would transfer data from the ADC
to the temporary memory location and then the second DMA would
transfer the data out of the temporary memory into my 256 buffer. The
major issue here is timing. The first DMA's interrupt must be turned
off so that the processor is not interrupted, also it cannot be timed
off the ADC because the DMA is triggered on the very last sample
(EOS).

Have any of you had success in sampling sequences and using the DMA to
move the data?

Thank you for your input.

alex





Beginning Microcontrollers with the MSP430

On Monday 18 July 2005 10:57 am, alex3d_p wrote:
> Hi all,
>
>  I am using the MSP430 to sample 4 analog signals sequentially and
>  would like to use the DMA to automate ADC data collection. I set up
>  the ADC to sample the 4 pins as a sequence. I then would like to setup
>  the DMA to collect these 4 words and put them into a buffer of 256
>  words and notify me when it is done. I have been trying all different
>  combinations of ADC and DMA settings and I have not been able to get
>  anything to work. Here are the ways I have tried:
>
>  Set the DMA to single transfers (256 times). Here I was hoping the
>  DMA would wrap around on the EOS bit in the ADC. Of course this does
>  not work.
>
>  I set the DMA to do block transfers, but since the blocks are small I
>  get interrupts every 4 words.

Isn't this what you want? Or do you want a large block of memory to be written 
before the interrupt? You can't transfer a small block repeatetly to a large 
block of memory to my knowledge, both the from and to locations must be the 
same size. So it sounds like you're stuck with an interrupt every 4 words. (4 
samples?) 

If you use single transfers, you can use several DMA channels to do single 
location to a block of RAM. This would restrict you to 3 channels though. For 
an example of this, refer to the MSP140_DMA_09.c example on the TI site..

HTH
-Micah 

alex3d_p wrote:

>Hi all,
>
>I am using the MSP430 to sample 4 analog signals sequentially and
>would like to use the DMA to automate ADC data collection. I set up
>the ADC to sample the 4 pins as a sequence. I then would like to setup
>the DMA to collect these 4 words and put them into a buffer of 256
>words and notify me when it is done. I have been trying all different
>combinations of ADC and DMA settings and I have not been able to get
>anything to work. Here are the ways I have tried:
>
> Set the DMA to single transfers (256 times). Here I was hoping the
>DMA would wrap around on the EOS bit in the ADC. Of course this does
>not work.
>
> I set the DMA to do block transfers, but since the blocks are small I
>get interrupts every 4 words.
>  
>
Set the ADC12 to sample the same 4 channels 4 times each, ie 16 samples, 
which redcues the DMA ISR overhead. The ADC should be set for repeat 
sequence of channels.

In the DMA ISR clear the ADC12IFG, and the DMAIFG flag flag that 
represents EOS, this will retrigger the ADC12 sequence and the DMA. In 
block mode the DMA will fill your sequence, of 256.

Al


> Finally, I tried to use two DMA channels, and a
intermediate memory
>location as a buffer. One DMA channel would transfer data from the ADC
>to the temporary memory location and then the second DMA would
>transfer the data out of the temporary memory into my 256 buffer. The
>major issue here is timing. The first DMA's interrupt must be turned
>off so that the processor is not interrupted, also it cannot be timed
>off the ADC because the DMA is triggered on the very last sample
>(EOS).
>
>Have any of you had success in sampling sequences and using the DMA to
>move the data?
>
>Thank you for your input.
>
>alex
>
>
>
>
>
>
>.
>
> 
>Yahoo! Groups Links
>
>
>
> 
>
>
>
>
>  
>


> >  I am using the MSP430 to sample 4 analog signals sequentially
and
> >  would like to use the DMA to automate ADC
data collection. I set up
> >  the ADC to sample the 4 pins as a sequence. I then would like to
setup
> >  the DMA to collect these 4 words and put
them into a buffer of 256
> >  words and notify me when it is done. I have been trying all different
> >  combinations of ADC and DMA settings and I have not been able to get
> >  anything to work. Here are the ways I have tried:
> >
> >  Set the DMA to single transfers (256 times). Here I was hoping the
> >  DMA would wrap around on the EOS bit in the ADC. Of course this does
> >  not work.
> >
> >  I set the DMA to do block transfers, but since the blocks are small I
> >  get interrupts every 4 words.
> 
> Isn't this what you want? Or do you want a large block of memory to
be written 
> before the interrupt? You can't transfer a small
block repeatetly to
a large 
> block of memory to my knowledge, both the from and
to locations must
be the 
> same size. So it sounds like you're stuck with an
interrupt every 4
words. (4 
> samples?) 
> 
> If you use single transfers, you can use several DMA channels to do
single 
> location to a block of RAM. This would restrict
you to 3 channels
though. For 
> an example of this, refer to the MSP140_DMA_09.c
example on the TI
site..
> 
> HTH
> -Micah

Hi Micah,

You are exactly right, I want a small block to large block movement,
where the small block is repeatedly copied to the large block. I was
afraid that the DMA on the MSP430 could not do such a transfer. Yes, I
think if no one else knows away to achieve such a transfer, I will
have to use three DMA channels.

alex




On Tuesday 19 July 2005 2:39 pm, alex3d_p wrote:
> > > I am using the MSP430 to sample 4
analog signals sequentially and
> > >
>  > > would like to use the DMA to automate ADC data collection. I
set up
>  > > the ADC to sample the 4 pins as a sequence. I then would like
to
>
>  setup
>
>  > > the DMA to collect these 4 words and put them into a buffer of
256
>  > > words and notify me when it is done. I have been trying all
different
>  > > combinations of ADC and DMA settings and I have not been able
to get
>  > > anything to work. Here are the ways I have tried:
>  > >
>  > > Set the DMA to single transfers (256 times). Here I was hoping
the
>  > > DMA would wrap around on the EOS bit in the ADC. Of course this
does
>  > > not work.
>  > >
>  > > I set the DMA to do block transfers, but since the blocks are
small I
>  > > get interrupts every 4 words.
>  >
>  > Isn't this what you want? Or do you want a large block of memory to
>
>  be written
>
>  > before the interrupt? You can't transfer a small block repeatetly to
>
>  a large
>
>  > block of memory to my knowledge, both the from and to locations must
>
>  be the
>
>  > same size. So it sounds like you're stuck with an interrupt every 4
>
>  words. (4
>
>  > samples?)
>  >
>  > If you use single transfers, you can use several DMA channels to do
>
>  single
>
>  > location to a block of RAM. This would restrict you to 3 channels
>
>  though. For
>
>  > an example of this, refer to the MSP140_DMA_09.c example on the TI
>
>  site..
>
>  > HTH
>  > -Micah
>
>  Hi Micah,
>
>  You are exactly right, I want a small block to large block movement,
>  where the small block is repeatedly copied to the large block. I was
>  afraid that the DMA on the MSP430 could not do such a transfer. Yes, I
>  think if no one else knows away to achieve such a transfer, I will
>  have to use three DMA channels.
>
>  alex
>

Apparently, according to Al's post, you can do this, although the docs weren't 
clear on confirming this. I didn't look that much into it either. I have no 
doubt he knows what he's talking about. It would be much more efficient to do 
things his way. 
-Micah

--- In msp430@msp4..., Micah Stevens <micah@9...> wrote:
> On Tuesday 19 July 2005 2:39 pm, alex3d_p wrote:
> > > >  I am using the MSP430 to sample 4 analog signals
sequentially and
> > > >
> >  > >  would like to use the DMA to automate ADC data collection.
I
set up
> >  > >  the ADC to sample the 4 pins as a
sequence. I then would like to
> >
> >  setup
> >
> >  > >  the DMA to collect these 4 words and put them into a
buffer
of 256
> >  > >  words and notify me when it is
done. I have been trying all
different
> >  > >  combinations of ADC and DMA
settings and I have not been
able to get
> >  > >  anything to work. Here are the
ways I have tried:
> >  > >
> >  > >  Set the DMA to single transfers (256 times). Here I was
hoping the
> >  > >  DMA would wrap around on the EOS
bit in the ADC. Of course
this does
> >  > >  not work.
> >  > >
> >  > >  I set the DMA to do block transfers, but since the blocks
are small I
> >  > >  get interrupts every 4 words.
> >  >
> >  > Isn't this what you want? Or do you want a large block of memory
to
> >
> >  be written
> >
> >  > before the interrupt? You can't transfer a small block
repeatetly to
> >
> >  a large
> >
> >  > block of memory to my knowledge, both the from and to locations
must
> >
> >  be the
> >
> >  > same size. So it sounds like you're stuck with an interrupt
every 4
> >
> >  words. (4
> >
> >  > samples?)
> >  >
> >  > If you use single transfers, you can use several DMA channels to
do
> >
> >  single
> >
> >  > location to a block of RAM. This would restrict you to 3
channels
> >
> >  though. For
> >
> >  > an example of this, refer to the MSP140_DMA_09.c example on the
TI
> >
> >  site..
> >
> >  > HTH
> >  > -Micah
> >
> >  Hi Micah,
> >
> >  You are exactly right, I want a small block to large block movement,
> >  where the small block is repeatedly copied to the large block. I was
> >  afraid that the DMA on the MSP430 could not do such a transfer.
Yes, I
> >  think if no one else knows away to achieve
such a transfer, I will
> >  have to use three DMA channels.
> >
> >  alex
> >
> 
> Apparently, according to Al's post, you can do this, although the
docs weren't 
> clear on confirming this. I didn't look that much
into it either. I
have no 
> doubt he knows what he's talking about. It would
be much more
efficient to do 
> things his way. 
> -Micah

The problem with Al's suggestion, for my application, is that I still
get an interrupt every 16 words. I am going to be doing calculations
in the background while data is being continuously collected. With
interrupts coming every 16 words there might be issues with handling
the ISRs. This will be even more significant when I increase the size
of the buffers from 256 to 1kb or more. With the three channel, there
will be less interrupts and ISRs to handle.

alex



You can't get around the need to restart the ADC12 sequence by clearing 
the IFG flag. Either your ADC mmust interrupt or your DMA must. If you 
trigger the DMA from the ADC12 completion then the DMA MUST interrupt to 
enable the next sequence. If you struture your ISRs well there will be 
no problems, you cannot do this cleanly without ISRs. You would need to 
stall the ADC12 until your foreground program recognised the DMA 
completion then clkear ADCIFG in the foreground. This would make the 
sampling rate variable, which would screw up most post processing tasks. 
You can't have everything, either you stall data collection until you 
recognise the transfer completion, or you interrupt. This isn't the 
problem you are making it into (of course if Ti had thought to retrigger 
data collection from the DMA it wouldn't be a problem) I do this without 
DMA on a 149 based real time imaging system, and manage to draw graphics 
at the same time, you just need to think it through optimise your 
calculations and place them accordingly. The ISR, after all only needs 
to clear the IFG for DMA and the ADC.

Al

alex3d_p wrote:

>--- In msp430@msp4..., Micah Stevens
<micah@9...> wrote:
>  
>
>>On Tuesday 19 July 2005 2:39 pm, alex3d_p wrote:
>>    
>>
>>>>> I am using the MSP430 to sample 4 analog signals
sequentially and
>>>>>
>>>>>          
>>>>>
>>> > >  would like to use the DMA to automate ADC data
collection. I
>>>      
>>>
>set up
>  
>
>>> > >  the ADC to sample the 4 pins as a sequence. I then would
like to
>>>
>>> setup
>>>
>>> > >  the DMA to collect these 4 words and put them into a
buffer
>>>      
>>>
>of 256
>  
>
>>> > >  words and notify me when it is done. I have been trying
all
>>>      
>>>
>different
>  
>
>>> > >  combinations of ADC and DMA settings and I have not been
>>>      
>>>
>able to get
>  
>
>>> > >  anything to work. Here are the ways I have tried:
>>> > >
>>> > >  Set the DMA to single transfers (256 times). Here I was
>>>      
>>>
>hoping the
>  
>
>>> > >  DMA would wrap around on the EOS bit in the ADC. Of
course
>>>      
>>>
>this does
>  
>
>>> > >  not work.
>>> > >
>>> > >  I set the DMA to do block transfers, but since the
blocks
>>>      
>>>
>are small I
>  
>
>>> > >  get interrupts every 4 words.
>>> >
>>> > Isn't this what you want? Or do you want a large block of
memory to
>>>
>>> be written
>>>
>>> > before the interrupt? You can't transfer a small block
>>>      
>>>
>repeatetly to
>  
>
>>> a large
>>>
>>> > block of memory to my knowledge, both the from and to
locations
>>>      
>>>
>must
>  
>
>>> be the
>>>
>>> > same size. So it sounds like you're stuck with an interrupt
every 4
>>>
>>> words. (4
>>>
>>> > samples?)
>>> >
>>> > If you use single transfers, you can use several DMA channels
to do
>>>
>>> single
>>>
>>> > location to a block of RAM. This would restrict you to 3
channels
>>>
>>> though. For
>>>
>>> > an example of this, refer to the MSP140_DMA_09.c example on
the TI
>>>
>>> site..
>>>
>>> > HTH
>>> > -Micah
>>>
>>> Hi Micah,
>>>
>>> You are exactly right, I want a small block to large block
movement,
>>> where the small block is repeatedly copied to the large block. I
was
>>> afraid that the DMA on the MSP430 could not do such a transfer.
>>>      
>>>
>Yes, I
>  
>
>>> think if no one else knows away to achieve such a transfer, I will
>>> have to use three DMA channels.
>>>
>>> alex
>>>
>>>      
>>>
>>Apparently, according to Al's post, you can do this, although the
>>    
>>
>docs weren't 
>  
>
>>clear on confirming this. I didn't look that much into it either. I
>>    
>>
>have no 
>  
>
>>doubt he knows what he's talking about. It would be much more
>>    
>>
>efficient to do 
>  
>
>>things his way. 
>>-Micah
>>    
>>
>
>The problem with Al's suggestion, for my application, is that I still
>get an interrupt every 16 words. I am going to be doing calculations
>in the background while data is being continuously collected. With
>interrupts coming every 16 words there might be issues with handling
>the ISRs. This will be even more significant when I increase the size
>of the buffers from 256 to 1kb or more. With the three channel, there
>will be less interrupts and ISRs to handle.
>
>alex
>
>
>
>
>.
>
> 
>Yahoo! Groups Links
>
>
>
> 
>
>
>
>
>  
>