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};
9 #define LIGHT_THRESHOLD 600
12 #ifdef ADCSC /* Let us hope that this is a "new" model */
15 # define PBTN(x) P2##x
18 # define BIT_BTN2 BIT7
22 # define PBTN(x) P1##x
27 static int expon2(int duty)
31 int extra = (duty & 1) ? comp>>1 : 0;
32 return (duty ? comp|extra : 0);
39 unsigned int Time_Count = 0;
40 unsigned int Time_Left = 5;
41 unsigned int Time_Indicate = 2;
43 WDTCTL = WDTPW | WDTHOLD; // stop watchdog timer
45 P1DIR |= BIT_RL|BIT_GL|BIT2; // Set LEDs & PWM to output direction
46 P1OUT &= ~(BIT_RL|BIT_GL); // LEDs off
48 P1SEL1 |= BIT2; // PWM out
50 P1SEL |= BIT2; // PWM out
54 PBTN(DIR) &= ~(BIT_BTN|BIT_BTN2); // Buttons
55 PBTN(OUT) |= BIT_BTN|BIT_BTN2; // Pull up
56 PBTN(REN) |= BIT_BTN|BIT_BTN2; // Enable pull-up
57 PBTN(IES) |= BIT_BTN|BIT_BTN2; // INT on Hi->Lo edge
58 PBTN(IE) |= BIT_BTN|BIT_BTN2; // INT enable
60 P2DIR &= ~(BIT4|BIT5); // PIR Sensors
61 P2OUT &= ~(BIT4|BIT5); // Pull down
62 P2REN |= BIT4|BIT5; // Enable pull-down
63 P2IES &= ~(BIT4|BIT5); // INT on Lo->Hi edge
64 P2IE |= BIT4|BIT5; // INT enable
68 #ifdef ADCPCTL4 /* Newer model */
69 SYSCFG2 |= ADCPCTL4|ADCPCTL5; // disconnect pin 4 and 5 from GPIO
70 ADCCTL0 |= ADCSHT_2 | ADCON; // ADCON, S&H=16 ADC clks
71 ADCCTL1 |= ADCSHP; // ADCCLK = MODOSC; sampling timer
72 ADCCTL2 |= ADCRES; // 10-bit conversion results
73 ADCMCTL0 |= ADCINCH_4; // A4 ADC input select; Vref=AVCC
74 ADCIE |= ADCIE0; // Enable ADC conv complete interrupt
75 // channel 5 is unused, reserved for measuring current
77 ADC10CTL0 = ADC10SHT_2 + ADC10ON + ADC10IE; // ADCON, S&H=16 ADC clks
78 ADC10CTL1 = INCH_4; // A4 ADC input select
79 // channel 5 is unused, reserved for measuring current
85 # define TASSEL__SMCLK TASSEL_2
87 # define MC__CONTINUOUS MC_2
88 # define TA0CCR2 TA0CCR1
89 # define TA0CCTL2 TA0CCTL1
92 // Configure timer A0 for PWM
93 TA0CCR0 = 1 << PWM_ORDER; // PWM Period 2^10 ca. 1 kHz
94 TA0CCR2 = 0; // CCR1 PWM duty cycle
95 TA0CCTL2 = OUTMOD_7; // CCR1 reset/set
96 TA0CTL = TASSEL__SMCLK | MC__UP | TACLR;// SMCLK, up mode
97 // SMCLK, no divider, up mode, no interrupt, clear TAR
99 //Configure timer A1 for counting time
100 TA1CTL |= TASSEL__SMCLK | MC__CONTINUOUS | TACLR | TAIE;
101 // SMCLK, no divider, continuous mode, interrupt enable
104 // Disable the GPIO power-on default high-impedance mode to activate
105 // previously configured port settings
106 PM5CTL0 &= ~LOCKLPM5;
113 _disable_interrupts();
116 _enable_interrupts();
118 // Button 2 or PIR events initiate light measurement
119 // and tuns on green or red led
120 if (events & (1<<ev_btn2|1<<ev_pir1|1<<ev_pir2)) {
121 if (events & 1<<ev_pir1)
122 P1OUT |= BIT_GL; // Set green LED on
123 if (events & 1<<ev_pir2)
124 P1OUT |= BIT_RL; // Set red LED on
125 // Sampling and conversion start
127 ADCCTL0 |= ADCENC | ADCSC;
129 ADC10CTL0 |= ENC + ADC10SC;
133 // End of light measurement. Set new Duty_Cycle,
134 // zero increment and turn off green led
135 if (events & 1<<ev_adc) {
136 P1OUT ^= (BIT_GL|BIT_RL); // Flip green and red LEDs
138 if (ADC_Result < LIGHT_THRESHOLD)
144 // Button 1 sets non-zero increment (and toggles it)
145 if (events & 1<<ev_btn1) {
146 P1OUT |= (BIT_GL|BIT_RL); // Set green and red LEDs on
148 if (Duty_Cycle > PWM_HALF) {
157 // Timer event (100 ms) changed duty cycle and flashes red led
158 if (events & 1<<ev_tmr) {
162 P1OUT &= ~(BIT_RL|BIT_GL); // LEDs off
164 if (Time_Count++ > 10) {
168 else if (Duty_Cycle > 1)
172 if (++Duty_Cycle >= (PWM_ORDER<<1)) {
173 Duty_Cycle = PWM_ORDER<<1;
176 } else if (Increment < 0) {
177 if (--Duty_Cycle < 1) {
184 TA0CCR2 = expon2(Duty_Cycle);
186 __bis_SR_register(LPM0_bits | GIE);
189 return 0; /* not reached */
192 // TIMER interrupt routine
193 #if defined(__TI_COMPILER_VERSION__) || defined(__IAR_SYSTEMS_ICC__)
194 #pragma vector = TIMER1_A1_VECTOR
195 __interrupt void Timer_A (void)
196 #elif defined(__GNUC__)
197 void __attribute__ ((interrupt(TIMER1_A1_VECTOR))) Timer_A (void)
199 #error Compiler not supported!
202 switch(__even_in_range(TA1IV,TA1IV_TAIFG))
205 break; // No interrupt
207 break; // CCR1 not used
209 break; // CCR2 not used
211 irq_events |= 1<<ev_tmr;
212 __bic_SR_register_on_exit(LPM0_bits); // Wake up
220 # define ADCMEM0 ADC10MEM
221 # define ADC_VECTOR ADC10_VECTOR
224 // ADC interrupt service routine
225 #if defined(__TI_COMPILER_VERSION__) || defined(__IAR_SYSTEMS_ICC__)
226 #pragma vector=ADC_VECTOR
227 __interrupt void ADC_ISR(void)
228 #elif defined(__GNUC__)
229 void __attribute__ ((interrupt(ADC_VECTOR))) ADC_ISR (void)
231 #error Compiler not supported!
235 switch(__even_in_range(ADCIV,ADCIV_ADCIFG))
241 case ADCIV_ADCTOVIFG:
251 ADC_Result = ADCMEM0;
252 irq_events |= 1<<ev_adc;
253 __bic_SR_register_on_exit(LPM0_bits); // Wake up
262 // GPIO interrupt service routine
263 #if defined(__TI_COMPILER_VERSION__) || defined(__IAR_SYSTEMS_ICC__)
264 #pragma vector=PORT2_VECTOR
265 __interrupt void Port_2(void)
266 #elif defined(__GNUC__)
267 void __attribute__ ((interrupt(PORT2_VECTOR))) Port_2 (void)
269 #error Compiler not supported!
273 irq_events |= 1<<ev_pir1;
274 P2IFG &= ~BIT4; // Clear P2.4 IFG
277 irq_events |= 1<<ev_pir2;
278 P2IFG &= ~BIT5; // Clear P2.5 IFG
281 __bic_SR_register_on_exit(LPM0_bits); // Wake up
283 // GPIO interrupt service routine
284 #if defined(__TI_COMPILER_VERSION__) || defined(__IAR_SYSTEMS_ICC__)
285 #pragma vector=PORT1_VECTOR
286 __interrupt void Port_1(void)
287 #elif defined(__GNUC__)
288 void __attribute__ ((interrupt(PORT1_VECTOR))) Port_1 (void)
290 #error Compiler not supported!
293 #endif /* (PBTN() == P1) */
294 if (PBTN(IFG) & BIT_BTN) {
295 irq_events |= 1<<ev_btn1;
296 PBTN(IFG) &= ~BIT_BTN; // Clear button IFG
299 if (PBTN(IFG) & BIT_BTN2) {
300 irq_events |= 1<<ev_btn2;
301 PBTN(IFG) &= ~BIT_BTN2; // Clear button 2 IFG
304 __bic_SR_register_on_exit(LPM0_bits); // Wake up