VFD modular clock firmware

Dependencies:   DipCortex-EEprom RTC flw mbed

Revision:
0:f6e68b4ce169
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/IV18Display.cpp	Mon Feb 09 13:40:46 2015 +0000
@@ -0,0 +1,178 @@
+/*
+ * 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 "IV18Display.h"
+#include "prefs.h"
+
+uint8_t calculate_segments_7(uint8_t character);
+
+IV18Display::IV18Display(PinName data, PinName clock, PinName latch, PinName blank)
+  : VFDDisplay(data, clock, latch, blank, 8)
+{
+    m_reverse_display = true;
+    m_multiplex_limit = 8; // fixme: set to 8 to run . and - digit
+    m_has_dots = true;
+    
+    printf(" Akafugu");
+}
+
+// Writes to the HV5812 driver for IV-18
+// HV1~10:  Digit grids, 10 bits
+// HV11~18: VFD segments, 8 bits
+// HV19~20: NC
+void IV18Display::writeDisplay(uint8_t digit, uint16_t segments)
+{
+  if (digit < 8 && m_dots & (1<<digit))
+    segments |= (1<<7); // DP is at bit 7
+  
+  uint32_t val = (1 << digit) | ((uint32_t)segments << 10);
+
+  writeHV5812(0); // unused upper byte: for HV518P compatibility
+  writeHV5812(val >> 16);
+  writeHV5812(val >> 8);
+  writeHV5812(val);
+  
+  m_latch = 1;
+  m_latch = 0;
+}
+
+uint16_t IV18Display::calculateSegments(char c, uint8_t digit)
+{
+    if (digit == 8) {
+        uint16_t ret = 0;
+        if (m_alarm_indicator)
+            ret |= (1<<7);
+        if (m_gps_indicator)
+            ret |= (1<<6);
+        return ret;
+    }
+    else {
+        return calculate_segments_7(c);
+    }
+}
+
+/*
+void IV18Display::printTime(time_t t, uint8_t hundredths) {
+    struct tm *tmp = localtime(&t);
+    if (tmp == NULL) return;
+    
+    char buf[16];
+
+    if (m_mode == Short) {
+        strftime(buf, 16, " %H.%M.%S ", tmp);
+    }
+    else if (m_mode == Extra) {
+        strftime(buf, 16, "%H.%M.%S", tmp);        
+    }
+    else {
+        strftime(buf, 16, "%H-%M-%S", tmp);
+    }
+    
+    if (m_mode == Extra)
+        printf("%s.%d", buf, hundredths-1);
+    else
+        printf(buf);
+}
+*/
+
+void IV18Display::printTime(struct tm* tm, uint8_t hundredths) {
+    char buf[16];
+    
+    PrefsData* prefs = get_prefs();
+    
+    if (!prefs->prefs.disp_24h && tm->tm_hour >= 12) { // set dot for PM
+        m_gps_indicator = true;
+    }
+    else {
+        m_gps_indicator = false;
+    }
+
+    if (m_mode == Short && prefs->prefs.disp_24h) {
+        strftime(buf, 16, " %H.%M.%S ", tm);
+    }
+    else if (m_mode == Short) {
+        strftime(buf, 16, " %I.%M.%S ", tm);        
+    }
+    else if (m_mode == Extra && prefs->prefs.disp_24h) {
+        strftime(buf, 16, "%H.%M.%S", tm);        
+    }
+    else if (m_mode == Extra) {
+        strftime(buf, 16, "%I.%M.%S", tm);        
+    }
+    else if (prefs->prefs.disp_24h) {
+        strftime(buf, 16, "%H-%M-%S", tm);    
+    }
+    else {
+        strftime(buf, 16, "%I-%M-%S", tm);
+    }
+    
+    if (m_mode == Extra)
+        printf("%s.%d", buf, hundredths-1);
+    else
+        printf(buf);    
+}
+
+void IV18Display::printTimeLong(struct tm* tm, uint8_t hundredths) {
+    char buf[48];
+
+    if (m_mode == Short || m_mode == Extra) {
+        strftime(buf, 48, " %H%M%S %A %B %d %Y", tm);
+    }
+    else {
+        strftime(buf, 48, "%H-%M-%S %A %B %d %Y", tm);
+    }
+    
+    printf(buf);    
+}
+
+void IV18Display::printTimeSet(struct tm* tm, bool showSeconds) {
+        char buf[16];
+        if (showSeconds) {
+                strftime(buf, 16, "%H-%M-%S", tm);
+        }
+        else {
+                strftime(buf, 16, "AL %H-%M", tm);
+        }
+        printf(buf); 
+}
+
+void IV18Display::printDate(struct tm* tm) {
+    char buf[16];
+    strftime(buf, 16, "%F", tm);
+    printf(buf);
+}
+
+void IV18Display::handleBlink(char d) {
+        // fixme: blink should be handled in virtual function in IV18Display
+    if (m_display_on)
+        writeDisplay(m_multiplex_counter, calculateSegments(d, m_multiplex_counter));
+    else {
+            if (m_blink_mode == Seconds && m_multiplex_counter <= 1) {
+        writeDisplay(m_multiplex_counter, 0);               
+            }
+            else if (m_blink_mode == Minutes && m_multiplex_counter >= 3 && m_multiplex_counter <= 4) {
+        writeDisplay(m_multiplex_counter, 0);               
+            }
+            else if (m_blink_mode == Hours && m_multiplex_counter >= 6 && m_multiplex_counter <= 7) {
+        writeDisplay(m_multiplex_counter, 0);               
+            }
+            else if (m_blink_mode == Full) {
+        writeDisplay(m_multiplex_counter, 0);               
+            }
+            else {
+        writeDisplay(m_multiplex_counter, calculateSegments(d, m_multiplex_counter));
+            }
+        }
+}