summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/datatypes.h44
-rw-r--r--meson.build9
-rw-r--r--src/meson.build2
-rw-r--r--src/server/gtk.c216
-rw-r--r--src/server/gtk.h1
-rw-r--r--src/server/gtk.obin15864 -> 0 bytes
-rw-r--r--src/server/gtklayout.ui333
-rw-r--r--src/server/gtklayout_flash.ui371
-rw-r--r--src/server/meson.build1
-rw-r--r--src/server/util.c142
-rw-r--r--src/server/util.h11
-rw-r--r--src/tempmodule/configuration.c33
-rw-r--r--src/tempmodule/configuration.h28
l---------src/tempmodule/datatypes.h1
-rw-r--r--src/tempmodule/indicator.c15
-rw-r--r--src/tempmodule/indicator.h3
-rw-r--r--src/tempmodule/main.ino12
-rw-r--r--src/tempmodule/meson.build5
-rw-r--r--src/tempmodule/volatile_ops.c38
-rw-r--r--src/tempmodule/volatile_ops.h36
20 files changed, 1168 insertions, 133 deletions
diff --git a/include/datatypes.h b/include/datatypes.h
new file mode 100644
index 0000000..50c3389
--- /dev/null
+++ b/include/datatypes.h
@@ -0,0 +1,44 @@
+/*
+ * Hot Beverage Companion – data types
+ *
+ * Copyright (C) 2018 Gediminas Jakutis
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; version 2.1
+ * of the License.
+ *
+ * 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#ifndef CONFIGURATION_DATA_INCLUDED
+#define CONFIGURATION_DATA_INCLUDED
+
+/* the union should help prevent the compiler from
+ * reordering fields as it sees fit when optimizing.
+ */
+
+#define PADDING_START {0xff, 0xee, 0xdd, 0xff}
+#define PADDING_END {0xff, 0xdd, 0xcc, 0xff}
+
+struct configuration {
+ union {
+ struct {
+ unsigned char padding_start[4];
+ char ssid[32];
+ char password[32];
+ int calibration[4];
+ unsigned char padding_end[4];
+ };
+ unsigned char __full[sizeof(int) * 4 + 32 * 2 + 4 * 2];
+ };
+};
+
+#endif /* CONFIGURATION_DATA_INCLUDED */
diff --git a/meson.build b/meson.build
index d1f6305..cbef6cb 100644
--- a/meson.build
+++ b/meson.build
@@ -6,14 +6,17 @@ deps = [dependency('threads')]
deps += dependency('gtk+-3.0')
deps += dependency('ncurses')
+progname = 'coffeetemp'
+resource_dir = join_paths(get_option('datadir'), progname)
+
subdir('src')
-progname = 'coffeetemp'
+inc = include_directories('include')
-resource_dir = join_paths(get_option('datadir'), progname)
resource_dir_arg = 'DATA_DIR=' + '"' + join_paths(get_option('prefix'), resource_dir) + '"'
add_project_arguments('-D', resource_dir_arg, language : 'c')
+add_project_link_arguments('-rdynamic', language : 'c')
-destktop_application = executable(progname, sources, gui_app : true, install : true, dependencies : deps, extra_files : extra)
+destktop_application = executable(progname, sources, include_directories : inc, gui_app : true, install : true, dependencies : deps, extra_files : extra)
install_data(extra, install_dir : resource_dir)
diff --git a/src/meson.build b/src/meson.build
index eba583d..5453018 100644
--- a/src/meson.build
+++ b/src/meson.build
@@ -2,4 +2,4 @@ subdir('server')
subdir('tempmodule')
sources = dp_sources
-extra = dp_extra
+extra = [dp_extra]
diff --git a/src/server/gtk.c b/src/server/gtk.c
index 36b36bb..f48d1d9 100644
--- a/src/server/gtk.c
+++ b/src/server/gtk.c
@@ -20,6 +20,7 @@
#include <gtk/gtk.h>
#include <time.h>
+#include <stdlib.h>
#include <string.h>
#include "util.h"
#include "gtk.h"
@@ -37,20 +38,45 @@ struct gtkui {
GObject *voltage;
GObject *reslabel;
GObject *voltlabel;
- GObject *showmorebutton;
- GObject *button_on;
- GObject *button_off;
+ GObject *show_more;
+ GObject *show_less;
GObject *ticker;
GError *error;
int showmore;
};
+struct gtkui_flash {
+ GtkBuilder *builder;
+ GObject *window;
+ GObject *ssid;
+ GObject *password;
+ GObject *htemp;
+ GObject *mhtemp;
+ GObject *mltemp;
+ GObject *ltemp;
+ GObject *flashdialog;
+ GObject *dialog_ok;
+ GObject *dialog_text;
+ const char *confdata[6];
+ int close_with_dialog;
+};
+
static struct settings settings;
static struct gtkui gtkui;
+static struct gtkui_flash gtkui_flash;
static int gtkui_update(void *data);
static void gtkui_die(void *data);
-static void gtkui_togglemore(void);
+static int strtokel(const char * const s);
+void gtkui_togglemore(void);
+void gtkui_flashwindow_create(void);
+void gtkui_flashwindow_destroy(void);
+void gtkui_flashwindow_clean(void);
+void gtkui_issue_flash_request(void);
+void gtkui_readhtemp(void);
+void gtkui_readmhtemp(void);
+void gtkui_readmltemp(void);
+void gtkui_readltemp(void);
int gtkui_init(int *argc, char ***argv, int nd, struct timespec period)
{
@@ -66,10 +92,7 @@ int gtkui_init(int *argc, char ***argv, int nd, struct timespec period)
gtkui.builder = gtk_builder_new();
- if (!gtk_builder_add_from_file(gtkui.builder, DATA_DIR "/gtklayout.ui", &gtkui.error)) {
- ret = ERROR;
- goto fail;
- }
+ gtkui.builder = gtk_builder_new_from_file(DATA_DIR "/gtklayout.ui");
gtkui.window = gtk_builder_get_object(gtkui.builder, "window");
gtkui.tempvalue = gtk_builder_get_object(gtkui.builder, "tempvalue");
@@ -77,12 +100,13 @@ int gtkui_init(int *argc, char ***argv, int nd, struct timespec period)
gtkui.voltage = gtk_builder_get_object(gtkui.builder, "voltage");
gtkui.reslabel = gtk_builder_get_object(gtkui.builder, "reslabel");
gtkui.voltlabel = gtk_builder_get_object(gtkui.builder, "voltlabel");
- gtkui.showmorebutton = gtk_builder_get_object(gtkui.builder, "showmore");
- gtkui.button_on = gtk_builder_get_object(gtkui.builder, "button_on");
- gtkui.button_off = gtk_builder_get_object(gtkui.builder, "button_off");
+ gtkui.show_more = gtk_builder_get_object(gtkui.builder, "show_more");
+ gtkui.show_less = gtk_builder_get_object(gtkui.builder, "show_less");
gtkui.ticker = gtk_builder_get_object(gtkui.builder, "ticker");
- g_signal_connect(gtkui.window, "destroy", G_CALLBACK(gtk_main_quit), NULL);
- g_signal_connect(gtkui.showmorebutton, "toggled", G_CALLBACK(gtkui_togglemore), NULL);
+ gtk_builder_connect_signals(gtkui.builder, NULL);
+ g_object_unref(G_OBJECT(gtkui.builder));
+ gtkui.builder = NULL;
+
gtkui.showmore = 1; /* we are setting this so we can toggle this off on the following call */
gtkui_togglemore();
@@ -137,13 +161,165 @@ static void gtkui_die(void *data)
return;
}
-static void gtkui_togglemore(void)
+static int strtokel(const char * const s)
+{
+ int ret;
+
+ ret = atoi(s);
+ ret += 273;
+ ret *= 10;
+
+ return ret;
+}
+
+void gtkui_togglemore(void)
{
gtkui.showmore = !gtkui.showmore;
- gtkui.showmore ? gtk_button_set_image(GTK_BUTTON(gtkui.showmorebutton), GTK_WIDGET(gtkui.button_on)) :
- gtk_button_set_image(GTK_BUTTON(gtkui.showmorebutton), GTK_WIDGET(gtkui.button_off));
- gtk_widget_set_visible (GTK_WIDGET(gtkui.resistance), gtkui.showmore);
- gtk_widget_set_visible (GTK_WIDGET(gtkui.voltage), gtkui.showmore);
- gtk_widget_set_visible (GTK_WIDGET(gtkui.reslabel), gtkui.showmore);
- gtk_widget_set_visible (GTK_WIDGET(gtkui.voltlabel), gtkui.showmore);
+
+ /* this actually switches them around their state */
+ gtk_widget_set_visible(GTK_WIDGET(gtkui.show_more), !gtkui.showmore);
+ gtk_widget_set_visible(GTK_WIDGET(gtkui.show_less), gtkui.showmore);
+
+ gtk_widget_set_visible(GTK_WIDGET(gtkui.resistance), gtkui.showmore);
+ gtk_widget_set_visible(GTK_WIDGET(gtkui.voltage), gtkui.showmore);
+ gtk_widget_set_visible(GTK_WIDGET(gtkui.reslabel), gtkui.showmore);
+ gtk_widget_set_visible(GTK_WIDGET(gtkui.voltlabel), gtkui.showmore);
+}
+
+void gtkui_flashwindow_create(void)
+{
+ if (gtkui_flash.window) {
+ goto fail;
+ }
+
+ gtkui_flash.builder = gtk_builder_new_from_file(DATA_DIR "/gtklayout_flash.ui");
+ gtkui_flash.window = gtk_builder_get_object(gtkui_flash.builder, "flashwindow");
+ gtkui_flash.ssid = gtk_builder_get_object(gtkui_flash.builder, "ssid_entry");
+ gtkui_flash.password = gtk_builder_get_object(gtkui_flash.builder, "pass_entry");
+ gtkui_flash.htemp = gtk_builder_get_object(gtkui_flash.builder, "htemp_entry");
+ gtkui_flash.mhtemp = gtk_builder_get_object(gtkui_flash.builder, "mhtemp_entry");
+ gtkui_flash.mltemp = gtk_builder_get_object(gtkui_flash.builder, "mltemp_entry");
+ gtkui_flash.ltemp = gtk_builder_get_object(gtkui_flash.builder, "ltemp_entry");
+ gtkui_flash.flashdialog = gtk_builder_get_object(gtkui_flash.builder, "flashdialog");
+ gtkui_flash.dialog_ok = gtk_builder_get_object(gtkui_flash.builder, "dialog_ok");
+ gtkui_flash.dialog_text = gtk_builder_get_object(gtkui_flash.builder, "dialog_text");
+ gtk_builder_connect_signals(gtkui_flash.builder, NULL);
+ g_object_unref(G_OBJECT(gtkui_flash.builder));
+ gtkui_flash.builder = NULL;
+
+fail:
+ return;
+}
+
+void gtkui_window_destroy(void *window)
+{
+ gtk_window_close(GTK_WINDOW(window));
+}
+
+void gtkui_flashwindow_clean(void)
+{
+ gtkui_flash.window = NULL;
+}
+
+void gtkui_issue_flash_request(void)
+{
+ static const struct configuration def = {{{
+ PADDING_START,
+ "ssid", /* ssid */
+ "password", /* password */
+ {3330, 3230, 3130, 3030}, /* calibration */
+ PADDING_END
+ }}};
+
+ struct configuration conf;
+ size_t i;
+ size_t len;
+ const char *tmp;
+
+ gtk_widget_set_visible(GTK_WIDGET(gtkui_flash.flashdialog), 1);
+
+ for (i = 0; i < sizeof (gtkui_flash.confdata); ++i) {
+ switch (i) {
+ case 0:
+ tmp = gtkui_flash.confdata[i] ? gtkui_flash.confdata[i] : def.ssid;
+ len = strlen(tmp) > (sizeof(conf.ssid) - 1) ? sizeof(conf.ssid) - 1 : strlen(tmp);
+ memcpy(conf.ssid, tmp, len);
+ conf.ssid[len] = '\0';
+ break;
+ case 1:
+ tmp = gtkui_flash.confdata[i] ? gtkui_flash.confdata[i] : def.password;
+ len = strlen(tmp) > (sizeof(conf.password) - 1) ? sizeof(conf.password) - 1 : strlen(tmp);
+ memcpy(conf.password, tmp, len);
+ conf.password[len] = '\0';
+ break;
+ case 2:
+ case 3:
+ case 4:
+ case 5:
+ tmp = gtkui_flash.confdata[i] ? (char *) strlen(gtkui_flash.confdata[i]) : NULL;
+ conf.calibration[i - 2] = tmp ? strtokel(gtkui_flash.confdata[i]) : def.calibration[i -2];
+ break;
+ default:
+ break;
+ }
+
+ }
+
+ write_settings(DATA_DIR "/fw.bin", &conf);
+}
+
+void gtkui_readssid(void)
+{
+ gtkui_flash.confdata[0] = gtk_entry_get_text(GTK_ENTRY(gtkui_flash.ssid));
+}
+
+void gtkui_readpass(void)
+{
+ gtkui_flash.confdata[1] = gtk_entry_get_text(GTK_ENTRY(gtkui_flash.password));
+}
+
+void gtkui_readhtemp(void)
+{
+ gtkui_flash.confdata[2] = gtk_entry_get_text(GTK_ENTRY(gtkui_flash.htemp));
+}
+
+void gtkui_readmhtemp(void)
+{
+ gtkui_flash.confdata[3] = gtk_entry_get_text(GTK_ENTRY(gtkui_flash.mhtemp));
+}
+
+void gtkui_readmltemp(void)
+{
+ gtkui_flash.confdata[4] = gtk_entry_get_text(GTK_ENTRY(gtkui_flash.mltemp));
+}
+
+void gtkui_readltemp(void)
+{
+ gtkui_flash.confdata[5] = gtk_entry_get_text(GTK_ENTRY(gtkui_flash.ltemp));
+}
+
+void gtkui_manhandle_flashdialog(void *dialog)
+{
+ gtk_label_set_markup(GTK_LABEL(gtkui_flash.dialog_text), "Writing to flash... ");
+ if (gtkui_flash.close_with_dialog) {
+ gtk_widget_destroy(GTK_WIDGET(dialog));
+ /* we also want to close tha parent */
+ gtk_window_close(GTK_WINDOW(gtkui_flash.window));
+ } else {
+ gtk_widget_set_visible(GTK_WIDGET(dialog), 0);
+ }
+}
+
+void gtkui_dialog_done(int status)
+{
+ static const char * const text[2] = {"done", "FAIL"};
+ static const char * const color[2] = {"#4E9A06", "#EF2929"};
+ char msg[128];
+
+ status = status ? 1 : status;
+ gtkui_flash.close_with_dialog = !status;
+ sprintf(msg, "Writing to flash... <span foreground=\"%s\" font_weight=\"bold\">%s!</span>", color[status], text[status]);
+
+ gtk_widget_set_sensitive(GTK_WIDGET(gtkui_flash.dialog_ok), 1);
+ gtk_label_set_markup(GTK_LABEL(gtkui_flash.dialog_text), msg);
}
diff --git a/src/server/gtk.h b/src/server/gtk.h
index 0c47b0b..ad739e5 100644
--- a/src/server/gtk.h
+++ b/src/server/gtk.h
@@ -27,5 +27,6 @@
int gtkui_init(int *argc, char ***argv, int nd, struct timespec period);
int gtkui_loop(void);
+void gtkui_dialog_done(int status);
#endif /* GTK_H_INCLUDED */
diff --git a/src/server/gtk.o b/src/server/gtk.o
deleted file mode 100644
index 0c2098d..0000000
--- a/src/server/gtk.o
+++ /dev/null
Binary files differ
diff --git a/src/server/gtklayout.ui b/src/server/gtklayout.ui
index 69fd947..e6d3f5a 100644
--- a/src/server/gtklayout.ui
+++ b/src/server/gtklayout.ui
@@ -2,12 +2,17 @@
<!-- Generated with glade 3.20.0 -->
<interface>
<requires lib="gtk+" version="3.20"/>
- <object class="GtkImage" id="button_off">
+ <object class="GtkImage" id="gtk-flash">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="stock">gtk-properties</property>
+ </object>
+ <object class="GtkImage" id="gtk-no-stock">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="stock">gtk-no</property>
</object>
- <object class="GtkImage" id="button_on">
+ <object class="GtkImage" id="gtk-yes-stock">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="stock">gtk-yes</property>
@@ -15,112 +20,260 @@
<object class="GtkWindow" id="window">
<property name="visible">True</property>
<property name="can_focus">False</property>
- <property name="title" translatable="yes">Coffeetemp</property>
<property name="resizable">False</property>
+ <signal name="destroy" handler="gtk_main_quit" swapped="no"/>
<child>
- <object class="GtkGrid">
+ <object class="GtkBox">
<property name="visible">True</property>
<property name="can_focus">False</property>
+ <property name="orientation">vertical</property>
<child>
- <object class="GtkLabel" id="ticker">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- </object>
- <packing>
- <property name="left_attach">0</property>
- <property name="top_attach">0</property>
- </packing>
- </child>
- <child>
- <object class="GtkLabel">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="label" translatable="yes"> Temperature: </property>
- </object>
- <packing>
- <property name="left_attach">1</property>
- <property name="top_attach">0</property>
- </packing>
- </child>
- <child>
- <object class="GtkLabel" id="tempvalue">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- </object>
- <packing>
- <property name="left_attach">2</property>
- <property name="top_attach">0</property>
- </packing>
- </child>
- <child>
- <object class="GtkToggleButton" id="showmore">
- <property name="label" translatable="yes">show all</property>
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="receives_default">True</property>
- <property name="image">button_on</property>
- <property name="always_show_image">True</property>
- <property name="draw_indicator">True</property>
- </object>
- <packing>
- <property name="left_attach">3</property>
- <property name="top_attach">0</property>
- </packing>
- </child>
- <child>
- <object class="GtkLabel" id="reslabel">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="label" translatable="yes"> Resistence: </property>
- </object>
- <packing>
- <property name="left_attach">1</property>
- <property name="top_attach">1</property>
- </packing>
- </child>
- <child>
- <object class="GtkLabel" id="resistance">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- </object>
- <packing>
- <property name="left_attach">2</property>
- <property name="top_attach">1</property>
- </packing>
- </child>
- <child>
- <object class="GtkLabel" id="voltage">
+ <object class="GtkMenuBar" id="menu">
<property name="visible">True</property>
<property name="can_focus">False</property>
+ <child>
+ <object class="GtkMenuItem">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes">_File</property>
+ <property name="use_underline">True</property>
+ <child type="submenu">
+ <object class="GtkMenu">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <child>
+ <object class="GtkImageMenuItem">
+ <property name="label">gtk-quit</property>
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="use_underline">True</property>
+ <property name="use_stock">True</property>
+ <property name="always_show_image">True</property>
+ <signal name="activate" handler="gtk_main_quit" swapped="no"/>
+ </object>
+ </child>
+ </object>
+ </child>
+ </object>
+ </child>
+ <child>
+ <object class="GtkMenuItem">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes">_Edit</property>
+ <property name="use_underline">True</property>
+ <child type="submenu">
+ <object class="GtkMenu">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <child>
+ <object class="GtkImageMenuItem">
+ <property name="label">_Reflash</property>
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="use_underline">True</property>
+ <property name="image">gtk-flash</property>
+ <property name="use_stock">False</property>
+ <property name="always_show_image">True</property>
+ <signal name="activate" handler="gtkui_flashwindow_create" swapped="no"/>
+ </object>
+ </child>
+ </object>
+ </child>
+ </object>
+ </child>
+ <child>
+ <object class="GtkMenuItem">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes">_View</property>
+ <property name="use_underline">True</property>
+ <child type="submenu">
+ <object class="GtkMenu">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <child>
+ <object class="GtkImageMenuItem" id="show_more">
+ <property name="label">Show _more</property>
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="use_underline">True</property>
+ <property name="image">gtk-yes-stock</property>
+ <property name="use_stock">False</property>
+ <property name="always_show_image">True</property>
+ <signal name="activate" handler="gtkui_togglemore" swapped="no"/>
+ </object>
+ </child>
+ <child>
+ <object class="GtkImageMenuItem" id="show_less">
+ <property name="label">Show _less</property>
+ <property name="can_focus">False</property>
+ <property name="use_underline">True</property>
+ <property name="image">gtk-no-stock</property>
+ <property name="use_stock">False</property>
+ <property name="always_show_image">True</property>
+ <signal name="activate" handler="gtkui_togglemore" swapped="no"/>
+ </object>
+ </child>
+ </object>
+ </child>
+ </object>
+ </child>
+ <child>
+ <object class="GtkMenuItem">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes">_Help</property>
+ <property name="use_underline">True</property>
+ <child type="submenu">
+ <object class="GtkMenu">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <child>
+ <object class="GtkImageMenuItem">
+ <property name="label">gtk-about</property>
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="use_underline">True</property>
+ <property name="use_stock">True</property>
+ <property name="always_show_image">True</property>
+ </object>
+ </child>
+ </object>
+ </child>
+ </object>
+ </child>
</object>
<packing>
- <property name="left_attach">2</property>
- <property name="top_attach">2</property>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
</packing>
</child>
<child>
- <object class="GtkLabel" id="voltlabel">
+ <object class="GtkGrid">
<property name="visible">True</property>
<property name="can_focus">False</property>
- <property name="label" translatable="yes"> Voltage: </property>
+ <child>
+ <object class="GtkLabel" id="ticker">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="margin_left">4</property>
+ <property name="margin_right">2</property>
+ <property name="margin_top">2</property>
+ <property name="margin_bottom">2</property>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="halign">end</property>
+ <property name="margin_left">2</property>
+ <property name="margin_right">2</property>
+ <property name="margin_top">2</property>
+ <property name="margin_bottom">2</property>
+ <property name="label" translatable="yes"> Temperature: </property>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="tempvalue">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="halign">start</property>
+ <property name="margin_left">2</property>
+ <property name="margin_right">2</property>
+ <property name="margin_top">2</property>
+ <property name="margin_bottom">2</property>
+ </object>
+ <packing>
+ <property name="left_attach">2</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="reslabel">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="halign">end</property>
+ <property name="margin_left">2</property>
+ <property name="margin_right">2</property>
+ <property name="margin_top">2</property>
+ <property name="margin_bottom">2</property>
+ <property name="label" translatable="yes"> Resistence: </property>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="resistance">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="halign">start</property>
+ <property name="margin_left">2</property>
+ <property name="margin_right">2</property>
+ <property name="margin_top">2</property>
+ <property name="margin_bottom">2</property>
+ </object>
+ <packing>
+ <property name="left_attach">2</property>
+ <property name="top_attach">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="voltage">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="halign">start</property>
+ <property name="margin_left">2</property>
+ <property name="margin_right">2</property>
+ <property name="margin_top">2</property>
+ <property name="margin_bottom">2</property>
+ </object>
+ <packing>
+ <property name="left_attach">2</property>
+ <property name="top_attach">2</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="voltlabel">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="halign">end</property>
+ <property name="margin_left">2</property>
+ <property name="margin_right">2</property>
+ <property name="margin_top">2</property>
+ <property name="margin_bottom">2</property>
+ <property name="label" translatable="yes"> Voltage: </property>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">2</property>
+ </packing>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
</object>
<packing>
- <property name="left_attach">1</property>
- <property name="top_attach">2</property>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
</packing>
</child>
- <child>
- <placeholder/>
- </child>
- <child>
- <placeholder/>
- </child>
- <child>
- <placeholder/>
- </child>
- <child>
- <placeholder/>
- </child>
</object>
</child>
</object>
diff --git a/src/server/gtklayout_flash.ui b/src/server/gtklayout_flash.ui
new file mode 100644
index 0000000..9972a4e
--- /dev/null
+++ b/src/server/gtklayout_flash.ui
@@ -0,0 +1,371 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Generated with glade 3.20.0 -->
+<interface>
+ <requires lib="gtk+" version="3.20"/>
+ <object class="GtkImage" id="cancel">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="stock">gtk-cancel</property>
+ </object>
+ <object class="GtkImage" id="ok">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="stock">gtk-apply</property>
+ </object>
+ <object class="GtkWindow" id="flashwindow">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="title" translatable="yes">coffeetemp – write flash</property>
+ <property name="resizable">False</property>
+ <property name="destroy_with_parent">True</property>
+ <child>
+ <object class="GtkGrid">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <signal name="destroy" handler="gtkui_flashwindow_clean" swapped="no"/>
+ <child>
+ <object class="GtkEntry" id="ssid_entry">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="max_length">32</property>
+ <signal name="changed" handler="gtkui_readssid" swapped="no"/>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkEntry" id="pass_entry">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="max_length">32</property>
+ <property name="visibility">False</property>
+ <property name="input_purpose">password</property>
+ <signal name="changed" handler="gtkui_readpass" swapped="no"/>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkEntry" id="htemp_entry">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="max_length">6</property>
+ <property name="input_purpose">digits</property>
+ <signal name="changed" handler="gtkui_readhtemp" swapped="no"/>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">2</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="halign">end</property>
+ <property name="margin_left">2</property>
+ <property name="margin_right">2</property>
+ <property name="margin_top">2</property>
+ <property name="margin_bottom">2</property>
+ <property name="label" translatable="yes">SSID:</property>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="halign">end</property>
+ <property name="margin_left">2</property>
+ <property name="margin_right">2</property>
+ <property name="margin_top">2</property>
+ <property name="margin_bottom">2</property>
+ <property name="label" translatable="yes">Password:</property>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="halign">end</property>
+ <property name="margin_left">2</property>
+ <property name="margin_right">2</property>
+ <property name="margin_top">2</property>
+ <property name="margin_bottom">2</property>
+ <property name="label" translatable="yes">High Temp:</property>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">2</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="halign">end</property>
+ <property name="margin_left">2</property>
+ <property name="margin_right">2</property>
+ <property name="margin_top">2</property>
+ <property name="margin_bottom">2</property>
+ <property name="label" translatable="yes">Mid-high Temp:</property>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">3</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkEntry" id="mhtemp_entry">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="max_length">6</property>
+ <property name="input_purpose">digits</property>
+ <signal name="changed" handler="gtkui_readmhtemp" swapped="no"/>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">3</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="halign">start</property>
+ <property name="margin_left">2</property>
+ <property name="margin_right">2</property>
+ <property name="margin_top">2</property>
+ <property name="margin_bottom">2</property>
+ <property name="label" translatable="yes">°C</property>
+ </object>
+ <packing>
+ <property name="left_attach">2</property>
+ <property name="top_attach">2</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="halign">start</property>
+ <property name="margin_left">2</property>
+ <property name="margin_right">2</property>
+ <property name="margin_top">2</property>
+ <property name="margin_bottom">2</property>
+ <property name="label" translatable="yes">°C</property>
+ </object>
+ <packing>
+ <property name="left_attach">2</property>
+ <property name="top_attach">3</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="cancelbutton">
+ <property name="label" translatable="yes">Cancel</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="image">cancel</property>
+ <signal name="clicked" handler="gtk_window_close" object="flashwindow" swapped="no"/>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">6</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="flashbutton">
+ <property name="label" translatable="yes">Write Flash</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="image">ok</property>
+ <signal name="clicked" handler="gtkui_issue_flash_request" swapped="no"/>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">6</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="halign">end</property>
+ <property name="margin_left">2</property>
+ <property name="margin_right">2</property>
+ <property name="margin_top">2</property>
+ <property name="margin_bottom">2</property>
+ <property name="label" translatable="yes">Low Temp:</property>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">5</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkEntry" id="ltemp_entry">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="max_length">6</property>
+ <property name="input_purpose">digits</property>
+ <signal name="changed" handler="gtkui_readltemp" swapped="no"/>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">5</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="halign">start</property>
+ <property name="margin_left">2</property>
+ <property name="margin_right">2</property>
+ <property name="margin_top">2</property>
+ <property name="margin_bottom">2</property>
+ <property name="label" translatable="yes">°C</property>
+ </object>
+ <packing>
+ <property name="left_attach">2</property>
+ <property name="top_attach">4</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="halign">start</property>
+ <property name="margin_left">2</property>
+ <property name="margin_right">2</property>
+ <property name="margin_top">1</property>
+ <property name="margin_bottom">1</property>
+ <property name="label" translatable="yes">°C</property>
+ </object>
+ <packing>
+ <property name="left_attach">2</property>
+ <property name="top_attach">5</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="halign">end</property>
+ <property name="margin_left">2</property>
+ <property name="margin_right">2</property>
+ <property name="margin_top">1</property>
+ <property name="margin_bottom">1</property>
+ <property name="label" translatable="yes">Mid-low Temp:</property>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">4</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkEntry" id="mltemp_entry">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="max_length">6</property>
+ <property name="input_purpose">digits</property>
+ <signal name="changed" handler="gtkui_readmltemp" swapped="no"/>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">4</property>
+ </packing>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ </object>
+ </child>
+ </object>
+ <object class="GtkDialog" id="flashdialog">
+ <property name="can_focus">False</property>
+ <property name="title" translatable="yes">Flashing...</property>
+ <property name="resizable">False</property>
+ <property name="modal">True</property>
+ <property name="destroy_with_parent">True</property>
+ <property name="type_hint">dialog</property>
+ <property name="skip_taskbar_hint">True</property>
+ <property name="transient_for">flashwindow</property>
+ <property name="attached_to">flashwindow</property>
+ <signal name="close" handler="gtkui_manhandle_flashdialog" swapped="no"/>
+ <signal name="delete-event" handler="gtk_widget_hide_on_delete" swapped="no"/>
+ <child internal-child="vbox">
+ <object class="GtkBox">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">2</property>
+ <child internal-child="action_area">
+ <object class="GtkButtonBox">
+ <property name="can_focus">False</property>
+ <property name="layout_style">end</property>
+ <child>
+ <object class="GtkButton" id="dialog_ok">
+ <property name="label">gtk-ok</property>
+ <property name="visible">True</property>
+ <property name="sensitive">False</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="use_stock">True</property>
+ <signal name="clicked" handler="gtkui_manhandle_flashdialog" object="flashdialog" swapped="yes"/>
+ </object>
+ <packing>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">2</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="dialog_text">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="halign">start</property>
+ <property name="margin_left">3</property>
+ <property name="margin_right">3</property>
+ <property name="margin_top">3</property>
+ <property name="margin_bottom">3</property>
+ <property name="hexpand">True</property>
+ <property name="label" translatable="yes">Writing to flash... </property>
+ <property name="width_chars">25</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ </object>
+</interface>
diff --git a/src/server/meson.build b/src/server/meson.build
index c95f9a9..2b7af61 100644
--- a/src/server/meson.build
+++ b/src/server/meson.build
@@ -14,6 +14,7 @@ dp_filenames = [
dp_extra_filenames = [
'gtklayout.ui',
+ 'gtklayout_flash.ui',
]
dp_sources = files(dp_filenames)
diff --git a/src/server/util.c b/src/server/util.c
index bb494c8..4aee886 100644
--- a/src/server/util.c
+++ b/src/server/util.c
@@ -18,12 +18,32 @@
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/wait.h>
+#include <gtk/gtk.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <time.h>
+#include <endian.h>
#include <string.h>
+#include <stdlib.h>
+#include <stdio.h>
#include "util.h"
#include "net.h"
+#include "gtk.h"
+
+struct child_data {
+ char **argv;
+ int fd;
+ char *buf;
+};
static float digest_temp(const short int rawtemp);
static float digest_volt(const short int rawvolt);
+static int find_settings_region(char *start, char *end, char *buf, size_t n);
+static int flash(char *buf, size_t address, size_t size, char* port);
+void reap_dead_children(int pid, int status, void *data);
/*
* raw data is in 0.1°K per 1. Subtract 2730 to get Celsius.
@@ -57,3 +77,125 @@ int refresh_data(int nd, struct tempmodule_state *state)
return ret;
}
+
+
+int write_settings(char *imagename, const struct configuration * const conf)
+{
+ /* the largest flash size supported by ESP-8266 is 16MiB, so let's just use that. */
+ static const size_t flash_size = 16 * 1024 * 1024;
+ char pattern_a[4] = PADDING_START;
+ char pattern_b[4] = PADDING_END;
+ ssize_t buf_used;
+ ssize_t offset;
+ char *buf = NULL;
+ int fd;
+ int ret = ERROR;
+
+ fd = open(imagename, O_RDONLY);
+ if (fd < 0) {
+ goto fail;
+ }
+ buf = malloc(flash_size);
+ buf_used = read(fd, buf, flash_size);
+ close(fd);
+ if (buf_used < sizeof(struct configuration)) {
+ goto fail;
+ }
+
+ offset = find_settings_region(pattern_a, pattern_b, buf, buf_used);
+ if (offset == ERROR) {
+ goto fail;
+ };
+
+ memcpy(buf + offset, conf, sizeof(struct configuration));
+ /* make sure the block written is aligned on 4k boundry
+ * and is 4k of size.
+ *
+ * see:
+ * https://github.com/espressif/esptool/issues/306
+ */
+ offset &= ~(0xfff);
+ ret = flash(buf + offset, offset, 4 * 1024, NULL);
+
+fail:
+ free(buf);
+ return ret;
+}
+
+static int find_settings_region(char *start, char *end, char *buf, size_t n)
+{
+ int ret = ERROR;
+ char *a;
+
+ if (!(a = memmem(buf, n, start, 4))) {
+ goto fail;
+ }
+
+ if ((a - buf + sizeof(struct configuration)) > n) {
+ goto fail;
+ }
+
+ if (memcmp(a + sizeof(struct configuration) - 4, end, 4)) {
+ goto fail;
+ }
+
+ ret = a - buf;
+fail:
+ return ret;
+}
+
+static int flash(char *buf, size_t address, size_t size, char* port)
+{
+ static const char esptool[] = "esptool.py";
+ static const char command[] = "write_flash";
+ struct child_data *cdata;
+ char tmpfn[] = "espXXXXXX"; /* temporary file name template */
+ char *fifn; /* flash image file name */
+ char textbuf[32];
+ char *argv[7] = {0};
+ int ret = ERROR;
+ pid_t pid;
+ int fd;
+ size_t i = 1;
+
+ fd = mkstemp(tmpfn);
+ write(fd, buf, size);
+ fifn = malloc(0x100);
+ memset(fifn, '\0', 0x100);
+ sprintf(textbuf, "/proc/self/fd/%d", fd);
+ if (readlink(textbuf, fifn, 0x100) == -1) {
+ exit(TMPFILE);
+ }
+
+ argv[0] = strdup(esptool);
+ if (port) {
+ argv[i++] = strdup("--port");
+ argv[i++] = strdup(port);
+ }
+ argv[i++] = strdup(command);
+ sprintf(textbuf, "%#.4lx", address);
+ argv[i++] = strdup(textbuf);
+ argv[i++] = strdup(fifn);
+ argv[i] = NULL;
+
+ cdata = malloc(sizeof(*cdata));
+ cdata->argv = argv;
+ cdata->fd = fd;
+ cdata->buf = fifn;
+
+ g_spawn_async_with_pipes(NULL, argv, NULL, G_SPAWN_SEARCH_PATH | G_SPAWN_LEAVE_DESCRIPTORS_OPEN | G_SPAWN_DO_NOT_REAP_CHILD, NULL, NULL, &pid, NULL, NULL, NULL, NULL);
+ g_child_watch_add(pid, reap_dead_children, cdata);
+ return ret;
+}
+
+void reap_dead_children(int pid, int status, void *data)
+{
+ struct child_data *a;
+
+ a = data;
+ free(a->buf);
+ close(a->fd);
+ free(data);
+ g_spawn_close_pid(pid);
+ gtkui_dialog_done(status);
+}
diff --git a/src/server/util.h b/src/server/util.h
index 9c0f907..ef5cde2 100644
--- a/src/server/util.h
+++ b/src/server/util.h
@@ -21,13 +21,17 @@
#ifndef UTIL_H_INCLUDED
#define UTIL_H_INCLUDED
+#include "datatypes.h"
+
#define arrsize(a) (sizeof(a)/sizeof(*a))
enum response {
ERROR = -1,
- A_OK = 0,
- NONEWDATA = 1,
- DEAD = 2
+ A_OK = 0, /* would be "OK", but clashes with some lib definitions */
+ NONEWDATA,
+ DEAD,
+ NO_ESPTOOL,
+ TMPFILE,
};
struct tempmodule_state {
@@ -51,5 +55,6 @@ struct tempmodule_state {
};
int refresh_data(int nd, struct tempmodule_state *state);
+int write_settings(char *imagename, const struct configuration * const conf);
#endif /* UTIL_H_INCLUDED */
diff --git a/src/tempmodule/configuration.c b/src/tempmodule/configuration.c
new file mode 100644
index 0000000..76acde8
--- /dev/null
+++ b/src/tempmodule/configuration.c
@@ -0,0 +1,33 @@
+/*
+ * Hot Beverage Companion – configuration data
+ *
+ * Copyright (C) 2018 Gediminas Jakutis
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; version 2.1
+ * of the License.
+ *
+ * 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/* We want the padding data to be detectible in the binary
+ * so we could find out the boundries of inner workings.
+ * We also want to detect byte order from the padding.
+ */
+
+#include "datatypes.h"
+volatile const struct configuration configuration = {{{
+ PADDING_START,
+ "ssid", /* ssid */
+ "password", /* password */
+ {3430, 3330, 3230, 3130}, /* calibration */
+ PADDING_END
+}}};
diff --git a/src/tempmodule/configuration.h b/src/tempmodule/configuration.h
new file mode 100644
index 0000000..dfe1264
--- /dev/null
+++ b/src/tempmodule/configuration.h
@@ -0,0 +1,28 @@
+/*
+ * Hot Beverage Companion – configuration data
+ *
+ * Copyright (C) 2018 Gediminas Jakutis
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; version 2.1
+ * of the License.
+ *
+ * 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#ifndef CONFIGURATION_INCLUDED
+#define CONFIGURATION_INCLUDED
+
+#include "datatypes.h"
+
+extern volatile const struct configuration configuration;
+
+#endif /* CONFIGURATION_INCLUDED */
diff --git a/src/tempmodule/datatypes.h b/src/tempmodule/datatypes.h
new file mode 120000
index 0000000..3a91016
--- /dev/null
+++ b/src/tempmodule/datatypes.h
@@ -0,0 +1 @@
+../../include/datatypes.h \ No newline at end of file
diff --git a/src/tempmodule/indicator.c b/src/tempmodule/indicator.c
index 2968958..16df495 100644
--- a/src/tempmodule/indicator.c
+++ b/src/tempmodule/indicator.c
@@ -19,6 +19,8 @@
*/
#include "indicator.h"
+#include "configuration.h"
+#include "volatile_ops.h"
#define HIGH 1
#define LOW 0
@@ -38,8 +40,9 @@ static const unsigned int greenled = 4; /* D2 */
static const unsigned int blueled = 14; /* D5 */
static void indicator_set_state(unsigned int red, unsigned int green, unsigned int blue);
+static void indicator_calibrate(int const * const calibration);
-void indicator_init(int temp, unsigned int const * const calibration)
+void indicator_init(int temp)
{
static const int default_calibration[] = {3430, 3330, 3230, 3130};
@@ -49,11 +52,7 @@ void indicator_init(int temp, unsigned int const * const calibration)
state.current_temp = temp;
- if (calibration) {
- indicator_calibrate(calibration);
- } else {
- indicator_calibrate(default_calibration);
- }
+ indicator_calibrate(configuration.calibration);
}
@@ -79,9 +78,9 @@ void indicator_update(const int temp, const unsigned int on)
}
}
-void indicator_calibrate(int const * const calibration)
+static void indicator_calibrate(int const * const calibration)
{
- memcpy(state.calibration, calibration, sizeof(state.calibration));
+ volatile_memcpy(state.calibration, calibration, sizeof(state.calibration));
indicator_update(state.current_temp, 1);
}
diff --git a/src/tempmodule/indicator.h b/src/tempmodule/indicator.h
index 99f4e1c..23ac87d 100644
--- a/src/tempmodule/indicator.h
+++ b/src/tempmodule/indicator.h
@@ -25,9 +25,8 @@
extern "C" {
#endif
-void indicator_init(int temp, unsigned int const * const calibration);
+void indicator_init(int temp);
void indicator_update(const int temp, const unsigned int on);
-void indicator_calibrate(int const * const calibration);
#ifdef __cplusplus
}
diff --git a/src/tempmodule/main.ino b/src/tempmodule/main.ino
index 29ebc11..914b3ff 100644
--- a/src/tempmodule/main.ino
+++ b/src/tempmodule/main.ino
@@ -25,6 +25,8 @@
#include <limits.h>
#include "indicator.h"
#include "temperature.h"
+#include "configuration.h"
+#include "volatile_ops.h"
#define arrsize(a) (sizeof(a)/sizeof(*a))
@@ -69,7 +71,7 @@ void setup(void)
pinMode(thermistorvcc, OUTPUT);
digitalWrite(thermistorvcc, LOW);
- indicator_init(0, NULL);
+ indicator_init(0);
WiFi.mode(WIFI_OFF);
WiFi.forceSleepBegin();
@@ -90,12 +92,15 @@ void setup(void)
void loop(void)
{
- static const char * const ssid = "SSID";
- static const char * const password = "password";
+ char ssid[32];
+ char password[32];
static unsigned int ticker = 0;
short int data[3];
size_t i;
+ volatile_memcpy(ssid, configuration.ssid, sizeof(configuration.ssid));
+ volatile_memcpy(password, configuration.password, sizeof(configuration.ssid));
+
udp_init_packet(ip, port);
if (wifidesired && !wifistate) {
@@ -193,7 +198,6 @@ static void wifi_disconnect(void)
wifiled_off();
Udp.stop();
WiFi.disconnect(1);
- WiFi.mode(WIFI_OFF);
WiFi.forceSleepBegin();
yield();
wifistate = 0;
diff --git a/src/tempmodule/meson.build b/src/tempmodule/meson.build
index e974884..b2c88b9 100644
--- a/src/tempmodule/meson.build
+++ b/src/tempmodule/meson.build
@@ -1,3 +1,4 @@
+fw_filename = 'fw.bin'
if get_option('fwbuild')
espmake = find_program('espmake')
@@ -5,9 +6,9 @@ if get_option('fwbuild')
fw_filenames = ['main.ino', 'indicator.c', 'temperature.c', 'indicator.h', 'temperature.h']
fw_sources = files(fw_filenames)
fw = custom_target('fw',
- output : 'fw.bin',
+ output : fw_filename,
input : fw_sources,
- command : [espmake, '-C', sourcedir, '&&', 'cp', '/tmp/mkESP/main_d1_mini/main.bin', '@OUTDIR@/fw.bin'])
+ command : [espmake, '-C', sourcedir, '&&', 'cp', '/tmp/mkESP/main_d1_mini/main.bin', '@OUTDIR@/' + fw_filename], install : true, install_dir : resource_dir)
if get_option('fwflash')
esptool = find_program('esptool.py')
diff --git a/src/tempmodule/volatile_ops.c b/src/tempmodule/volatile_ops.c
new file mode 100644
index 0000000..432955a
--- /dev/null
+++ b/src/tempmodule/volatile_ops.c
@@ -0,0 +1,38 @@
+/*
+ * Hot Beverage Companion – volatile data ops
+ *
+ * Copyright (C) 2018 Gediminas Jakutis
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; version 2.1
+ * of the License.
+ *
+ * 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#include "volatile_ops.h"
+
+void *volatile_memcpy(void *dest, volatile const void * const src, size_t n)
+{
+ char *d;
+ volatile const char *s;
+
+ if (!n) {
+ return dest;
+ }
+
+ d = dest;
+ s = src;
+
+ while (n--) {
+ d[n] = s[n];
+ }
+}
diff --git a/src/tempmodule/volatile_ops.h b/src/tempmodule/volatile_ops.h
new file mode 100644
index 0000000..7a165b9
--- /dev/null
+++ b/src/tempmodule/volatile_ops.h
@@ -0,0 +1,36 @@
+/*
+ * Hot Beverage Companion – volatile data ops
+ *
+ * Copyright (C) 2018 Gediminas Jakutis
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; version 2.1
+ * of the License.
+ *
+ * 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#ifndef VOLATILE_OPS_INCLUDED
+#define VOLATILE_OPS_INCLUDED
+
+#include <stddef.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void *volatile_memcpy(void *dest, volatile const void * const src, size_t n);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* VOLATILE_OPS_INCLUDED */