VFD modular clock firmware
Dependencies: DipCortex-EEprom RTC flw mbed
Diff: IV18Display.cpp
- 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)); + } + } +}