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

// Furnace 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 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;

 

            P1DIR  &= ~(BIT3);              // In - Flame Good

            P1OUT |= BIT3;

            P1SEL  &= ~(BIT3);

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

            P1REN |= BIT3;                      // pullup/pulldown enabled

 

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

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

            P1DIR |= BIT4;

 

            P1DIR &= ~(BIT5);               // In - Diagnostics

            P1OUT |= BIT5;                     // pullup

            P1SEL  &= ~(BIT5);

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

            P1REN |= BIT5;                      // pullup/pulldown enabled

 

            P1SEL  &= ~(BIT6);              // Out - Backchannel Link

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

            P1DIR |= BIT6;                       // Out   P1OUT |= BIT6;

 

            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

                        }

 

// This happens about 124us after 24VAC goes positive

// Now do the switches

 

// First switch input (from Diagnostic LED)  - First time period

                        switches = P1IN & BIT5;                   // check the bit

 

                        if(switches == 0)

                        {

                                    P1OUT &= ~(BIT6);              // First Pulse Out

                        }

                        else  { P1OUT |= BIT6; }

                        wait(TIME);

 

// Now the second switch (from Flame Good LED) - Second time period

                        switches = P1IN & BIT3;

 

                        if(switches == 0)

                        {

                                    P1OUT &= ~(BIT6);              // Second Pulse Out

                        }

                        else  { P1OUT |= BIT6; }

                        wait(TIME);

 

// clear BIT6

                        P1OUT &= ~(BIT6);

            }  // end of main loop

 

            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

}

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

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