Compare commits
16 Commits
WorkingBef
...
master
Author | SHA1 | Date | |
---|---|---|---|
![]() |
ee4e7b7c5d | ||
![]() |
5f7c7fbe41 | ||
![]() |
cea727198a | ||
![]() |
16f109fb80 | ||
![]() |
07febefc74 | ||
![]() |
d33d8ffe4a | ||
![]() |
7fa9715d41 | ||
![]() |
d997d21ac1 | ||
![]() |
fb4b9675ce | ||
![]() |
cfbf2d9424 | ||
![]() |
00638e3edc | ||
![]() |
7654302a94 | ||
![]() |
ea178ca5c4 | ||
![]() |
b99473f1f2 | ||
![]() |
314c6eba8d | ||
![]() |
6970336f53 |
1
.hgtags
Normal file
1
.hgtags
Normal file
@ -0,0 +1 @@
|
|||||||
|
2716b70f46c080a1b9d189c5a4d649c661cad949 WorkingBeforeRefactoring
|
BIN
resources/DCFzzeit.pdf
Normal file
BIN
resources/DCFzzeit.pdf
Normal file
Binary file not shown.
3227
resources/Zifferblatt.graffle
Normal file
3227
resources/Zifferblatt.graffle
Normal file
File diff suppressed because it is too large
Load Diff
169
src/clock.c
Normal file
169
src/clock.c
Normal file
@ -0,0 +1,169 @@
|
|||||||
|
#include <stdint.h>
|
||||||
|
#include <avr/io.h>
|
||||||
|
#include <avr/interrupt.h>
|
||||||
|
|
||||||
|
#include "clock.h"
|
||||||
|
|
||||||
|
|
||||||
|
volatile clock_t clock;
|
||||||
|
volatile opTime_t opTime;
|
||||||
|
|
||||||
|
volatile uint8_t useLocalClock = 1;
|
||||||
|
|
||||||
|
volatile uint8_t nextSecond = 0;
|
||||||
|
volatile uint8_t nextMinute = 0;
|
||||||
|
volatile uint8_t tack = 0;
|
||||||
|
volatile uint8_t step = 0;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void clockInit() {
|
||||||
|
clock.hour = 0;
|
||||||
|
clock.minute = 0;
|
||||||
|
clock.second = 0;
|
||||||
|
|
||||||
|
opTime.day = 0;
|
||||||
|
opTime.hour = 0;
|
||||||
|
opTime.minute = 0;
|
||||||
|
opTime.second = 0;
|
||||||
|
|
||||||
|
// seconds
|
||||||
|
TCCR2 = 0b00000101;
|
||||||
|
ASSR |= (1 << AS2);
|
||||||
|
TIMSK |= (1 << TOIE2) | (1 << TICIE1);
|
||||||
|
|
||||||
|
// heartbeat
|
||||||
|
TCCR0 = (1 << CS02) | (1 << CS00);
|
||||||
|
TIMSK |= (1 << TOIE0);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
ISR(TIMER2_OVF_vect) {
|
||||||
|
clock.second++;
|
||||||
|
|
||||||
|
if (useLocalClock == 1) {
|
||||||
|
if (clock.second >= 60) {
|
||||||
|
clock.minute++;
|
||||||
|
}
|
||||||
|
if (clock.minute >= 60) {
|
||||||
|
clock.minute = 0;
|
||||||
|
clock.hour++;
|
||||||
|
}
|
||||||
|
if (clock.hour >= 24) {
|
||||||
|
clock.hour = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (clock.second >= 60) {
|
||||||
|
clock.second = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
opTime.second++;
|
||||||
|
nextSecond = 1;
|
||||||
|
|
||||||
|
if (opTime.second >= 60) {
|
||||||
|
opTime.second = 0;
|
||||||
|
opTime.minute++;
|
||||||
|
|
||||||
|
nextMinute = 1;
|
||||||
|
}
|
||||||
|
if (opTime.minute >= 60) {
|
||||||
|
opTime.minute = 0;
|
||||||
|
opTime.hour++;
|
||||||
|
}
|
||||||
|
if (opTime.hour >= 24) {
|
||||||
|
opTime.hour = 0;
|
||||||
|
opTime.day++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ISR(TIMER0_OVF_vect) {
|
||||||
|
static uint8_t subDivTack = 0;
|
||||||
|
subDivTack++;
|
||||||
|
if (subDivTack >= SUB_DIV_LED) {
|
||||||
|
subDivTack = 0;
|
||||||
|
tack = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static uint8_t subDivStepper = 0;
|
||||||
|
subDivStepper++;
|
||||||
|
if (subDivStepper >= SUB_DIV_STEPPER) {
|
||||||
|
subDivStepper = 0;
|
||||||
|
step = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
opTime_t clockGetOpTime() {
|
||||||
|
return opTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
void clockSetUseLocalClock(uint8_t x) {
|
||||||
|
useLocalClock = x;
|
||||||
|
}
|
||||||
|
|
||||||
|
void clockSetClock(uint8_t year, uint8_t month, uint8_t day, uint8_t weekday, uint8_t hour, uint8_t minute) {
|
||||||
|
cli();
|
||||||
|
clock.year = year;
|
||||||
|
clock.month = month;
|
||||||
|
clock.day = day;
|
||||||
|
clock.weekday = weekday;
|
||||||
|
clock.hour = hour;
|
||||||
|
clock.minute = minute;
|
||||||
|
sei();
|
||||||
|
}
|
||||||
|
|
||||||
|
void clockClearSecond() {
|
||||||
|
cli();
|
||||||
|
clock.second = 0;
|
||||||
|
sei();
|
||||||
|
}
|
||||||
|
|
||||||
|
clock_t clockGetClock() {
|
||||||
|
cli();
|
||||||
|
clock_t c = clock;
|
||||||
|
sei();
|
||||||
|
return c;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t clockNextSecond() {
|
||||||
|
if (nextSecond != 0) {
|
||||||
|
nextSecond = 0;
|
||||||
|
return 1;
|
||||||
|
} else {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t clockNextMinute() {
|
||||||
|
if (nextMinute != 0) {
|
||||||
|
nextMinute = 0;
|
||||||
|
return 1;
|
||||||
|
} else {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
uint8_t clockNextStep() {
|
||||||
|
if (step != 0) {
|
||||||
|
step = 0;
|
||||||
|
return 1;
|
||||||
|
} else {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t clockNextBlink() {
|
||||||
|
if (tack != 0) {
|
||||||
|
tack = 0;
|
||||||
|
return 1;
|
||||||
|
} else {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
44
src/clock.h
Normal file
44
src/clock.h
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
#ifndef CLOCK_H_
|
||||||
|
#define CLOCK_H_
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
|
||||||
|
#define SUB_DIV_LED 30
|
||||||
|
#define SUB_DIV_STEPPER 7
|
||||||
|
|
||||||
|
|
||||||
|
typedef struct clock_s {
|
||||||
|
uint8_t hour;
|
||||||
|
uint8_t minute;
|
||||||
|
uint8_t second;
|
||||||
|
uint8_t day;
|
||||||
|
uint8_t weekday;
|
||||||
|
uint8_t month;
|
||||||
|
uint8_t year;
|
||||||
|
} clock_t;
|
||||||
|
|
||||||
|
typedef struct opTime_s {
|
||||||
|
uint8_t second;
|
||||||
|
uint8_t minute;
|
||||||
|
uint8_t hour;
|
||||||
|
uint16_t day;
|
||||||
|
} opTime_t;
|
||||||
|
|
||||||
|
|
||||||
|
void clockInit();
|
||||||
|
|
||||||
|
uint8_t clockNextStep();
|
||||||
|
uint8_t clockNextBlink();
|
||||||
|
uint8_t clockNextSecond();
|
||||||
|
uint8_t clockNextMinute();
|
||||||
|
|
||||||
|
void clockSetUseLocalClock(uint8_t x);
|
||||||
|
void clockClearSecond();
|
||||||
|
void clockSetClock(uint8_t year, uint8_t month, uint8_t day, uint8_t weekday, uint8_t hour, uint8_t minute);
|
||||||
|
clock_t clockGetClock();
|
||||||
|
opTime_t clockGetOpTime();
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#endif /* CLOCK_H_ */
|
401
src/dcf77.c
Normal file
401
src/dcf77.c
Normal file
@ -0,0 +1,401 @@
|
|||||||
|
#include <stdint.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <avr/io.h>
|
||||||
|
#include <avr/interrupt.h>
|
||||||
|
|
||||||
|
#include "clock.h"
|
||||||
|
#include "validLed.h"
|
||||||
|
#include "stepper.h"
|
||||||
|
#include "dcf77.h"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void dcf77Init() {
|
||||||
|
// signal measurment
|
||||||
|
TCCR1A = 0;
|
||||||
|
TCCR1B = (1 << CS12) | (1 << CS10);
|
||||||
|
|
||||||
|
DDRD &= ~(1 << PD2);
|
||||||
|
DDRD &= ~(1 << PD3);
|
||||||
|
PORTD |= (1 << PD2) | (1 << PD3);
|
||||||
|
MCUCR |= (1 << ISC11) | (1 << ISC10) | (1 << ISC01);
|
||||||
|
GICR |= (1 << INT0) | (1 << INT1);
|
||||||
|
|
||||||
|
dcf77SetValid(0);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
volatile uint8_t tick;
|
||||||
|
volatile uint16_t captValue = 0;
|
||||||
|
volatile uint16_t gapValue = 0;
|
||||||
|
volatile uint8_t valid = 0;
|
||||||
|
uint32_t validCnt = 0;
|
||||||
|
uint32_t timeValidCnt = 0;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
ISR(INT0_vect) {
|
||||||
|
uint16_t tmpCnt = TCNT1;
|
||||||
|
gapValue = tmpCnt - captValue;
|
||||||
|
TCNT1 = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
ISR(INT1_vect) {
|
||||||
|
captValue = TCNT1;
|
||||||
|
tick = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void dcf77SetValid(uint8_t x) {
|
||||||
|
valid = x;
|
||||||
|
validLedSetStatus(valid);
|
||||||
|
if (valid == 1) {
|
||||||
|
validCnt++;
|
||||||
|
clockSetUseLocalClock(1);
|
||||||
|
} else if (valid == 2) {
|
||||||
|
timeValidCnt++;
|
||||||
|
clockSetUseLocalClock(0);
|
||||||
|
stepperEnable();
|
||||||
|
} else {
|
||||||
|
clockSetUseLocalClock(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t getValid() {
|
||||||
|
return valid;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void dcf77Engine() {
|
||||||
|
static receivedData_t rd;
|
||||||
|
static uint8_t state = 0;
|
||||||
|
static uint8_t showState = 0;
|
||||||
|
uint8_t bit = 0;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
if (tick != 0) {
|
||||||
|
tick = 0;
|
||||||
|
|
||||||
|
uint16_t pulse = (((uint32_t) captValue) * 1000) / 15625;
|
||||||
|
uint16_t gap = (((uint32_t) gapValue) * 1000) / 15625;
|
||||||
|
|
||||||
|
if (gap > START_GAP_MIN) {
|
||||||
|
if (valid == 0) {
|
||||||
|
dcf77SetValid(1);;
|
||||||
|
}
|
||||||
|
state = 0;
|
||||||
|
clockClearSecond();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pulse > ZERO_WIDTH_MIN && pulse < ZERO_WIDTH_MAX) {
|
||||||
|
bit = 0;
|
||||||
|
} else if (pulse > ONE_WIDTH_MIN && pulse < ONE_WIDTH_MAX) {
|
||||||
|
bit = 1;
|
||||||
|
} else {
|
||||||
|
bit = 2;
|
||||||
|
dcf77SetValid(0);;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if (valid > 0) {
|
||||||
|
switch (state) {
|
||||||
|
case 0:
|
||||||
|
if (bit != 0)
|
||||||
|
dcf77SetValid(0);
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
break;
|
||||||
|
case 4:
|
||||||
|
break;
|
||||||
|
case 5:
|
||||||
|
break;
|
||||||
|
case 6:
|
||||||
|
break;
|
||||||
|
case 7:
|
||||||
|
break;
|
||||||
|
case 8:
|
||||||
|
break;
|
||||||
|
case 9:
|
||||||
|
break;
|
||||||
|
case 10:
|
||||||
|
break;
|
||||||
|
case 11:
|
||||||
|
break;
|
||||||
|
case 12:
|
||||||
|
break;
|
||||||
|
case 13:
|
||||||
|
break;
|
||||||
|
case 14:
|
||||||
|
break;
|
||||||
|
case 15:
|
||||||
|
break;
|
||||||
|
case 16:
|
||||||
|
break;
|
||||||
|
case 17:
|
||||||
|
break;
|
||||||
|
case 18:
|
||||||
|
break;
|
||||||
|
case 19:
|
||||||
|
break;
|
||||||
|
case 20:
|
||||||
|
if (bit != 1)
|
||||||
|
dcf77SetValid(0);
|
||||||
|
break;
|
||||||
|
case 21:
|
||||||
|
rd.minuteOneCnt = 0;
|
||||||
|
rd.minuteDigit0 = 0;
|
||||||
|
rd.minuteDigit0 |= bit;
|
||||||
|
if (bit == 1)
|
||||||
|
rd.minuteOneCnt++;
|
||||||
|
break;
|
||||||
|
case 22:
|
||||||
|
rd.minuteDigit0 |= (bit << 1);
|
||||||
|
if (bit == 1)
|
||||||
|
rd.minuteOneCnt++;
|
||||||
|
break;
|
||||||
|
case 23:
|
||||||
|
rd.minuteDigit0 |= (bit << 2);
|
||||||
|
if (bit == 1)
|
||||||
|
rd.minuteOneCnt++;
|
||||||
|
break;
|
||||||
|
case 24:
|
||||||
|
rd.minuteDigit0 |= (bit << 3);
|
||||||
|
if (bit == 1)
|
||||||
|
rd.minuteOneCnt++;
|
||||||
|
break;
|
||||||
|
case 25:
|
||||||
|
rd.minuteDigit1 = 0;
|
||||||
|
rd.minuteDigit1 |= bit;
|
||||||
|
if (bit == 1)
|
||||||
|
rd.minuteOneCnt++;
|
||||||
|
break;
|
||||||
|
case 26:
|
||||||
|
rd.minuteDigit1 |= (bit << 1);
|
||||||
|
if (bit == 1)
|
||||||
|
rd.minuteOneCnt++;
|
||||||
|
break;
|
||||||
|
case 27:
|
||||||
|
rd.minuteDigit1 |= (bit << 2);
|
||||||
|
if (bit == 1)
|
||||||
|
rd.minuteOneCnt++;
|
||||||
|
break;
|
||||||
|
case 28:
|
||||||
|
rd.minuteOneCnt += bit;
|
||||||
|
if (rd.minuteOneCnt % 2 != 0) {
|
||||||
|
printf("MINUTE INVALID\n");
|
||||||
|
dcf77SetValid(0);
|
||||||
|
} else {
|
||||||
|
printf("MINUTE %u %u\n", rd.minuteDigit0, rd.minuteDigit1);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 29:
|
||||||
|
rd.hourOneCnt = 0;
|
||||||
|
rd.hourDigit0 = 0;
|
||||||
|
rd.hourDigit0 |= bit;
|
||||||
|
if (bit == 1)
|
||||||
|
rd.hourOneCnt++;
|
||||||
|
break;
|
||||||
|
case 30:
|
||||||
|
rd.hourDigit0 |= (bit << 1);
|
||||||
|
if (bit == 1)
|
||||||
|
rd.hourOneCnt++;
|
||||||
|
break;
|
||||||
|
case 31:
|
||||||
|
rd.hourDigit0 |= (bit << 2);
|
||||||
|
if (bit == 1)
|
||||||
|
rd.hourOneCnt++;
|
||||||
|
break;
|
||||||
|
case 32:
|
||||||
|
rd.hourDigit0 |= (bit << 3);
|
||||||
|
if (bit == 1)
|
||||||
|
rd.hourOneCnt++;
|
||||||
|
break;
|
||||||
|
case 33:
|
||||||
|
rd.hourDigit1 = 0;
|
||||||
|
rd.hourDigit1 |= bit;
|
||||||
|
if (bit == 1)
|
||||||
|
rd.hourOneCnt++;
|
||||||
|
break;
|
||||||
|
case 34:
|
||||||
|
rd.hourDigit1 |= (bit << 1);
|
||||||
|
if (bit == 1)
|
||||||
|
rd.hourOneCnt++;
|
||||||
|
break;
|
||||||
|
case 35:
|
||||||
|
rd.hourOneCnt += bit;
|
||||||
|
if (rd.hourOneCnt % 2 != 0) {
|
||||||
|
printf("HOUR INVALID\n");
|
||||||
|
dcf77SetValid(0);
|
||||||
|
} else {
|
||||||
|
printf("HOUR %u %u\n", rd.hourDigit0, rd.hourDigit1);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 36:
|
||||||
|
rd.dateOneCnt = 0;
|
||||||
|
rd.dayDigit0 = 0;
|
||||||
|
rd.dayDigit0 |= bit;
|
||||||
|
if (bit == 1)
|
||||||
|
rd.dateOneCnt++;
|
||||||
|
break;
|
||||||
|
case 37:
|
||||||
|
rd.dayDigit0 |= (bit << 1);
|
||||||
|
if (bit == 1)
|
||||||
|
rd.dateOneCnt++;
|
||||||
|
break;
|
||||||
|
case 38:
|
||||||
|
rd.dayDigit0 |= (bit << 2);
|
||||||
|
if (bit == 1)
|
||||||
|
rd.dateOneCnt++;
|
||||||
|
break;
|
||||||
|
case 39:
|
||||||
|
rd.dayDigit0 |= (bit << 3);
|
||||||
|
if (bit == 1)
|
||||||
|
rd.dateOneCnt++;
|
||||||
|
break;
|
||||||
|
case 40:
|
||||||
|
rd.dayDigit1 = 0;
|
||||||
|
rd.dayDigit1 |= bit;
|
||||||
|
if (bit == 1)
|
||||||
|
rd.dateOneCnt++;
|
||||||
|
break;
|
||||||
|
case 41:
|
||||||
|
rd.dayDigit1 |= (bit << 1);
|
||||||
|
if (bit == 1)
|
||||||
|
rd.dateOneCnt++;
|
||||||
|
break;
|
||||||
|
case 42:
|
||||||
|
rd.weekdayDigit0 = 0;
|
||||||
|
rd.weekdayDigit0 |= bit;
|
||||||
|
if (bit == 1)
|
||||||
|
rd.dateOneCnt++;
|
||||||
|
break;
|
||||||
|
case 43:
|
||||||
|
rd.weekdayDigit0 |= (bit << 1);
|
||||||
|
if (bit == 1)
|
||||||
|
rd.dateOneCnt++;
|
||||||
|
break;
|
||||||
|
case 44:
|
||||||
|
rd.weekdayDigit0 |= (bit << 2);
|
||||||
|
if (bit == 1)
|
||||||
|
rd.dateOneCnt++;
|
||||||
|
break;
|
||||||
|
case 45:
|
||||||
|
rd.monthDigit0 = 0;
|
||||||
|
rd.monthDigit0 |= bit;
|
||||||
|
if (bit == 1)
|
||||||
|
rd.dateOneCnt++;
|
||||||
|
break;
|
||||||
|
case 46:
|
||||||
|
rd.monthDigit0 |= (bit << 1);
|
||||||
|
if (bit == 1)
|
||||||
|
rd.dateOneCnt++;
|
||||||
|
break;
|
||||||
|
case 47:
|
||||||
|
rd.monthDigit0 |= (bit << 2);
|
||||||
|
if (bit == 1)
|
||||||
|
rd.dateOneCnt++;
|
||||||
|
break;
|
||||||
|
case 48:
|
||||||
|
rd.monthDigit0 |= (bit << 3);
|
||||||
|
if (bit == 1)
|
||||||
|
rd.dateOneCnt++;
|
||||||
|
break;
|
||||||
|
case 49:
|
||||||
|
rd.monthDigit1 = 0;
|
||||||
|
rd.monthDigit1 |= bit;
|
||||||
|
if (bit == 1)
|
||||||
|
rd.dateOneCnt++;
|
||||||
|
break;
|
||||||
|
case 50:
|
||||||
|
rd.yearDigit0 = 0;
|
||||||
|
rd.yearDigit0 |= bit;
|
||||||
|
if (bit == 1)
|
||||||
|
rd.dateOneCnt++;
|
||||||
|
break;
|
||||||
|
case 51:
|
||||||
|
rd.yearDigit0 |= (bit << 1);
|
||||||
|
if (bit == 1)
|
||||||
|
rd.dateOneCnt++;
|
||||||
|
break;
|
||||||
|
case 52:
|
||||||
|
rd.yearDigit0 |= (bit << 2);
|
||||||
|
if (bit == 1)
|
||||||
|
rd.dateOneCnt++;
|
||||||
|
break;
|
||||||
|
case 53:
|
||||||
|
rd.yearDigit0 |= (bit << 3);
|
||||||
|
if (bit == 1)
|
||||||
|
rd.dateOneCnt++;
|
||||||
|
break;
|
||||||
|
case 54:
|
||||||
|
rd.yearDigit1 = 0;
|
||||||
|
rd.yearDigit1 |= bit;
|
||||||
|
if (bit == 1)
|
||||||
|
rd.dateOneCnt++;
|
||||||
|
break;
|
||||||
|
case 55:
|
||||||
|
rd.yearDigit1 |= (bit << 1);
|
||||||
|
if (bit == 1)
|
||||||
|
rd.dateOneCnt++;
|
||||||
|
break;
|
||||||
|
case 56:
|
||||||
|
rd.yearDigit1 |= (bit << 2);
|
||||||
|
if (bit == 1)
|
||||||
|
rd.dateOneCnt++;
|
||||||
|
break;
|
||||||
|
case 57:
|
||||||
|
rd.yearDigit1 |= (bit << 3);
|
||||||
|
if (bit == 1)
|
||||||
|
rd.dateOneCnt++;
|
||||||
|
break;
|
||||||
|
case 58:
|
||||||
|
rd.dateOneCnt += bit;
|
||||||
|
if (rd.dateOneCnt % 2 != 0) {
|
||||||
|
printf("DATE INVALID\n");
|
||||||
|
dcf77SetValid(0);
|
||||||
|
} else {
|
||||||
|
printf("DAY %u %u\n", rd.dayDigit0, rd.dayDigit1);
|
||||||
|
printf("WEEKDAY %u\n", rd.weekdayDigit0);
|
||||||
|
printf("MONTH %u %u\n", rd.monthDigit0, rd.monthDigit1);
|
||||||
|
printf("YEAR %u %u\n", rd.yearDigit0, rd.yearDigit1);
|
||||||
|
|
||||||
|
clockSetClock(rd.yearDigit0 + rd.yearDigit1 * 10,
|
||||||
|
rd.monthDigit0 + rd.monthDigit1 * 10,
|
||||||
|
rd.dayDigit0 + rd.dayDigit1 * 10,
|
||||||
|
rd.weekdayDigit0,
|
||||||
|
rd.hourDigit0 + rd.hourDigit1 * 10,
|
||||||
|
rd.minuteDigit0 + rd.minuteDigit1 * 10);
|
||||||
|
|
||||||
|
dcf77SetValid(2);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 59:
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
valid = 0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
showState = state;
|
||||||
|
state++;
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("DCF77: %d %02d %d %d %d %ld %ld\n",
|
||||||
|
valid, showState, bit, pulse, gap, validCnt, timeValidCnt);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
39
src/dcf77.h
Normal file
39
src/dcf77.h
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
#ifndef DCF77_H_
|
||||||
|
#define DCF77_H_
|
||||||
|
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
|
||||||
|
#define START_GAP_MIN 1500
|
||||||
|
#define ONE_WIDTH_MIN 170
|
||||||
|
#define ONE_WIDTH_MAX 260
|
||||||
|
#define ZERO_WIDTH_MIN 70
|
||||||
|
#define ZERO_WIDTH_MAX 150
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
typedef struct receivedData_s {
|
||||||
|
uint8_t minuteDigit0;
|
||||||
|
uint8_t minuteDigit1;
|
||||||
|
uint8_t minuteOneCnt;
|
||||||
|
uint8_t hourDigit0;
|
||||||
|
uint8_t hourDigit1;
|
||||||
|
uint8_t hourOneCnt;
|
||||||
|
uint8_t dayDigit0;
|
||||||
|
uint8_t dayDigit1;
|
||||||
|
uint8_t weekdayDigit0;
|
||||||
|
uint8_t monthDigit0;
|
||||||
|
uint8_t monthDigit1;
|
||||||
|
uint8_t yearDigit0;
|
||||||
|
uint8_t yearDigit1;
|
||||||
|
uint8_t dateOneCnt;
|
||||||
|
} receivedData_t;
|
||||||
|
|
||||||
|
|
||||||
|
void dcf77Init();
|
||||||
|
void dcf77Engine();
|
||||||
|
void dcf77SetValid(uint8_t x);
|
||||||
|
|
||||||
|
|
||||||
|
#endif /* DCF77_H_ */
|
704
src/main.c
704
src/main.c
@ -1,712 +1,52 @@
|
|||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <avr/io.h>
|
#include <avr/io.h>
|
||||||
#include <avr/interrupt.h>
|
#include <avr/interrupt.h>
|
||||||
#include <util/delay.h>
|
|
||||||
|
|
||||||
|
#include "dcf77.h"
|
||||||
|
#include "clock.h"
|
||||||
#include "uartdrv.h"
|
#include "uartdrv.h"
|
||||||
|
#include "stepper.h"
|
||||||
|
#include "validLed.h"
|
||||||
|
|
||||||
|
|
||||||
#define START_GAP_MIN 1500
|
|
||||||
#define ONE_WIDTH_MIN 170
|
|
||||||
#define ONE_WIDTH_MAX 260
|
|
||||||
#define ZERO_WIDTH_MIN 70
|
|
||||||
#define ZERO_WIDTH_MAX 150
|
|
||||||
|
|
||||||
#define SUB_DIV_LED 30
|
|
||||||
#define SUB_DIV_STEPPER 3
|
|
||||||
|
|
||||||
#define STEPS_PER_MINUTE 3
|
|
||||||
#define STEPS_PER_HOUR 7
|
|
||||||
|
|
||||||
|
|
||||||
typedef struct receivedData_s {
|
|
||||||
uint8_t minuteDigit0;
|
|
||||||
uint8_t minuteDigit1;
|
|
||||||
uint8_t minuteOneCnt;
|
|
||||||
uint8_t hourDigit0;
|
|
||||||
uint8_t hourDigit1;
|
|
||||||
uint8_t hourOneCnt;
|
|
||||||
uint8_t dayDigit0;
|
|
||||||
uint8_t dayDigit1;
|
|
||||||
uint8_t weekdayDigit0;
|
|
||||||
uint8_t monthDigit0;
|
|
||||||
uint8_t monthDigit1;
|
|
||||||
uint8_t yearDigit0;
|
|
||||||
uint8_t yearDigit1;
|
|
||||||
uint8_t dateOneCnt;
|
|
||||||
} receivedData_t;
|
|
||||||
|
|
||||||
typedef struct clock_s {
|
|
||||||
uint8_t hour;
|
|
||||||
uint8_t minute;
|
|
||||||
uint8_t second;
|
|
||||||
uint8_t day;
|
|
||||||
uint8_t weekday;
|
|
||||||
uint8_t month;
|
|
||||||
uint8_t year;
|
|
||||||
} clock_t;
|
|
||||||
|
|
||||||
typedef struct opTime_s {
|
|
||||||
uint8_t second;
|
|
||||||
uint8_t minute;
|
|
||||||
uint16_t hour;
|
|
||||||
} opTime_t;
|
|
||||||
|
|
||||||
|
|
||||||
receivedData_t rd;
|
|
||||||
|
|
||||||
volatile clock_t clock;
|
|
||||||
volatile opTime_t opTime;
|
|
||||||
volatile uint8_t tick;
|
|
||||||
volatile uint16_t captValue = 0;
|
|
||||||
volatile uint16_t gapValue = 0;
|
|
||||||
volatile uint8_t valid = 0;
|
|
||||||
volatile uint8_t tack = 0;
|
|
||||||
volatile uint8_t step = 0;
|
|
||||||
|
|
||||||
extern uint8_t bufferReadIdx;
|
|
||||||
extern uint8_t bufferWriteIdx;
|
|
||||||
|
|
||||||
ISR(TIMER2_OVF_vect) {
|
|
||||||
clock.second++;
|
|
||||||
|
|
||||||
if (valid != 2) {
|
|
||||||
if (clock.second >= 60) {
|
|
||||||
clock.second = 0;
|
|
||||||
clock.minute++;
|
|
||||||
}
|
|
||||||
if (clock.minute >= 60) {
|
|
||||||
clock.minute = 0;
|
|
||||||
clock.hour++;
|
|
||||||
}
|
|
||||||
if (clock.hour >= 24) {
|
|
||||||
clock.hour = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
opTime.second++;
|
|
||||||
|
|
||||||
if (opTime.second >= 60) {
|
|
||||||
opTime.second = 0;
|
|
||||||
opTime.minute++;
|
|
||||||
}
|
|
||||||
if (opTime.minute >= 60) {
|
|
||||||
opTime.minute = 0;
|
|
||||||
opTime.hour++;
|
|
||||||
}
|
|
||||||
if (opTime.hour >= 24) {
|
|
||||||
opTime.hour = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ISR(INT0_vect) {
|
|
||||||
uint16_t tmpCnt = TCNT1;
|
|
||||||
gapValue = tmpCnt - captValue;
|
|
||||||
TCNT1 = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
ISR(INT1_vect) {
|
|
||||||
captValue = TCNT1;
|
|
||||||
tick = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
ISR(TIMER0_OVF_vect) {
|
|
||||||
static uint8_t subDivTack = 0;
|
|
||||||
subDivTack++;
|
|
||||||
if (subDivTack >= SUB_DIV_LED) {
|
|
||||||
subDivTack = 0;
|
|
||||||
tack = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
static uint8_t subDivStepper = 0;
|
|
||||||
subDivStepper++;
|
|
||||||
if (subDivStepper >= SUB_DIV_STEPPER) {
|
|
||||||
subDivStepper = 0;
|
|
||||||
step = 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
int main() {
|
int main() {
|
||||||
uartdrvInit();
|
|
||||||
|
|
||||||
clock.hour = 0;
|
|
||||||
clock.minute = 0;
|
|
||||||
clock.second = 0;
|
|
||||||
|
|
||||||
opTime.hour = 0;
|
|
||||||
opTime.minute = 0;
|
|
||||||
opTime.second = 0;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// seconds
|
|
||||||
TCCR2 = 0b00000101;
|
|
||||||
ASSR |= (1 << AS2);
|
|
||||||
TIMSK |= (1 << TOIE2) | (1 << TICIE1);
|
|
||||||
|
|
||||||
// signal measurment
|
|
||||||
TCCR1A = 0;
|
|
||||||
TCCR1B = (1 << CS12) | (1 << CS10);
|
|
||||||
|
|
||||||
DDRD &= ~(1 << PD2);
|
|
||||||
DDRD &= ~(1 << PD3);
|
|
||||||
PORTD |= (1 << PD2) | (1 << PD3);
|
|
||||||
MCUCR |= (1 << ISC11) | (1 << ISC10) | (1 << ISC01);
|
|
||||||
GICR |= (1 << INT0) | (1 << INT1);
|
|
||||||
|
|
||||||
// esd prot
|
// esd prot
|
||||||
DDRD |= (1 << PD5) | (1 << PD6);
|
DDRD |= (1 << PD5) | (1 << PD6);
|
||||||
|
|
||||||
// valid led
|
|
||||||
DDRB |= (1 << PB0);
|
|
||||||
TCCR0 = (1 << CS02) | (1 << CS00);
|
|
||||||
TIMSK |= (1 << TOIE0);
|
|
||||||
|
|
||||||
// position switches
|
uartdrvInit();
|
||||||
DDRB &= ~(1 << PB1);
|
clockInit();
|
||||||
DDRB &= ~(1 << PB2);
|
dcf77Init();
|
||||||
PORTB |= (1 << PB1) | (1 << PB2);
|
stepperInit();
|
||||||
|
validLedInit();
|
||||||
|
|
||||||
// dark switch
|
|
||||||
DDRD &= ~(1 << PD7);
|
|
||||||
PORTD |= (1 << PD7);
|
|
||||||
|
|
||||||
// stepper
|
|
||||||
DDRC |= (1 << PC4) | (1 << PC3) | (1 << PC2) | (1 << PC1) | (1 << PC0);
|
|
||||||
DDRA |= (1 << PA0) | (1 << PA1);
|
|
||||||
|
|
||||||
PORTC &= ~(1 << PC3);
|
|
||||||
PORTC &= ~(1 << PC2);
|
|
||||||
PORTC &= ~(1 << PC1);
|
|
||||||
PORTC &= ~(1 << PC0);
|
|
||||||
|
|
||||||
PORTA &= ~(1 << PA0);
|
|
||||||
PORTA &= ~(1 << PA1);
|
|
||||||
|
|
||||||
PORTC &= ~(1 << PC4);
|
|
||||||
_delay_ms(1);
|
|
||||||
PORTC |= (1 << PC4);
|
|
||||||
|
|
||||||
sei();
|
sei();
|
||||||
|
|
||||||
printf("MyClock started\n");
|
printf("MyClock started\n");
|
||||||
|
|
||||||
|
|
||||||
uint8_t bit = 0;
|
|
||||||
uint8_t state = 0;
|
|
||||||
uint16_t validCnt = 0;
|
|
||||||
uint16_t timeValidCnt = 0;
|
|
||||||
uint8_t ledToggle = 0;
|
|
||||||
|
|
||||||
|
|
||||||
while (1) {
|
while (1) {
|
||||||
if (tick != 0) {
|
dcf77Engine();
|
||||||
tick = 0;
|
|
||||||
|
|
||||||
uint16_t pulse = (((uint32_t) captValue) * 1000) / 15625;
|
stepperEngine();
|
||||||
uint16_t gap = (((uint32_t) gapValue) * 1000) / 15625;
|
|
||||||
|
|
||||||
if (gap > START_GAP_MIN) {
|
validLedEngine();
|
||||||
if (valid == 0) {
|
|
||||||
validCnt++;
|
|
||||||
valid = 1;
|
if (clockNextSecond()) {
|
||||||
}
|
clock_t clock = clockGetClock();
|
||||||
state = 0;
|
printf("Time: %02d:%02d:%02d %d %02d.%02d.%02d\n",
|
||||||
clock.second = 0;
|
clock.year, clock.month, clock.day, clock.weekday,
|
||||||
|
clock.hour, clock.minute, clock.second);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pulse > ZERO_WIDTH_MIN && pulse < ZERO_WIDTH_MAX) {
|
if (clockNextMinute()) {
|
||||||
bit = 0;
|
opTime_t opTime = clockGetOpTime();
|
||||||
} else if (pulse > ONE_WIDTH_MIN && pulse < ONE_WIDTH_MAX) {
|
printf("**** OpTime: %d %02d:%02d:%02d\n", opTime.day, opTime.hour, opTime.minute, opTime.second);
|
||||||
bit = 1;
|
|
||||||
} else {
|
|
||||||
bit = 2;
|
|
||||||
valid = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
if (valid > 0) {
|
|
||||||
switch (state) {
|
|
||||||
case 0:
|
|
||||||
if (bit != 0)
|
|
||||||
valid = 0;
|
|
||||||
break;
|
|
||||||
case 1:
|
|
||||||
break;
|
|
||||||
case 2:
|
|
||||||
break;
|
|
||||||
case 3:
|
|
||||||
break;
|
|
||||||
case 4:
|
|
||||||
break;
|
|
||||||
case 5:
|
|
||||||
break;
|
|
||||||
case 6:
|
|
||||||
break;
|
|
||||||
case 7:
|
|
||||||
break;
|
|
||||||
case 8:
|
|
||||||
break;
|
|
||||||
case 9:
|
|
||||||
break;
|
|
||||||
case 10:
|
|
||||||
break;
|
|
||||||
case 11:
|
|
||||||
break;
|
|
||||||
case 12:
|
|
||||||
break;
|
|
||||||
case 13:
|
|
||||||
break;
|
|
||||||
case 14:
|
|
||||||
break;
|
|
||||||
case 15:
|
|
||||||
break;
|
|
||||||
case 16:
|
|
||||||
break;
|
|
||||||
case 17:
|
|
||||||
break;
|
|
||||||
case 18:
|
|
||||||
break;
|
|
||||||
case 19:
|
|
||||||
break;
|
|
||||||
case 20:
|
|
||||||
if (bit != 1)
|
|
||||||
valid = 0;
|
|
||||||
break;
|
|
||||||
case 21:
|
|
||||||
rd.minuteOneCnt = 0;
|
|
||||||
rd.minuteDigit0 = 0;
|
|
||||||
rd.minuteDigit0 |= bit;
|
|
||||||
if (bit == 1)
|
|
||||||
rd.minuteOneCnt++;
|
|
||||||
break;
|
|
||||||
case 22:
|
|
||||||
rd.minuteDigit0 |= (bit << 1);
|
|
||||||
if (bit == 1)
|
|
||||||
rd.minuteOneCnt++;
|
|
||||||
break;
|
|
||||||
case 23:
|
|
||||||
rd.minuteDigit0 |= (bit << 2);
|
|
||||||
if (bit == 1)
|
|
||||||
rd.minuteOneCnt++;
|
|
||||||
break;
|
|
||||||
case 24:
|
|
||||||
rd.minuteDigit0 |= (bit << 3);
|
|
||||||
if (bit == 1)
|
|
||||||
rd.minuteOneCnt++;
|
|
||||||
break;
|
|
||||||
case 25:
|
|
||||||
rd.minuteDigit1 = 0;
|
|
||||||
rd.minuteDigit1 |= bit;
|
|
||||||
if (bit == 1)
|
|
||||||
rd.minuteOneCnt++;
|
|
||||||
break;
|
|
||||||
case 26:
|
|
||||||
rd.minuteDigit1 |= (bit << 1);
|
|
||||||
if (bit == 1)
|
|
||||||
rd.minuteOneCnt++;
|
|
||||||
break;
|
|
||||||
case 27:
|
|
||||||
rd.minuteDigit1 |= (bit << 2);
|
|
||||||
if (bit == 1)
|
|
||||||
rd.minuteOneCnt++;
|
|
||||||
break;
|
|
||||||
case 28:
|
|
||||||
rd.minuteOneCnt += bit;
|
|
||||||
if (rd.minuteOneCnt % 2 != 0) {
|
|
||||||
printf("MINUTE INVALID\n");
|
|
||||||
valid = 0;
|
|
||||||
} else {
|
|
||||||
printf("MINUTE %u %u\n", rd.minuteDigit0, rd.minuteDigit1);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case 29:
|
|
||||||
rd.hourOneCnt = 0;
|
|
||||||
rd.hourDigit0 = 0;
|
|
||||||
rd.hourDigit0 |= bit;
|
|
||||||
if (bit == 1)
|
|
||||||
rd.hourOneCnt++;
|
|
||||||
break;
|
|
||||||
case 30:
|
|
||||||
rd.hourDigit0 |= (bit << 1);
|
|
||||||
if (bit == 1)
|
|
||||||
rd.hourOneCnt++;
|
|
||||||
break;
|
|
||||||
case 31:
|
|
||||||
rd.hourDigit0 |= (bit << 2);
|
|
||||||
if (bit == 1)
|
|
||||||
rd.hourOneCnt++;
|
|
||||||
break;
|
|
||||||
case 32:
|
|
||||||
rd.hourDigit0 |= (bit << 3);
|
|
||||||
if (bit == 1)
|
|
||||||
rd.hourOneCnt++;
|
|
||||||
break;
|
|
||||||
case 33:
|
|
||||||
rd.hourDigit1 = 0;
|
|
||||||
rd.hourDigit1 |= bit;
|
|
||||||
if (bit == 1)
|
|
||||||
rd.hourOneCnt++;
|
|
||||||
break;
|
|
||||||
case 34:
|
|
||||||
rd.hourDigit1 |= (bit << 1);
|
|
||||||
if (bit == 1)
|
|
||||||
rd.hourOneCnt++;
|
|
||||||
break;
|
|
||||||
case 35:
|
|
||||||
rd.hourOneCnt += bit;
|
|
||||||
if (rd.hourOneCnt % 2 != 0) {
|
|
||||||
printf("HOUR INVALID\n");
|
|
||||||
valid = 0;
|
|
||||||
} else {
|
|
||||||
printf("HOUR %u %u\n", rd.hourDigit0, rd.hourDigit1);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case 36:
|
|
||||||
rd.dateOneCnt = 0;
|
|
||||||
rd.dayDigit0 = 0;
|
|
||||||
rd.dayDigit0 |= bit;
|
|
||||||
if (bit == 1)
|
|
||||||
rd.dateOneCnt++;
|
|
||||||
break;
|
|
||||||
case 37:
|
|
||||||
rd.dayDigit0 |= (bit << 1);
|
|
||||||
if (bit == 1)
|
|
||||||
rd.dateOneCnt++;
|
|
||||||
break;
|
|
||||||
case 38:
|
|
||||||
rd.dayDigit0 |= (bit << 2);
|
|
||||||
if (bit == 1)
|
|
||||||
rd.dateOneCnt++;
|
|
||||||
break;
|
|
||||||
case 39:
|
|
||||||
rd.dayDigit0 |= (bit << 3);
|
|
||||||
if (bit == 1)
|
|
||||||
rd.dateOneCnt++;
|
|
||||||
break;
|
|
||||||
case 40:
|
|
||||||
rd.dayDigit1 = 0;
|
|
||||||
rd.dayDigit1 |= bit;
|
|
||||||
if (bit == 1)
|
|
||||||
rd.dateOneCnt++;
|
|
||||||
break;
|
|
||||||
case 41:
|
|
||||||
rd.dayDigit1 |= (bit << 1);
|
|
||||||
if (bit == 1)
|
|
||||||
rd.dateOneCnt++;
|
|
||||||
break;
|
|
||||||
case 42:
|
|
||||||
rd.weekdayDigit0 = 0;
|
|
||||||
rd.weekdayDigit0 |= bit;
|
|
||||||
if (bit == 1)
|
|
||||||
rd.dateOneCnt++;
|
|
||||||
break;
|
|
||||||
case 43:
|
|
||||||
rd.weekdayDigit0 |= (bit << 1);
|
|
||||||
if (bit == 1)
|
|
||||||
rd.dateOneCnt++;
|
|
||||||
break;
|
|
||||||
case 44:
|
|
||||||
rd.weekdayDigit0 |= (bit << 2);
|
|
||||||
if (bit == 1)
|
|
||||||
rd.dateOneCnt++;
|
|
||||||
break;
|
|
||||||
case 45:
|
|
||||||
rd.monthDigit0 = 0;
|
|
||||||
rd.monthDigit0 |= bit;
|
|
||||||
if (bit == 1)
|
|
||||||
rd.dateOneCnt++;
|
|
||||||
break;
|
|
||||||
case 46:
|
|
||||||
rd.monthDigit0 |= (bit << 1);
|
|
||||||
if (bit == 1)
|
|
||||||
rd.dateOneCnt++;
|
|
||||||
break;
|
|
||||||
case 47:
|
|
||||||
rd.monthDigit0 |= (bit << 2);
|
|
||||||
if (bit == 1)
|
|
||||||
rd.dateOneCnt++;
|
|
||||||
break;
|
|
||||||
case 48:
|
|
||||||
rd.monthDigit0 |= (bit << 3);
|
|
||||||
if (bit == 1)
|
|
||||||
rd.dateOneCnt++;
|
|
||||||
break;
|
|
||||||
case 49:
|
|
||||||
rd.monthDigit1 = 0;
|
|
||||||
rd.monthDigit1 |= bit;
|
|
||||||
if (bit == 1)
|
|
||||||
rd.dateOneCnt++;
|
|
||||||
break;
|
|
||||||
case 50:
|
|
||||||
rd.yearDigit0 = 0;
|
|
||||||
rd.yearDigit0 |= bit;
|
|
||||||
if (bit == 1)
|
|
||||||
rd.dateOneCnt++;
|
|
||||||
break;
|
|
||||||
case 51:
|
|
||||||
rd.yearDigit0 |= (bit << 1);
|
|
||||||
if (bit == 1)
|
|
||||||
rd.dateOneCnt++;
|
|
||||||
break;
|
|
||||||
case 52:
|
|
||||||
rd.yearDigit0 |= (bit << 2);
|
|
||||||
if (bit == 1)
|
|
||||||
rd.dateOneCnt++;
|
|
||||||
break;
|
|
||||||
case 53:
|
|
||||||
rd.yearDigit0 |= (bit << 3);
|
|
||||||
if (bit == 1)
|
|
||||||
rd.dateOneCnt++;
|
|
||||||
break;
|
|
||||||
case 54:
|
|
||||||
rd.yearDigit1 = 0;
|
|
||||||
rd.yearDigit1 |= bit;
|
|
||||||
if (bit == 1)
|
|
||||||
rd.dateOneCnt++;
|
|
||||||
break;
|
|
||||||
case 55:
|
|
||||||
rd.yearDigit1 |= (bit << 1);
|
|
||||||
if (bit == 1)
|
|
||||||
rd.dateOneCnt++;
|
|
||||||
break;
|
|
||||||
case 56:
|
|
||||||
rd.yearDigit1 |= (bit << 2);
|
|
||||||
if (bit == 1)
|
|
||||||
rd.dateOneCnt++;
|
|
||||||
break;
|
|
||||||
case 57:
|
|
||||||
rd.yearDigit1 |= (bit << 3);
|
|
||||||
if (bit == 1)
|
|
||||||
rd.dateOneCnt++;
|
|
||||||
break;
|
|
||||||
case 58:
|
|
||||||
rd.dateOneCnt += bit;
|
|
||||||
if (rd.dateOneCnt % 2 != 0) {
|
|
||||||
printf("DATE INVALID\n");
|
|
||||||
valid = 0;
|
|
||||||
} else {
|
|
||||||
printf("DAY %u %u\n", rd.dayDigit0, rd.dayDigit1);
|
|
||||||
printf("WEEKDAY %u\n", rd.weekdayDigit0);
|
|
||||||
printf("MONTH %u %u\n", rd.monthDigit0, rd.monthDigit1);
|
|
||||||
printf("YEAR %u %u\n", rd.yearDigit0, rd.yearDigit1);
|
|
||||||
|
|
||||||
clock.minute = rd.minuteDigit0 + rd.minuteDigit1 * 10;
|
|
||||||
clock.hour = rd.hourDigit0 + rd.hourDigit1 * 10;
|
|
||||||
clock.day = rd.dayDigit0 + rd.dayDigit1 * 10;
|
|
||||||
clock.weekday = rd.weekdayDigit0;
|
|
||||||
clock.month = rd.monthDigit0 + rd.monthDigit1 * 10;
|
|
||||||
clock.year = rd.yearDigit0 + rd.yearDigit1 * 10;
|
|
||||||
|
|
||||||
|
|
||||||
valid = 2;
|
|
||||||
timeValidCnt++;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case 59:
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
valid = 0;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
printf("% 4d:%02d:%02d %02d:%02d:%02d %02d.%02d.%02d %d %d %02d %d %d %d %d %d %d %d\n",
|
|
||||||
opTime.hour, opTime.minute, opTime.second,
|
|
||||||
clock.hour, clock.minute, clock.second,
|
|
||||||
clock.day, clock.month, clock.year, clock.weekday,
|
|
||||||
valid, state, bit, pulse, gap, validCnt, timeValidCnt,
|
|
||||||
bufferReadIdx, bufferWriteIdx);
|
|
||||||
|
|
||||||
state++;
|
|
||||||
} else {
|
|
||||||
|
|
||||||
printf("% 4d:%02d:%02d %02d:%02d:%02d %02d.%02d.%02d %d %d %02d %d %d %d %d %d %d %d\n",
|
|
||||||
opTime.hour, opTime.minute, opTime.second,
|
|
||||||
clock.hour, clock.minute, clock.second,
|
|
||||||
clock.day, clock.month, clock.year, clock.weekday,
|
|
||||||
valid, state, bit, pulse, gap, validCnt, timeValidCnt,
|
|
||||||
bufferReadIdx, bufferWriteIdx);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static uint8_t oldPositionSwitch = 255;
|
|
||||||
uint8_t positionSwitch = PINB & ((1 << PB1) | (1 << PB2));
|
|
||||||
if (oldPositionSwitch != positionSwitch) {
|
|
||||||
oldPositionSwitch = positionSwitch;
|
|
||||||
printf("POS: %02d\n", positionSwitch);
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((timeValidCnt > 0) && (step != 0)) {
|
|
||||||
step = 0;
|
|
||||||
|
|
||||||
static uint8_t stepperState = 0;
|
|
||||||
|
|
||||||
static uint8_t currentMinutePosition = 0;
|
|
||||||
static uint8_t minuteStepPosition = 0;
|
|
||||||
static int8_t minuteDirection = 0;
|
|
||||||
|
|
||||||
static uint8_t currentHourPosition = 0;
|
|
||||||
static uint8_t hourStepPosition = 0;
|
|
||||||
static int8_t hourDirection = 0;
|
|
||||||
|
|
||||||
switch (stepperState) {
|
|
||||||
case 0:
|
|
||||||
//printf("0 ");
|
|
||||||
// is current minute position different from desired one?
|
|
||||||
minuteStepPosition = clock.minute * STEPS_PER_MINUTE;
|
|
||||||
|
|
||||||
if (currentMinutePosition != minuteStepPosition) {
|
|
||||||
printf("M:\n");
|
|
||||||
|
|
||||||
stepperState = 1;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case 1:
|
|
||||||
printf("1 ");
|
|
||||||
// switch on the minute motor and set the direction
|
|
||||||
PORTA |= (1 << PA1);
|
|
||||||
|
|
||||||
if (currentMinutePosition > minuteStepPosition) {
|
|
||||||
printf("b\n");
|
|
||||||
minuteDirection = -1;
|
|
||||||
PORTC &= ~(1 << PC2);
|
|
||||||
} else {
|
|
||||||
printf("f\n");
|
|
||||||
minuteDirection = 1;
|
|
||||||
PORTC |= (1 << PC2);
|
|
||||||
}
|
|
||||||
|
|
||||||
stepperState = 2;
|
|
||||||
break;
|
|
||||||
case 2:
|
|
||||||
printf("2 ");
|
|
||||||
|
|
||||||
// move one step
|
|
||||||
|
|
||||||
printf("d: %d, c: %d\n", minuteStepPosition, currentMinutePosition);
|
|
||||||
|
|
||||||
currentMinutePosition += minuteDirection;
|
|
||||||
|
|
||||||
PORTC |= (1 << PC3);
|
|
||||||
_delay_us(50);
|
|
||||||
PORTC &= ~(1 << PC3);
|
|
||||||
|
|
||||||
if (currentMinutePosition == minuteStepPosition) {
|
|
||||||
stepperState = 3;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case 3:
|
|
||||||
printf("3\n");
|
|
||||||
|
|
||||||
// switch off the minute motor
|
|
||||||
PORTA &= ~(1 << PA1);
|
|
||||||
|
|
||||||
stepperState = 4;
|
|
||||||
break;
|
|
||||||
case 4:
|
|
||||||
printf("4 ");
|
|
||||||
|
|
||||||
// is current hour position different from desired one?
|
|
||||||
hourStepPosition = clock.hour * STEPS_PER_HOUR;
|
|
||||||
|
|
||||||
if (currentHourPosition != hourStepPosition) {
|
|
||||||
printf(" H:\n");
|
|
||||||
|
|
||||||
stepperState = 5;
|
|
||||||
} else {
|
|
||||||
// done
|
|
||||||
printf("\n");
|
|
||||||
stepperState = 0;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case 5:
|
|
||||||
printf("5 ");
|
|
||||||
|
|
||||||
// switch on the hour motor and set the direction
|
|
||||||
PORTA |= (1 << PA0);
|
|
||||||
|
|
||||||
if (currentHourPosition > hourStepPosition) {
|
|
||||||
printf("b\n");
|
|
||||||
hourDirection = -1;
|
|
||||||
PORTC |= (1 << PC0);
|
|
||||||
} else {
|
|
||||||
printf("f\n");
|
|
||||||
hourDirection = 1;
|
|
||||||
PORTC &= ~(1 << PC0);
|
|
||||||
}
|
|
||||||
|
|
||||||
stepperState = 6;
|
|
||||||
break;
|
|
||||||
case 6:
|
|
||||||
printf("6 ");
|
|
||||||
|
|
||||||
// move one step
|
|
||||||
|
|
||||||
printf("d: %d, c: %d\n", hourStepPosition, currentHourPosition);
|
|
||||||
|
|
||||||
currentHourPosition += hourDirection;
|
|
||||||
|
|
||||||
PORTC |= (1 << PC1);
|
|
||||||
_delay_us(50);
|
|
||||||
PORTC &= ~(1 << PC1);
|
|
||||||
|
|
||||||
if (currentHourPosition == hourStepPosition) {
|
|
||||||
stepperState = 7;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case 7:
|
|
||||||
printf("7\n");
|
|
||||||
|
|
||||||
// switch off the hour motor
|
|
||||||
PORTA &= ~(1 << PA0);
|
|
||||||
|
|
||||||
stepperState = 8;
|
|
||||||
break;
|
|
||||||
case 8:
|
|
||||||
printf("8\n");
|
|
||||||
|
|
||||||
// done
|
|
||||||
stepperState = 0;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
printf("default\n");
|
|
||||||
stepperState = 0;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
if (tack != 0) {
|
|
||||||
tack = 0;
|
|
||||||
|
|
||||||
uint8_t light = PIND & (1 << PD7);
|
|
||||||
switch (valid) {
|
|
||||||
case 0:
|
|
||||||
PORTB &= ~(1 << PB0);
|
|
||||||
break;
|
|
||||||
case 1:
|
|
||||||
if (ledToggle != 0) {
|
|
||||||
ledToggle = 0;
|
|
||||||
PORTB &= ~(1 << PB0);
|
|
||||||
} else {
|
|
||||||
ledToggle = 1;
|
|
||||||
if (light != 0) {
|
|
||||||
PORTB |= (1 << PB0);
|
|
||||||
} else {
|
|
||||||
PORTB &= ~(1 << PB0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case 2:
|
|
||||||
if (light != 0) {
|
|
||||||
PORTB |= (1 << PB0);
|
|
||||||
} else {
|
|
||||||
PORTB &= ~(1 << PB0);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
351
src/stepper.c
Normal file
351
src/stepper.c
Normal file
@ -0,0 +1,351 @@
|
|||||||
|
#include <stdint.h>
|
||||||
|
#include <avr/io.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <util/delay.h>
|
||||||
|
|
||||||
|
|
||||||
|
#include "clock.h"
|
||||||
|
#include "stepper.h"
|
||||||
|
#include "validLed.h"
|
||||||
|
|
||||||
|
#define STEPPER_REG_1_DIR DDRC
|
||||||
|
#define STEPPER_REG_1 PORTC
|
||||||
|
|
||||||
|
#define HOUR_MOTOR_DIRECTION PC0
|
||||||
|
#define HOUR_MOTOR_PULSE PC1
|
||||||
|
#define MINUTE_MOTOR_DIRECTION PC2
|
||||||
|
#define MINUTE_MOTOR_PULSE PC3
|
||||||
|
|
||||||
|
#define STEPPER_CTRL_RESET PC4
|
||||||
|
|
||||||
|
#define STEPPER_REG_2_DIR DDRA
|
||||||
|
#define STEPPER_REG_2 PORTA
|
||||||
|
|
||||||
|
#define HOUR_MOTOR_ENABLE PA0
|
||||||
|
#define MINUTE_MOTOR_ENABLE PA1
|
||||||
|
|
||||||
|
#define STEPPER_REG_3_DIR DDRB
|
||||||
|
#define STEPPER_REG_3 PORTB
|
||||||
|
|
||||||
|
#define HOUR_POSITION_SWITCH PB1
|
||||||
|
#define MINUTE_POSITION_SWITCH PB2
|
||||||
|
|
||||||
|
|
||||||
|
uint8_t stepperEnableFlag = 0;
|
||||||
|
|
||||||
|
|
||||||
|
static inline void hourMotorEnable() {
|
||||||
|
STEPPER_REG_2 |= (1 << HOUR_MOTOR_ENABLE);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void hourMotorDisable() {
|
||||||
|
STEPPER_REG_2 &= ~(1 << HOUR_MOTOR_ENABLE);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void minuteMotorEnable() {
|
||||||
|
STEPPER_REG_2 |= (1 << MINUTE_MOTOR_ENABLE);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void minuteMotorDisable() {
|
||||||
|
STEPPER_REG_2 &= ~(1 << MINUTE_MOTOR_ENABLE);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static inline void hourMotorBackward() {
|
||||||
|
STEPPER_REG_1 &= ~(1 << HOUR_MOTOR_DIRECTION);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void hourMotorForward() {
|
||||||
|
STEPPER_REG_1 |= (1 << HOUR_MOTOR_DIRECTION);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void minuteMotorForward() {
|
||||||
|
STEPPER_REG_1 &= ~(1 << MINUTE_MOTOR_DIRECTION);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void minuteMotorBackward() {
|
||||||
|
STEPPER_REG_1 |= (1 << MINUTE_MOTOR_DIRECTION);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static inline void hourMotorPulse() {
|
||||||
|
STEPPER_REG_1 |= (1 << HOUR_MOTOR_PULSE);
|
||||||
|
_delay_us(50);
|
||||||
|
STEPPER_REG_1 &= ~(1 << HOUR_MOTOR_PULSE);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void minuteMotorPulse() {
|
||||||
|
STEPPER_REG_1 |= (1 << MINUTE_MOTOR_PULSE);
|
||||||
|
_delay_us(50);
|
||||||
|
STEPPER_REG_1 &= ~(1 << MINUTE_MOTOR_PULSE);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static inline void stepperCtrlReset() {
|
||||||
|
STEPPER_REG_1 &= ~(1 << STEPPER_CTRL_RESET);
|
||||||
|
_delay_ms(1);
|
||||||
|
STEPPER_REG_1 |= (1 << STEPPER_CTRL_RESET);
|
||||||
|
}
|
||||||
|
|
||||||
|
void stepperInit() {
|
||||||
|
// stepper
|
||||||
|
STEPPER_REG_1_DIR |= (1 << STEPPER_CTRL_RESET) |
|
||||||
|
(1 << MINUTE_MOTOR_PULSE) | (1 << MINUTE_MOTOR_DIRECTION) |
|
||||||
|
(1 << HOUR_MOTOR_PULSE) | (1 << HOUR_MOTOR_DIRECTION);
|
||||||
|
STEPPER_REG_2_DIR |= (1 << MINUTE_MOTOR_ENABLE) | (1 << HOUR_MOTOR_ENABLE);
|
||||||
|
|
||||||
|
STEPPER_REG_1 &= ~(1 << MINUTE_MOTOR_PULSE);
|
||||||
|
STEPPER_REG_1 &= ~(1 << MINUTE_MOTOR_DIRECTION);
|
||||||
|
STEPPER_REG_1 &= ~(1 << HOUR_MOTOR_PULSE);
|
||||||
|
STEPPER_REG_1 &= ~(1 << HOUR_MOTOR_DIRECTION);
|
||||||
|
|
||||||
|
STEPPER_REG_2 &= ~(1 << MINUTE_MOTOR_ENABLE);
|
||||||
|
STEPPER_REG_2 &= ~(1 << HOUR_MOTOR_ENABLE);
|
||||||
|
|
||||||
|
// position switches
|
||||||
|
STEPPER_REG_3_DIR &= ~(1 << MINUTE_POSITION_SWITCH);
|
||||||
|
STEPPER_REG_3_DIR &= ~(1 << HOUR_POSITION_SWITCH);
|
||||||
|
|
||||||
|
// pull-up on
|
||||||
|
STEPPER_REG_3 |= (1 << MINUTE_POSITION_SWITCH) | (1 << HOUR_POSITION_SWITCH);
|
||||||
|
|
||||||
|
|
||||||
|
stepperCtrlReset();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void stepperEnable() {
|
||||||
|
stepperEnableFlag = 1;
|
||||||
|
|
||||||
|
}
|
||||||
|
void stepperEngine() {
|
||||||
|
|
||||||
|
static uint8_t stepperState = 100;
|
||||||
|
|
||||||
|
static uint16_t currentMinutePosition = 0;
|
||||||
|
static uint16_t minuteStepPosition = 0;
|
||||||
|
static int8_t minuteDirection = 0;
|
||||||
|
|
||||||
|
static uint16_t currentHourPosition = 0;
|
||||||
|
static uint16_t hourStepPosition = 0;
|
||||||
|
static int8_t hourDirection = 0;
|
||||||
|
|
||||||
|
|
||||||
|
if (clockNextStep()) {
|
||||||
|
|
||||||
|
static uint8_t oldPositionSwitch = 255;
|
||||||
|
uint8_t positionSwitch = PINB & ((1 << PB1) | (1 << PB2));
|
||||||
|
uint8_t minutePositionSwitch = (positionSwitch & (1 << PB2)) != 0;
|
||||||
|
uint8_t hourPositionSwitch = (positionSwitch & (1 << PB1)) != 0;
|
||||||
|
if (oldPositionSwitch != positionSwitch) {
|
||||||
|
oldPositionSwitch = positionSwitch;
|
||||||
|
printf("POS: %02d\n", positionSwitch);
|
||||||
|
printf("MinuteSwitch: %d\n", minutePositionSwitch);
|
||||||
|
printf("HourSwitch: %d\n", hourPositionSwitch);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
clock_t clock = clockGetClock();
|
||||||
|
|
||||||
|
switch (stepperState) {
|
||||||
|
case 100:
|
||||||
|
printf("100 Minute zeroing ");
|
||||||
|
minuteMotorEnable();
|
||||||
|
minuteMotorBackward();
|
||||||
|
currentMinutePosition = 0;
|
||||||
|
stepperState = 101;
|
||||||
|
break;
|
||||||
|
case 101:
|
||||||
|
printf("101 ");
|
||||||
|
currentMinutePosition++;
|
||||||
|
printf("%d\n", currentMinutePosition);
|
||||||
|
minuteMotorPulse();
|
||||||
|
if (minutePositionSwitch == 0) {
|
||||||
|
stepperState = 102;
|
||||||
|
}
|
||||||
|
if (currentMinutePosition > 500) {
|
||||||
|
stepperState = 200;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 102:
|
||||||
|
printf("102 Minute zeroed\n");
|
||||||
|
currentMinutePosition = 0;
|
||||||
|
minuteMotorDisable();
|
||||||
|
stepperState = 103;
|
||||||
|
break;
|
||||||
|
case 103:
|
||||||
|
printf("103 Hour zeroing ");
|
||||||
|
hourMotorEnable();
|
||||||
|
hourMotorBackward();
|
||||||
|
currentHourPosition = 0;
|
||||||
|
stepperState = 104;
|
||||||
|
break;
|
||||||
|
case 104:
|
||||||
|
printf("104 ");
|
||||||
|
currentHourPosition++;
|
||||||
|
printf("%d\n", currentHourPosition);
|
||||||
|
hourMotorPulse();
|
||||||
|
if (hourPositionSwitch == 0) {
|
||||||
|
stepperState = 105;
|
||||||
|
}
|
||||||
|
if (currentHourPosition > 500) {
|
||||||
|
stepperState = 201;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 105:
|
||||||
|
printf("105 Hour zeroed\n");
|
||||||
|
currentHourPosition = 0;
|
||||||
|
hourMotorDisable();
|
||||||
|
stepperState = 0;
|
||||||
|
break;
|
||||||
|
case 200:
|
||||||
|
printf("200 Minute zeroing error\n");
|
||||||
|
{
|
||||||
|
static uint8_t ledToggle = 0;
|
||||||
|
if (ledToggle != 0) {
|
||||||
|
ledToggle = 0;
|
||||||
|
validLedDisable();
|
||||||
|
} else {
|
||||||
|
ledToggle = 1;
|
||||||
|
validLedEnable();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 201:
|
||||||
|
printf("201 Hour zeroing error\n");
|
||||||
|
{
|
||||||
|
static uint8_t ledToggle = 0;
|
||||||
|
if (ledToggle != 0) {
|
||||||
|
ledToggle = 0;
|
||||||
|
validLedDisable();
|
||||||
|
} else {
|
||||||
|
ledToggle = 1;
|
||||||
|
validLedEnable();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 0:
|
||||||
|
//printf("0 ");
|
||||||
|
if (stepperEnableFlag == 1) {
|
||||||
|
// is current minute position different from desired one?
|
||||||
|
minuteStepPosition = clock.minute * STEPS_PER_MINUTE;
|
||||||
|
|
||||||
|
if (currentMinutePosition != minuteStepPosition) {
|
||||||
|
printf("M:\n");
|
||||||
|
|
||||||
|
stepperState = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
printf("1 ");
|
||||||
|
// switch on the minute motor and set the direction
|
||||||
|
minuteMotorEnable();
|
||||||
|
|
||||||
|
if (currentMinutePosition > minuteStepPosition) {
|
||||||
|
printf("b\n");
|
||||||
|
minuteDirection = -1;
|
||||||
|
minuteMotorBackward();
|
||||||
|
} else {
|
||||||
|
printf("f\n");
|
||||||
|
minuteDirection = 1;
|
||||||
|
minuteMotorForward();
|
||||||
|
}
|
||||||
|
|
||||||
|
stepperState = 2;
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
printf("2 ");
|
||||||
|
|
||||||
|
// move one step
|
||||||
|
currentMinutePosition += minuteDirection;
|
||||||
|
|
||||||
|
minuteMotorPulse();
|
||||||
|
|
||||||
|
printf("d: %d, c: %d\n", minuteStepPosition, currentMinutePosition);
|
||||||
|
|
||||||
|
if (currentMinutePosition == minuteStepPosition) {
|
||||||
|
stepperState = 3;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
printf("3\n");
|
||||||
|
|
||||||
|
// switch off the minute motor
|
||||||
|
minuteMotorDisable();
|
||||||
|
|
||||||
|
stepperState = 4;
|
||||||
|
break;
|
||||||
|
case 4:
|
||||||
|
printf("4 ");
|
||||||
|
|
||||||
|
// is current hour position different from desired one?
|
||||||
|
hourStepPosition = clock.hour * STEPS_PER_HOUR;
|
||||||
|
|
||||||
|
if (currentHourPosition != hourStepPosition) {
|
||||||
|
printf(" H:\n");
|
||||||
|
|
||||||
|
stepperState = 5;
|
||||||
|
} else {
|
||||||
|
// done
|
||||||
|
printf("\n");
|
||||||
|
stepperState = 0;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 5:
|
||||||
|
printf("5 ");
|
||||||
|
|
||||||
|
// switch on the hour motor and set the direction
|
||||||
|
hourMotorEnable();
|
||||||
|
|
||||||
|
if (currentHourPosition > hourStepPosition) {
|
||||||
|
printf("b\n");
|
||||||
|
hourDirection = -1;
|
||||||
|
hourMotorBackward();
|
||||||
|
} else {
|
||||||
|
printf("f\n");
|
||||||
|
hourDirection = 1;
|
||||||
|
hourMotorForward();
|
||||||
|
}
|
||||||
|
|
||||||
|
stepperState = 6;
|
||||||
|
break;
|
||||||
|
case 6:
|
||||||
|
printf("6 ");
|
||||||
|
|
||||||
|
// move one step
|
||||||
|
currentHourPosition += hourDirection;
|
||||||
|
|
||||||
|
hourMotorPulse();
|
||||||
|
|
||||||
|
printf("d: %d, c: %d\n", hourStepPosition, currentHourPosition);
|
||||||
|
|
||||||
|
if (currentHourPosition == hourStepPosition) {
|
||||||
|
stepperState = 7;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 7:
|
||||||
|
printf("7\n");
|
||||||
|
|
||||||
|
// switch off the hour motor
|
||||||
|
hourMotorDisable();
|
||||||
|
|
||||||
|
stepperState = 8;
|
||||||
|
break;
|
||||||
|
case 8:
|
||||||
|
printf("8\n");
|
||||||
|
|
||||||
|
// done
|
||||||
|
stepperState = 0;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
printf("default\n");
|
||||||
|
stepperState = 0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
16
src/stepper.h
Normal file
16
src/stepper.h
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
#ifndef STEPPER_H_
|
||||||
|
#define STEPPER_H_
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
#define STEPS_PER_MINUTE 3
|
||||||
|
#define STEPS_PER_HOUR 7
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void stepperInit();
|
||||||
|
void stepperEnable();
|
||||||
|
void stepperEngine();
|
||||||
|
|
||||||
|
|
||||||
|
#endif /* STEPPER_H_ */
|
@ -6,21 +6,28 @@
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
#define BUFFER_SIZE 256
|
volatile uint8_t buffer[UART_TX_BUFFER_SIZE+5];
|
||||||
volatile uint8_t buffer[BUFFER_SIZE+5];
|
|
||||||
volatile uint8_t bufferReadIdx = 0;
|
volatile uint8_t bufferReadIdx = 0;
|
||||||
volatile uint8_t bufferWriteIdx = 0;
|
volatile uint8_t bufferWriteIdx = 0;
|
||||||
|
|
||||||
void uartdrvInit() {
|
static inline void enableDataRegisterEmptyInterrupt() {
|
||||||
|
UCSRB |= (1 << UDRIE);
|
||||||
|
}
|
||||||
|
|
||||||
// UART
|
static inline void disableDataRegisterEmptyInterrupt() {
|
||||||
|
UCSRB &= ~(1 << UDRIE);
|
||||||
|
}
|
||||||
|
|
||||||
|
void uartdrvInit() {
|
||||||
// TXD
|
// TXD
|
||||||
DDRD |= (1 << PD1);
|
DDRD |= (1 << PD1);
|
||||||
|
|
||||||
// transmitter enable
|
// transmitter enable
|
||||||
UCSRB = (1 << TXEN);
|
UCSRB = (1 << TXEN);
|
||||||
|
|
||||||
// 8 data bit, no parity, 1 stop bit
|
// 8 data bit, no parity, 1 stop bit
|
||||||
UCSRC = (1 << UCSZ1) | (1 << UCSZ0);
|
UCSRC = (1 << UCSZ1) | (1 << UCSZ0);
|
||||||
|
|
||||||
// 2400 Baud @ 16MHz
|
// 2400 Baud @ 16MHz
|
||||||
UBRRL = 0xa0;
|
UBRRL = 0xa0;
|
||||||
UBRRH = 0x01;;
|
UBRRH = 0x01;;
|
||||||
@ -30,16 +37,16 @@ void uartdrvInit() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void uartdrvWrite(uint8_t o) {
|
void uartdrvWrite(uint8_t o) {
|
||||||
// loop_until_bit_is_set(UCSRA, UDRE);
|
if (bufferWriteIdx == UART_TX_BUFFER_SIZE - 1) {
|
||||||
// UDR = o;
|
while (bufferReadIdx == UART_TX_BUFFER_SIZE);
|
||||||
if (bufferWriteIdx == BUFFER_SIZE - 1) {
|
|
||||||
while (bufferReadIdx == BUFFER_SIZE);
|
|
||||||
} else {
|
} else {
|
||||||
while (bufferReadIdx == bufferWriteIdx + 1);
|
while (bufferReadIdx == bufferWriteIdx + 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
buffer[bufferWriteIdx] = o;
|
buffer[bufferWriteIdx] = o;
|
||||||
bufferWriteIdx++;
|
bufferWriteIdx++;
|
||||||
UCSRB |= (1 << UDRIE);
|
|
||||||
|
enableDataRegisterEmptyInterrupt();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -55,10 +62,10 @@ ISR(USART_UDRE_vect) {
|
|||||||
if (bufferReadIdx != bufferWriteIdx) {
|
if (bufferReadIdx != bufferWriteIdx) {
|
||||||
UDR = buffer[bufferReadIdx];
|
UDR = buffer[bufferReadIdx];
|
||||||
bufferReadIdx++;
|
bufferReadIdx++;
|
||||||
if (bufferReadIdx > BUFFER_SIZE) {
|
if (bufferReadIdx > UART_TX_BUFFER_SIZE) {
|
||||||
bufferReadIdx = 0;
|
bufferReadIdx = 0;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
UCSRB &= ~(1 << UDRIE);
|
disableDataRegisterEmptyInterrupt();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -5,28 +5,12 @@
|
|||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
|
|
||||||
#define UART_CMD_BUF_SIZE 4
|
|
||||||
#define UART_CMD_CYCLES 10
|
|
||||||
|
|
||||||
typedef struct uartdrvCmdBuf_s {
|
#define UART_TX_BUFFER_SIZE 256
|
||||||
uint8_t idx;
|
|
||||||
uint8_t cmdStart;
|
|
||||||
uint8_t cmdDelay;
|
|
||||||
uint8_t cmdReady;
|
|
||||||
uint8_t cmd;
|
|
||||||
uint8_t buf[UART_CMD_BUF_SIZE];
|
|
||||||
} uartdrvCmdBuf_t;
|
|
||||||
|
|
||||||
|
|
||||||
extern void uartInitCallback();
|
|
||||||
extern void uartWriteCallback(uint8_t o);
|
|
||||||
|
|
||||||
int uartdrvPutchar(char c, FILE *stream);
|
|
||||||
void uartdrvInit();
|
void uartdrvInit();
|
||||||
|
int uartdrvPutchar(char c, FILE *stream);
|
||||||
void uartdrvWrite(uint8_t o);
|
void uartdrvWrite(uint8_t o);
|
||||||
|
|
||||||
void uartdrvCmdCycle();
|
|
||||||
|
|
||||||
void uartdrvCmdReceived();
|
|
||||||
|
|
||||||
#endif /* UARTDRV_H_ */
|
#endif /* UARTDRV_H_ */
|
||||||
|
85
src/validLed.c
Normal file
85
src/validLed.c
Normal file
@ -0,0 +1,85 @@
|
|||||||
|
#include <stdint.h>
|
||||||
|
#include <avr/io.h>
|
||||||
|
|
||||||
|
#include "clock.h"
|
||||||
|
|
||||||
|
|
||||||
|
#define VALID_LED_REG_DIR DDRB
|
||||||
|
#define VALID_LED_REG PORTB
|
||||||
|
|
||||||
|
#define VALID_LED PB0
|
||||||
|
|
||||||
|
#define DARK_SWITCH_REG_DIR DDRD
|
||||||
|
#define DARK_SWITCH_OUT_REG PORTD
|
||||||
|
#define DARK_SWITCH_IN_REG PIND
|
||||||
|
|
||||||
|
#define DARK_SWITCH PD7
|
||||||
|
|
||||||
|
|
||||||
|
uint8_t validLedStatus = 0;
|
||||||
|
|
||||||
|
|
||||||
|
void validLedInit() {
|
||||||
|
// validLed
|
||||||
|
VALID_LED_REG_DIR |= (1 << VALID_LED);
|
||||||
|
|
||||||
|
// dark switch
|
||||||
|
DARK_SWITCH_REG_DIR &= ~(1 << DARK_SWITCH);
|
||||||
|
// pull-up on
|
||||||
|
DARK_SWITCH_OUT_REG |= (1 << DARK_SWITCH);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void validLedSetStatus(uint8_t x) {
|
||||||
|
validLedStatus = x;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t isNotDark() {
|
||||||
|
return DARK_SWITCH_IN_REG & (1 << DARK_SWITCH);
|
||||||
|
}
|
||||||
|
|
||||||
|
void validLedEnable() {
|
||||||
|
VALID_LED_REG |= (1 << VALID_LED);
|
||||||
|
}
|
||||||
|
|
||||||
|
void validLedDisable() {
|
||||||
|
VALID_LED_REG &= ~(1 << VALID_LED);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void validLedEngine() {
|
||||||
|
static uint8_t ledToggle = 0;
|
||||||
|
|
||||||
|
|
||||||
|
if (clockNextBlink()) {
|
||||||
|
uint8_t light = isNotDark();
|
||||||
|
|
||||||
|
switch (validLedStatus) {
|
||||||
|
case 0:
|
||||||
|
validLedDisable();
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
if (ledToggle != 0) {
|
||||||
|
ledToggle = 0;
|
||||||
|
validLedDisable();
|
||||||
|
} else {
|
||||||
|
ledToggle = 1;
|
||||||
|
if (light != 0) {
|
||||||
|
validLedEnable();
|
||||||
|
} else {
|
||||||
|
validLedDisable();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
if (light != 0) {
|
||||||
|
validLedEnable();
|
||||||
|
} else {
|
||||||
|
validLedDisable();
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
13
src/validLed.h
Normal file
13
src/validLed.h
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
#ifndef VALIDLED_H_
|
||||||
|
#define VALIDLED_H_
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void validLedInit();
|
||||||
|
void validLedEngine();
|
||||||
|
void validLedSetStatus(uint8_t x);
|
||||||
|
|
||||||
|
void validLedEnable();
|
||||||
|
void validLedDisable();
|
||||||
|
|
||||||
|
#endif /* VALIDLED_H_ */
|
Loading…
x
Reference in New Issue
Block a user