summaryrefslogtreecommitdiff
path: root/main.c
diff options
context:
space:
mode:
Diffstat (limited to 'main.c')
-rw-r--r--main.c266
1 files changed, 240 insertions, 26 deletions
diff --git a/main.c b/main.c
index f130906..cd9666a 100644
--- a/main.c
+++ b/main.c
@@ -1,46 +1,260 @@
#include "main.h"
-#include "max7219.h"
#include "clock.h"
#include "timebase.h"
#include "dcf77.h"
+#include "lcd.h"
+#include <avr/sleep.h>
+#include <avr/eeprom.h>
+#include <util/delay.h>
+
+#ifdef WHOPR
+#include "clock.c"
+#include "timebase.c"
+#include "dcf77.c"
+#include "lcd.c"
+#endif
+
+#define B_SW_BACK PINB5
+#define B_SW_FRWD PINB6
+
+#define A_OCPL_A PA5
+#define A_OCPL_B PA6
+
+#define EE_HOUR 0
+#define EE_MINUTE 1
+#define EE_CKSUM 2
+#define EE_BOOTC 4
+
+static uint8_t ext_hour, ext_minute;
+static uint16_t bootcount;
+
+#define WAIT 64
+uint8_t waitctr = 0;
+enum stepstate {
+ STEP_INACTIVE = 0,
+ STEP_ACTIVE,
+} stepstate = STEP_INACTIVE;
+
+const char PROGMEM disp[2] = {'_', '+'};
+const char PROGMEM status[24] = "normalsync adj + adj - ";
+const char PROGMEM cksumfail[] = "cksum fail";
+
+static void puttwo(uint8_t arg)
+{
+ uint8_t b = '0', a = '0' + arg;
+ while (a > '9')
+ b++, a -= 10;
+ lcd_put(b);
+ lcd_put(a);
+}
+
+static void puttime(void)
+{
+ const char * PROGMEM msg;
+
+ lcd_line1();
+ puttwo(time.year);
+ puttwo(time.month);
+ puttwo(time.day);
+ lcd_put(' ');
+ puttwo(time.hour);
+ puttwo(time.minute);
+ puttwo(time.second);
+
+ lcd_line2();
+ msg = &status[0];
+ if (time.year <= 10)
+ msg = &status[6];
+ if (~PINB & (1 << B_SW_FRWD))
+ msg = &status[12];
+ if (~PINB & (1 << B_SW_BACK))
+ msg = &status[18];
+
+ lcd_puts(msg, 6);
+ lcd_put(__LPM(&disp[stepstate]));
+ puttwo(ext_hour);
+ puttwo(ext_minute);
+ lcd_put(' ');
+ puttwo(bootcount / 100);
+ puttwo(bootcount % 100);
+}
+
+static uint8_t setaccel;
+
+static void countfwd(void)
+{
+ cli();
+ ext_minute++;
+ if (ext_minute == 60) {
+ ext_minute = 0;
+ ext_hour++;
+ if (ext_hour == 12)
+ ext_hour = 0;
+ }
+ sei();
+}
+
+static void step_set(void)
+{
+ if (ext_minute & 1) {
+ PORTA &= ~(1 << A_OCPL_A);
+ } else {
+ PORTA &= ~(1 << A_OCPL_B);
+ }
+}
+
+static void step_end(void)
+{
+ PORTA |= (1 << A_OCPL_A);
+ PORTA |= (1 << A_OCPL_B);
+}
+
+static void perform(void)
+{
+ if (waitctr)
+ return;
+
+ step_end();
+
+ if (~PINB & (1 << B_SW_BACK)) {
+ waitctr = setaccel;
+ if (setaccel > 3)
+ setaccel--;
+ cli();
+ if (ext_minute)
+ ext_minute--;
+ else {
+ ext_minute = 59;
+ if (ext_hour)
+ ext_hour--;
+ else
+ ext_hour = 11;
+ }
+ sei();
+ return;
+ }
+ if (~PINB & (1 << B_SW_FRWD)) {
+ waitctr = setaccel;
+ if (setaccel > 3)
+ setaccel--;
+ countfwd();
+ return;
+ }
+ setaccel = WAIT;
+
+ if (time.year <= 10)
+ return;
+
+ PORTA &= ~(1 << PA2);
+
+ uint8_t hbuf, mbuf, hdelta;
+
+ cli();
+ hbuf = time.hour;
+ mbuf = time.minute;
+ sei();
+
+ if (hbuf >= 12)
+ hbuf -= 12;
+
+ switch (stepstate) {
+ case STEP_INACTIVE:
+ if (hbuf == ext_hour && mbuf <= ext_minute)
+ break;
+ hdelta = 11 + ext_hour - hbuf;
+ while (hdelta >= 12)
+ hdelta -=12;
+ if (hdelta < 3)
+ break;
+ countfwd();
+
+ step_set();
+ stepstate = STEP_ACTIVE;
+ waitctr = WAIT;
+ break;
+ case STEP_ACTIVE:
+ stepstate = STEP_INACTIVE;
+ waitctr = WAIT;
+ break;
+ }
+}
+
+extern void __vectors(void) __attribute__((noreturn));
+__attribute__ ((noreturn))
+SIGNAL (SIG_ANA_COMP)
+{
+ PORTA = 0xff;
+
+ eeprom_write_byte((void *)EE_HOUR, ext_hour);
+ eeprom_write_byte((void *)EE_MINUTE, ext_minute);
+ eeprom_write_byte((void *)EE_CKSUM, ext_hour ^ ext_minute ^ 0xff);
+
+ do
+ _delay_ms(100);
+ while (ACSR & (1 << ACO));
+ __vectors();
+}
int main( void )
{
+
PORTA = 0xFF; // enable pull ups
PORTB = 0xFF;
- DDRA |= 1<<PA4;
- display_init();
- display_off();
+ DDRA |= (1 << PA4) | (1 << PA3) | (1 << PA2) | (1 << A_OCPL_A) | (1 << A_OCPL_B);
+
+ MCUCR = 0;
+ ACSR = (1 << ACBG) | (1 << ACIS1) | (1 << ACIS0) | (1 << ACIE);
+ _delay_ms(1);
+ ACSR |= (1 << ACI);
+
timebase_init();
+ lcd_init();
+
+ ext_hour = eeprom_read_byte((void *)EE_HOUR);
+ ext_minute = eeprom_read_byte((void *)EE_MINUTE);
+ uint8_t ec = eeprom_read_byte((void *)EE_CKSUM);
+
+ if ((ec ^ ext_hour ^ ext_minute) != 0xff) {
+ lcd_puts(cksumfail, sizeof(cksumfail) - 1);
+ while (1)
+ ;
+ }
+
+ bootcount = eeprom_read_word((void *)EE_BOOTC);
+ eeprom_write_word((void *)EE_BOOTC, ++bootcount);
+
+ /* last pulse may not have been long enough */
+ step_set();
+ _delay_ms(1000);
+ step_end();
+
sei();
+
for(;;){
+ bool do_puttime = false;
+
scan_dcf77();
#if 1
if( DCF77_PIN & 1<<DCF77 )
- PORTA |= 1<< PA4;
+ PORTA |= 1<< PA3;
else
- PORTA &= ~(1<<PA4);
+ PORTA &= ~(1<<PA3);
#endif
- if( timeflags & 1<<ONE_SECOND ){
- timeflags = 0;
- clock();
- if( synchronize == 0 )
- continue;
- if( synchronize == 1 && time.hour == 3 ){
- if( time.minute == 20 )
- display_off();
- if( time.minute == 28 )
- synchronize = 2;
- continue;
- }
- if( time.hour == 4 )
- synchronize = 1;
-
- DDRA &= ~(1<<PA4);
- display_clear();
- display_time();
- display_out();
- }
+ if( timeflags & 1<<ONE_SECOND ){
+ timeflags = 0;
+ clock();
+ do_puttime = true;
+ }
+
+ if (!waitctr) {
+ perform();
+ do_puttime = true;
+ }
+
+ if (do_puttime)
+ puttime();
+/* sleep_enable();
+ sleep_cpu(); */
}
}