stub of settings
This commit is contained in:
+3
-2
@@ -22,9 +22,10 @@ add_executable(zavlaha
|
||||
src/lcd/lcdbuf.c
|
||||
src/screens/app_gui.c
|
||||
src/screens/screen_home.c
|
||||
src/screens/screen_settings.c
|
||||
src/screens/screen_cyklus.c
|
||||
src/app_io.c
|
||||
src/app_config.c
|
||||
src/screens/screen_cyklus.c)
|
||||
src/app_config.c)
|
||||
|
||||
# Add pico_stdlib library which aggregates commonly used features
|
||||
target_link_libraries(zavlaha pico_stdlib hardware_i2c hardware_adc hardware_irq)
|
||||
|
||||
+43
-5
@@ -2,20 +2,58 @@
|
||||
* TODO file description
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include "app_config.h"
|
||||
#include "ee.h"
|
||||
|
||||
#define APPCONFIG_EE_BASE_ADDR 0
|
||||
|
||||
// TODO sensible defaults, loading and saving to/from EE
|
||||
struct AppConfig app_config = {
|
||||
struct AppConfig app_config;
|
||||
|
||||
static const struct AppConfig DEFAULTS = {
|
||||
.circuit_base_time_s = 10, // for a test
|
||||
.circuit_time_percent = {30, 60, 90, 100}, // for a test
|
||||
.schedules = {
|
||||
{6, 45},
|
||||
{255, 0},
|
||||
{255, 0},
|
||||
{255, 0}
|
||||
{true, 6, 45},
|
||||
{false, 255, 0},
|
||||
{false, 255, 0},
|
||||
{false, 255, 0}
|
||||
},
|
||||
.moisture_enable = true,
|
||||
.moisture_dry = 2800,
|
||||
.moisture_wet = 1600,
|
||||
.moisture_threshold_percent = 70,
|
||||
};
|
||||
|
||||
static void load_fallback_config() {
|
||||
// Read failed, load defaults
|
||||
memcpy(&app_config, &DEFAULTS, sizeof(struct AppConfig));
|
||||
}
|
||||
|
||||
void appconfig_load()
|
||||
{
|
||||
uint8_t magic = 0;
|
||||
if (0 != ee_read(APPCONFIG_EE_BASE_ADDR, &magic, 1) || magic != APPCONFIG_VERSION) {
|
||||
printf("Couldn't read EE to check magic!\r\n");
|
||||
load_fallback_config();
|
||||
return;
|
||||
}
|
||||
|
||||
if (0 != ee_read(APPCONFIG_EE_BASE_ADDR, (uint8_t *) &app_config, APPCONFIG_SIZE)) {
|
||||
printf("Couldn't read EE to load config!\r\n");
|
||||
load_fallback_config();
|
||||
}
|
||||
}
|
||||
|
||||
void appconfig_save()
|
||||
{
|
||||
printf("PERSISTENCE DISABLED - NOT SAVING\r\n");
|
||||
return; // FIXME - when all GUIs are finished, add persistence
|
||||
|
||||
// whatever, just write everything
|
||||
if (0 != ee_write(APPCONFIG_EE_BASE_ADDR, (const uint8_t *) &app_config, APPCONFIG_SIZE)) {
|
||||
printf("Couldn't write EE!");
|
||||
}
|
||||
}
|
||||
|
||||
+14
-5
@@ -11,23 +11,32 @@
|
||||
#define CIRCUIT_COUNT 4
|
||||
#define SCHEDULE_COUNT 4
|
||||
|
||||
#define UNUSED_SCHEDULE_HOUR 0xFF
|
||||
|
||||
struct ScheduleTime {
|
||||
struct __attribute__((packed)) ScheduleTime {
|
||||
bool enable;
|
||||
uint8_t h;
|
||||
uint8_t m;
|
||||
};
|
||||
|
||||
struct AppConfig {
|
||||
struct __attribute__((packed)) AppConfig {
|
||||
uint8_t magic_version;
|
||||
uint16_t circuit_base_time_s;
|
||||
uint8_t circuit_time_percent[CIRCUIT_COUNT]; // 0% can be used to disable a branch
|
||||
struct ScheduleTime schedules[SCHEDULE_COUNT]; // 0xFF hour is used to disable the slot
|
||||
bool scheduler_enable;
|
||||
struct ScheduleTime schedules[SCHEDULE_COUNT];
|
||||
bool moisture_enable;
|
||||
uint16_t moisture_dry;
|
||||
uint16_t moisture_wet;
|
||||
uint8_t moisture_threshold_percent;
|
||||
};
|
||||
|
||||
#define APPCONFIG_SIZE sizeof(struct AppConfig)
|
||||
|
||||
#define APPCONFIG_VERSION 0b11100001
|
||||
|
||||
extern struct AppConfig app_config;
|
||||
|
||||
void appconfig_load();
|
||||
|
||||
void appconfig_save();
|
||||
|
||||
#endif //ZAVLAHA_APP_CONFIG_H
|
||||
|
||||
+2
-2
@@ -499,11 +499,11 @@ const struct LcdBuf_CGRAM_Symbol CGRAM_CZ[] = {
|
||||
.fallback = '*',
|
||||
.data = {
|
||||
0b11111,
|
||||
0b11011,
|
||||
0b01010,
|
||||
0b10001,
|
||||
0b00000,
|
||||
0b10001,
|
||||
0b01010,
|
||||
0b11011,
|
||||
0b11111,
|
||||
},
|
||||
},
|
||||
|
||||
+2
-2
@@ -97,8 +97,8 @@ const struct LcdBuf_CGROM_Entry CGROM_A00[] = {
|
||||
{.address = 123, .symbol = "{"},
|
||||
{.address = 124, .symbol = "|"},
|
||||
{.address = 125, .symbol = "}"},
|
||||
{.address = 126, .symbol = "←"},
|
||||
{.address = 127, .symbol = "→"},
|
||||
{.address = 126, .symbol = "→"},
|
||||
{.address = 127, .symbol = "←"},
|
||||
|
||||
// lots of japanese symbols - add them yourself if you need them
|
||||
{.address = 0xA2, .symbol = "「"},
|
||||
|
||||
+7
-1
@@ -11,6 +11,7 @@
|
||||
#include "ee.h"
|
||||
#include "lcd/lcdbuf.h"
|
||||
#include "screens/app_gui.h"
|
||||
#include "app_config.h"
|
||||
|
||||
/*
|
||||
|
||||
@@ -71,7 +72,7 @@ void irq_uart() {
|
||||
}
|
||||
}
|
||||
|
||||
int main()
|
||||
int __attribute__((noreturn)) main()
|
||||
{
|
||||
// picotool binary info
|
||||
bi_decl(bi_1pin_with_name(PIN_LED, "LED"));
|
||||
@@ -123,11 +124,14 @@ int main()
|
||||
adc_init();
|
||||
adc_gpio_init(PIN_MOISTURE);
|
||||
|
||||
appconfig_load();
|
||||
|
||||
lcd_init();
|
||||
|
||||
gui_init();
|
||||
|
||||
for(;;) {
|
||||
// Check if any key was pushed
|
||||
uint32_t interrupts = save_and_disable_interrupts();
|
||||
GuiEvent event = GUI_EVENT_NONE;
|
||||
if (keypad_buffer[keypad_buffer_rp] != 0) {
|
||||
@@ -142,6 +146,8 @@ int main()
|
||||
restore_interrupts(interrupts);
|
||||
|
||||
gui_loop_iter(event);
|
||||
|
||||
// TODO scheduler logic
|
||||
}
|
||||
|
||||
//
|
||||
|
||||
@@ -62,6 +62,11 @@ void gui_loop_iter(GuiEvent message) {
|
||||
/** Switch to a different screen handler.
|
||||
* If "init" is true, immediately call it with the init event. */
|
||||
void switch_screen(screen_t pScreen, bool init) {
|
||||
if (s_app.screen == pScreen) {
|
||||
// already, no op
|
||||
return;
|
||||
}
|
||||
|
||||
s_app.screen = pScreen;
|
||||
|
||||
LcdBuffer_Clear(&lcd);
|
||||
|
||||
@@ -49,6 +49,7 @@ void request_paint();
|
||||
|
||||
void screen_home(GuiEvent event);
|
||||
void screen_cyklus(GuiEvent event);
|
||||
void screen_settings(GuiEvent event);
|
||||
// XXX other prototypes
|
||||
|
||||
struct State {
|
||||
|
||||
@@ -12,6 +12,8 @@
|
||||
#include "ds_rtc.h"
|
||||
#include "app_io.h"
|
||||
|
||||
// TODO
|
||||
|
||||
|
||||
void screen_cyklus(GuiEvent event)
|
||||
{
|
||||
|
||||
@@ -16,7 +16,6 @@ static uint32_t last_time = 0;
|
||||
static struct rtc_time rtc_time = {};
|
||||
static uint16_t moisture = 0;
|
||||
|
||||
static char showbuf[20];
|
||||
static uint8_t showbuf_wp = 0;
|
||||
|
||||
void screen_home(GuiEvent event)
|
||||
@@ -26,7 +25,6 @@ void screen_home(GuiEvent event)
|
||||
|
||||
switch (event) {
|
||||
case GUI_EVENT_SCREEN_INIT:
|
||||
memset(showbuf, ' ', sizeof(showbuf));
|
||||
// pass
|
||||
case GUI_EVENT_SCREEN_TICK:
|
||||
if (elapsed >= 100) {
|
||||
@@ -37,9 +35,8 @@ void screen_home(GuiEvent event)
|
||||
}
|
||||
break;
|
||||
|
||||
case GUI_EVENT_PAINT:
|
||||
LcdBuffer_Write(&lcd, 0, 0, showbuf);
|
||||
|
||||
case GUI_EVENT_PAINT:;
|
||||
// TODO
|
||||
uint32_t moisture_pt = ((uint32_t)(moisture > 2800 ? 0 : (2800 - moisture)) * 100) / (2800 - 1600);
|
||||
|
||||
sprintf(stmp, " %2d:%02d:%02d %3d%% 🌢 ", rtc_time.hour, rtc_time.minute, rtc_time.second, moisture_pt);
|
||||
@@ -48,17 +45,11 @@ void screen_home(GuiEvent event)
|
||||
LcdBuffer_Write(&lcd, 1, 0, "Plán. závlaha 7:15");
|
||||
LcdBuffer_Write(&lcd, 2, 0, "❶Spustit ❷Přeskočit");
|
||||
LcdBuffer_Write(&lcd, 3, 0, "🅰Nastavení");
|
||||
|
||||
// LcdBuffer_Write(&lcd, 1, 0, "❶ Spustit cyklus");
|
||||
// LcdBuffer_Write(&lcd, 2, 0, "❷ Ruční řízení");
|
||||
// LcdBuffer_Write(&lcd, 3, 0, "🅰 Nastavení");
|
||||
|
||||
// LcdBuffer_Write(&lcd, 1, 0, "🅰Program 🅱Poměry");
|
||||
// LcdBuffer_Write(&lcd, 2, 0, "🅲Vlhkoměr 🅳Čas");
|
||||
break;
|
||||
|
||||
case GUI_EVENT_KEY_1:
|
||||
switch_screen(screen_cyklus, true);
|
||||
// TODO
|
||||
switch_screen(screen_cyklus, true); // fake cycle
|
||||
break;
|
||||
|
||||
case GUI_EVENT_KEY_2:
|
||||
@@ -66,16 +57,7 @@ void screen_home(GuiEvent event)
|
||||
break;
|
||||
|
||||
case GUI_EVENT_KEY_A:
|
||||
// TODO
|
||||
switch_screen(screen_settings, true);
|
||||
break;
|
||||
|
||||
default:
|
||||
if (event >= 32) {
|
||||
showbuf[showbuf_wp++] = event;
|
||||
if (showbuf_wp == 20) {
|
||||
showbuf_wp = 0;
|
||||
}
|
||||
request_paint();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,144 @@
|
||||
/**
|
||||
* TODO file description
|
||||
*/
|
||||
//
|
||||
// Created by MightyPork on 2023/04/09.
|
||||
//
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include "app_gui.h"
|
||||
#include "gui_event.h"
|
||||
#include "ds_rtc.h"
|
||||
#include "app_io.h"
|
||||
#include "app_config.h"
|
||||
|
||||
static int page = 1;
|
||||
|
||||
#define PAGECOUNT 3
|
||||
|
||||
static struct AppConfig scratch;
|
||||
|
||||
/** Clear the top 3 lines in the LCD - this fixes some problems with utf8 allocations
|
||||
* (char still held by a line later overwritten) */
|
||||
static void clear_menu_lines();
|
||||
|
||||
void screen_settings(GuiEvent event)
|
||||
{
|
||||
char buf[100];
|
||||
switch (event) {
|
||||
case GUI_EVENT_SCREEN_INIT:
|
||||
page = 1;
|
||||
memcpy(&scratch, &app_config, APPCONFIG_SIZE);
|
||||
break;
|
||||
|
||||
case GUI_EVENT_PAINT:
|
||||
switch (page) {
|
||||
case 1:
|
||||
snprintf(buf, 100, "1. Program=%s", scratch.scheduler_enable ? "ZAP" : "VYP");
|
||||
LcdBuffer_Write(&lcd, 0, 0, buf);
|
||||
LcdBuffer_Write(&lcd, 1, 0, "2. Upravit program");
|
||||
LcdBuffer_Write(&lcd, 2, 0, "3. Nastavit čas");
|
||||
break;
|
||||
|
||||
case 2:
|
||||
LcdBuffer_Write(&lcd, 0, 0, "1. Délka zálivky");
|
||||
LcdBuffer_Write(&lcd, 1, 0, "2. Kompenzace tlaku");
|
||||
break;
|
||||
|
||||
case 3:
|
||||
snprintf(buf, 100, "1. Blok.vlhkostí=%s", scratch.moisture_enable ? "ZAP" : "VYP");
|
||||
LcdBuffer_Write(&lcd, 0, 0, buf);
|
||||
LcdBuffer_Write(&lcd, 1, 0, "2. Kalibrace vlhkom.");
|
||||
LcdBuffer_Write(&lcd, 2, 0, "3. Nastavit práh");
|
||||
break;
|
||||
}
|
||||
|
||||
snprintf(buf, 100, "⊛←%d/%d→¤ 🅰Ulož 🅳Zruš", page, PAGECOUNT);
|
||||
LcdBuffer_Write(&lcd, 3, 0, buf);
|
||||
break;
|
||||
|
||||
case GUI_EVENT_KEY_B:
|
||||
case GUI_EVENT_KEY_STAR:
|
||||
if (page > 1) {
|
||||
page--;
|
||||
clear_menu_lines();
|
||||
request_paint();
|
||||
}
|
||||
break;
|
||||
|
||||
case GUI_EVENT_KEY_C:
|
||||
case GUI_EVENT_KEY_HASH:
|
||||
if (page < PAGECOUNT) {
|
||||
page++;
|
||||
clear_menu_lines();
|
||||
request_paint();
|
||||
}
|
||||
break;
|
||||
|
||||
case GUI_EVENT_KEY_A: // SAVE
|
||||
memcpy(&app_config, &scratch, APPCONFIG_SIZE);
|
||||
appconfig_save();
|
||||
switch_screen(screen_home, true);
|
||||
break;
|
||||
|
||||
case GUI_EVENT_KEY_D: // CANCEL
|
||||
switch_screen(screen_home, true);
|
||||
break;
|
||||
|
||||
default:
|
||||
switch (page) {
|
||||
case 1:
|
||||
switch (event) {
|
||||
case GUI_EVENT_KEY_1: // Program Zap/VYP
|
||||
scratch.scheduler_enable ^= 1;
|
||||
request_paint();
|
||||
break;
|
||||
|
||||
case GUI_EVENT_KEY_2: // Upravit program
|
||||
// TODO
|
||||
break;
|
||||
|
||||
case GUI_EVENT_KEY_3: // Nastavit cas
|
||||
// TODO
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
case 2:
|
||||
switch (event) {
|
||||
case GUI_EVENT_KEY_1: // Délka zálivky
|
||||
break;
|
||||
|
||||
case GUI_EVENT_KEY_2: // Kompenzace tlaku
|
||||
// TODO
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
case 3:
|
||||
switch (event) {
|
||||
case GUI_EVENT_KEY_1: // Blokace vlhkosti Zap/VYP
|
||||
scratch.moisture_enable ^= 1;
|
||||
request_paint();
|
||||
break;
|
||||
|
||||
case GUI_EVENT_KEY_2: // Kalibrace vlhkomeru
|
||||
// TODO
|
||||
break;
|
||||
|
||||
case GUI_EVENT_KEY_3: // Nastavit prah
|
||||
// TODO
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void clear_menu_lines()
|
||||
{
|
||||
LcdBuffer_Write(&lcd, 0, 0, " ");
|
||||
LcdBuffer_Write(&lcd, 1, 0, " ");
|
||||
LcdBuffer_Write(&lcd, 2, 0, " ");
|
||||
}
|
||||
Reference in New Issue
Block a user