diff --git a/main.c b/main.c index 959ac45..85babe6 100644 --- a/main.c +++ b/main.c @@ -58,6 +58,9 @@ volatile bool frame_flag = false; /**< flag set when a frame has passed */ #define SQUARE_WAVE_PIN 0 /**< pin connected to RTC DS1307 square wave output */ volatile uint8_t rtc_seconds = 0; /**< number of seconds passed incremented by the square wave */ +#define STANDBY_TIMEOUT 30 /**< number of seconds after last shake before going down */ +volatile uint16_t standby_timer = 0; /**< number of seconds since last wake-up/activity */ + #define FRAME_TIMER 1 /**< timer to count frame time */ #define FRAME_RATE 25 /**< frame rate */ volatile uint8_t frame_count = 0; /**< number of frames passed */ @@ -209,12 +212,20 @@ void main(void) } #endif + // enable wake up + rcc_periph_clock_enable(RCC_PWR); // enable power domain clock + if (pwr_get_wakeup_flag()) { + printf("woke up from standby\n"); + } + pwr_enable_wakeup_pin(); + // disable internal RTC printf("disable internal RTC: "); rcc_periph_clock_enable(RCC_PWR); // enable power domain clock rcc_periph_clock_enable(RCC_BKP); // enable backup domain clock pwr_disable_backup_domain_write_protect(); // enable write on backup domain (including RTC) RCC_BDCR &= ~RCC_BDCR_RTCEN; // disable RTC + pwr_enable_backup_domain_write_protect(); // re-enable write protect printf("OK\n"); // setup external RTC @@ -357,6 +368,14 @@ void main(void) action = true; // action has been performed led_toggle(); // toggle LED (good to indicate if main function is stuck) frame_count = 0; // resync frame counter to second + if (standby_timer>=STANDBY_TIMEOUT) { // standby timeout complete + // go into standby mode + printf("standing by\n"); + led_max7219_off(0xff); // switch displays off + pwr_clear_wakeup_flag(); // clear flag + SCB_SCR |= SCB_SCR_SLEEPDEEP; // enable deep sleep + pwr_set_standby_mode(); // go to deep sleep + } if (rtc_seconds>=60) { // one minute passed rtc_ds1307_time = rtc_ds1307_read_time(); // get time/date from external RTC if (rtc_ds1307_time==NULL) { @@ -370,10 +389,14 @@ void main(void) } } } + while (pwr_get_wakeup_flag()) { // someone is moving the clapperboard + pwr_clear_wakeup_flag(); // clear flag + standby_timer = 0; // restart standby timer + } if (action) { // go to sleep if nothing had to be done, else recheck for activity action = false; } else { - __WFI(); // go to sleep + __WFI(); // go to sleep and wait for interrupt } } // main loop } @@ -383,6 +406,9 @@ void EXTI_ISR(SQUARE_WAVE_PIN)(void) { exti_reset_request(EXTI(SQUARE_WAVE_PIN)); // reset interrupt rtc_seconds++; // increment number of seconds passed + if (standby_timer