We are able to select the frequency we use with the RSELx bits in BCSCTL1 (select range 0 to 15) and the DCOx bits in DCOCTL (select step 0 to 7). How do we know which pair we want? The device-specific datasheet should give you some help in that regard. For the G2x11, we see the DCO frequency table on page 26. For any device, this table will either list the typical value for a sample of selections, or a set of min/max values for the selection set. (Note: As of this writing, the current revision of the G2x11 datasheet (SLAS695B) is printed incorrectly, giving typical values for some selections and min/max values for others. In future revisions of the document it will likely be changed to only one or the other.) TI uses an ordered pair notation to describe the DCO setting, such as (8,2) for Range 8, Step 2 (or DCO 2 to use their term). We'll use that notation from now on to describe DCO settings with the convention DCO(r, s) where r is the range value and s is the step value.
As an example, note that DCO(6,3) is typically 0.80 MHz (or 800 kHz), while DCO(13,3) is 7.8 MHz. Note that the table only lists DCO(r,3) pairs for each range, and also values for DCO(0,0) and DCO(15,7), the low and high end of the DCO values. What about all the others? At the bottom of the table, there are two values called SRSEL and SDCO. These values give the ratio of subsequent ranges and steps as SRSEL = (r+1,s)/(r,s) and SDCO = (r,s+1)/r(s), allowing you to get a value for any of the possible combinations. For example, DCO(6,4) would be SDCO * DCO(6,3), or in the case of the G2211, 1.08*0.80 Mhz = 0.864 MHz. DCO(6,7) would be SDCO * DCO(6,6) = SDCO * (SDCO * DCO(6,5)) and so on, so a general formula would be DCO(r,s+n) = SDCO^n * DCO(r,s). (Note that you can get the lower step values with negative n, eg. DCO(6,1) = DCO(6,3-2) = SDCO ^ (-2) * DCO(6,3).)
One final topic before getting to the code; each MSP430 device comes with at least one calibrated value for the DCO. These values are found for each individual chip at the fabrication facility and programed into the information memory section of the flash memory. The values are not necessarily the same for my G2211 as it is for yours, but if you ever accidentally (or intentionally) erase the calibration values, TI does provide a program that will recalibrate the DCO and write the values to the memory for later use. (You should be able to find this program in the code examples you can download for your device. The G2xx code can be obtained here, and the program is called msp430x20xx_dco_flashcal.c.) The G2x11 devices only have one calibrated frequency at 1 MHz.
Now for the practical part. Fire up CCS with your launchpad, and enter the debugging mode with any program you have. We're not going to actually run the program, just look at some of the registers as they come up by default. The MSP430 x2xx devices supposedly default to a 1.1 MHz DCO. What value actually comes up? In the debugger, open up a view of the registers, and find the BCS+ registers under System_Clock. For the G2211, the registers start with values of 0x60 for DCOCTL and 0x87 for BCSCTL1. Expand the registers to look at the individual bits, and we can see that RSEL is 0b0111, or 7, and DCO is 0b011, or 3. The default setting for the DCO is DCO(7,3), which according to the datasheet is between 0.80 MHz and 1.50 MHz. The actual value depends on your unit, the temperature, pressure, phase of the moon... ok, not really the moon phase, but you get the idea. If you happen to have an oscilloscope, we can actually look at the frequency by using the alternate function for P1.4-- the SMCLK can be driven by the DCO and put on this pin for external use.
Let's write up some code to actually change the DCO now. We're mostly interested in manipulating the DCOx and RSELx bits, which are bits 5-7 in DCOCTL and 0-3 in BCSCTL1 respectively. When we've selected the pair of values we want, we can change those bits in code. For example, if we want to change to DCO(12,2), we want 0b1100 for RSELx and 0b010 for DCOx. We can set these values in our code with the following:
BCSCTL1 &= ~(BIT0 + BIT1); // set bits 0 and 1 to 0
BCSCTL1 |= BIT2 + BIT3; // set bits 2 and 3 to 1DCOCTL &= ~(BIT5 + BIT7); // set bits 5 and 7 to 0
DCOCTL |= BIT6; // set bit 6 to 1
Does the order matter? Well, keep in mind the frequency will change with every step. So after the first line, assuming we have the default configuration found above, the bits have changed to 0b0100, putting us in DCO(4,3). The second line moves us to DCO(12,3). The third line moves us to DCO(12,2), making the last step redundant. If we had started by setting bits 2 and 3 in RSELx, we would have stepped from DCO(7,3) to DCO(15,3), putting a really high frequency on everything. That may not be an issue, but if you have any sensitive components you might consider stepping rather than jumping up to higher frequencies. If MCLK is driven by DCO (it is by default) you may find some problems as the higher frequencies may be above the 16 MHz limit for the processor. Going the other direction, jumping down puts the DCO at a really low frequency, which slows down the operation of the subsequent steps, but shouldn't cause any serious trouble.
Setting to calibrated values is much easier, since CCS provides us with shortcuts to those values:
BCSCTL1 = CALBC1_1MHZ;
DCOCTL = CALDCO_1MHZ;
Those two lines are all that's needed to set the DCO at exactly 1 MHz! (Within 3%, anyway.)
I've written some code in dcodemo_g2211.c that gives an example of how to use the DCO in a program. Browse through it and try running it on your launchpad to see how it works. The program simply flashes the LED with a delay loop and waits for the user to press the button. The program then changes the DCO frequency, and re-flashes the LED. Since the frequency increases, however, the LED flash is much faster, even though it uses the same delay loop! The DCO is controlling the operating speed of the processor, and so the for loop steps through much more quickly. Another button press slows down the DCO and re-flashes the LED, this time at a slow rate. Another button press returns the LaunchPad to the original state, and the program runs through again.
We haven't covered all the features of the DCO yet, and will discuss them as we progress further. Next we'll talk about the use of timers in the MSP430. As always, feel free to discuss and ask questions about what you've read here!
Reader Exercise: My G2211 unit that came with my LaunchPad uses DCO(6,5) for the calibrated 1 MHz frequency on the DCO, and sets the MODx bits to 0b00101 (which is also 5). What does yours use? Write a program that uses the calibrated value and use the debugger to find out what the register settings are for the 1 MHz calibration on your unit. Supposedly, these are set individually to the chip, so I'd be interested to hear if anyone actually has a different value than mine!