23 October 2011

Tutorial 16c: Accurate Clocks

Perfectly synchronized clocks can measure the bits
anywhere in the middle.
Clock Accuracy
So just how accurate does a clock need to be for UART? First, consider a perfect pair of clocks, each operating at exactly the same frequency. In this case, it doesn't much matter where we measure the incoming bits, as long as we measure after the bit has changed to the next one. If there's some error, however, a slow clock will measure later and later, until it missed a bit completely. A fast clock will likewise measure earlier and earlier, until it measures the same bit twice. Not knowing before hand if your clock is fast or slow, it makes sense to shoot for the middle of the bit; that way you have as much time as possible before the error takes over and you make a mistake.

Errors can add up very quickly when there are
small differences between clocks.
Looking at the plot on the left, using clocks that are off by only 6%, notice where the first problem occurs: bit 9 is completely skipped! Using these clocks, we can't even reliably send one frame of data! (By the way, this type of transmission error is classified as a frame error.) My choice of 6% for this plot isn't arbitrary; the error quoted in the datasheets for the MSP430 give the calibrated DCO frequencies (calibrated, mind you; not just the DCO in general) a tolerance over temperature and any other changes of ±3%. If we use calibrated DCO as the clock for both sender and receiver, we could feasibly have as much as a 6% error, making UART transmission completely unreliable!

In reality, not all hope is lost; this is a worst case scenario, and likely the clock in your computer (assuming you want to communicate with it instead of another MSP430) is more accurate than that. A total of 5% tolerance between the clocks would, on average, encounter a frame error on bit 11, and 4% tolerance on bit 13, so as long as we have better tolerance than that and have a short gap between frames to "resynchronize", we should be able to communicate. Note this does mean we are limited in the frame sizes we can use reliably, and our actual data transmission rate will be a little less since we need a recovery between frames. If you want fast communication, you need an accurate clock!

Crystal Oscillators
The best option for accuracy in a clock is to use a crystal. The watch crystal that comes with the LaunchPad is accurate over a wide temperature range to 20 ppm (0.002%)! There are some disadvantages, however: crystals take a while to stabilize, and use more power. In addition, at 32,768 Hz, we can't achieve very high transmission rates. Typically we want at least 16 clock cycles per bit to accurately catch the start bit and start sampling at the center of each bit. Using that rule of thumb, the highest bit rate we could attain with the watch crystal is 2048 baud. Larger MSP430 devices allow for high frequency crystals, but the G2xx series that are compatible with the LaunchPad do not. However, if we're careful, getting transmission rates up to 9600 baud with the watch crystal can be done.

Soldering the crystal to your LaunchPad might seem a daunting task with such a small part, but in reality it's not terribly difficult. A little bit of patience (mostly in the form of a little piece of masking tape) is all you need. Aside from a soldering iron and solder, of course. If you have not already put a crystal on your LaunchPad and would like to, there are a number of good demonstrations of the technique for soldering the crystal to the board available on YouTube. For now, I'll assume you've successfully put it on.

You may have noticed a couple of empty pads near the crystal for capacitors. For a crystal to oscillate at the right frequency, it needs to see a particular capacitance to ground. If the capacitance is off, the frequency may be off, or the crystal may not oscillate at all. The crystal included in the LaunchPad kit wants to see 12.5 pF. The MSP430 crystal inputs also have user-selectable capacitances internal to the device. The user can select from 1, 6, 10, and 12.5 pF as the effective capacitance seen by the crystal. (The device defaults to 6 pF.) The selection is done by the two XCAPx bits in the BCSCTL3 register.

If for some reason you need a capacitance other than one of these, you can solder the proper capacitors to the pads on the outside. Unfortunately, it's not as easy as putting 12.5 pF capacitors on the pads; the capacitors you put on will be in parallel with the capacitance from the traces and the chip itself. The formula for calculating the right load capacitors is: C1 = C2 = 2*C_Load - (Cp + Ci). C_Load would be whatever capacitance the crystal expects to see, Cp any parasitic capacitance from traces etc., and Ci the Capacitance of the MSP430 device. The last two terms can be assumed to be whatever is set in XCAPx. So for a crystal that wants 18 pF, you would want to put 30 pF capacitors on the board (using the default 6 pF).

Most of what's needed to use the watch crystal is set as the default values in the BCS+ module. To use the supplied crystal, you really only need two lines:

BCSCTL3 |= XCAP_3;       // 12.5 pF for LaunchPad crystal
__delay_cycles(55000);   // let crystal stabilize

The first line sets up the proper capacitance for your crystal, and should be changed if you're using a different capacitance value. The second line lets enough time pass for the crystal to stabilize at the operating frequency. How long do you really need to wait? Typically you need a few hundreds of milliseconds. The above code will wait for 55000 clock cycles; at the default DCO of 1.1 MHz, that's about 50 milliseconds. Depending on your application, you can wait longer if necessary.

Self-Calibrating the DCO
If you're paying attention, you might have spotted another problem with the watch crystal: how do we get a standard clock rate from the crystal? 9600 baud is 3.41 clock cycles. 1200 baud uses more clock cycles, so is more reliable, but it's still 27.31 clock cycles. The closest division we can get is 27 clock cycles, which would correspond to 1213.6 baud, an error of 1.1%. It seems we've lost a lot of the accuracy we gained using the crystal! There are crystals available that divide perfectly into the standard baud rates. A 7.3728 MHz crystal, for example, has exactly 768 clock cycles per bit for 9600 baud. If you use an MSP430 device that allows for a high frequency crystal, this is an excellent choice for serial communication at standard rates. Another option, however, is to use the DCO.

But wait, didn't we just argue that the calibrated values of the DCO are too large to be reliable? Yes, but under certain circumstances we can do better. For one, the error margins quoted in the data sheet cover both the entire temperature range where the MSP430 can be used-- from -40° to 85°F-- and the entire range of voltages at which it can operate-- from 1.8 to 3.6 V. Generally we won't be operating in such extremes. Even if we are, as long as the temperature and operating voltage aren't going to change too much during operation, we can recalibrate the DCO to that particular configuration! The accuracy of the clock will be much better than the quoted 3% in this case; the datasheet even specifies that from 0° to 85°F, the calibration is good to 0.5% at 3 V. (Obviously a consistent voltage is the real key to a stable DCO.)

Calibrating the DCO is quite simple, but it requires a very accurate clock to compare the DCO against; this is a job for a crystal. The idea is simple-- use the crystal to time an accurate interval (say 1 s.) We know how many oscillations should occur for a given frequency in that interval, so we adjust the DCO until we get as close to that as we can get. Then we save the values for DCOCTL and BCSCTL1, and we have an accurate calibration for our clock! Here's how all the magic happens:


void Set_DCO(unsigned int Delta) {    // Set DCO to selected
                                      // frequency
  unsigned int Compare, Oldcapture = 0;


  BCSCTL1 |= DIVA_3;                  // ACLK = LFXT1CLK/8
  TACCTL0 = CM_1 + CCIS_1 + CAP;      // CAP, ACLK
  TACTL = TASSEL_2 + MC_2 + TACLR;    // SMCLK, cont-mode, clear


  while (1) {
    while (!(CCIFG & TACCTL0));       // Wait until capture     
                                      // occured
    TACCTL0 &= ~CCIFG;                // Capture occured, clear 
                                      // flag
    Compare = TACCR0;                 // Get current captured 
                                      // SMCLK
    Compare = Compare - Oldcapture;   // SMCLK difference
    Oldcapture = TACCR0;              // Save current captured 
                                      // SMCLK


    if (Delta == Compare)
      break;                          // If equal, leave  
                                      // "while(1)"
    else if (Delta < Compare) {
      DCOCTL--;                       // DCO is too fast, slow 
                                      // it down
      if (DCOCTL == 0xFF)             // Did DCO roll under?
        if (BCSCTL1 & 0x0f)
          BCSCTL1--;                  // Select lower RSEL
    }
    else {
      DCOCTL++;                       // DCO is too slow, speed 
                                      // it up
      if (DCOCTL == 0x00)             // Did DCO roll over?
        if ((BCSCTL1 & 0x0f) != 0x0f)
          BCSCTL1++;                  // Sel higher RSEL
    }
  }
  TACCTL0 = 0;                        // Stop TACCR0
  TACTL = 0;                          // Stop Timer_A
  BCSCTL1 &= ~DIVA_3;                 // ACLK = LFXT1CLK
}

This code comes from the dco_flashcal.c example code available with most of the MSP430 devices. The example code file for the G2xx1 devices seems to not have it; I copied this from the F21x2 examples and changed TACCTL2 to TACCTL0 to be compatible with LaunchPad devices.

It's a bit of code to sort through, but it turns out to be straightforward. ACLK is configured to use the watch crystal divided by 8-- 4096 Hz. The timer is set to capture mode, triggering off a rising edge of CCI0B. (From the G2231 or G2211 datasheets, this corresponds to ACLK. If these terms seem confusing, review the tutorial on the capacitance meter which used the capture mode.) The timer itself is running off SMCLK, sourced by the DCO. If we want to calibrate 2 MHz, then in one clock cycle of ACLK, we expect 2 MHz/ 4096 Hz = 488.3 SMCLK cycles. We pass the value 488 to this routine, which starts the clocks and timers. When a capture occurs, it checks to see if more or fewer cycles of SMCLK have happened, and adjusts DCO and RSEL accordingly. It repeats this, until it finds the configuration that returns exactly 488 cycles in the interval. The values in DCO and RSEL are then the calibration values we want to save; we just look at the DCOCTL and BCSCTL1 registers and save their values for future use.

This routine is used in the example code found in DCOcalibrate.c. Try it out (with the crystal soldered on, of course), and see what values are obtained for DCOCTL and BCSCTL1 for each frequency it calibrates. If you happen to have an oscilloscope, measure them on P1.4 to see if they're right. (The code finishes on the last calibration done; you can modify the code to end with the one you want to measure, or add code to change to the frequency you want to see.) You can write these values down for future reference, but next time we'll look briefly at writing to the flash memory in the MSP430 so you can save it for use later on!

Reader Exercises:  How good is the calibration done in the factory? Modify the code to find the calibration values for 1 MHz. How do they compare to the values stored in CALDCO_1MHZ and CALBC1_1MHZ? It seems many have reported that the 1 MHz calibration from the factory, at least for early batch runs of the value line devices, is closer to 980 kHz.


How much does temperature affect the results? Place your LaunchPad somewhere warm for a while (or cold; a freezer might not be best, though-- too much water around!) and re-run the code. How much difference is there in the calibration values?


Could you use a calibrated frequency to go the other direction and measure the crystal frequency? Imagine doing an experiment to see how the four XCAPx settings might affect the crystal. Which ones oscillate? How much does the frequency change if you use 10 pF instead of 12.5 pF? See if you can write some code to find out!

7 comments:

Anonymous said...

where is function delay(cycles) for msp430 launchpad.
Do I need a header file for this.

Unknown said...

If you're using CCS, it should be built in for you.

I just realized that I used it in the tutorial, but not in the example code. The for loop in the example code can be replaced by a __delay_cycles() loop of appropriate length.

Pinkerton Wells said...

Have a look at the Wikipedia entry for UART. You'll learn that the "A" in UART stands for Asynchronous ... and how The Old Ones managed to do serial communication without high precision clocks.

Unknown said...

Pinkerton: Thanks for pointing that out; as I understand it, asynchronous means they don't have to be using the same clocks, but rather have their own independent clocks. They may not count seconds at the same time, but they do need to do it at the same rate. It is really cool how they can get around the error in timings, of course. It gets much more difficult the more bits you send in a single word-- using the standard 8N1, of course, you can get around the timing errors much more easily. 16N1 might be trickier. =)

I only bring this up because of the "U"-- universal. UART is not (nor does not have to be) 8N1. That's simply one protocol that can be done in UART.

Scientific Instruments said...

I’ve seen progression in every post. Your newer posts are simply wonderful compared to your posts in the past. Keep up the good work.

Unknown said...

Hello David,

There are some things that I am not sure about them with this code:
1) When you "BCSCTL1++" you change all of the bits of BCSCTL1 where some of them changing different things that should not be change (the ACLK divider for example).
2) It's looks like you waiting for an exact match between "Compare" and "Delta". When thinking about the different clocks and their accuracy it's looks like the condition that should be met have to be "Delta - Epsilon < Compare < Delta + Epsilon".

I just finished to write code that take this two issues into consideration. And I've found interesting results.

I will appreciate if you can take a look and tell me what you think:
http://dl.dropbox.com/u/13390055/DcoCalibrate.c

And again
Thanks a lot for your great job!
(I'm waiting to know how to donate...)

Tom

Unknown said...

Tom,

Those are excellent points. Using the increment operator actually works in this case, because the bits being changed in BCSCTL1 to adjust the frequency are the lowest 4 bits (RSELx are bits 0-3 in BCSCTL1). The code actually does protect against overshooting these bits, in the line that does the comparison just before the increment operator:
if ((BCSCTL1 & 0x0f) != 0x0f)

As for an exact comparison as opposed to an epsilon comparison, I think you may have the right idea. I think the exact comparison was used here because we're comparing an integer number of clock cycles. You won't be able to get the exact frequency, because of the discrete steps, of course. But the closest value to your desired frequency will be an integer number of clock cycles. In theory, there should be some combination of DCOCTL and BCSCTL1 that gives that value.

One word of caution about using an epsilon range: you might find it settling on a frequency near, but not as close as it could be, to your target. If epsilon is wide enough that multiple combinations fall in range, you might not get as accurate of a calibration as you'd like.

I'll take a look over your code, and if I have any other comments, I'll let you know!

PS: I'm not sure about the legal issues of taking donations; it's something I'd have to look into. In the mean time, the companies advertising here do appreciate the traffic, and especially purchases made there. Thanks for your generosity!