Thanks again for your very good suggestions. You will don't believe
in where was the problem: I must initialyze timers before the
DAC+DMA!!! Other thing is that I have to get one sample in each 2
sine wave cicles, because 20us is not enought for ADC
sample+conversion+isr.
And now I resolved the syncronization problem.
Thank you very much for dedicate some of your time to help me.

Best regards,

Ederson
--- In m..., Hugh Molesworth
wrote:>
> Hi Ederson
>
> You just provided an important clue, I think. Try
> slowing down your clock from the full 8MHz to
> (say) 2MHz by applying the /4 option in both
> timers, and see if that makes a difference; I
> suspect your interrupts are running out of time
> so that you miss some ticks, which of course will
> mess up your samples. Do you have interrupts from
> other sources doing anything, by the way?
>
> I looked at the sync of the two timers, and I
> don't have a problem. However, I'm not running
> your exact code, though as I mentioned if I can
> find time I will try it. You can check the timer
> outputs on port pins, and make it easier by
> reducing the B timer length from 160 to something
> more easily observable on a 'scope, such as 10
> (ie. only take 10 ADC samples per full 160-pulse
> DMA sine cycle). Pulse a port pin at the start
> and end of your interrupt, one port pin dedicated
> to each type of interrupt. Display the analogue
> waveform with these timer outputs and pulses and
> it might be easier to see what is happening. On
> the '149 ADC12 the 160 ADC samples are not really
> meaningful anyway, since the ADC sample is too
> long, unless you can get the single clock sample
> mode to work correctly (set SHP=0). Your code
> currently averages over a sample time of 4+ clock
> cycles. I suppose you could look at that as a moving average.
>
> Hugh
>

You just provided an important clue, I think. Try
slowing down your clock from the full 8MHz to
(say) 2MHz by applying the /4 option in both
timers, and see if that makes a difference; I
suspect your interrupts are running out of time
so that you miss some ticks, which of course will
mess up your samples. Do you have interrupts from
other sources doing anything, by the way?

I looked at the sync of the two timers, and I
don't have a problem. However, I'm not running
your exact code, though as I mentioned if I can
find time I will try it. You can check the timer
outputs on port pins, and make it easier by
reducing the B timer length from 160 to something
more easily observable on a 'scope, such as 10
(ie. only take 10 ADC samples per full 160-pulse
DMA sine cycle). Pulse a port pin at the start
and end of your interrupt, one port pin dedicated
to each type of interrupt. Display the analogue
waveform with these timer outputs and pulses and
it might be easier to see what is happening. On
the '149 ADC12 the 160 ADC samples are not really
meaningful anyway, since the ADC sample is too
long, unless you can get the single clock sample
mode to work correctly (set SHP=0). Your code
currently averages over a sample time of 4+ clock
cycles. I suppose you could look at that as a moving average.

Hugh

At 05:58 AM 8/1/2008, you wrote:
Hello Hugh,

Your suggestion about configurate timer lenght with one more point to
shift signal sample was very good. And about index, you have sure, I
was missing one sample. I verifyed the other things, but the
different measures is still happen.
Now I saw that in the fist measure, for the first "A" serial receive,
after microcontroller reset, the result is always the same, but in
new "A" receive, without microcontroler reset, the following measures
get different values.
One solution is reset microcontroller after any measure, but is not a
good procedure.
I tried to read ADC samples by using the other DMA channel, but when
the both DMAs (DMA0 to DAC sine wave generation triggered by timer_A
and DMA1 to ADC 160 point read triggered by timer_B) are working
toghether, the timers get crazy and this solution doesn't work.
So now the main question is: Why the measure restart process have a
behavior different than the first measure? May be a trash in some
register? I verifyed the reset of all registers involved in the start
of a new measure. But the result is the same only in the first
measure... May be a problem with MSP430?

Your suggestion about configurate timer lenght with one more point to
shift signal sample was very good. And about index, you have sure, I
was missing one sample. I verifyed the other things, but the
different measures is still happen.
Now I saw that in the fist measure, for the first "A" serial receive,
after microcontroller reset, the result is always the same, but in
new "A" receive, without microcontroler reset, the following measures
get different values.
One solution is reset microcontroller after any measure, but is not a
good procedure.
I tried to read ADC samples by using the other DMA channel, but when
the both DMAs (DMA0 to DAC sine wave generation triggered by timer_A
and DMA1 to ADC 160 point read triggered by timer_B) are working
toghether, the timers get crazy and this solution doesn't work.
So now the main question is: Why the measure restart process have a
behavior different than the first measure? May be a trash in some
register? I verifyed the reset of all registers involved in the start
of a new measure. But the result is the same only in the first
measure... May be a problem with MSP430?

A couple of things I noticed while loading up a
board, though I got sidetracked before I got
further with it. One is that you post-increment
the counters then test, so you are one cycle
short of the 160 samples you are looking for, I
think, since you read for index = 0 to 158 but
you never actually read index=159 since you reset
the counters at that point. That by itself might explain your issue.

The other thought I had is to do away with
messing about with CCR += 1 and instead just set
the B counter effective length to 161 instead of
160 8MHz cycles. Since the sine wave has an
effective length of 160 8MHz cycles, that will
cause the sample point to shift by 1 cycle each full since wave cycle.

Also I notice that with interrupt overhead and
time to process, the 8MHz '149 is not going to be
an order of magnitude faster by sampling
comb-like more than 1 sample per full sine cycle
as I suggested; you might get a factor of x2 or
x3 faster but no more so it probably isn't worth
trying. I was thinking of the nice 25MHz '5438 I
was playing with which is a lot faster.

Ok, last point. The 5MHz ADC clock is
asynchronous to the 8MHz DAC clock, so there will
be jitter in the sampled ADC reading. better to
also use the 8MHz clock for the ADC. Also the
sample window for the ADC is relatively long
compared with the 20uSec/32 DAC step; you can
shorten it by going to a single 8MHz clock width
sample (set SHP=0) but then I think you might run
foul of some ADC errata. Have to try it and see.

You have an interesting problem; I was looking at
something similar for 32kHz and 50kHz
ultrasonics. I'll try and look at it further.

Hugh

At 01:42 PM 7/30/2008, you wrote:
Thanks Hugh,

Now I'm still with the problem.
I verifyed that timer_B resets before the end of ADC isr. I thought
it was the problem, and I changed the code to get a sample waiting 2
cicles of the source signal to get other sample, by configuring
TBCCR0=319. It resolved the ADC isr problem, but didn't resolved the
main problem. I'm getting different measures of phase for readings of
the same analog circuit black box.
Now I don't have sure if the problem is the timers synchronization or
another.
However, I verifyed that the problem is in the first cycle sampled,
doesn't matter what I do with it after (signal processing...).
Sometimes my read get one phase delay, sometimes my read get another
phase delay.
Here is the big challenge: generate a 50KHz sine wave with DAC and
get it in ADC with the same phase delay always!

Now I'm still with the problem.
I verifyed that timer_B resets before the end of ADC isr. I thought
it was the problem, and I changed the code to get a sample waiting 2
cicles of the source signal to get other sample, by configuring
TBCCR0=319. It resolved the ADC isr problem, but didn't resolved the
main problem. I'm getting different measures of phase for readings of
the same analog circuit black box.
Now I don't have sure if the problem is the timers synchronization or
another.
However, I verifyed that the problem is in the first cycle sampled,
doesn't matter what I do with it after (signal processing...).
Sometimes my read get one phase delay, sometimes my read get another
phase delay.
Here is the big challenge: generate a 50KHz sine wave with DAC and
get it in ADC with the same phase delay always!

I fixed a typo in the code below, MC_1 wasn't
supposed to be in the first two lines .
Also I noticed on re-reading your code that you
already cleared Mode Control in the last ADC
interrupt, so my suggestion only really applies
to the pre-load to remove the offset. If I get a
chance, I'll load some code onto a board over the
next few days and have a look at it.

At 11:37 AM 7/25/2008, you wrote:
I see that you clear the timers on receipt of the
"A", but you leave both of them running (TACLR
doesn't stop the timer) and the following TACTL
and TBCTL doesn't alter the count at that instant.

The change from "+" to "|" is largely cosmetic,
but it better represents what you are trying to
achieve and can avoid some ripple errors when
incorrect definitions are used by mistake. With 2
timers, one is always started after the other so
to force them to have the same starting value you
would have to pre-load the earlier timer with a
value which increments to the required starting
value when the later timer starts. ie. how many
clock ticks are in the instruction "TBCTL="
above. If both cpu and timer are on 8MHz, then it
will be a few ticks; if the clock tick were much
slower than the cpu then there wouldn't be any. I
don't think you really care about that though, as
long as the relationship doesn't drift, but you
could pre-load TAR with (say) 4-2=2 after you
stop it but before you restart it. Look up the
assembly instruction which your compiler
generates then see how many clock cycles that requires.

The other option is to just use a single timer to
do both functions, but then of course you would
have to move the DAC CCR trigger forward each
interrupt as well as the ADC CCR trigger.

Also currently you require 160 complete DAC sine
wave cycles to acquire a complete ADC sine wave
cycle. You could reduce this drastically by
skipping ahead the appropriate minimum number of
sample points and sampling almost immediately,
instead of skipping just 1 point then waiting for
the next DAC sine wave cycle. That way you can
reduce the acquisition by an order of magnitude.

Also I assume you must calibrate the phase delay
for the ADC conversion time, along with the
front-end phase delay caused by any CR filter on
the DAC output and phase delay for extra
amplification on the ADC input. You can avoid
that calibration by making the reading
ratiometric. Use identical signal paths on both
DAC output after the filter and the measured
input, typically using a resistive divider on the
filtered output and a dual op-amp on the input
(assuming you are using an op-amp on the existing
input already). Then alternately measure the two
ADC inputs and the additional phase delay vanishes.

Hugh

At 07:14 AM 7/25/2008, you wrote:
Hi Hugh,

Thanks for your help.
The timer_B clock is 8MHz, so when I increment TBCCR1 in ADC isr the
TBR count is much more than TBCCR1+1, because the ADC isr is called
after the acquisition + conversion time that is 17 clock cicles of
5MHz ADC clock. I have sure that the timer_B and ADC are synchronized.
In the case of reseting timer_A and timer_B togheter, I do it in
each "A" receive. When the signal process finishes, I stop both
timers and initiates them again only when I receive an "A". Every
time that I receive "A", I have to start the measure process.
Since I stop the timers and peripherals after processing signal and I
clear and restart again the peripherals and timers only when "A"
receive, I think I don't need a timer isr to clear timer counters.
However, I implemented your suggestions, but didn't work.
I'm not understanding how to make the timers initialize always at the
same point...

The change from "+" to "|" is largely cosmetic,
but it better represents what you are trying to
achieve and can avoid some ripple errors when
incorrect definitions are used by mistake. With 2
timers, one is always started after the other so
to force them to have the same starting value you
would have to pre-load the earlier timer with a
value which increments to the required starting
value when the later timer starts. ie. how many
clock ticks are in the instruction "TBCTL="
above. If both cpu and timer are on 8MHz, then it
will be a few ticks; if the clock tick were much
slower than the cpu then there wouldn't be any. I
don't think you really care about that though, as
long as the relationship doesn't drift, but you
could pre-load TAR with (say) 4-2=2 after you
stop it but before you restart it. Look up the
assembly instruction which your compiler
generates then see how many clock cycles that requires.

The other option is to just use a single timer to
do both functions, but then of course you would
have to move the DAC CCR trigger forward each
interrupt as well as the ADC CCR trigger.

Also currently you require 160 complete DAC sine
wave cycles to acquire a complete ADC sine wave
cycle. You could reduce this drastically by
skipping ahead the appropriate minimum number of
sample points and sampling almost immediately,
instead of skipping just 1 point then waiting for
the next DAC sine wave cycle. That way you can
reduce the acquisition by an order of magnitude.

Also I assume you must calibrate the phase delay
for the ADC conversion time, along with the
front-end phase delay caused by any CR filter on
the DAC output and phase delay for extra
amplification on the ADC input. You can avoid
that calibration by making the reading
ratiometric. Use identical signal paths on both
DAC output after the filter and the measured
input, typically using a resistive divider on the
filtered output and a dual op-amp on the input
(assuming you are using an op-amp on the existing
input already). Then alternately measure the two
ADC inputs and the additional phase delay vanishes.

Hugh

At 07:14 AM 7/25/2008, you wrote:
Hi Hugh,

Thanks for your help.
The timer_B clock is 8MHz, so when I increment TBCCR1 in ADC isr the
TBR count is much more than TBCCR1+1, because the ADC isr is called
after the acquisition + conversion time that is 17 clock cicles of
5MHz ADC clock. I have sure that the timer_B and ADC are synchronized.
In the case of reseting timer_A and timer_B togheter, I do it in
each "A" receive. When the signal process finishes, I stop both
timers and initiates them again only when I receive an "A". Every
time that I receive "A", I have to start the measure process.
Since I stop the timers and peripherals after processing signal and I
clear and restart again the peripherals and timers only when "A"
receive, I think I don't need a timer isr to clear timer counters.
However, I implemented your suggestions, but didn't work.
I'm not understanding how to make the timers initialize always at the
same point...

Thanks for your help.
The timer_B clock is 8MHz, so when I increment TBCCR1 in ADC isr the
TBR count is much more than TBCCR1+1, because the ADC isr is called
after the acquisition + conversion time that is 17 clock cicles of
5MHz ADC clock. I have sure that the timer_B and ADC are synchronized.
In the case of reseting timer_A and timer_B togheter, I do it in
each "A" receive. When the signal process finishes, I stop both
timers and initiates them again only when I receive an "A". Every
time that I receive "A", I have to start the measure process.
Since I stop the timers and peripherals after processing signal and I
clear and restart again the peripherals and timers only when "A"
receive, I think I don't need a timer isr to clear timer counters.
However, I implemented your suggestions, but didn't work.
I'm not understanding how to make the timers initialize always at the
same point...

Your first problem, I think, is that you move the
next ADC sample point too soon. By this I mean
that when TBCCR is hit an ADC conversion starts
and completes controlled by the (typically) 5MHz
ADC clock. On completion your ADC isr moves the
synchronous sample point forward by 1 place:
TBCCR1 += 1; // Inc TB
However, this instruction may occur before TB has
incremented again, which means potentially you
have another ADC sample started before you are
ready for it. Better to move that line of code to
where you really want it to be, that is in the TB
overflow interrupt when TB rolls over from 159 to 0.

Your second problem is the loss of synch. Are you
running this code just once, ie on receipt of an
"A", or do you want it to run every time you
receive an "A"? In that latter case, you need to
re-synch the timers A & B on detection of the
"A". Add this extra step either by just stopping
and clearing the timers using TACLR and TBCLR, or
by pre-loading the TAR and TBR counter registers
to some other known value. Of course this is
better done in the timer isr since the receipt of
the "A" start character is asynchronous to the
timer clocking, and therefore may occur as a tick
is taking place giving potential instability in
measurements. I suggest you set a flag in the rx
isr which is checked in the timer isr, which when
set stops and clears the timers and then restarts them.

I removed the spurious "" characters in the
code below for clarity. Not sure what they were ...

Hugh

At 06:08 AM 7/24/2008, you wrote:
Hi,
I want to measure the phase delay in an analog
circuit applying a 50KHz sine wave generated in
DAC (that access a table using DMA) and read this
same signal with the ADC of the MSP430F156
microcontroller. I want to reconstruct the sine
wave readwith 160 points, so the ADCspeed
doesn't support sample the 50KHz sine wave,
however, I'm using a technique that I read 160
sine wave cicles andget onesample of each
cicle incrementing the point of sampling. I am
using timer_A to generate clock for DACoutput
the sine wave and Timer_B to start A/D
conversionsin each point of the sine wave
incrementing TBCCR1. I start the phase measure by
software with RS232 communication, so when the
firmware detects a start command from the
software, it starts a measure generating the sine
wave and, at the same time, reading it back.
My problem is the start of both timers. I am
starting timer_Bin the next line of timer_A
start, butTimer_B does not start always in the
same count of timer_A, and because that, the
measure of phase delay between sine wave
generated and sine wave read is not always the
same. I'm not understanding what is happening.
The most important part of the code follows below.
Could somebodyhelp me?
Thanks in advance,
Ederson
----------

Hi,
I want to measure the phase delay in an analog circuit applying a 50KHz sine
wave generated in DAC (that access a table using DMA) and read this same signal
with the ADC of the MSP430F156 microcontroller. I want to reconstruct the sine
wave read with 160 points, so the ADC speed doesn't support sample the
50KHz sine wave, however, I'm using a technique that I read 160 sine wave cicles
and get one sample of each cicle incrementing the point of sampling. I
am using timer_A to generate clock for DAC output the sine wave and Timer_B
to start A/D conversions in each point of the sine wave incrementing
TBCCR1. I start the phase measure by software with RS232 communication, so when
the firmware detects a start command from the software, it starts a measure
generating the sine wave and, at the same time, reading it back.
My problem is the start of both timers. I am starting timer_B in the next
line of timer_A start, but Timer_B does not start always in the same count
of timer_A, and because that, the measure of phase delay between sine wave
generated and sine wave read is not always the same. I'm not understanding what
is happening.
The most important part of the code follows below.
Could somebody help me?
Thanks in advance,
Ederson
----------
#include
void main(void)
{
WDTCTL = WDTPW + WDTHOLD;
/*Initialization of variables...*/