-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathnec.inc
375 lines (299 loc) · 17.5 KB
/
nec.inc
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
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
;
; File : nec.inc (part of "Feron Light Advanced Control" project)
;
; Author : Sergey V. DUDANOV
; E-Mail : sergey.dudanov@gmail.com
; Git : https://github.com/dudanov/feron-light-advanced-control
; License: GPL v3 (https://www.gnu.org/licenses/gpl.txt)
; CUSTOM ADDRESS FOR SET HB-VALUE (AS COMMAND) WITH DIMMING
.equ NEC_HBDIM_ADDRESS = 0xB721
; CUSTOM ADDRESS FOR SET HB-VALUE (AS COMMAND) WITHOUT DIMMING
.equ NEC_HBSET_ADDRESS = 0xB781
; NATIVE ADDRESS [ USED NATIVE HB: A, B, D, E, F ]
.equ NEC_FERON_ADDRESS = 0xB7A0
; NATIVE IR COMMANDS
.equ NEC_FERON_TIM1H = 0xA8
.equ NEC_FERON_BRUP = 0xAB
.equ NEC_FERON_MODE = 0xAC
.equ NEC_FERON_BRDN = 0xBC
.equ NEC_FERON_SELECT = 0xDB
.equ NEC_FERON_POWER = 0xE9
.equ NEC_FERON_HUEDN = 0xEB
.equ NEC_FERON_HUEUP = 0xEF
.equ NEC_FERON_NIGHT = 0xF5
.equ NEC_FERON_TIM30M = 0xFA
; ### CUSTOM COMMANDS ###
.equ NEC_PWRON = 0xEA ; power ON
.equ NEC_PWROFF = 0xEC ; power OFF
.equ NEC_HUE_ROTATE = 0xF0 ; rotate HUE
.equ NEC_BR_ROTATE = 0xA2 ; rotate BRIGHTNESS
; 0x0X: BH <= EEPROM:X (with dimming)
; 0x1X: BH <= EEPROM:X (without dimming)
; 0x2X: BH => EEPROM:X
; 0x3X: HUE = X
; 0x4X: BR = X
; 0x5X: HUE += X
; 0x6X: HUE -= X
; 0x7X: BR += X
; 0x8X: BR -= X
.equ NEC_RX_NONE = 0
.equ NEC_RX_MAIN = 1
.equ NEC_RX_REPEAT = 2
; **** START OF IR EVENT BLOCK ****
sbrs PIN_REG, TSSOP_PIN ; [1]
rjmp _space ; [1][2] -> space occured
; [MARK] ANALYSE
cpi NECCNT_REG, NEC_T(21) ; [1]
brsh _abort ; [1][2] -> PROTOCOL ERROR: TOO BIG MARK
sbrc STATUS_REG, NEC_LEADER_BIT ; [2][1]
rjmp _data_mark ; [0][2] -> DATA MARK 1T CHECKING
; LEADER [MARK] DETECTION
cpi NECCNT_REG, NEC_T(12) ; [1]
brlo _abort ; [1][2] -> PROTOCOL ERROR: TOO LOW LEADER MARK
sbr STATUS_REG, _BV(NEC_LEADER_BIT) ; [1]
rjmp _nec_tim_reset ; [2] ----> GOOD: LEADER MARK DETECTED
; [SPACE] ANALYSE
_space:
cpi NECCNT_REG, NECCNT_MAX ; [1]
breq _abort ; [1][2] -> SPACE TOO MUCH. NEW COMMAND SESSION DETECTED.
cpi NECCNT_REG, NEC_T(10) ; [1]
brsh _frame_end ; [1][2] -> FRAME END: SPACE BEETWEEN FRAMES DETECTED
tst BITCNT_REG ; [1]
brne PC+11 ; [1][2] -> NEED READ DATA BIT
cpi NECCNT_REG, NEC_T(6) ; [1]
brsh PC+5 ; [1][2] -> MAIN FRAME DETECTED
tst NEC_FRAME_REG ; [1]
breq _frame_end ; [1][2] -> PROTOCOL ERROR: NO MAIN FRAME IN BUFFER
ldi NEC_FRAME_REG, NEC_RX_REPEAT ; [1]
rjmp _set_fin ; [2]
; prepare for main frame reading
ldi NEC_FRAME_REG, NEC_RX_MAIN ; [1]
ldi BITCNT_REG, 32 ; [1]
ldi XL, sram_nec_data ; [1]
rjmp _nec_tim_reset ; [2] ----> GOOD: MAIN FRAME INIT
; [SPACE] READING DATA
cpi NECCNT_REG, NEC_T(2) ; [1]
ror BYTE_REG ; [1]
dec BITCNT_REG ; [1]
breq PC+7 ; [1][2] -> OK: READING COMPLETE. CHECK INVERSION OF LAST DATA BYTE
mov TMP_REG, BITCNT_REG ; [1]
andi TMP_REG, 7 ; [1]
brne PC+3 ; [1][2] -> OK: CONTINUE READ
com BYTE_REG ; [1]
st X+, BYTE_REG ; [2]
rjmp _nec_tim_reset ; [2] ----> OK: ONE MORE BYTE READED
ld TMP_REG, -X ; [2]
cpse TMP_REG, BYTE_REG ; [2][1]
_abort:
rjmp _nec_abort ; [0][2] -> PROTOCOL ERROR: LAST DATA BYTE NOT INVERTED
_set_fin:
sbr STATUS_REG, _BV(NEC_FIN_BIT) ; [1]
rjmp _nec_tim_reset ; [2]
_frame_end:
rjmp _nec_frame_end ; [2]
; 1T DATA [MARKS] CHECKING
_data_mark:
cpi NECCNT_REG, NEC_T(2) ; [1]
brsh _abort ; [1][2] -> PROTOCOL ERROR: TOO LONG DATA MARK
sbrs STATUS_REG, NEC_FIN_BIT ; [2][1]
rjmp _nec_tim_reset ; [2] ----> GOOD: DATA MARK TIMING IS OK
; #### START OF PACKET PROCESSING ####
ldd TMP_REG, Y+1 ; [2]
cpi TMP_REG, high(NEC_FERON_ADDRESS) ; [1]
brne PC+5 ; [1][2] -> ABORT: WRONG HIGH BYTE OF ADDRESS
ldd TMP_REG, Y+0 ; [2]
cpi TMP_REG, low(NEC_FERON_ADDRESS) ; [1]
breq _native_address ; [1][2] -> GOOD: FERON NATIVE ADDRESS RECEIVED
sbrc NEC_FRAME_REG, 1 ; [2][1]
rjmp _nec_abort ; [0][2] -> ABORT: REPEAT PACKET
; #### ONLY MAIN PACKETS ####
cpi TMP_REG, low(NEC_HBDIM_ADDRESS) ; [1]
breq PC+3 ; [1][2] -> CUSTOM "BH SET WITH DIM" COMMAND
cpi TMP_REG, low(NEC_HBSET_ADDRESS) ; [1]
brne PC-4 ; [1][2] -> ABORT: UNKNOWN LOW BYTE OF ADDRESS
bst TMP_REG, 7 ; [1] without dimming address is 0x81
ldd BH_VALUE_REG, Y+2 ; [2]
rjmp _bh_set ; [2] -> BH DIRECT SET
; # FERON NATIVE ADDRESS COMMANDS #
_native_address:
ldd TMP_REG, Y+2 ; [2]
sbrc NEC_FRAME_REG, 1 ; [2][1]
rjmp _all_native_frames ; [0][2] -> REPEAT FRAME
; #### ONLY MAIN PACKETS ####
bst TMP_REG, 4 ; [1]
cpi TMP_REG, 0x20 ; [1]
brsh _above_1f ; [1][2] -> IS NEXT COMMAND?
; [0x0X-0x1X]: CUSTOM "BH LOAD FROM PRESET" IN EEPROM
cbr TMP_REG, 0xF0 ; [1] EEPROM address [0:15] as preset number
rcall eeprom_read ; [17+]
_bh_set:
sbr STATUS_REG, _BV(PWR_BIT) ; [1]
rcall update_from_table ; [16]
brtc PC+3 ; [1][2] -> [0x0X]: CUSTOM "LOAD BH PRESET WITH DIM" COMMAND
; [0x1X]: CUSTOM "LOAD BH PRESET WITHOUT DIM" COMMAND
out OCR1_REG, CH1_TARGET_REG ; [1]
out OCR2_REG, CH2_TARGET_REG ; [1]
rjmp _nec_abort ; [2] -> ABORT: NON-REPEATABLE COMMAND WAS EXECUTED
_above_1f:
cpi TMP_REG, NEC_FERON_POWER ; [1]
brne PC+5 ; [1][2] -> IS NEXT COMMAND?
; [0xE9]: NATIVE "POWER" COMMAND
subi STATUS_REG, _BV(PWR_BIT) ; [1]
andi STATUS_REG, _BV(PWR_BIT) ; [1]
rcall update_target_registers ; [13+]
rjmp _nec_abort ; [2] -> ABORT: NON-REPEATABLE COMMAND WAS EXECUTED
cpi TMP_REG, NEC_PWRON ; [1]
brne PC+4 ; [1][2] -> IS NEXT COMMAND?
; [0xEA]: CUSTOM "POWER ON" COMMAND. MAY BE USED TO CANCEL THE TIMER
ldi STATUS_REG, _BV(PWR_BIT) ; [1]
rcall update_from_table ; [18]
rjmp _nec_abort ; [2] -> ABORT: NON-REPEATABLE COMMAND WAS EXECUTED
sbrs STATUS_REG, PWR_BIT ; [2][1]
rjmp _nec_abort ; [0][2] -> ABORT: IGNORE OTHER COMMANDS IN "POWER OFF" STATE
; #### ONLY MAIN PACKETS IN "POWER ON" STATE ####
cpi TMP_REG, 0x30 ; [1]
brsh _above_2f ; [1][2] -> IS NEXT COMMAND?
; [0x2X]: CUSTOM "SAVE BH PRESET" COMMAND
cbr TMP_REG, 0xF0 ; [1] EEPROM address as preset number
rcall eeprom_write_bh ; [20+]
rjmp _nec_abort ; [2] -> ABORT: NON-REPEATABLE COMMAND WAS EXECUTED
_above_2f:
cpi TMP_REG, 0x90 ; [1]
brsh _above_8f ; [1][2] -> NOT DIRECT COMMANDS
; ### CUSTOM GROUP MODIFY COMMANDS [0x30-0x8F] ###
cpi TMP_REG, 0x50 ; [1]
brcc PC+10 ; [1][2] -> SOME OF CUSTOM MODIFY COMMANDS
cbr TMP_REG, 0xF0 ; [1]
brtc PC+3 ; [1][2] -> DIRECT BRIGHTNESS COMMANDS
; [0x3X]: CUSTOM "HUE = X" COMMAND
cbr BH_VALUE_REG, 0x0F ; [1]
rjmp PC+3 ; [2] ->
; [0x4X]: CUSTOM "BR = X" COMMAND
swap TMP_REG ; [1]
cbr BH_VALUE_REG, 0xF0 ; [1]
or BH_VALUE_REG, TMP_REG ; [1]
rcall update_from_table ; [16]
rjmp _nec_abort ; [2] -> ABORT: NON-REPEATABLE COMMAND WAS EXECUTED
cpi TMP_REG, 0x70 ; [1]
cbr TMP_REG, 0xF0 ; [1] CF not affected
brcc PC+3 ; [1][2] -> NOT INCREMENT COMMANDS
; [0x5X]: CUSTOM "HUE += X" COMMAND
brts _hue_add_command ; [1][2] ->
; [0x6X]: CUSTOM "HUE -= X" COMMAND
rjmp _hue_sub_command ; [2] ->
swap TMP_REG ; [1]
; [0x7X]: CUSTOM "BR += X" COMMAND
brts _br_add_command ; [2] ->
; [0x8X]: CUSTOM "BR -= X" COMMAND
rjmp _br_sub_command ; [2] ->
_above_8f:
cpi TMP_REG, NEC_PWROFF ; [1]
brne PC+4 ; [1][2] -> IS NEXT COMMAND?
; [0xEC]: CUSTOM "POWER OFF" COMMAND
clr STATUS_REG ; [1]
rcall reset_target_registers ; [10]
rjmp _nec_abort ; [2] -> ABORT: NON-REPEATABLE COMMAND WAS EXECUTED
cpi TMP_REG, NEC_FERON_TIM30M ; [1]
brne PC+4 ; [1][2] -> IS NEXT COMMAND?
; [0xFA]: NATIVE "30MIN TIMER" COMMAND
ldi TIMLO_REG, low(1800) ; [1]
ldi TIMHI_REG, high(1800) ; [1]
rjmp PC+5 ; [2] ->
cpi TMP_REG, NEC_FERON_TIM1H ; [1]
brne PC+5 ; [1][2] -> IS NEXT COMMAND?
; [0xA8]: NATIVE "1H TIMER" COMMAND
ldi TIMLO_REG, low(3600) ; [1]
ldi TIMHI_REG, high(3600) ; [1]
sbr STATUS_REG, _BV(TMR_BIT) | _BV(FRC_BIT) ; [1] <-
rjmp _nec_abort ; [2] -> ABORT: NON-REPEATABLE COMMAND WAS EXECUTED
; #### MAIN AND REPEAT PACKETS ####
_all_native_frames:
sbrc STATUS_REG, PWR_BIT ; [1][1][2]
sbrs STATUS_REG, TARGET_BIT ; [2][1][0]
rjmp _nec_frame_end ; [0][2][2] -> IGNORE OTHER COMMANDS IN "POWER OFF" OR "DIMMING" STATE
; ### MAIN AND REPEAT PACKETS IN "POWER ON" AND "NOT DIMMING" STATE ###
cpi TMP_REG, NEC_FERON_HUEUP ; [1]
brne PC+7 ; [1][2] -> IS NEXT COMMAND?
; [0xEF]: NATIVE "HUE++" COMMAND
ldi TMP_REG, 0x01 ; [1]
_hue_add_command:
add BH_VALUE_REG, TMP_REG ; [1]
brhc _update_for_repeat ; [1][2] -> HUE is not overflowed. Final command.
; HUE is overflowed. Limit value to 15 and fix corrupted BR value.
sbr BH_VALUE_REG, 0x0F ; [1]
subi BH_VALUE_REG, 0x10 ; [1]
rjmp _update_for_repeat ; [2] -> UPDATE TARGET REGISTERS AND PERMIT REPEAT FRAMES
cpi TMP_REG, NEC_FERON_BRUP ; [1]
brne PC+6 ; [1][2] -> IS NEXT COMMAND?
; [0xAB]: NATIVE "BR++" COMMAND
ldi TMP_REG, 0x10 ; [1]
_br_add_command:
add BH_VALUE_REG, TMP_REG ; [1]
brcc _update_for_repeat ; [1][2] -> BR is not overflowed
; BR is overflowed. Limit value to 15.
sbr BH_VALUE_REG, 0xF0 ; [1]
rjmp _update_for_repeat ; [2] -> UPDATE TARGET REGISTERS AND PERMIT REPEAT FRAMES
cpi TMP_REG, NEC_FERON_HUEDN ; [1]
brne PC+7 ; [1][2] -> IS NEXT COMMAND?
; [0xEB]: NATIVE "HUE--" COMMAND
ldi TMP_REG, 0x01 ; [1]
_hue_sub_command:
sub BH_VALUE_REG, TMP_REG ; [1]
brhc _update_for_repeat ; [1][2] -> HUE is not overflowed.
; HUE is overflowed. Limit value to 0 and fix corrupted BR value.
cbr BH_VALUE_REG, 0x0F ; [1]
subi BH_VALUE_REG, 0xF0 ; [1]
rjmp _update_for_repeat ; [2] -> UPDATE TARGET REGISTERS AND PERMIT REPEAT FRAMES
cpi TMP_REG, NEC_FERON_BRDN ; [1]
brne PC+6 ; [1][2] -> IS NEXT COMMAND?
; [0xBC]: NATIVE "BR--" COMMAND
ldi TMP_REG, 0x10 ; [1]
_br_sub_command:
sub BH_VALUE_REG, TMP_REG ; [1]
brcc _update_for_repeat ; [1][2] -> BR is not overflowed.
; BR is overflowed. Limit value to 0.
cbr BH_VALUE_REG, 0xF0 ; [1]
rjmp _update_for_repeat ; [2] -> UPDATE TARGET REGISTERS AND PERMIT REPEAT FRAMES
; ### ROTATE COMMANDS BLOCK ###
cpi TMP_REG, NEC_BR_ROTATE ; [1]
brne PC+5 ; [1][2] -> IS NEXT COMMAND?
; [0xA2]: CUSTOM "ROTATE BRIGHTNESS" COMMAND
swap BH_VALUE_REG ; [1]
rcall rotate_hue ; [18]
swap BH_VALUE_REG ; [1]
rjmp _update_for_repeat ; [2] -> UPDATE TARGET REGISTERS AND PERMIT REPEAT FRAMES
cpi TMP_REG, NEC_HUE_ROTATE ; [1]
; [0xF0]: CUSTOM "ROTATE HUE" COMMAND
breq PC+12 ; [1][2] -> ROTATE HUE COMMAND
cpi TMP_REG, NEC_FERON_NIGHT ; [1]
brne PC+5 ; [1][2] -> IS NEXT COMMAND?
; [0xF5]: NATIVE "NIGHT" COMMAND
cpi BH_VALUE_REG, 0x10 ; [1]
cbr BH_VALUE_REG, 0xF0 ; [1] SET BRIGHTNESS TO MIN
brlo PC+7 ; [1][2] -> BRIGHTNESS ALREADY ZERO. ROTATE HUE
rjmp _update_for_repeat ; [2] -> UPDATE TARGET REGISTERS AND PERMIT REPEAT FRAMES
cpi TMP_REG, NEC_FERON_MODE ; [1]
brne PC+6 ; [1][2] -> IS NEXT COMMAND?
; [0xAC]: NATIVE "MAX" COMMAND
cpi BH_VALUE_REG, 0xF0 ; [1]
sbr BH_VALUE_REG, 0xF0 ; [1] SET BRIGHTNESS TO MAX
brlo _update_for_repeat ; [1][2] -> UPDATE TARGET REGISTERS AND PERMIT REPEAT FRAMES
rcall rotate_hue ; [18]
rjmp _update_for_repeat ; [2] -> UPDATE TARGET REGISTERS AND PERMIT REPEAT FRAMES
; ### END OF ROTATE COMMANDS BLOCK ###
cpi TMP_REG, NEC_FERON_SELECT ; [1]
brne _nec_abort ; [1][2] -> ABORT: UNSUPPORTED COMMAND
; [0xDB]: NATIVE "SELECT" COMMAND
mov BH_VALUE_REG, RAND_REG ; [1]
_update_for_repeat:
rcall update_from_table ; [16]
rjmp _nec_frame_end ; [2] ->
; END OF MESSAGE PROCESSING
_nec_abort:
ldi NEC_FRAME_REG, NEC_RX_NONE ; [1]
_nec_frame_end:
cbr STATUS_REG, NEC_STATUS_MASK ; [1]
clr BITCNT_REG ; [1]
_nec_tim_reset:
clr NECCNT_REG ; [1]
; **** END OF IR EVENT BLOCK ****