VFD modular clock firmware

Dependencies:   DipCortex-EEprom RTC flw mbed

Revision:
0:f6e68b4ce169
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/menu.cpp	Mon Feb 09 13:40:46 2015 +0000
@@ -0,0 +1,215 @@
+/*
+ * VFD Modular Clock - mbed
+ * (C) 2011-14 Akafugu Corporation
+ *
+ * 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 2 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.
+ *
+ */
+
+#include "global.h"
+#include "menu.h"
+
+char menu_buf[MAX_BUF];
+
+/////////////////////////////////////////////////////////
+// MenuItemValue
+
+MenuItemValue::MenuItemValue(int32_t min, int32_t max)
+: m_min(min)
+, m_max(max)
+, m_value(min)
+, m_activated(false)
+{
+}
+
+int32_t MenuItemValue::getValue()
+{
+    return m_value;
+}
+
+int32_t MenuItemValue::incrementValue()
+{
+    if (m_activated) {
+        m_value++;
+        if (m_value > m_max) m_value = m_min;
+    }
+    else {
+        m_activated = true;    
+    }
+    
+    return m_value;
+}    
+
+void MenuItemValue::resetActive()
+{
+    m_activated = false;
+}
+
+/////////////////////////////////////////////////////////
+// MenuItem
+
+MenuItem::MenuItem(const char* shortName, const char* longName, bool onOff, PREFS pref)
+: m_onOff(onOff)
+, m_pref(pref)
+{
+    strncpy(m_shortName, shortName, 4);
+    strncpy(m_longName, longName, 8);
+    m_menuItemValue = new MenuItemValue(0, 1);
+}
+
+MenuItem::MenuItem(const char* shortName, bool onOff, PREFS pref)
+: m_onOff(onOff)
+, m_pref(pref)
+{
+    strncpy(m_shortName, shortName, 4);
+    m_longName[0] = 0;
+    m_menuItemValue = new MenuItemValue(0, 1);
+}
+
+MenuItem::MenuItem(const char* shortName, const char* longName, int32_t min, int32_t max, PREFS pref)
+: m_onOff(false)
+, m_pref(pref)
+{
+    strncpy(m_shortName, shortName, 4);
+    strncpy(m_longName, longName, 8);    
+    m_menuItemValue = new MenuItemValue(min, max);
+}
+
+MenuItem::MenuItem(const char* shortName, int32_t min, int32_t max, PREFS pref)
+: m_onOff(false)
+, m_pref(pref)
+{
+    strncpy(m_shortName, shortName, 4);
+    m_longName[0] = 0;
+    m_menuItemValue = new MenuItemValue(min, max);
+}
+
+const char* MenuItem::getName(uint8_t digits) const
+{
+    if (m_longName[0] == 0) return m_shortName;
+    return digits <= 4 ? m_shortName : m_longName;
+}
+
+extern DigitalOut led;
+
+const char* MenuItem::selectValue(uint8_t digits) const
+{
+    uint32_t value = m_menuItemValue->incrementValue();
+
+    // special handling
+    if (m_pref == PREF_GPS_TZM) {
+        value *= 15;    
+    }
+    
+    if (m_onOff) {
+        if (value == 1)
+            snprintf(menu_buf, MAX_BUF-1, "%s", "on");
+        else
+            snprintf(menu_buf, MAX_BUF-1, "%s", "off");
+    }
+    else if (m_pref == PREF_FLW) {
+        if (value == 0)
+            snprintf(menu_buf, MAX_BUF-1, "%s", "off");
+        if (value == 1)
+            snprintf(menu_buf, MAX_BUF-1, "%s", "on");
+        else if (value == 2)
+            snprintf(menu_buf, MAX_BUF-1, "%s", "full");            
+    }
+    else {
+        // special handling for year/month/day - these values are not stored in the eeprom
+        // but go directly to the RTC chip
+        if (m_pref == PREF_YEAR) {
+            set_year(value);    
+        }
+        else if (m_pref == PREF_MONTH) {
+            set_month(value);    
+        }
+        else if (m_pref == PREF_DAY) {
+            set_day(value);    
+        }
+        
+        snprintf(menu_buf, MAX_BUF-1, "%d", value);    
+    }
+    
+    // save to prefs
+    if (m_pref != PREF_NULL) {
+        set_pref(m_pref, value);
+    }
+
+    return menu_buf;
+}
+
+void MenuItem::resetActive() const
+{
+    m_menuItemValue->resetActive();
+}
+
+const MenuItem menu1("TIME", "SET TIME", true, PREF_SET_TIME);
+const MenuItem menu2("ALRM", "SET ALR", true, PREF_SET_ALARM);
+const MenuItem menu3("24H", true, PREF_24H);
+const MenuItem menu4("BRIT", "BRITE", 2, 10, PREF_BRIGHTNESS);
+const MenuItem menu5("YEAR", 2014, 2075, PREF_YEAR);
+const MenuItem menu6("MNTH", "MONTH", 1, 12, PREF_MONTH);
+const MenuItem menu7("DAY", 1, 31, PREF_DAY);
+const MenuItem menu8("GPS", true, PREF_GPS);
+const MenuItem menu9("TZH", "GPS TZH", -12, 14, PREF_GPS_TZH);
+const MenuItem menu10("TZM", "GPS TZM", 0, 3, PREF_GPS_TZM);
+const MenuItem menu11("ADTE", "AUTODATE", true, PREF_AUTODATE);
+const MenuItem menu12("FLW", 0, 2, PREF_FLW);
+
+#ifdef HAVE_GPS
+#define ITEMS 12
+const MenuItem* menuItems[] = { &menu1, &menu2, &menu3, &menu4, &menu5, &menu6, &menu7, &menu8, &menu9, &menu10, &menu11, &menu12 };
+#else
+#define ITEMS 8
+const MenuItem* menuItems[] = { &menu1, &menu2, &menu3, &menu4, &menu5, &menu6, &menu7, &menu12 };
+#endif
+
+Menu::Menu()
+    : m_position(0)
+    , m_size(ITEMS)
+    , m_digits(8)
+{
+}
+
+const char* Menu::reset()
+{
+    m_position = 0;
+    return menuItems[m_position]->getName(m_digits);
+}
+
+const char* Menu::next()
+{
+    menuItems[m_position]->resetActive();
+    
+    m_position++;
+    if (m_position >= ITEMS) m_position = 0;
+    
+    return menuItems[m_position]->getName(m_digits);
+}
+
+const char* Menu::select(bool& enterSetTime, bool& enterSetAlarm)
+{
+    enterSetTime = enterSetAlarm = false;
+    
+    if (menuItems[m_position]->isSetTimeTrigger())
+        enterSetTime = true;
+
+    if (menuItems[m_position]->isSetAlarmTrigger())
+        enterSetAlarm = true;
+    
+    return menuItems[m_position]->selectValue(m_digits);
+}
+
+void Menu::leave()
+{
+    menuItems[m_position]->resetActive(); 
+    save_prefs();   
+}
\ No newline at end of file