summaryrefslogtreecommitdiffstats
path: root/app
diff options
context:
space:
mode:
Diffstat (limited to 'app')
-rw-r--r--app/max7219.c300
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();
}
+
+