Split interface.c in two files, one for the interface code, one for the parameters...
authorNathael Pajani <nathael.pajani@ed3l.fr>
Sun, 12 Jun 2022 18:53:31 +0000 (20:53 +0200)
committerNathael Pajani <nathael.pajani@ed3l.fr>
Tue, 8 Nov 2022 11:07:29 +0000 (12:07 +0100)
v10/interface.c
v10/interface.h
v10/param.c [new file with mode: 0644]
v10/param.h [new file with mode: 0644]

index 0814636..7cf713e 100644 (file)
@@ -40,6 +40,7 @@
 #include "interface.h"
 #include "version.h"
 #include "time.h"
+#include "param.h"
 
 /***************************************************************************** */
 /* Buttons inputs on front panel */
@@ -190,408 +191,6 @@ int interface_config(uint32_t uart)
 }
 
 
-
-/***************************************************************************** */
- /* Menu part */
-
-enum interface_modes {
-       MODE_RUN = 0,
-       MODE_CONFIG,
-       MODE_DISPLAY,
-};
-static int interface_mode = MODE_RUN;
-volatile int manual_activation_request = 0;
-
-enum menu_list {
-       MAIN_MENU,
-       FORCE_MODE,
-       DATE_CONFIG,
-       LIMITS,
-       RESET_CONFIG,
-       SAVE_CONFIG,
-       TEST_MODE,
-       NB_MENU, /* This one must be the last */
-};
-static const char* menu_titles[] = {
-       [MAIN_MENU] = "Menu principal",
-       [FORCE_MODE] = "Marche Forcee",
-       [DATE_CONFIG] = "Regl. Heure",
-       [LIMITS] = "Regl. Limites",
-       [SAVE_CONFIG] = "Save config",
-       [RESET_CONFIG] = "Reset config",
-       [TEST_MODE] = "Test mode",
-};
-static uint8_t current_menu = MAIN_MENU;
-static uint8_t current_entry = FORCE_MODE;
-
-enum force_mode_list {
-       MANUAL_FORCE_MODE,
-       AUTO_FORCE_MODE,
-       FORCE_NB_MENU, /* This one must be the last */
-};
-static const char* force_modes_titles[] = {
-       [MANUAL_FORCE_MODE] = "Manuelle",
-       [AUTO_FORCE_MODE] = "Automatique",
-};
-static uint8_t force_cur_menu = MANUAL_FORCE_MODE;
-static uint8_t force_cur_entry = MANUAL_FORCE_MODE;
-
-enum limits_menu_list {
-       TEMP_MAX,
-       PMAX_GRID,
-       PMAX_PROD,
-       PMAX_CONSO,
-       LOAD_TYPE,
-       FORCED_MODE_VAL,
-       LIM_NB_MENU, /* This one must be the last */
-};
-static const char* limits_modes_titles[] = {
-       [TEMP_MAX] = "Temp Max",
-       [PMAX_GRID] = "Pmax Abon.",
-       [PMAX_PROD] = "Pmax Prod.",
-       [PMAX_CONSO] = "P Charge",
-       [LOAD_TYPE] = "Type Charge",
-       [FORCED_MODE_VAL] = "Force Val",
-};
-static uint8_t limits_cur_menu = TEMP_MAX;
-static uint8_t limits_cur_entry = TEMP_MAX;
-
-enum test_menu_list {
-       TEST_FAN,
-       TEST_12V,
-       TEST_CMDV,
-       TEST_NB_MENU, /* This one must be the last */
-};
-static const char* test_modes_titles[] = {
-       [TEST_FAN] = "Fan",
-       [TEST_12V] = "DC 12V",
-       [TEST_CMDV] = "CMD Val",
-};
-extern uint8_t force_fan;
-extern int8_t force_cmd;
-extern uint32_t zc_cnt;
-extern void DC_switch_start();
-static uint8_t test_cur_entry = TEST_FAN;
-
-
-/* Current sub-menu level. main menu is level 0 */
-int sub_menu_level = 0;
-
-
-void config_interface_handle(void)
-{
-       char line[DISP_LLEN];
-       uint8_t button = 0;
-
-       if (current_menu >= NB_MENU) {
-               current_menu = MAIN_MENU;
-       }
-       button = button_pressed;
-       button_pressed = 0;
-       /* Start config with a blank screen */
-       erase_screen_content();
-
-       /* Display current menu title */
-       display_line(0, 1, menu_titles[current_menu]);
-
-       switch (current_menu) {
-               case MAIN_MENU: {
-                               int i = 0;
-                               for (i = 1; i < NB_MENU; i++) {
-                                       if (i != current_entry) {
-                                               display_line(i + 1, 2, menu_titles[i]);
-                                       } else {
-                                               snprintf(line, DISP_LLEN, " >%s", menu_titles[i]);
-                                               display_line(i + 1, 0, line);
-                                       }
-                               }
-                               if (button & BUTTON_UP) {
-                                       current_entry -= 1;
-                               }
-                               if (button & BUTTON_DOWN) {
-                                       current_entry += 1;
-                               }
-                               if (current_entry >= NB_MENU) {
-                                       current_entry = 1;
-                               } else if (current_entry == 0) {
-                                       current_entry = NB_MENU - 1;
-                               }
-                               if (button & BUTTON_RIGHT) {
-                                       current_menu = current_entry;
-                                       sub_menu_level = 1;
-                               }
-                               if (button & (BUTTON_LEFT | BUTTON_OK)) {
-                                       interface_mode = MODE_RUN;
-                               }
-                       }
-                       break;
-               case DATE_CONFIG: {
-                               static uint8_t date_idx = 0;
-                               snprintf(line, DISP_LLEN, "%c", 0x60);
-                               display_line(3, 6 + (date_idx * 3), line);
-                               rtc_pcf85363_time_read(&rtc_conf, &now);
-                               snprintf(line, DISP_LLEN, "%02xh%02x:%02x", now.hour, now.min, now.sec);
-                               display_line(4, 6, line);
-                               snprintf(line, DISP_LLEN, "%c", 0x7F);
-                               display_line(5, 6 + (date_idx * 3), line);
-                               if ((button & BUTTON_RIGHT) && (date_idx < 2)) {
-                                       date_idx++;
-                               }
-                               if ((button & BUTTON_LEFT) && (date_idx > 0)) {
-                                       date_idx--;
-                               }
-                               if (button & (BUTTON_UP | BUTTON_DOWN)) {
-                                       uint32_t seconds = rtc_pcf85363_daytime_to_seconds(&now);
-                                       uint32_t add[6] = {
-                                               3600, 60, 1,
-                                               (23 * 3600), (23* 3600 + 59 * 60), (23 * 3600 + 59 * 60 + 59),
-                                       };
-                                       if (button & BUTTON_UP) {
-                                               if (seconds < add[date_idx + 3]) {
-                                                       seconds += add[date_idx];
-                                               } else {
-                                                       seconds -= add[date_idx + 3];
-                                               }
-                                       } else {
-                                               if (seconds < add[date_idx]) {
-                                                       seconds += add[date_idx + 3];
-                                               } else {
-                                                       seconds -= add[date_idx];
-                                               }
-                                       }
-                                       rtc_pcf85363_seconds_to_daytime(&now, seconds);
-                                       rtc_pcf85363_time_write(&rtc_conf, &now);
-                               }
-                               if (button & BUTTON_OK) {
-                                       sub_menu_level = 0;
-                                       current_menu = MAIN_MENU;
-                               }
-                       }
-                       break;
-               case LIMITS: {
-                               if (sub_menu_level == 1) {
-                                       int i = 0;
-                                       for (i = 0; i < LIM_NB_MENU; i++) {
-                                               if (i != limits_cur_entry) {
-                                                       display_line(i + 2, 3, limits_modes_titles[i]);
-                                               } else {
-                                                       snprintf(line, DISP_LLEN, "  >%s", limits_modes_titles[i]);
-                                                       display_line(i + 2, 0, line);
-                                               }
-                                       }
-                                       if (button & BUTTON_UP) {
-                                               limits_cur_entry -= 1;
-                                       }
-                                       if (button & BUTTON_DOWN) {
-                                               limits_cur_entry += 1;
-                                       }
-                                       if (limits_cur_entry >= LIM_NB_MENU) {
-                                               limits_cur_entry = 0;
-                                       } else if (limits_cur_entry == 0xFF) {
-                                               limits_cur_entry = LIM_NB_MENU - 1;
-                                       }
-                                       if (button & (BUTTON_OK | BUTTON_RIGHT)) {
-                                               limits_cur_menu = limits_cur_entry;
-                                               sub_menu_level = 2;
-                                       }
-                                       if (button & BUTTON_LEFT) {
-                                               sub_menu_level = 0;
-                                               current_menu = MAIN_MENU;
-                                       }
-                               } else { /* sub_menu_level == 2 */
-                                       display_line(1, 1, limits_modes_titles[limits_cur_menu]);
-                                       switch (limits_cur_menu) {
-                                               case TEMP_MAX:
-                                                       snprintf(line, DISP_LLEN, "          %c", 0x60);
-                                                       display_line(3, 1, line);
-                                                       snprintf(line, DISP_LLEN, "Abs. max: %d %cC", sc_conf.conf_max_temp / 100, 0x24);
-                                                       display_line(4, 1, line);
-                                                       snprintf(line, DISP_LLEN, "          %c", 0x7f);
-                                                       display_line(5, 1, line);
-                                                       if (button & BUTTON_UP) {
-                                                               if (sc_conf.conf_max_temp <= 8500) {
-                                                                       sc_conf.conf_max_temp += 500;
-                                                               } else {
-                                                                       sc_conf.conf_max_temp = 9000;
-                                                               }
-                                                       }
-                                                       if (button & BUTTON_DOWN) {
-                                                               if (sc_conf.conf_max_temp > 500) {
-                                                                       sc_conf.conf_max_temp -= 500;
-                                                               } else {
-                                                                       sc_conf.conf_max_temp = 0;
-                                                               }
-                                                       }
-                                                       if (button & BUTTON_LEFT) {
-                                                               sub_menu_level = 1;
-                                                       }
-                                                       if (button & BUTTON_OK) {
-                                                               sub_menu_level = 0;
-                                                               current_menu = MAIN_MENU;
-                                                       }
-                                                       break;
-                                               case FORCED_MODE_VAL:
-                                                       break;
-                                               case PMAX_GRID:
-                                                       /* remember to update max_intensity */
-                                                       break;
-                                               case PMAX_PROD:
-                                                       /* remember to update sunny_days_prod_value */
-                                                       break;
-                                               case PMAX_CONSO:
-                                                       break;
-                                               case LOAD_TYPE:
-                                                       break;
-                                       }
-                               }
-                       }
-                       break;
-               case FORCE_MODE: {
-                               if (sub_menu_level == 1) {
-                                       int i = 0;
-                                       for (i = 0; i < FORCE_NB_MENU; i++) {
-                                               if (i != force_cur_entry) {
-                                                       display_line(i + 2, 3, force_modes_titles[i]);
-                                               } else {
-                                                       snprintf(line, DISP_LLEN, " ->%s", force_modes_titles[i]);
-                                                       display_line(i + 2, 0, line);
-                                               }
-                                       }
-                                       if (button & BUTTON_UP) {
-                                               force_cur_entry -= 1;
-                                       }
-                                       if (button & BUTTON_DOWN) {
-                                               force_cur_entry += 1;
-                                       }
-                                       if (force_cur_entry >= FORCE_NB_MENU) {
-                                               force_cur_entry = 0;
-                                       } else if (force_cur_entry == 0xFF) {
-                                               force_cur_entry = FORCE_NB_MENU - 1;
-                                       }
-                                       if (button & (BUTTON_OK | BUTTON_RIGHT)) {
-                                               force_cur_menu = force_cur_entry;
-                                               sub_menu_level = 2;
-                                       }
-                                       if (button & BUTTON_LEFT) {
-                                               sub_menu_level = 0;
-                                               current_menu = MAIN_MENU;
-                                       }
-                               } else {
-                               }
-                       }
-                       break;
-               case TEST_MODE: {
-                               int i = 0;
-                               uint8_t states[3];
-
-                               states[TEST_FAN] = force_fan;
-                               states[TEST_12V] = (zc_cnt != 0) ? 1 : 0;
-                               states[TEST_CMDV] = (force_cmd != -1) ? 1 : 0;
-
-                               for (i = 0; i < TEST_NB_MENU; i++) {
-                                       if (i != test_cur_entry) {
-                                               display_line(i + 2, 3, test_modes_titles[i]);
-                                       } else {
-                                               snprintf(line, DISP_LLEN, " ->%s : %d", test_modes_titles[i], states[i]);
-                                               display_line(i + 2, 0, line);
-                                       }
-                               }
-                               if (button & BUTTON_UP) {
-                                       test_cur_entry -= 1;
-                               }
-                               if (button & BUTTON_DOWN) {
-                                       test_cur_entry += 1;
-                               }
-                               if (test_cur_entry >= TEST_NB_MENU) {
-                                       test_cur_entry = 0;
-                               } else if (test_cur_entry == 0xFF) {
-                                       test_cur_entry = TEST_NB_MENU - 1;
-                               }
-                               if (button & (BUTTON_LEFT | BUTTON_RIGHT)) {
-                                       switch (test_cur_entry) {
-                                               case TEST_FAN:
-                                                       force_fan = !force_fan;
-                                                       break;
-                                               case TEST_12V:
-                                                       /* Generate a fake zero-cross detect by calling the handler directly */
-                                                       DC_switch_start();
-                                                       break;
-                                               case TEST_CMDV:
-                                                       if (force_cmd >= 0) {
-                                                               force_cmd = -1;
-                                                       } else {
-                                                               force_cmd = 50;
-                                                       }
-                                               default:
-                                                       break;
-                                       }
-                               }
-                               if (button & BUTTON_OK) {
-                                       sub_menu_level = 0;
-                                       current_menu = MAIN_MENU;
-                               }
-                       }
-                       break;
-               case SAVE_CONFIG: {
-                               snprintf(line, DISP_LLEN, "Sauver config ?");
-                               display_line(2, 1, line);
-                               snprintf(line, DISP_LLEN, "Valider = OK");
-                               display_line(5, 1, line);
-                               snprintf(line, DISP_LLEN, "Gauche = Annul");
-                               display_line(6, 1, line);
-                               if (button & BUTTON_LEFT) {
-                                       sub_menu_level = 0;
-                                       current_menu = MAIN_MENU;
-                               }
-                               if (button & BUTTON_OK) {
-                                       int ret = 0;
-                                       erase_screen_content();
-                                       snprintf(line, DISP_LLEN, "Saving ...");
-                                       display_line(4, 2, line);
-                                       ssd130x_display_full_screen(&display);
-                                       ret = scialys_user_flash_update();
-                                       uprintf(UART0, "\nFlash update from menu: %d\n", ret);
-                                       msleep(1500);
-                                       sub_menu_level = 0;
-                                       current_menu = MAIN_MENU;
-                               }
-                       }
-                       break;
-               case RESET_CONFIG: {
-                               snprintf(line, DISP_LLEN, "Efface Config ?");
-                               display_line(2, 1, line);
-                               snprintf(line, DISP_LLEN, "Valider = OK");
-                               display_line(5, 1, line);
-                               snprintf(line, DISP_LLEN, "Gauche = Annul");
-                               display_line(6, 1, line);
-                               if (button & BUTTON_LEFT) {
-                                       sub_menu_level = 0;
-                                       current_menu = MAIN_MENU;
-                               }
-                               if (button & BUTTON_OK) {
-                                       erase_screen_content();
-                                       snprintf(line, DISP_LLEN, "Chargement ...");
-                                       display_line(4, 8, line);
-                                       ssd130x_display_full_screen(&display);
-                                       sc_conf.conf_version = 0x00;
-                                       scialys_check_config();
-                                       uprintf(UART0, "\nSystem defaults reloaded from menu\n");
-                                       msleep(500);
-                                       sub_menu_level = 0;
-                                       current_menu = MAIN_MENU;
-                               }
-                       }
-                       break;
-               default:
-                       interface_mode = MODE_RUN;
-                       current_menu = MAIN_MENU;
-                       break;
-       }
-       /* Update Oled display */
-       ssd130x_display_full_screen(&display);
-}
-
-
 /***************************************************************************** */
  /* usual menu and switch to config menu */
 
@@ -600,6 +199,12 @@ extern uint32_t solar_prod_value;
 extern uint32_t home_conso_value;
 extern volatile uint8_t command_val;
 
+
+static int interface_mode = MODE_RUN;
+volatile int manual_activation_request = 0;
+
+extern int8_t force_cmd;
+
 void interface_update(char heat_mode)
 {
        int abs_centi = water_centi_degrees;
@@ -658,8 +263,6 @@ void interface_update(char heat_mode)
                display_line(6, 0, line);
                snprintf(line, DISP_LLEN, MODULE_VERSION_STR " - " SOFT_VERSION_STR "." COMPILE_VERSION);
                display_line(7, 0, line);
-               /* Update Oled display */
-               ssd130x_display_full_screen(&display);
 
                /* Update RGB leds */
                /* FIXME : use for error signal */
@@ -668,8 +271,10 @@ void interface_update(char heat_mode)
                ws2812_send_frame(&ws2812_leds, 0);
        } else {
                /* Config mode. Mode entered by button action, which implies that interface board is present. */
-               config_interface_handle();
+               interface_mode = config_interface_handle();
        }
+       /* Update Oled display */
+       ssd130x_display_full_screen(&display);
 }
 
 
index 71a4da9..e43ab1f 100644 (file)
@@ -52,11 +52,22 @@ extern volatile uint8_t button_pressed;
 
 /***************************************************************************** */
 /* Configuration */
+
 /* Configure interface board */
 int interface_config(uint32_t uart);
 
+enum interface_modes {
+    MODE_RUN = 0,
+    MODE_CONFIG,
+    MODE_DISPLAY,
+};
+
 /* Interface content update */
 void interface_update(char mode);
 
+void erase_screen_content(void);
+
+int display_line(uint8_t line, uint8_t col, const char* text);
+
 #endif /* INTERFACE_H */
 
diff --git a/v10/param.c b/v10/param.c
new file mode 100644 (file)
index 0000000..ca62c55
--- /dev/null
@@ -0,0 +1,438 @@
+/****************************************************************************
+ *   apps/scialys/v10/param.c
+ *
+ * Copyright 2016-2022 Nathael Pajani <nathael.pajani@ed3l.fr>
+ *
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ *************************************************************************** */
+
+#include "core/system.h"
+#include "core/systick.h"
+#include "core/pio.h"
+
+#include "drivers/serial.h"
+#include "drivers/gpio.h"
+#include "drivers/i2c.h"
+
+#include "extdrv/status_led.h"
+#include "extdrv/ws2812.h"
+#include "extdrv/ssd130x_oled_driver.h"
+#include "extdrv/ssd130x_oled_buffer.h"
+
+#include "lib/stdio.h"
+#include "lib/font.h"
+#include "lib/time.h"
+
+#include "config.h"
+#include "interface.h"
+#include "version.h"
+#include "time.h"
+
+
+/***************************************************************************** */
+ /* Menu part */
+
+enum menu_list {
+       MAIN_MENU,
+       FORCE_MODE,
+       DATE_CONFIG,
+       LIMITS,
+       RESET_CONFIG,
+       SAVE_CONFIG,
+       TEST_MODE,
+       NB_MENU, /* This one must be the last */
+};
+static const char* menu_titles[] = {
+       [MAIN_MENU] = "Menu principal",
+       [FORCE_MODE] = "Marche Forcee",
+       [DATE_CONFIG] = "Regl. Heure",
+       [LIMITS] = "Regl. Limites",
+       [SAVE_CONFIG] = "Save config",
+       [RESET_CONFIG] = "Reset config",
+       [TEST_MODE] = "Test mode",
+};
+static uint8_t current_menu = MAIN_MENU;
+static uint8_t current_entry = FORCE_MODE;
+
+enum force_mode_list {
+       MANUAL_FORCE_MODE,
+       AUTO_FORCE_MODE,
+       FORCE_NB_MENU, /* This one must be the last */
+};
+static const char* force_modes_titles[] = {
+       [MANUAL_FORCE_MODE] = "Manuelle",
+       [AUTO_FORCE_MODE] = "Automatique",
+};
+static uint8_t force_cur_menu = MANUAL_FORCE_MODE;
+static uint8_t force_cur_entry = MANUAL_FORCE_MODE;
+
+enum limits_menu_list {
+       TEMP_MAX,
+       PMAX_GRID,
+       PMAX_PROD,
+       PMAX_CONSO,
+       LOAD_TYPE,
+       FORCED_MODE_VAL,
+       LIM_NB_MENU, /* This one must be the last */
+};
+static const char* limits_modes_titles[] = {
+       [TEMP_MAX] = "Temp Max",
+       [PMAX_GRID] = "Pmax Abon.",
+       [PMAX_PROD] = "Pmax Prod.",
+       [PMAX_CONSO] = "P Charge",
+       [LOAD_TYPE] = "Type Charge",
+       [FORCED_MODE_VAL] = "Force Val",
+};
+static uint8_t limits_cur_menu = TEMP_MAX;
+static uint8_t limits_cur_entry = TEMP_MAX;
+
+enum test_menu_list {
+       TEST_FAN,
+       TEST_12V,
+       TEST_CMDV,
+       TEST_NB_MENU, /* This one must be the last */
+};
+static const char* test_modes_titles[] = {
+       [TEST_FAN] = "Fan",
+       [TEST_12V] = "DC 12V",
+       [TEST_CMDV] = "CMD Val",
+};
+extern uint8_t force_fan;
+extern int8_t force_cmd;
+extern uint32_t zc_cnt;
+extern void DC_switch_start();
+static uint8_t test_cur_entry = TEST_FAN;
+
+
+/* Current sub-menu level. main menu is level 0 */
+int sub_menu_level = 0;
+
+
+/* Configuraton menu handler
+ * Return 0 to get back to 
+ */
+int config_interface_handle(void)
+{
+       char line[DISP_LLEN];
+       int interface_mode = MODE_CONFIG;
+       uint8_t button = 0;
+
+       if (current_menu >= NB_MENU) {
+               current_menu = MAIN_MENU;
+       }
+       button = button_pressed;
+       button_pressed = 0;
+       /* Start config with a blank screen */
+       erase_screen_content();
+
+       /* Display current menu title */
+       display_line(0, 1, menu_titles[current_menu]);
+
+       switch (current_menu) {
+               case MAIN_MENU: {
+                               int i = 0;
+                               for (i = 1; i < NB_MENU; i++) {
+                                       if (i != current_entry) {
+                                               display_line(i + 1, 2, menu_titles[i]);
+                                       } else {
+                                               snprintf(line, DISP_LLEN, " >%s", menu_titles[i]);
+                                               display_line(i + 1, 0, line);
+                                       }
+                               }
+                               if (button & BUTTON_UP) {
+                                       current_entry -= 1;
+                               }
+                               if (button & BUTTON_DOWN) {
+                                       current_entry += 1;
+                               }
+                               if (current_entry >= NB_MENU) {
+                                       current_entry = 1;
+                               } else if (current_entry == 0) {
+                                       current_entry = NB_MENU - 1;
+                               }
+                               if (button & BUTTON_RIGHT) {
+                                       current_menu = current_entry;
+                                       sub_menu_level = 1;
+                               }
+                               if (button & (BUTTON_LEFT | BUTTON_OK)) {
+                                       interface_mode = MODE_RUN;
+                               }
+                       }
+                       break;
+               case DATE_CONFIG: {
+                               static uint8_t date_idx = 0;
+                               snprintf(line, DISP_LLEN, "%c", 0x60);
+                               display_line(3, 6 + (date_idx * 3), line);
+                               rtc_pcf85363_time_read(&rtc_conf, &now);
+                               snprintf(line, DISP_LLEN, "%02xh%02x:%02x", now.hour, now.min, now.sec);
+                               display_line(4, 6, line);
+                               snprintf(line, DISP_LLEN, "%c", 0x7F);
+                               display_line(5, 6 + (date_idx * 3), line);
+                               if ((button & BUTTON_RIGHT) && (date_idx < 2)) {
+                                       date_idx++;
+                               }
+                               if ((button & BUTTON_LEFT) && (date_idx > 0)) {
+                                       date_idx--;
+                               }
+                               if (button & (BUTTON_UP | BUTTON_DOWN)) {
+                                       uint32_t seconds = rtc_pcf85363_daytime_to_seconds(&now);
+                                       uint32_t add[6] = {
+                                               3600, 60, 1,
+                                               (23 * 3600), (23* 3600 + 59 * 60), (23 * 3600 + 59 * 60 + 59),
+                                       };
+                                       if (button & BUTTON_UP) {
+                                               if (seconds < add[date_idx + 3]) {
+                                                       seconds += add[date_idx];
+                                               } else {
+                                                       seconds -= add[date_idx + 3];
+                                               }
+                                       } else {
+                                               if (seconds < add[date_idx]) {
+                                                       seconds += add[date_idx + 3];
+                                               } else {
+                                                       seconds -= add[date_idx];
+                                               }
+                                       }
+                                       rtc_pcf85363_seconds_to_daytime(&now, seconds);
+                                       rtc_pcf85363_time_write(&rtc_conf, &now);
+                               }
+                               if (button & BUTTON_OK) {
+                                       sub_menu_level = 0;
+                                       current_menu = MAIN_MENU;
+                               }
+                       }
+                       break;
+               case LIMITS: {
+                               if (sub_menu_level == 1) {
+                                       int i = 0;
+                                       for (i = 0; i < LIM_NB_MENU; i++) {
+                                               if (i != limits_cur_entry) {
+                                                       display_line(i + 2, 3, limits_modes_titles[i]);
+                                               } else {
+                                                       snprintf(line, DISP_LLEN, "  >%s", limits_modes_titles[i]);
+                                                       display_line(i + 2, 0, line);
+                                               }
+                                       }
+                                       if (button & BUTTON_UP) {
+                                               limits_cur_entry -= 1;
+                                       }
+                                       if (button & BUTTON_DOWN) {
+                                               limits_cur_entry += 1;
+                                       }
+                                       if (limits_cur_entry >= LIM_NB_MENU) {
+                                               limits_cur_entry = 0;
+                                       } else if (limits_cur_entry == 0xFF) {
+                                               limits_cur_entry = LIM_NB_MENU - 1;
+                                       }
+                                       if (button & (BUTTON_OK | BUTTON_RIGHT)) {
+                                               limits_cur_menu = limits_cur_entry;
+                                               sub_menu_level = 2;
+                                       }
+                                       if (button & BUTTON_LEFT) {
+                                               sub_menu_level = 0;
+                                               current_menu = MAIN_MENU;
+                                       }
+                               } else { /* sub_menu_level == 2 */
+                                       display_line(1, 1, limits_modes_titles[limits_cur_menu]);
+                                       switch (limits_cur_menu) {
+                                               case TEMP_MAX:
+                                                       snprintf(line, DISP_LLEN, "          %c", 0x60);
+                                                       display_line(3, 1, line);
+                                                       snprintf(line, DISP_LLEN, "Abs. max: %d %cC", sc_conf.conf_max_temp / 100, 0x24);
+                                                       display_line(4, 1, line);
+                                                       snprintf(line, DISP_LLEN, "          %c", 0x7f);
+                                                       display_line(5, 1, line);
+                                                       if (button & BUTTON_UP) {
+                                                               if (sc_conf.conf_max_temp <= 8500) {
+                                                                       sc_conf.conf_max_temp += 500;
+                                                               } else {
+                                                                       sc_conf.conf_max_temp = 9000;
+                                                               }
+                                                       }
+                                                       if (button & BUTTON_DOWN) {
+                                                               if (sc_conf.conf_max_temp > 500) {
+                                                                       sc_conf.conf_max_temp -= 500;
+                                                               } else {
+                                                                       sc_conf.conf_max_temp = 0;
+                                                               }
+                                                       }
+                                                       if (button & BUTTON_LEFT) {
+                                                               sub_menu_level = 1;
+                                                       }
+                                                       if (button & BUTTON_OK) {
+                                                               sub_menu_level = 0;
+                                                               current_menu = MAIN_MENU;
+                                                       }
+                                                       break;
+                                               case FORCED_MODE_VAL:
+                                                       break;
+                                               case PMAX_GRID:
+                                                       /* remember to update max_intensity */
+                                                       break;
+                                               case PMAX_PROD:
+                                                       /* remember to update sunny_days_prod_value */
+                                                       break;
+                                               case PMAX_CONSO:
+                                                       break;
+                                               case LOAD_TYPE:
+                                                       break;
+                                       }
+                               }
+                       }
+                       break;
+               case FORCE_MODE: {
+                               if (sub_menu_level == 1) {
+                                       int i = 0;
+                                       for (i = 0; i < FORCE_NB_MENU; i++) {
+                                               if (i != force_cur_entry) {
+                                                       display_line(i + 2, 3, force_modes_titles[i]);
+                                               } else {
+                                                       snprintf(line, DISP_LLEN, " ->%s", force_modes_titles[i]);
+                                                       display_line(i + 2, 0, line);
+                                               }
+                                       }
+                                       if (button & BUTTON_UP) {
+                                               force_cur_entry -= 1;
+                                       }
+                                       if (button & BUTTON_DOWN) {
+                                               force_cur_entry += 1;
+                                       }
+                                       if (force_cur_entry >= FORCE_NB_MENU) {
+                                               force_cur_entry = 0;
+                                       } else if (force_cur_entry == 0xFF) {
+                                               force_cur_entry = FORCE_NB_MENU - 1;
+                                       }
+                                       if (button & (BUTTON_OK | BUTTON_RIGHT)) {
+                                               force_cur_menu = force_cur_entry;
+                                               sub_menu_level = 2;
+                                       }
+                                       if (button & BUTTON_LEFT) {
+                                               sub_menu_level = 0;
+                                               current_menu = MAIN_MENU;
+                                       }
+                               } else {
+                               }
+                       }
+                       break;
+               case TEST_MODE: {
+                               int i = 0;
+                               uint8_t states[3];
+
+                               states[TEST_FAN] = force_fan;
+                               states[TEST_12V] = (zc_cnt != 0) ? 1 : 0;
+                               states[TEST_CMDV] = (force_cmd != -1) ? 1 : 0;
+
+                               for (i = 0; i < TEST_NB_MENU; i++) {
+                                       if (i != test_cur_entry) {
+                                               display_line(i + 2, 3, test_modes_titles[i]);
+                                       } else {
+                                               snprintf(line, DISP_LLEN, " ->%s : %d", test_modes_titles[i], states[i]);
+                                               display_line(i + 2, 0, line);
+                                       }
+                               }
+                               if (button & BUTTON_UP) {
+                                       test_cur_entry -= 1;
+                               }
+                               if (button & BUTTON_DOWN) {
+                                       test_cur_entry += 1;
+                               }
+                               if (test_cur_entry >= TEST_NB_MENU) {
+                                       test_cur_entry = 0;
+                               } else if (test_cur_entry == 0xFF) {
+                                       test_cur_entry = TEST_NB_MENU - 1;
+                               }
+                               if (button & (BUTTON_LEFT | BUTTON_RIGHT)) {
+                                       switch (test_cur_entry) {
+                                               case TEST_FAN:
+                                                       force_fan = !force_fan;
+                                                       break;
+                                               case TEST_12V:
+                                                       /* Generate a fake zero-cross detect by calling the handler directly */
+                                                       DC_switch_start();
+                                                       break;
+                                               case TEST_CMDV:
+                                                       if (force_cmd >= 0) {
+                                                               force_cmd = -1;
+                                                       } else {
+                                                               force_cmd = 50;
+                                                       }
+                                               default:
+                                                       break;
+                                       }
+                               }
+                               if (button & BUTTON_OK) {
+                                       sub_menu_level = 0;
+                                       current_menu = MAIN_MENU;
+                               }
+                       }
+                       break;
+               case SAVE_CONFIG: {
+                               snprintf(line, DISP_LLEN, "Sauver config ?");
+                               display_line(2, 1, line);
+                               snprintf(line, DISP_LLEN, "Valider = OK");
+                               display_line(5, 1, line);
+                               snprintf(line, DISP_LLEN, "Gauche = Annul");
+                               display_line(6, 1, line);
+                               if (button & BUTTON_LEFT) {
+                                       sub_menu_level = 0;
+                                       current_menu = MAIN_MENU;
+                               }
+                               if (button & BUTTON_OK) {
+                                       int ret = 0;
+                                       erase_screen_content();
+                                       snprintf(line, DISP_LLEN, "Saving ...");
+                                       display_line(4, 2, line);
+                                       ret = scialys_user_flash_update();
+                                       uprintf(UART0, "\nFlash update from menu: %d\n", ret);
+                                       msleep(1500);
+                                       sub_menu_level = 0;
+                                       current_menu = MAIN_MENU;
+                               }
+                       }
+                       break;
+               case RESET_CONFIG: {
+                               snprintf(line, DISP_LLEN, "Efface Config ?");
+                               display_line(2, 1, line);
+                               snprintf(line, DISP_LLEN, "Valider = OK");
+                               display_line(5, 1, line);
+                               snprintf(line, DISP_LLEN, "Gauche = Annul");
+                               display_line(6, 1, line);
+                               if (button & BUTTON_LEFT) {
+                                       sub_menu_level = 0;
+                                       current_menu = MAIN_MENU;
+                               }
+                               if (button & BUTTON_OK) {
+                                       erase_screen_content();
+                                       snprintf(line, DISP_LLEN, "Chargement ...");
+                                       display_line(4, 8, line);
+                                       sc_conf.conf_version = 0x00;
+                                       scialys_check_config();
+                                       uprintf(UART0, "\nSystem defaults reloaded from menu\n");
+                                       msleep(500);
+                                       sub_menu_level = 0;
+                                       current_menu = MAIN_MENU;
+                               }
+                       }
+                       break;
+               default:
+                       interface_mode = MODE_RUN;
+                       current_menu = MAIN_MENU;
+                       break;
+       }
+       return interface_mode;
+}
+
+
diff --git a/v10/param.h b/v10/param.h
new file mode 100644 (file)
index 0000000..35d385a
--- /dev/null
@@ -0,0 +1,35 @@
+/****************************************************************************
+ *   apps/scialys/v10/param.h
+ *
+ * Copyright 2016-2022 Nathael Pajani <nathael.pajani@ed3l.fr>
+ *
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ *************************************************************************** */
+
+#ifndef PARAM_H
+#define PARAM_H
+
+
+/***************************************************************************** */
+/* Configuration menu */
+
+/* Configuraton menu handler
+ * Return 0 to get back to 
+ */
+int config_interface_handle(void);
+
+#endif /* PARAM_H */
+