From 8c7ee88332652e7e79f6c1e4baacabe2183f7e8e Mon Sep 17 00:00:00 2001 From: root Date: Tue, 2 Mar 2021 12:54:03 +0000 Subject: working, with hybrid FLL/PLL, new refclk input and support for max7219 displays, neo 5 and neo 7 and a bazillion other fixes --- app/max7219.c | 348 +++++++++++++++++++++++++++++++++++++++++++++------------- 1 file changed, 270 insertions(+), 78 deletions(-) (limited to 'app/max7219.c') 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); + + } + + +} + + -- cgit v1.2.3