WIP: trying deep sleep

This commit is contained in:
Martin Brodbeck 2023-01-10 11:27:15 +01:00
parent aaa2c6dac4
commit 377dd3c4e6
8 changed files with 177 additions and 29 deletions

View file

@ -61,6 +61,7 @@ target_link_libraries(${CMAKE_PROJECT_NAME}
pico_lwip_sntp
hardware_rtc
hardware_pio
hardware_sleep
)
pico_add_extra_outputs(${CMAKE_PROJECT_NAME})

View file

@ -8,6 +8,7 @@
#include "hardware/pio.h"
#include "hardware/rtc.h"
#include "hardware/structs/scb.h"
#include "pico/cyw43_arch.h"
#include "pico/stdlib.h"
@ -63,13 +64,18 @@ int main() {
NtpClient::stop();
wifi_disable(); // We don't need Wifi anymore
datetime_t dt;
auto dates = parseCsv(csv);
#ifdef DEBUG
printf("Number of Dates: %d\n", dates.size());
#endif
datetime_t dt;
// save values for later
uint scb_orig = scb_hw->scr;
uint clock0_orig = clocks_hw->sleep_en0;
uint clock1_orig = clocks_hw->sleep_en1;
while (true) {
auto timestamp = time_us_64() + 60'000'000ull;
@ -82,9 +88,7 @@ int main() {
return date.date == tomorrowYMD;
});
int8_t hour = dt.hour + 1; // MEZ
if (isDST(dt.day, dt.month, dt.dotw))
++hour; // MESZ
int8_t hour = isDST(dt) ? dt.hour + 1 : dt.hour;
printf("%d-%02d-%02d %02d:%02d.%02d\n", dt.year, dt.month, dt.day, hour, dt.min, dt.sec);
@ -127,8 +131,21 @@ int main() {
}
} else {
// If we start already close to a full hour, dont't do a deep sleep yet
if (dt.min == 59 && dt.sec >= 57) {
sleep_ms((60 - dt.sec) * 1'000);
continue;
}
led.blinkReady();
sleep_until(static_cast<absolute_time_t>(timestamp));
datetime_t dtUntil = dt;
add_one_hour(dtUntil); // next hour
dtUntil.sec = 0;
dtUntil.min = 0;
perform_sleep(dtUntil);
recover_from_sleep(scb_orig, clock0_orig, clock1_orig);
}
}

View file

@ -8,24 +8,20 @@
// Called by lwip sntp in order to set the time
void set_system_time(u32_t sec) {
sec += 3600; // MEZ
time_t epoch = sec;
struct tm *utc = gmtime(&epoch);
struct tm *mez = gmtime(&epoch);
datetime_t datetime;
datetime.year = utc->tm_year + 1900;
datetime.month = utc->tm_mon + 1;
datetime.day = utc->tm_mday;
datetime.hour = utc->tm_hour;
datetime.min = utc->tm_min;
datetime.sec = utc->tm_sec;
datetime.dotw = utc->tm_wday;
datetime.year = mez->tm_year + 1900;
datetime.month = mez->tm_mon + 1;
datetime.day = mez->tm_mday;
datetime.hour = mez->tm_hour;
datetime.min = mez->tm_min;
datetime.sec = mez->tm_sec;
datetime.dotw = mez->tm_wday;
bool success = rtc_set_datetime(&datetime);
#ifdef DEBUG
if (success) {
printf("RTC successfully set.\n");
}
#endif
rtc_set_datetime(&datetime);
}
void NtpClient::setDateTime() {

View file

@ -4,23 +4,30 @@
#include <iostream>
#include <sstream>
#include "pico/sleep.h"
#include "pico/stdlib.h"
// #include "stdlib.h"
#include "hardware/clocks.h"
#include "hardware/rosc.h"
#include "hardware/structs/scb.h"
using namespace std;
bool isDST(int8_t day, int8_t month, int8_t dow) {
bool isDST(const datetime_t &dt) {
// January, february, november and december are out.
if (month < 3 || month > 10) {
if (dt.month < 3 || dt.month > 10) {
return false;
}
// April to September are in
if (month > 3 && month < 10) {
if (dt.month > 3 && dt.month < 10) {
return true;
}
int previousSunday = day - dow;
int previousSunday = dt.day - dt.dotw;
// In march, we are DST if our previous sunday was on or after the 25th.
if (month == 3) {
if (dt.month == 3) {
return previousSunday >= 25;
}
@ -186,4 +193,57 @@ void wifi_disable() {
cyw43_arch_gpio_put(CYW43_WL_GPIO_LED_PIN, 0);
cyw43_wifi_leave(&cyw43_state, CYW43_ITF_STA);
cyw43_arch_deinit();
}
}
void recover_from_sleep(uint scb_orig, uint clock0_orig, uint clock1_orig) {
// Re-enable ring Oscillator control
rosc_write(&rosc_hw->ctrl, ROSC_CTRL_ENABLE_BITS);
// reset procs back to default
scb_hw->scr = scb_orig;
clocks_hw->sleep_en0 = clock0_orig;
clocks_hw->sleep_en1 = clock1_orig;
// reset clocks
clocks_init();
stdio_init_all();
return;
}
void perform_sleep(datetime_t &untilDt) {
printf("Going to sleep...\n");
uart_default_tx_wait_blocking();
sleep_goto_sleep_until(&untilDt, nullptr);
}
void add_one_day(datetime_t &dt) {
int daysPerMonth[13] = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
// Is it a leap year?
if ((dt.year % 4 == 0 && dt.year % 100 != 0) || dt.year % 400 == 0) {
daysPerMonth[2] = 29;
}
if (dt.month == 12 && dt.day == daysPerMonth[12]) {
dt.year += 1;
dt.month = 1;
dt.day = 1;
} else if (dt.day == daysPerMonth[dt.month]) {
dt.month = (dt.month + 1) % 12;
dt.day = 1;
} else {
dt.day += 1;
}
}
void add_one_hour(datetime_t &dt) {
if (dt.hour == 23) {
add_one_day(dt);
dt.hour = 0;
} else {
dt.hour += 1;
}
}

View file

@ -27,4 +27,12 @@ void wifi_enable();
void wifi_disable();
bool isDST(int8_t day, int8_t month, int8_t dow);
bool isDST(const datetime_t &dt);
void recover_from_sleep(uint scb_orig, uint clock0_orig, uint clock1_orig);
void perform_sleep(datetime_t &untilDt);
//void add_one_day(datetime_t &dt);
void add_one_hour(datetime_t &dt);