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.

01 October 2010

Yes, the blog is officially back!

Thanks, everyone, for your patience.  My research has been moving quite a bit lately and occupied the majority of my time.  Fortunately the 16 hour work-days are over, and I have some spare time and motivation to play with the LaunchPad some more.  I've posted the first part of a multi-part tutorial on Low Power Modes (by popular demand!) and have a bunch of great ideas coming up.  We'll be working toward being able to make your own LaunchPad circuit board (minus the SBW programmer, of course) and communicating with a computer among many other fun things.  Send me a note if you have any particular topics you're aching to learn about.  We'll keep on with LPMs and start ADC soon as I wait for the boards I've designed to arrive.  Watch for some design notes and other posts to come soon!

Tutorial 11-a: Going Low Power

Now that we have some degree of control over the MSP430, it's a good opportunity to introduce the low power mode.  This feature is arguably one of the most important for the MSP430, and is an excellent reason for choosing this microcontroller over many others.  Let's look at how the modes work.

The operating mode of the MSP430 is controlled with four different bits in the status register.  These bits are called CPUOFF, OSCOFF, SCG0, and SCG1.  The first two are fairly self-evident; the first of these controls the power to the CPU of the MSP430.  The second controls the power to the external oscillator (ie. crystal usually).  In addition, these bits turn on/off MCLK and ACLK respectively, since those are associated with the CPU and LFXTL.  The other two bits add more control over SMCLK, the DCO, and the DC generator.

Page from the x2xx Family Guide describing
the low power modes.
In the x2xx Family Guide, page 2-15 shows a diagram and table explaining how the operating modes work.  For our convenience, TI has defined 6 different modes that are easily accessible to us via the header files.  The MSP430 starts off in Active Mode, where the CPU and all clocks are up and running.  This is the mode in which we've been running up until now.  Any time the MSP430 needs to do something, it will be in Active Mode.  That's not to say that peripherals can't operate in the other modes.  There are 5 low power modes, labeled LPM0 through LPM4.  These are the commonly used configurations, and only rarely will you need one of the other 10 possible modes available with a 4-bit configuration.  (One exception to that would be turning off an unused crystal oscillator that's soldered to your LaunchPad, but not being used in your current project.  More on that later.)

the _BIS_SR() function we saw earlier is perhaps the easiest method of using the LPMs.  The header files define a set of names called LPMx_bits to help with the bit management.  To enter a low power mode, simply issue the command _BIS_SR(LPMx_bits); with x replaced by the LPM number you've chosen.  Keep in mind that if you want to use interrupts, you will also have to add GIE to the argument, or at least _enable_interrupt(); before going into the LPM.

Another good thing to keep in mind is that the LPMs are distinct; you don't need to include LPM0 to use LPM1.  In fact, doing so (eg. using a command such as _BIS_SR(LPM0_bits + LPM1_bits + GIE);) would have undesirable side effects by adding the binary values that the header file definitions provide together.

One of the features of the MSP430 architecture is that you don't need to tell the CPU to wake up on the interrupt, nor do you need to put it back in the LPM manually.  All of this is done automatically; when an interrupt is triggered, the Status Register is saved to memory (pushed onto the stack) and reset, waking up the CPU.  Once the ISR has been satisfied, the original Status Register (including the LPM setting) is popped off the stack back into its place, and the MSP430 returns to the low power state.  If you require your program to wake up the chip and stay awake, you will need to include a line in your ISR to do so:


_BIC_SR(LPMx_bits);  // clears the bits corresponding to LPMx and exits the low power mode

Note the different function name; _BIS_SR() is Bit Set Status Register (ie. set to 1) while _BIC_SR() is Bit Clear Status Register (ie. clear to 0).

Example using the Low Power Modes
As an example, I've coded up a simple program that plays a tone on an 8Ω speaker.  The speaker I have has two pins with 0.2" separation, and so it plugs right into the headers on the LaunchPad.  To accommodate the spacing, I'm using P1.0 and P1.2 to drive the speaker.  If you don't have a speaker available, you can simulate the same idea using the two LEDs on the LaunchPad; just follow the instructions in the code and change SOUT to BIT6 and adjust the frequency accordingly.

The idea is simple; we start with P1.0 high, P1.2 low, and switch each at a given frequency.  This method provides a square wave, not a pure tone, but it does work.  Keep in mind that audible frequencies are generally in the 100's and 1000's of Hz.  It might be interesting to see how low of a frequency you can hear (clicking doesn't count; listen for an actual tone) and how high you can hear.  Also, you can keep one pin constantly low and switch only the other if you want to reduce the volume.

There's more to explore with the low power modes, and next time we'll start playing with the low frequency oscillator to drop into the deeper sleep modes.

Reader Exercise:  This tutorial's code uses LPM0.  Try out the other low power modes by using LPMx_bits in place of LPM0_bits.  What happens if you try to use LPM1?  LPM2?  LPM3?  LPM4? Can you explain why some of these work and others don't?  Those that work, is there any actual difference between the modes as implemented for this program?  As you answer these questions, think about what clock is sourcing the timer and what oscillator is used for the clock.