From 328474f555ab0958e0921c7d04d8d7dbb1789bc4 Mon Sep 17 00:00:00 2001
From: tslil clingman <>
Date: Wed, 29 Sep 2021 14:33:21 -0400
Subject: Init
---
code/src/main.c | 133 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 133 insertions(+)
create mode 100644 code/src/main.c
(limited to 'code/src/main.c')
diff --git a/code/src/main.c b/code/src/main.c
new file mode 100644
index 0000000..de2d35f
--- /dev/null
+++ b/code/src/main.c
@@ -0,0 +1,133 @@
+/*
+ Copyright 2021, tslil clingman
+
+ This program is free software: you can redistribute it and/or modify it under
+ the terms of the GNU General Public License as published by the Free Software
+ Foundation, either version 3 of the License.
+
+ This program is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+ PARTICULAR PURPOSE. See the GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along with
+ this program. If not, see .
+*/
+
+#include
+#include
+#include
+
+#include "TinyI2CMaster.h"
+
+#include "font.h"
+
+#define DISP1_ADDR 0x3C
+#define DISP2_ADDR 0x3D
+#define RTC_ADDR 0x68
+
+// -----------------------------------------------------------------------------
+// SSD1306 driver
+
+#define INIT_LEN 7
+PROGMEM const uint8_t init[INIT_LEN] = {0xAE, // display off
+ 0x8D, // charge pump
+ 0x14,
+ 0xAF, // display on
+ 0x20,
+ 0xA6, // Normal display
+ 0x02 // page address mode
+};
+
+void disp_init(const uint8_t addr, const uint8_t upside_down) {
+ i2c_start(addr,0);
+ i2c_write(0x00);
+ for (uint8_t k = 0; k>=2)
+ for (uint8_t l=0; l<4; l++)
+ i2c_write(((b&1)?0xF0:0x00)|
+ ((b&2)?0x0F:0x00));
+ }
+ }
+}
+
+// -----------------------------------------------------------------------------
+// Interface
+
+uint8_t bcd_to_dec(uint8_t k) { return (((k)/16)*10) + ((k)%16); }
+
+uint8_t dec_to_bcd(uint8_t k) { return (((k)/10)*16) + ((k)%10); }
+
+int main(void) {
+ // Init screens
+ i2c_init();
+ disp_init(DISP1_ADDR,1);
+ disp_init(DISP2_ADDR,0);
+ // Setup input pullups
+ DDRA = ~(_BV(DDA0) | _BV(DDA1));
+ PORTA = _BV(DDA0) | _BV(DDA1);
+ // Tracking state
+ uint8_t input = 0, hours = 99, minutes = 99;
+ while(1) {
+ // Increase hours?
+ if (!(PINA&_BV(DDA0))) {
+ if ((hours+=1)>23) hours=0;
+ input = 1;
+ }
+ // Increase minutes?
+ if (!(PINA&_BV(DDA1))) {
+ if ((minutes+=1)>59) minutes=0;
+ input = 1;
+ }
+ // Store changes
+ if (input) {
+ input = 0;
+ i2c_start(RTC_ADDR,0);
+ i2c_write(0);
+ i2c_write(0); // Seconds
+ i2c_write(dec_to_bcd(minutes));
+ i2c_write(dec_to_bcd(hours));
+ i2c_stop();
+ }
+ // Draw minutes
+ disp_draw_digit(DISP1_ADDR, (minutes/10)%10, 0);
+ disp_draw_digit(DISP1_ADDR, (minutes%10), 4);
+ // Draw hours
+ disp_draw_digit(DISP2_ADDR, (hours/10)%10, 0);
+ disp_draw_digit(DISP2_ADDR, (hours%10), 4);
+ // Poll for update
+ i2c_start(RTC_ADDR,0);
+ i2c_write(1);
+ i2c_start(RTC_ADDR,2);
+ minutes = bcd_to_dec(i2c_read());
+ hours = bcd_to_dec(i2c_read());
+ i2c_stop();
+ // Delay
+ _delay_ms(100);
+ }
+ return 0;
+}
--
cgit v1.3.1