diff options
Diffstat (limited to 'app/max7219.c')
-rw-r--r-- | app/max7219.c | 143 |
1 files changed, 143 insertions, 0 deletions
diff --git a/app/max7219.c b/app/max7219.c new file mode 100644 index 0000000..fbba10d --- /dev/null +++ b/app/max7219.c @@ -0,0 +1,143 @@ +#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(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); + + set (0, 0, 0); + set (0, 1, 0); + unlock(); +} + +static void write_pair (uint8_t reg, int d) +{ + write_reg (reg, d / 10); + write_reg (reg - 1, (d % 10) | 0x80); +} + +void max7219_write (int d, int h, int m, int s) +{ + + write_pair (8, d); + write_pair (6, h); + write_pair (4, m); + write_pair (2, s); + +} + +void max7219_dispatch (void) +{ + uint32_t now = SCS_DWT_CYCCNT; + uint64_t abs = abs_extend (now); + EPOCH e = pll_decompose (abs); + UTC u = time_epoch_to_utc (e); + + + max7219_write (u.mday, u.hour, u.minute, u.second); +} + +void +max7219_init (int on) +{ + 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_reg (0xa, 0x8); //intensity + } else { + write_reg (0xc, 0x0); //Power up + } + + + +} + + + + |