VFD modular clock firmware

Dependencies:   DipCortex-EEprom RTC flw mbed

Committer:
Backstr?m
Date:
Tue Feb 24 23:01:40 2015 +0900
Revision:
12:dfb422107412
Parent:
0:f6e68b4ce169
Added tag v1.0.2 for changeset 34b344fdec98

Who changed what in which revision?

UserRevisionLine numberNew contents of line
Backstrom 0:f6e68b4ce169 1 /*
Backstrom 0:f6e68b4ce169 2 * VFD Modular Clock - mbed
Backstrom 0:f6e68b4ce169 3 * (C) 2011-14 Akafugu Corporation
Backstrom 0:f6e68b4ce169 4 *
Backstrom 0:f6e68b4ce169 5 * This program is free software; you can redistribute it and/or modify it under the
Backstrom 0:f6e68b4ce169 6 * terms of the GNU General Public License as published by the Free Software
Backstrom 0:f6e68b4ce169 7 * Foundation; either version 2 of the License, or (at your option) any later
Backstrom 0:f6e68b4ce169 8 * version.
Backstrom 0:f6e68b4ce169 9 *
Backstrom 0:f6e68b4ce169 10 * This program is distributed in the hope that it will be useful, but WITHOUT ANY
Backstrom 0:f6e68b4ce169 11 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
Backstrom 0:f6e68b4ce169 12 * PARTICULAR PURPOSE. See the GNU General Public License for more details.
Backstrom 0:f6e68b4ce169 13 *
Backstrom 0:f6e68b4ce169 14 */
Backstrom 0:f6e68b4ce169 15
Backstrom 0:f6e68b4ce169 16 #include "IV18Display.h"
Backstrom 0:f6e68b4ce169 17 #include "prefs.h"
Backstrom 0:f6e68b4ce169 18
Backstrom 0:f6e68b4ce169 19 uint8_t calculate_segments_7(uint8_t character);
Backstrom 0:f6e68b4ce169 20
Backstrom 0:f6e68b4ce169 21 IV18Display::IV18Display(PinName data, PinName clock, PinName latch, PinName blank)
Backstrom 0:f6e68b4ce169 22 : VFDDisplay(data, clock, latch, blank, 8)
Backstrom 0:f6e68b4ce169 23 {
Backstrom 0:f6e68b4ce169 24 m_reverse_display = true;
Backstrom 0:f6e68b4ce169 25 m_multiplex_limit = 8; // fixme: set to 8 to run . and - digit
Backstrom 0:f6e68b4ce169 26 m_has_dots = true;
Backstrom 0:f6e68b4ce169 27
Backstrom 0:f6e68b4ce169 28 printf(" Akafugu");
Backstrom 0:f6e68b4ce169 29 }
Backstrom 0:f6e68b4ce169 30
Backstrom 0:f6e68b4ce169 31 // Writes to the HV5812 driver for IV-18
Backstrom 0:f6e68b4ce169 32 // HV1~10: Digit grids, 10 bits
Backstrom 0:f6e68b4ce169 33 // HV11~18: VFD segments, 8 bits
Backstrom 0:f6e68b4ce169 34 // HV19~20: NC
Backstrom 0:f6e68b4ce169 35 void IV18Display::writeDisplay(uint8_t digit, uint16_t segments)
Backstrom 0:f6e68b4ce169 36 {
Backstrom 0:f6e68b4ce169 37 if (digit < 8 && m_dots & (1<<digit))
Backstrom 0:f6e68b4ce169 38 segments |= (1<<7); // DP is at bit 7
Backstrom 0:f6e68b4ce169 39
Backstrom 0:f6e68b4ce169 40 uint32_t val = (1 << digit) | ((uint32_t)segments << 10);
Backstrom 0:f6e68b4ce169 41
Backstrom 0:f6e68b4ce169 42 writeHV5812(0); // unused upper byte: for HV518P compatibility
Backstrom 0:f6e68b4ce169 43 writeHV5812(val >> 16);
Backstrom 0:f6e68b4ce169 44 writeHV5812(val >> 8);
Backstrom 0:f6e68b4ce169 45 writeHV5812(val);
Backstrom 0:f6e68b4ce169 46
Backstrom 0:f6e68b4ce169 47 m_latch = 1;
Backstrom 0:f6e68b4ce169 48 m_latch = 0;
Backstrom 0:f6e68b4ce169 49 }
Backstrom 0:f6e68b4ce169 50
Backstrom 0:f6e68b4ce169 51 uint16_t IV18Display::calculateSegments(char c, uint8_t digit)
Backstrom 0:f6e68b4ce169 52 {
Backstrom 0:f6e68b4ce169 53 if (digit == 8) {
Backstrom 0:f6e68b4ce169 54 uint16_t ret = 0;
Backstrom 0:f6e68b4ce169 55 if (m_alarm_indicator)
Backstrom 0:f6e68b4ce169 56 ret |= (1<<7);
Backstrom 0:f6e68b4ce169 57 if (m_gps_indicator)
Backstrom 0:f6e68b4ce169 58 ret |= (1<<6);
Backstrom 0:f6e68b4ce169 59 return ret;
Backstrom 0:f6e68b4ce169 60 }
Backstrom 0:f6e68b4ce169 61 else {
Backstrom 0:f6e68b4ce169 62 return calculate_segments_7(c);
Backstrom 0:f6e68b4ce169 63 }
Backstrom 0:f6e68b4ce169 64 }
Backstrom 0:f6e68b4ce169 65
Backstrom 0:f6e68b4ce169 66 /*
Backstrom 0:f6e68b4ce169 67 void IV18Display::printTime(time_t t, uint8_t hundredths) {
Backstrom 0:f6e68b4ce169 68 struct tm *tmp = localtime(&t);
Backstrom 0:f6e68b4ce169 69 if (tmp == NULL) return;
Backstrom 0:f6e68b4ce169 70
Backstrom 0:f6e68b4ce169 71 char buf[16];
Backstrom 0:f6e68b4ce169 72
Backstrom 0:f6e68b4ce169 73 if (m_mode == Short) {
Backstrom 0:f6e68b4ce169 74 strftime(buf, 16, " %H.%M.%S ", tmp);
Backstrom 0:f6e68b4ce169 75 }
Backstrom 0:f6e68b4ce169 76 else if (m_mode == Extra) {
Backstrom 0:f6e68b4ce169 77 strftime(buf, 16, "%H.%M.%S", tmp);
Backstrom 0:f6e68b4ce169 78 }
Backstrom 0:f6e68b4ce169 79 else {
Backstrom 0:f6e68b4ce169 80 strftime(buf, 16, "%H-%M-%S", tmp);
Backstrom 0:f6e68b4ce169 81 }
Backstrom 0:f6e68b4ce169 82
Backstrom 0:f6e68b4ce169 83 if (m_mode == Extra)
Backstrom 0:f6e68b4ce169 84 printf("%s.%d", buf, hundredths-1);
Backstrom 0:f6e68b4ce169 85 else
Backstrom 0:f6e68b4ce169 86 printf(buf);
Backstrom 0:f6e68b4ce169 87 }
Backstrom 0:f6e68b4ce169 88 */
Backstrom 0:f6e68b4ce169 89
Backstrom 0:f6e68b4ce169 90 void IV18Display::printTime(struct tm* tm, uint8_t hundredths) {
Backstrom 0:f6e68b4ce169 91 char buf[16];
Backstrom 0:f6e68b4ce169 92
Backstrom 0:f6e68b4ce169 93 PrefsData* prefs = get_prefs();
Backstrom 0:f6e68b4ce169 94
Backstrom 0:f6e68b4ce169 95 if (!prefs->prefs.disp_24h && tm->tm_hour >= 12) { // set dot for PM
Backstrom 0:f6e68b4ce169 96 m_gps_indicator = true;
Backstrom 0:f6e68b4ce169 97 }
Backstrom 0:f6e68b4ce169 98 else {
Backstrom 0:f6e68b4ce169 99 m_gps_indicator = false;
Backstrom 0:f6e68b4ce169 100 }
Backstrom 0:f6e68b4ce169 101
Backstrom 0:f6e68b4ce169 102 if (m_mode == Short && prefs->prefs.disp_24h) {
Backstrom 0:f6e68b4ce169 103 strftime(buf, 16, " %H.%M.%S ", tm);
Backstrom 0:f6e68b4ce169 104 }
Backstrom 0:f6e68b4ce169 105 else if (m_mode == Short) {
Backstrom 0:f6e68b4ce169 106 strftime(buf, 16, " %I.%M.%S ", tm);
Backstrom 0:f6e68b4ce169 107 }
Backstrom 0:f6e68b4ce169 108 else if (m_mode == Extra && prefs->prefs.disp_24h) {
Backstrom 0:f6e68b4ce169 109 strftime(buf, 16, "%H.%M.%S", tm);
Backstrom 0:f6e68b4ce169 110 }
Backstrom 0:f6e68b4ce169 111 else if (m_mode == Extra) {
Backstrom 0:f6e68b4ce169 112 strftime(buf, 16, "%I.%M.%S", tm);
Backstrom 0:f6e68b4ce169 113 }
Backstrom 0:f6e68b4ce169 114 else if (prefs->prefs.disp_24h) {
Backstrom 0:f6e68b4ce169 115 strftime(buf, 16, "%H-%M-%S", tm);
Backstrom 0:f6e68b4ce169 116 }
Backstrom 0:f6e68b4ce169 117 else {
Backstrom 0:f6e68b4ce169 118 strftime(buf, 16, "%I-%M-%S", tm);
Backstrom 0:f6e68b4ce169 119 }
Backstrom 0:f6e68b4ce169 120
Backstrom 0:f6e68b4ce169 121 if (m_mode == Extra)
Backstrom 0:f6e68b4ce169 122 printf("%s.%d", buf, hundredths-1);
Backstrom 0:f6e68b4ce169 123 else
Backstrom 0:f6e68b4ce169 124 printf(buf);
Backstrom 0:f6e68b4ce169 125 }
Backstrom 0:f6e68b4ce169 126
Backstrom 0:f6e68b4ce169 127 void IV18Display::printTimeLong(struct tm* tm, uint8_t hundredths) {
Backstrom 0:f6e68b4ce169 128 char buf[48];
Backstrom 0:f6e68b4ce169 129
Backstrom 0:f6e68b4ce169 130 if (m_mode == Short || m_mode == Extra) {
Backstrom 0:f6e68b4ce169 131 strftime(buf, 48, " %H%M%S %A %B %d %Y", tm);
Backstrom 0:f6e68b4ce169 132 }
Backstrom 0:f6e68b4ce169 133 else {
Backstrom 0:f6e68b4ce169 134 strftime(buf, 48, "%H-%M-%S %A %B %d %Y", tm);
Backstrom 0:f6e68b4ce169 135 }
Backstrom 0:f6e68b4ce169 136
Backstrom 0:f6e68b4ce169 137 printf(buf);
Backstrom 0:f6e68b4ce169 138 }
Backstrom 0:f6e68b4ce169 139
Backstrom 0:f6e68b4ce169 140 void IV18Display::printTimeSet(struct tm* tm, bool showSeconds) {
Backstrom 0:f6e68b4ce169 141 char buf[16];
Backstrom 0:f6e68b4ce169 142 if (showSeconds) {
Backstrom 0:f6e68b4ce169 143 strftime(buf, 16, "%H-%M-%S", tm);
Backstrom 0:f6e68b4ce169 144 }
Backstrom 0:f6e68b4ce169 145 else {
Backstrom 0:f6e68b4ce169 146 strftime(buf, 16, "AL %H-%M", tm);
Backstrom 0:f6e68b4ce169 147 }
Backstrom 0:f6e68b4ce169 148 printf(buf);
Backstrom 0:f6e68b4ce169 149 }
Backstrom 0:f6e68b4ce169 150
Backstrom 0:f6e68b4ce169 151 void IV18Display::printDate(struct tm* tm) {
Backstrom 0:f6e68b4ce169 152 char buf[16];
Backstrom 0:f6e68b4ce169 153 strftime(buf, 16, "%F", tm);
Backstrom 0:f6e68b4ce169 154 printf(buf);
Backstrom 0:f6e68b4ce169 155 }
Backstrom 0:f6e68b4ce169 156
Backstrom 0:f6e68b4ce169 157 void IV18Display::handleBlink(char d) {
Backstrom 0:f6e68b4ce169 158 // fixme: blink should be handled in virtual function in IV18Display
Backstrom 0:f6e68b4ce169 159 if (m_display_on)
Backstrom 0:f6e68b4ce169 160 writeDisplay(m_multiplex_counter, calculateSegments(d, m_multiplex_counter));
Backstrom 0:f6e68b4ce169 161 else {
Backstrom 0:f6e68b4ce169 162 if (m_blink_mode == Seconds && m_multiplex_counter <= 1) {
Backstrom 0:f6e68b4ce169 163 writeDisplay(m_multiplex_counter, 0);
Backstrom 0:f6e68b4ce169 164 }
Backstrom 0:f6e68b4ce169 165 else if (m_blink_mode == Minutes && m_multiplex_counter >= 3 && m_multiplex_counter <= 4) {
Backstrom 0:f6e68b4ce169 166 writeDisplay(m_multiplex_counter, 0);
Backstrom 0:f6e68b4ce169 167 }
Backstrom 0:f6e68b4ce169 168 else if (m_blink_mode == Hours && m_multiplex_counter >= 6 && m_multiplex_counter <= 7) {
Backstrom 0:f6e68b4ce169 169 writeDisplay(m_multiplex_counter, 0);
Backstrom 0:f6e68b4ce169 170 }
Backstrom 0:f6e68b4ce169 171 else if (m_blink_mode == Full) {
Backstrom 0:f6e68b4ce169 172 writeDisplay(m_multiplex_counter, 0);
Backstrom 0:f6e68b4ce169 173 }
Backstrom 0:f6e68b4ce169 174 else {
Backstrom 0:f6e68b4ce169 175 writeDisplay(m_multiplex_counter, calculateSegments(d, m_multiplex_counter));
Backstrom 0:f6e68b4ce169 176 }
Backstrom 0:f6e68b4ce169 177 }
Backstrom 0:f6e68b4ce169 178 }