===== Parallax PIC16Cxx Assembler v4.7 =====
1 ;IR REMOTE CONTROL
2 ;for Toshiba CATV Home Terminal model TCJ552B
3 ;Version 2.0
4 ;Copyright 2001 Tickets, All rights reserved
5 ;
6 ; * Use 3.58MHz resonator for proper operation
7 ;
8 ; NOTE: This code is written in Parallax SPASM assembler
9 ;
10 0000- devicepic16f84,hs_osc,wdt_off,protect_off,pwrt_on
11 0000- ID'IRRC'
12 ;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
13 ; DEFINITIONS
14 ;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
15 ; IR LED
16 =0205 led_out=PortA.4; LED output/Active Low
17
18 =0016 time_h=22; Cycles of H bit for 0.56msec
19 =0078 time_0=120; L duration for data 0
20 =00FA time_1=250; L duration for data 1
21 =00AA time_start=170; Cycles of Leader (-255)
22
23 =0008 bit_cnt=8; Bit count
24
25 ; Key scan
26 =0049 code_system=49h; Toshiba
27 =001C key_shift=1ch; Key scan code of SHIFT
28 =000C key_chup=0ch; Channel Up
29 =0010 key_chdn=10h; Channel Down
30 =0014 key_vrup=14h; Volume Up
31 =0018 key_vrdn=18h; Volume Down
32 =0020 data_shift=32; Add to key code in shift mode
33 =0206 col0=PortB.4; COLUMN scan ports (Input)
34 =0286 col1=PortB.5
35 =0306 col2=PortB.6
36 =0386 col3=PortB.7
37
38 =00FF no_key=0ffh; Key matrix code for no key
39
40 ; Port Settings
41 =00E0 porta_dir=11100000b
42 =00F0 portb_dir=11110000b
43 =0381 portb_pullup=OPTION.7; 0 to enable PortB pull-up
44
45 ; Control registers settings
46 =0000 mask_int=00000000b; INTCON register
47 =007F mask_opt=01111111b; OPTION register
48
49 ; Interrupt
50 =000B int_rbif=INTCON.0; PortB interrupt flag
51 =010B int_toif=INTCON.2; WDT
52 =018B int_rbie=INTCON.3; PortB interrupt enable
53 =038B int_gie=INTCON.7; General interrupt enable
54
55 ;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
56 000C- org0ch; Top of available RAM
57
58 000C- time_cntrds1; Cycle counter
59 000D- delay_cntrds1; Delay counter
60 000E- cntr_1msecds1; Counter for 1msec wait
61 000F- cntr_15msecds1; Counter for 16msec wait
62 0010- cntr_100msecds1; Counter for 100msec wait
63 0011- cntr_1secds1; Counter for 1sec wait
64
65 0012- tx_data_buffds1; Store code to be transmitted
66 0013- code_buffds1; Store result data code from key_scan
67 0014- bit_cntrds1; Bit counter to send byte
68
69 0015- key_rowds1; Row for keyscan
70 0016- key_columnds1; Column for keyscan
71 0017- key_matrixds1; Result key matrix code (0-63)
72 0018- cntr_rowds1; Counter for row scan
73 0019- cntr_colds1; Counter for column scan
74 001A- cntr_nokeyds1; Counts key scan cycles to sense no-key
75 001B- shift_32ds1; Contains 00100000b in shift mode
76 001C- flag_rowds1; NZ if row scan get key press
77 001D- flag_colds1; NZ if column scan get key press
78 001E- flag_nokeyds1; NZ if no key is pressed for a while
79 001F- flag_continueds1; NZ if key press is continued
80
81 0020- flag_errords1; 0:No error NZ:Error
82
83 ;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
84 0000- org0; Top of program
85 0000- 2805 jmpstart
86
87 0001- interrupt_routine
88 0004- org04h; Interrupt vector/NOT USED
89
90 0004- 0009 reti; End of interrupt
91
92 ;------
93 0005- start
94 0005- 2054 callinit
95
96 ;------
97 ; MAIN LOOP
98 ;------
99 0006- main
100 0006- 3010 0085 movPortA,#10h; Set scan port output to L
101 0008- 3000 0086 movPortB,#0h
102
103 000A- 0806 movw,PortB; Clear PortB input mismatch
104 000B- 100B clrbint_rbif; Clear RBIF for sure
105 000C- 158B setbint_rbie; Enable PortB mismatch int
106
107 000D- 0063 sleep; Sleep untill interrupt occurs
108 ; Process next instruction on interrupt
109 ; No interrupt vector (04h) called
110 ; since GIE is disabled
111 000E- 118B clrbint_rbie; Disable PortB interrupt
112 000F- 100B clrbint_rbif; Clear PortB interrupt flag
113
114 0010- 214B calldelay_15msec; Remove key bounces
115 0011- 2063 callprocess_key; Main Process
116
117 0012- 2806 gotomain; Wait for next key
118
119 ;------
120 ; KEY SCAN TABLE
121 ; This should be placed within first 256 byte
122 ;------
123 0013- key_table
124 0013- 0782 jmppc+w; W contains matrix code
125 ; Returns data code in W
126 ; 55h should be ignored
127 0014- 3412 3411 340F 3415 retw12h,11h,0fh,15h,16h,1ch,55h,1dh
0018- 3416 341C 3455 341D
128 001C- 3417 3400 3419 3414 retw17h,00h,19h,14h,1bh,03h,02h,01h
0020- 341B 3403 3402 3401
129 0024- 341F 3406 3405 3404 retw1fh,06h,05h,04h,1ah,09h,08h,07h
0028- 341A 3409 3408 3407
130 002C- 341E 3418 340B 340A retw1eh,18h,0bh,0ah,55h,10h,13h,0eh
0030- 3455 3410 3413 340E
131
132 0034- 34FF 3455 3443 3455 retw0ffh,55h,43h,55h,55h,5dh,44h,4eh
0038- 3455 345D 3444 344E
133 003C- 3455 3455 3445 3455 retw55h,55h,45h,55h,55h,55h,5bh,55h
0040- 3455 3455 345B 3455
134 0044- 3455 3455 345C 3455 retw55h,55h,5ch,55h,42h,55h,5eh,55h
0048- 3442 3455 345E 3455
135 004C- 3455 3455 345F 3441 retw55h,55h,5fh,41h,55h,55h,0feh,40h
0050- 3455 3455 34FE 3440
136
137 ;------
138 ; POWER ON INITIALIZE
139 ;------
140 0054- init
141 0054- 3000 008B movINTCON,#mask_int
142 0056- 307F 0081 movOPTION,#mask_opt
143 0058- 138B clrbint_gie; Disable GIE
144 ; Ports Direction
145 0059- 30E0 0065 mov!ra,#porta_dir; All PortA for output
146 005B- 30F0 0066 mov!rb,#portb_dir; RB0-3 for output, RB4-7 for output
147 005D- 3010 0085 movPortA,#10h; row4-7 to L,led_out to H
148 005F- 3000 0086 movPortB,#0h; row0-3 to L
149
150 0061- 019B clrshift_32; Clear shift data (32)
151
152 0062- 0008 ret
153
154 ;------
155 ; Process Key Input
156 ;------
157 0063- process_key
158 0063- 019F clrflag_continue; Prepare for new key input
159 0064- :loop
160 0064- 2096 callkey_scan; Scan keys
161
162 0065- 30FF 0217 1903 2893 cjekey_matrix,#no_key,:finish; No key, do nothing
163
164 0069- 3000 021F 1903 287E cjeflag_continue,#0,:skip0; Continue?
165 006D- 300C 0217 1903 288A cjekey_matrix,#key_chup,:skip; Repeat Channel Up
166 0071- 3010 0217 1903 288A cjekey_matrix,#key_chdn,:skip; Repeat Channel Down
167 0075- 3014 0217 1903 288A cjekey_matrix,#key_vrup,:skip; Repeat Volume Up
168 0079- 3018 0217 1903 288A cjekey_matrix,#key_vrdn,:skip; Repeat Volume Down
169 007D- 288F goto:skip2; Else don't process
170
171 007E- :skip0
172 007E- 301C 0217 1D03 288A cjnekey_matrix,#key_shift,:skip; Shift mode?
173 0082- :wait_release
174 0082- 2096 callkey_scan; Wait till SHIFT key is released
175 0083- 301C 0217 1903 2882 cjekey_matrix,#key_shift,:wait_release
176
177 0087- 3020 009B movshift_32,#data_shift
178 0089- 2893 goto:finish; Shift data is set
179
180 008A- :skip
181 008A- 0817 movw,key_matrix; Set key matrix code
182 008B- 2013 callkey_table; Get Remote Control code
183 008C- 0093 movcode_buff,w; Set in transmit buffer
184
185 008D- 20DA calltx_data; Send IR
186
187 008E- 019B clrshift_32; Reset shift mode
188 008F- :skip2
189 008F- 2145 calldelay_100msec; Interval for next signal
190
191 0090- 3001 009F movflag_continue,#1; Set continue flag
192 0092- 2864 goto:loop
193
194 0093- :finish
195 0093- 019F clrflag_continue; Key released
196 0094- 2145 calldelay_100msec; Interva for next signal
197
198 0095- 0008 ret
199
200 ;------
201 ; KEY SCAN
202 ;------
203 0096- key_scan
204 0096- 0197 clrkey_matrix; Initialize scan matrix
205
206 0097- :loop1
207 0097- 0196 clrkey_column; Prepare for new scan
208 0098- 301F 0085 movPortA,#1fh; Clear PortA
209 009A- 30FE 0086 movPortB,#0feh; Set RB0 to low
210 009C- 3004 0099 movcntr_col,#4; Test four times
211 009E- :loop2
212 009E- 20C9 callrow_scan
213 009F- 3000 049C orflag_row,#00h; Test flag
214 00A1- 1D03 28BD jnz:finish; Yes, key is pressed
215
216 00A3- 1403 setbc;
217 00A4- 0D86 rlPortB; Next row
218 00A5- 0A96 inckey_column; Increment Key Matrix code
219
220 00A6- 0B99 289E djnzcntr_col,:loop2
221
222 00A8- :loop3
223 00A8- 301E 0085 movPortA,#1eh; Set RA0 to low
224 00AA- 300F 0086 movPortB,#0fh; Clear PortB
225 00AC- 3004 0099 movcntr_col,#4; Test four times
226 00AE- :loop4
227 00AE- 20C9 callrow_scan
228 00AF- 3000 049C orflag_row,#00h; Test flag
229 00B1- 1D03 28BD jnz:finish; Yes, key press is sensed
230
231 00B3- 0399 deccntr_col
232 00B4- 1903 28BA jz:skip; Avoid RA4(LED) to be Low
233
234 00B6- 1403 setbc; Column scan
235 00B7- 0D85 rlPortA
236 00B8- 0A96 inckey_column
237
238 00B9- 28AE goto:loop4
239 00BA- :skip
240 00BA- 30FF 0097 movkey_matrix,#no_key
241 00BC- 28C8 goto:no_key; No key is pressed
242
243 00BD- :finish
244 00BD- 0815 0097 movkey_matrix,key_row
245 00BF- 3007 0596 andkey_column,#0000111b; Use last 3 bits
246 00C1- 1003 clrbc
247 00C2- 0D96 rlkey_column; Move to upward
248 00C3- 0D96 rlkey_column
249 00C4- 0816 0797 addkey_matrix,key_column
250 00C6- 081B 0797 addkey_matrix,shift_32; Add 32 in shift mode
251 00C8- :no_key
252 00C8- 0008 ret
253 ;------
254 00C9- row_scan
255 00C9- 019C clrflag_row
256 00CA- 0195 clrkey_row
257 00CB- 1E06 28D8 jnbcol0,:finish
258 00CD- 0A95 inckey_row
259 00CE- 1E86 28D8 jnbcol1,:finish
260 00D0- 0A95 inckey_row
261 00D1- 1F06 28D8 jnbcol2,:finish
262 00D3- 0A95 inckey_row
263 00D4- 1F86 28D8 jnbcol3,:finish
264 00D6- 0A95 inckey_row
265 00D7- :exit
266 00D7- 0008 ret
267
268 00D8- :finish
269 00D8- 0A9C incflag_row
270 00D9- 28D7 goto:exit
271
272 ;------
273 ; TRANSMIT DATA
274 ;------
275 00DA- tx_data
276 00DA- 20EF calltx_leader; 4.5msec leader burst
277
278 00DB- 211E calltx_bit1; 4.5msec space (gap)
279 00DC- 211E calltx_bit1
280 00DD- 211E calltx_bit1
281
282 00DE- 3049 0092 movtx_data_buff,#code_system; Send system code
283 00E0- 210A calltx_byte
284
285 00E1- 3049 0092 movtx_data_buff,#code_system
286 00E3- 30FF 0692 xortx_data_buff,#0ffh; Invert system code
287 00E5- 210A calltx_byte
288
289 00E6- 0813 0092 movtx_data_buff,code_buff; Send Data code
290 00E8- 210A calltx_byte
291
292 00E9- 0813 0092 movtx_data_buff,code_buff
293 00EB- 30FF 0692 xortx_data_buff,#0ffh; Invert data code
294 00ED- 210A calltx_byte
295
296 00EE- 2126 calltx_bit; End bit
297
298 ;------
299 ; TRANSMIT LEADER
300 ;------
301 00EF- tx_leader; Send 0 for 4.5msec
302 ;movtime_cntr,#0ffh; Count 1
303 ;call:loop
304 00EF- 30AA 008C movtime_cntr,#time_start; Additional count
305 00F1- 20F3 call:loop
306
307 00F2- 0008 ret
308
309 00F3- :loop
310 00F3- 1205 clrbled_out; Turn on LED
311 00F4- 0000 nop
312 00F5- 0000 nop
313 00F6- 0000 nop
314 00F7- 0000 nop
315 00F8- 0000 nop
316 00F9- 0000 nop
317 00FA- 1605 setbled_out; Turn off LED
318 00FB- 0000 nop
319 00FC- 0000 nop
320 00FD- 0000 nop
321 00FE- 0000 nop
322 00FF- 0000 nop
323 0100- 0000 nop
324 0101- 0000 nop
325 0102- 0000 nop
326 0103- 0000 nop
327 0104- 0000 nop
328 0105- 0000 nop
329 0106- 038C dectime_cntr; Count cycles
330 0107- 1D03 28F3 jnz:loop
331
332 0109- 0008 ret
333
334 ;------
335 ; TRANSMIT BYTE
336 ;------
337 010A- tx_byte; TX data in tx_data
338 010A- 3008 0094 movbit_cntr,#bit_cnt; 8bits
339 010C- 1003 clc
340 010D- :loop
341 010D- 2126 calltx_bit; Transmit LED pulse
342 010E- 0C92 rrtx_data_buff; Adjust duration
343 010F- 1C03 2913 jnc:skip0; Skip if 0
344 0111- 211E calltx_bit1; Bit 1
345 0112- 2914 jmp:finish
346 0113- :skip0
347 0113- 2118 calltx_bit0; Bit 0
348 0114- :finish
349 0114- 0394 decbit_cntr
350 0115- 1D03 290D jnz:loop
351
352 0117- 0008 ret
353
354 ;------
355 ; BIT 0 DURATION
356 ;------
357 0118- tx_bit0
358 0118- 3078 008C movtime_cntr,#time_0
359 011A- :loop
360 011A- 038C dectime_cntr
361 011B- 1D03 291A jnz:loop
362
363 011D- 0008 ret
364
365 ;------
366 ; BIT 1 DURATION
367 ;------
368 011E- tx_bit1
369 011E- 30FA 008C movtime_cntr,#time_1
370 0120- :loop
371 0120- 038C dectime_cntr
372 0121- 0000 nop
373 0122- 0000 nop
374 0123- 1D03 2920 jnz:loop
375
376 0125- 0008 ret
377
378 ;------
379 ; TRANSMIT LED PULSE
380 ;------
381 0126- tx_bit
382 0126- 3016 008C movtime_cntr,#time_h
383 0128- :loop
384 0128- 1205 clrbled_out; Turn on LED
385 0129- 0000 nop
386 012A- 0000 nop
387 012B- 0000 nop
388 012C- 0000 nop
389 012D- 0000 nop
390 012E- 0000 nop
391 012F- 1605 setbled_out; Turn off LED
392 0130- 0000 nop
393 0131- 0000 nop
394 0132- 0000 nop
395 0133- 0000 nop
396 0134- 0000 nop
397 0135- 0000 nop
398 0136- 0000 nop
399 0137- 0000 nop
400 0138- 0000 nop
401 0139- 0000 nop
402 013A- 0000 nop
403 013B- 038C dectime_cntr; Count cycles
404 013C- 1D03 2928 jnz:loop
405
406 013E- 0008 ret
407
408 ;------
409 ; DELAY ROUTINES
410 ; (Multi entry Multi exit)
411 ;------
412 013F- delay_1sec
413 013F- 300A 0091 movcntr_1sec,#10
414 0141- :loop
415 0141- 2145 calldelay_100msec
416 0142- 0B91 2941 djnzcntr_1sec,:loop
417
418 0144- 0008 ret
419
420 ;------
421 0145- delay_100msec
422 0145- 3064 0090 movcntr_100msec,#100
423 0147- :loop
424 0147- 2152 calldelay_1msec
425 0148- 0B90 2947 djnzcntr_100msec,:loop
426
427 014A- 0008 ret
428
429 ;------
430 014B- delay_15msec
431 014B- 300F 008F movcntr_15msec,#15
432 014D- :loop
433 014D- 2152 calldelay_1msec
434 014E- 0B8F 294D djnzcntr_15msec,:loop
435
436 0150- 0008 ret
437 ;------
438 0151- delay_2msec
439 0151- 2152 calldelay_1msec
440 ;------
441 0152- delay_1msec
442 0152- 30FF 008E movcntr_1msec,#0ffh; 1msec delay for 3.58MHz
443 0154- :loop
444 0154- 0000 nop
445 0155- 0000 nop
446 0156- 0000 nop
447 0157- 0000 nop
448 0158- 0B8E 2954 djnzcntr_1msec,:loop
449
450 015A- 0008 ret
451
452
===== Errors: 0 =====