Ejemplo n.º 1
0
void main(void)
{
    initialize();

    /*
    // test: write alphabet
    while (1) {
    	for (int i = 'A'; i <= 'Z'+1; i++) {
    		set_char_at(i, 0);
    		set_char_at(i+1, 1);
    		set_char_at(i+2, 2);
    		set_char_at(i+3, 3);

    		if (get_digits() == 6) {
    			set_char_at(i+4, 4);
    			set_char_at(i+5, 5);
    		}

    		_delay_ms(250);
    	}
    }
    */

    uint8_t hour = 0, min = 0, sec = 0;

    // Counters used when setting time
    int16_t time_to_set = 0;
    uint16_t button_released_timer = 0;
    uint16_t button_speed = 25;

    set_string("--------");

    piezo_init();
    beep(500, 1);
    beep(1000, 1);
    beep(500, 1);

    while (1) {
        get_button_state(&buttons);

        // When alarming:
        // any button press cancels alarm
        if (g_alarming) {
            read_rtc(clock_mode);

            // fixme: if keydown is detected here, wait for keyup and clear state
            // this prevents going into the menu when disabling the alarm
            if (buttons.b1_keydown || buttons.b1_keyup || buttons.b2_keydown || buttons.b2_keyup) {
                buttons.b1_keyup = 0; // clear state
                buttons.b2_keyup = 0; // clear state
                g_alarming = false;
            }
            else {
                alarm();
            }
        }
        // If both buttons are held:
        //  * If the ALARM BUTTON SWITCH is on the LEFT, go into set time mode
        //  * If the ALARM BUTTON SWITCH is on the RIGHT, go into set alarm mode
        else if (clock_state == STATE_CLOCK && buttons.both_held) {
            if (g_alarm_switch) {
                clock_state = STATE_SET_ALARM;
                show_set_alarm();
                rtc_get_alarm_s(&hour, &min, &sec);
                time_to_set = hour*60 + min;
            }
            else {
                clock_state = STATE_SET_CLOCK;
                show_set_time();
                rtc_get_time_s(&hour, &min, &sec);
                time_to_set = hour*60 + min;
            }

            set_blink(true);

            // wait until both buttons are released
            while (1) {
                _delay_ms(50);
                get_button_state(&buttons);
                if (buttons.none_held)
                    break;
            }
        }
        // Set time or alarm
        else if (clock_state == STATE_SET_CLOCK || clock_state == STATE_SET_ALARM) {
            // Check if we should exit STATE_SET_CLOCK or STATE_SET_ALARM
            if (buttons.none_held) {
                set_blink(true);
                button_released_timer++;
                button_speed = 50;
            }
            else {
                set_blink(false);
                button_released_timer = 0;
                button_speed++;
            }

            // exit mode after no button has been touched for a while
            if (button_released_timer >= 160) {
                set_blink(false);
                button_released_timer = 0;
                button_speed = 1;

                // fixme: should be different in 12h mode
                if (clock_state == STATE_SET_CLOCK)
                    rtc_set_time_s(time_to_set / 60, time_to_set % 60, 0);
                else
                    rtc_set_alarm_s(time_to_set / 60, time_to_set % 60, 0);

                clock_state = STATE_CLOCK;
            }

            // Increase / Decrease time counter
            if (buttons.b1_repeat) time_to_set+=(button_speed/100);
            if (buttons.b1_keyup)  time_to_set++;
            if (buttons.b2_repeat) time_to_set-=(button_speed/100);
            if (buttons.b2_keyup)  time_to_set--;

            if (time_to_set  >= 1440) time_to_set = 0;
            if (time_to_set  < 0) time_to_set = 1439;

            show_time_setting(time_to_set / 60, time_to_set % 60, 0);
        }
        // Left button enters menu
        else if (clock_state == STATE_CLOCK && buttons.b2_keyup) {
            clock_state = STATE_MENU_BRIGHTNESS;
            show_setting_int("BRIT", "BRITE", g_brightness, false);
            buttons.b2_keyup = 0; // clear state
        }
        // Right button toggles display mode
        else if (clock_state == STATE_CLOCK && buttons.b1_keyup) {
            clock_mode++;
            if (clock_mode == MODE_LAST) clock_mode = MODE_NORMAL;
            buttons.b1_keyup = 0; // clear state
        }
        else if (clock_state >= STATE_MENU_BRIGHTNESS) {
            if (buttons.none_held)
                button_released_timer++;
            else
                button_released_timer = 0;

            if (button_released_timer >= 80) {
                button_released_timer = 0;
                clock_state = STATE_CLOCK;
            }

            switch (clock_state) {
            case STATE_MENU_BRIGHTNESS:
                if (buttons.b1_keyup) {
                    g_brightness++;
                    buttons.b1_keyup = false;

                    if (g_brightness > 10) g_brightness = 1;

                    eeprom_update_byte(&b_brightness, g_brightness);

                    if (shield == SHIELD_IV17)
                        show_setting_string("BRIT", "BRITE", (g_brightness % 2 == 0) ? "  lo" : "  hi", true);
                    else
                        show_setting_int("BRIT", "BRITE", g_brightness, true);
                    set_brightness(g_brightness);
                }
                break;
            case STATE_MENU_24H:
                if (buttons.b1_keyup) {
                    g_24h_clock = !g_24h_clock;
                    eeprom_update_byte(&b_24h_clock, g_24h_clock);

                    show_setting_string("24H", "24H", g_24h_clock ? " on" : " off", true);
                    buttons.b1_keyup = false;
                }
                break;
            case STATE_MENU_VOL:
                if (buttons.b1_keyup) {
                    g_volume = !g_volume;
                    eeprom_update_byte(&b_volume, g_volume);

                    show_setting_string("VOL", "VOL", g_volume ? " hi" : " lo", true);
                    piezo_init();
                    beep(1000, 1);
                    buttons.b1_keyup = false;
                }
                break;
            case STATE_MENU_TEMP:
                if (buttons.b1_keyup) {
                    g_show_temp = !g_show_temp;
                    eeprom_update_byte(&b_show_temp, g_show_temp);

                    show_setting_string("TEMP", "TEMP", g_show_temp ? " on" : " off", true);
                    buttons.b1_keyup = false;
                }
                break;
            case STATE_MENU_DOTS:
                if (buttons.b1_keyup) {
                    g_show_dots = !g_show_dots;
                    eeprom_update_byte(&b_show_dots, g_show_dots);

                    show_setting_string("DOTS", "DOTS", g_show_dots ? " on" : " off", true);
                    buttons.b1_keyup = false;
                }
                break;
            default:
                break; // do nothing
            }

            if (buttons.b2_keyup) {
                clock_state++;

                // show temperature setting only when running on a DS3231
                if (clock_state == STATE_MENU_TEMP && !rtc_is_ds3231()) clock_state++;

                // don't show dots settings for shields that have no dots
                if (clock_state == STATE_MENU_DOTS && !g_has_dots) clock_state++;

                if (clock_state == STATE_MENU_LAST) clock_state = STATE_MENU_BRIGHTNESS;

                switch (clock_state) {
                case STATE_MENU_BRIGHTNESS:
                    show_setting_int("BRIT", "BRITE", g_brightness, false);
                    break;
                case STATE_MENU_VOL:
                    show_setting_string("VOL", "VOL", g_volume ? " hi" : " lo", false);
                    break;
                case STATE_MENU_24H:
                    show_setting_string("24H", "24H", g_24h_clock ? " on" : " off", false);
                    break;
                case STATE_MENU_DOTS:
                    show_setting_string("DOTS", "DOTS", g_show_dots ? " on" : " off", false);
                    break;
                case STATE_MENU_TEMP:
                    show_setting_string("TEMP", "TEMP", g_show_temp ? " on" : " off", false);
                    break;
                default:
                    break; // do nothing
                }

                buttons.b2_keyup = 0; // clear state
            }
        }
        else {
            // read RTC only aprox every 15ms
            static uint16_t cnt = 0;
            if (cnt++ % 15 == 0)
                read_rtc(clock_mode);
        }

        // fixme: alarm should not be checked when setting time or alarm
        if (g_alarm_switch && rtc_check_alarm())
            g_alarming = true;

        _delay_ms(10);
    }
}
Ejemplo n.º 2
0
void initialize(void)
{

    PIEZO_DDR |= _BV(PIEZO_LOW_BIT);
    PIEZO_DDR |= _BV(PIEZO_HIGH_BIT);

    PIEZO_LOW_OFF;
    PIEZO_HIGH_OFF;

    // Set buttons as inputs
    BUTTON_DDR &= ~(_BV(BUTTON1_BIT));
    BUTTON_DDR &= ~(_BV(BUTTON2_BIT));
    SWITCH_DDR  &= ~(_BV(SWITCH_BIT));

    // Enable pullups for buttons
    BUTTON_PORT |= _BV(BUTTON1_BIT);
    BUTTON_PORT |= _BV(BUTTON2_BIT);
    SWITCH_PORT |= _BV(SWITCH_BIT);

    LED_DDR  |= _BV(LED_BIT); // indicator led

    for (int i = 0; i < 5; i++) {
        LED_HIGH;
        _delay_ms(100);
        LED_LOW;
        _delay_ms(100);
    }

    sei();
    twi_init_master();

    rtc_init();
    rtc_set_ds1307();

    //rtc_set_time_s(16, 59, 50);
    //rtc_set_alarm_s(17,0,0);

    piezo_init();
    beep(440, 1);
    globals_init();
    display_init(g_brightness);

    g_alarm_switch = get_alarm_switch();

#ifdef FEATURE_FLW
    g_has_eeprom = has_eeprom();
//	if (!g_has_eeprom)  beep(440,2);  // debug
    if (!g_has_eeprom)
        g_flw_enabled = false;
    if (tm_ && g_has_eeprom)
        seed_random(tm_->Hour * 10000 + tm_->Minute + 100 + tm_->Second);
#endif

    beep(1320, 1);
    menu_init();  // must come after display, flw init
    rtc_get_alarm_s(&alarm_hour, &alarm_min, &alarm_sec);

    // set up interrupt for alarm switch
    PCICR |= (1 << PCIE2);
    PCMSK2 |= (1 << PCINT18);

#ifdef FEATURE_WmGPS
    // setup uart for GPS
    gps_init(g_gps_enabled);
#endif
#ifdef FEATURE_AUTO_DST
    if (g_DST_mode)
        DSTinit(tm_, g_DST_Rules);  // re-compute DST start, end
#endif
}