// Clock4

//   Calibrates DCO synced to 32.768 KHz crystal (8MHz)

 

// MSP430G25531

// Jed Margolin  3/14/2016.

 

//  Built with Code Composer Studio v6

//***************************************************************************************

// main.c

 

#include <msp430.h>

//#include <msp430G2211.h>

 

#define DELTA_1MHZ    244                       // 244 x 4096Hz = 999.4Hz

#define DELTA_8MHZ    1953                     // 1953 x 4096Hz = 7.99MHz

#define DELTA_12MHZ   2930                    // 2930 x 4096Hz = 12.00MHz

#define DELTA_16MHZ   3906                    // 3906 x 4096Hz = 15.99MHz

 

#define TIME 100

#define DCOUNT 8

 

void wait(unsigned int);

void wait2(void);

void Set_DCO(unsigned int Delta);

//================================================

int main(void)

{

            unsigned char caldata1, caldata2;                  // Temp. storage for constants

            volatile unsigned int k = 0;

 

            WDTCTL = WDTPW + WDTHOLD;           // Stop watchdog timer

 

            wait(150);                                           // give the crystal 500ms to stabilize

 

            P1SEL  |= BIT0;                                 // ACLK

            P1SEL2 &= ~(BIT0);

            P1DIR  |= BIT0;

 

            P1SEL  &= BIT1;                               // In

            P1SEL2 |= BIT1;                                // not used by msp430g2211

            P1REN |= BIT1;                                  // pullup/pulldown enabled

            P1OUT |= BIT1;                                 //

            P1DIR &= ~(BIT1);               // In

 

            P1SEL  &= ~(BIT2);              // Out

            P1SEL2 &= ~(BIT2);             // not used by msp430g2211

            P1DIR |= BIT2;                                   //

 

            P1SEL  &= ~(BIT3);              // Out - for testing

            P1SEL2 &= ~(BIT3);             // not used by msp430g2211

            P1DIR |= BIT3;                                   //

 

            P1SEL  |= BIT4;                                 // Out for SMCLK so we know it's working

            P1SEL2 &= ~(BIT4);             // not used by msp430g2211

            P1DIR |= BIT4;                                   //

 

            P1SEL  &= ~(BIT5);              // In

            P1SEL2 &= ~(BIT5);             // not used by msp430g2211

            P1REN |= BIT5;                                  // pullup/pulldown enabled

            P1OUT |= BIT5;                                 // pullup

            P1DIR &= ~(BIT5);               //

 

            P1SEL  &= ~(BIT6);              // Out

            P1SEL2 &= ~(BIT6);             // not used by msp430g2211

//          P1REN |= BIT6;                                  // pullup/pulldown enabled

//          P1OUT |= BIT6;                                 // pullup

            P1DIR |= (BIT6);                    //

 

            P1SEL  &= ~(BIT7);              // In

            P1SEL2 &= ~(BIT7);             // not used by msp430g2211

            P1REN |= BIT7;                                  // pullup/pulldown enabled

            P1DIR &= ~(BIT7);               // In

            P1OUT |= BIT7;                                 // pullup

 

// Lock the DCO to the 32768 crystal - 8 MHz

            Set_DCO(DELTA_8MHZ);               // Set DCO and obtain constants

            caldata1 = DCOCTL;             // for debugging

            caldata2 = BCSCTL1;

 

            while (1)                                 // main loop

            {

                        P1OUT |= BIT6;

                        wait(TIME);

                        P1OUT &= ~(BIT6);

                        wait(TIME);

            }  // end while main loop

 

} // end main

//==================================

void wait(unsigned int time)              // 500 uS

{

    volatile unsigned int i,j;

 

    for(i=time; i>0; i--)

    {

            for(j=382; j>0; j--);

            {

            }

    }

 

 return;

}

//==========================================================

//==========================================================

void wait2()

{

volatile unsigned int i;

 

            for(i=0; i<48; i++){}

            return;

}

 

//========================================================

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 &= 0xCF;                        // ACLK = LFXT1CLK, DIV 1

}

//=================================================================