powersave #2
8 changed files with 177 additions and 29 deletions
3
.vscode/c_cpp_properties.json
vendored
3
.vscode/c_cpp_properties.json
vendored
|
@ -4,7 +4,8 @@
|
||||||
"name": "Linux",
|
"name": "Linux",
|
||||||
"includePath": [
|
"includePath": [
|
||||||
"${workspaceFolder}/**",
|
"${workspaceFolder}/**",
|
||||||
"${env:PICO_SDK_PATH}/**"
|
"${env:PICO_SDK_PATH}/**",
|
||||||
|
"${env:PICO_EXTRAS_PATH}/**"
|
||||||
],
|
],
|
||||||
"defines": [],
|
"defines": [],
|
||||||
"compilerPath": "/usr/bin/arm-none-eabi-gcc",
|
"compilerPath": "/usr/bin/arm-none-eabi-gcc",
|
||||||
|
|
|
@ -14,6 +14,9 @@ set(PICO_BOARD pico_w CACHE STRING "Board type")
|
||||||
# Pull in Raspberry Pi Pico SDK (must be before project)
|
# Pull in Raspberry Pi Pico SDK (must be before project)
|
||||||
include(pico_sdk_import.cmake)
|
include(pico_sdk_import.cmake)
|
||||||
|
|
||||||
|
# Pull in Raspberry Pi Pico Extras
|
||||||
|
include(pico_extras_import.cmake)
|
||||||
|
|
||||||
if (PICO_SDK_VERSION_STRING VERSION_LESS "1.4.0")
|
if (PICO_SDK_VERSION_STRING VERSION_LESS "1.4.0")
|
||||||
message(FATAL_ERROR "Raspberry Pi Pico SDK version 1.4.0 (or later) required. Your version is ${PICO_SDK_VERSION_STRING}")
|
message(FATAL_ERROR "Raspberry Pi Pico SDK version 1.4.0 (or later) required. Your version is ${PICO_SDK_VERSION_STRING}")
|
||||||
endif()
|
endif()
|
||||||
|
|
62
pico_extras_import.cmake
Normal file
62
pico_extras_import.cmake
Normal file
|
@ -0,0 +1,62 @@
|
||||||
|
# This is a copy of <PICO_EXTRAS_PATH>/external/pico_extras_import.cmake
|
||||||
|
|
||||||
|
# This can be dropped into an external project to help locate pico-extras
|
||||||
|
# It should be include()ed prior to project()
|
||||||
|
|
||||||
|
if (DEFINED ENV{PICO_EXTRAS_PATH} AND (NOT PICO_EXTRAS_PATH))
|
||||||
|
set(PICO_EXTRAS_PATH $ENV{PICO_EXTRAS_PATH})
|
||||||
|
message("Using PICO_EXTRAS_PATH from environment ('${PICO_EXTRAS_PATH}')")
|
||||||
|
endif ()
|
||||||
|
|
||||||
|
if (DEFINED ENV{PICO_EXTRAS_FETCH_FROM_GIT} AND (NOT PICO_EXTRAS_FETCH_FROM_GIT))
|
||||||
|
set(PICO_EXTRAS_FETCH_FROM_GIT $ENV{PICO_EXTRAS_FETCH_FROM_GIT})
|
||||||
|
message("Using PICO_EXTRAS_FETCH_FROM_GIT from environment ('${PICO_EXTRAS_FETCH_FROM_GIT}')")
|
||||||
|
endif ()
|
||||||
|
|
||||||
|
if (DEFINED ENV{PICO_EXTRAS_FETCH_FROM_GIT_PATH} AND (NOT PICO_EXTRAS_FETCH_FROM_GIT_PATH))
|
||||||
|
set(PICO_EXTRAS_FETCH_FROM_GIT_PATH $ENV{PICO_EXTRAS_FETCH_FROM_GIT_PATH})
|
||||||
|
message("Using PICO_EXTRAS_FETCH_FROM_GIT_PATH from environment ('${PICO_EXTRAS_FETCH_FROM_GIT_PATH}')")
|
||||||
|
endif ()
|
||||||
|
|
||||||
|
if (NOT PICO_EXTRAS_PATH)
|
||||||
|
if (PICO_EXTRAS_FETCH_FROM_GIT)
|
||||||
|
include(FetchContent)
|
||||||
|
set(FETCHCONTENT_BASE_DIR_SAVE ${FETCHCONTENT_BASE_DIR})
|
||||||
|
if (PICO_EXTRAS_FETCH_FROM_GIT_PATH)
|
||||||
|
get_filename_component(FETCHCONTENT_BASE_DIR "${PICO_EXTRAS_FETCH_FROM_GIT_PATH}" REALPATH BASE_DIR "${CMAKE_SOURCE_DIR}")
|
||||||
|
endif ()
|
||||||
|
FetchContent_Declare(
|
||||||
|
pico_extras
|
||||||
|
GIT_REPOSITORY https://github.com/raspberrypi/pico-extras
|
||||||
|
GIT_TAG master
|
||||||
|
)
|
||||||
|
if (NOT pico_extras)
|
||||||
|
message("Downloading Raspberry Pi Pico Extras")
|
||||||
|
FetchContent_Populate(pico_extras)
|
||||||
|
set(PICO_EXTRAS_PATH ${pico_extras_SOURCE_DIR})
|
||||||
|
endif ()
|
||||||
|
set(FETCHCONTENT_BASE_DIR ${FETCHCONTENT_BASE_DIR_SAVE})
|
||||||
|
else ()
|
||||||
|
if (PICO_SDK_PATH AND EXISTS "${PICO_SDK_PATH}/../pico-extras")
|
||||||
|
set(PICO_EXTRAS_PATH ${PICO_SDK_PATH}/../pico-extras)
|
||||||
|
message("Defaulting PICO_EXTRAS_PATH as sibling of PICO_SDK_PATH: ${PICO_EXTRAS_PATH}")
|
||||||
|
else()
|
||||||
|
message(FATAL_ERROR
|
||||||
|
"PICO EXTRAS location was not specified. Please set PICO_EXTRAS_PATH or set PICO_EXTRAS_FETCH_FROM_GIT to on to fetch from git."
|
||||||
|
)
|
||||||
|
endif()
|
||||||
|
endif ()
|
||||||
|
endif ()
|
||||||
|
|
||||||
|
set(PICO_EXTRAS_PATH "${PICO_EXTRAS_PATH}" CACHE PATH "Path to the PICO EXTRAS")
|
||||||
|
set(PICO_EXTRAS_FETCH_FROM_GIT "${PICO_EXTRAS_FETCH_FROM_GIT}" CACHE BOOL "Set to ON to fetch copy of PICO EXTRAS from git if not otherwise locatable")
|
||||||
|
set(PICO_EXTRAS_FETCH_FROM_GIT_PATH "${PICO_EXTRAS_FETCH_FROM_GIT_PATH}" CACHE FILEPATH "location to download EXTRAS")
|
||||||
|
|
||||||
|
get_filename_component(PICO_EXTRAS_PATH "${PICO_EXTRAS_PATH}" REALPATH BASE_DIR "${CMAKE_BINARY_DIR}")
|
||||||
|
if (NOT EXISTS ${PICO_EXTRAS_PATH})
|
||||||
|
message(FATAL_ERROR "Directory '${PICO_EXTRAS_PATH}' not found")
|
||||||
|
endif ()
|
||||||
|
|
||||||
|
set(PICO_EXTRAS_PATH ${PICO_EXTRAS_PATH} CACHE PATH "Path to the PICO EXTRAS" FORCE)
|
||||||
|
|
||||||
|
add_subdirectory(${PICO_EXTRAS_PATH} pico_extras)
|
|
@ -61,6 +61,7 @@ target_link_libraries(${CMAKE_PROJECT_NAME}
|
||||||
pico_lwip_sntp
|
pico_lwip_sntp
|
||||||
hardware_rtc
|
hardware_rtc
|
||||||
hardware_pio
|
hardware_pio
|
||||||
|
hardware_sleep
|
||||||
)
|
)
|
||||||
|
|
||||||
pico_add_extra_outputs(${CMAKE_PROJECT_NAME})
|
pico_add_extra_outputs(${CMAKE_PROJECT_NAME})
|
||||||
|
|
|
@ -8,6 +8,7 @@
|
||||||
|
|
||||||
#include "hardware/pio.h"
|
#include "hardware/pio.h"
|
||||||
#include "hardware/rtc.h"
|
#include "hardware/rtc.h"
|
||||||
|
#include "hardware/structs/scb.h"
|
||||||
|
|
||||||
#include "pico/cyw43_arch.h"
|
#include "pico/cyw43_arch.h"
|
||||||
#include "pico/stdlib.h"
|
#include "pico/stdlib.h"
|
||||||
|
@ -63,13 +64,18 @@ int main() {
|
||||||
NtpClient::stop();
|
NtpClient::stop();
|
||||||
wifi_disable(); // We don't need Wifi anymore
|
wifi_disable(); // We don't need Wifi anymore
|
||||||
|
|
||||||
datetime_t dt;
|
|
||||||
|
|
||||||
auto dates = parseCsv(csv);
|
auto dates = parseCsv(csv);
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
printf("Number of Dates: %d\n", dates.size());
|
printf("Number of Dates: %d\n", dates.size());
|
||||||
#endif
|
#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) {
|
while (true) {
|
||||||
auto timestamp = time_us_64() + 60'000'000ull;
|
auto timestamp = time_us_64() + 60'000'000ull;
|
||||||
|
|
||||||
|
@ -82,9 +88,7 @@ int main() {
|
||||||
return date.date == tomorrowYMD;
|
return date.date == tomorrowYMD;
|
||||||
});
|
});
|
||||||
|
|
||||||
int8_t hour = dt.hour + 1; // MEZ
|
int8_t hour = isDST(dt) ? dt.hour + 1 : dt.hour;
|
||||||
if (isDST(dt.day, dt.month, dt.dotw))
|
|
||||||
++hour; // MESZ
|
|
||||||
|
|
||||||
printf("%d-%02d-%02d %02d:%02d.%02d\n", dt.year, dt.month, dt.day, hour, dt.min, dt.sec);
|
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 {
|
} 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();
|
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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -8,24 +8,20 @@
|
||||||
|
|
||||||
// Called by lwip sntp in order to set the time
|
// Called by lwip sntp in order to set the time
|
||||||
void set_system_time(u32_t sec) {
|
void set_system_time(u32_t sec) {
|
||||||
|
sec += 3600; // MEZ
|
||||||
|
|
||||||
time_t epoch = sec;
|
time_t epoch = sec;
|
||||||
struct tm *utc = gmtime(&epoch);
|
struct tm *mez = gmtime(&epoch);
|
||||||
datetime_t datetime;
|
datetime_t datetime;
|
||||||
datetime.year = utc->tm_year + 1900;
|
datetime.year = mez->tm_year + 1900;
|
||||||
datetime.month = utc->tm_mon + 1;
|
datetime.month = mez->tm_mon + 1;
|
||||||
datetime.day = utc->tm_mday;
|
datetime.day = mez->tm_mday;
|
||||||
datetime.hour = utc->tm_hour;
|
datetime.hour = mez->tm_hour;
|
||||||
datetime.min = utc->tm_min;
|
datetime.min = mez->tm_min;
|
||||||
datetime.sec = utc->tm_sec;
|
datetime.sec = mez->tm_sec;
|
||||||
datetime.dotw = utc->tm_wday;
|
datetime.dotw = mez->tm_wday;
|
||||||
|
|
||||||
bool success = rtc_set_datetime(&datetime);
|
rtc_set_datetime(&datetime);
|
||||||
|
|
||||||
#ifdef DEBUG
|
|
||||||
if (success) {
|
|
||||||
printf("RTC successfully set.\n");
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void NtpClient::setDateTime() {
|
void NtpClient::setDateTime() {
|
||||||
|
|
|
@ -4,23 +4,30 @@
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <sstream>
|
#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;
|
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.
|
// January, february, november and december are out.
|
||||||
if (month < 3 || month > 10) {
|
if (dt.month < 3 || dt.month > 10) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// April to September are in
|
// April to September are in
|
||||||
if (month > 3 && month < 10) {
|
if (dt.month > 3 && dt.month < 10) {
|
||||||
return true;
|
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.
|
// 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;
|
return previousSunday >= 25;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -186,4 +193,57 @@ void wifi_disable() {
|
||||||
cyw43_arch_gpio_put(CYW43_WL_GPIO_LED_PIN, 0);
|
cyw43_arch_gpio_put(CYW43_WL_GPIO_LED_PIN, 0);
|
||||||
cyw43_wifi_leave(&cyw43_state, CYW43_ITF_STA);
|
cyw43_wifi_leave(&cyw43_state, CYW43_ITF_STA);
|
||||||
cyw43_arch_deinit();
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
10
src/utils.h
10
src/utils.h
|
@ -27,4 +27,12 @@ void wifi_enable();
|
||||||
|
|
||||||
void wifi_disable();
|
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);
|
Loading…
Reference in a new issue