diff options
Diffstat (limited to 'app')
-rw-r--r-- | app/max7219.c | 300 |
1 files changed, 154 insertions, 146 deletions
diff --git a/app/max7219.c b/app/max7219.c index 6cd93f3..add2044 100644 --- a/app/max7219.c +++ b/app/max7219.c @@ -9,6 +9,11 @@ #define MOSI (GPIO5) #define MOSI_PORT GPIOB +#define N_DISPLAYS 3 +#define N_DIGITS 8 + +static uint8_t fb[N_DISPLAYS][N_DIGITS]; + static void set (int sck, int ncs, int mosi) @@ -73,54 +78,66 @@ unlock (void) static void write_reg (uint8_t reg, uint8_t data) { + unsigned i; + while (lock()); set (0, 1, 0); set (0, 0, 0); - spip_send_8 (reg); - spip_send_8 (data); - - spip_send_8 (reg); - spip_send_8 (data); - - spip_send_8 (reg); - spip_send_8 (data); + for (i = 0; i < N_DISPLAYS; ++i) { + spip_send_8 (reg); + spip_send_8 (data); + } set (0, 0, 0); set (0, 1, 0); unlock(); } +static void cls (void) +{ + unsigned i; + + for (i = 0; i < N_DISPLAYS; ++i) + memset (&fb[i], 0, N_DIGITS); +} + + + static void -_write_regs (uint8_t reg, uint8_t *data) +refresh (void) { + static uint8_t last_brightness = 255; + unsigned i, j; + + if (last_brightness != pot_brightness) { + last_brightness = pot_brightness; + write_reg (0xa, last_brightness); + } + + while (lock()); - set (0, 1, 0); - set (0, 0, 0); + for (j = 0; j < N_DIGITS; ++j) { + set (0, 1, 0); + set (0, 0, 0); - spip_send_8 (reg); - spip_send_8 (data[2]); + i = N_DISPLAYS - 1; - spip_send_8 (reg); - spip_send_8 (data[1]); + do { + spip_send_8 (N_DIGITS - j); + spip_send_8 (fb[i][j]); + } while (i--); - spip_send_8 (reg); - spip_send_8 (data[0]); + set (0, 0, 0); + set (0, 1, 0); + } - set (0, 0, 0); - set (0, 1, 0); unlock(); } -static void write_regs (uint8_t reg, uint8_t d1, uint8_t d2, uint8_t d3) -{ - uint8_t d[3] = {d1, d2, d3}; - _write_regs (reg, d); -} - #define SDP 0x80 #define SA 0x40 @@ -254,113 +271,49 @@ static uint8_t hex (unsigned v) return 0; } - -static void _write_triad (uint8_t reg, int *d, int *dp) +static void write_dd (int u, unsigned x, unsigned y) { + unsigned t; - uint8_t regs0[3] = {0x0, 0x0, 0x0}; - uint8_t regs1[3] = {0x0, 0x0, 0x0}; - unsigned i; - - for (i = 0; i < 3; ++i) { + if (u < 0) return; - if (d[i] < 0) continue; + if (u > 99) return; - if (d[i] > 99) continue; + t = u / 10; + u %= 10; - regs0[i] = hex (d[i] % 10); - regs1[i] = hex (d[i] / 10); - } - - for (i = 0; i < 3; ++i) - if (dp[i]) regs0[i] |= SDP; - - - _write_regs (reg++, regs0); - _write_regs (reg, regs1); + fb[y][x] = hex (t); + fb[y][x + 1] = hex (u); } -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}; - _write_triad (reg, d, dp); -} -static void _write_triad_h (uint8_t reg, int *d, int *dp) +static void write_string (const char *s, unsigned x, unsigned y) { - uint8_t regs0[3] = {0x0, 0x0, 0x0}; - uint8_t regs1[3] = {0x0, 0x0, 0x0}; - unsigned i; - - for (i = 0; i < 2; ++i) { - - if (d[i] < 0) continue; - if (d[i] > 99) continue; + for (; (x < N_DIGITS) && *s; s++, x++) { + fb[y][x] = hex (*s); - regs0[i] = hex (d[i] % 10); - regs1[i] = hex (d[i] / 10); + if (* (s + 1) == '.') { + fb[y][x] |= SDP; + s++; + } } - - do { - if (d[i] < 0) continue; - - if (d[i] > 0x100) continue; - - regs0[i] = hex (d[i] & 0xf); - regs1[i] = hex (d[i] >> 4); - } while (0); - - for (i = 0; i < 3; ++i) - if (dp[i]) regs0[i] |= SDP; - - - _write_regs (reg++, regs0); - _write_regs (reg, regs1); } -static void write_triad_h (uint8_t reg, int d1, int d2, int d3, int dp1, int dp2, int dp3) +static inline void write_dp (unsigned x, unsigned y) { - int d[3] = {d1, d2, d3}; - int dp[3] = {dp1, dp2, dp3}; - - _write_triad_h (reg, d, dp); + fb[y][x] |= SDP; } -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) { - uint8_t d[3] = {0xf, 0xf, 0xf}; unsigned i; MAP_OUTPUT_PP (SCK); @@ -376,12 +329,11 @@ max7219_init (int on) write_reg (0xf, 0x0); //normal mode write_reg (0x9, 0x0); //no decode - write_reg (0xb, 0x7); //8 digits + write_reg (0xb, N_DIGITS - 1); //8 digits write_reg (0xa, pot_brightness); - for (i = 1; i <= 8; ++i) - _write_regs (i, d); - + for (i = 0; i < N_DIGITS; ++i) + write_reg (N_DIGITS - i, 0x0); } else { write_reg (0xc, 0x0); //Power up @@ -420,72 +372,128 @@ void max7219_report_svin (int valid, int active) } +static const char *day_name[] = {"su", "mo", "tu", "we", "th", "fr", "sa"}; + void max7219_dispatch (void) { uint64_t abs = ref_get(); - static uint8_t last_brightness = 255; + char buf[32]; int wday; EPOCH e; UTC u; UTC gu; ST l; + unsigned i; + uint64_t wot; - if (last_brightness != pot_brightness) { - last_brightness = pot_brightness; - write_reg (0xa, last_brightness); - } + cls(); 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; - + write_string ("gps init", 0, 0); + + else if (!ref_valid) { + write_string ("gps acq.", 0, 0); + write_dd (gps_sats_searching, 0, 1); + write_dp (1, 1); + write_dd (gps_sats_inop, 2, 1); + write_dp (3, 1); + write_dd (gps_sats_locked, 4, 1); + write_dp (5, 1); + write_dd (gps_sats_with_e, 6, 1); + } else { e = ref_decompose (abs); u = time_epoch_to_utc (e); + + write_dd (u.hour, 0, 0); + write_dp (1, 0); + write_dd (u.minute, 2, 0); + write_dp (3, 0); + write_dd (u.second, 4, 0); + write_dp (5, 0); + write_dd (u.nanosecond / 10000000, 6, 0); + + l = time_utc_to_lst (u, gps_lon); - if (have_lock) { + write_dd (l.hour, 0, 1); + write_dp (1, 1); + write_dd (l.minute, 2, 1); + write_dp (3, 1); + write_dd (l.second, 4, 1); + write_dp (5, 1); + write_dd (l.nanosecond / 10000000, 6, 1); + + wot = e.s; + wot /= 4; + wot %= 4; + + switch (wot) { + case 0: + + if (!have_lock) break; + e.s += 86400; e.s += gps_utc_diff; gu = time_epoch_to_utc (e); - } else { - 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_h (7, u.hour, l.hour, (if0.ip_addr.addr >> 24) & 0xff, 1, 1, 1); - if (u.minute == m) return; + wday = gps_wday; + + if (wday < 0) wday = 0; + + if (wday > 6) wday = 6; + + + write_string (day_name[wday], 0, 2); + write_dp (1, 2); + write_dd (gu.hour, 2, 2); + write_dp (3, 2); + write_dd (gu.minute, 4, 2); + write_dp (5, 2); + write_dd (gu.second, 6, 2); + + break; - m = u.minute; + case 1: + if (!have_lock) break; - printf ("LEDS: %02d.%02d.%02d.%02d %02d.%02d.%02d.%02d %02x.%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, - (int) ((if0.ip_addr.addr >> 24) & 0xff), - gu.hour, - gu.minute, - gu.second, - gps_lon); + snprintf (buf, sizeof (buf), "%.8f", gps_lat); + buf[sizeof (buf) - 1] = 0; + write_string (buf, 0, 2); + break; + case 2: + if (!have_lock) break; + + snprintf (buf, sizeof (buf), "%.8f", gps_lon); + buf[sizeof (buf) - 1] = 0; + write_string (buf, 0, 2); + break; + + case 3: + + + for (i = 0; i < 8; ++i) + fb[2][i ^ 1] = hex ((if0.ip_addr.addr >> (i << 2)) & 0xf); + + break; + } } + if (time_lock_enabled) write_dp (7, 0); + if (have_time_lock) write_dp (7, 1); + + if (have_dgps) write_dp (7, 2); + + + refresh(); } + + |