2 ;For Toshiba CATV Home Terminal Model TCJ552B

2 ;For Toshiba CATV Home Terminal Model TCJ552B

===== 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 =====