Reply by Jon Kirwan May 19, 20112011-05-19
On Thu, 19 May 2011 22:02:07 -0000, OCY wrote:

>Jon,
>
>Thanks. I was not aware of the proper load cap of that crystal.

No problem. I had contacted Microcrystal in Europe when I
first got the Launchpad in the mail, because as I said before
I like to nail down every detail and the crystal in the kit
was an "unknown" to me. I got the datasheet and more
details, besides. Glad to pass that along.

> The delay between clearing OFIFG and testing it again, TI
> examples show a loop of 255. I think that is way too short
> if you start the code immediately after power up.

I completely agree. That link I pointed you at says about
450ms and unless their processor is running on the VLO, it's
too short. I am using 21000 right now for the default 1.1MHz
DCO rate. The loop is 3 clocks per, so that meets and
exceeds the "50us minimum" that is recommended. Of course,
even that is way too short. But it matches the docs and I
like to do that where there is doc, anyway.

> I did some test (code is shown below). In order to simulate
> power up in a debug session (where the target chip is always
> powered up), I disabled the LFXT1 oscillator, turn on the
> green LED, and wait for SW2 to be pressed. After that, I
> turn off the green LED, enabled the oscillator and proceed.
> Next I capture 4000 deltas and keep the max and min. And
> then I capture the sum of 16 more deltas. When all finished,
> I light up the red LED and loop forever.
>
> You may use the debugger to reset the target and start to
> run. After you see the green LED, wait for various amount of
> time and press the SW2 button. The green LED will go off and
> the red LED will come on. At that time, use debugger to stop
> the CPU and examine the registers to see the max, min, and
> 16*delta.
>
> My code is shown below. Note that it defines DLT as 255, the
> value TI uses. I think it is acceptable only if you pressed
> SW2 immediately after the green LED is on. If you want the
> delta to be decent enough after the chip was turned off for
> more than a few seconds, you need to change DLY to a much
> much bigger number.
>

Thanks so much, OCY. I don't have time right now, but I will
try it out and learn a few things along the way. Maybe make
some interesting modifications for my own thoughts.

Much appreciated. And thanks for the detailed discussion.
It's the kind of thing I really enjoy when the chance arrives
and I really do greatly appreciate the moments you've
offered.

Jon

Beginning Microcontrollers with the MSP430

Reply by old_cow_yellow May 19, 20112011-05-19
Jon,

Thanks. I was not aware of the proper load cap of that crystal.

The delay between clearing OFIFG and testing it again, TI examples show a loop of 255. I think that is way too short if you start the code immediately after power up.

I did some test (code is shown below). In order to simulate power up in a debug session (where the target chip is always powered up), I disabled the LFXT1 oscillator, turn on the green LED, and wait for SW2 to be pressed. After that, I turn off the green LED, enabled the oscillator and proceed. Next I capture 4000 deltas and keep the max and min. And then I capture the sum of 16 more deltas. When all finished, I light up the red LED and loop forever.

You may use the debugger to reset the target and start to run. After you see the green LED, wait for various amount of time and press the SW2 button. The green LED will go off and the red LED will come on. At that time, use debugger to stop the CPU and examine the registers to see the max, min, and 16*delta.

My code is shown below. Note that it defines DLT as 255, the value TI uses. I think it is acceptable only if you pressed SW2 immediately after the green LED is on. If you want the delta to be decent enough after the chip was turned off for more than a few seconds, you need to change DLY to a much much bigger number.

BR

OCY

;=============================================================#include
#define DLY 255
ORG 0FFFEh
DC16 main
RSEG CODE
main: MOV.W #0x280,SP
MOV.W #WDTPW+WDTHOLD,&WDTCTL
MOV.B #BIT6,&P1OUT
MOV.B #BIT0+BIT6,&P1DIR
MOV.B #0,&P2SEL
L0: BIT.B #BIT3,&P1IN
JNZ L0 ;green LED is on, wait a while
; and press S2 to continue
MOV.B #0,&P1OUT
MOV.B #XCAP_2,&BCSCTL3
MOV.B #0xC0,&P2SEL
L1: BIC.B #OFIFG,&IFG1
MOV.W DLY,R15
L2: SUB.W #1,R15
JNZ L2
BIT.B #OFIFG,&IFG1
JNZ L1
MOV.B #XT2OFF+15,&BCSCTL1
MOV.W #4000-1,R4 ;count down from 4000
MOV.W #0,R5 ;max delta
MOV.W #0xFFFF,R6 ;min delta
MOV.W #CM_1+CCIS_1+SCS+CAP+OUTMOD_0,&TACCTL0
MOV.W #MC_2+ID_0+TASSEL_2,&TACTL
CALL #await_aclk
L3: MOV.W R15,R14 ;previous
CALL #await_aclk
MOV.W R15,R7
SUB.W R14,R7 ;delta
CMP.W R7,R5
JHS L4
MOV.W R7,R5 ;new max
L4: CMP.W R6,R7
JHS L5
MOV.W R7,R6 ;new min
L5: SUB.W #1,R4 ;repeat?
JNZ L3
MOV.W #16-1,R4 ;count down from 16
L6: CALL #await_aclk
SUB.W #1,R4 ;repeat?
JNZ L6
MOV.W R15,R7
SUB.W R14,R7 ;16*deltas
MOV.B #BIT0,&P1OUT
JMP $ ;red LED is on
; break here and view registers
; R5 = max of 4000 deltas
; R6 = min of 4000 deltas
; R7 = sum of next 16 (0x10) deltas
await_aclk:
await_aclk_01:
bit #CCIFG, &TACCTL0
jeq await_aclk_01
mov &TACCR0, r15
bic #CCIFG, &TACCTL0
ret
END
;=============================================================
--- In m..., Jon Kirwan wrote:
>
> On Tue, 17 May 2011 18:41:45 -0000, you wrote:
>
> >Okay, I assume that you did the following:
> >
> >main: MOV.W #0x280,SP
> > MOV.W #WDTPW+WDTHOLD,&WDTCTL
> > MOV.B #XCAP_3,&BCSCTL3
> > MOV.W #0,R15
> >L1: BIC.B #OFIFG,&IFG1
> >L2: SUB.W #1,R15
> > JNZ L2
> > BIT.B #OFIFG,&IFG1
> > JNZ L1
> > MOV.B #XT2OFF+15,&BCSCTL1
>
> OCY, something else comes to mind about your initialization
> code shown above. I hope you don't mind me bringing you back
> to this for a moment.
>
> You set up the Microcrystal to XCAP_3 loading. In the header
> file, just for anyone who doesn't already have it in mind,
> that is:
>
> #define XCAP_3 (0x0C) /* XIN/XOUT Cap : 12.5 pF */
>
> Which is the highest loading. Excessively high loading
> results in more power consumption, if I recall correctly and
> may slightly pull down the oscillation frequency.
>
> There is a file provided by Microcrystal, available on
> e2e.ti.com that covers this crystal and the Launchpad system
> from TI. It is at:
>
> http://e2e.ti.com/cfs-file.ashx/__key/CommunityServer.Discussions.Components.Files/166/2772.TI_5F00_MSP430_5F00_Crystal-Recommendations.pdf
>
> If you skip down to page 4 (of 5), it is about the x2xx
> family and recommends using XCAP_2, not XCAP_3. As an
> alternative, they suggest XCAP_1. Both XCAP_0 and XCAP_3 are
> not recommended.
>
> Were you aware?
>
> Jon
>

Reply by Jon Kirwan May 18, 20112011-05-18
On Tue, 17 May 2011 18:41:45 -0000, you wrote:

>Okay, I assume that you did the following:
>
>main: MOV.W #0x280,SP
> MOV.W #WDTPW+WDTHOLD,&WDTCTL
> MOV.B #XCAP_3,&BCSCTL3
> MOV.W #0,R15
>L1: BIC.B #OFIFG,&IFG1
>L2: SUB.W #1,R15
> JNZ L2
> BIT.B #OFIFG,&IFG1
> JNZ L1
> MOV.B #XT2OFF+15,&BCSCTL1

OCY, something else comes to mind about your initialization
code shown above. I hope you don't mind me bringing you back
to this for a moment.

You set up the Microcrystal to XCAP_3 loading. In the header
file, just for anyone who doesn't already have it in mind,
that is:

#define XCAP_3 (0x0C) /* XIN/XOUT Cap : 12.5 pF */

Which is the highest loading. Excessively high loading
results in more power consumption, if I recall correctly and
may slightly pull down the oscillation frequency.

There is a file provided by Microcrystal, available on
e2e.ti.com that covers this crystal and the Launchpad system
from TI. It is at:

http://e2e.ti.com/cfs-file.ashx/__key/CommunityServer.Discussions.Components.Files/166/2772.TI_5F00_MSP430_5F00_Crystal-Recommendations.pdf

If you skip down to page 4 (of 5), it is about the x2xx
family and recommends using XCAP_2, not XCAP_3. As an
alternative, they suggest XCAP_1. Both XCAP_0 and XCAP_3 are
not recommended.

Were you aware?

Jon
Reply by Jon Kirwan May 18, 20112011-05-18
On Wed, 18 May 2011 17:11:25 -0000, OCY wrote:

>Jon,
>
>You said:
>> .................................. Problem is, I want it
>> nailed down hard. Without the theory behind it, no matter
>> what I do and no matter how perfectly all my testing verifies
>> that it does work, the code generated from my ignorance
>> remains a potential risk. I don't like that feeling.
>
> Same here. But I do not think this kind of attitude is a
> "Problem";) I am just as curious as you are to get to the
> bottom of what you found.

I try to imagine defending my code and having to say, "well,
I have some guesses but I really don't know why except that
the delay seems to work."

> The reason I included a long long delay is that I know the
> watch crystal controlled oscillator takes a long long time
> to start and stabilize. If the device is already powered up
> for a while (as in the case of a debug session under the
> control of a development tool), it is not needed. I think it
> is not related to the bad delta between the first two
> captures.

Understood. The code reference I mentioned in the Family
Guide uses a much smaller delay (255) for the same purpose.
Any particular reason you chose NOT to follow their example
here and instead use a delay hundreds of times longer?

Indeed, another question comes to mind. There is a signal
called LFXT1OF that is accessible. It is combinatorial and
doesn't require clearing (nor can it be) and informs on the
status of the LFXT1 crystal. Why not simply wait on that?
Why repeatedly clear, then delay, then test the OFIFG?

> Instead, I think changing DIVA from 1 to 8 may have
> something to do with what you found. As a result, ACLK will
> change from 32.768 kHz to 4.096 kHz. But when? Will TimerA
> see the change over? (That is, see one cycle of 32.768 kHz
> before the 4.096 kHz clocks.)

Hmm. Now that's a thought. Thanks. I'll think about it a
little to see if that holds good water.

Thanks for the sincere discussion OCY. Very nice and
appreciated.

Jon
Reply by old_cow_yellow May 18, 20112011-05-18
Jon,

You said:

> .................................. Problem is, I want it
> nailed down hard. Without the theory behind it, no matter
> what I do and no matter how perfectly all my testing verifies
> that it does work, the code generated from my ignorance
> remains a potential risk. I don't like that feeling.

Same here. But I do not think this kind of attitude is a "Problem";) I am just as curious as you are to get to the bottom of what you found.

The reason I included a long long delay is that I know the watch crystal controlled oscillator takes a long long time to start and stabilize. If the device is already powered up for a while (as in the case of a debug session under the control of a development tool), it is not needed. I think it is not related to the bad delta between the first two captures.

Instead, I think changing DIVA from 1 to 8 may have something to do with what you found. As a result, ACLK will change from 32.768 kHz to 4.096 kHz. But when? Will TimerA see the change over? (That is, see one cycle of 32.768 kHz before the 4.096 kHz clocks.)

-- OCY

Reply by Jon Kirwan May 18, 20112011-05-18
On Wed, 18 May 2011 06:53:07 +0000 (UTC), you wrote:

>Jon Kirwan :
>
>> On Tue, 17 May 2011 14:08:16 +0000 (UTC), you wrote:
>>
>>>I remember that there are some silicon bugs (e.g. TA12 TA16) in MSP430
>>>devices related to ACLK and Timer capture/compare after initialization.
>>>
>>>Have you checked the errata of your device?
>>
>> Oh, yes. In fact, I not only mentioned the fact that I had
>> checked the errata in the very post you are replying to, but
>> I also mentioned that fact in the original post, as well. I
>> looked closely at them and am following those rules. I also
>> searched for ACLK in them and checked anything mentioning it.
>
>Sorry, life is short, I just did not really read your very long article, just
>fly over it. Keep it as short as possible and simple. :-)

No harm done.

Jon
Reply by Matthias Weingart May 18, 20112011-05-18
Jon Kirwan :

> On Tue, 17 May 2011 14:08:16 +0000 (UTC), you wrote:
>
>>I remember that there are some silicon bugs (e.g. TA12 TA16) in MSP430
>>devices related to ACLK and Timer capture/compare after initialization.
>>
>>Have you checked the errata of your device?
>
> Oh, yes. In fact, I not only mentioned the fact that I had
> checked the errata in the very post you are replying to, but
> I also mentioned that fact in the original post, as well. I
> looked closely at them and am following those rules. I also
> searched for ACLK in them and checked anything mentioning it.

Sorry, life is short, I just did not really read your very long article, just
fly over it. Keep it as short as possible and simple. :-)

M.

Reply by Jon Kirwan May 17, 20112011-05-17
Let me add a note. I'm working on other things, but I went
back and double-checked some details.

When the G2231 starts up, OFIFG=1 but LFXT1OF=0. The LFXT1
is up and running, no errors, but by default the OFIFG=1 and
that is done because they want to MAKE SURE that the
processor __uses__ the DCO, at POR. That's clear enough.
Clearing OFIFG doesn't impact the LFXT1 oscillator system. It
merely permits the use of it for MCLK, if you might want
that. It is LFXT1OF, which is a combinatorial signal and not
a latch, that tells you the story.

Without a delay inserted at the top, and running the same
code today that yesterday gave me 1 error in 3 or 4 tries, is
now giving me fewer errors. Mostly, it happens right after
downloading code via the TI USB FET tool. If I reset and run
again, it almost always works. Yesterday, it would fail more
often. But I still do see the rare case where it "fails"
(according to my criteria), unless I insert a delay loop. It
also occasionally (still rarely) fails if I wait on LFXT1OF,
whether or not I first clear OFIFG.

I need to insert some code to manually reset the cpu and set
a breakpoint that only takes place on failures (so I will
need code to test against a tight range and go somewhere else
where the breakpoint is at should the value go outside the
range.) If it "succeeds" (again, according to my rules),
then I will reset the CPU and force a restart. In this way,
the debugger can be used to see if there are ANY single
failures at all, regardless of how many thousands or tens of
thousands of tries it takes to find one.

I'll try that now. Bulletproof and full understanding is
required.

By the way, OCY, your example code for starting things up
with the R15 delay loop comes almost straight out of the x2xx
Family Guide (I'm using SLAU144H) on page 279, section
heading 5.2.7.1. But they use 255 for the loop. Not the
very long period you use. Turns out, I had tried out the
small timing loop of 255 as a precursor to doing the rest and
that didn't always work. If I expanded it to about 1000, it
did always work.

Anyway, I know what works. In fact, I know quite a few ways
that work. And I have some vague ideas about possible
reasons for the occasional failure. Problem is, I want it
nailed down hard. Without the theory behind it, no matter
what I do and no matter how perfectly all my testing verifies
that it does work, the code generated from my ignorance
remains a potential risk. I don't like that feeling.

And very sincere thanks OCY for even bothering to think and
try anything to help me. I sincerely appreciate it and need
to say so. It means a lot.

Jon
Reply by Jon Kirwan May 17, 20112011-05-17
Very similar code. I happen to set up some port I/O
directions and I also set the ACLK for a divisor of 8.
Otherwise, looks similar. Here's the prior instructions:

mov #SFE(CSTACK), SP
mov #WDTPW+WDTHOLD, &WDTCTL
bis.b #01000011b, &P1DIR
clr.b &DCOCTL
mov.b #XT2OFF + DIVA_3 + 15, &BCSCTL1
mov.b #01111111b, &DCOCTL

I knew that 1k-word of flash _might_ be tight (it won't be),
so I decided to rely upon stated initial conditions of the
various registers. The datasheet for the provided capacitor,
the Microcrystal MS3V-T1R was in hand, but it supports 7, 9,
and 12.5pF. The parts list for the LaunchPad was not in
hand, so I permitted the 6pF default to stand, above. I
could always change that when I took the extra time.

The documentation regarding the errata sheet on changing RSEL
from the default 7 to 15 is followed in the above code. Note
that there is a different process going in the other
direction. But they provide examples in the TLV chapter of
the x2xx Family manual, which I chose to follow per
instructions in the errata.

Your code, however, does something which inherently does what
I did to make things work before making those two calls.
However, that doesn't tell me __WHY__. So let's look at your
code, again:

>main: MOV.W #0x280,SP
> MOV.W #WDTPW+WDTHOLD,&WDTCTL
> MOV.B #XCAP_3,&BCSCTL3
> MOV.W #0,R15
>L1: BIC.B #OFIFG,&IFG1
>L2: SUB.W #1,R15
> JNZ L2
> BIT.B #OFIFG,&IFG1
> JNZ L1
> MOV.B #XT2OFF+15,&BCSCTL1

I'm going to skip over the dead-obvious first two
instructions. Nothing needs be said there.

The XCAP_3 setting to BCSCTL3 is different than the power up
case. But I don't think it's important, for now. It only
means the xtal gets pulled a little. It doesn't address
itself, unless you wish to say so, towards the question at
hand. But if you think that's it, I'd be happy to test it
here.

The last instruction modifies RSEL after those waiting for
the crystal to show "good." That's an interesting approach,
but I don't think it is a necessary one. I should be able to
transition to RSEL without regard to whether or not the
crystal is up and running. So I'll ignore that unless you
have a theory about why LFXT1 and setting RSEL are
necessarily tethered to each other.

So that gets us to these:

> MOV.W #0,R15
>L1: BIC.B #OFIFG,&IFG1
>L2: SUB.W #1,R15
> JNZ L2
> BIT.B #OFIFG,&IFG1
> JNZ L1

Here you clear OFIFG, wait a LONG TIME (R15 delay loop), and
then test OFIFG. If OFIFG is in error, you clear it again,
wait a LONG TIME again (R15 is back to zero, again), and then
repeat the process.

My code works perfectly well without most of that. If I
_only_ apply your R15 delay loop and NOTHING ELSE AT ALL, it
works perfectly.

My problem isn't getting right results. It's knowing ALL of
the details why.

In the case you provide above, you are ensuring that the
crystal is running before proceeding. I do that, too. And
it is. But my testing for that excluded the LONG DELAY part.
I just sat in a dead loop (which, by the way, was never
needed because by the time the processor was running it seems
that the crystal was also always running before I could even
start testing it.

So, of course you get good results with the above code. You
perform a LONG DELAY at least one time. Without the rest of
your OFIFG testing code (and mine deleted as well) it always
works perfectly, delay loop only.

It's still not an understanding. I know it works. But I
need to know why in terms of the electronics design of the
cpu. The details are important to me.

Jon
On Tue, 17 May 2011 18:41:45 -0000, OCY wrote:

>>
>> You can assume that I've already set up the DCO at RSEL
>> and that the LFXT1 is up and running and the error bit clear.
>>Okay, I assume that you did the following:
>
>main: MOV.W #0x280,SP
> MOV.W #WDTPW+WDTHOLD,&WDTCTL
> MOV.B #XCAP_3,&BCSCTL3
> MOV.W #0,R15
>L1: BIC.B #OFIFG,&IFG1
>L2: SUB.W #1,R15
> JNZ L2
> BIT.B #OFIFG,&IFG1
> JNZ L1
> MOV.B #XT2OFF+15,&BCSCTL1
>
>After that I copied your code:
>
> mov #CM_1 + CCIS_1 + SCS + CAP + OUTMOD_0, &TACCTL0
> mov #MC_2 + ID_0 + TASSEL_2, &TACTL
> call #await_aclk
> mov r15, r14
> call #await_aclk
> sub r14, r15
>
>And added an infinity loop followed by your subroutine.
>
> JMP $
>await_aclk
>await_aclk_01
> bit #CCIFG, &TACCTL0
> jeq await_aclk_01
> mov &TACCR0, r15
> bic #CCIFG, &TACCTL0
> ret
>
>What I found is, r14 is kind of random and r15 is always what I expected.
>
>Using one G2211, I always get 0x01B6 or 0x01b7. Using a different G2211, I always get 0x01D4 or 0x01D5. They correspond to DCO frequency of ~14.4 MHz and ~15.4 MHz respectively.
>
>
Reply by old_cow_yellow May 17, 20112011-05-17
>
> You can assume that I've already set up the DCO at RSEL
> and that the LFXT1 is up and running and the error bit clear.
>

Okay, I assume that you did the following:

main: MOV.W #0x280,SP
MOV.W #WDTPW+WDTHOLD,&WDTCTL
MOV.B #XCAP_3,&BCSCTL3
MOV.W #0,R15
L1: BIC.B #OFIFG,&IFG1
L2: SUB.W #1,R15
JNZ L2
BIT.B #OFIFG,&IFG1
JNZ L1
MOV.B #XT2OFF+15,&BCSCTL1

After that I copied your code:

mov #CM_1 + CCIS_1 + SCS + CAP + OUTMOD_0, &TACCTL0
mov #MC_2 + ID_0 + TASSEL_2, &TACTL
call #await_aclk
mov r15, r14
call #await_aclk
sub r14, r15

And added an infinity loop followed by your subroutine.

JMP $
await_aclk
await_aclk_01
bit #CCIFG, &TACCTL0
jeq await_aclk_01
mov &TACCR0, r15
bic #CCIFG, &TACCTL0
ret

What I found is, r14 is kind of random and r15 is always what I expected.

Using one G2211, I always get 0x01B6 or 0x01b7. Using a different G2211, I always get 0x01D4 or 0x01D5. They correspond to DCO frequency of ~14.4 MHz and ~15.4 MHz respectively.