03 October 2010

Tutorial 11-b: Using the Auxiliary Clock

If you did the exercise at the end of the last tutorial, you probably noticed that the program stopped working if you tried using any of the LPMs other than LPM0 or LPM1.  The reason for this has to do with the clock that is chosen to power the timer.  So let's take a careful look at just what's happening in the limboG2211.c program.

First of all, we set the DCO to the calibrated 1 MHz frequency.  Pretty straight-forward here; the MSP430 MCLK timing the CPU will operate at very close to 1 MHz.  What isn't as obvious is that the sub-main clock (SMCLK) is also driven by the DCO, and so also operates at 1 MHz.

The timer is then configured to run with the SMCLK divided by 8, or at 125 kHz.  The timer counts to TACCR0 and then triggers an interrupt, wherein the current through the speaker (or current to the LEDs if you changed it to that mode) is switched.  The frequency of the switching drives the speaker to create a particular tone.

In between switches, the MSP430 enters LPM0.  We can see what happens to the chip when entering this mode by looking again at the diagram and table on page 2-15 of the x2xx Family Guide: the CPUOFF bit in the Status Register is set to 1.  The CPU turns off, as does MCLK, leaving SMCLK and ACLK running.  If we run LPM1, then the CPUOFF bit is set as in LPM0, and in addition SCG0 is set to 1.  We can see that this mode has the added benefit of turning off the DCO if the SMCLK is not being used.  In our case, we're using SMCLK to drive Timer A, so the DCO is not turned off for LPM1.  Essentially, for this program, there is no difference between LPMs 0 and 1.

If we move to LPM2, however, we set CPUOFF and SCG1, which has a much different effect: in addition to the CPU and MCLK, SMCLK is disabled, allowing the DCO to also be disabled.  In our program, then, when we enter LPM2 we turn off the clock driving Timer A; Timer A never reaches TACCR0, and an interrupt is never triggered to cause the MSP430 to exit the LPM.  In LPM2, however, ACLK is allowed to continue running.  If we drive Timer A with ACLK, then, we could use deeper modes and consume less power overall!  Less power means more battery life and more efficient use of the resources in the MSP430 design.

ACLK is typically driven at low frequencies (comparatively), and so draws less power than does DCO, further improving our goal of reducing power consumption.  By default, it is set to use a 32,768 Hz quartz crystal.  Your LaunchPad kit came with a crystal that you can solder onto the board to use here.  Alternatively, you can configure the LFXT1 clock source to run from an internal oscillator, similar to the DCO, that operates at a very low frequency (typically 12 kHz).  This oscillator is referred to simply as the VLO.

Configuring LFXT1 and ACLK
If you're planning to use the crystal oscillator on LFXT1, there's likely little that needs to be done.  The crystal that comes with the LaunchPad needs 12.5 pF capacitors for stability, and you might notice the SMD solder pads near the crystal location for capacitors.  You can use discrete capacitors if you like, but the MSP430 is also configured with a few capacitances internally, and 12.5 pF is one of the choices.  Using the crystal is a simple matter of soldering it onto the board and configuring the BCS+ module correctly.  There are a lot of switches and controls involved here, so we'll save crystal control for a later tutorial, and assume for now that we're going to use the VLO to source the Auxiliary Clock.

Section 5.3 in the x2xx Family Guide (starting on page 5-13) holds the necessary information for configuring the BCS+ module.  The registers we need for now are BCSCTL1 and BCSCTL3.  In terms of setting up the VLO, we need the XTS bit in BCSCTL1 (bit 6) and the LFXT1Sx bits in BCSCTL3 (bits 5 and 4).  The XTS bit sets the LFXT1 clock source to low or high frequency.  Many MSP430s in the x2xx family let you use a high frequency crystal for this source; the value line devices, however, only support low frequency (ie. 32,768 Hz) crystals.  When this bit is cleared to 0 we have configured the chip for low frequency ranges.  Some devices, including the value line chips that come with the LaunchPad, allow us to use the VLO.  This mode is selected by setting the LFXT1Sx bits to 0b10, as described on page 5-16.  To do this in C, we again make use of a header file definition:

BCSCTL3 |= LFXT1S1;  // sets LFXT1Sx to 0b10, VLO mode

We don't need to explicitly change the XTS bit, as it defaults to the low frequency setting.  This line is sufficient for setting up the VLO.

With LFXT1 now oscillating at 12 kHz, ACLK can be used for the peripherals.  You may recall from Tutorial 08-a that ACLK only sources from LFXT1, using either a crystal or the VLO.  We can, however, alter the frequency for ACLK by dividing the VLO by 2, 4, or 8.  This is done in BCSCTL1 with the DIVAx bits (5 and 4) with the configurations given on page 5-14.  For our purposes, we'll set ACLK to run at about 3 kHz by dividing the VLO by 4.  We do this with the following code:

BCSCTL1 |= DIVA_2;  // ACLK divide by 4

Keep in mind that you can also divide the clock in the peripheral itself, or further divide inside the peripheral.  For example, we can run Timer A at 750 Hz by dividing by an additional factor of 4:

TACTL = TASSEL_1 + ID_2 + MC_1 + TACLR;  // use ACLK, div 4, up mode, clear

To summarize, we can modify the limboG2211.c code to use the following:

BCSCTL1 = CALBC1_1MHZ; // Running at 1 MHz
DCOCTL = CALDCO_1MHZ;
BCSCTL3 |= LFXT1S1;     // VLO mode


TACCR0 = 14;  // With the Timer using ACLK (12 kHz), this
  // value gives a frequency of 12000/(TACCR0+1) Hz.
  // For TACCR0 = 14, that's 800 Hz.

TACCTL0 = CCIE;         // Enable interrupts for CCR0.
TACTL = TASSEL_1 + MC_1 + TACLR;  // ACLK, up mode, clear timer.

_BIS_SR(LPM3_bits + GIE);  // Enter LPM3 and enable interrupts

This code sets ACLK to run from the VLO (at ~12 kHz) and then uses Timer A to switch the speaker at ~800 Hz.  Most importantly, since we are now sourcing the timer which causes interrupts from ACLK, we can use LPM2 and 3 in our program.  Note that LPM4 would turn off the ACLK; using LPM4 is only feasible if we have some external interrupt source, such as watching for a signal on one of the GIO pins.

We'll return to looking at the low power modes soon; the first real scientific project we'll do will analyze and compare the power consumption of a simple MSP430 design using the various LPM settings.  To do this, however, we're going to need to measure an analog signal and record data.  The next tutorial will start us in this direction by looking at analog to digital conversion.

Reader Exercise:  Suppose your LaunchPad has the crystal soldered onto it, and is being used in a project that does not use ACLK at all.  The crystal will continue to oscillate, and use power (albeit a very small amount) that is not contributing to the overall design.  Note that none of the standard LPMs disable ACLK and the crystal oscillator except LPM4.  Write up the needed line(s) of code that would create a new LPM that keeps MCLK, SMCLK, and the DCO running, but disables ACLK and the crystal oscillator.

7 comments:

suspended-chord said...

Very nice post, beretta!

This is a very good description of the VLO and using ACLK as a source.

This helped my understanding immensely. Thank you very much, and keep up the great work!

KaziQ said...

Hey man,

About the DCO and BCSCTL.
Sometimes we refer to these as separate things like independent from each other, but when we slow the clock down for ex: DCO freq (0, 0) then the whole system slows down. We didn't get in any LPM but we slowed down the CPU by somehow slowing down the clock? DCO is directly the CPU freq?

Thanks for caring

KaziQ said...

Hey man,

I am the same anonymous guy (not anymore :) ). I don't know if couple of days ago I was able to post my question. So here we go again.

So when we manipulate the timers DCO and BSCCTL1, the cpu slows down. when we get in low power modes, CPU does not slow down, but the timers turn on and off which will affect the power consumption.

I have couple questions out of these rather confusing ideas I need to clarify. How do the timers affect the CPU frequency? How do we know the exact CPU frequency?

How are the timers related to the CPU frequency? The main timer I am assuming that increments each cycle of the CPU regardless to what happens. But if we can slow that down and CPU slows down(?) doesn't that change the power consumption? So the ultimate LPM mode would be for us turn off all the timers but Crystal, slow down the CPU DCO(0, 0). Am I right?

If you can explain the full relation between timers and CPU freq. By CPU I mean micro controller by the way.

Again I couldn't have done without your tutorials.
Thanks

David said...

So I had written up a response to your questions, and somehow it never got posted... here's a short answer for the time being:

You might review Tutorial 8a and 11a (especially the figure taken from the x2xx Family User's Guide), as the questions are really addressed there.

Keep in mind you're not changing timers with DCOCTL and BCSCTL1, you're changing the DCO clock. By default, the MCLK is sourced by the DCO, and the CPU uses MCLK, so changing the DCO directly changes the speed of the CPU.

You get some power savings by operating at a lower frequency, but the real impact comes in using the LPMs, where we turn clocks off completely (and in some cases, the CPU too) until an interrupt indicates that they're needed. In that case, if you turn off all the clocks except ACLK being sourced by the LFXT1 crystal, there's no point in slowing the DCO, since it's not even running!

Hope that helps.

RocketMan said...

First I want to say thank you for all you've shared here. This is by far the most comprehensive launchpad-usage-tutorial collection available. You have helped me amongst countless newcomers to this system. Thank you!

Now on to my comment:

You wrote:
BCSCTL3 |= LFXT1S1; // sets LFXT1Sx to 0b10, VLO mode

I'm looking at the BCSCTL3 chart (section 5.3.4) in the MSP430 Family PDF. For LFXT1Sx, it shows VLOCLK as three(10), but it looks like you're setting it to one(01).
Shouldn't the line read:
BCSCTL3 |= LFXT1S_3;

If not, what am I missing here?
TQ

RocketMan said...

correction: I said VLOCLK is "three(10)" when I should have said "two(10)" and my suggested line would be

BCSCTL3 |= LFXT1S_2;

sorry about that.

David Olson said...

RocketMan: What you've set there is correct (changing _3 to _2, of course). The confusion comes from two different notations; this is about the time where I switched to the notation you're using.

If you look in the header file for your device, you'll see two types of definitions: LFXT1Sx and LFXT1S_x. The underscore is the difference; the first way defines the two specific bits, to be used in whatever appropriate combination, while the second defines all of the specific modes individually. So LFXT1S1 is defined as the second bit for the two controlling the mode, or 0b10. LFXT1S_2 is defined as the mode specified by 0b10 specifically.

It's probably more clear when you look at mode 3, which sets LFXT1 to use an external input. The mode is specifically defined as LFXT1S_3, but is also equivalent to LFXT1S1 + LFXT1S0, which sets both bits individually.

So the way I did it here, and the way you suggest are actually equivalent. Hope that helps!