EmbeddedRelated.com
Forums

ADC10 DTC in MSP430F2274

Started by GB March 29, 2009
Hello,

I have a question about the DTC in ADC10.
I am trying to sample several channels sequentially.
The ADC10 on the MSP430F2274 has a Data Transfer Controller, basically a DMA from what I understand. The code I see as example from TI sets most up, and I've made some modifications as follows:

int delay;
ADC10CTL1 = INCH_4 + CONSEQ_1; // A4/A3/A2/A1/A0, single sequence
ADC10CTL0 = SREF_0 + ADC10SHT_2 + MSC + ADC10ON + ADC10IE;
for( delay = 240; delay > 0; delay-- ); // delay to allow reference to
ADC10DTC1 = 0x05; // 5 conversions

ADC10CTL0 &= ~ENC;
while (ADC10CTL1 & BUSY); // Wait if ADC10 core is active
ADC10SA = 0x200; // Data buffer start
ADC10CTL0 |= ENC + ADC10SC; // Sampling and conversion start

__bis_SR_register(CPUOFF + GIE); // LPM0 with interrupts enabled

ADC10CTL0 &= ~ENC;
ADC10CTL0 &= ~(REFON + ADC10ON); // turn off A/D to save power

so the following line sets up the place where we will put the results:
ADC10SA = 0x200; // Data buffer start

Can anyone explain how the results are placed? Since it's a 10 bit ADC, does it use two bytes for a total of 10 bytes?

Could I, for example, give it a pointer to some array of the necessary size to make it easier to read the results?
If not, how would I go about reading them?

I'd appreciate any insight into this.

Thank you

Beginning Microcontrollers with the MSP430

Hello,

The DTC will use 2 bytes for each new read, so there will be one
read on 0x200, then on 0x202 and so on. You just have to read these
addresses to get the data. You may also initialize ADC10SA with an
variable pointer, for exemple:

unsigned int my_data[5];
ADC10SA = my_data;

This way you don't have to worry where the data is allocated in RAM.
Just read it directly using the vector.

By the way, I notice a weird behavior when using DTC with continuous
read mode and debugger. I am not sure why, but when I halt the program
to debug and resumes it, the DTC "shifts" the address locations. For
example if DTC is writing A0,A1,A2 in memory during normal operation,
after halt-resume, it starts writing A1,A2,A0 (or any other rolled
sequence). If I reset and start the software everything goes back no
normal. Does anyone ever noticed this behavior (I am using ICC430 with
NoIce430)?

Calin

GB wrote:
> Hello,
>
> I have a question about the DTC in ADC10.
> I am trying to sample several channels sequentially.
> The ADC10 on the MSP430F2274 has a Data Transfer Controller, basically
> a DMA from what I understand. The code I see as example from TI sets
> most up, and I've made some modifications as follows:
>
> int delay;
> ADC10CTL1 = INCH_4 + CONSEQ_1; // A4/A3/A2/A1/A0, single sequence
> ADC10CTL0 = SREF_0 + ADC10SHT_2 + MSC + ADC10ON + ADC10IE;
> for( delay = 240; delay > 0; delay-- ); // delay to allow reference to
> ADC10DTC1 = 0x05; // 5 conversions
>
> ADC10CTL0 &= ~ENC;
> while (ADC10CTL1 & BUSY); // Wait if ADC10 core is active
> ADC10SA = 0x200; // Data buffer start
> ADC10CTL0 |= ENC + ADC10SC; // Sampling and conversion start
>
> __bis_SR_register(CPUOFF + GIE); // LPM0 with interrupts enabled
>
> ADC10CTL0 &= ~ENC;
> ADC10CTL0 &= ~(REFON + ADC10ON); // turn off A/D to save power
>
> so the following line sets up the place where we will put the results:
> ADC10SA = 0x200; // Data buffer start
>
> Can anyone explain how the results are placed? Since it's a 10 bit
> ADC, does it use two bytes for a total of 10 bytes?
>
> Could I, for example, give it a pointer to some array of the necessary
> size to make it easier to read the results?
> If not, how would I go about reading them?
>
> I'd appreciate any insight into this.
>
> Thank you


Thanks a lot for your help.
I will watch out for any strange behavior.

--- On Sun, 3/29/09, Gabriel Calin wrote:

> From: Gabriel Calin
> Subject: Re: [msp430] ADC10 DTC in MSP430F2274
> To: m...
> Date: Sunday, March 29, 2009, 1:41 PM
>
>
> Hello,
>
> The DTC will use 2 bytes for each new read, so there will
> be one
>
> read on 0x200, then on 0x202 and so on. You just have to
> read these
>
> addresses to get the data. You may also initialize ADC10SA
> with an
>
> variable pointer, for exemple:
>
> unsigned int my_data[5];
>
> ADC10SA = my_data;
>
> This way you don't have to worry where the data is
> allocated in RAM.
>
> Just read it directly using the vector.
>
> By the way, I notice a weird behavior when using DTC with
> continuous
>
> read mode and debugger. I am not sure why, but when I halt
> the program
>
> to debug and resumes it, the DTC "shifts" the
> address locations. For
>
> example if DTC is writing A0,A1,A2 in memory during normal
> operation,
>
> after halt-resume, it starts writing A1,A2,A0 (or any other
> rolled
>
> sequence). If I reset and start the software everything
> goes back no
>
> normal. Does anyone ever noticed this behavior (I am using
> ICC430 with
>
> NoIce430)?
>
> Calin
>
> GB wrote:
>
> > > > Hello,
>
> > > I have a question about the DTC in ADC10.
>
> > I am trying to sample several channels sequentially.
>
> > The ADC10 on the MSP430F2274 has a Data Transfer
> Controller, basically
>
> > a DMA from what I understand. The code I see as
> example from TI sets
>
> > most up, and I've made some modifications as
> follows:
>
> > > int delay;
>
> > ADC10CTL1 = INCH_4 + CONSEQ_1; // A4/A3/A2/A1/ A0,
> single sequence
>
> > ADC10CTL0 = SREF_0 + ADC10SHT_2 + MSC + ADC10ON +
> ADC10IE;
>
> > for( delay = 240; delay > 0; delay-- ); // delay to
> allow reference to
>
> > ADC10DTC1 = 0x05; // 5 conversions
>
> > > ADC10CTL0 &= ~ENC;
>
> > while (ADC10CTL1 & BUSY); // Wait if ADC10 core is
> active
>
> > ADC10SA = 0x200; // Data buffer start
>
> > ADC10CTL0 |= ENC + ADC10SC; // Sampling and conversion
> start
>
> > > __bis_SR_register( CPUOFF + GIE); // LPM0 with
> interrupts enabled
>
> > > ADC10CTL0 &= ~ENC;
>
> > ADC10CTL0 &= ~(REFON + ADC10ON); // turn off A/D
> to save power
>
> > > so the following line sets up the place where we will
> put the results:
>
> > ADC10SA = 0x200; // Data buffer start
>
> > > Can anyone explain how the results are placed? Since
> it's a 10 bit
>
> > ADC, does it use two bytes for a total of 10 bytes?
>
> > > Could I, for example, give it a pointer to some array
> of the necessary
>
> > size to make it easier to read the results?
>
> > If not, how would I go about reading them?
>
> > > I'd appreciate any insight into this.
>
> > > Thank you
>
> > >
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>

I noticed the same strange DTC/debugger behavior about a year ago.
I had several TI techs and engineers involved and the final word I got
from them was an acknowledgment that it was indeed a confirmed strange
unexpected behavior, but never an explanation or a workaround.
The DTC seems to work perfectly well without the debugger stopping at
breakpoints, so I guess you just have to be aware of the issue and
recognize it so you don't go tearing your application apart trying to
find the source of the problem. (I was using IAR kickstart with a ez430
FET and msp430f2012.)
Gabriel Calin said the following on 3/29/2009 11:41 AM:
>
> Hello,
>
> The DTC will use 2 bytes for each new read, so there will be one
> read on 0x200, then on 0x202 and so on. You just have to read these
> addresses to get the data. You may also initialize ADC10SA with an
> variable pointer, for exemple:
>
> unsigned int my_data[5];
> ADC10SA = my_data;
>
> This way you don't have to worry where the data is allocated in RAM.
> Just read it directly using the vector.
>
> By the way, I notice a weird behavior when using DTC with continuous
> read mode and debugger. I am not sure why, but when I halt the program
> to debug and resumes it, the DTC "shifts" the address locations. For
> example if DTC is writing A0,A1,A2 in memory during normal operation,
> after halt-resume, it starts writing A1,A2,A0 (or any other rolled
> sequence). If I reset and start the software everything goes back no
> normal. Does anyone ever noticed this behavior (I am using ICC430 with
> NoIce430)?
>
> Calin
>
> GB wrote:
> >
> >
> > Hello,
> >
> > I have a question about the DTC in ADC10.
> > I am trying to sample several channels sequentially.
> > The ADC10 on the MSP430F2274 has a Data Transfer Controller, basically
> > a DMA from what I understand. The code I see as example from TI sets
> > most up, and I've made some modifications as follows:
> >
> > int delay;
> > ADC10CTL1 = INCH_4 + CONSEQ_1; // A4/A3/A2/A1/A0, single sequence
> > ADC10CTL0 = SREF_0 + ADC10SHT_2 + MSC + ADC10ON + ADC10IE;
> > for( delay = 240; delay > 0; delay-- ); // delay to allow reference to
> > ADC10DTC1 = 0x05; // 5 conversions
> >
> > ADC10CTL0 &= ~ENC;
> > while (ADC10CTL1 & BUSY); // Wait if ADC10 core is active
> > ADC10SA = 0x200; // Data buffer start
> > ADC10CTL0 |= ENC + ADC10SC; // Sampling and conversion start
> >
> > __bis_SR_register(CPUOFF + GIE); // LPM0 with interrupts enabled
> >
> > ADC10CTL0 &= ~ENC;
> > ADC10CTL0 &= ~(REFON + ADC10ON); // turn off A/D to save power
> >
> > so the following line sets up the place where we will put the results:
> > ADC10SA = 0x200; // Data buffer start
> >
> > Can anyone explain how the results are placed? Since it's a 10 bit
> > ADC, does it use two bytes for a total of 10 bytes?
> >
> > Could I, for example, give it a pointer to some array of the necessary
> > size to make it easier to read the results?
> > If not, how would I go about reading them?
> >
> > I'd appreciate any insight into this.
> >
> > Thank you
> >
> >


Thank you Aaron. Nice to know I wasn't the only one to notice this weird
behavior. It makes debugging really difficulty on my project, but I
guess I will have to live with it.

Calin

Aaron Greer wrote:
>
> I noticed the same strange DTC/debugger behavior about a year ago.
> I had several TI techs and engineers involved and the final word I got
> from them was an acknowledgment that it was indeed a confirmed strange
> unexpected behavior, but never an explanation or a workaround.
> The DTC seems to work perfectly well without the debugger stopping at
> breakpoints, so I guess you just have to be aware of the issue and
> recognize it so you don't go tearing your application apart trying to
> find the source of the problem. (I was using IAR kickstart with a ez430
> FET and msp430f2012.)
>
> Gabriel Calin said the following on 3/29/2009 11:41 AM:
> >
> > Hello,
> >
> > The DTC will use 2 bytes for each new read, so there will be one
> > read on 0x200, then on 0x202 and so on. You just have to read these
> > addresses to get the data. You may also initialize ADC10SA with an
> > variable pointer, for exemple:
> >
> > unsigned int my_data[5];
> > ADC10SA = my_data;
> >
> > This way you don't have to worry where the data is allocated in RAM.
> > Just read it directly using the vector.
> >
> > By the way, I notice a weird behavior when using DTC with continuous
> > read mode and debugger. I am not sure why, but when I halt the program
> > to debug and resumes it, the DTC "shifts" the address locations. For
> > example if DTC is writing A0,A1,A2 in memory during normal operation,
> > after halt-resume, it starts writing A1,A2,A0 (or any other rolled
> > sequence). If I reset and start the software everything goes back no
> > normal. Does anyone ever noticed this behavior (I am using ICC430 with
> > NoIce430)?
> >
> > Calin
> >
> > GB wrote:
> > >
> > >
> > > Hello,
> > >
> > > I have a question about the DTC in ADC10.
> > > I am trying to sample several channels sequentially.
> > > The ADC10 on the MSP430F2274 has a Data Transfer Controller, basically
> > > a DMA from what I understand. The code I see as example from TI sets
> > > most up, and I've made some modifications as follows:
> > >
> > > int delay;
> > > ADC10CTL1 = INCH_4 + CONSEQ_1; // A4/A3/A2/A1/A0, single sequence
> > > ADC10CTL0 = SREF_0 + ADC10SHT_2 + MSC + ADC10ON + ADC10IE;
> > > for( delay = 240; delay > 0; delay-- ); // delay to allow reference to
> > > ADC10DTC1 = 0x05; // 5 conversions
> > >
> > > ADC10CTL0 &= ~ENC;
> > > while (ADC10CTL1 & BUSY); // Wait if ADC10 core is active
> > > ADC10SA = 0x200; // Data buffer start
> > > ADC10CTL0 |= ENC + ADC10SC; // Sampling and conversion start
> > >
> > > __bis_SR_register(CPUOFF + GIE); // LPM0 with interrupts enabled
> > >
> > > ADC10CTL0 &= ~ENC;
> > > ADC10CTL0 &= ~(REFON + ADC10ON); // turn off A/D to save power
> > >
> > > so the following line sets up the place where we will put the results:
> > > ADC10SA = 0x200; // Data buffer start
> > >
> > > Can anyone explain how the results are placed? Since it's a 10 bit
> > > ADC, does it use two bytes for a total of 10 bytes?
> > >
> > > Could I, for example, give it a pointer to some array of the necessary
> > > size to make it easier to read the results?
> > > If not, how would I go about reading them?
> > >
> > > I'd appreciate any insight into this.
> > >
> > > Thank you
> > >
> > >
> >
> >
> >
> >