another update add alarm config
This commit is contained in:
parent
4e6396459a
commit
ecfb7ef1bc
@ -40,6 +40,7 @@ add_executable(smart_alarm smart_alarm.cpp
|
|||||||
sound.cpp
|
sound.cpp
|
||||||
ui.cpp
|
ui.cpp
|
||||||
fonts/Font5x7FixedMono.c
|
fonts/Font5x7FixedMono.c
|
||||||
|
alarm.cpp
|
||||||
)
|
)
|
||||||
|
|
||||||
pico_set_program_name(smart_alarm "smart_alarm")
|
pico_set_program_name(smart_alarm "smart_alarm")
|
||||||
|
|||||||
125
alarm.cpp
Normal file
125
alarm.cpp
Normal file
@ -0,0 +1,125 @@
|
|||||||
|
#include <array>
|
||||||
|
#include <cstdint>
|
||||||
|
#include <cstdlib>
|
||||||
|
#include <vector>
|
||||||
|
#include "alarm.h"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
alarm::alarm(uint8_t hours, uint8_t minutes, const std::array<bool, 7> &days_enabled, bool every_other_week, bool even_week){
|
||||||
|
this->minutes_store = minutes;
|
||||||
|
|
||||||
|
// Initialize scheduled field
|
||||||
|
this->scheduled = 0;
|
||||||
|
|
||||||
|
// Set bits 0-6 for days of the week
|
||||||
|
for (int i = 0; i < 7; i++) {
|
||||||
|
if (days_enabled[i]) {
|
||||||
|
this->scheduled |= (1 << i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set bit 7 for every other week functionality
|
||||||
|
if (every_other_week) {
|
||||||
|
this->scheduled |= (1 << 7);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Initialize hours field
|
||||||
|
this->hours_and_stuff_store = 0;
|
||||||
|
|
||||||
|
// Set bit 0 for even/odd week (only relevant if every_other_week is true)
|
||||||
|
if (every_other_week && even_week) {
|
||||||
|
this->hours_and_stuff_store |= (1 << 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set bit 1 as disabled flag
|
||||||
|
this->hours_and_stuff_store &= ~(1 << 1);
|
||||||
|
|
||||||
|
// Bit 2 is reserved (left as 0)
|
||||||
|
|
||||||
|
// Set bits 3-7 with actual hours value (shift left by 3)
|
||||||
|
this->hours_and_stuff_store |= (hours & 0x1F) << 3; // 0x1F masks to 5 bits (0-31)
|
||||||
|
};
|
||||||
|
|
||||||
|
uint8_t alarm::minutes() const {
|
||||||
|
return minutes_store;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t alarm::hours() const {
|
||||||
|
return (hours_and_stuff_store >> 3) & 0x1F; // Extract bits 3-7 and mask to 5 bits
|
||||||
|
}
|
||||||
|
|
||||||
|
std::array<bool, 7> alarm::days_enabled() const {
|
||||||
|
std::array<bool, 7> days;
|
||||||
|
for (int i = 0; i < 7; i++) {
|
||||||
|
days[i] = (scheduled & (1 << i)) != 0;
|
||||||
|
}
|
||||||
|
return days;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool alarm::every_other_week() const {
|
||||||
|
return (scheduled & (1 << 7)) != 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool alarm::even_week() const {
|
||||||
|
return (hours_and_stuff_store & (1 << 0)) != 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool alarm::enabled() const {
|
||||||
|
return (hours_and_stuff_store & (1 << 1)) != 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Enable/disable methods
|
||||||
|
void alarm::enable() {
|
||||||
|
hours_and_stuff_store |= (1 << 1); // Set bit 1
|
||||||
|
}
|
||||||
|
|
||||||
|
void alarm::disable() {
|
||||||
|
hours_and_stuff_store &= ~(1 << 1); // Clear bit 1
|
||||||
|
}
|
||||||
|
|
||||||
|
void alarm::set_state(bool enabled) {
|
||||||
|
if (enabled) {
|
||||||
|
enable();
|
||||||
|
} else {
|
||||||
|
disable();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void alarm::set_minutes(uint8_t minutes) {
|
||||||
|
this->minutes_store = minutes;
|
||||||
|
}
|
||||||
|
|
||||||
|
void alarm::set_hours(uint8_t hours) {
|
||||||
|
this->hours_and_stuff_store &= ~(0x1F << 3); // Clear bits 3-7
|
||||||
|
this->hours_and_stuff_store |= (hours & 0x1F) << 3; // Set new hours
|
||||||
|
}
|
||||||
|
|
||||||
|
void alarm::set_days_enabled(const std::array<bool, 7>& days_enabled) {
|
||||||
|
this->scheduled &= (1 << 7); // Keep only bit 7 (every_other_week)
|
||||||
|
|
||||||
|
// Set new day bits
|
||||||
|
for (int i = 0; i < 7; i++) {
|
||||||
|
if (days_enabled[i]) {
|
||||||
|
this->scheduled |= (1 << i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void alarm::set_every_other_week(bool every_other_week) {
|
||||||
|
if (every_other_week) {
|
||||||
|
this->scheduled |= (1 << 7); // Set bit 7
|
||||||
|
} else {
|
||||||
|
this->scheduled &= ~(1 << 7); // Clear bit 7
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void alarm::set_even_week(bool even_week) {
|
||||||
|
if (even_week) {
|
||||||
|
this->hours_and_stuff_store |= (1 << 0); // Set bit 0
|
||||||
|
} else {
|
||||||
|
this->hours_and_stuff_store &= ~(1 << 0); // Clear bit 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<alarm> alarms;
|
||||||
36
alarm.h
Normal file
36
alarm.h
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
#ifndef SMART_ALARM_PERSISTANCE_H
|
||||||
|
#define SMART_ALARM_PERSISTANCE_H
|
||||||
|
#include <array>
|
||||||
|
#include <cstdint>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
struct alarm
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
uint8_t scheduled; // BITs used to mark days 1 ring on that day 0 dosn't ring on that day last bit marks if it should rind only every other week, if all BITs are 0 it will ring only once
|
||||||
|
uint8_t hours_and_stuff_store; // if every other week is selected it will check first bit of this if it is 1 it will ring on even weeks and if 0 it will ring on odd week next 1 is enabled flags, next BIT is reserved rest is hours
|
||||||
|
uint8_t minutes_store;
|
||||||
|
public:
|
||||||
|
alarm(uint8_t hours, uint8_t minutes, const std::array<bool, 7> &days_enabled, bool every_other_week, bool even_week);
|
||||||
|
|
||||||
|
[[nodiscard]] uint8_t minutes() const;
|
||||||
|
[[nodiscard]] uint8_t hours() const;
|
||||||
|
[[nodiscard]] std::array<bool, 7> days_enabled() const;
|
||||||
|
[[nodiscard]] bool every_other_week() const;
|
||||||
|
[[nodiscard]] bool even_week() const;
|
||||||
|
[[nodiscard]] bool enabled() const;
|
||||||
|
|
||||||
|
// Enable/disable methods
|
||||||
|
void enable();
|
||||||
|
void disable();
|
||||||
|
void set_state(bool enabled);
|
||||||
|
|
||||||
|
void set_minutes(uint8_t minutes);
|
||||||
|
void set_hours(uint8_t hours);
|
||||||
|
void set_days_enabled(const std::array<bool, 7>& days_enabled);
|
||||||
|
void set_every_other_week(bool every_other_week);
|
||||||
|
void set_even_week(bool even_week);
|
||||||
|
};
|
||||||
|
|
||||||
|
extern std::vector<alarm> alarms;
|
||||||
|
#endif //SMART_ALARM_PERSISTANCE_H
|
||||||
186
display.cpp
186
display.cpp
@ -10,11 +10,17 @@
|
|||||||
#include "pico/time.h"
|
#include "pico/time.h"
|
||||||
#include "spi.h"
|
#include "spi.h"
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
|
#include <cstring>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
#include "Font5x7FixedMono.h"
|
#include "Font5x7FixedMono.h"
|
||||||
|
#include "alarm.h"
|
||||||
|
#include "control.h"
|
||||||
|
#include "macros.h"
|
||||||
|
#include "multicore_events.h"
|
||||||
|
|
||||||
#include "hardware/rtc.h"
|
#include "hardware/rtc.h"
|
||||||
|
#include "pico/multicore.h"
|
||||||
|
|
||||||
int32_t t_fine;
|
int32_t t_fine;
|
||||||
uint16_t dig_T1;
|
uint16_t dig_T1;
|
||||||
@ -74,18 +80,25 @@ gc9a01_GC9A01_obj_t create_lcd() {
|
|||||||
|
|
||||||
gc9a01_GC9A01_obj_t display;
|
gc9a01_GC9A01_obj_t display;
|
||||||
|
|
||||||
void draw_ui_circle(uint16_t color)
|
void draw_circle(int16_t x_center, int16_t y_center, int16_t r,
|
||||||
{
|
uint16_t color) {
|
||||||
for (int i = 720; i > 0; i--) {
|
for (uint16_t i = 720; i > 0; i--) {
|
||||||
int x = 120 + (int)(119.0 * sin((180.0 + i / 2.0) * M_TWOPI / 360.0));
|
uint8_t x = x_center +
|
||||||
int y = 120 + (int)(119.0 * cos((180.0 + i / 2.0) * M_TWOPI / 360.0));
|
static_cast<int16_t>(static_cast<float>(r) *
|
||||||
|
sin((180.0 + i / 2.0) * M_TWOPI / 360.0));
|
||||||
|
uint8_t y = y_center +
|
||||||
|
static_cast<int16_t>(static_cast<float>(r) *
|
||||||
|
cos((180.0 + i / 2.0) * M_TWOPI / 360.0));
|
||||||
gc9a01_draw_pixel(&display, x, y, color);
|
gc9a01_draw_pixel(&display, x, y, color);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void draw_ui_circle(uint16_t color) { draw_circle(120, 120, 119, color); }
|
||||||
|
|
||||||
std::array<uint16_t,2> get_ui_circle_vertical_pos(uint16_t x, uint16_t center_x, uint16_t center_y, uint16_t radius)
|
std::array<uint16_t, 2> get_ui_circle_vertical_pos(uint16_t x,
|
||||||
{
|
uint16_t center_x,
|
||||||
|
uint16_t center_y,
|
||||||
|
uint16_t radius) {
|
||||||
// Ctalculate horizontal distance from point to center
|
// Ctalculate horizontal distance from point to center
|
||||||
uint16_t dx = x - center_x;
|
uint16_t dx = x - center_x;
|
||||||
uint16_t dx_squared = dx * dx;
|
uint16_t dx_squared = dx * dx;
|
||||||
@ -93,7 +106,7 @@ std::array<uint16_t,2> get_ui_circle_vertical_pos(uint16_t x, uint16_t center_x,
|
|||||||
|
|
||||||
// Check if point's x-coordinate is within circle bounds
|
// Check if point's x-coordinate is within circle bounds
|
||||||
if (dx_squared >= radius_squared) {
|
if (dx_squared >= radius_squared) {
|
||||||
return {0,0}; // Outside circle - no vertical space
|
return {0, 0}; // Outside circle - no vertical space
|
||||||
}
|
}
|
||||||
|
|
||||||
// Calculate vertical distance from center to circle edge at this x
|
// Calculate vertical distance from center to circle edge at this x
|
||||||
@ -103,14 +116,12 @@ std::array<uint16_t,2> get_ui_circle_vertical_pos(uint16_t x, uint16_t center_x,
|
|||||||
uint16_t y_top = center_y - (uint16_t)vertical_offset;
|
uint16_t y_top = center_y - (uint16_t)vertical_offset;
|
||||||
uint16_t y_bottom = center_y + (uint16_t)vertical_offset;
|
uint16_t y_bottom = center_y + (uint16_t)vertical_offset;
|
||||||
|
|
||||||
std::array<uint16_t,2> positions ={y_top,y_bottom};
|
std::array<uint16_t, 2> positions = {y_top, y_bottom};
|
||||||
|
|
||||||
return positions;
|
return positions;
|
||||||
}
|
}
|
||||||
|
|
||||||
void clear_display() {
|
void clear_display() { gc9a01_fill(&display, BLACK); }
|
||||||
gc9a01_fill(&display, BLACK);
|
|
||||||
}
|
|
||||||
|
|
||||||
void display_start() {
|
void display_start() {
|
||||||
char buf[10];
|
char buf[10];
|
||||||
@ -121,31 +132,158 @@ void display_start() {
|
|||||||
sleep_ms(100);
|
sleep_ms(100);
|
||||||
clear_display();
|
clear_display();
|
||||||
|
|
||||||
|
|
||||||
draw_ui_circle(MAGENTA);
|
draw_ui_circle(MAGENTA);
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void print_time(const bool force_refresh) {
|
void print_time(const bool force_refresh) {
|
||||||
datetime_t t;
|
datetime_t t;
|
||||||
if (rtc_get_datetime(&t)) {
|
if (rtc_get_datetime(&t)) {
|
||||||
const GFXfont* font = &VGA1_16x32;
|
const GFXfont *font = &VGA1_16x32;
|
||||||
char buf[11];
|
char buf[11];
|
||||||
sprintf(buf,"%02d:%02d:%02d", t.hour, t.min, t.sec);
|
sprintf(buf, "%02d:%02d:%02d", t.hour, t.min, t.sec);
|
||||||
gc9a01_text(&display,font,buf,120-((16*8)/2),120-16,WHITE, BLACK);
|
gc9a01_text(&display, font, buf, 120 - ((16 * 8) / 2), 120 - 16, WHITE,
|
||||||
|
BLACK);
|
||||||
|
|
||||||
static uint8_t last_day = UINT8_MAX;
|
static uint8_t last_day = UINT8_MAX;
|
||||||
if (last_day != t.day || force_refresh) {
|
if (last_day != t.day || force_refresh) {
|
||||||
font = &Font5x7FixedMono;
|
font = &Font5x7FixedMono;
|
||||||
sprintf(buf,"%02d.%02d.%04d",t.day,t.month,t.year);
|
sprintf(buf, "%02d.%02d.%04d", t.day, t.month, t.year);
|
||||||
gc9a01_text_gfx_buffered(&display,font,buf,120-((6*10)/2),((120-16)+32)+7,WHITE,BLACK);
|
gc9a01_text_gfx_buffered(&display, font, buf, 120 - ((6 * 10) / 2),
|
||||||
|
((120 - 16) + 32) + 7, WHITE, BLACK);
|
||||||
last_day = t.day;
|
last_day = t.day;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
const char* rtc_fail= "NO SYNC!";
|
const char *rtc_fail = "NO SYNC!";
|
||||||
const GFXfont* font = &Font5x7FixedMono;
|
const GFXfont *font = &Font5x7FixedMono;
|
||||||
gc9a01_text_gfx_buffered(&display,font,rtc_fail,120-((5*8)/2),120-((7*1)/2),RED,BLACK);
|
gc9a01_text_gfx_buffered(&display, font, rtc_fail, 120 - ((5 * 8) / 2),
|
||||||
|
120 - ((7 * 1) / 2), RED, BLACK);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void print_alarm(alarm *alarm, selected_t selected, uint8_t x, u_int8_t y) {
|
||||||
|
bool setting_sub = false;
|
||||||
|
uint8_t selected_item = UINT8_MAX;
|
||||||
|
do
|
||||||
|
{
|
||||||
|
uint8_t item_index = 0;
|
||||||
|
gc9a01_rect(&display, x, y, ALARM_BOX_WIDTH, ALARM_BOX_HEIGHT, selected);
|
||||||
|
char buf[3];
|
||||||
|
sprintf(buf, "%02d", alarm->hours());
|
||||||
|
if (selected_item == item_index) {
|
||||||
|
gc9a01_fill_rect(&display,((x + ALARM_BOX_WIDTH / 2) - ((strlen(buf) * 5) / 2)) - 2,y + 3,(5*2)+1,7,BLACK);
|
||||||
|
}
|
||||||
|
gc9a01_text_gfx_buffered(&display, &Font5x7FixedMono, buf,((x + ALARM_BOX_WIDTH / 2) - ((strlen(buf) * 5) / 2)) - 2, y + 10, selected_item == item_index ? setting_sub ? SETTING : SELECTED : WHITE,BLACK);
|
||||||
|
item_index++;
|
||||||
|
sprintf(buf, ":");
|
||||||
|
gc9a01_text_gfx_buffered(&display, &Font5x7FixedMono, buf,(((x + ALARM_BOX_WIDTH / 2) - ((strlen(buf) * 5) / 2)) - 2)+(5*2)-(5/2), y + 10, WHITE,BLACK);
|
||||||
|
sprintf(buf, "%02d", alarm->minutes());
|
||||||
|
if (selected_item == item_index) {
|
||||||
|
gc9a01_fill_rect(&display,(((x + ALARM_BOX_WIDTH / 2) - ((strlen(buf) * 5) / 2)) - 2)+5*3,y + 3,(5*2)+1,7,BLACK);
|
||||||
|
}
|
||||||
|
gc9a01_text_gfx_buffered(&display, &Font5x7FixedMono, buf,(((x + ALARM_BOX_WIDTH / 2) - ((strlen(buf) * 5) / 2)) - 2)+5*3, y + 10, selected_item == item_index ? setting_sub ? SETTING : SELECTED : WHITE,BLACK);
|
||||||
|
item_index++;
|
||||||
|
|
||||||
|
gc9a01_fill_rect(&display, x+ALARM_BOX_WIDTH-7,
|
||||||
|
y+2,5,7,alarm->enabled() ? GREEN : RED);
|
||||||
|
if (selected_item == item_index) {
|
||||||
|
gc9a01_rect(&display, x+ALARM_BOX_WIDTH-7,
|
||||||
|
y+2,5,7,alarm->enabled() ? RED : GREEN);
|
||||||
|
}
|
||||||
|
item_index++;
|
||||||
|
|
||||||
|
u_int8_t x_text_abrivs = x + (5 / 2);
|
||||||
|
{
|
||||||
|
std::array<bool, 7> days_enabled = alarm->days_enabled();
|
||||||
|
|
||||||
|
for (uint8_t i = 0; i < days_enabled.size(); i++) {
|
||||||
|
gc9a01_fill_rect(&display, x_text_abrivs,
|
||||||
|
(y + ALARM_BOX_HEIGHT) - 10,5,7,days_enabled[i] ? GREEN : RED);
|
||||||
|
if (selected_item == item_index) {
|
||||||
|
gc9a01_rect(&display, x_text_abrivs,
|
||||||
|
(y + ALARM_BOX_HEIGHT) - 10,5,7,days_enabled[i] ? RED : GREEN);
|
||||||
|
}
|
||||||
|
item_index++;
|
||||||
|
x_text_abrivs += 5 + 5 / 2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (alarm->every_other_week()) {
|
||||||
|
char c = '=';
|
||||||
|
if (selected_item == item_index) {
|
||||||
|
gc9a01_fill_rect(&display, x_text_abrivs,(y + ALARM_BOX_HEIGHT) - 7, 5, 1, BLACK);
|
||||||
|
}
|
||||||
|
gc9a01_text_gfx_buffered(&display, &Font5x7FixedMono,&c,x_text_abrivs,(y + ALARM_BOX_HEIGHT) - 3,selected_item == item_index ? SELECTED : MAGENTA,BLACK);
|
||||||
|
item_index++;
|
||||||
|
x_text_abrivs += 5 + 5 / 2;
|
||||||
|
c = alarm->even_week() ? '2' : '1';
|
||||||
|
if (selected_item == item_index && c == '1') {
|
||||||
|
gc9a01_fill_rect(&display, x_text_abrivs+4,(y + ALARM_BOX_HEIGHT) - 9,1,2,BLACK);
|
||||||
|
}
|
||||||
|
gc9a01_text_gfx_buffered(&display, &Font5x7FixedMono,&c,x_text_abrivs,(y + ALARM_BOX_HEIGHT) - 3,selected_item == item_index ? SELECTED : alarm->even_week() ? MAGENTA : CYAN,BLACK);
|
||||||
|
item_index++;
|
||||||
|
} else {
|
||||||
|
constexpr char c = '-';
|
||||||
|
if (selected_item == item_index) {
|
||||||
|
gc9a01_fill_rect(&display, x_text_abrivs,(y + ALARM_BOX_HEIGHT) - 8, 5, 3, BLACK);
|
||||||
|
}
|
||||||
|
gc9a01_text_gfx_buffered(&display, &Font5x7FixedMono,&c,x_text_abrivs,(y + ALARM_BOX_HEIGHT) - 3,selected_item == item_index ? SELECTED : CYAN,BLACK);
|
||||||
|
item_index++;
|
||||||
|
}
|
||||||
|
if (selected == selected_t::SETTING) {
|
||||||
|
switch (static_cast<multicore_event_t>(multicore_fifo_pop_blocking())) {
|
||||||
|
case PRIMARY_BUTTON_PRESSED:
|
||||||
|
if (setting_sub) {
|
||||||
|
setting_sub = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
switch (selected_item) {
|
||||||
|
case 0: // hours
|
||||||
|
case 1: // minutes
|
||||||
|
setting_sub = true;
|
||||||
|
break;
|
||||||
|
case 2: // enable/disable
|
||||||
|
alarm->set_state(!alarm->enabled());
|
||||||
|
break;
|
||||||
|
case 10: // every other week
|
||||||
|
alarm->set_every_other_week(!alarm->every_other_week());
|
||||||
|
break;
|
||||||
|
case 11: // even week
|
||||||
|
alarm->set_even_week(!alarm->even_week());
|
||||||
|
break;
|
||||||
|
default: // days of the week
|
||||||
|
std::array<bool, 7> days_enabled = alarm->days_enabled();
|
||||||
|
days_enabled[selected_item-3] = !days_enabled[selected_item-3];
|
||||||
|
alarm->set_days_enabled(days_enabled);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case SECONDARY_BUTTON_PRESSED:
|
||||||
|
goto exit_print_alarm;
|
||||||
|
case KNOB_CHANGE: {
|
||||||
|
if (!setting_sub)
|
||||||
|
{selected_item = std::min(static_cast<uint8_t>(static_cast<float>(get_knob_percentage())/100.0f*static_cast<float>(item_index)),static_cast<uint8_t>(item_index-1));} else {
|
||||||
|
switch (selected_item) {
|
||||||
|
case 0:
|
||||||
|
alarm->set_hours(std::min(static_cast<uint8_t>(static_cast<float>(get_knob_percentage())/100.0f*static_cast<float>(24)),static_cast<uint8_t>(23)));
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
alarm->set_minutes(std::min(static_cast<uint8_t>(static_cast<float>(get_knob_percentage())/100.0f*static_cast<float>(60)),static_cast<uint8_t>(59)));
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
printf("ERROR: invalid option selected!!!\n");
|
||||||
|
}}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} while (selected == selected_t::SETTING);
|
||||||
|
exit_print_alarm:
|
||||||
|
return; // fix waring about C23 extension
|
||||||
|
}
|
||||||
|
|
||||||
|
void print_add_button(uint8_t center_x, uint8_t center_y, uint8_t w, uint16_t color) {
|
||||||
|
draw_circle(center_x, center_y, w/2, color);
|
||||||
|
const uint8_t plus_length = w - 7;
|
||||||
|
const uint8_t half_length = plus_length / 2;
|
||||||
|
gc9a01_hline(&display, center_x - half_length, center_y, plus_length, color);
|
||||||
|
gc9a01_vline(&display, center_x, center_y - half_length, plus_length, color);
|
||||||
}
|
}
|
||||||
|
|||||||
11
display.h
11
display.h
@ -3,6 +3,7 @@
|
|||||||
#include <array>
|
#include <array>
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
|
|
||||||
|
#include "alarm.h"
|
||||||
#include "gc9a01.h"
|
#include "gc9a01.h"
|
||||||
void display_start();
|
void display_start();
|
||||||
void print_time(bool force_refresh = false);
|
void print_time(bool force_refresh = false);
|
||||||
@ -12,6 +13,16 @@ std::array<uint16_t,2> get_ui_circle_vertical_pos(uint16_t x, uint16_t center_x
|
|||||||
|
|
||||||
extern gc9a01_GC9A01_obj_t display;
|
extern gc9a01_GC9A01_obj_t display;
|
||||||
|
|
||||||
|
enum selected_t {
|
||||||
|
NOT_SELECTED = WHITE,
|
||||||
|
SELECTED = GREEN,
|
||||||
|
SETTING = RED
|
||||||
|
};
|
||||||
|
|
||||||
|
void print_alarm(alarm* alarm, selected_t selected, uint8_t x,u_int8_t y);
|
||||||
|
void print_add_button(uint8_t center_x, uint8_t center_y,uint8_t w, uint16_t color);
|
||||||
#define MAX_X 240
|
#define MAX_X 240
|
||||||
#define MAX_Y 240
|
#define MAX_Y 240
|
||||||
|
#define ALARM_BOX_WIDTH 70
|
||||||
|
#define ALARM_BOX_HEIGHT 30
|
||||||
#endif //SMART_ALARM_DISPLAY_H
|
#endif //SMART_ALARM_DISPLAY_H
|
||||||
1
fonts/SOURCE
Normal file
1
fonts/SOURCE
Normal file
@ -0,0 +1 @@
|
|||||||
|
https://github.com/robjen/GFX_fonts
|
||||||
4
gen_sound.sh
Executable file
4
gen_sound.sh
Executable file
@ -0,0 +1,4 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
xxd -i alarm_sound.wav > alarm_sound.h
|
||||||
|
sed -i 's/unsigned/inline constexpr unsigned/g' alarm_sound.h
|
||||||
|
sed -i '1i\#pragma once\' alarm_sound.h
|
||||||
4
pins.h
4
pins.h
@ -8,4 +8,6 @@
|
|||||||
#define BUTTON_PRIMARY_IN 8
|
#define BUTTON_PRIMARY_IN 8
|
||||||
|
|
||||||
#define BUTTON_SECONDARY_PW 7
|
#define BUTTON_SECONDARY_PW 7
|
||||||
#define BUTTON_SECONDARY_IN 6
|
#define BUTTON_SECONDARY_IN 6
|
||||||
|
|
||||||
|
#define LED_PIN 5
|
||||||
@ -117,6 +117,8 @@ int main() {
|
|||||||
setup_pwm_audio();
|
setup_pwm_audio();
|
||||||
|
|
||||||
timezone_index = 353; // todo load from flash
|
timezone_index = 353; // todo load from flash
|
||||||
|
gpio_init(LED_PIN);
|
||||||
|
gpio_set_dir(LED_PIN, GPIO_OUT);
|
||||||
|
|
||||||
// sign of life
|
// sign of life
|
||||||
cyw43_arch_gpio_put(CYW43_WL_GPIO_LED_PIN, true);
|
cyw43_arch_gpio_put(CYW43_WL_GPIO_LED_PIN, true);
|
||||||
@ -173,7 +175,7 @@ int main() {
|
|||||||
|
|
||||||
if (!secondary_button_override) {
|
if (!secondary_button_override) {
|
||||||
page_selected =
|
page_selected =
|
||||||
page_selected + 1 >= page_functions.size() ? 0 : page_selected + 1;
|
page_selected + 1 >= page_functions.size() ? 0 : page_selected + 1;
|
||||||
multicore_reset_core1();
|
multicore_reset_core1();
|
||||||
clear_display();
|
clear_display();
|
||||||
multicore_launch_core1(page_functions[page_selected]);
|
multicore_launch_core1(page_functions[page_selected]);
|
||||||
|
|||||||
62
ui.cpp
62
ui.cpp
@ -171,7 +171,67 @@ void time_page() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void alarm_set_page() { draw_ui_circle(BLUE); }
|
static uint16_t get_alarm_x(uint8_t index) {
|
||||||
|
return (index % 2 == 0) ? 40 : (MAX_X - 40 - ALARM_BOX_WIDTH);
|
||||||
|
}
|
||||||
|
|
||||||
|
static uint8_t get_alarm_y(uint8_t index) {
|
||||||
|
return 40 + (index / 2) * (ALARM_BOX_HEIGHT + 5);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
[[noreturn]] void alarm_set_page() {
|
||||||
|
draw_ui_circle(BLUE);
|
||||||
|
full_redraw:
|
||||||
|
multicore_fifo_drain();
|
||||||
|
uint8_t y_pos = 40;
|
||||||
|
|
||||||
|
uint8_t selected_index = static_cast<uint8_t>(static_cast<float>(get_knob_percentage())/100.0f*static_cast<float>(alarms.size()));
|
||||||
|
for (uint8_t i = 0; i < alarms.size(); i++) {
|
||||||
|
print_alarm(&alarms[i], i == selected_index ? SELECTED : NOT_SELECTED, !(i % 2) ? 40 : MAX_X-40-ALARM_BOX_WIDTH,y_pos);
|
||||||
|
if (i % 2) {
|
||||||
|
y_pos += ALARM_BOX_HEIGHT+5;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
print_add_button(MAX_X/2,MAX_Y-14,20,selected_index == alarms.size() ? SELECTED : NOT_SELECTED);
|
||||||
|
|
||||||
|
while (true) {
|
||||||
|
switch (static_cast<multicore_event_t>(multicore_fifo_pop_blocking())) {
|
||||||
|
case PRIMARY_BUTTON_PRESSED:
|
||||||
|
if (selected_index == alarms.size()) {
|
||||||
|
alarms.emplace_back(0, 0, std::array<bool, 7>{false, false, false, false, false, false, false}, false, false);
|
||||||
|
goto full_redraw;
|
||||||
|
} else {
|
||||||
|
secondary_button_override = true;
|
||||||
|
print_alarm(&alarms[selected_index], SETTING,get_alarm_x(selected_index),get_alarm_y(selected_index));
|
||||||
|
secondary_button_override = false;
|
||||||
|
goto full_redraw;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case SECONDARY_BUTTON_PRESSED:
|
||||||
|
break;
|
||||||
|
case KNOB_CHANGE: {
|
||||||
|
uint8_t new_index = static_cast<uint8_t>(static_cast<float>(get_knob_percentage())/100.0f*static_cast<float>(alarms.size()));
|
||||||
|
if (new_index != selected_index) {
|
||||||
|
if (selected_index < alarms.size()) {
|
||||||
|
print_alarm(&alarms[selected_index], NOT_SELECTED,get_alarm_x(selected_index),get_alarm_y(selected_index));
|
||||||
|
} else {
|
||||||
|
print_add_button(MAX_X/2,MAX_Y-14,20,NOT_SELECTED);
|
||||||
|
}
|
||||||
|
if (new_index >= alarms.size()) {
|
||||||
|
print_add_button(MAX_X/2,MAX_Y-14,20,SELECTED);
|
||||||
|
} else {
|
||||||
|
print_alarm(&alarms[new_index], SELECTED,get_alarm_x(new_index),get_alarm_y(new_index));
|
||||||
|
}
|
||||||
|
selected_index = new_index;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
multicore_fifo_drain(); // prevent event stucking
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
std::array<void (*)(), 3> page_functions = {config_page, time_page,
|
std::array<void (*)(), 3> page_functions = {config_page, time_page,
|
||||||
alarm_set_page};
|
alarm_set_page};
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user