summaryrefslogtreecommitdiffstats
path: root/app/max7219.c
diff options
context:
space:
mode:
Diffstat (limited to 'app/max7219.c')
-rw-r--r--app/max7219.c348
1 files changed, 270 insertions, 78 deletions
diff --git a/app/max7219.c b/app/max7219.c
index 85e66a7..7d5858e 100644
--- a/app/max7219.c
+++ b/app/max7219.c
@@ -94,7 +94,7 @@ write_reg (uint8_t reg, uint8_t data)
static void
-write_regs (uint8_t reg, uint8_t data1, uint8_t data2, uint8_t data3)
+_write_regs (uint8_t reg, uint8_t *data)
{
while (lock());
@@ -102,134 +102,224 @@ write_regs (uint8_t reg, uint8_t data1, uint8_t data2, uint8_t data3)
set (0, 0, 0);
spip_send_8 (reg);
- spip_send_8 (data3);
+ spip_send_8 (data[2]);
spip_send_8 (reg);
- spip_send_8 (data2);
+ spip_send_8 (data[1]);
spip_send_8 (reg);
- spip_send_8 (data1);
+ spip_send_8 (data[0]);
set (0, 0, 0);
set (0, 1, 0);
unlock();
}
-static void write_triad (uint8_t reg, int d1, int d2, int d3, unsigned dm)
+static void write_regs (uint8_t reg, uint8_t d1, uint8_t d2, uint8_t d3)
{
- write_regs (reg++, (d1 % 10) | ((dm & 0x1) ? 0x80 : 0), (d2 % 10) | ((dm & 0x4) ? 0x80 : 0), (d3 % 10) | ((dm & 0x10) ? 0x80 : 0));
- write_regs (reg, (d1 / 10) | ((dm & 0x2) ? 0x80 : 0), (d2 / 10) | ((dm & 0x8) ? 0x80 : 0), (d3 / 10) | ((dm & 0x20) ? 0x80 : 0));
+ uint8_t d[3] = {d1, d2, d3};
+ _write_regs (reg, d);
}
-#if 0
-static void st_test (void)
+#define SDP 0x80
+#define SA 0x40
+#define SB 0x20
+#define SC 0x10
+#define SD 0x08
+#define SE 0x04
+#define SF 0x02
+#define SG 0x01
+
+static uint8_t hex (unsigned v)
{
+ switch (v) {
+ case 0:
+ case '0':
+ return SA | SF | SB | SE | SC | SD;
- UTC u = { 0 };
- double local_lon = 0.0;
- ST st;
- double ra;
+ case 1:
+ case '1':
+ return SB | SC;
- // LEDS: 12.13.28.00 01.01.29.05 13.27.42.05
+ case 2:
+ case '2':
+ case 'z':
+ return SA | SB | SG | SE | SD;
- u.year = 2021;
- u.month = 1;
- u.mday = 12;
- u.hour = 13;
- u.minute = 28;
+ case 3:
+ case '3':
+ return SA | SB | SG | SC | SD;
- ra = time_utc_to_ra (u);
- st = time_ra_to_st (ra + local_lon);
+ case 4:
+ case '4':
+ return SF | SG | SB | SC;
- printf ("%d:%02d:%02d\n", st.hour, st.minute, st.second);
+ case 5:
+ case '5':
+ case 's':
+ return SA | SF | SG | SC | SD;
- st = time_utc_to_lst (u, local_lon);
+ case 6:
+ case '6':
+ return SA | SF | SG | SE | SC | SD;
- printf ("%d:%02d:%02d\n", st.hour, st.minute, st.second);
+ case 7:
+ case '7':
+ return SA | SB | SC;
- for (;;);
-}
-#endif
+ case 8:
+ case '8':
+ return SA | SF | SB | SG | SE | SC | SD;
+ case 9:
+ case '9':
+ case 'g':
+ return SA | SF | SB | SG | SC | SD;
-unsigned fix_dots, fix_dots_even;
+ case 0xa:
+ case 'a':
+ return SA | SF | SB | SG | SE | SC;
-void max7219_report_fix (char fix, char fix2)
-{
- fix_dots = 0;
+ case 0xb:
+ case 'b':
+ return SF | SG | SE | SC | SD;
+ case 0xc:
+ case 'c':
+ return SG | SE | SD;
- if (fix == 'L')
- fix_dots |= 0x1;
+ case 0xd:
+ case 'd':
+ return SB | SG | SE | SC | SD;
- if (fix2 == 'D') fix_dots |= 0x4;
+ case 0xe:
+ case 'e':
+ return SA | SF | SG | SE | SD;
- if (fix == 'T') fix_dots |= 0x11;
-}
+ case 0xf:
+ case 'f':
+ return SA | SF | SG | SE;
-void max7219_report_svin (int valid, int active)
-{
- fix_dots_even = 0;
+ case 'h':
+ return SF | SG | SE | SC;
+
+ case 'i':
+ return SE;
+
+ case 'j':
+ return SB | SC | SD;
+
+ case 'k':
+ case 'x':
+ return SF | SB | SG | SE | SC;
+
+ case 'l':
+ return SF | SE | SD;
+
+ case 'm':
+ case 'n':
+ return SG | SE | SC;
+
+ case 'o':
+ return SG | SE | SC | SD;
+
+ case 'p':
+ return SA | SF | SB | SG | SE;
+
+ case 'q':
+ return SA | SF | SB | SG | SC;
+
+ case 'r':
+ return SG | SE;
+
+ case 't':
+ return SF | SG | SE | SD;
+
+ case 'u':
+ case 'w':
+ return SE | SC | SD;
+
+ case 'y':
+ return SF | SB | SG | SC | SD;
- if (active || valid) fix_dots_even |= 0x10;
+ case '-':
+ return SG;
+
+ case '.':
+ return SDP;
+
+ }
+
+ return 0;
}
-void max7219_dispatch (void)
+static void _write_triad (uint8_t reg, int *d, int *dp)
{
- uint32_t now = HW_CLOCK_REG;
- uint64_t abs = abs_extend (now);
- static unsigned m;
- EPOCH e;
- UTC u;
- UTC gu;
- ST l;
- unsigned last_dots;
+ uint8_t regs0[3] = {0x0, 0x0, 0x0};
+ uint8_t regs1[3] = {0x0, 0x0, 0x0};
+ unsigned i;
+ for (i = 0; i < 3; ++i) {
- e = pll_decompose (abs);
- u = time_epoch_to_utc (e);
- l = time_utc_to_lst (u, gps_lon);
+ if (d[i] < 0) continue;
- e.s += gps_utc_diff;
- gu = time_epoch_to_utc (e);
+ if (d[i] > 99) continue;
- last_dots = fix_dots;
+ regs0[i] = hex (d[i] % 10);
+ regs1[i] = hex (d[i] / 10);
+ }
- if (u.nanosecond < 500000000) last_dots |= fix_dots_even;
+ for (i = 0; i < 3; ++i)
+ if (dp[i]) regs0[i] |= SDP;
- write_triad (1, u.nanosecond / 10000000, l.nanosecond / 10000000, gu.second, last_dots);
- write_triad (3, u.second, l.second, gu.minute, 0x15);
- write_triad (5, u.minute, l.minute, gu.hour, 0x15);
- write_triad (7, u.hour, l.hour, gps_wday, 0x15);
+ _write_regs (reg++, regs0);
+ _write_regs (reg, regs1);
+}
- if (u.minute == m) return;
+static void write_triad (uint8_t reg, int d1, int d2, int d3, int dp1, int dp2, int dp3)
+{
+ int d[3] = {d1, d2, d3};
+ int dp[3] = {dp1, dp2, dp3};
- m = u.minute;
+ _write_triad (reg, d, dp);
+}
- printf ("LEDS: %02d.%02d.%02d.%02d %02d.%02d.%02d.%02d %02d.%02d.%02d.%02d lon %.6f\r\n",
- u.hour, u.minute, u.second,
- u.nanosecond / 10000000,
- l.hour,
- l.minute,
- l.second,
- l.nanosecond / 10000000,
- gps_wday,
- gu.hour,
- gu.minute,
- gu.second,
- gps_lon);
+static void write_string_over_numbers (char *str, int d1, int d2, int d3, int d4)
+{
+ unsigned reg;
+
+ uint8_t digits[9] = {
+ 0,
+ hex (d4 % 10),
+ hex (d4 / 10),
+ hex (d3 % 10) | SDP,
+ hex (d3 / 10),
+ hex (d2 % 10) | SDP,
+ hex (d2 / 10),
+ hex (d1 % 10) | SDP,
+ hex (d1 / 10)
+ };
+
+ for (reg = 8; reg && *str; reg--, str++)
+ write_regs (reg, hex (*str) | (!str[1] ? SDP : 0), digits[reg], 0);
+
+ for (; reg; reg--)
+ write_regs (reg, 0, digits[reg], 0);
+}
-}
void
-max7219_init (int on, int brightness)
+max7219_init (int on)
{
+ uint8_t d[3] = {0xf, 0xf, 0xf};
+ unsigned i;
+
MAP_OUTPUT_PP (SCK);
MAP_OUTPUT_PP (NCS);
MAP_OUTPUT_PP (MOSI);
@@ -242,17 +332,119 @@ max7219_init (int on, int brightness)
write_reg (0xc, 0x1); //Power up
write_reg (0xf, 0x0); //normal mode
- write_reg (0x9, 0xff); //BCD decode
+ write_reg (0x9, 0x0); //no decode
write_reg (0xb, 0x7); //8 digits
- write_regs (0xa, brightness, brightness, brightness);
+ write_reg (0xa, pot_brightness);
+
+ for (i = 1; i <= 8; ++i)
+ _write_regs (i, d);
+
+
} else {
write_reg (0xc, 0x0); //Power up
}
+}
+
+
+
+static int have_lock, have_dgps, have_time_lock, time_lock_enabled;
+
+void max7219_report_fix (char fix, char fix2)
+{
+
+ have_lock = 0;
+
+ if (fix == 'L')
+ have_lock = 1;
+
+ if (fix2 == 'D') have_dgps = 1;
+ else have_dgps = 0;
+
+ if (fix == 'T') {
+ have_lock = 1;
+ have_time_lock = 1;
+ }
+}
+
+void max7219_report_svin (int valid, int active)
+{
+ time_lock_enabled = 0;
+
+ if (active || valid) time_lock_enabled = 1;
}
+void max7219_dispatch (void)
+{
+ uint64_t abs = ref_get();
+ static uint8_t last_brightness = 255;
+ int wday;
+ EPOCH e;
+ UTC u;
+ UTC gu;
+ ST l;
+
+
+
+ if (last_brightness != pot_brightness) {
+ last_brightness = pot_brightness;
+ write_reg (0xa, last_brightness);
+ }
+
+ if (gps_initting)
+ write_string_over_numbers ("gps init", 0, 0, 0, 0);
+ else if (!ref_valid)
+ write_string_over_numbers ("gps acq", gps_sats_searching, gps_sats_inop, gps_sats_locked, gps_sats_with_e);
+
+ else {
+ static unsigned m;
+
+ e = ref_decompose (abs);
+ u = time_epoch_to_utc (e);
+ l = time_utc_to_lst (u, gps_lon);
+
+ if (have_lock) {
+ e.s += 86400;
+ e.s += gps_utc_diff;
+ gu = time_epoch_to_utc (e);
+ wday = gps_wday;
+ } else {
+ wday = 100;
+ gu.hour = 100;
+ gu.minute = 100;
+ gu.second = 100;
+ }
+
+ write_triad (1, u.nanosecond / 10000000, l.nanosecond / 10000000, gu.second, time_lock_enabled, have_time_lock, have_dgps);
+ write_triad (3, u.second, l.second, gu.minute, 1, 1, 1);
+ write_triad (5, u.minute, l.minute, gu.hour, 1, 1, 1);
+ write_triad (7, u.hour, l.hour, wday, 1, 1, 1);
+
+ if (u.minute == m) return;
+
+ m = u.minute;
+
+ printf ("LEDS: %02d.%02d.%02d.%02d %02d.%02d.%02d.%02d %02d.%02d.%02d.%02d lon %.6f\r\n",
+ u.hour, u.minute, u.second,
+ u.nanosecond / 10000000,
+ l.hour,
+ l.minute,
+ l.second,
+ l.nanosecond / 10000000,
+ gps_wday,
+ gu.hour,
+ gu.minute,
+ gu.second,
+ gps_lon);
+
+ }
+
+
+}
+
+