-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathdcf77_comm.asm
228 lines (172 loc) · 3.77 KB
/
dcf77_comm.asm
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
; Shifts in the lowest bit in r16 into the sample set.
add_sample:
; Save the parameter register.
push r16
; Shift in the lowest bit from the parameter into the lowest position of r20.
lsl r20
andi r16, 0x01
or r20, r16
; restore the parameter register.
pop r16
ret
; Returns the mean state of the last 8 samples in r16.
get_mean_state:
push r17
push r19
push r20
; mov r16, r20
; andi r16, 0x01
; rjmp exit_get_mean_state
; r17 will count ones.
clr r17
get_mean_state_count_loop:
sbrc r20, 0
inc r17
; Move down the next bit.
lsr r20
; Bail out if r20 i 0, then there are no more ones to count.
brne get_mean_state_count_loop
clr r16
; If r17 < 5, keep r16 as 0 and exit.
cpi r17, 4
brlo exit_get_mean_state
; If r17 >= 5, set r16 = 1 and exit.
ldi r16, 1
exit_get_mean_state:
pop r20
pop r19
pop r17
ret
; Function that adds a sample to the sample register and checks if this is a
; rising or falling flank. Returns NO_FLANK, RISING_FLANK or FALLING_FLANK in
; r16.
;
; Parameters:
; r16 - The sample bit in LSB.
; Returns:
; r16 - Which flank it was, either NO_FLANK, RISING_FLANK or
; FALLING_FLANK.
;
process_sample:
push r18
push r16
rcall get_mean_state
; Save state prior to sample, shifted left one step, in r18.
mov r18, r16
lsl r18
; Retrieve the new sample to add into r16 again.
pop r16
rcall add_sample
rcall get_mean_state
; After oring together the previous state, shifted one step left, with the
; new state, we will get 10 for falling flank, 01 for rising and 00 or 11 for
; no change. These correspond to the flank constants we declared above.
or r16, r18
cpi r16, NO_FLANK
breq low_low
cpi r16, RISING_FLANK
breq low_high
cpi r16, FALLING_FLANK
breq high_low
rjmp high_high
high_high:
; If r16 contains 11 binary, it indicates no flank. Set to NO_FLANK.
ldi r16, NO_FLANK
lds r18, high_time
inc r18
sts high_time, r18
clr r18
sts low_time, r18
rjmp exit_process_sample
low_high:
ldi r16, RISING_FLANK
rjmp exit_process_sample
low_low:
ldi r16, NO_FLANK
lds r18, low_time
inc r18
sts low_time, r18
clr r18
sts high_time, r18
rjmp exit_process_sample
high_low:
ldi r16, FALLING_FLANK
exit_process_sample:
pop r18
ret
counter_overflow:
push r16
in r16, SREG
push r16
;ldi r18, 1
; Get the current bit from the DCF77 circuit.
in r16, PIND
andi r16, 0x01
rcall process_sample
cpi r16, NO_FLANK
; Exit without touching the timers.
breq exit_counter_overflow
; Is this a rising flank?
cpi r16, RISING_FLANK
breq handle_rising_flank
rcall handle_falling_flank
rjmp exit_counter_overflow
handle_rising_flank:
; See if this is synch.
lds r16, low_time
cpi r16, 85
brlo no_synch
; Synch found.
ldi r16, 0xff
out PORTB, r16
no_synch:
clr r16
sts low_time, r16
ldi r16, 1
sts high_time, r16
exit_counter_overflow:
; Cleanup.
; sbrc r20, 0
; rcall clear_low_time
pop r16
out SREG, r16
pop r16
reti
; Function that resets low time and figures out if we got a logical one or zero
; from the DCF77-receiver.
;
; Parameters:
; -
; Return:
; -
handle_falling_flank:
push r16
; See how long the signal was high. More than 100 ms, set data out to 1,
; otherwise, set to 0.
lds r16, high_time
; Output the number of ticks the pulse has been high.
; out PORTB, r16
; rjmp exit_handle_falling_flank
cpi r16, 9
brsh handle_falling_flank_output_one
handle_falling_flank_output_zero:
ldi r16, 2
out PORTB, r16
rjmp exit_handle_falling_flank
handle_falling_flank_output_one:
ldi r16, 1
out PORTB, r16
rjmp exit_handle_falling_flank
exit_handle_falling_flank:
clr r16
sts high_time, r16
ldi r16, 1
sts low_time, r16
pop r16
ret
clear_low_time:
push r16
clr r16
sts low_time, r16
pop r16
ret