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