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

// Thermostat Adapter 15

//

// Jed Margolin  3/14/2016.

//

//  MSP430G2211

//  Built with Code Composer Studio v6

//  Calibrate DCO at 1MHz to the 32.768 KHz crystal

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

#include <msp430.h>

//#include <msp430G2211.h>

 

// main.c

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

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

#define TIME 6

#define DCOUNT 8

 

void Set_DCO(unsigned int Delta);

void wait(unsigned int);

 

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

 

int main(void)

{

int count;

unsigned char switches;

 

            WDTCTL = WDTPW | WDTHOLD; // Stop watchdog timer

 

            wait(1000);                                                     // give crystal 500ms to stabilize

 

            P1SEL  |= BIT0;                     // ACLK

//          P1SEL2 &= ~(BIT0);             // g2211 doesn't have it

            P1DIR  |= BIT0;

 

            P1SEL  &= ~(BIT2);              // Out for testing

//          P1SEL2 &= ~(BIT2);             // g2211 doesn't have it

            P1DIR |= BIT2;

 

            P1SEL  &= ~(BIT3);              // Out - Flame Good LED

//          P1SEL2 &= ~(BIT3);             // g2211 doesn't have it

            P1DIR |= BIT3;

 

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

//          P1SEL2 &= ~(BIT4);             // g2211 doesn't have it

            P1DIR |= BIT4;

 

            P1SEL  &= ~(BIT5);              // Out - Diagnostics LED

//          P1SEL2 &= ~(BIT5);             // g2211 doesn't have it

            P1DIR |= BIT5;

 

            P1DIR &= ~(BIT6);               // In - Backchannel link

            P1OUT |= BIT6;                     // pullup

            P1SEL  &= ~(BIT6);

//          P1SEL2 &= ~(BIT6);             // g2211 doesn't have it

            P1REN |= BIT6;                      // pullup/pulldown enabled

 

            P1DIR &= ~(BIT7);               // In - 60Hz phase

            P1OUT |= BIT7;                     // pullup

            P1SEL  &= ~(BIT7);

//          P1SEL2 &= ~(BIT7);             // g2211 doesn't have it

            P1REN |= BIT7;                      // pullup/pulldown enabled

 

            switches = 0x00;

 

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

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

              caldata1 = DCOCTL;                       // for debugging, two bytes at 0x200

              caldata2 = BCSCTL1;

 

// This is the Main Loop

              for(;;)

              {

 

// wait for one (negative 24VAC half-wave)

                        count = DCOUNT;

                        for(;;)

                        {

                                    switches = P1IN & BIT7;                   // Read the pin

 

                                    if(switches == BIT7)  {count--;}

                                    else {count = DCOUNT;}                  // reset the count

 

                                    if(count == 0) {break;}                      // we have a one

                        }

 

// wait for zero (positive 24VAC half-wave)

                        count = DCOUNT;

                        for(;;)

                        {

                                    switches = P1IN & BIT7;                   // Read the pin

 

                                    if(switches == 0)        {count--;}

                                    else {count = DCOUNT;}                  // reset the count

 

                                    if(count == 0) {break;}                      // we have a zero

                        }

 

// We have sync

// Now read the datastream

// Strobe Test Flag

                        P1OUT |= BIT2;                                 // turn on strobe

                        P1OUT &= ~(BIT2);                          // turn off strobe

 

// wait half-bit time

                        wait(3);

 

                        // Read Bit 6 (G')

                        switches = P1IN & BIT6;                   // check the bit

 

                        if(switches == 0)

                        {

                                    P1OUT &= ~(BIT5);              // turn on LED1

                        }

                        else  { P1OUT |= BIT5; }                   // turn off LED1

 

                        // Strobe Test Flag

                        P1OUT |= BIT2;                                 // turn on strobe

                        P1OUT &= ~(BIT2);                          // turn off strobe

 

// Do second bit

                        wait(6);                                               // wait for middle of second bit

 

// Read Bit 6 (G')

                        switches = P1IN & BIT6;                   // check the bit

 

                        if(switches == 0)

                        {

                                    P1OUT &= ~(BIT3);              // turn on LED2

                        }

                        else  { P1OUT |= BIT3; }                   // turn off LED2

 

// Strobe Test Flag

                        P1OUT |= BIT2;                                 // turn on strobe

                        P1OUT &= ~(BIT2);                          // turn off strobe

 

            }  // end main for

 

            return(0);

 

} // end main

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

void wait(unsigned int time)              // 500 uS

{

    volatile unsigned int i,j;

 

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

    {

            for(j=48; j>0; j--);{}

    }

            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 &= ~DIVA_3;                // ACLK is divide by 1

}

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