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