int main(void) { // Set all ports to input, and turn pull-up resistors on for the inputs we are using DDRB = 0x00; PORTB = (1 << SWITCH_PIN) | (1 << STAR2_PIN) | (1 << STAR3_PIN); // Set the switch as an interrupt for when we turn pin change interrupts on PCMSK = (1 << SWITCH_PIN); // Set PWM pin to output DDRB = (1 << PWM_PIN); // Set timer to do PWM for correct output pin and set prescaler timing TCCR0A = 0x23; // phase corrected PWM is 0x21 for PB1, fast-PWM is 0x23 TCCR0B = 0x01; // pre-scaler for timer (1 => 1, 2 => 8, 3 => 64...) // Turn features on or off as needed #ifdef VOLTAGE_MON ADC_on(); #else ADC_off(); #endif ACSR |= (1<<7); //AC off // Enable sleep mode set to Power Down that will be triggered by the sleep_mode() command. set_sleep_mode(SLEEP_MODE_PWR_DOWN); sleep_until_switch_press(); uint8_t last_mode_idx = 0; while(1) { // We will never leave this loop. The WDT will interrupt to check for switch presses and // will change the mode if needed. If this loop detects that the mode has changed, run the // logic for that mode while continuing to check for a mode change. if (mode_idx != last_mode_idx) { last_mode_idx = mode_idx; // The WDT changed the mode. PWM_LVL = pgm_read_byte(&modes[mode_idx]); if (PWM_LVL == 0) { _delay_ms(1); // Need this here, maybe instructions for PWM output not getting executed before shutdown? // Go to sleep sleep_until_switch_press(); } else { set_sleep_mode(SLEEP_MODE_IDLE); //in every other mode just reduce current consumption sleep_mode(); } } } return 0; // Standard Return Code }
int main(void) { // Set all ports to input, and turn pull-up resistors on for the inputs we are using DDRB = 0x00; PORTB = (1 << SWITCH_PIN) | (1 << STAR3_PIN); // Set the switch as an interrupt for when we turn pin change interrupts on PCMSK = (1 << SWITCH_PIN); // Set PWM pin to output #ifdef ALT_MODES DDRB = (1 << PWM_PIN) | (1 << ALT_PWM_PIN); #else DDRB = (1 << PWM_PIN); #endif // Set timer to do PWM for correct output pin and set prescaler timing //TCCR0A = 0x23; // phase corrected PWM is 0x21 for PB1, fast-PWM is 0x23 TCCR0B = 0x01; // pre-scaler for timer (1 => 1, 2 => 8, 3 => 64...) // Turn features on or off as needed #ifdef VOLTAGE_MON ADC_on(); #else ADC_off(); #endif ACSR |= (1<<7); //AC off // Determine if we are going L-H, or H-L based on Star 3 if ((PINB & (1 << STAR3_PIN)) == 0) { // High to Low low_to_high = 0; } else { low_to_high = 1; } // Enable sleep mode set to Power Down that will be triggered by the sleep_mode() command. set_sleep_mode(SLEEP_MODE_PWR_DOWN); sleep_until_switch_press(); uint8_t last_mode_idx = 0; while(1) { // We will never leave this loop. The WDT will interrupt to check for switch presses and // will change the mode if needed. If this loop detects that the mode has changed, run the // logic for that mode while continuing to check for a mode change. if (mode_idx != last_mode_idx) { // The WDT changed the mode. if (mode_idx > 0) { // No need to change the mode if we are just turning the light off // Check if the PWM mode is different if (mode_pwm[last_mode_idx] != mode_pwm[mode_idx]) { #ifdef ALT_MODES TCCR0A = mode_pwm[mode_idx] | 0b10100000; // Use both outputs #else TCCR0A = mode_pwm[mode_idx] | 0b00100000; // Only use the normal output #endif } } PWM_LVL = modes[mode_idx]; #ifdef ALT_MODES ALT_PWM_LVL = alt_modes[mode_idx]; #endif last_mode_idx = mode_idx; if (mode_pwm[mode_idx] == 0) { _delay_ms(1); // Need this here, maybe instructions for PWM output not getting executed before shutdown? // Go to sleep sleep_until_switch_press(); } } } return 0; // Standard Return Code }
int main(void) { // Set all ports to input, and turn pull-up resistors on for the inputs we are using DDRB = 0x00; PORTB = (1 << SWITCH_PIN); // Set the switch as an interrupt for when we turn pin change interrupts on PCMSK = (1 << SWITCH_PIN); // Set PWM pin to output DDRB = (1 << PWM_PIN); // Set timer to do PWM for correct output pin and set prescaler timing TCCR0A = 0x20 | PWM_MODE; // phase corrected PWM is 0x21 for PB1, fast-PWM is 0x23 #ifdef USE_PFM // 0x08 is for variable-speed PWM TCCR0B = 0x08 | 0x01; // pre-scaler for timer (1 => 1, 2 => 8, 3 => 64...) #else TCCR0B = 0x01; // pre-scaler for timer (1 => 1, 2 => 8, 3 => 64...) #endif // Turn features on or off as needed #ifdef VOLTAGE_MON ADC_on(); #else ADC_off(); #endif ACSR |= (1<<7); //AC off #ifdef BLINK_ON_POWER // blink once to let the user know we have power //TCCR0A = PHASE | 0b00100000; // Only use the normal output #ifdef USE_PFM CEIL_LVL = 255; #endif PWM_LVL = 255; _delay_ms(3); PWM_LVL = 0; _delay_ms(1); #endif // Enable sleep mode set to Power Down that will be triggered by the sleep_mode() command. set_sleep_mode(SLEEP_MODE_PWR_DOWN); sleep_until_switch_press(); uint8_t last_mode_idx = 0; while(1) { // We will never leave this loop. The WDT will interrupt to check for switch presses and // will change the mode if needed. If this loop detects that the mode has changed, run the // logic for that mode while continuing to check for a mode change. if (mode_idx != last_mode_idx) { // The WDT changed the mode. PWM_LVL = pgm_read_byte(modes + mode_idx); last_mode_idx = mode_idx; _delay_ms(1); if (mode_idx == 0) { // Finish executing instructions for PWM level change // and/or voltage readout mode before shutdown. do { _delay_ms(1); } while (0); // FIXME: stay on for a while to catch doubleclicks // Go to sleep sleep_until_switch_press(); // FIXME: lock mode can result in fast PWM=0 staying lit // (MCU wakes up and stays awake, should go back to sleep) } } } return 0; // Standard Return Code }