X-Git-Url: http://www.average.org/gitweb/?p=sensor-light.git;a=blobdiff_plain;f=msp430%2Fmain.c;h=fc80ae9b04fdbeeb4e180960ee4b055c34d745db;hp=38f681c340a9c117b789fa140d3bfff63c8555e5;hb=662310e4999c78fb786068643f100e76b9294c68;hpb=7cd84e920809d1e8f15209fa17ab21a81af40435 diff --git a/msp430/main.c b/msp430/main.c index 38f681c..fc80ae9 100644 --- a/msp430/main.c +++ b/msp430/main.c @@ -4,6 +4,11 @@ static volatile unsigned int ADC_Result; static volatile unsigned int irq_events = 0; enum {ev_btn1 = 0, ev_btn2, ev_pir1, ev_pir2, ev_tmr, ev_adc, ev_MAX}; +#define PWM_ORDER 10 +#define PWM_HALF 5 +#define LIGHT_THRESHOLD 800 +#define TIME_ON 160 + #ifdef ADCSC /* Let us hope that this is a "new" model */ # define BIT_RL BIT0 # define BIT_GL BIT1 @@ -19,18 +24,30 @@ enum {ev_btn1 = 0, ev_btn2, ev_pir1, ev_pir2, ev_tmr, ev_adc, ev_MAX}; # define BIT_BTN2 0 #endif +static int expon2(int duty) +{ + int shift = duty>>1; + int comp = 1<>1 : 0; + return (duty ? comp|extra : 0); +} + int main(void) { - int Duty_Cycle = 1; + int Duty_Cycle = 0; int Increment = 1; - unsigned int Time_Count = 0; - unsigned int Time_Left = 5; + unsigned int Time_Left = 50; + unsigned int Time_Indicate = 2; WDTCTL = WDTPW | WDTHOLD; // stop watchdog timer // Configure GPIO Out - P1DIR |= BIT_RL|BIT_GL|BIT7; // Set LEDs & PWM to output direction + P1DIR |= BIT_RL|BIT_GL|BIT2; // Set LEDs & PWM to output direction P1OUT &= ~(BIT_RL|BIT_GL); // LEDs off - P1SEL1 |= BIT7; // PWM out +#ifdef P1SEL1 + P1SEL1 |= BIT2; // PWM out +#else + P1SEL |= BIT2; // PWM out +#endif // Configure GPIO In PBTN(DIR) &= ~(BIT_BTN|BIT_BTN2); // Buttons @@ -56,22 +73,37 @@ int main(void) ADCIE |= ADCIE0; // Enable ADC conv complete interrupt // channel 5 is unused, reserved for measuring current #else -# error older mode ADC unimplemented + ADC10CTL0 = ADC10SHT_2 + ADC10ON + ADC10IE; // ADCON, S&H=16 ADC clks + ADC10CTL1 = INCH_4; // A4 ADC input select // channel 5 is unused, reserved for measuring current #endif + // Timer and PWM + +#ifndef TASSEL__SMCLK +# define TASSEL__SMCLK TASSEL_2 +# define MC__UP MC_1 +# define MC__CONTINUOUS MC_2 +# define TA0CCR2 TA0CCR1 +# define TA0CCTL2 TA0CCTL1 +#endif + // Configure timer A0 for PWM - TA0CCR0 = 10000-1; // PWM Period - TA0CCTL2 = OUTMOD_7; // CCR2 reset/set - TA0CCR2 = 500; // CCR2 PWM duty cycle - TA0CTL = TASSEL__SMCLK | MC__UP | TACLR; // SMCLK, up mode, clear TAR + TA0CCR0 = 1 << PWM_ORDER; // PWM Period 2^10 ca. 1 kHz + TA0CCR2 = 0; // CCR1 PWM duty cycle + TA0CCTL2 = OUTMOD_7; // CCR1 reset/set + TA0CTL = TASSEL__SMCLK | MC__UP | TACLR;// SMCLK, up mode + // SMCLK, no divider, up mode, no interrupt, clear TAR //Configure timer A1 for counting time - TA1CTL |= TASSEL__SMCLK | MC__CONTINUOUS | TACLR | TAIE; // SMCLK, no divider, continuous mode + TA1CTL |= TASSEL__SMCLK | MC__CONTINUOUS | TACLR | TAIE; + // SMCLK, no divider, continuous mode, interrupt enable +#ifdef LOCKLPM5 // Disable the GPIO power-on default high-impedance mode to activate // previously configured port settings PM5CTL0 &= ~LOCKLPM5; +#endif while(1) { @@ -82,65 +114,72 @@ int main(void) irq_events = 0; _enable_interrupts(); - // Button 2 or PIR events initiate light measurement and tuns on green led + // Button 2 or PIR events initiate light measurement + // and tuns on green or red led if (events & (1< 1) { - Time_Left = 15; - continue; - } - ADCCTL0 |= ADCENC | ADCSC; // Sampling and conversion start - // ADC10CTL0 |= ENC + ADC10SC; // Sampling and conversion start - P1OUT |= BIT_GL; // Set green LED on + if (events & 1< 5000) { + P1OUT |= (BIT_GL|BIT_RL); // Set green and red LEDs on + Time_Indicate = 5; + if (Duty_Cycle > PWM_HALF) { Time_Left = 0; Increment = -1; } else { - Time_Left = 15; + Time_Left = TIME_ON; Increment = 1; } } // Timer event (100 ms) changed duty cycle and flashes red led if (events & 1< 10) { - Time_Count = 0; - P1OUT ^= BIT_RL; // blink - if (Time_Left) - Time_Left--; - else if (Duty_Cycle > 1) - Increment = -1; - } - if (Increment == 0) - continue; - else if (Increment > 0) - Duty_Cycle *= 2; - else if (Increment < 0) - Duty_Cycle /= 2; - if (Duty_Cycle < 1) { - Duty_Cycle = 1; - Increment = 0; + if (Time_Indicate) { + Time_Indicate--; + if (!Time_Indicate) + P1OUT &= ~(BIT_RL|BIT_GL); // LEDs off } - if (Duty_Cycle > (10000-1)) { - Duty_Cycle = 10000-1; - Increment = 0; + if (Time_Left) { + Time_Left--; + if (!Time_Left) + if (Duty_Cycle) + Increment = -1; } - TA0CCR2 = Duty_Cycle; + if (Increment > 0) { + if (++Duty_Cycle >= (PWM_ORDER<<1)) { + Duty_Cycle = PWM_ORDER<<1; + Increment = 0; + } + } else if (Increment < 0) { + if (--Duty_Cycle < 1) { + Duty_Cycle = 0; + Increment = 0; + } + } else // Increment _was_ zero - no change! + continue; + + TA0CCR2 = expon2(Duty_Cycle); } __bis_SR_register(LPM0_bits | GIE); __no_operation(); @@ -175,6 +214,11 @@ void __attribute__ ((interrupt(TIMER1_A1_VECTOR))) Timer_A (void) } } +#ifndef ADC_VECTOR +# define ADCMEM0 ADC10MEM +# define ADC_VECTOR ADC10_VECTOR +#endif + // ADC interrupt service routine #if defined(__TI_COMPILER_VERSION__) || defined(__IAR_SYSTEMS_ICC__) #pragma vector=ADC_VECTOR @@ -185,6 +229,7 @@ void __attribute__ ((interrupt(ADC_VECTOR))) ADC_ISR (void) #error Compiler not supported! #endif { +#ifdef ADCIV_NONE switch(__even_in_range(ADCIV,ADCIV_ADCIFG)) { case ADCIV_NONE: @@ -200,13 +245,16 @@ void __attribute__ ((interrupt(ADC_VECTOR))) ADC_ISR (void) case ADCIV_ADCINIFG: break; case ADCIV_ADCIFG: +#endif ADC_Result = ADCMEM0; irq_events |= 1<