//****************************************************************************
// 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
}
//=========================================================================
//=========================================================================