Going on with code cleaning, re-organisation, and fixes
authorNathael Pajani <nathael.pajani@ed3l.fr>
Sun, 20 Nov 2022 16:03:33 +0000 (17:03 +0100)
committerNathael Pajani <nathael.pajani@ed3l.fr>
Sun, 20 Nov 2022 16:05:04 +0000 (17:05 +0100)
v10/comm.c [new file with mode: 0644]
v10/comm.h [new file with mode: 0644]
v10/config.c
v10/config.h
v10/interface.c
v10/main.c
v10/param.c
v10/sensors.c [new file with mode: 0644]
v10/sensors.h [new file with mode: 0644]
v10/time.c

diff --git a/v10/comm.c b/v10/comm.c
new file mode 100644 (file)
index 0000000..90e7f3d
--- /dev/null
@@ -0,0 +1,59 @@
+/****************************************************************************
+ *   apps/scialys/v10/comm.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 "extdrv/status_led.h"
+
+#include "core/user_information_block.h"
+#include "core/iap.h"
+
+#include "config.h"
+#include "interface.h"
+#include "time.h"
+#include "uSD.h"
+
+
+/***************************************************************************** */
+/* Rx interrupt handler for system configuration over USB */
+void config_rx(uint8_t c)
+{
+       /* FAN control */
+       if (c == 'f') {
+               gpio_set(fan_ctrl);
+       } else {
+               gpio_clear(fan_ctrl);
+       }
+}
+
+
+/* Communication with slave modules over UART1 */
+void comm_rx(uint8_t c)
+{
+}
+
+
+
diff --git a/v10/comm.h b/v10/comm.h
new file mode 100644 (file)
index 0000000..beff0e9
--- /dev/null
@@ -0,0 +1,35 @@
+/****************************************************************************
+ *   apps/scialys/v10/comm.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 COMM_H
+#define COMM_H
+
+
+/* Rx interrupt handler for system configuration over USB */
+void config_rx(uint8_t c);
+
+
+/* Communication with slave modules over UART1 */
+void comm_rx(uint8_t c);
+
+
+#endif /* COMM_H */
+
index 702ea0d..595176f 100644 (file)
@@ -1,5 +1,5 @@
 /****************************************************************************
- *   apps/scialys/v010/config.c
+ *   apps/scialys/v10/config.c
  *
  * Copyright 2016-2021 Nathael Pajani <nathael.pajani@ed3l.fr>
  *
@@ -40,6 +40,7 @@
 
 #include "config.h"
 #include "interface.h"
+#include "comm.h"
 #include "time.h"
 #include "uSD.h"
 
@@ -200,6 +201,7 @@ extern void ac_switch_on(uint32_t flags);
 extern void zero_cross(uint32_t flags);
 extern void power_track(uint32_t flags);
 
+/* Configure micro-controller internal modules */
 void modules_config(void)
 {
        uart_on(UART0, 115200, config_rx);
@@ -208,7 +210,7 @@ void modules_config(void)
        ssp_master_on(SSP_BUS_0, LPC_SSP_FRAME_SPI, 8, 4*1000*1000);
        adc_on(NULL);
        adc_start_burst_conversion(ADC_MCH(0) | ADC_MCH(1) | ADC_MCH(2), LPC_ADC_SEQ(0));
-       /* Configure and start timers */
+       /* Activate and configure timers */
        /* This one is used to generate the second zero-crossing, which is not seen by the ZC detector */
        timer_on(LPC_TIMER_32B0, 0, zero_cross);
        timer_counter_config(LPC_TIMER_32B0, &ac_timer_conf_zc);
@@ -221,6 +223,46 @@ void modules_config(void)
 }
 
 
+extern void handle_cmd_update(uint32_t curent_tick);
+extern void track_isnail_values(uint32_t curent_tick);
+extern void handle_dec_request(uint32_t curent_tick);
+/* Period (in ms) of the handler for the command value update */
+#define CMD_UPD_PERIOD 50
+/* Period (in ms) of the handler for the isnail (tores) ADC update
+ * Do not use a multiple of 10 in order not to be in sync with possible glitchs from the mains
+ */
+#define ADC_UPD_PERIOD 17
+
+/* Add systick callbacks and update and start timers */
+void scialys_systick_and_timers_config(void)
+{
+       uint32_t clk_cycles_ac_zc = 0;
+       /* We want 100 Hz (50 Hz but two zero crossings) with 1% granularity */
+       clk_cycles_ac_zc = get_main_clock() / (100 * 100);
+       uprintf(UART0, "clk_cycles_ac_zc: %d\n", clk_cycles_ac_zc);
+
+       /* Configure the fake zero-cross generation timer to 100Hz.
+        * Do not start it now, it will be started by the first real zero-cross detected in order to
+        *   generate the other half zc (not seen by system due to hardware design)
+        * Also sarted by config when DC mode is set */
+       timer_set_match(LPC_TIMER_32B0, CHAN0, (clk_cycles_ac_zc * 100));
+
+       /* Configure the power tracking timer.
+        * 20 points per half sin wave should be enough to get the min and max */
+       timer_set_match(LPC_TIMER_16B0, CHAN0, (clk_cycles_ac_zc * 5));
+       timer_start(LPC_TIMER_16B0);
+
+       /* Add a systick callback to handle command value update */
+       add_systick_callback(handle_cmd_update, CMD_UPD_PERIOD);
+
+       /* Add a systick callback to track ismail values (power consumption and production) */
+       add_systick_callback(track_isnail_values, ADC_UPD_PERIOD);
+
+       /* Add a systick callback to handle time counting */
+       add_systick_callback(handle_dec_request, DEC_PERIOD);
+}
+
+
 /***************************************************************************** */
 /* External components */
 
@@ -253,29 +295,6 @@ struct tmp101_sensor_config tmp101_sensor_display = {
        .resolution = TMP_RES_ELEVEN_BITS,
 };
 
-int temp_read(uint32_t uart, int* deci_degrees_disp, int* deci_degrees_power)
-{
-       int ret = 0;
-       int conv = 0;
-
-       if (interface_board_present != 0) {
-               ret = tmp101_sensor_read(&tmp101_sensor_display, NULL, deci_degrees_disp);
-               if (ret == 0) {
-                       conv |= CONV_DISPLAY_OK;
-               } else {
-                       uprintf(uart, "TMP101 read error on display board : %d\n", ret);
-               }
-       }
-       if (power_board_present != 0) {
-               ret = tmp101_sensor_read(&tmp101_sensor_power, NULL, deci_degrees_power);
-               if (ret == 0) {
-                       conv |= CONV_POWER_OK;
-               } else {
-                       uprintf(uart, "TMP101 read error on power board : %d\n", ret);
-               }
-       }
-       return conv;
-}
 
 
 /* Configure external components */
index af8ce21..d97ed99 100644 (file)
 #include "lib/stdio.h"
 
 
+/* Main frequency (core) */
 #define SELECTED_FREQ  FREQ_SEL_48MHz
 
+/* Period (in ms) of the decrementer handler from the systick interrupt */
+#define DEC_PERIOD  100
+
+
 /***************************************************************************** */
 /* Configuration storage */
 
@@ -196,7 +201,7 @@ void system_init();
 void fault_info(const char* name, uint32_t len);
 
 
-/* Configure modules and main functions */
+/* Configure micro-controller internal modules */
 void modules_config(void);
 
 /* Configure GPIO for specific board usage */
@@ -205,15 +210,9 @@ void board_io_config(void);
 /* Configure external components */
 int external_components_config(uint32_t uart);
 
+/* Add systick callbacks and update and start timers */
+void scialys_systick_and_timers_config(void);
 
-/***************************************************************************** */
-/* Other parts ... */
-
-/* Internal Temperature sensors */
-#define CONV_DISPLAY_OK  (0x01 << 0)
-#define CONV_POWER_OK    (0x01 << 1)
-#define CONV_OK   (CONV_POWER_OK | CONV_DISPLAY_OK)
-int temp_read(uint32_t uart, int* deci_degrees_disp, int* deci_degrees_power);
 
 #endif /* CONFIG_H */
 
index a053a61..5ccac17 100644 (file)
@@ -214,7 +214,6 @@ extern uint32_t solar_prod_value;
 extern uint32_t home_conso_value;
 extern volatile uint8_t command_val;
 extern int manual_activation_request;
-extern int8_t force_cmd;
 
 static int interface_mode = MODE_RUN;
 
@@ -246,14 +245,6 @@ void interface_update(char heat_mode)
                        if (button_pressed & BUTTON_UP) {
                                interface_mode = MODE_CONFIG;
                        }
-                       if (force_cmd >= 0) {
-                               if ((button_pressed & BUTTON_RIGHT) && (force_cmd <= 95)) {
-                                       force_cmd += 5;
-                               }
-                               if ((button_pressed & BUTTON_LEFT) && (force_cmd >= 5)) {
-                                       force_cmd -= 5;
-                               }
-                       }
                        button_pressed = 0;
                }
 
index 1979da2..efbd226 100644 (file)
 /***************************************************************************** */
 /* System configuration */
 
-/* Period (in ms) of the decrementer handler from the systick interrupt */
-#define DEC_PERIOD  100
-/* Period (in ms) of the handler for the command value update */
-#define CMD_UPD_PERIOD 50
-#define ADC_UPD_PERIOD 17
 /* This multiplier is used for all durations and delays which are stored in number of hours */
 #define T_MULT  (3600 * 1000 / DEC_PERIOD)
 
 #define OVERVOLTAGE_PROTECTION_CYCLES 100
 
 
-uint8_t forced_heater_mode = 0;  /* flag */
-uint32_t forced_heater_delay = 0;
-uint32_t forced_heater_time = 0;
-uint8_t manual_forced_heater = 0;  /* flag */
-int manual_activation_request = 0;
-
-
-uint8_t error_shutdown = 0;  /* flag */
-
-
+/* Flags and counters */
+uint8_t forced_heater_mode = 0; /* Flag only */
+uint32_t forced_heater_delay = 0; /* Flag and counter */
+uint32_t forced_heater_time = 0; /* Flag and counter */
+uint8_t manual_forced_heater = 0; /* Flag only */
+int manual_activation_request = 0; /* Flag and counter */
+uint8_t error_shutdown = 0; /* Flag only */
 #define EXTERNAL_DISABLE_FORCE  0  /* Input is pulled low when external disable is ON */
-uint8_t external_disable = 0;
-uint8_t temp_shutdown = 0;
-uint8_t overvoltage = 0; /* Used to create a delay when overvoltage is detected, 
+uint8_t external_disable = 0; /* Flag only */
+uint8_t temp_shutdown = 0; /* Flag only */
+uint8_t overvoltage = 0; /* Flag and counter. Used to create a delay when overvoltage is detected,
                                                        set to OVERVOLTAGE_PROTECTION_CYCLES and decreases to 0 */
 
 enum modes {
@@ -79,7 +71,7 @@ enum modes {
        temp_OK = 'T', /* Max temperature reached */
 };
 
-/* Water and internaltemperature */
+/* Water temperature */
 int water_centi_degrees = 0;
 
 /* Set to ABSOLUTE_MAX_WATER_TEMP - 1.5°C when enbling max temp hysteresis */
@@ -96,32 +88,17 @@ int32_t max_intensity = 0;
 struct rtc_time now;
 
 
-/***************************************************************************** */
-/* Rx interrupt handler for system configuration over USB */
-void config_rx(uint8_t c)
-{
-       /* FAN control */
-       if (c == 'f') {
-               gpio_set(fan_ctrl);
-       } else {
-               gpio_clear(fan_ctrl);
-       }
-}
 
+/***************************************************************************** */
+/* Decrementer for forced heating modes timers */
 
-/* Communication with slave modules over UART1 */
-void comm_rx(uint8_t c)
+void handle_dec_request(uint32_t curent_tick)
 {
-}
-
-
-
-/***************************************************************************** */
-/* Decrementer for heating timers */
-void handle_dec_request(uint32_t curent_tick) {
+       /* Manual forced mode */
        if (manual_activation_request > 0) {
                manual_activation_request--;
        }
+       /* Automatic forced mode */
        if (forced_heater_mode == 1) {
                if (forced_heater_delay > 0) {
                        forced_heater_delay--;
@@ -135,15 +112,19 @@ void handle_dec_request(uint32_t curent_tick) {
 
 
 /***************************************************************************** */
-/* Track power production and usage */
+/* Power Tracking */
 
-/* Average value computed on last NB_VAL ADC values */
+/* Average value computed on the last "NB_VAL" ADC values */
 uint32_t solar_prod_value = 0;
 uint32_t home_conso_value = 0;
 #define NB_VAL 4  /* MUST be a power of 2 */
 #define NB_SHIFT 2
 
-static void track_isnail_values(uint32_t flags)
+/*
+ * Track power production and usage
+ * These are obtained by reading the Tore outputs (i-Snail output through ADC 0 and 1)
+ */
+void track_isnail_values(uint32_t curent_tick)
 {
        static uint8_t idx = 0;
        static uint16_t solar[NB_VAL];
@@ -179,17 +160,54 @@ static void track_isnail_values(uint32_t flags)
        home_conso_value = sum_home << (6 - NB_SHIFT);
 }
 
+
+/*
+ * Track power used by load.
+ * These are obtained from ACS711 through ADC 2
+ * ADC values are between 0 and 1023, no load value is at about 520
+ */
+#define TRACK_MAX  1
+#define TRACK_MIN  0
+static volatile uint16_t load_power_highest = 520;
+static volatile uint16_t load_power_lowest = 520;
+
+void power_track(uint32_t flags)
+{
+       /* Start tracking the higest value */
+       static int tracking = TRACK_MAX;
+       static uint16_t last_value = 0;
+       uint16_t val = 0;
+
+       /* Get load power usage */
+       adc_get_value(&val, LPC_ADC(2));
+
+       /* Four possibilities :
+        *    tracking max and value increasing : nothing to do
+        *    tracking max and value decreasing : we found the max, store it and change tracking
+        *    tracking min and value decreasing : nothing to do
+        *    tracking min and value increasing : we found the min, store it and change tracking
+        */
+       if (tracking == TRACK_MAX) {
+               if (last_value > val) {
+                       /* Found max */
+                       load_power_highest = last_value;
+                       tracking = TRACK_MIN;
+               }
+       } else {
+               if (last_value < val) {
+                       /* Found min */
+                       load_power_lowest = last_value;
+                       tracking = TRACK_MAX;
+               }
+       }
+       last_value = val;
+}
+
+
 /***************************************************************************** */
 /* AC control */
 
-volatile uint8_t command_val = 0;
 volatile int act_cmd = 0; /* Start off */
-int8_t force_cmd = -1; /* Forced command value, for tests */
-int8_t old_cmd = 0; /* Used to store cmd value when entering over-voltage protection mode */
-#define FAN_CNT_START (15 * 1000)
-static uint16_t fan_on = 0;
-uint8_t force_fan = 0; /* Request to force fan ON from test menu */
-
 
 void set_ctrl_duty_cycle(uint8_t value)
 {
@@ -208,31 +226,34 @@ void ac_switch_on(uint32_t flags)
        gpio_clear(ac_ctrl);
 }
 
-static uint32_t clk_cycles_ac_zc = 0;
+
 extern uint32_t power_delay[101];
 volatile uint32_t zc_cnt = 0;
 
+/*
+ * Zero crossing handler (either detected or fake one)
+ * If command is at 100%, only set (keep ?) Mosfets ON (gpio_clear)
+ * Else, start with mosfets OFF, in order not to have to break established current.
+ * FIXME : If U and I not in sync, we should sync to I nul, not V nul.
+ */
 void zero_cross(uint32_t unused)
 {
        uint32_t delay = 0;
 
        zc_cnt++;
+       /* Command at 100% ? set Mosfets ON and return. */
        if (act_cmd == 100) {
                gpio_clear(ac_ctrl);
                return;
        }
+       /* Set Mosfet OFF */
        gpio_set(ac_ctrl);
+       /* Command at 0% ? leave Mosfets OFF (do not start timer) and return. */
        if (act_cmd == 0) {
                return;
        }
        /* Set timer to trigger ac out ON at given delay */
-       if (0) {
-               /* Time based delay */
-               delay = clk_cycles_ac_zc * (100 - act_cmd);
-       } else {
-               /* Power based delay */
-               delay = power_delay[100 - act_cmd];
-       }
+       delay = power_delay[100 - act_cmd];
        timer_set_match(LPC_TIMER_32B1, CHAN0, delay);
        timer_restart(LPC_TIMER_32B1);
 }
@@ -240,11 +261,22 @@ void zero_cross(uint32_t unused)
 /* This one is used to synchronize to the real zero-crossing detection, if any. */
 void zero_cross_detect(uint32_t unused)
 {
+       /* Prepare to generate the fake second zero crossing */
        timer_restart(LPC_TIMER_32B0);
+       /* And call zero cross handler for this one */
        zero_cross(0);
 }
 
+
+
 /* Handle the power command */
+volatile uint8_t command_val = 0;
+int8_t old_cmd = 0; /* Used to store cmd value when entering over-voltage protection mode */
+#define FAN_COUNTER_START_VAL (15 * 1000)
+static uint16_t fan_on = 0;
+uint8_t force_fan = 0; /* Request to force fan ON from test menu */
+#define PROTECTION_CMD_VAL 100
+
 static uint8_t linky_disable = 0;
 #define CMD_UP_DELAY_RESET_VALUE  3
 void handle_cmd_update(uint32_t curent_tick)
@@ -253,11 +285,14 @@ void handle_cmd_update(uint32_t curent_tick)
        static uint8_t cmd_up_delay = CMD_UP_DELAY_RESET_VALUE;
        int delta = solar_prod_value - home_conso_value;
 
-       /* Unable to read internal temperature : turn off heating */
-       if (error_shutdown == 1) {
-               cmd = 0;
-               force_fan = 1;
+       /* Forced over-voltage protection or test mode */
+       if (overvoltage != 0) {
+               cmd = PROTECTION_CMD_VAL;
                goto cmd_update_end;
+       } else if (old_cmd != -1) {
+               /* Get back to normal after over-voltage protection */
+               cmd = old_cmd;
+               old_cmd = -1;
        }
 
        /* Water max temperature protection with hysteresys */
@@ -275,14 +310,11 @@ void handle_cmd_update(uint32_t curent_tick)
                max_temp_hysteresys = ABSOLUTE_MAX_WATER_TEMP;
        }
 
-       /* Forced over-voltage protection or test mode */
-       if (force_cmd != -1) {
-               cmd = force_cmd;
+       /* Unable to read internal temperature : turn off heating */
+       if ((temp_shutdown == 1) || (error_shutdown == 1)) {
+               cmd = 0;
+               force_fan = 1;
                goto cmd_update_end;
-       } else if (old_cmd != -1) {
-               /* Get back to normal after over-voltage protection */
-               cmd = old_cmd;
-               old_cmd = -1;
        }
 
        /* Which is the current mode ? */
@@ -370,8 +402,9 @@ cmd_update_limited_end:
        }
 
 cmd_update_end:
+       /* Update FAN command (start or stop FAN) */
        if ((cmd > 0) || (force_fan == 1)) {
-               fan_on = FAN_CNT_START;
+               fan_on = FAN_COUNTER_START_VAL;
                gpio_set(fan_ctrl);
        } else {
                if (fan_on > 0) {
@@ -388,40 +421,53 @@ cmd_update_end:
 /* Over-voltage protection */
 void overvoltage_protect(uint32_t gpio)
 {
-       gpio_clear(ac_ctrl);
-       timer_stop(LPC_TIMER_32B1);
-       set_ctrl_duty_cycle(100);
-       force_cmd = 100;
+       gpio_clear(ac_ctrl); /* Turn mosfets ON */
+       timer_stop(LPC_TIMER_32B1); /* Stop mosfets timer */
+       set_ctrl_duty_cycle(100); /* Update "actual command" */
        overvoltage = OVERVOLTAGE_PROTECTION_CYCLES;
-       gpio_set(fan_ctrl);
-       old_cmd = command_val;
+       gpio_set(fan_ctrl); /* Turn on FAN immediatly */
+       old_cmd = command_val; /* Save current command value (to be restored after overvoltage protection */
 }
 
 
 /* Update current working mode depending on environnement */
 volatile char mode = heat; /* Debug info */
 volatile char* msg = NULL;
-void mode_update(uint32_t unused)
+void mode_update(void)
 {
        /* Default mode : try to heat the water tank */
        mode = heat;
 
        /* Need to enter Forced heating mode ? */
-       if (water_centi_degrees < sc_conf.enter_forced_mode_temp) {
+       if ((water_centi_degrees < sc_conf.enter_forced_mode_temp) && (sc_conf.auto_force_type != FORCE_TYPE_OFF)) {
                if (forced_heater_mode == 0) {
                        msg = "Water temp low, entering forced mode\n";
                        forced_heater_mode = 1;
                }
                status_led(red_on);
                mode = forced;
-       } else if ((water_centi_degrees > sc_conf.auto_forced_target_heater_temp) && (forced_heater_mode == 1)) {
-               status_led(red_off);
-               msg = "Water temp OK, forced mode exit\n";
-               forced_heater_mode = 0;
-               mode = temp_OK;
+       } else if (forced_heater_mode == 1) {
+               int exit_forced = 0;
+               /* End of forced heating ? (target reached) ? */
+               switch (sc_conf.auto_force_type) {
+                       case FORCE_TYPE_TIMER:
+                       case FORCE_TYPE_TARGET:
+                       case FORCE_TYPE_MIN:
+                       case FORCE_TYPE_MAX:
+                               if ((water_centi_degrees > sc_conf.auto_forced_target_heater_temp) && ()) {
+                               }
+               }
+               if (exit_forced == 1) {
+                       status_led(red_off);
+                       msg = "Water temp OK, forced mode exit\n";
+                       forced_heater_mode = 0;
+                       mode = temp_OK;
+               }
        }
 
-       /* Do not force if there is a lot of sun, it may be enough to heat again soon */
+       /* Do not force if there is a lot of sun, it may be enough to heat again soon
+        * 'sunny_days_prod_value' is computed from 'sc_conf.source_has_power_ok'
+        */
        if ((solar_prod_value > sunny_days_prod_value) && (forced_heater_mode == 1)) {
                mode = delayed_heat_prod;
                forced_heater_mode = 0;
@@ -434,16 +480,14 @@ void mode_update(uint32_t unused)
                mode = ext_disable;
                msg = "Forced mode disabled by external input\n";
        }
-       /* Get Over-Voltage or Over-Temperature information */
+
+       /* Get Over-Temperature information */
        temp_shutdown = (gpio_read(overtemperature_pin) ? 0 : 1);
+       /* Update Over-Voltage information */
        if (overvoltage > 0) {
                uint8_t ov_tmp = (gpio_read(overvoltage_pin) ? 0 : 1);
                if (ov_tmp == 0) {
                        overvoltage--;
-                       if (overvoltage == 0) {
-                               /* Get back to normal */
-                               force_cmd = -1;
-                       }
                }
        }
 
@@ -473,84 +517,75 @@ void mode_update(uint32_t unused)
 }
 
 /***************************************************************************** */
-/* Power tracking - load part */
 
-/* ADC values are between 0 and 1023, no load value is at about 520 */
-#define TRACK_MAX  1
-#define TRACK_MIN  0
-static volatile uint16_t load_power_highest = 520;
-static volatile uint16_t load_power_lowest = 520;
-void power_track(uint32_t flags)
+/* Add a false zero-cross, but make sure to do it only once and only if we are not AC powered */
+void DC_switch_start(void)
 {
-       /* Start tracking the higest value */
-       static int tracking = TRACK_MAX;
-       static uint16_t last_value = 0;
-       uint16_t val = 0;
-
-       /* Get load power usage */
-       adc_get_value(&val, LPC_ADC(2));
-
-       /* Four possibilities :
-        *    tracking max and value increasing : nothing to do
-        *    tracking max and value decreasing : we found the max, store it and change tracking
-        *    tracking min and value decreasing : nothing to do
-        *    tracking min and value increasing : we found the min, store it and change tracking
-        */
-       if (tracking == TRACK_MAX) {
-               if (last_value > val) {
-                       /* Found max */
-                       load_power_highest = last_value;
-                       tracking = TRACK_MIN;
-               }
+       static int already_done = 0;
+       if ((already_done == 0) && (zc_cnt == 0)) {
+               int ret = add_systick_callback(zero_cross, 10); /* 2 zero-crossing at 50Hz -> 100Hz -> 10ms */
+               uprintf(UART0, "Entering forced DC mode on systick callback %d\n", ret);
+               already_done = 1;
        } else {
-               if (last_value < val) {
-                       /* Found min */
-                       load_power_lowest = last_value;
-                       tracking = TRACK_MAX;
-               }
+               uprintf(UART0, "DC forced mode not available. On: %d, Zc: %d\n", already_done, zc_cnt);
        }
-       last_value = val;
 }
 
 
 /***************************************************************************** */
-void scialys_systick_and_timers_config(void)
+void update_internal_temp(void)
 {
-       /* We want 100 Hz (50 Hz but two zero crossings) with 1% granularity */
-       clk_cycles_ac_zc = get_main_clock() / (100 * 100);
-       uprintf(UART0, "clk_cycles_ac_zc: %d\n", clk_cycles_ac_zc);
-
-       /* Configure the fake zero-cross generation timer to 100Hz.
-        * Do not start it now, it will be started by the first real zero-cross detected in order to
-        *   generate the other half zc (not seen by system due to hardware design)
-        * Also sarted by config when DC mode is set */
-       timer_set_match(LPC_TIMER_32B0, CHAN0, (clk_cycles_ac_zc * 100));
-
-       /* Configure the power tracking timer.
-        * 20 points per half sin wave should be enough to get the min and max */
-       timer_set_match(LPC_TIMER_16B0, CHAN0, (clk_cycles_ac_zc * 5));
-       timer_start(LPC_TIMER_16B0);
+       /* Get internal temperatures */
+       ret = temp_read(UART0, &deci_degrees_disp, &deci_degrees_power);
+       if (ret != CONV_OK) {
+               force_fan = 1;
+       }
+       /* Internal temperature protection */
+       if ((deci_degrees_power > MAX_INTERNAL_TEMP) || (deci_degrees_disp > MAX_INTERNAL_TEMP)) {
+               error_shutdown = 1;
+               uprintf(UART0, "Error shutdown !\n");
+       } else if ((deci_degrees_power < ((MAX_INTERNAL_TEMP) / 2)) &&
+                               (deci_degrees_disp < ((MAX_INTERNAL_TEMP) / 2))) {
+               error_shutdown = 0;
+       }
+}
 
-       /* Add a systick callback to handle command value update */
-       add_systick_callback(handle_cmd_update, CMD_UPD_PERIOD);
 
-       /* Add a systick callback to track ismail values (power consumption and production) */
-       add_systick_callback(track_isnail_values, ADC_UPD_PERIOD);
+/* Store data on uSD once every N seconds.
+ * Note : Once every second requires about 1Go per year.
+ */
+#define NB_SEC_STORE 5
+void store_data(uint32_t cur_tick)
+{
+       static uint32_t last_tick_store = 0;
+       static struct sd_data_blob data;
+       static uint8_t nb_val = 0;
 
-       /* Add a systick callback to handle time counting */
-       add_systick_callback(handle_dec_request, DEC_PERIOD);
-}
+       if (nb_val == 0) {
+               memset(&data, 0, sizeof(struct sd_data_blob));
+       }
+       /* simple tick wrapping handling */
+       if ((cur_tick < last_tick_store) || ((~0 - last_tick_store) < (NB_SEC_STORE * 1000))) {
+               last_tick_store = 0;
+       }
 
-/* Add a false zero-cross, but make sure to do it only once and only if we are not AC powered */
-void DC_switch_start(void)
-{
-       static int already_done = 0;
-       if ((already_done == 0) && (zc_cnt == 0)) {
-               int ret = add_systick_callback(zero_cross, 10); /* 2 zero-crossing at 50Hz -> 100Hz -> 10ms */
-               uprintf(UART0, "Entering forced DC mode on systick callback %d\n", ret);
-               already_done = 1;
-       } else {
-               uprintf(UART0, "DC forced mode already ON: %d/%d\n", already_done, zc_cnt);
+       /* Each flag is set if seen once within the interval */
+       data.flags |= (fan_on ? 1 : 0) | (force_fan << 1);
+       data.flags |= (error_shutdown << 2) | (temp_shutdown << 3) | (overvoltage << 4);
+       data.flags |= (external_disable << 5);
+       data.flags |= (forced_heater_mode << 6) | (manual_activation_request << 7);
+
+       /* Add current value to the storage value */
+       /* FIXME */
+       nb_val++;
+
+       if (cur_tick > (last_tick_store + (NB_SEC_STORE * 1000))) {
+               /* Divide by the number of values */
+               /* FIXME */
+               scialys_uSD_append_data(&data);
+               uprintf(UART0, "Saved 5s data\n");
+               nb_val = 0;
+               last_tick_store = cur_tick;
        }
 }
 
@@ -563,7 +598,6 @@ int main(void)
 
        /* Order is important here */
        system_init();
-       msleep(800); /* Required for uSD to stabilise before SPI is setup .... */
        board_io_config();
        modules_config();
        external_components_config(UART0);
@@ -573,67 +607,23 @@ int main(void)
        scialys_systick_and_timers_config();
 
        uprintf(UART0, "System setup complete.\n");
-       uprintf(UART0, "Max intensity: %d\n", max_intensity);
-       msleep(500);
+       msleep(100);
        status_led(green_only);
 
        while (1) {
                /* Feed the dog */
-               if ((solar_prod_value != 0) && (home_conso_value != 0) &&
-                       (solar_prod_value < 45000) && (home_conso_value < 45000) ) {
-                       /* FIXME : Make max solar prod and home conso a parameter */
+               if ((solar_prod_value != 0) && (home_conso_value != 0)) {
                        watchdog_feed();
                }
 
                /* Update internal temperatures */
-               if (1) {
-                       /* Get internal temperatures */
-                       ret = temp_read(UART0, &deci_degrees_disp, &deci_degrees_power);
-                       if (ret != CONV_OK) {
-                               if ((ret & CONV_POWER_OK) == 0) {
-                                       force_fan = 1;
-                               }
-                               if ((ret & CONV_DISPLAY_OK) == 0) {
-                                       force_fan = 1;
-                               }
-                       }
-                       /* Internal temperature protection */
-                       if ((deci_degrees_power > MAX_INTERNAL_TEMP) || (deci_degrees_disp > MAX_INTERNAL_TEMP)) {
-                               error_shutdown = 1;
-                               uprintf(UART0, "Error shutdown !\n");
-                       } else if ((deci_degrees_power < ((MAX_INTERNAL_TEMP) / 2)) &&
-                                               (deci_degrees_disp < ((MAX_INTERNAL_TEMP) / 2))) {
-                               error_shutdown = 0;
-                       }
-               }
+               update_internal_temp();
 
                /* Update water tank temperature */
-               #define WTA_NB_VAL 8 /* Choose a multiple of 2 */
-               #define WTA_SHIFT  3 /* Set shift according to WTA_NB_VAL */
-               if (1) {
-                       static int water_centi_average[WTA_NB_VAL];
-                       static int wta_idx = 0;
-                       int ret = 0, i = 0;
-                       /* Get thermocouple value, store in table only if valid */
-                       ret = max31855_sensor_read(&thermocouple, NULL, &water_centi_degrees);
-                       if (ret != 0) {
-                               uprintf(UART0, "Water Temp read error : %d\n", ret);
-                       } else {
-                               water_centi_average[wta_idx++] = water_centi_degrees;
-                               if (wta_idx >= WTA_NB_VAL) {
-                                       wta_idx = 0;
-                               }
-                       }
-                       water_centi_degrees = 0;
-                       /* Average water tank temperature */
-                       for (i = 0; i < WTA_NB_VAL; i++) {
-                               water_centi_degrees += water_centi_average[i];
-                       }
-                       water_centi_degrees >>= WTA_SHIFT;
-               }
+               water_centi_degrees = water_temp_update();
 
                /* Update current mode */
-               mode_update(0);
+               mode_update();
 
                /* Display */
                /* only update twice per second */
@@ -647,42 +637,8 @@ int main(void)
                        last_tick_update = cur_tick;
                }
 
-               /* Store data on uSD once every N seconds.
-                * Note : Once every second requires about 1Go per year.
-                */
-               #define NB_SEC_STORE 5
-               if (1) {
-                       static uint32_t last_tick_store = 0;
-                       static struct sd_data_blob data;
-                       static uint8_t nb_val = 0;
-
-                       if (nb_val == 0) {
-                               memset(&data, 0, sizeof(struct sd_data_blob));
-                       }
-                       /* simple tick wrapping handling */
-                       if ((cur_tick < last_tick_store) || ((~0 - last_tick_store) < (NB_SEC_STORE * 1000))) {
-                               last_tick_store = 0;
-                       }
-                       
-                       /* Each flag is set if seen once within the interval */
-                       data.flags |= (fan_on ? 1 : 0) | (force_fan << 1);
-               data.flags |= (error_shutdown << 2) | (temp_shutdown << 3) | (overvoltage << 4);
-               data.flags |= (external_disable << 5);
-               data.flags |= (forced_heater_mode << 6) | (manual_activation_request << 7);
-
-                       /* Add current value to the storage value */
-                       /* FIXME */
-                       nb_val++;
-
-                       if (cur_tick > (last_tick_store + (NB_SEC_STORE * 1000))) {
-                               /* Divide by the number of values */
-                               /* FIXME */
-                               scialys_uSD_append_data(&data);
-                               uprintf(UART0, "Saved 5s data\n");
-                               nb_val = 0;
-                               last_tick_store = cur_tick;
-                       }
-               }
+               /* Store data on uSD once every N seconds. */
+               store_data(cur_tick);
 
                /* Debug */
                if (1) {
index afdba75..3466277 100644 (file)
@@ -350,6 +350,7 @@ int config_interface_handle(void)
                                                                        sc_conf.grid_power_limit = 36;
                                                                }
                                                        }
+                                                       /* This one is used in main loop after computation */
                                                        update_max_intensity();
                                                        BUTTONS_ACTS_DEFAULT();
                                                        break;
@@ -385,6 +386,7 @@ int config_interface_handle(void)
                                                                        sc_conf.source_has_power_ok = 36000;
                                                                }
                                                        }
+                                                       /* This one is used in main loop after computation */
                                                        update_sunny_days_prod_value();
                                                        BUTTONS_ACTS_DEFAULT();
                                                        break;
diff --git a/v10/sensors.c b/v10/sensors.c
new file mode 100644 (file)
index 0000000..18c17ea
--- /dev/null
@@ -0,0 +1,101 @@
+/****************************************************************************
+ *   apps/scialys/v10/sensors.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/gpio.h"
+#include "drivers/i2c.h"
+#include "drivers/adc.h"
+#include "drivers/ssp.h"
+
+#include "extdrv/tmp101_temp_sensor.h"
+#include "extdrv/max31855_thermocouple.h"
+
+#include "config.h"
+#include "sensors.h"
+
+
+/***************************************************************************** */
+/* External components */
+
+extern uint8_t interface_board_present ;
+extern uint8_t power_board_present;
+
+int temp_read(uint32_t uart, int* deci_degrees_disp, int* deci_degrees_power)
+{
+       int ret = 0;
+       int conv = 0;
+
+       if (interface_board_present != 0) {
+               ret = tmp101_sensor_read(&tmp101_sensor_display, NULL, deci_degrees_disp);
+               if (ret == 0) {
+                       conv |= CONV_DISPLAY_OK;
+               } else {
+                       uprintf(uart, "TMP101 read error on display board : %d\n", ret);
+               }
+       }
+       if (power_board_present != 0) {
+               ret = tmp101_sensor_read(&tmp101_sensor_power, NULL, deci_degrees_power);
+               if (ret == 0) {
+                       conv |= CONV_POWER_OK;
+               } else {
+                       uprintf(uart, "TMP101 read error on power board : %d\n", ret);
+               }
+       }
+       return conv;
+}
+
+
+/***************************************************************************** */
+/* Update water tank temperature */
+
+
+int water_temp_update(void)
+{
+       static int water_centi_average[WTA_NB_VAL];
+       static int wta_idx = 0;
+       int water_centi_degrees = 0;
+       int ret = 0, i = 0;
+
+       /* Get thermocouple value, store in table only if valid */
+       ret = max31855_sensor_read(&thermocouple, NULL, &water_centi_degrees);
+       if (ret != 0) {
+               uprintf(UART0, "Water Temp read error : %d\n", ret);
+       } else {
+               water_centi_average[wta_idx++] = water_centi_degrees;
+               if (wta_idx >= WTA_NB_VAL) {
+                       wta_idx = 0;
+               }
+       }
+       water_centi_degrees = 0;
+       /* Average water tank temperature */
+       for (i = 0; i < WTA_NB_VAL; i++) {
+               water_centi_degrees += water_centi_average[i];
+       }
+       water_centi_degrees >>= WTA_SHIFT; /* Division */
+
+       return water_centi_degrees;
+}
+
+
+
diff --git a/v10/sensors.h b/v10/sensors.h
new file mode 100644 (file)
index 0000000..6786be3
--- /dev/null
@@ -0,0 +1,61 @@
+/****************************************************************************
+ *   apps/scialys/v10/sensors.h
+ *
+ * Copyright 2016-2021 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 SENSORS_H
+#define SENSORS_H
+
+#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 "drivers/adc.h"
+#include "drivers/ssp.h"
+#include "drivers/timers.h"
+
+#include "extdrv/status_led.h"
+#include "extdrv/max31855_thermocouple.h"
+
+#include "lib/stdio.h"
+
+
+
+/***************************************************************************** */
+/* Internal Temperature sensors */
+
+#define CONV_DISPLAY_OK  (0x01 << 0)
+#define CONV_POWER_OK    (0x01 << 1)
+#define CONV_OK   (CONV_POWER_OK | CONV_DISPLAY_OK)
+int temp_read(uint32_t uart, int* deci_degrees_disp, int* deci_degrees_power);
+
+
+/***************************************************************************** */
+/* Update water tank temperature */
+#define WTA_NB_VAL 8 /* Choose a multiple of 2 */
+#define WTA_SHIFT  3 /* Set shift according to WTA_NB_VAL */
+int water_temp_update(void);
+
+
+
+#endif /* SENSORS_H */
+
index 5259dcd..da5e1d0 100644 (file)
@@ -39,9 +39,9 @@ struct rtc_pcf85363a_config rtc_conf = {
 };
 /* Oldest acceptable time in RTC. BCD coded. */
 const struct rtc_time oldest = {
-    .year = 0x21,
-    .month = 0x04,
-    .day = 0x24,
+    .year = 0x22,
+    .month = 0x11,
+    .day = 0x10,
     .hour = 0x13,
     .min = 0x37,
 };