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