aboutsummaryrefslogtreecommitdiff
path: root/software
diff options
context:
space:
mode:
Diffstat (limited to 'software')
-rw-r--r--software/.clang-format5
-rw-r--r--software/.ycm_extra_conf.py26
-rw-r--r--software/Makefile17
-rwxr-xr-xsoftware/inc/int/dcf77.c123
-rwxr-xr-xsoftware/inc/int/dcf77.h68
-rw-r--r--software/main.c129
6 files changed, 368 insertions, 0 deletions
diff --git a/software/.clang-format b/software/.clang-format
new file mode 100644
index 0000000..b8ecd2e
--- /dev/null
+++ b/software/.clang-format
@@ -0,0 +1,5 @@
1BasedOnStyle: Webkit
2IndentWidth: 2
3BreakBeforeBraces: Allman
4AllowShortIfStatementsOnASingleLine: false
5ColumnLimit: 120
diff --git a/software/.ycm_extra_conf.py b/software/.ycm_extra_conf.py
new file mode 100644
index 0000000..42834fb
--- /dev/null
+++ b/software/.ycm_extra_conf.py
@@ -0,0 +1,26 @@
1import os
2import ycm_core
3
4def FlagsForFile( filename, **kwargs ):
5 return {
6 'flags': [
7 '-Wall',
8 '-Wextra',
9 '-Werror',
10 '-Wno-long-long',
11 '-Wno-variadic-macros',
12 '-fexceptions',
13 '-ferror-limit=10000',
14 '-DNDEBUG',
15 '-std=c99',
16 '-x', 'c',
17 '-D_GNU_SOURCE',
18 '-D__AVR_ATtiny85__',
19 '-D__AVR__',
20 '-I.',
21 '-I', '/usr/avr/include/'
22 ],
23 'do_cache': True,
24 }
25
26# vim:set et sw=2 ts=2 tw=120:
diff --git a/software/Makefile b/software/Makefile
new file mode 100644
index 0000000..e81f5a1
--- /dev/null
+++ b/software/Makefile
@@ -0,0 +1,17 @@
1FLAGS=-Wall -O5 -Werror
2FLAGS+=-mmcu=attiny85
3FLAGS+=-D__AVR_ATtiny85__=1
4# FLAGS+=-DF_CPU=120000UL
5# FLAGS+=-DF_CPU=960000UL
6FLAGS+=-DF_CPU=800000UL
7FLAGS+=-I inc/int/
8FLAGS+=-I/usr/lib/gcc/avr/6.3.0/plugin/include/
9FLAGS+=-I/usr/avr/include
10
11program: all
12 avrdude -V -B100 -p t85 -c avrisp2 -P usb -U flash:w:main.hex
13
14all:
15 avr-gcc $(FLAGS) -o main.elf main.c inc/int/dcf77.c
16 avr-objcopy -j .text -j .data -O ihex main.elf main.hex
17
diff --git a/software/inc/int/dcf77.c b/software/inc/int/dcf77.c
new file mode 100755
index 0000000..31f1663
--- /dev/null
+++ b/software/inc/int/dcf77.c
@@ -0,0 +1,123 @@
1// vim:set et sw=2 ts=2 tw=120:
2#include "dcf77.h"
3
4// 7372800/a=10000
5// 115200 / a * x = 10000
6// 7372800/8/150
7
8// returns -1 on error
9unsigned char getBits(const DCF start, const char len)
10{
11 static const unsigned char mult[] = {1, 2, 4, 8, 10, 20, 40, 80};
12 /// unsigned char p = 1; //parity
13 unsigned char r = 0; // retval
14 unsigned char i;
15 for(i=0; i<len; i++)
16 r += dcf77[start+i].bit * mult[i];
17 /// if(dcf77[start+i].bit)
18 /// p ^= 1;
19 return r;
20}
21
22// interrupt service routine (ISR) for timer 0 A compare match
23ISR(TIMER0_COMPB_vect)
24{
25
26}
27
28// ISR(TIMER0A_COMP_vect)
29ISR(TIMER0_COMPA_vect)
30{
31 interval++;
32 if (++t_current.ms >= 1000) // one second
33 {
34 t_current.ms = 0; // restart
35 if (++t_current.s > 59) // one minute
36 {
37 t_current.s = 0; // restart
38 if (++t_current.m > 59) // one hour
39 {
40 t_current.m = 0; // restart
41 if (++t_current.h > 23) // one day
42 {
43 t_current.h = 0; // restart
44 t_current.dd++;
45 }
46 }
47 }
48 }
49}
50
51ISR(INT0_vect)
52{
53}
54
55ISR(PCINT0_vect)
56{
57 // if(INT0_CONTROL == INT0_RISING_EDGE)
58 // if(MCUCR & (1<<ISC00))
59 // {
60 if (interval > 1000 && interval < 2000) // 59th second - no rising edge at the beginning
61 {
62 if(dcf77_bit == 59) // check if every bit has been transfered
63 {
64 t_current.m = getBits(DCF_MIN, 7);
65 t_current.h = getBits(DCF_HOUR, 6);
66 t_current.dd = getBits(DCF_DAY, 6);
67 t_current.wd = getBits(DCF_WEEKDAY, 3);
68 t_current.mm = getBits(DCF_MONTH, 5);
69 t_current.yy = getBits(DCF_YEAR, 8);
70 }
71
72 // 59th second: synchronize with receiver...
73 dcf77_bit = 0;
74 t_current.s = 0;
75 t_current.ms = 0;
76
77 // falling edge causes interrupt...
78 // INT0_CONTROL = INT0_FALLING_EDGE;
79 }
80 else // INT0_FALLING_EDGE
81 {
82 if(interval > 50 && interval < 150)
83 dcf77[dcf77_bit++].bit = 0;
84 else if(interval > 150 && interval < 250)
85 dcf77[dcf77_bit++].bit = 1;
86
87 // rising edge causes interrupt...
88 // INT0_CONTROL = INT0_RISING_EDGE;
89 }
90
91 TCNT0 = 0;
92 interval = 0;
93}
94
95/*
96void timer_init()
97{
98 // 7372800/8
99 // >>>>>> DDRD &= ~((1<<PD2) | (1<<PD3)); // make INT0 and INT1 input-pins
100
101 // Prescaler...
102 // output compare...
103
104 //OCR0 = 152 - 1;
105 //TCCR0 |= (0<<WGM01) | (1<<WGM01);
106
107 // ICNC1 (Input Capture Noise Canceler (4 CKs) Timer/Counter 1
108 // ICES1 (Input Capture Edge Select Timer/Counter 1) - 1:increasing 0:falling
109 // CSx: set prescaler (010 means 8)
110 /// TCCR1B = (1<<ICNC1) | (1<<ICES1) | (0<<CS12) | (1<<CS11) | (0<<CS10);
111 // OCIE0: Output Compare Match Interrupt Enable
112 // TICIE: Timer/Counter Input Capture Interrupt Enable
113
114 // interrupts_init...
115 // General Interrupt Mask Register (enables interrupts)
116 GIMSK |= (1<<INT0);
117 // GICR |= (1<<INT0);
118 // MCU Control Register (controls CPU-behaviours like interrupts & sleepmode)
119 MCUCR |= (1<<ISC01) | (1<<ISC00); // any logical change generates interrupt
120 INT0_CONTROL = INT0_RISING_EDGE; // going to toggle int0-behaviour
121 /// loworhigh.bit = 0;
122}
123*/
diff --git a/software/inc/int/dcf77.h b/software/inc/int/dcf77.h
new file mode 100755
index 0000000..2d79cdd
--- /dev/null
+++ b/software/inc/int/dcf77.h
@@ -0,0 +1,68 @@
1#ifndef CLOCK_H
2#define CLOCK_H
3 /* this dcf77-module relies on a accuarate clock (crystal) 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 <avr/io.h>
11 #include <avr/interrupt.h>
12 #include <stdint.h>
13
14 #define INT0_CONTROL MCUCR
15 // #define INT0_FALLING_EDGE 0x02
16 // #define INT0_RISING_EDGE 0x03
17 #define INT0_FALLING_EDGE (1<<ISC01)
18 #define INT0_RISING_EDGE (1<<ISC01 | 1<<ISC00)
19 #define INT0_EDGE_ANY (1<<ISC00)
20
21 typedef struct
22 {
23 volatile unsigned char bit : 1;
24 } Bit;
25
26 typedef struct
27 {
28 uint16_t h; // hour
29 uint16_t m; // minute
30 uint16_t s; // second
31 uint16_t ms; // milli second
32 uint8_t yy; // year
33 uint8_t mm; // month
34 uint8_t dd; // day
35 uint8_t wd; // weekday
36 } Time;
37
38 typedef enum
39 {
40 DCF_FIRST = 0, // start of a new minute (note: always 0)
41 DCF_WEATHER = 14, // proprietary :-(
42 DCF_ANTENNA = 15, // 0: normal, 1: replacement
43 DCF_DST = 16, // daylight saving time: this hour new time...
44 DCF_MEZ = 17, // 'summer-time'
45 DCF_MESZ = 18, // 'winter-time'
46 DCF_DBLSEC = 19, // one extra second gonna be inserted
47 DCF_START = 20, // begin of time-info (note: always 1)
48 DCF_MIN = 21, // 7 bit
49 DCF_MINP = 28, // parity bit for minutes
50 DCF_HOUR = 29, // 6 bit
51 DCF_HOURP = 35, // parity bit for hours
52 DCF_DAY = 36, // 6 bit
53 DCF_WEEKDAY = 42, // 3 bit
54 DCF_MONTH = 45, // 5 bit
55 DCF_YEAR = 50, // 8 bit
56 DCF_DATEP = 58 // parity bit for date
57 } DCF;
58
59 volatile Bit dcf77[60];
60 volatile uint8_t dcf77_bit;
61 volatile Time t_current;
62 volatile uint16_t interval;
63
64 /// void getBits(volatile unsigned char* target, const DCF start, const char len, const DCF parity);
65 /// void set_dcf_value();
66 /// void interrupts_init();
67
68#endif
diff --git a/software/main.c b/software/main.c
new file mode 100644
index 0000000..9e2cb5d
--- /dev/null
+++ b/software/main.c
@@ -0,0 +1,129 @@
1// vim:set et sw=2 ts=2 tw=120:
2#include <stdint.h>
3#include <avr/io.h>
4#include <avr/interrupt.h>
5#include <util/delay.h>
6
7#include "inc/int/dcf77.h"
8
9#define CTC_MATCH_OVERFLOW ((F_CPU / 1000) / 8)
10
11// set bit
12static inline void BIT_SET(volatile uint8_t* target, uint8_t bit) __attribute__((always_inline));
13static inline void BIT_SET(volatile uint8_t* target, uint8_t bit) { *target |= (1 << bit); };
14
15// set clear
16static inline void BIT_CLEAR(volatile uint8_t* target, uint8_t bit) __attribute__((always_inline));
17static inline void BIT_CLEAR(volatile uint8_t* target, uint8_t bit) { *target &= ~(1 << bit); };
18
19
20/*
21 *
22 * PB2 : connected to ShiftClock on Port 11
23 * PB3 : connected to MemoryClock on Port 12 (shows content of memory)
24 * PB4 (PIN3) : connected to SERIAL_IN on pin 14
25 *
26 */
27
28void print_data(uint16_t data)
29{
30 BIT_CLEAR(&PORTB, PB3);
31 for (char i = 0; i < 16; i++)
32 {
33 data & 0x1 << i
34 ? BIT_SET(&PORTB, PB4)
35 : BIT_CLEAR(&PORTB, PB4);
36 // pulse sck...
37 BIT_SET(&PORTB, PB2);
38 BIT_CLEAR(&PORTB, PB2);
39 }
40 BIT_SET(&PORTB, PB3);
41}
42
43int main(void)
44{
45
46 BIT_CLEAR(&PORTB, PB5);
47 _delay_ms(20);
48 BIT_SET(&PORTB, PB5);
49 BIT_CLEAR(&PORTB, PB5);
50 _delay_ms(20);
51 BIT_SET(&PORTB, PB5);
52
53
54
55 // make all pins output pins...
56 // DDRB = 0xFF;
57 DDRB = 0b11111110;
58 PORTB |= 1<<PB0; // activate pullup
59 PORTB |= 1<<PB1; // activate receiver
60 PORTB &= ~(1<<PB1);
61
62 // DDRB &= ~(1 << PB0); // makes PB0 an input pin (INT0)
63 // PORTB |= (1 << PB0); // activate input resistor
64
65 // activate dcf77-receiver...
66 // PORTB &= (1 << PB1); // sets PB1 to low
67 // _delay_ms(20);
68 // PORTB &= ~(1 << PB1); // sets PB1 to low
69
70
71 cli();
72
73 GIMSK |= (1<<INT0); // External Interrupt Request 0 Enable
74 GIMSK |= (1<<PCIE); // Pin Change Interrupt Enable
75
76 // MCU Control Register (controls CPU-behaviours like interrupts & sleepmode)
77 // MCUCR |= ~(1<<ISC01) | (1<<ISC00); // any logical change generates interrupt
78 PCMSK |= (1<<PCINT0);
79 // INT0_CONTROL = INT0_RISING_EDGE; // going to toggle int0-behaviour
80
81 TCCR0A |= (1 << WGM01); // CTC mode
82 // TCCR0B |= (1 << CS00);
83 TCCR0B |= (1 << CS01); // Prescaler 8
84 // TCCR0B |= (1 << CS02); // Prescaler 256
85 // OCR0A |= (1 << WGM01); // CTC mode
86
87 // OCR0A = 149;
88 OCR0A = 125;
89 // OCR0A = CTC_MATCH_OVERFLOW;
90 TIMSK |= (1 << OCIE0A); // if you want interrupt
91
92 sei();
93
94 for(uint8_t i=0; i<16; i++)
95 {
96 print_data(3<<i);
97 _delay_ms(5);
98 }
99
100 while (1)
101 {
102 //print_data(lastinterval<<1 | (PINB & PB0));
103
104 print_data(
105 (uint16_t) 0
106 | ((uint16_t) (PINB & 0x0001))<<15
107 | t_current.h<<8
108 | t_current.m
109 );
110 // print_data(interval | ((PINB & PB0) == 1 ? 2 : 0));
111 //print_data(PINB);
112 }
113 return 0;
114}
115
116
117/*
118for(uint16_t hour=0; hour<24; hour++)
119 for(uint16_t minute=0; minute<60; minute++)
120 for (uint16_t second = 1; second < 60; second++)
121 {
122 // clear register (reset)
123 // print_data(hour<< 12 | minute << 6 | second);
124 // print_data((int64_t) dcf77);
125 // dcf77[dcf77_bit].bit == 1
126 // ? print_data(0xFFFF)
127 // : print_data(0x0000);
128 }A
129*/
..