/
Decoder.c
428 lines (382 loc) · 9.16 KB
/
Decoder.c
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
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
/**
* @file
* DECODER.c
* @author Brian Kang
* @version 1.0
* @section LICENSE
* Copyright (C) 2011~2012 Intersil Corporation
* @section DESCRIPTION
* Internal Decoder module
******************************************************************************
*/
#include "Config.h"
#include "reg.h"
#include "typedefs.h"
#include "TW8835.h"
#include "Global.h"
#include "main.h"
#include "Printf.h"
#include "Monitor.h"
#include "I2C.h"
#include "CPU.h"
#include "Scaler.h"
#include "InputCtrl.h"
//-----------------------------------------------------------------------------
/**
* check Video Loss
*
* register
* R101[0]
*
* oldname: CheckDecoderVDLOSS().
*
* @param n: wait counter
* @return
* 0:Video detected
* 1:Video not present. Video Loss
*/
BYTE DecoderCheckVDLOSS( BYTE n )
{
volatile BYTE mode;
BYTE start;
dPrintf("\nDecoderCheckVDLOSS(%d) start",(WORD)n);
start = n;
WriteTW88Page(PAGE1_DECODER );
while (n--) {
mode = ReadTW88(REG101); //read Chip Status
if (( mode & 0x80 ) == 0 ) {
dPrintf("->end%bd",start - n);
return ( 0 ); //check video detect flag
}
delay1ms(10);
}
ePrintf("\nDecoderCheckVDLOSS->fail");
return ( 1 ); //fail. We loss the Video
}
#ifdef SUPPORT_FOSD_MENU
//-----------------------------------------------------------------------------
/**
* Is it a video Loss State
*
* @return
* - 1:If no Input
* - 0:Found Input
*/
BYTE DecoderIsNoInput(void)
{
DECLARE_LOCAL_page
BYTE ret;
ReadTW88Page(page);
WriteTW88Page(PAGE1_DECODER);
ret = TW8835_R101;
WriteTW88Page(page);
if(ret & 0x80)
return 1; //No Input
return 0; //found Input
}
#endif
//-----------------------------------------------------------------------------
/**
* set input mux format
*
* register
* R102 - input format.
* R105.
* R106.
* @param InputMode
*/
void InMuxSetInput(BYTE InputMode)
{
BYTE r102, r105, r106;
WriteTW88Page(PAGE1_DECODER );
r105 = ReadTW88(REG105) & 0xF0;
r106 = ReadTW88(REG106) & ~0x03; //Do not change Y.
switch(InputMode) {
case INPUT_CVBS:
r102 = 0x40; // 0x40 - FC27:27MHz, IFSEL:Composite, YSEL:YIN0
r105 |= 0x0F; //decoder mode
r106 |= 0x03; // C,V adc in Power Down.
break;
case INPUT_SVIDEO:
r102 = 0x54; // 0x54 - FC27:27MHz, IFSEL:S-Video, YSEL:YIN1, CSEL:CIN0
r105 |= 0x0F; //decoder mode
r106 |= 0x01; // V in PowerDown
break;
case INPUT_COMP: //target r102:4A,r105:04 r016:00
// -> 4A 00 00
r102 = 0x4A ; // 0x4A - FC27:27MHz,
// IFSEL:Composite, We are using aRGB. So composite is a correct value
// YSEL:YIN2, CSEL:CIN1, VSEL:VIN0
//r105 |= 0x04; //??? ? someone overwrite as 00. R105[2]=0b is a correct
//r106 //C & V adc in normal(not Power Down)
break;
case INPUT_PC: //target r102:4A r105:04 r106:00
r102 = 0x4A; // 0x4A - FC27:27MHz,
// IFSEL:Composite, We are using aRGB. So composite is a correct value
// YSEL:YIN2, CSEL:CIN1, VSEL:VIN0
//r105 = //RGB mode
//?? I think R105[2] have to be 0. not 1b.
//r106 //C & V adc in normal(not Power Down)
break;
case INPUT_DVI: //target ? don't care
case INPUT_HDMIPC:
case INPUT_HDMITV:
case INPUT_BT656:
//digital. don't care.
r102 = 0x00;
break;
}
if(r102) { //need update?
WriteTW88(REG102, r102 );
WriteTW88(REG105, r105 );
WriteTW88(REG106, r106 );
}
}
//---------------------------------------------
//description
// input data format selection
// if input is PC(aRGB),DVI,HDMI, you have to set.
//parameter
// 0:YCbCr 1:RGB
//
//CVBS:0x40
//SVIDEO:0x54. IFSET:SVIDEO, YSEL:YIN1
#if 0
void DecoderSetPath(BYTE path)
{
WriteTW88Page(PAGE1_DECODER );
WriteTW88(REG102, path );
}
#endif
//R104 HSYNC Delay Control
//
//parameter
// input_mode 0:RGB mode, 1:decoder mode
//register
// R105
#if 0
void DecoderSetAFE(BYTE input_mode)
{
WriteTW88Page(PAGE1_DECODER );
if(input_mode==0) {
WriteTW88(REG105, (ReadTW88(REG105) & 0xF0) | 0x04); //? C is for decoder, not RGB
}
else {
WriteTW88(REG105, (ReadTW88(REG105) | 0x0F));
}
}
#endif
#ifdef UNCALLED_SEGMENT
//-----------------------------------------------------------------------------
//register
// R106[2]
// R106[1]
// R106[0]
void DecoderPowerDown(BYTE fOn)
{
WriteTW88Page(PAGE1_DECODER)
if(fOn) WriteTW88(REG106, ReadTW88(REG106) | 0x07);
else WriteTW88(REG106, ReadTW88(REG106) & ~0x07);
}
#endif
//-----------------------------------------------------------------------------
//desc: set/get vertical delay
//@param
//output
//
//register
// R107[7:6]R108[7:0]
#ifdef UNCALLED_SEGMENT
void DecoderSetVDelay(WORD delay)
{
WriteTW88Page(PAGE1_DECODER ); // get VDelay from Decoder
WriteTW88(REG107, (ReadTW88(REG107 ) & 0x3F) | ( (delay & 0x0300) >> 2));
WriteTW88(REG108, (BYTE)delay );
}
#endif
//-----------------------------------------------------------------------------
/**
* get decoder vertical delay value
*/
WORD DecoderGetVDelay(void)
{
WORD vDelay;
WriteTW88Page(PAGE1_DECODER ); // get VDelay from Decoder
vDelay = ReadTW88(REG107 ) & 0xC0;
vDelay <<= 2;
vDelay |= ReadTW88(REG108 );
return vDelay;
}
//-----------------------------------------------------------------------------
/**
* set decoder vertical active length
*
* register
* R107[5:4]R109[7:0]
*/
void DecoderSetVActive(WORD length)
{
WriteTW88Page(PAGE1_DECODER );
WriteTW88(REG107, (ReadTW88(REG107) & 0xCF) | ( (length & 0x0300) >> 4));
WriteTW88(REG109, (BYTE)length );
}
#ifdef UNCALLED_SEGMENT
//-----------------------------------------------------------------------------
WORD DecoderGetVActive(void)
{
WORD vActive;
WriteTW88Page(PAGE1_DECODER );
vActive = ReadTW88(REG107 ) & 0x30;
vActive <<= 4;
vActive |= ReadTW88(REG109 );
return vActive;
}
#endif
//-----------------------------------------------------------------------------
//desc:set/get Horizontal delay
//register
// R107[3:2]R10A[7:0]
#ifdef UNCALLED_SEGMENT
void DecoderSetHDelay(WORD delay)
{
WriteTW88Page(PAGE1_DECODER ); // get VDelay from Decoder
WriteTW88(REG107, (ReadTW88(REG107 ) & 0xF3) | ( (delay & 0x0300) >> 6));
WriteTW88(REG10A, (BYTE)delay );
}
WORD DecoderGetHDelay(void)
{
WORD hDelay;
WriteTW88Page(PAGE1_DECODER ); // get VDelay from Decoder
hDelay = ReadTW88(REG107 ) & 0x0C;
hDelay <<= 6;
hDelay |= ReadTW88(REG10A );
return hDelay;
}
#endif
//-----------------------------------------------------------------------------
//desc: set/get Horizontal active
//register
// R107[1:0]R10B[7:0]
#ifdef UNCALLED_SEGMENT
void DecoderSetHActive(WORD length)
{
WriteTW88Page(PAGE1_DECODER ); // get VDelay from Decoder
WriteTW88(REG107, (ReadTW88(REG107 ) & 0xFC) | ( (length & 0x0300) >> 8));
WriteTW88(REG10B, (BYTE)length );
}
WORD DecoderGetHActive(void)
{
WORD hActive;
WriteTW88Page(PAGE1_DECODER ); // get VDelay from Decoder
hActive = ReadTW88(REG107 ) & 0x03;
hActive <<= 8;
hActive |= ReadTW88(REG10B );
return hActive;
}
#endif
//-----------------------------------------------------------------------------
/**
* read detected decoder mode
*
* register
* R11C[7] 0:idle, 1:detection in progress
* R11C[6:4] 000: NTSC
* 001: PAL
* ...
* 111:N/A
*/
BYTE DecoderReadDetectedMode(void)
{
BYTE mode;
WriteTW88Page(PAGE1_DECODER);
mode = ReadTW88(REG11C);
mode >>= 4;
return mode;
}
#ifdef SUPPORT_FOSD_MENU
//-----------------------------------------------------------------------------
/**
* read video input standard
*
* BKTODO120201 Pls, remove this
*/
BYTE DecoderReadVInputSTD(void)
{
DECLARE_LOCAL_page
BYTE std, ret;
ReadTW88Page(page);
if( DecoderIsNoInput() ) ret = 1; // Noinput!! BUGBUG
std = DecoderReadDetectedMode();
if(std & 0x08)
ret = 0xff; // Detection in progress..
else
ret = std + 1;
WriteTW88Page(page );
return (ret);
}
#endif
//-----------------------------------------------------------------------------
/**
* check detected decoder video input standard
*
* To get a stable the correct REG11C[6:4] value,
* read REG101[6] and REG130[7:5] also.
* I saw the following values(BK110303)
* E7 E7 67 67 87 87 87 87 ..... 87 87 87 87 87 87 87 87 87 07 07 07 ....
* B7 B7 B7 37 37 87 87 87 ..... 87 87 87 87 87 87 87 87 87 07 07 07 07 07 07 07
*
* oldname: CheckDecoderSTD
*
* register
* R11C[6:4].
* R101[6].
* R130[7:5].
* @return
* 0x80: filed.
* other: detected standard value.
*/
BYTE DecoderCheckSTD( BYTE n )
{
volatile BYTE r11c,r101,r130;
BYTE start=n;
BYTE count;
ePrintf("\nDecoderCheckSTD(%d) start",(WORD)n);
WriteTW88Page(PAGE1_DECODER ); // set Decoder page
count=0;
while (n--) {
r11c = ReadTW88(REG11C);
if (( r11c & 0x80 ) == 0 ) {
r101 = ReadTW88(REG101);
r130 = ReadTW88(REG130);
dPrintf("\n%02bx:%02bx-%02bx-%02bx ",start-n, r11c, r101,r130);
if((r101 & 0x40) && ((r130 & 0xE0)==0)) {
ePrintf("->success:%d",(WORD)start-n);
if(count > 4)
return (r11c);
count++;
}
}
delay1ms(5);
}
ePrintf("->fail");
return ( 0x80 );
}
//-----------------------------------------------------------------------------
/**
* set decoder freerun mode
*
* example
* DecoderFreerun(DECODER_FREERUN_60HZ);
*
* R133[7:6]
* @param
* mode 0:AutoMode
* 1:AutoMode
* 2:60Hz
* 3:50Hz
*/
void DecoderFreerun(BYTE mode)
{
WriteTW88Page(PAGE1_DECODER );
WriteTW88(REG133, (ReadTW88(REG133) & 0x3F) | (mode<<6));
}