--- /dev/null
+#include <msp430.h> \r
+\r
+static volatile unsigned int ADC_Result;\r
+static volatile unsigned int irq_events = 0;\r
+enum {ev_btn1 = 0, ev_btn2, ev_pir1, ev_pir2, ev_tmr, ev_adc, ev_MAX};\r
+\r
+int main(void)\r
+{\r
+ int Duty_Cycle = 1;\r
+ int Increment = 1;\r
+ unsigned int Time_Count = 0;\r
+ unsigned int Time_Left = 5;\r
+\r
+ WDTCTL = WDTPW | WDTHOLD; // stop watchdog timer\r
+ // Configure GPIO Out\r
+ P1DIR |= BIT0|BIT1|BIT2; // Set P1.0&1&2/LEDs to output direction\r
+ P1OUT &= ~(BIT0|BIT1); // P1.0&1 LEDs off\r
+ P1SEL1 |= BIT2; // P1.2 PWM out\r
+\r
+ // Configure GPIO In\r
+ P2DIR &= ~(BIT3|BIT7); // Buttons\r
+ P2OUT |= BIT3|BIT7; // Pull up\r
+ P2REN |= BIT3|BIT7; // Enable pull-up\r
+ P2IES |= BIT3|BIT7; // INT on Hi->Lo edge\r
+ P2IE |= BIT3|BIT7; // INT enable\r
+\r
+ P2DIR &= ~(BIT2|BIT5); // PIR Sensors\r
+ P2OUT &= ~(BIT2|BIT5); // Pull down\r
+ P2REN |= BIT2|BIT5; // Enable pull-down\r
+ P2IES &= ~(BIT2|BIT5); // INT on Lo->Hi edge\r
+ P2IE |= BIT2|BIT5; // INT enable\r
+ P2IFG = 0; // ??? Needed?\r
+\r
+ // Configure ADC A7 pin\r
+ SYSCFG2 |= ADCPCTL7;\r
+\r
+ // Configure ADC10\r
+ ADCCTL0 |= ADCSHT_2 | ADCON; // ADCON, S&H=16 ADC clks\r
+ ADCCTL1 |= ADCSHP; // ADCCLK = MODOSC; sampling timer\r
+ ADCCTL2 |= ADCRES; // 10-bit conversion results\r
+ ADCMCTL0 |= ADCINCH_7; // A7 ADC input select; Vref=AVCC\r
+ ADCIE |= ADCIE0; // Enable ADC conv complete interrupt\r
+\r
+ // Configure timer A0 for PWM\r
+ TA0CCR0 = 10000-1; // PWM Period\r
+ TA0CCTL2 = OUTMOD_7; // CCR2 reset/set\r
+ TA0CCR2 = 500; // CCR2 PWM duty cycle\r
+ TA0CTL = TASSEL__SMCLK | MC__UP | TACLR; // SMCLK, up mode, clear TAR\r
+\r
+ //Configure timer A1 for counting time\r
+ TA1CTL |= TASSEL__SMCLK | MC__CONTINUOUS | TACLR | TAIE; // SMCLK, no divider, continuous mode\r
+\r
+ // Disable the GPIO power-on default high-impedance mode to activate\r
+ // previously configured port settings\r
+ PM5CTL0 &= ~LOCKLPM5;\r
+\r
+ while(1)\r
+ {\r
+ unsigned int events;\r
+\r
+ _disable_interrupt();\r
+ events = irq_events;\r
+ irq_events = 0;\r
+ _enable_interrupt();\r
+\r
+ // Button 2 or PIR events initiate light measurement and turns on green led\r
+ if (events & (1<<ev_btn2|1<<ev_pir1|1<<ev_pir2)) {\r
+ if (Duty_Cycle > 1) {\r
+ Time_Left = 15;\r
+ continue;\r
+ }\r
+ ADCCTL0 |= ADCENC | ADCSC; // Sampling and conversion start\r
+ P1OUT |= BIT1; // Set P1.1 LED on\r
+ }\r
+\r
+ // End of light measurement, set new Duty_Cycle and zero increment and turns off green led\r
+ if (events & 1<<ev_adc) {\r
+ P1OUT &= ~BIT1; // Clear P1.1 LED off\r
+ if (Time_Left)\r
+ continue;\r
+ if (ADC_Result < 200)\r
+ continue;\r
+ Time_Left = 15;\r
+ Increment = 1;\r
+ }\r
+\r
+ // Button 1 sets non-zero increment (and toggles it)\r
+ if (events & 1<<ev_btn1) {\r
+ if (Duty_Cycle > 5000) {\r
+ Time_Left = 0;\r
+ Increment = -1;\r
+ } else {\r
+ Time_Left = 15;\r
+ Increment = 1;\r
+ }\r
+ }\r
+\r
+ // Timer event (100 ms) changed duty cycle and flashes red led\r
+ if (events & 1<<ev_tmr) {\r
+ if (Time_Count++ > 10) {\r
+ Time_Count = 0;\r
+ P1OUT ^= BIT0;\r
+ if (Time_Left)\r
+ Time_Left--;\r
+ else if (Duty_Cycle > 1)\r
+ Increment = -1;\r
+ }\r
+ if (Increment == 0)\r
+ continue;\r
+ else if (Increment > 0)\r
+ Duty_Cycle *= 2;\r
+ else if (Increment < 0)\r
+ Duty_Cycle /= 2;\r
+ if (Duty_Cycle < 1) {\r
+ Duty_Cycle = 1;\r
+ Increment = 0;\r
+ }\r
+ if (Duty_Cycle > (10000-1)) {\r
+ Duty_Cycle = 10000-1;\r
+ Increment = 0;\r
+ }\r
+ TA0CCR2 = Duty_Cycle;\r
+ }\r
+ __bis_SR_register(LPM0_bits | GIE);\r
+ __no_operation();\r
+ }\r
+ return 0; /* not reached */\r
+}\r
+\r
+// TIMER interrupt routine\r
+#if defined(__TI_COMPILER_VERSION__) || defined(__IAR_SYSTEMS_ICC__)\r
+#pragma vector = TIMER1_A1_VECTOR\r
+__interrupt void Timer_A (void)\r
+#elif defined(__GNUC__)\r
+void __attribute__ ((interrupt(TIMER1_A1_VECTOR))) Timer_A (void)\r
+#else\r
+#error Compiler not supported!\r
+#endif\r
+{\r
+ switch(__even_in_range(TA1IV,TA1IV_TAIFG))\r
+ {\r
+ case TA1IV_NONE:\r
+ break; // No interrupt\r
+ case TA1IV_TACCR1:\r
+ break; // CCR1 not used\r
+ case TA1IV_TACCR2:\r
+ break; // CCR2 not used\r
+ case TA1IV_TAIFG:\r
+ irq_events |= 1<<ev_tmr;\r
+ __bic_SR_register_on_exit(LPM0_bits); // Clear CPUOFF bit from LPM0\r
+ break;\r
+ default:\r
+ break;\r
+ }\r
+ //if (Time_Count++ > 1000) {\r
+ // Time_Count = 0;\r
+ // __bic_SR_register_on_exit(LPM0_bits); // Clear CPUOFF bit from LPM0\r
+ //}\r
+}\r
+\r
+// ADC interrupt service routine\r
+#if defined(__TI_COMPILER_VERSION__) || defined(__IAR_SYSTEMS_ICC__)\r
+#pragma vector=ADC_VECTOR\r
+__interrupt void ADC_ISR(void)\r
+#elif defined(__GNUC__)\r
+void __attribute__ ((interrupt(ADC_VECTOR))) ADC_ISR (void)\r
+#else\r
+#error Compiler not supported!\r
+#endif\r
+{\r
+ switch(__even_in_range(ADCIV,ADCIV_ADCIFG))\r
+ {\r
+ case ADCIV_NONE:\r
+ break;\r
+ case ADCIV_ADCOVIFG:\r
+ break;\r
+ case ADCIV_ADCTOVIFG:\r
+ break;\r
+ case ADCIV_ADCHIIFG:\r
+ break;\r
+ case ADCIV_ADCLOIFG:\r
+ break;\r
+ case ADCIV_ADCINIFG:\r
+ break;\r
+ case ADCIV_ADCIFG:\r
+ ADC_Result = ADCMEM0;\r
+ irq_events |= 1<<ev_adc;\r
+ __bic_SR_register_on_exit(LPM0_bits); // Clear CPUOFF bit from LPM0\r
+ break;\r
+ default:\r
+ break;\r
+ }\r
+}\r
+\r
+// GPIO interrupt service routine\r
+#if defined(__TI_COMPILER_VERSION__) || defined(__IAR_SYSTEMS_ICC__)\r
+#pragma vector=PORT2_VECTOR\r
+__interrupt void Port_2(void)\r
+#elif defined(__GNUC__)\r
+void __attribute__ ((interrupt(PORT2_VECTOR))) Port_2 (void)\r
+#else\r
+#error Compiler not supported!\r
+#endif\r
+{\r
+ if (P2IFG & BIT3) {\r
+ irq_events |= 1<<ev_btn1;\r
+ P2IFG &= ~BIT3; // Clear P1.3 IFG\r
+ }\r
+ if (P2IFG & BIT7) {\r
+ irq_events |= 1<<ev_btn2;\r
+ P2IFG &= ~BIT7; // Clear P1.3 IFG\r
+ }\r
+ if (P2IFG & BIT2) {\r
+ irq_events |= 1<<ev_pir1;\r
+ P2IFG &= ~BIT2; // Clear P1.4 IFG\r
+ }\r
+ if (P2IFG & BIT5) {\r
+ irq_events |= 1<<ev_pir2;\r
+ P2IFG &= ~BIT5; // Clear P1.7 IFG\r
+ }\r
+ __bic_SR_register_on_exit(LPM3_bits); // Exit LPM3\r
+}\r