/*
* Babby's First MSP430G2xx Program
* Toggle an LED on the Launchpad on button press
*
* Copyright (c) 2011, Chris Sammis (http://csammisrun.net)
* Source released under the MIT License (http://www.opensource.org/licenses/mit-license.php)
*
*/
#include <io.h>
#include <signal.h>
unsigned char ucWdt_Debounce_Pin = 0x00;
void debounce(unsigned char ucPin);
int main()
{
// Stop the watchdog timer
WDTCTL = WDTPW + WDTHOLD; // WDTPW is a Magic Number (MSP430G2XX user guide section 10.3)
// Initialize the clocks
// cstodo what is actually happening here?
BCSCTL1 = CALBC1_1MHZ;
DCOCTL = CALDCO_1MHZ;
BCSCTL2 &= ~DIVS_3;
// Configure output to the Launchpad green LED
P1DIR = BIT6 + BIT0; // Set P1.6 (green LED on Launchpad) to output
P1OUT |= BIT6; // Set P1.6 high to turn on the LED
P1OUT &= ~BIT0; //debug Turn off red LED
// Configure input from the Launchpad switch (P1.3)
P1IE = BIT3; // Enable interrupts from P1.3
P1OUT |= BIT3; // Set P1.3 output to high...
P1REN = BIT3; // ...and then enable the pull resistor (P1OUT.3 high specifies "up")
__bis_SR_register(CPUOFF | GIE); // Switch to LPM0 and enable interrupts
return 0;
}
// General ISR to switch interrupts from P1
interrupt(PORT1_VECTOR) p1_isr()
{
// P1IFG has bits set indicating which pin caused the interrupt
switch (P1IFG)
{
case BIT3:
debounce(BIT3);
// Toggle P1.6's output
P1OUT ^= BIT6;
break;
default:
P1IFG = 0; // Unhandled interrupt, just reset the flag
break;
}
}
// General debounce routines using the WDT
//
// Debouncing disables the input interrupt briefly so that the ISR
// can continue without being re-entered unexpectedly.
void debounce(unsigned char ucPin)
{
P1IFG &= ~ucPin; // Clear the pending interrupt flag corresponding to the pin
P1IE &= ~ucPin; // Disable this interrupt (will be re-enabled at end of debounce)
ucWdt_Debounce_Pin = ucPin; // Store the pin so it can be accessed in the WDT ISR
// Configure the WDT to fire off after SMCLK (1MHz) / 512 = 29ms
WDTCTL = (WDTPW + WDTTMSEL + WDTCNTCL + WDTIS1);
P1OUT |= BIT0; // Debug: Turn on the red LED until the WDT_isr
IFG1 &= ~WDTIFG; // Clear the WDT interrupt flag
IE1 |= WDTIE; // Enable WDT interrupts
}
// WDT interrupt vector: re-enables interrupts on P1.ucWdt_Debounce_Pin
interrupt(WDT_VECTOR) wdt_isr()
{
P1OUT &= ~BIT0; // Debug: Turn off the red LED
IE1 &= ~WDTIE; // Disable the WDT interrupt
IFG1 &= ~WDTIFG; // Clear the WDT interrupt flag
WDTCTL = WDTPW + WDTHOLD; // Stop the WDT again
P1IE |= ucWdt_Debounce_Pin; // Re-enable the interrupts on the debounced pin
}
//eof