Initial msp430 program
authorEugene Crosser <crosser@average.org>
Sun, 10 Dec 2017 22:13:47 +0000 (23:13 +0100)
committerEugene Crosser <crosser@average.org>
Sun, 10 Dec 2017 22:13:47 +0000 (23:13 +0100)
msp430/main.c [new file with mode: 0644]

diff --git a/msp430/main.c b/msp430/main.c
new file mode 100644 (file)
index 0000000..914b865
--- /dev/null
@@ -0,0 +1,222 @@
+#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