diff options
Diffstat (limited to 'src/inc/int')
| -rwxr-xr-x | src/inc/int/dcf77/clock.c | 157 | ||||
| -rwxr-xr-x | src/inc/int/dcf77/clock.h | 98 |
2 files changed, 255 insertions, 0 deletions
diff --git a/src/inc/int/dcf77/clock.c b/src/inc/int/dcf77/clock.c new file mode 100755 index 0000000..75f33fe --- /dev/null +++ b/src/inc/int/dcf77/clock.c | |||
| @@ -0,0 +1,157 @@ | |||
| 1 | #include "clock.h" | ||
| 2 | |||
| 3 | |||
| 4 | // returns -1 on error | ||
| 5 | unsigned char getBits(const DCF start, const char len, const DCF pbit) | ||
| 6 | { | ||
| 7 | static const unsigned char mult[] = {1, 2, 4, 8, 10, 20 ,40 ,80}; | ||
| 8 | /// unsigned char p = 1; //parity | ||
| 9 | unsigned char r = 0; // retval | ||
| 10 | unsigned char i; | ||
| 11 | for(i=0; i<len; i++) | ||
| 12 | { | ||
| 13 | r += dcf77[start+i].bit * mult[i]; | ||
| 14 | /// if(dcf77[start+i].bit) | ||
| 15 | /// p ^= 1; | ||
| 16 | } | ||
| 17 | |||
| 18 | // 1110011 | ||
| 19 | // 001000 | ||
| 20 | |||
| 21 | // 8 | ||
| 22 | // 72 | ||
| 23 | |||
| 24 | /// if((pbit != DCF_FIRST) && (dcf77[pbit].bit != p)) | ||
| 25 | /// return -1; | ||
| 26 | /// else | ||
| 27 | return r; | ||
| 28 | } | ||
| 29 | |||
| 30 | void set_dcf_value() | ||
| 31 | { | ||
| 32 | // check for parity | ||
| 33 | /// if | ||
| 34 | /// ( | ||
| 35 | /// (dcf77[DCF_FIRST].bit != 0 ) | | ||
| 36 | /// (dcf77[DCF_START].bit != 1 ) | | ||
| 37 | /// (getBits(DCF_MIN, 7, DCF_MINP) == -1) | | ||
| 38 | /// (getBits(DCF_MIN, 7, DCF_START) > 59) | | ||
| 39 | /// (getBits(DCF_HOUR, 6, DCF_HOURP) == -1) | ||
| 40 | /// ) return; | ||
| 41 | |||
| 42 | // set new time | ||
| 43 | t_current.m = (getBits(DCF_MIN, 7, DCF_START)) - 1; | ||
| 44 | t_current.h = (getBits(DCF_HOUR, 6, DCF_START)); | ||
| 45 | t_current.dd = (getBits(DCF_DAY, 6, DCF_START)); | ||
| 46 | t_current.wd = (getBits(DCF_WEEKDAY, 3, DCF_START)); | ||
| 47 | t_current.mm = (getBits(DCF_MONTH, 5, DCF_START)); | ||
| 48 | t_current.yy = (getBits(DCF_YEAR, 8, DCF_START)); | ||
| 49 | } | ||
| 50 | |||
| 51 | // 7372800/a=10000 | ||
| 52 | // 115200 / a * x = 10000 | ||
| 53 | // 7372800/8/150 | ||
| 54 | ISR(TIMER0_COMP_vect) // called 10000 times per second (12000000/8/150) | ||
| 55 | { | ||
| 56 | //cli(); | ||
| 57 | // F_CPU / PRESCALER / (OCR0 + 1) | ||
| 58 | if(++t_current.us >= 10) // one u-second | ||
| 59 | { | ||
| 60 | t_current.us = 0; // restart | ||
| 61 | // interval length of dcf77 can be greater than 1000 ms... count it! | ||
| 62 | ++interval; | ||
| 63 | |||
| 64 | /* | ||
| 65 | cli(); | ||
| 66 | if(t_current.ms <= 500) | ||
| 67 | { OCR1A = 50 + (200 - (t_current.ms / 3)); } | ||
| 68 | else | ||
| 69 | { OCR1A = 50 + (200 - ((1000 - t_current.ms) / 3)); } | ||
| 70 | sei(); | ||
| 71 | */ | ||
| 72 | |||
| 73 | if(++t_current.ms >= 1000) // one second | ||
| 74 | { | ||
| 75 | t_current.ms = 0; // restart | ||
| 76 | if(++t_current.s > 59) // one minute | ||
| 77 | { | ||
| 78 | t_current.s = 0; // restart | ||
| 79 | if(++t_current.m > 59) // one hour | ||
| 80 | { | ||
| 81 | t_current.m = 0; // restart | ||
| 82 | if(++t_current.h > 23) // one day | ||
| 83 | { | ||
| 84 | t_current.h = 0; // restart | ||
| 85 | t_current.dd++; | ||
| 86 | } | ||
| 87 | } | ||
| 88 | } | ||
| 89 | } | ||
| 90 | } | ||
| 91 | //sei(); | ||
| 92 | } | ||
| 93 | |||
| 94 | ISR(INT0_vect) | ||
| 95 | { | ||
| 96 | /// stdout_put_int(interval, uart_putc); | ||
| 97 | /// stdout_put_string("INT0 call\n", uart_putc); | ||
| 98 | cli(); | ||
| 99 | if(INT0_CONTROL == INT0_RISING_EDGE) | ||
| 100 | { | ||
| 101 | if(interval > 1000 && interval < 2000) // 59th second - no rising edge at the beginning | ||
| 102 | { | ||
| 103 | /// if(dcf77_bit == 59) // check if every bit has been transfered | ||
| 104 | set_dcf_value(); // completely received- apply new time data | ||
| 105 | |||
| 106 | // 59th second: synchronize with receiver... | ||
| 107 | dcf77_bit = 0; | ||
| 108 | TCNT0 = 0; | ||
| 109 | t_current.s = 0; | ||
| 110 | t_current.ms = 0; | ||
| 111 | t_current.us = 0; | ||
| 112 | } | ||
| 113 | INT0_CONTROL = INT0_FALLING_EDGE; | ||
| 114 | } | ||
| 115 | else // INT0_FALLING_EDGE | ||
| 116 | { | ||
| 117 | dcf77[dcf77_bit++].bit = interval >= 200 ? 1 : 0; | ||
| 118 | lastinterval = interval; | ||
| 119 | |||
| 120 | INT0_CONTROL = INT0_RISING_EDGE; | ||
| 121 | } | ||
| 122 | |||
| 123 | interval = 0; // reset interval to count next interval | ||
| 124 | sei(); | ||
| 125 | } | ||
| 126 | |||
| 127 | |||
| 128 | void timer_init() | ||
| 129 | { | ||
| 130 | // 7372800/8 | ||
| 131 | DDRD &= ~((1<<PD2) | (1<<PD3)); // make INT0 and INT1 input-pins | ||
| 132 | |||
| 133 | // Prescaler... | ||
| 134 | TCCR0 = (0<<CS02) | (1<<CS01) | (0<<CS00) | (1<<WGM01); | ||
| 135 | // output compare... | ||
| 136 | OCR0 = 149; | ||
| 137 | //OCR0 = 152 - 1; | ||
| 138 | //TCCR0 |= (0<<WGM01) | (1<<WGM01); | ||
| 139 | |||
| 140 | // ICNC1 (Input Capture Noise Canceler (4 CKs) Timer/Counter 1 | ||
| 141 | // ICES1 (Input Capture Edge Select Timer/Counter 1) - 1:increasing 0:falling | ||
| 142 | // CSx: set prescaler (010 means 8) | ||
| 143 | /// TCCR1B = (1<<ICNC1) | (1<<ICES1) | (0<<CS12) | (1<<CS11) | (0<<CS10); | ||
| 144 | // OCIE0: Output Compare Match Interrupt Enable | ||
| 145 | // TICIE: Timer/Counter Input Capture Interrupt Enable | ||
| 146 | TIMSK |= (1<<OCIE0); | ||
| 147 | |||
| 148 | // interrupts_init... | ||
| 149 | // General Interrupt Mask Register (enables interrupts) | ||
| 150 | //GIMSK |= (1<<INT0); | ||
| 151 | GICR |= (1<<INT0); | ||
| 152 | // MCU Control Register (controls CPU-behaviours like interrupts & sleepmode) | ||
| 153 | //MCUCR |= (0<<ISC01) | (1<<ISC00); // any logical change generates interrupt | ||
| 154 | INT0_CONTROL = INT0_RISING_EDGE; // going to toggle int0-behaviour | ||
| 155 | /// loworhigh.bit = 0; | ||
| 156 | } | ||
| 157 | |||
diff --git a/src/inc/int/dcf77/clock.h b/src/inc/int/dcf77/clock.h new file mode 100755 index 0000000..c7f75c7 --- /dev/null +++ b/src/inc/int/dcf77/clock.h | |||
| @@ -0,0 +1,98 @@ | |||
| 1 | #ifndef CLOCK_H | ||
| 2 | #define CLOCK_H | ||
| 3 | /* this dcf77-module relies on a accuarate clock (cristal) for receiving | ||
| 4 | * the dcf-signal. therefor the clock is going to work as expected, | ||
| 5 | * even with no dcf77-signal available. | ||
| 6 | * receivement is automatically turned on, if the avr is connected to the | ||
| 7 | * signal via INT0. if there is no signal the clock will not be set (K.I.S.S.) | ||
| 8 | * | ||
| 9 | */ | ||
| 10 | #include <stdint.h> | ||
| 11 | #include <avr/io.h> | ||
| 12 | #include <avr/interrupt.h> | ||
| 13 | #include <limits.h> | ||
| 14 | |||
| 15 | /// #include "../stdout.h" | ||
| 16 | /// #include "../display/display.h" | ||
| 17 | /// #include "../uart/uart.h" | ||
| 18 | |||
| 19 | #define INT0_CONTROL MCUCR | ||
| 20 | #define INT0_FALLING_EDGE 0x02 | ||
| 21 | #define INT0_RISING_EDGE 0x03 | ||
| 22 | |||
| 23 | |||
| 24 | |||
| 25 | typedef struct | ||
| 26 | { | ||
| 27 | volatile unsigned char bit : 1; | ||
| 28 | } Bit; | ||
| 29 | |||
| 30 | typedef struct | ||
| 31 | { | ||
| 32 | unsigned char h ; // hour | ||
| 33 | unsigned char m ; // minute | ||
| 34 | unsigned char s ; // second | ||
| 35 | unsigned char dd; // day | ||
| 36 | unsigned char wd; // weekday | ||
| 37 | unsigned char mm; // month | ||
| 38 | unsigned char yy; // year | ||
| 39 | unsigned char us; // 10th second | ||
| 40 | unsigned int ms; // milli second | ||
| 41 | } Time; | ||
| 42 | |||
| 43 | typedef enum | ||
| 44 | { | ||
| 45 | DCF_FIRST = 0, // start of a new minute (note: always 0) | ||
| 46 | DCF_WEATHER = 14, // proprietary :-( | ||
| 47 | DCF_ANTENNA = 15, // 0: normal, 1: replacement | ||
| 48 | DCF_DST = 16, // daylight saving time: this hour new time... | ||
| 49 | DCF_MEZ = 17, // 'summer-time' | ||
| 50 | DCF_MESZ = 18, // 'winter-time' | ||
| 51 | DCF_DBLSEC = 19, // one extra second gonna be inserted | ||
| 52 | DCF_START = 20, // begin of time-info (note: always 1) | ||
| 53 | DCF_MIN = 21, // 7 bit | ||
| 54 | DCF_MINP = 28, // parity bit for minutes | ||
| 55 | DCF_HOUR = 29, // 6 bit | ||
| 56 | DCF_HOURP = 35, // parity bit for hours | ||
| 57 | DCF_DAY = 36, // 6 bit | ||
| 58 | DCF_WEEKDAY = 42, // 3 bit | ||
| 59 | DCF_MONTH = 45, // 5 bit | ||
| 60 | DCF_YEAR = 50, // 8 bit | ||
| 61 | DCF_DATEP = 58 // parity bit for date | ||
| 62 | } DCF; | ||
| 63 | |||
| 64 | /* | ||
| 65 | typedef struct | ||
| 66 | { | ||
| 67 | Bit useless[14]; | ||
| 68 | Bit antenna; | ||
| 69 | Bit dst; | ||
| 70 | Bit mez; | ||
| 71 | Bit mesz; | ||
| 72 | Bit dblsec; | ||
| 73 | Bit start; // < always 1 - use for verification | ||
| 74 | unsigned char min : 7; | ||
| 75 | Bit min_p; // < minutes parity | ||
| 76 | unsigned char hour : 6; | ||
| 77 | Bit hour_p; // < hours parity | ||
| 78 | unsigned char day : 6; // day of month | ||
| 79 | unsigned char dow : 3; // day of week (1=monday) | ||
| 80 | unsigned char month : 5; // month of year | ||
| 81 | unsigned char year : 8; // year | ||
| 82 | Bit date_p; // parity of date | ||
| 83 | } DCF_Signal; | ||
| 84 | */ | ||
| 85 | |||
| 86 | |||
| 87 | volatile Bit dcf77[60]; | ||
| 88 | volatile unsigned char dcf77_bit; | ||
| 89 | volatile Time t_current; | ||
| 90 | volatile unsigned int interval; | ||
| 91 | volatile unsigned int lastinterval; | ||
| 92 | |||
| 93 | /// void getBits(volatile unsigned char* target, const DCF start, const char len, const DCF parity); | ||
| 94 | /// void set_dcf_value(); | ||
| 95 | void timer_init(); | ||
| 96 | /// void interrupts_init(); | ||
| 97 | |||
| 98 | #endif | ||
