]> www.average.org Git - sensor-light.git/blob - msp430/main.c
09b34f84d319d716f6c295a9b1f5af557adaa3f7
[sensor-light.git] / msp430 / main.c
1 #include <msp430.h> 
2
3 static volatile unsigned int ADC_Result;
4 static volatile unsigned int irq_events = 0;
5 enum {ev_btn1 = 0, ev_btn2, ev_pir1, ev_pir2, ev_tmr, ev_adc, ev_MAX};
6
7 int main(void)
8 {
9         int Duty_Cycle = 1;
10         int Increment = 1;
11         unsigned int Time_Count = 0;
12         unsigned int Time_Left = 5;
13
14         WDTCTL = WDTPW | WDTHOLD;       // stop watchdog timer
15         // Configure GPIO Out
16         P1DIR |= BIT0|BIT1|BIT2;        // Set LEDs & PWM to output direction
17         P1OUT &= ~(BIT0|BIT1);          // P1.0&1 LEDs off
18         P1SEL1 |= BIT2;                 // P1.2 PWM out
19
20         // Configure GPIO In
21         P2DIR &= ~(BIT3|BIT7);          // Buttons
22         P2OUT |= BIT3|BIT7;             // Pull up
23         P2REN |= BIT3|BIT7;             // Enable pull-up
24         P2IES |= BIT3|BIT7;             // INT on Hi->Lo edge
25         P2IE  |= BIT3|BIT7;             // INT enable
26
27         P2DIR &= ~(BIT2|BIT5);          // PIR Sensors
28         P2OUT &= ~(BIT2|BIT5);          // Pull down
29         P2REN |= BIT2|BIT5;             // Enable pull-down
30         P2IES &= ~(BIT2|BIT5);          // INT on Lo->Hi edge
31         P2IE  |= BIT2|BIT5;             // INT enable
32
33         // Configure ADC A7 pin
34         SYSCFG2 |= ADCPCTL7;
35
36         // Configure ADC10
37         ADCCTL0 |= ADCSHT_2 | ADCON;    // ADCON, S&H=16 ADC clks
38         ADCCTL1 |= ADCSHP;              // ADCCLK = MODOSC; sampling timer
39         ADCCTL2 |= ADCRES;              // 10-bit conversion results
40         ADCMCTL0 |= ADCINCH_7;          // A7 ADC input select; Vref=AVCC
41         ADCIE |= ADCIE0;                // Enable ADC conv complete interrupt
42
43         // Configure timer A0 for PWM
44         TA0CCR0 = 10000-1;              // PWM Period
45         TA0CCTL2 = OUTMOD_7;            // CCR2 reset/set
46         TA0CCR2 = 500;                  // CCR2 PWM duty cycle
47         TA0CTL = TASSEL__SMCLK | MC__UP | TACLR;        // SMCLK, up mode, clear TAR
48
49         //Configure timer A1 for counting time
50         TA1CTL |= TASSEL__SMCLK | MC__CONTINUOUS | TACLR | TAIE;        // SMCLK, no divider, continuous mode
51
52         // Disable the GPIO power-on default high-impedance mode to activate
53         // previously configured port settings
54         PM5CTL0 &= ~LOCKLPM5;
55
56         while(1)
57         {
58                 unsigned int events;
59
60                 _disable_interrupts();
61                 events = irq_events;
62                 irq_events = 0;
63                 _enable_interrupts();
64
65                 // Button 2 or PIR events initiate light measurement and tuns on green led
66                 if (events & (1<<ev_btn2|1<<ev_pir1|1<<ev_pir2)) {
67                         if (Duty_Cycle > 1) {
68                                 Time_Left = 15;
69                                 continue;
70                         }
71                         ADCCTL0 |= ADCENC | ADCSC;      // Sampling and conversion start
72                         P1OUT |= BIT1;  // Set P1.1 LED on
73                 }
74
75                 // End of light measurement, set new Duty_Cycle and zero increment and tuns off green led
76                 if (events & 1<<ev_adc) {
77                         P1OUT &= ~BIT1; // Clear P1.1 LED off
78                         if (Time_Left)
79                                 continue;
80                         if (ADC_Result < 200)
81                                 continue;
82                         Time_Left = 15;
83                         Increment = 1;
84                 }
85
86                 // Button 1 sets non-zero increment (and toggles it)
87                 if (events & 1<<ev_btn1) {
88                         if (Duty_Cycle > 5000) {
89                                 Time_Left = 0;
90                                 Increment = -1;
91                         } else {
92                                 Time_Left = 15;
93                                 Increment = 1;
94                         }
95                 }
96
97                 // Timer event (100 ms) changed duty cycle and flashes red led
98                 if (events & 1<<ev_tmr) {
99                         if (Time_Count++ > 10) {
100                                 Time_Count = 0;
101                                 P1OUT ^= BIT0;
102                                 if (Time_Left)
103                                         Time_Left--;
104                                 else if (Duty_Cycle > 1)
105                                         Increment = -1;
106                         }
107                         if (Increment == 0)
108                                 continue;
109                         else if (Increment > 0)
110                                 Duty_Cycle *= 2;
111                         else if (Increment < 0)
112                                 Duty_Cycle /= 2;
113                         if (Duty_Cycle < 1) {
114                                 Duty_Cycle = 1;
115                                 Increment = 0;
116                         }
117                         if (Duty_Cycle > (10000-1)) {
118                                 Duty_Cycle = 10000-1;
119                                 Increment = 0;
120                         }
121                         TA0CCR2 = Duty_Cycle;
122                 }
123                 __bis_SR_register(LPM0_bits | GIE);
124                 __no_operation();
125         }
126         return 0; /* not reached */
127 }
128
129 // TIMER interrupt routine
130 #if defined(__TI_COMPILER_VERSION__) || defined(__IAR_SYSTEMS_ICC__)
131 #pragma vector = TIMER1_A1_VECTOR
132 __interrupt void Timer_A (void)
133 #elif defined(__GNUC__)
134 void __attribute__ ((interrupt(TIMER1_A1_VECTOR))) Timer_A (void)
135 #else
136 #error Compiler not supported!
137 #endif
138 {
139         switch(__even_in_range(TA1IV,TA1IV_TAIFG))
140         {
141                 case TA1IV_NONE:
142                         break;  // No interrupt
143                 case TA1IV_TACCR1:
144                         break;  // CCR1 not used
145                 case TA1IV_TACCR2:
146                         break;  // CCR2 not used
147                 case TA1IV_TAIFG:
148                         irq_events |= 1<<ev_tmr;
149                         __bic_SR_register_on_exit(LPM0_bits);   // Clear CPUOFF bit from LPM0
150                         break;
151                 default:
152                         break;
153         }
154         //if (Time_Count++ > 1000) {
155         //    Time_Count = 0;
156         //    __bic_SR_register_on_exit(LPM0_bits);     // Clear CPUOFF bit from LPM0
157         //}
158 }
159
160 // ADC interrupt service routine
161 #if defined(__TI_COMPILER_VERSION__) || defined(__IAR_SYSTEMS_ICC__)
162 #pragma vector=ADC_VECTOR
163 __interrupt void ADC_ISR(void)
164 #elif defined(__GNUC__)
165 void __attribute__ ((interrupt(ADC_VECTOR))) ADC_ISR (void)
166 #else
167 #error Compiler not supported!
168 #endif
169 {
170         switch(__even_in_range(ADCIV,ADCIV_ADCIFG))
171         {
172                 case ADCIV_NONE:
173                         break;
174                 case ADCIV_ADCOVIFG:
175                         break;
176                 case ADCIV_ADCTOVIFG:
177                         break;
178                 case ADCIV_ADCHIIFG:
179                         break;
180                 case ADCIV_ADCLOIFG:
181                         break;
182                 case ADCIV_ADCINIFG:
183                         break;
184                 case ADCIV_ADCIFG:
185                         ADC_Result = ADCMEM0;
186                         irq_events |= 1<<ev_adc;
187                         __bic_SR_register_on_exit(LPM0_bits);   // Clear CPUOFF bit from LPM0
188                         break;
189                 default:
190                         break;
191         }
192 }
193
194 // GPIO interrupt service routine
195 #if defined(__TI_COMPILER_VERSION__) || defined(__IAR_SYSTEMS_ICC__)
196 #pragma vector=PORT2_VECTOR
197 __interrupt void Port_2(void)
198 #elif defined(__GNUC__)
199 void __attribute__ ((interrupt(PORT2_VECTOR))) Port_2 (void)
200 #else
201 #error Compiler not supported!
202 #endif
203 {
204         if (P2IFG & BIT3) {
205                 irq_events |= 1<<ev_btn1;
206                 P2IFG &= ~BIT3; // Clear P1.3 IFG
207         }
208         if (P2IFG & BIT7) {
209                 irq_events |= 1<<ev_btn2;
210                 P2IFG &= ~BIT7; // Clear P1.3 IFG
211         }
212         if (P2IFG & BIT2) {
213                 irq_events |= 1<<ev_pir1;
214                 P2IFG &= ~BIT2; // Clear P1.4 IFG
215         }
216         if (P2IFG & BIT5) {
217                 irq_events |= 1<<ev_pir2;
218                 P2IFG &= ~BIT5; // Clear P1.7 IFG
219         }
220         __bic_SR_register_on_exit(LPM3_bits);   // Exit LPM3
221 }