#include "project.h" #define NCS (GPIO7) #define NCS_PORT GPIOG #define SCK (GPIO3) #define SCK_PORT GPIOB #define MOSI (GPIO5) #define MOSI_PORT GPIOB static void set (int sck, int ncs, int mosi) { if (sck) SET (SCK); else CLEAR (SCK); if (ncs) SET (NCS); else CLEAR (NCS); if (mosi) SET (MOSI); else CLEAR (MOSI); // delay_us(1); //delay_us(10); } static void spip_send_8 (uint8_t wot) { int i; for (i = 0; i < 8; ++i) { set (0, 0, wot & 0x80); set (1, 0, wot & 0x80); set (0, 0, wot & 0x80); wot <<= 1; } } static int mutex = 0; static int lock (void) { if (__sync_add_and_fetch (&mutex, 1) != 1) { __sync_sub_and_fetch (&mutex, 1); return -1; } return 0; } static void unlock (void) { __sync_sub_and_fetch (&mutex, 1); } static void write_reg (uint8_t reg, uint8_t data) { 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); set (0, 0, 0); set (0, 1, 0); unlock(); } static void write_regs (uint8_t reg, uint8_t data1, uint8_t data2, uint8_t data3) { while (lock()); set (0, 1, 0); set (0, 0, 0); spip_send_8 (reg); spip_send_8 (data3); spip_send_8 (reg); spip_send_8 (data2); spip_send_8 (reg); spip_send_8 (data1); set (0, 0, 0); set (0, 1, 0); unlock(); } static void write_triad (uint8_t reg, int d1, int d2, int d3, unsigned dm) { 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)); } #if 0 static void st_test (void) { UTC u = { 0 }; double local_lon = 0.0; ST st; double ra; // LEDS: 12.13.28.00 01.01.29.05 13.27.42.05 u.year = 2021; u.month = 1; u.mday = 12; u.hour = 13; u.minute = 28; ra = time_utc_to_ra (u); st = time_ra_to_st (ra + local_lon); printf ("%d:%02d:%02d\n", st.hour, st.minute, st.second); st = time_utc_to_lst (u, local_lon); printf ("%d:%02d:%02d\n", st.hour, st.minute, st.second); for (;;); } #endif unsigned fix_dots, fix_dots_even; void max7219_report_fix (char fix, char fix2) { fix_dots = 0; if (fix == 'L') fix_dots |= 0x1; if (fix2 == 'D') fix_dots |= 0x4; if (fix == 'T') fix_dots |= 0x11; } void max7219_report_svin (int valid, int active) { fix_dots_even = 0; if (active || valid) fix_dots_even |= 0x10; } void max7219_dispatch (void) { 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; e = pll_decompose (abs); u = time_epoch_to_utc (e); l = time_utc_to_lst (u, gps_lon); e.s += gps_utc_diff; gu = time_epoch_to_utc (e); last_dots = fix_dots; if (u.nanosecond < 500000000) last_dots |= fix_dots_even; 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); 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); } void max7219_init (int on, int brightness) { MAP_OUTPUT_PP (SCK); MAP_OUTPUT_PP (NCS); MAP_OUTPUT_PP (MOSI); set (0, 1, 0); if (on) { write_reg (0xc, 0x1); //Power up write_reg (0xf, 0x0); //normal mode write_reg (0x9, 0xff); //BCD decode write_reg (0xb, 0x7); //8 digits write_regs (0xa, brightness, brightness, brightness); } else { write_reg (0xc, 0x0); //Power up } }