Compare commits

...

16 Commits

Author SHA1 Message Date
hg
ee4e7b7c5d Angle re-measured 2013-02-10 00:22:53 +01:00
Wolfgang Hottgenroth
5f7c7fbe41 new 2013-02-09 13:23:36 +01:00
wolfgang
cea727198a zeroing 2013-02-04 22:47:02 +01:00
wolfgang
16f109fb80 stepper debug 2013-01-31 23:00:32 +01:00
wolfgang
07febefc74 long 2013-01-31 18:12:19 +01:00
wolfgang
d33d8ffe4a change stepper timing 2013-01-30 07:46:03 +01:00
wolfgang
7fa9715d41 fix second overrun, minute direction, optime display 2013-01-29 18:40:35 +01:00
hg
d997d21ac1 beautifying 2013-01-29 16:10:24 +01:00
hg
fb4b9675ce beautifying 2013-01-29 16:09:04 +01:00
hg
cfbf2d9424 beautifying 2013-01-29 16:08:34 +01:00
hg
00638e3edc beautifying 2013-01-29 16:07:14 +01:00
hg
7654302a94 beautifying 2013-01-29 16:06:40 +01:00
hg
ea178ca5c4 refactoring 2013-01-29 14:42:31 +01:00
hg
b99473f1f2 refactoring 2013-01-29 14:38:59 +01:00
hg
314c6eba8d refactoring 2013-01-29 12:39:36 +01:00
wolfgang
6970336f53 Added tag WorkingBeforeRefactoring for changeset 2716b70f46c0 2013-01-29 12:14:28 +01:00
14 changed files with 4386 additions and 709 deletions

1
.hgtags Normal file
View File

@ -0,0 +1 @@
2716b70f46c080a1b9d189c5a4d649c661cad949 WorkingBeforeRefactoring

BIN
resources/DCFzzeit.pdf Normal file

Binary file not shown.

File diff suppressed because it is too large Load Diff

169
src/clock.c Normal file
View 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
View 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
View 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
View 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_ */

View File

@ -1,712 +1,52 @@
#include <stdint.h>
#include <avr/io.h>
#include <avr/interrupt.h>
#include <util/delay.h>
#include "dcf77.h"
#include "clock.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() {
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
DDRD |= (1 << PD5) | (1 << PD6);
// valid led
DDRB |= (1 << PB0);
TCCR0 = (1 << CS02) | (1 << CS00);
TIMSK |= (1 << TOIE0);
// position switches
DDRB &= ~(1 << PB1);
DDRB &= ~(1 << PB2);
PORTB |= (1 << PB1) | (1 << PB2);
uartdrvInit();
clockInit();
dcf77Init();
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();
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) {
if (tick != 0) {
tick = 0;
dcf77Engine();
uint16_t pulse = (((uint32_t) captValue) * 1000) / 15625;
uint16_t gap = (((uint32_t) gapValue) * 1000) / 15625;
stepperEngine();
if (gap > START_GAP_MIN) {
if (valid == 0) {
validCnt++;
valid = 1;
}
state = 0;
clock.second = 0;
}
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;
valid = 0;
}
validLedEngine();
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);
}
if (clockNextSecond()) {
clock_t clock = clockGetClock();
printf("Time: %02d:%02d:%02d %d %02d.%02d.%02d\n",
clock.year, clock.month, clock.day, clock.weekday,
clock.hour, clock.minute, clock.second);
}
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;
}
if (clockNextMinute()) {
opTime_t opTime = clockGetOpTime();
printf("**** OpTime: %d %02d:%02d:%02d\n", opTime.day, opTime.hour, opTime.minute, opTime.second);
}
}

351
src/stepper.c Normal file
View 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
View 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_ */

View File

@ -6,21 +6,28 @@
#define BUFFER_SIZE 256
volatile uint8_t buffer[BUFFER_SIZE+5];
volatile uint8_t buffer[UART_TX_BUFFER_SIZE+5];
volatile uint8_t bufferReadIdx = 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
DDRD |= (1 << PD1);
// transmitter enable
UCSRB = (1 << TXEN);
// 8 data bit, no parity, 1 stop bit
UCSRC = (1 << UCSZ1) | (1 << UCSZ0);
// 2400 Baud @ 16MHz
UBRRL = 0xa0;
UBRRH = 0x01;;
@ -30,16 +37,16 @@ void uartdrvInit() {
}
void uartdrvWrite(uint8_t o) {
// loop_until_bit_is_set(UCSRA, UDRE);
// UDR = o;
if (bufferWriteIdx == BUFFER_SIZE - 1) {
while (bufferReadIdx == BUFFER_SIZE);
if (bufferWriteIdx == UART_TX_BUFFER_SIZE - 1) {
while (bufferReadIdx == UART_TX_BUFFER_SIZE);
} else {
while (bufferReadIdx == bufferWriteIdx + 1);
}
buffer[bufferWriteIdx] = o;
bufferWriteIdx++;
UCSRB |= (1 << UDRIE);
enableDataRegisterEmptyInterrupt();
}
@ -55,10 +62,10 @@ ISR(USART_UDRE_vect) {
if (bufferReadIdx != bufferWriteIdx) {
UDR = buffer[bufferReadIdx];
bufferReadIdx++;
if (bufferReadIdx > BUFFER_SIZE) {
if (bufferReadIdx > UART_TX_BUFFER_SIZE) {
bufferReadIdx = 0;
}
} else {
UCSRB &= ~(1 << UDRIE);
disableDataRegisterEmptyInterrupt();
}
}

View File

@ -5,28 +5,12 @@
#include <stdio.h>
#define UART_CMD_BUF_SIZE 4
#define UART_CMD_CYCLES 10
typedef struct uartdrvCmdBuf_s {
uint8_t idx;
uint8_t cmdStart;
uint8_t cmdDelay;
uint8_t cmdReady;
uint8_t cmd;
uint8_t buf[UART_CMD_BUF_SIZE];
} uartdrvCmdBuf_t;
#define UART_TX_BUFFER_SIZE 256
extern void uartInitCallback();
extern void uartWriteCallback(uint8_t o);
int uartdrvPutchar(char c, FILE *stream);
void uartdrvInit();
int uartdrvPutchar(char c, FILE *stream);
void uartdrvWrite(uint8_t o);
void uartdrvCmdCycle();
void uartdrvCmdReceived();
#endif /* UARTDRV_H_ */

85
src/validLed.c Normal file
View 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
View 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_ */