From 9083b9888252def392326581bd489d905f365416 Mon Sep 17 00:00:00 2001 From: PoliEcho Date: Sat, 4 Oct 2025 22:25:57 +0200 Subject: [PATCH] I dont even know --- CMakeLists.txt | 2 + GC9A01/gc9a01.h | 1 + alarm.cpp | 97 +++++++++-- alarm.h | 3 +- bell.c | 391 ++++++++++++++++++++++++++++++++++++++++++++ bell.h | 11 ++ display.cpp | 1 + display.h | 2 + link.h | 8 + multicore_utils.cpp | 17 ++ pins.h | 3 +- smart_alarm.cpp | 4 +- smart_alarm.h | 5 + sound.cpp | 4 +- sound.h | 4 +- ui.cpp | 49 +++++- ui.h | 1 + 17 files changed, 580 insertions(+), 23 deletions(-) create mode 100644 bell.c create mode 100644 bell.h create mode 100644 link.h create mode 100644 multicore_utils.cpp create mode 100644 smart_alarm.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 9542d18..9e1d278 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -42,6 +42,8 @@ add_executable(smart_alarm smart_alarm.cpp fonts/Font5x7FixedMono.c alarm.cpp dateutils.cpp + bell.c + multicore_utils.cpp ) pico_set_program_name(smart_alarm "smart_alarm") diff --git a/GC9A01/gc9a01.h b/GC9A01/gc9a01.h index e0de5e3..72cdc54 100644 --- a/GC9A01/gc9a01.h +++ b/GC9A01/gc9a01.h @@ -103,6 +103,7 @@ void gc9a01_vline(gc9a01_GC9A01_obj_t *self, uint16_t x, uint16_t y, uint16_t w, void gc9a01_text(gc9a01_GC9A01_obj_t *self, const GFXfont *font, char *str, uint16_t x0, uint16_t y0, uint16_t fg_color, uint16_t bg_color); void gc9a01_text_gfx_transparent(gc9a01_GC9A01_obj_t *self, const GFXfont *font, const char *str, uint16_t x0, uint16_t y0, uint16_t color); void gc9a01_text_gfx_buffered(gc9a01_GC9A01_obj_t *self, const GFXfont *font, const char *str, uint16_t x0, uint16_t y0, uint16_t fg_color, uint16_t bg_color); +void gc9a01_blit_buffer(gc9a01_GC9A01_obj_t *self, uint16_t x, uint16_t y, uint16_t w, uint16_t h, uint8_t *buf, int len); uint8_t gc9a01_get_color(uint8_t bpp); uint16_t color565(uint8_t r, uint8_t g, uint8_t b); #ifdef __cplusplus diff --git a/alarm.cpp b/alarm.cpp index c182184..002ca38 100644 --- a/alarm.cpp +++ b/alarm.cpp @@ -4,7 +4,14 @@ #include #include "alarm.h" +#include +#include + +#include "dateutils.h" +#include "link.h" +#include "ui.h" #include "hardware/rtc.h" +#include "pico/multicore.h" #include "pico/util/datetime.h" @@ -126,10 +133,11 @@ void alarm::set_even_week(bool even_week) { #include "pico/util/datetime.h" -datetime_t alarm::get_next_ring_time() const { + +void alarm::get_next_ring_time(datetime_t &ret) const { if (!enabled()) { - datetime_t invalid = {0}; - return invalid; + ret = {0}; + return; } datetime_t now; @@ -140,7 +148,7 @@ datetime_t alarm::get_next_ring_time() const { candidate.min = minutes(); candidate.sec = 0; - auto days = days_enabled(); + std::array days = days_enabled(); bool any_day_enabled = false; for (uint8_t i = 0; i < 7; i++) { if (days[i]) { @@ -150,12 +158,33 @@ datetime_t alarm::get_next_ring_time() const { } if (!any_day_enabled) { + // One-time alarm: schedule for tomorrow if time passed today if (candidate.hour < now.hour || (candidate.hour == now.hour && candidate.min <= now.min)) { - datetime_t invalid = {0}; - return invalid; + + candidate.day++; + + // Handle month overflow + const uint8_t days_in_month[] = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; + uint8_t max_days = days_in_month[candidate.month]; + if (candidate.month == 2 && (candidate.year % 4 == 0 && + (candidate.year % 100 != 0 || candidate.year % 400 == 0))) { + max_days = 29; + } + + if (candidate.day > max_days) { + candidate.day = 1; + candidate.month++; + if (candidate.month > 12) { + candidate.month = 1; + candidate.year++; + } + } + + candidate.dotw = (now.dotw + 1) % 7; } - return candidate; + memcpy(&ret, &candidate, sizeof(datetime_t)); + return; } // Optimized ISO 8601 week calculation @@ -174,8 +203,7 @@ datetime_t alarm::get_next_ring_time() const { uint8_t week = (ordinal - iso_weekday + 10) / 7; if (week == 0) { - // use int16_t insted of uint16_t to avoid warning - int16_t prev_year = dt.year - 1; + int16_t prev_year = dt.year - 1; // fix warning bool leap = (prev_year % 4 == 0 && (prev_year % 100 != 0 || prev_year % 400 == 0)); datetime_t prev_jan1 = {prev_year, 1, 1, 0, 0, 0, 0}; @@ -255,14 +283,55 @@ datetime_t alarm::get_next_ring_time() const { continue; } } - - return test_date; + memcpy(&ret, &test_date, sizeof(datetime_t)); + return; } - datetime_t invalid = {0}; - return invalid; + ret = {0}; + return; } -std::vector alarms; \ No newline at end of file +std::vector alarms; + +uint8_t armed_alarm = 0; +void alarm_trigger_callback() { + printf("alarm triggered!\n"); + + { + std::array days_enabled = alarms[armed_alarm].days_enabled(); + bool one_time = true; + for (bool b : days_enabled) { + if (b) {one_time = false;break;} + } + if (one_time) {alarms[armed_alarm].disable();} + } + rearm_alarm_timers(); + if (get_core_num()) { + alarm_gone_off_page(); + } else { + multicore_launch_core1(&alarm_gone_off_page); + } +} + +void rearm_alarm_timers() { + printf("arming alarm...\n"); + rtc_disable_alarm(); + if (alarms.empty()) return; + datetime_t first_alarm; + alarms[0].get_next_ring_time(first_alarm); + datetime_t testing; + for (uint8_t i = 1; i < alarms.size(); i++) { + if (alarms[i].enabled()) { + alarms[i].get_next_ring_time(testing); + if (compare_datetime(&testing, &first_alarm) == SMALLER_THAN) { + memcpy(&first_alarm, &testing, sizeof(datetime_t)); + armed_alarm = i; + } + } + } + printf("alarm set to %d:%d:%d %d.%d.%d\n",first_alarm.hour,first_alarm.min,first_alarm.sec,first_alarm.day,first_alarm.month,first_alarm.year); + rtc_set_alarm(&first_alarm,&alarm_trigger_callback); + rtc_enable_alarm(); +} \ No newline at end of file diff --git a/alarm.h b/alarm.h index 948356f..15c903f 100644 --- a/alarm.h +++ b/alarm.h @@ -21,7 +21,7 @@ public: [[nodiscard]] bool every_other_week() const; [[nodiscard]] bool even_week() const; [[nodiscard]] bool enabled() const; - [[nodiscard]] datetime_t get_next_ring_time() const; + void get_next_ring_time(datetime_t &ret) const; // Enable/disable methods void enable(); @@ -36,4 +36,5 @@ public: }; extern std::vector alarms; +void rearm_alarm_timers(); #endif //SMART_ALARM_PERSISTANCE_H \ No newline at end of file diff --git a/bell.c b/bell.c new file mode 100644 index 0000000..b8fc13c --- /dev/null +++ b/bell.c @@ -0,0 +1,391 @@ +/* GIMP RGB C-Source image dump (bell.c) */ + +#include +#include + +const struct bell_image_t bell_image = { + 64, 64, + "\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202" + "\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\000\370\000\370\000" + "\370\000\370\000\370\000\370\000\370\000\370\000\370\000\370\000\370\000\370\000\370\000\370\000" + "\370\000\370\000\370\000\370\000\370\000\370\000\370\000\370\000\370\000\370\000\370\000\370\202" + "\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020" + "\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202" + "\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020" + "\202\020\202\020\202\020\202\020\202\020\000\370\000\370\000\370\000\370\000\370\000\370\000" + "\370\000\370\000\370\000\370\000\370\000\370\000\370\000\370\000\370\000\370\000\370\000\370\000" + "\370\000\370\000\370\000\370\000\370\000\370\000\370\000\370\000\370\000\370\202\020\202\020" + "\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202" + "\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020" + "\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202" + "\020\202\020\202\020\000\370\000\370\000\370\000\370\000\370\000\370\000\370\000\370\000\370\000" + "\370\000\370\000\370\000\370\000\370\000\370\000\370\000\370\000\370\000\370\000\370\000\370\000" + "\370\000\370\000\370\000\370\000\370\000\370\000\370\202\020\202\020\202\020\202\020\202" + "\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020" + "\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202" + "\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\000\370" + "\000\370\000\370\000\370\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020" + "\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202" + "\020\202\020\202\020\202\020\000\370\000\370\000\370\000\370\202\020\202\020\202\020\202" + "\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020" + "\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202" + "\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\000\370\000\370\000" + "\370\000\370\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020" + "\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202" + "\020\202\020\202\020\202\020\202\020\000\370\000\370\000\370\000\370\202\020\202\020\202" + "\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020" + "\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202" + "\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\000\370\000\370\000" + "\370\000\370\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020" + "\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202" + "\020\202\020\202\020\202\020\202\020\000\370\000\370\000\370\000\370\202\020\202\020\202" + "\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020" + "\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202" + "\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\000\370\000\370\000\370\000" + "\370\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020" + "\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202" + "\020\202\020\202\020\202\020\202\020\202\020\000\370\000\370\000\370\000\370\202\020\202" + "\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020" + "\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202" + "\020\202\020\202\020\202\020\202\020\202\020\202\020\000\370\000\370\000\370\000\370\202" + "\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020" + "\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202" + "\020\202\020\202\020\202\020\202\020\202\020\202\020\000\370\000\370\000\370\000\370\202" + "\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020" + "\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202" + "\020\202\020\202\020\202\020\202\020\202\020\202\020\000\370\000\370\000\370\000\370\202" + "\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020" + "\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202" + "\020\202\020\202\020\202\020\202\020\202\020\202\020\000\370\000\370\000\370\000\370\202" + "\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020" + "\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202" + "\020\202\020\202\020\202\020\202\020\202\020\000\370\000\370\000\370\000\370\202\020\202" + "\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020" + "\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202" + "\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\000\370\000\370\000\370\000" + "\370\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020" + "\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202" + "\020\202\020\202\020\202\020\202\020\000\370\000\370\000\370\000\370\202\020\202\020\202" + "\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020" + "\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202" + "\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\000\370\000\370\000" + "\370\000\370\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020" + "\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202" + "\020\202\020\202\020\202\020\202\020\000\370\000\370\000\370\000\370\202\020\202\020\202" + "\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020" + "\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202" + "\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\000\370\000\370\000" + "\370\000\370\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020" + "\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202" + "\020\202\020\202\020\202\020\000\370\000\370\000\370\000\370\202\020\202\020\202\020\202" + "\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020" + "\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202" + "\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\000\370" + "\000\370\000\370\000\370\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020" + "\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202" + "\020\202\020\202\020\000\370\000\370\000\370\000\370\202\020\202\020\202\020\202\020\202" + "\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020" + "\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202" + "\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020" + "\000\370\000\370\000\370\000\370\202\020\202\020\202\020\202\020\202\020\202\020\202\020" + "\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202" + "\020\202\020\202\020\000\370\000\370\000\370\000\370\202\020\202\020\202\020\202\020\202" + "\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020" + "\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202" + "\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020" + "\000\370\000\370\000\370\000\370\202\020\202\020\202\020\202\020\202\020\202\020\202\020" + "\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202" + "\020\202\020\000\370\000\370\000\370\000\370\202\020\202\020\202\020\202\020\202\020\202" + "\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020" + "\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202" + "\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020" + "\202\020\000\370\000\370\000\370\000\370\202\020\202\020\202\020\202\020\202\020\202\020" + "\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202" + "\020\000\370\000\370\000\370\000\370\202\020\202\020\202\020\202\020\202\020\202\020\202" + "\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020" + "\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202" + "\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020" + "\202\020\202\020\000\370\000\370\000\370\000\370\202\020\202\020\202\020\202\020\202\020" + "\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202" + "\020\000\370\000\370\000\370\000\370\202\020\202\020\202\020\202\020\202\020\202\020\202" + "\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020" + "\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202" + "\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020" + "\202\020\202\020\000\370\000\370\000\370\000\370\202\020\202\020\202\020\202\020\202\020" + "\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\000" + "\370\000\370\000\370\000\370\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202" + "\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020" + "\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202" + "\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020" + "\202\020\202\020\202\020\000\370\000\370\000\370\000\370\202\020\202\020\202\020\202\020" + "\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\000\370\000\370" + "\000\370\000\370\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202" + "\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020" + "\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202" + "\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020" + "\202\020\202\020\202\020\202\020\000\370\000\370\000\370\000\370\202\020\202\020\202\020" + "\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\000\370\000\370" + "\000\370\000\370\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202" + "\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020" + "\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202" + "\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020" + "\202\020\202\020\202\020\202\020\000\370\000\370\000\370\000\370\202\020\202\020\202\020" + "\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\000\370\000\370\000\370" + "\000\370\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202" + "\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020" + "\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202" + "\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020" + "\202\020\202\020\202\020\202\020\202\020\000\370\000\370\000\370\000\370\202\020\202\020" + "\202\020\202\020\202\020\202\020\202\020\202\020\202\020\000\370\000\370\000\370\000\370" + "\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202" + "\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020" + "\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202" + "\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020" + "\202\020\202\020\202\020\202\020\202\020\202\020\000\370\000\370\000\370\000\370\202\020" + "\202\020\202\020\202\020\202\020\202\020\202\020\202\020\000\370\000\370\000\370\000\370" + "\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202" + "\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020" + "\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202" + "\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020" + "\202\020\202\020\202\020\202\020\202\020\202\020\000\370\000\370\000\370\000\370\202\020" + "\202\020\202\020\202\020\202\020\202\020\202\020\202\020\000\370\000\370\000\370\202\020" + "\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202" + "\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020" + "\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202" + "\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020" + "\202\020\202\020\202\020\202\020\202\020\202\020\000\370\000\370\000\370\000\370\202\020" + "\202\020\202\020\202\020\202\020\202\020\202\020\202\020\000\370\000\370\000\370\202\020" + "\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202" + "\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020" + "\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202" + "\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020" + "\202\020\202\020\202\020\202\020\202\020\202\020\202\020\000\370\000\370\000\370\202\020" + "\202\020\202\020\202\020\202\020\202\020\202\020\202\020\000\370\000\370\000\370\202\020" + "\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202" + "\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020" + "\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202" + "\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020" + "\202\020\202\020\202\020\202\020\202\020\202\020\202\020\000\370\000\370\000\370\202\020" + "\202\020\202\020\202\020\202\020\202\020\202\020\202\020\000\370\000\370\000\370\202\020" + "\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202" + "\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020" + "\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202" + "\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020" + "\202\020\202\020\202\020\202\020\202\020\202\020\202\020\000\370\000\370\000\370\202\020" + "\202\020\202\020\202\020\202\020\202\020\202\020\202\020\000\370\000\370\000\370\202\020" + "\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202" + "\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020" + "\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202" + "\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020" + "\202\020\202\020\202\020\202\020\202\020\202\020\202\020\000\370\000\370\000\370\202\020" + "\202\020\202\020\202\020\202\020\202\020\202\020\202\020\000\370\000\370\000\370\202\020" + "\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202" + "\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020" + "\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202" + "\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020" + "\202\020\202\020\202\020\202\020\202\020\202\020\202\020\000\370\000\370\000\370\202\020" + "\202\020\202\020\202\020\202\020\202\020\202\020\202\020\000\370\000\370\000\370\202\020" + "\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202" + "\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020" + "\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202" + "\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020" + "\202\020\202\020\202\020\202\020\202\020\202\020\202\020\000\370\000\370\000\370\202\020" + "\202\020\202\020\202\020\202\020\202\020\202\020\202\020\000\370\000\370\000\370\202\020" + "\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202" + "\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020" + "\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202" + "\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020" + "\202\020\202\020\202\020\202\020\202\020\202\020\202\020\000\370\000\370\000\370\202\020" + "\202\020\202\020\202\020\202\020\202\020\202\020\202\020\000\370\000\370\000\370\202\020" + "\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202" + "\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020" + "\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202" + "\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020" + "\202\020\202\020\202\020\202\020\202\020\202\020\202\020\000\370\000\370\000\370\202\020" + "\202\020\202\020\202\020\202\020\202\020\202\020\202\020\000\370\000\370\000\370\202\020" + "\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202" + "\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020" + "\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202" + "\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020" + "\202\020\202\020\202\020\202\020\202\020\202\020\202\020\000\370\000\370\000\370\202\020" + "\202\020\202\020\202\020\202\020\202\020\202\020\202\020\000\370\000\370\000\370\202\020" + "\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202" + "\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020" + "\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202" + "\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020" + "\202\020\202\020\202\020\202\020\202\020\202\020\202\020\000\370\000\370\000\370\202\020" + "\202\020\202\020\202\020\202\020\202\020\202\020\202\020\000\370\000\370\000\370\202\020" + "\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202" + "\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020" + "\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202" + "\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020" + "\202\020\202\020\202\020\202\020\202\020\202\020\202\020\000\370\000\370\000\370\202\020" + "\202\020\202\020\202\020\202\020\202\020\202\020\202\020\000\370\000\370\000\370\202\020" + "\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202" + "\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020" + "\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202" + "\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020" + "\202\020\202\020\202\020\202\020\202\020\202\020\202\020\000\370\000\370\000\370\202\020" + "\202\020\202\020\202\020\202\020\202\020\202\020\202\020\000\370\000\370\000\370\202\020" + "\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202" + "\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020" + "\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202" + "\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020" + "\202\020\202\020\202\020\202\020\202\020\202\020\202\020\000\370\000\370\000\370\202\020" + "\202\020\202\020\202\020\202\020\202\020\202\020\202\020\000\370\000\370\000\370\202\020" + "\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202" + "\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020" + "\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202" + "\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020" + "\202\020\202\020\202\020\202\020\202\020\202\020\202\020\000\370\000\370\000\370\202\020" + "\202\020\202\020\202\020\202\020\202\020\202\020\202\020\000\370\000\370\000\370\202\020" + "\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202" + "\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020" + "\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202" + "\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020" + "\202\020\202\020\202\020\202\020\202\020\202\020\202\020\000\370\000\370\000\370\202\020" + "\202\020\202\020\202\020\202\020\202\020\202\020\202\020\000\370\000\370\000\370\202\020" + "\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202" + "\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020" + "\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202" + "\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020" + "\202\020\202\020\202\020\202\020\202\020\202\020\202\020\000\370\000\370\000\370\202\020" + "\202\020\202\020\202\020\202\020\202\020\202\020\202\020\000\370\000\370\000\370\202\020" + "\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202" + "\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020" + "\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202" + "\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020" + "\202\020\202\020\202\020\202\020\202\020\202\020\202\020\000\370\000\370\000\370\202\020" + "\202\020\202\020\202\020\202\020\202\020\202\020\202\020\000\370\000\370\000\370\202\020" + "\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202" + "\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020" + "\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202" + "\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020" + "\202\020\202\020\202\020\202\020\202\020\202\020\202\020\000\370\000\370\000\370\202\020" + "\202\020\202\020\202\020\202\020\202\020\202\020\202\020\000\370\000\370\000\370\202\020" + "\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202" + "\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020" + "\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202" + "\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020" + "\202\020\202\020\202\020\202\020\202\020\202\020\202\020\000\370\000\370\000\370\202\020" + "\202\020\202\020\202\020\202\020\202\020\202\020\202\020\000\370\000\370\000\370\202\020" + "\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202" + "\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020" + "\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202" + "\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020" + "\202\020\202\020\202\020\202\020\202\020\202\020\202\020\000\370\000\370\000\370\202\020" + "\202\020\202\020\202\020\202\020\202\020\202\020\202\020\000\370\000\370\000\370\202\020" + "\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202" + "\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020" + "\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202" + "\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020" + "\202\020\202\020\202\020\202\020\202\020\202\020\202\020\000\370\000\370\000\370\202\020" + "\202\020\202\020\202\020\202\020\202\020\202\020\202\020\000\370\000\370\000\370\202\020" + "\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202" + "\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020" + "\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202" + "\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020" + "\202\020\202\020\202\020\202\020\202\020\202\020\202\020\000\370\000\370\000\370\202\020" + "\202\020\202\020\202\020\202\020\202\020\202\020\202\020\000\370\000\370\000\370\202\020" + "\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202" + "\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020" + "\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202" + "\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020" + "\202\020\202\020\202\020\202\020\202\020\202\020\202\020\000\370\000\370\000\370\202\020" + "\202\020\202\020\202\020\202\020\202\020\202\020\202\020\000\370\000\370\000\370\202\020" + "\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202" + "\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020" + "\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202" + "\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020" + "\202\020\202\020\202\020\202\020\202\020\202\020\202\020\000\370\000\370\000\370\202\020" + "\202\020\202\020\202\020\202\020\202\020\202\020\202\020\000\370\000\370\000\370\202\020" + "\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202" + "\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020" + "\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202" + "\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020" + "\202\020\202\020\202\020\202\020\202\020\202\020\202\020\000\370\000\370\000\370\202\020" + "\202\020\202\020\202\020\202\020\202\020\202\020\202\020\000\370\000\370\000\370\202\020" + "\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202" + "\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020" + "\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202" + "\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020" + "\202\020\202\020\202\020\202\020\202\020\202\020\202\020\000\370\000\370\000\370\202\020" + "\202\020\202\020\202\020\202\020\202\020\202\020\202\020\000\370\000\370\000\370\202\020" + "\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202" + "\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020" + "\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202" + "\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020" + "\202\020\202\020\202\020\202\020\202\020\202\020\202\020\000\370\000\370\000\370\202\020" + "\202\020\202\020\202\020\202\020\202\020\202\020\202\020\000\370\000\370\000\370\202\020" + "\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202" + "\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020" + "\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202" + "\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020" + "\202\020\202\020\202\020\202\020\202\020\202\020\202\020\000\370\000\370\000\370\202\020" + "\202\020\202\020\202\020\202\020\202\020\202\020\202\020\000\370\000\370\000\370\202\020" + "\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202" + "\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020" + "\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202" + "\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020" + "\202\020\202\020\202\020\202\020\202\020\202\020\202\020\000\370\000\370\000\370\202\020" + "\202\020\202\020\202\020\202\020\202\020\202\020\000\370\000\370\000\370\000\370\202\020" + "\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202" + "\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020" + "\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202" + "\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020" + "\202\020\202\020\202\020\202\020\202\020\202\020\202\020\000\370\000\370\000\370\000\370" + "\202\020\202\020\202\020\202\020\000\370\000\370\000\370\000\370\000\370\000\370\202\020\202" + "\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020" + "\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202" + "\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020" + "\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202" + "\020\202\020\202\020\202\020\202\020\202\020\202\020\000\370\000\370\000\370\000\370\000\370" + "\000\370\202\020\000\370\000\370\000\370\000\370\000\370\000\370\000\370\000\370\000\370\000\370" + "\000\370\000\370\000\370\000\370\000\370\000\370\000\370\000\370\000\370\000\370\000\370\000\370" + "\000\370\000\370\000\370\000\370\000\370\000\370\000\370\000\370\000\370\000\370\000\370\000\370" + "\000\370\000\370\000\370\000\370\000\370\000\370\000\370\000\370\000\370\000\370\000\370\000\370" + "\000\370\000\370\000\370\000\370\000\370\000\370\000\370\000\370\000\370\000\370\000\370\000\370" + "\000\370\000\370\000\370\000\370\000\370\000\370\000\370\000\370\000\370\000\370\000\370\000\370" + "\000\370\000\370\000\370\000\370\000\370\000\370\000\370\000\370\000\370\000\370\000\370\000\370" + "\000\370\000\370\000\370\000\370\000\370\000\370\000\370\000\370\000\370\000\370\000\370\000\370" + "\000\370\000\370\000\370\000\370\000\370\000\370\000\370\000\370\000\370\000\370\000\370\000\370" + "\000\370\000\370\000\370\000\370\000\370\000\370\000\370\000\370\000\370\000\370\000\370\000\370" + "\000\370\000\370\000\370\000\370\000\370\000\370\000\370\000\370\000\370\000\370\202\020\202\020" + "\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202" + "\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020" + "\202\020\202\020\000\350\000\370\000\370\000\370\000\370\000\370\000\370\000\370\000\370\000\370" + "\000\370\000\370\000\370\000\350\202\020\202\020\202\020\202\020\202\020\202\020\202\020" + "\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202" + "\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020" + "\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202" + "\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020" + "\202\020A\300\000\370\000\370\000\370\000\370\000\370\000\370\000\370\000\370\000\370\000\370" + "\000\370\000\370A\300\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020" + "\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202" + "\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020" + "\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202" + "\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020" + "ap\000\360\000\370\000\370\000\370\000\370\000\370\000\370\000\370\000\370\000\370\000\370\000\360" + "ap\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020" + "\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202" + "\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020" + "\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202" + "\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020A\250\000" + "\370\000\370\000\370\000\370\000\370\000\370\000\370\000\370\000\370\000\370A\250\202\020\202" + "\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020" + "\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202" + "\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020" + "\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202" + "\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020A\250\000" + "\360\000\370\000\370\000\370\000\370\000\370\000\370\000\360A\250\202\020\202\020\202\020" + "\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202" + "\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020" + "\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202" + "\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020" + "\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020ap" + "A\300\000\350\000\370\000\370\000\350A\300ap\202\020\202\020\202\020\202\020\202\020\202" + "\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020" + "\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202\020\202" + "\020\202\020", +}; + diff --git a/bell.h b/bell.h new file mode 100644 index 0000000..0c77f9e --- /dev/null +++ b/bell.h @@ -0,0 +1,11 @@ +#ifndef SMART_ALARM_BELL_H +#define SMART_ALARM_BELL_H +#include + +struct bell_image_t{ + uint8_t width; + uint8_t height; + uint8_t pixel_data[64 * 64 * 2 + 1]; +}; +extern const struct bell_image_t bell_image; +#endif //SMART_ALARM_BELL_H \ No newline at end of file diff --git a/display.cpp b/display.cpp index 5fc966b..2ebea58 100644 --- a/display.cpp +++ b/display.cpp @@ -243,6 +243,7 @@ void print_alarm(alarm *alarm, selected_t selected, uint8_t x, u_int8_t y) { break; case 2: // enable/disable alarm->set_state(!alarm->enabled()); + rearm_alarm_timers(); break; case 10: // every other week alarm->set_every_other_week(!alarm->every_other_week()); diff --git a/display.h b/display.h index 4ded42d..4a9e3ca 100644 --- a/display.h +++ b/display.h @@ -25,4 +25,6 @@ void print_add_button(uint8_t center_x, uint8_t center_y,uint8_t w, uint16_t col #define MAX_Y 240 #define ALARM_BOX_WIDTH 70 #define ALARM_BOX_HEIGHT 30 + +#define ORANGE 0xf420 #endif //SMART_ALARM_DISPLAY_H \ No newline at end of file diff --git a/link.h b/link.h new file mode 100644 index 0000000..a9ddc90 --- /dev/null +++ b/link.h @@ -0,0 +1,8 @@ +#ifndef SMART_ALARM_LINK_H +#define SMART_ALARM_LINK_H +#include +extern uint32_t __StackTop; // Core 0 stack top +extern uint32_t __StackBottom; // Core 0 stack bottom +extern uint32_t __StackOneTop; // Core 1 stack top +extern uint32_t __StackOneBottom; // Core 1 stack bottom +#endif //SMART_ALARM_LINK_H \ No newline at end of file diff --git a/multicore_utils.cpp b/multicore_utils.cpp new file mode 100644 index 0000000..6e41303 --- /dev/null +++ b/multicore_utils.cpp @@ -0,0 +1,17 @@ + +#include + +#include "pins.h" +#include "hardware/gpio.h" +#include "pico/platform.h" +#include "pico/time.h" + +[[noreturn]] void core1_launch_with_reset_self() { + assert(get_core_num());// assert if called with core0 + gpio_put(INTERUPT_PIN, true); + while (true) { + sleep_ms(UINT32_MAX); + } +} + +void core0_launch_interupt_handler() {} diff --git a/pins.h b/pins.h index 0fe5666..da36fac 100644 --- a/pins.h +++ b/pins.h @@ -10,4 +10,5 @@ #define BUTTON_SECONDARY_PW 7 #define BUTTON_SECONDARY_IN 6 -#define LED_PIN 5 \ No newline at end of file +#define LED_PIN 5 +#define INTERUPT_PIN 2 \ No newline at end of file diff --git a/smart_alarm.cpp b/smart_alarm.cpp index 2532543..8f548c9 100644 --- a/smart_alarm.cpp +++ b/smart_alarm.cpp @@ -87,6 +87,8 @@ extern "C" void sync_system_time(unsigned int sec, unsigned int usec) { } } +uint8_t page_selected = 1; + int main() { stdio_init_all(); if (cyw43_arch_init()) { @@ -162,7 +164,7 @@ int main() { printf("SNTP initialized, waiting for time sync...\n"); - uint8_t page_selected = 1; + multicore_launch_core1(page_functions[page_selected]); diff --git a/smart_alarm.h b/smart_alarm.h new file mode 100644 index 0000000..29feb30 --- /dev/null +++ b/smart_alarm.h @@ -0,0 +1,5 @@ +#ifndef SMART_ALARM_SMART_ALARM_H +#define SMART_ALARM_SMART_ALARM_H +#include +extern uint8_t page_selected; +#endif //SMART_ALARM_SMART_ALARM_H \ No newline at end of file diff --git a/sound.cpp b/sound.cpp index efdb998..d558aea 100644 --- a/sound.cpp +++ b/sound.cpp @@ -58,7 +58,7 @@ void setup_pwm_audio() { pwm_set_gpio_level(SPEAKER_PIN, 128); // Set to middle level (silence) } -void play_audio() { +void play_alarm_audio() { audio_pos = 0; audio_playing = true; @@ -68,7 +68,7 @@ void play_audio() { add_repeating_timer_us(delay_us, audio_timer_callback, NULL, &timer); } -void stop_audio() { +void stop_alarm_audio() { audio_playing = false; pwm_set_gpio_level(SPEAKER_PIN, 128); // Return to silence level } \ No newline at end of file diff --git a/sound.h b/sound.h index 76314d1..bcd2df6 100644 --- a/sound.h +++ b/sound.h @@ -2,8 +2,8 @@ #define SMART_ALARM_SOUND_H void setup_pwm_audio(); -void play_audio(); -void stop_audio(); +void play_alarm_audio(); +void stop_alarm_audio(); extern volatile float volume_multiplier; diff --git a/ui.cpp b/ui.cpp index 801a4ff..956e9b3 100644 --- a/ui.cpp +++ b/ui.cpp @@ -12,10 +12,15 @@ #include "macros.h" #include "lwip/arch.h" #include "multicore_events.h" +#include "pins.h" +#include "smart_alarm.h" #include "pico/multicore.h" #include "pico/time.h" #include "sound.h" #include "timezones.h" +#include "hardware/gpio.h" +#include "bell.h" +#include "link.h" bool secondary_button_override = false; @@ -51,7 +56,7 @@ void volume_update(configuration* self,bool hard) } } -void config_page() { +[[noreturn]] void config_page() { char volume_str[17]; char timezone_str[41]; std::array options = {{{timezone_str,&timezone_set_text,&timezone_update,timezone_index, 0,true}, {volume_str,&volume_set_text,&volume_update,*(uint32_t*)&volume_multiplier, 0, false}}}; @@ -161,7 +166,7 @@ void config_page() { } -void time_page() { +[[noreturn]] void time_page() { draw_ui_circle(MAGENTA); print_time(true); while (true) { @@ -235,3 +240,43 @@ static uint8_t get_alarm_y(uint8_t index) { std::array page_functions = {config_page, time_page, alarm_set_page}; + +[[noreturn]] void alarm_gone_off_page() { + printf("alarm went off\n"); + clear_display(); + page_selected = 1; + secondary_button_override = false; + draw_ui_circle(ORANGE); + gc9a01_blit_buffer(&display,120-(bell_image.width/2),180-(bell_image.height/2),bell_image.width,bell_image.height,const_cast(bell_image.pixel_data),std::size(bell_image.pixel_data)); + gpio_put(LED_PIN, true); + play_alarm_audio(); + print_time(true); + multicore_fifo_drain(); + while (true) { + { + uint32_t event; + if (multicore_fifo_pop_timeout_us(500000,&event)) { + if (event == PRIMARY_BUTTON_PRESSED) { + stop_alarm_audio(); + gpio_put(LED_PIN, false); + clear_display(); + if (get_core_num()) { + asm volatile ( + "ldr r3, %[stack_top] \n\t" + "mov sp, r3 \n\t" + : + : [stack_top] "m" (__StackOneTop) + : "r3" + );// clear the stack to prevent stack overflow from circular function calling + time_page(); + } else { + multicore_launch_core1(&time_page); + } + } + } + multicore_fifo_drain(); + + } + print_time(); + } +} \ No newline at end of file diff --git a/ui.h b/ui.h index 9a495c6..6c24a09 100644 --- a/ui.h +++ b/ui.h @@ -3,4 +3,5 @@ #include extern std::array page_functions; extern bool secondary_button_override; +void alarm_gone_off_page(); #endif //SMART_ALARM_UI_H \ No newline at end of file