2 * R820T tuner driver, taken from Realteks RTL2832U Linux Kernel Driver
4 * This driver is a mess, and should be cleaned up/rewritten.
11 #include "rtlsdr_i2c.h"
12 #include "tuner_r820t.h"
14 int r820t_SetRfFreqHz(void *pTuner, unsigned long RfFreqHz)
16 R828_Set_Info R828Info;
18 // if(pExtra->IsStandardModeSet==NO)
19 // goto error_status_set_tuner_rf_frequency;
21 // R828Info.R828_Standard = (R828_Standard_Type)pExtra->StandardMode;
22 R828Info.R828_Standard = (R828_Standard_Type)DVB_T_6M;
23 R828Info.RF_Hz = (UINT32)(RfFreqHz);
24 R828Info.RF_KHz = (UINT32)(RfFreqHz/1000);
26 if(R828_SetFrequency(pTuner, R828Info, NORMAL_MODE) != RT_Success)
27 return FUNCTION_ERROR;
29 return FUNCTION_SUCCESS;
32 int r820t_SetStandardMode(void *pTuner, int StandardMode)
34 if(R828_SetStandard(pTuner, (R828_Standard_Type)StandardMode) != RT_Success)
35 return FUNCTION_ERROR;
37 return FUNCTION_SUCCESS;
40 int r820t_SetStandby(void *pTuner, int LoopThroughType)
43 if(R828_Standby(pTuner, (R828_LoopThrough_Type)LoopThroughType) != RT_Success)
44 return FUNCTION_ERROR;
46 return FUNCTION_SUCCESS;
49 // The following context is implemented for R820T source code.
51 /* just reverses the bits of a byte */
53 r820t_Convert(int InvertNum)
64 for(CountNum = 0;CountNum < 8;CountNum ++)
66 if(BitNum & InvertNum)
77 I2C_Write_Len(void *pTuner, R828_I2C_LEN_TYPE *I2C_Info)
79 unsigned char DeviceAddr;
83 unsigned char RegStartAddr;
84 unsigned char *pWritingBytes;
85 unsigned long ByteNum;
87 unsigned char WritingBuffer[128];
88 unsigned long WritingByteNum, WritingByteNumMax, WritingByteNumRem;
89 unsigned char RegWritingAddr;
91 // Get regiser start address, writing bytes, and byte number.
92 RegStartAddr = I2C_Info->RegAddr;
93 pWritingBytes = I2C_Info->Data;
94 ByteNum = (unsigned long)I2C_Info->Len;
96 // Calculate maximum writing byte number.
97 // WritingByteNumMax = pBaseInterface->I2cWritingByteNumMax - LEN_1_BYTE;
98 WritingByteNumMax = 2 - 1; //9 orig
100 // Set tuner register bytes with writing bytes.
101 // Note: Set tuner register bytes considering maximum writing byte number.
102 for(i = 0; i < ByteNum; i += WritingByteNumMax)
104 // Set register writing address.
105 RegWritingAddr = RegStartAddr + i;
107 // Calculate remainder writing byte number.
108 WritingByteNumRem = ByteNum - i;
110 // Determine writing byte number.
111 WritingByteNum = (WritingByteNumRem > WritingByteNumMax) ? WritingByteNumMax : WritingByteNumRem;
113 // Set writing buffer.
114 // Note: The I2C format of tuner register byte setting is as follows:
115 // start_bit + (DeviceAddr | writing_bit) + RegWritingAddr + writing_bytes (WritingByteNum bytes) +
117 WritingBuffer[0] = RegWritingAddr;
119 for(j = 0; j < WritingByteNum; j++)
120 WritingBuffer[j+1] = pWritingBytes[i + j];
122 // Set tuner register bytes with writing buffer.
123 // if(pI2cBridge->ForwardI2cWritingCmd(pI2cBridge, DeviceAddr, WritingBuffer, WritingByteNum + LEN_1_BYTE) !=
125 // goto error_status_set_tuner_registers;
127 if (rtlsdr_i2c_write_fn(pTuner, R820T_I2C_ADDR, WritingBuffer, WritingByteNum + 1) < 0)
135 I2C_Read_Len(void *pTuner, R828_I2C_LEN_TYPE *I2C_Info)
141 uint8_t RegStartAddr;
142 uint8_t ReadingBytes[128];
143 unsigned long ByteNum;
145 // Get regiser start address, writing bytes, and byte number.
147 ByteNum = (unsigned long)I2C_Info->Len;
149 // Set tuner register reading address.
150 // Note: The I2C format of tuner register reading address setting is as follows:
151 // start_bit + (DeviceAddr | writing_bit) + RegReadingAddr + stop_bit
152 // if(pI2cBridge->ForwardI2cWritingCmd(pI2cBridge, DeviceAddr, &RegStartAddr, LEN_1_BYTE) != FUNCTION_SUCCESS)
153 // goto error_status_set_tuner_register_reading_address;
155 if (rtlsdr_i2c_write_fn(pTuner, R820T_I2C_ADDR, &RegStartAddr, 1) < 0)
158 // Get tuner register bytes.
159 // Note: The I2C format of tuner register byte getting is as follows:
160 // start_bit + (DeviceAddr | reading_bit) + reading_bytes (ReadingByteNum bytes) + stop_bit
161 // if(pI2cBridge->ForwardI2cReadingCmd(pI2cBridge, DeviceAddr, ReadingBytes, ByteNum) != FUNCTION_SUCCESS)
162 // goto error_status_get_tuner_registers;
164 if (rtlsdr_i2c_read_fn(pTuner, R820T_I2C_ADDR, ReadingBytes, ByteNum) < 0)
167 for(i = 0; i<ByteNum; i++)
169 I2C_Info->Data[i] = (UINT8)r820t_Convert(ReadingBytes[i]);
176 error_status_get_tuner_registers:
177 error_status_set_tuner_register_reading_address:
183 I2C_Write(void *pTuner, R828_I2C_TYPE *I2C_Info)
185 uint8_t WritingBuffer[2];
187 // Set writing bytes.
188 // Note: The I2C format of tuner register byte setting is as follows:
189 // start_bit + (DeviceAddr | writing_bit) + addr + data + stop_bit
190 WritingBuffer[0] = I2C_Info->RegAddr;
191 WritingBuffer[1] = I2C_Info->Data;
193 // Set tuner register bytes with writing buffer.
194 // if(pI2cBridge->ForwardI2cWritingCmd(pI2cBridge, DeviceAddr, WritingBuffer, LEN_2_BYTE) != FUNCTION_SUCCESS)
195 // goto error_status_set_tuner_registers;
197 // printf("called %s: %02x -> %02x\n", __FUNCTION__, WritingBuffer[0], WritingBuffer[1]);
199 if (rtlsdr_i2c_write_fn(pTuner, R820T_I2C_ADDR, WritingBuffer, 2) < 0)
208 unsigned long WaitTimeMs
211 /* simply don't wait for now */
215 //-----------------------------------------------------
219 // This file is R820T tuner driver
220 // Copyright 2011 by Rafaelmicro., Inc.
222 //-----------------------------------------------------
225 //#include "stdafx.h"
227 //#include "..\I2C_Sys.h"
230 #if(TUNER_CLK_OUT==TRUE) //enable tuner clk output for share Xtal application
231 UINT8 R828_iniArry[27] = {0x83, 0x32, 0x75, 0xC0, 0x40, 0xD6, 0x6C, 0xF5, 0x63,
232 /* 0x05 0x06 0x07 0x08 0x09 0x0A 0x0B 0x0C 0x0D */
234 0x75, 0x68, 0x6C, 0x83, 0x80, 0x00, 0x0F, 0x00, 0xC0,//xtal_check
235 /* 0x0E 0x0F 0x10 0x11 0x12 0x13 0x14 0x15 0x16 */
237 0x30, 0x48, 0xCC, 0x60, 0x00, 0x54, 0xAE, 0x4A, 0xC0};
238 /* 0x17 0x18 0x19 0x1A 0x1B 0x1C 0x1D 0x1E 0x1F */
240 UINT8 R828_iniArry[27] = {0x83, 0x32, 0x75, 0xC0, 0x40, 0xD6, 0x6C, 0xF5, 0x63,
241 /* 0x05 0x06 0x07 0x08 0x09 0x0A 0x0B 0x0C 0x0D */
243 0x75, 0x78, 0x6C, 0x83, 0x80, 0x00, 0x0F, 0x00, 0xC0,//xtal_check
244 /* 0x0E 0x0F 0x10 0x11 0x12 0x13 0x14 0x15 0x16 */
246 0x30, 0x48, 0xCC, 0x60, 0x00, 0x54, 0xAE, 0x4A, 0xC0};
247 /* 0x17 0x18 0x19 0x1A 0x1B 0x1C 0x1D 0x1E 0x1F */
250 UINT8 R828_ADDRESS=0x34;
251 UINT8 Rafael_Chip = R820T;
252 //----------------------------------------------------------//
253 // Internal Structs //
254 //----------------------------------------------------------//
255 typedef struct _R828_SectType
262 typedef enum _BW_Type
272 typedef struct _Sys_Info_Type
284 UINT8 FLT_EXT_WIDEST;
288 typedef struct _Freq_Info_Type
299 typedef struct _SysFreq_Info_Type
314 //----------------------------------------------------------//
315 // Internal Parameters //
316 //----------------------------------------------------------//
319 XTAL_LOW_CAP_30P = 0,
326 R828_SectType IMR_Data[5] = {
332 };//Please keep this array data for standby mode.
333 R828_I2C_TYPE R828_I2C;
334 R828_I2C_LEN_TYPE R828_I2C_Len;
337 UINT32 R828_CAL_LO_khz;
338 UINT8 R828_IMR_point_num;
339 UINT8 R828_IMR_done_flag = FALSE;
340 UINT8 R828_Fil_Cal_flag[STD_SIZE];
341 static UINT8 R828_Fil_Cal_code[STD_SIZE];
343 static UINT8 Xtal_cap_sel = XTAL_LOW_CAP_0P;
344 static UINT8 Xtal_cap_sel_tmp = XTAL_LOW_CAP_0P;
345 //----------------------------------------------------------//
346 // Internal static struct //
347 //----------------------------------------------------------//
348 static SysFreq_Info_Type SysFreq_Info1;
349 static Sys_Info_Type Sys_Info1;
350 //static Freq_Info_Type R828_Freq_Info;
351 static Freq_Info_Type Freq_Info1;
352 //----------------------------------------------------------//
353 // Internal Functions //
354 //----------------------------------------------------------//
355 R828_ErrCode R828_Xtal_Check(void *pTuner);
356 R828_ErrCode R828_InitReg(void *pTuner);
357 R828_ErrCode R828_IMR_Prepare(void *pTuner);
358 R828_ErrCode R828_IMR(void *pTuner, UINT8 IMR_MEM, int IM_Flag);
359 R828_ErrCode R828_PLL(void *pTuner, UINT32 LO_Freq, R828_Standard_Type R828_Standard);
360 R828_ErrCode R828_MUX(void *pTuner, UINT32 RF_KHz);
361 R828_ErrCode R828_IQ(void *pTuner, R828_SectType* IQ_Pont);
362 R828_ErrCode R828_IQ_Tree(void *pTuner, UINT8 FixPot, UINT8 FlucPot, UINT8 PotReg, R828_SectType* CompareTree);
363 R828_ErrCode R828_CompreCor(R828_SectType* CorArry);
364 R828_ErrCode R828_CompreStep(void *pTuner, R828_SectType* StepArry, UINT8 Pace);
365 R828_ErrCode R828_Muti_Read(void *pTuner, UINT8 IMR_Reg, UINT16* IMR_Result_Data);
366 R828_ErrCode R828_Section(void *pTuner, R828_SectType* SectionArry);
367 R828_ErrCode R828_F_IMR(void *pTuner, R828_SectType* IQ_Pont);
368 R828_ErrCode R828_IMR_Cross(void *pTuner, R828_SectType* IQ_Pont, UINT8* X_Direct);
370 Sys_Info_Type R828_Sys_Sel(R828_Standard_Type R828_Standard);
371 Freq_Info_Type R828_Freq_Sel(UINT32 RF_freq);
372 SysFreq_Info_Type R828_SysFreq_Sel(R828_Standard_Type R828_Standard,UINT32 RF_freq);
374 R828_ErrCode R828_Filt_Cal(void *pTuner, UINT32 Cal_Freq,BW_Type R828_BW);
375 //R828_ErrCode R828_SetFrequency(void *pTuner, R828_Set_Info R828_INFO, R828_SetFreq_Type R828_SetFreqMode);
377 Sys_Info_Type R828_Sys_Sel(R828_Standard_Type R828_Standard)
379 Sys_Info_Type R828_Sys_Info;
381 switch (R828_Standard)
386 R828_Sys_Info.IF_KHz=3570;
387 R828_Sys_Info.BW=BW_6M;
388 R828_Sys_Info.FILT_CAL_LO=56000; //52000->56000
389 R828_Sys_Info.FILT_GAIN=0x10; //+3dB, 6MHz on
390 R828_Sys_Info.IMG_R=0x00; //image negative
391 R828_Sys_Info.FILT_Q=0x10; //R10[4]:low Q(1'b1)
392 R828_Sys_Info.HP_COR=0x6B; // 1.7M disable, +2cap, 1.0MHz
393 R828_Sys_Info.EXT_ENABLE=0x60; //R30[6]=1 ext enable; R30[5]:1 ext at LNA max-1
394 R828_Sys_Info.LOOP_THROUGH=0x00; //R5[7], LT ON
395 R828_Sys_Info.LT_ATT=0x00; //R31[7], LT ATT enable
396 R828_Sys_Info.FLT_EXT_WIDEST=0x00;//R15[7]: FLT_EXT_WIDE OFF
397 R828_Sys_Info.POLYFIL_CUR=0x60; //R25[6:5]:Min
402 R828_Sys_Info.IF_KHz=4070;
403 R828_Sys_Info.BW=BW_7M;
404 R828_Sys_Info.FILT_CAL_LO=60000;
405 R828_Sys_Info.FILT_GAIN=0x10; //+3dB, 6MHz on
406 R828_Sys_Info.IMG_R=0x00; //image negative
407 R828_Sys_Info.FILT_Q=0x10; //R10[4]:low Q(1'b1)
408 R828_Sys_Info.HP_COR=0x2B; // 1.7M disable, +1cap, 1.0MHz
409 R828_Sys_Info.EXT_ENABLE=0x60; //R30[6]=1 ext enable; R30[5]:1 ext at LNA max-1
410 R828_Sys_Info.LOOP_THROUGH=0x00; //R5[7], LT ON
411 R828_Sys_Info.LT_ATT=0x00; //R31[7], LT ATT enable
412 R828_Sys_Info.FLT_EXT_WIDEST=0x00;//R15[7]: FLT_EXT_WIDE OFF
413 R828_Sys_Info.POLYFIL_CUR=0x60; //R25[6:5]:Min
418 R828_Sys_Info.IF_KHz=4570;
419 R828_Sys_Info.BW=BW_7M;
420 R828_Sys_Info.FILT_CAL_LO=63000;
421 R828_Sys_Info.FILT_GAIN=0x10; //+3dB, 6MHz on
422 R828_Sys_Info.IMG_R=0x00; //image negative
423 R828_Sys_Info.FILT_Q=0x10; //R10[4]:low Q(1'b1)
424 R828_Sys_Info.HP_COR=0x2A; // 1.7M disable, +1cap, 1.25MHz
425 R828_Sys_Info.EXT_ENABLE=0x60; //R30[6]=1 ext enable; R30[5]:1 ext at LNA max-1
426 R828_Sys_Info.LOOP_THROUGH=0x00; //R5[7], LT ON
427 R828_Sys_Info.LT_ATT=0x00; //R31[7], LT ATT enable
428 R828_Sys_Info.FLT_EXT_WIDEST=0x00;//R15[7]: FLT_EXT_WIDE OFF
429 R828_Sys_Info.POLYFIL_CUR=0x60; //R25[6:5]:Min
434 R828_Sys_Info.IF_KHz=4570;
435 R828_Sys_Info.BW=BW_8M;
436 R828_Sys_Info.FILT_CAL_LO=68500;
437 R828_Sys_Info.FILT_GAIN=0x10; //+3dB, 6MHz on
438 R828_Sys_Info.IMG_R=0x00; //image negative
439 R828_Sys_Info.FILT_Q=0x10; //R10[4]:low Q(1'b1)
440 R828_Sys_Info.HP_COR=0x0B; // 1.7M disable, +0cap, 1.0MHz
441 R828_Sys_Info.EXT_ENABLE=0x60; //R30[6]=1 ext enable; R30[5]:1 ext at LNA max-1
442 R828_Sys_Info.LOOP_THROUGH=0x00; //R5[7], LT ON
443 R828_Sys_Info.LT_ATT=0x00; //R31[7], LT ATT enable
444 R828_Sys_Info.FLT_EXT_WIDEST=0x00;//R15[7]: FLT_EXT_WIDE OFF
445 R828_Sys_Info.POLYFIL_CUR=0x60; //R25[6:5]:Min
449 R828_Sys_Info.IF_KHz=4063;
450 R828_Sys_Info.BW=BW_6M;
451 R828_Sys_Info.FILT_CAL_LO=59000;
452 R828_Sys_Info.FILT_GAIN=0x10; //+3dB, 6MHz on
453 R828_Sys_Info.IMG_R=0x00; //image negative
454 R828_Sys_Info.FILT_Q=0x10; //R10[4]:low Q(1'b1)
455 R828_Sys_Info.HP_COR=0x6A; // 1.7M disable, +2cap, 1.25MHz
456 R828_Sys_Info.EXT_ENABLE=0x40; //R30[6], ext enable; R30[5]:0 ext at LNA max
457 R828_Sys_Info.LOOP_THROUGH=0x00; //R5[7], LT ON
458 R828_Sys_Info.LT_ATT=0x00; //R31[7], LT ATT enable
459 R828_Sys_Info.FLT_EXT_WIDEST=0x00;//R15[7]: FLT_EXT_WIDE OFF
460 R828_Sys_Info.POLYFIL_CUR=0x60; //R25[6:5]:Min
464 R828_Sys_Info.IF_KHz=4570;
465 R828_Sys_Info.BW=BW_8M;
466 R828_Sys_Info.FILT_CAL_LO=68500;
467 R828_Sys_Info.FILT_GAIN=0x10; //+3dB, 6MHz on
468 R828_Sys_Info.IMG_R=0x00; //image negative
469 R828_Sys_Info.FILT_Q=0x10; //R10[4]:low Q(1'b1)
470 R828_Sys_Info.HP_COR=0x0D; // 1.7M disable, +0cap, 0.7MHz
471 R828_Sys_Info.EXT_ENABLE=0x60; //R30[6]=1 ext enable; R30[5]:1 ext at LNA max-1
472 R828_Sys_Info.LOOP_THROUGH=0x00; //R5[7], LT ON
473 R828_Sys_Info.LT_ATT=0x00; //R31[7], LT ATT enable
474 R828_Sys_Info.FLT_EXT_WIDEST=0x00;//R15[7]: FLT_EXT_WIDE OFF
475 R828_Sys_Info.POLYFIL_CUR=0x60; //R25[6:5]:Min
480 return R828_Sys_Info;
483 Freq_Info_Type R828_Freq_Sel(UINT32 LO_freq)
485 Freq_Info_Type R828_Freq_Info;
489 R828_Freq_Info.OPEN_D=0x08; // low
490 R828_Freq_Info.RF_MUX_PLOY = 0x02; //R26[7:6]=0 (LPF) R26[1:0]=2 (low)
491 R828_Freq_Info.TF_C=0xDF; //R27[7:0] band2,band0
492 R828_Freq_Info.XTAL_CAP20P=0x02; //R16[1:0] 20pF (10)
493 R828_Freq_Info.XTAL_CAP10P=0x01;
494 R828_Freq_Info.XTAL_CAP0P=0x00;
495 R828_Freq_Info.IMR_MEM = 0;
498 else if(LO_freq>=50000 && LO_freq<55000)
500 R828_Freq_Info.OPEN_D=0x08; // low
501 R828_Freq_Info.RF_MUX_PLOY = 0x02; //R26[7:6]=0 (LPF) R26[1:0]=2 (low)
502 R828_Freq_Info.TF_C=0xBE; //R27[7:0] band4,band1
503 R828_Freq_Info.XTAL_CAP20P=0x02; //R16[1:0] 20pF (10)
504 R828_Freq_Info.XTAL_CAP10P=0x01;
505 R828_Freq_Info.XTAL_CAP0P=0x00;
506 R828_Freq_Info.IMR_MEM = 0;
508 else if( LO_freq>=55000 && LO_freq<60000)
510 R828_Freq_Info.OPEN_D=0x08; // low
511 R828_Freq_Info.RF_MUX_PLOY = 0x02; //R26[7:6]=0 (LPF) R26[1:0]=2 (low)
512 R828_Freq_Info.TF_C=0x8B; //R27[7:0] band7,band4
513 R828_Freq_Info.XTAL_CAP20P=0x02; //R16[1:0] 20pF (10)
514 R828_Freq_Info.XTAL_CAP10P=0x01;
515 R828_Freq_Info.XTAL_CAP0P=0x00;
516 R828_Freq_Info.IMR_MEM = 0;
518 else if( LO_freq>=60000 && LO_freq<65000)
520 R828_Freq_Info.OPEN_D=0x08; // low
521 R828_Freq_Info.RF_MUX_PLOY = 0x02; //R26[7:6]=0 (LPF) R26[1:0]=2 (low)
522 R828_Freq_Info.TF_C=0x7B; //R27[7:0] band8,band4
523 R828_Freq_Info.XTAL_CAP20P=0x02; //R16[1:0] 20pF (10)
524 R828_Freq_Info.XTAL_CAP10P=0x01;
525 R828_Freq_Info.XTAL_CAP0P=0x00;
526 R828_Freq_Info.IMR_MEM = 0;
528 else if( LO_freq>=65000 && LO_freq<70000)
530 R828_Freq_Info.OPEN_D=0x08; // low
531 R828_Freq_Info.RF_MUX_PLOY = 0x02; //R26[7:6]=0 (LPF) R26[1:0]=2 (low)
532 R828_Freq_Info.TF_C=0x69; //R27[7:0] band9,band6
533 R828_Freq_Info.XTAL_CAP20P=0x02; //R16[1:0] 20pF (10)
534 R828_Freq_Info.XTAL_CAP10P=0x01;
535 R828_Freq_Info.XTAL_CAP0P=0x00;
536 R828_Freq_Info.IMR_MEM = 0;
538 else if( LO_freq>=70000 && LO_freq<75000)
540 R828_Freq_Info.OPEN_D=0x08; // low
541 R828_Freq_Info.RF_MUX_PLOY = 0x02; //R26[7:6]=0 (LPF) R26[1:0]=2 (low)
542 R828_Freq_Info.TF_C=0x58; //R27[7:0] band10,band7
543 R828_Freq_Info.XTAL_CAP20P=0x02; //R16[1:0] 20pF (10)
544 R828_Freq_Info.XTAL_CAP10P=0x01;
545 R828_Freq_Info.XTAL_CAP0P=0x00;
546 R828_Freq_Info.IMR_MEM = 0;
548 else if( LO_freq>=75000 && LO_freq<80000)
550 R828_Freq_Info.OPEN_D=0x00; // high
551 R828_Freq_Info.RF_MUX_PLOY = 0x02; //R26[7:6]=0 (LPF) R26[1:0]=2 (low)
552 R828_Freq_Info.TF_C=0x44; //R27[7:0] band11,band11
553 R828_Freq_Info.XTAL_CAP20P=0x02; //R16[1:0] 20pF (10)
554 R828_Freq_Info.XTAL_CAP10P=0x01;
555 R828_Freq_Info.XTAL_CAP0P=0x00;
556 R828_Freq_Info.IMR_MEM = 0;
558 else if( LO_freq>=80000 && LO_freq<90000)
560 R828_Freq_Info.OPEN_D=0x00; // high
561 R828_Freq_Info.RF_MUX_PLOY = 0x02; //R26[7:6]=0 (LPF) R26[1:0]=2 (low)
562 R828_Freq_Info.TF_C=0x44; //R27[7:0] band11,band11
563 R828_Freq_Info.XTAL_CAP20P=0x02; //R16[1:0] 20pF (10)
564 R828_Freq_Info.XTAL_CAP10P=0x01;
565 R828_Freq_Info.XTAL_CAP0P=0x00;
566 R828_Freq_Info.IMR_MEM = 0;
568 else if( LO_freq>=90000 && LO_freq<100000)
570 R828_Freq_Info.OPEN_D=0x00; // high
571 R828_Freq_Info.RF_MUX_PLOY = 0x02; //R26[7:6]=0 (LPF) R26[1:0]=2 (low)
572 R828_Freq_Info.TF_C=0x34; //R27[7:0] band12,band11
573 R828_Freq_Info.XTAL_CAP20P=0x01; //R16[1:0] 10pF (01)
574 R828_Freq_Info.XTAL_CAP10P=0x01;
575 R828_Freq_Info.XTAL_CAP0P=0x00;
576 R828_Freq_Info.IMR_MEM = 0;
578 else if( LO_freq>=100000 && LO_freq<110000)
580 R828_Freq_Info.OPEN_D=0x00; // high
581 R828_Freq_Info.RF_MUX_PLOY = 0x02; //R26[7:6]=0 (LPF) R26[1:0]=2 (low)
582 R828_Freq_Info.TF_C=0x34; //R27[7:0] band12,band11
583 R828_Freq_Info.XTAL_CAP20P=0x01; //R16[1:0] 10pF (01)
584 R828_Freq_Info.XTAL_CAP10P=0x01;
585 R828_Freq_Info.XTAL_CAP0P=0x00;
586 R828_Freq_Info.IMR_MEM = 0;
588 else if( LO_freq>=110000 && LO_freq<120000)
590 R828_Freq_Info.OPEN_D=0x00; // high
591 R828_Freq_Info.RF_MUX_PLOY = 0x02; //R26[7:6]=0 (LPF) R26[1:0]=2 (low)
592 R828_Freq_Info.TF_C=0x24; //R27[7:0] band13,band11
593 R828_Freq_Info.XTAL_CAP20P=0x01; //R16[1:0] 10pF (01)
594 R828_Freq_Info.XTAL_CAP10P=0x01;
595 R828_Freq_Info.XTAL_CAP0P=0x00;
596 R828_Freq_Info.IMR_MEM = 1;
598 else if( LO_freq>=120000 && LO_freq<140000)
600 R828_Freq_Info.OPEN_D=0x00; // high
601 R828_Freq_Info.RF_MUX_PLOY = 0x02; //R26[7:6]=0 (LPF) R26[1:0]=2 (low)
602 R828_Freq_Info.TF_C=0x24; //R27[7:0] band13,band11
603 R828_Freq_Info.XTAL_CAP20P=0x01; //R16[1:0] 10pF (01)
604 R828_Freq_Info.XTAL_CAP10P=0x01;
605 R828_Freq_Info.XTAL_CAP0P=0x00;
606 R828_Freq_Info.IMR_MEM = 1;
608 else if( LO_freq>=140000 && LO_freq<180000)
610 R828_Freq_Info.OPEN_D=0x00; // high
611 R828_Freq_Info.RF_MUX_PLOY = 0x02; //R26[7:6]=0 (LPF) R26[1:0]=2 (low)
612 R828_Freq_Info.TF_C=0x14; //R27[7:0] band14,band11
613 R828_Freq_Info.XTAL_CAP20P=0x01; //R16[1:0] 10pF (01)
614 R828_Freq_Info.XTAL_CAP10P=0x01;
615 R828_Freq_Info.XTAL_CAP0P=0x00;
616 R828_Freq_Info.IMR_MEM = 1;
618 else if( LO_freq>=180000 && LO_freq<220000)
620 R828_Freq_Info.OPEN_D=0x00; // high
621 R828_Freq_Info.RF_MUX_PLOY = 0x02; //R26[7:6]=0 (LPF) R26[1:0]=2 (low)
622 R828_Freq_Info.TF_C=0x13; //R27[7:0] band14,band12
623 R828_Freq_Info.XTAL_CAP20P=0x00; //R16[1:0] 0pF (00)
624 R828_Freq_Info.XTAL_CAP10P=0x00;
625 R828_Freq_Info.XTAL_CAP0P=0x00;
626 R828_Freq_Info.IMR_MEM = 1;
628 else if( LO_freq>=220000 && LO_freq<250000)
630 R828_Freq_Info.OPEN_D=0x00; // high
631 R828_Freq_Info.RF_MUX_PLOY = 0x02; //R26[7:6]=0 (LPF) R26[1:0]=2 (low)
632 R828_Freq_Info.TF_C=0x13; //R27[7:0] band14,band12
633 R828_Freq_Info.XTAL_CAP20P=0x00; //R16[1:0] 0pF (00)
634 R828_Freq_Info.XTAL_CAP10P=0x00;
635 R828_Freq_Info.XTAL_CAP0P=0x00;
636 R828_Freq_Info.IMR_MEM = 2;
638 else if( LO_freq>=250000 && LO_freq<280000)
640 R828_Freq_Info.OPEN_D=0x00; // high
641 R828_Freq_Info.RF_MUX_PLOY = 0x02; //R26[7:6]=0 (LPF) R26[1:0]=2 (low)
642 R828_Freq_Info.TF_C=0x11; //R27[7:0] highest,highest
643 R828_Freq_Info.XTAL_CAP20P=0x00; //R16[1:0] 0pF (00)
644 R828_Freq_Info.XTAL_CAP10P=0x00;
645 R828_Freq_Info.XTAL_CAP0P=0x00;
646 R828_Freq_Info.IMR_MEM = 2;
648 else if( LO_freq>=280000 && LO_freq<310000)
650 R828_Freq_Info.OPEN_D=0x00; // high
651 R828_Freq_Info.RF_MUX_PLOY = 0x02; //R26[7:6]=0 (LPF) R26[1:0]=2 (low)
652 R828_Freq_Info.TF_C=0x00; //R27[7:0] highest,highest
653 R828_Freq_Info.XTAL_CAP20P=0x00; //R16[1:0] 0pF (00)
654 R828_Freq_Info.XTAL_CAP10P=0x00;
655 R828_Freq_Info.XTAL_CAP0P=0x00;
656 R828_Freq_Info.IMR_MEM = 2;
658 else if( LO_freq>=310000 && LO_freq<450000)
660 R828_Freq_Info.OPEN_D=0x00; // high
661 R828_Freq_Info.RF_MUX_PLOY = 0x41; //R26[7:6]=1 (bypass) R26[1:0]=1 (middle)
662 R828_Freq_Info.TF_C=0x00; //R27[7:0] highest,highest
663 R828_Freq_Info.XTAL_CAP20P=0x00; //R16[1:0] 0pF (00)
664 R828_Freq_Info.XTAL_CAP10P=0x00;
665 R828_Freq_Info.XTAL_CAP0P=0x00;
666 R828_Freq_Info.IMR_MEM = 2;
668 else if( LO_freq>=450000 && LO_freq<588000)
670 R828_Freq_Info.OPEN_D=0x00; // high
671 R828_Freq_Info.RF_MUX_PLOY = 0x41; //R26[7:6]=1 (bypass) R26[1:0]=1 (middle)
672 R828_Freq_Info.TF_C=0x00; //R27[7:0] highest,highest
673 R828_Freq_Info.XTAL_CAP20P=0x00; //R16[1:0] 0pF (00)
674 R828_Freq_Info.XTAL_CAP10P=0x00;
675 R828_Freq_Info.XTAL_CAP0P=0x00;
676 R828_Freq_Info.IMR_MEM = 3;
678 else if( LO_freq>=588000 && LO_freq<650000)
680 R828_Freq_Info.OPEN_D=0x00; // high
681 R828_Freq_Info.RF_MUX_PLOY = 0x40; //R26[7:6]=1 (bypass) R26[1:0]=0 (highest)
682 R828_Freq_Info.TF_C=0x00; //R27[7:0] highest,highest
683 R828_Freq_Info.XTAL_CAP20P=0x00; //R16[1:0] 0pF (00)
684 R828_Freq_Info.XTAL_CAP10P=0x00;
685 R828_Freq_Info.XTAL_CAP0P=0x00;
686 R828_Freq_Info.IMR_MEM = 3;
690 R828_Freq_Info.OPEN_D=0x00; // high
691 R828_Freq_Info.RF_MUX_PLOY = 0x40; //R26[7:6]=1 (bypass) R26[1:0]=0 (highest)
692 R828_Freq_Info.TF_C=0x00; //R27[7:0] highest,highest
693 R828_Freq_Info.XTAL_CAP20P=0x00; //R16[1:0] 0pF (00)
694 R828_Freq_Info.XTAL_CAP10P=0x00;
695 R828_Freq_Info.XTAL_CAP0P=0x00;
696 R828_Freq_Info.IMR_MEM = 4;
699 return R828_Freq_Info;
702 SysFreq_Info_Type R828_SysFreq_Sel(R828_Standard_Type R828_Standard,UINT32 RF_freq)
704 SysFreq_Info_Type R828_SysFreq_Info;
706 switch(R828_Standard)
713 if( (RF_freq==506000) || (RF_freq==666000) || (RF_freq==818000) )
715 R828_SysFreq_Info.MIXER_TOP=0x14; // MIXER TOP:14 , TOP-1, low-discharge
716 R828_SysFreq_Info.LNA_TOP=0xE5; // Detect BW 3, LNA TOP:4, PreDet Top:2
717 R828_SysFreq_Info.CP_CUR=0x28; //101, 0.2
718 R828_SysFreq_Info.DIV_BUF_CUR=0x20; // 10, 200u
722 R828_SysFreq_Info.MIXER_TOP=0x24; // MIXER TOP:13 , TOP-1, low-discharge
723 R828_SysFreq_Info.LNA_TOP=0xE5; // Detect BW 3, LNA TOP:4, PreDet Top:2
724 R828_SysFreq_Info.CP_CUR=0x38; // 111, auto
725 R828_SysFreq_Info.DIV_BUF_CUR=0x30; // 11, 150u
727 R828_SysFreq_Info.LNA_VTH_L=0x53; // LNA VTH 0.84 , VTL 0.64
728 R828_SysFreq_Info.MIXER_VTH_L=0x75; // MIXER VTH 1.04, VTL 0.84
729 R828_SysFreq_Info.AIR_CABLE1_IN=0x00;
730 R828_SysFreq_Info.CABLE2_IN=0x00;
731 R828_SysFreq_Info.PRE_DECT=0x40;
732 R828_SysFreq_Info.LNA_DISCHARGE=14;
733 R828_SysFreq_Info.FILTER_CUR=0x40; // 10, low
741 R828_SysFreq_Info.MIXER_TOP=0x24; // MIXER TOP:13 , TOP-1, low-discharge
742 R828_SysFreq_Info.LNA_TOP=0xE5; // Detect BW 3, LNA TOP:4, PreDet Top:2
743 R828_SysFreq_Info.LNA_VTH_L=0x53; // LNA VTH 0.84 , VTL 0.64
744 R828_SysFreq_Info.MIXER_VTH_L=0x75; // MIXER VTH 1.04, VTL 0.84
745 R828_SysFreq_Info.AIR_CABLE1_IN=0x00;
746 R828_SysFreq_Info.CABLE2_IN=0x00;
747 R828_SysFreq_Info.PRE_DECT=0x40;
748 R828_SysFreq_Info.LNA_DISCHARGE=14;
749 R828_SysFreq_Info.CP_CUR=0x38; // 111, auto
750 R828_SysFreq_Info.DIV_BUF_CUR=0x30; // 11, 150u
751 R828_SysFreq_Info.FILTER_CUR=0x40; // 10, low
755 R828_SysFreq_Info.MIXER_TOP=0x24; // MIXER TOP:13 , TOP-1, low-discharge
756 R828_SysFreq_Info.LNA_TOP=0xE5; // Detect BW 3, LNA TOP:4, PreDet Top:2
757 R828_SysFreq_Info.LNA_VTH_L=0x75; // LNA VTH 1.04 , VTL 0.84
758 R828_SysFreq_Info.MIXER_VTH_L=0x75; // MIXER VTH 1.04, VTL 0.84
759 R828_SysFreq_Info.AIR_CABLE1_IN=0x00;
760 R828_SysFreq_Info.CABLE2_IN=0x00;
761 R828_SysFreq_Info.PRE_DECT=0x40;
762 R828_SysFreq_Info.LNA_DISCHARGE=14;
763 R828_SysFreq_Info.CP_CUR=0x38; // 111, auto
764 R828_SysFreq_Info.DIV_BUF_CUR=0x30; // 11, 150u
765 R828_SysFreq_Info.FILTER_CUR=0x40; // 10, low
769 R828_SysFreq_Info.MIXER_TOP=0x24; // MIXER TOP:13 , TOP-1, low-discharge
770 R828_SysFreq_Info.LNA_TOP=0xE5; // Detect BW 3, LNA TOP:4, PreDet Top:2
771 R828_SysFreq_Info.LNA_VTH_L=0x53; // LNA VTH 0.84 , VTL 0.64
772 R828_SysFreq_Info.MIXER_VTH_L=0x75; // MIXER VTH 1.04, VTL 0.84
773 R828_SysFreq_Info.AIR_CABLE1_IN=0x00;
774 R828_SysFreq_Info.CABLE2_IN=0x00;
775 R828_SysFreq_Info.PRE_DECT=0x40;
776 R828_SysFreq_Info.LNA_DISCHARGE=14;
777 R828_SysFreq_Info.CP_CUR=0x38; // 111, auto
778 R828_SysFreq_Info.DIV_BUF_CUR=0x30; // 11, 150u
779 R828_SysFreq_Info.FILTER_CUR=0x40; // 10, low
785 #if(USE_DIPLEXER==TRUE)
786 if ((Rafael_Chip==R820C) || (Rafael_Chip==R820T) || (Rafael_Chip==R828S))
788 // Air-in (>=DIP_FREQ) & cable-1(<DIP_FREQ)
789 if(RF_freq >= DIP_FREQ)
791 R828_SysFreq_Info.AIR_CABLE1_IN = 0x00; //air in, cable-1 off
792 R828_SysFreq_Info.CABLE2_IN = 0x00; //cable-2 off
796 R828_SysFreq_Info.AIR_CABLE1_IN = 0x60; //cable-1 in, air off
797 R828_SysFreq_Info.CABLE2_IN = 0x00; //cable-2 off
801 return R828_SysFreq_Info;
805 R828_ErrCode R828_Xtal_Check(void *pTuner)
810 for(ArrayNum=0;ArrayNum<27;ArrayNum++)
812 R828_Arry[ArrayNum] = R828_iniArry[ArrayNum];
815 //cap 30pF & Drive Low
816 R828_I2C.RegAddr = 0x10;
817 R828_Arry[11] = (R828_Arry[11] & 0xF4) | 0x0B ;
818 R828_I2C.Data = R828_Arry[11];
819 if(I2C_Write(pTuner, &R828_I2C) != RT_Success)
822 //set pll autotune = 128kHz
823 R828_I2C.RegAddr = 0x1A;
824 R828_Arry[21] = R828_Arry[21] & 0xF3;
825 R828_I2C.Data = R828_Arry[21];
826 if(I2C_Write(pTuner, &R828_I2C) != RT_Success)
829 //set manual initial reg = 111111;
830 R828_I2C.RegAddr = 0x13;
831 R828_Arry[14] = (R828_Arry[14] & 0x80) | 0x7F;
832 R828_I2C.Data = R828_Arry[14];
833 if(I2C_Write(pTuner, &R828_I2C) != RT_Success)
837 R828_I2C.RegAddr = 0x13;
838 R828_Arry[14] = (R828_Arry[14] & 0xBF);
839 R828_I2C.Data = R828_Arry[14];
840 if(I2C_Write(pTuner, &R828_I2C) != RT_Success)
843 R828_Delay_MS(pTuner, 5);
845 R828_I2C_Len.RegAddr = 0x00;
846 R828_I2C_Len.Len = 3;
847 if(I2C_Read_Len(pTuner, &R828_I2C_Len) != RT_Success)
850 // if 30pF unlock, set to cap 20pF
851 #if (USE_16M_XTAL==TRUE)
852 //VCO=2360MHz for 16M Xtal. VCO band 26
853 if(((R828_I2C_Len.Data[2] & 0x40) == 0x00) || ((R828_I2C_Len.Data[2] & 0x3F) > 29) || ((R828_I2C_Len.Data[2] & 0x3F) < 23))
855 if(((R828_I2C_Len.Data[2] & 0x40) == 0x00) || ((R828_I2C_Len.Data[2] & 0x3F) == 0x3F))
859 R828_I2C.RegAddr = 0x10;
860 R828_Arry[11] = (R828_Arry[11] & 0xFC) | 0x02;
861 R828_I2C.Data = R828_Arry[11];
862 if(I2C_Write(pTuner, &R828_I2C) != RT_Success)
865 R828_Delay_MS(pTuner, 5);
867 R828_I2C_Len.RegAddr = 0x00;
868 R828_I2C_Len.Len = 3;
869 if(I2C_Read_Len(pTuner, &R828_I2C_Len) != RT_Success)
872 // if 20pF unlock, set to cap 10pF
873 #if (USE_16M_XTAL==TRUE)
874 if(((R828_I2C_Len.Data[2] & 0x40) == 0x00) || ((R828_I2C_Len.Data[2] & 0x3F) > 29) || ((R828_I2C_Len.Data[2] & 0x3F) < 23))
876 if(((R828_I2C_Len.Data[2] & 0x40) == 0x00) || ((R828_I2C_Len.Data[2] & 0x3F) == 0x3F))
880 R828_I2C.RegAddr = 0x10;
881 R828_Arry[11] = (R828_Arry[11] & 0xFC) | 0x01;
882 R828_I2C.Data = R828_Arry[11];
883 if(I2C_Write(pTuner, &R828_I2C) != RT_Success)
886 R828_Delay_MS(pTuner, 5);
888 R828_I2C_Len.RegAddr = 0x00;
889 R828_I2C_Len.Len = 3;
890 if(I2C_Read_Len(pTuner, &R828_I2C_Len) != RT_Success)
893 // if 10pF unlock, set to cap 0pF
894 #if (USE_16M_XTAL==TRUE)
895 if(((R828_I2C_Len.Data[2] & 0x40) == 0x00) || ((R828_I2C_Len.Data[2] & 0x3F) > 29) || ((R828_I2C_Len.Data[2] & 0x3F) < 23))
897 if(((R828_I2C_Len.Data[2] & 0x40) == 0x00) || ((R828_I2C_Len.Data[2] & 0x3F) == 0x3F))
901 R828_I2C.RegAddr = 0x10;
902 R828_Arry[11] = (R828_Arry[11] & 0xFC) | 0x00;
903 R828_I2C.Data = R828_Arry[11];
904 if(I2C_Write(pTuner, &R828_I2C) != RT_Success)
907 R828_Delay_MS(pTuner, 5);
909 R828_I2C_Len.RegAddr = 0x00;
910 R828_I2C_Len.Len = 3;
911 if(I2C_Read_Len(pTuner, &R828_I2C_Len) != RT_Success)
914 // if unlock, set to high drive
915 #if (USE_16M_XTAL==TRUE)
916 if(((R828_I2C_Len.Data[2] & 0x40) == 0x00) || ((R828_I2C_Len.Data[2] & 0x3F) > 29) || ((R828_I2C_Len.Data[2] & 0x3F) < 23))
918 if(((R828_I2C_Len.Data[2] & 0x40) == 0x00) || ((R828_I2C_Len.Data[2] & 0x3F) == 0x3F))
922 R828_I2C.RegAddr = 0x10;
923 R828_Arry[11] = (R828_Arry[11] & 0xF7) ;
924 R828_I2C.Data = R828_Arry[11];
925 if(I2C_Write(pTuner, &R828_I2C) != RT_Success)
929 R828_Delay_MS(pTuner, 20);
931 R828_I2C_Len.RegAddr = 0x00;
932 R828_I2C_Len.Len = 3;
933 if(I2C_Read_Len(pTuner, &R828_I2C_Len) != RT_Success)
936 #if (USE_16M_XTAL==TRUE)
937 if(((R828_I2C_Len.Data[2] & 0x40) == 0x00) || ((R828_I2C_Len.Data[2] & 0x3F) > 29) || ((R828_I2C_Len.Data[2] & 0x3F) < 23))
939 if(((R828_I2C_Len.Data[2] & 0x40) == 0x00) || ((R828_I2C_Len.Data[2] & 0x3F) == 0x3F))
944 else //0p+high drive lock
946 Xtal_cap_sel_tmp = XTAL_HIGH_CAP_0P;
951 Xtal_cap_sel_tmp = XTAL_LOW_CAP_0P;
956 Xtal_cap_sel_tmp = XTAL_LOW_CAP_10P;
961 Xtal_cap_sel_tmp = XTAL_LOW_CAP_20P;
966 Xtal_cap_sel_tmp = XTAL_LOW_CAP_30P;
971 R828_ErrCode R828_Init(void *pTuner)
973 // R820T_EXTRA_MODULE *pExtra;
976 // Get tuner extra module.
977 // pExtra = &(pTuner->Extra.R820t);
980 //if(R828_InitReg(pTuner) != RT_Success)
983 if(R828_IMR_done_flag==FALSE)
987 // if(R828_InitReg(pTuner) != RT_Success)
991 if((Rafael_Chip==R820T) || (Rafael_Chip==R828S) || (Rafael_Chip==R820C))
993 Xtal_cap_sel = XTAL_HIGH_CAP_0P;
997 if(R828_Xtal_Check(pTuner) != RT_Success) //1st
1000 Xtal_cap_sel = Xtal_cap_sel_tmp;
1002 if(R828_Xtal_Check(pTuner) != RT_Success) //2nd
1005 if(Xtal_cap_sel_tmp > Xtal_cap_sel)
1007 Xtal_cap_sel = Xtal_cap_sel_tmp;
1010 if(R828_Xtal_Check(pTuner) != RT_Success) //3rd
1013 if(Xtal_cap_sel_tmp > Xtal_cap_sel)
1015 Xtal_cap_sel = Xtal_cap_sel_tmp;
1021 for (i=0; i<STD_SIZE; i++)
1023 R828_Fil_Cal_flag[i] = FALSE;
1024 R828_Fil_Cal_code[i] = 0;
1029 if(R828_InitReg(pTuner) != RT_Success) //write initial reg before doing cal
1032 if(R828_IMR_Prepare(pTuner) != RT_Success)
1035 if(R828_IMR(pTuner, 3, TRUE) != RT_Success) //Full K node 3
1038 if(R828_IMR(pTuner, 1, FALSE) != RT_Success)
1041 if(R828_IMR(pTuner, 0, FALSE) != RT_Success)
1044 if(R828_IMR(pTuner, 2, FALSE) != RT_Success)
1047 if(R828_IMR(pTuner, 4, FALSE) != RT_Success)
1050 R828_IMR_done_flag = TRUE;
1055 if(R828_InitReg(pTuner) != RT_Success)
1063 R828_ErrCode R828_InitReg(void *pTuner)
1065 UINT8 InitArryCount;
1071 //UINT32 LO_KHz = 0;
1074 R828_I2C_Len.RegAddr = 0x05;
1075 R828_I2C_Len.Len = InitArryNum;
1076 for(InitArryCount = 0;InitArryCount < InitArryNum;InitArryCount ++)
1078 R828_I2C_Len.Data[InitArryCount] = R828_iniArry[InitArryCount];
1080 if(I2C_Write_Len(pTuner, &R828_I2C_Len) != RT_Success)
1087 R828_ErrCode R828_IMR_Prepare(void *pTuner)
1094 for(ArrayNum=0;ArrayNum<27;ArrayNum++)
1096 R828_Arry[ArrayNum] = R828_iniArry[ArrayNum];
1099 //lna off (air-in off)
1100 R828_I2C.RegAddr = 0x05;
1101 R828_Arry[0] = R828_Arry[0] | 0x20;
1102 R828_I2C.Data = R828_Arry[0];
1103 if(I2C_Write(pTuner, &R828_I2C) != RT_Success)
1105 //mixer gain mode = manual
1106 R828_I2C.RegAddr = 0x07;
1107 R828_Arry[2] = (R828_Arry[2] & 0xEF);
1108 R828_I2C.Data = R828_Arry[2];
1109 if(I2C_Write(pTuner, &R828_I2C) != RT_Success)
1111 //filter corner = lowest
1112 R828_I2C.RegAddr = 0x0A;
1113 R828_Arry[5] = R828_Arry[5] | 0x0F;
1114 R828_I2C.Data = R828_Arry[5];
1115 if(I2C_Write(pTuner, &R828_I2C) != RT_Success)
1117 //filter bw=+2cap, hp=5M
1118 R828_I2C.RegAddr = 0x0B;
1119 R828_Arry[6] = (R828_Arry[6] & 0x90) | 0x60;
1120 R828_I2C.Data = R828_Arry[6];
1121 if(I2C_Write(pTuner, &R828_I2C) != RT_Success)
1123 //adc=on, vga code mode, gain = 26.5dB
1124 R828_I2C.RegAddr = 0x0C;
1125 R828_Arry[7] = (R828_Arry[7] & 0x60) | 0x0B;
1126 R828_I2C.Data = R828_Arry[7];
1127 if(I2C_Write(pTuner, &R828_I2C) != RT_Success)
1130 R828_I2C.RegAddr = 0x0F;
1131 R828_Arry[10] &= 0xF7;
1132 R828_I2C.Data = R828_Arry[10];
1133 if(I2C_Write(pTuner, &R828_I2C) != RT_Success)
1136 R828_I2C.RegAddr = 0x18;
1137 R828_Arry[19] = R828_Arry[19] | 0x10;
1138 R828_I2C.Data = R828_Arry[19];
1139 if(I2C_Write(pTuner, &R828_I2C) != RT_Success)
1141 //from ring = ring pll in
1142 R828_I2C.RegAddr = 0x1C;
1143 R828_Arry[23] = R828_Arry[23] | 0x02;
1144 R828_I2C.Data = R828_Arry[23];
1145 if(I2C_Write(pTuner, &R828_I2C) != RT_Success)
1148 R828_I2C.RegAddr = 0x1E;
1149 R828_Arry[25] = R828_Arry[25] | 0x80;
1150 R828_I2C.Data = R828_Arry[25];
1151 if(I2C_Write(pTuner, &R828_I2C) != RT_Success)
1154 R828_Arry[1] = R828_Arry[1] | 0x20;
1155 R828_I2C.RegAddr = 0x06;
1156 R828_I2C.Data = R828_Arry[1];
1157 if(I2C_Write(pTuner, &R828_I2C) != RT_Success)
1163 R828_ErrCode R828_IMR(void *pTuner, UINT8 IMR_MEM, int IM_Flag)
1172 R828_SectType IMR_POINT;
1180 if (R828_Xtal>24000)
1181 RingRef = R828_Xtal /2;
1183 RingRef = R828_Xtal;
1187 if((16+n)* 8 * RingRef >= 3100000)
1193 if(n==15) //n_ring not found
1201 R828_Arry[19] &= 0xF0; //set ring[3:0]
1202 R828_Arry[19] |= n_ring;
1203 RingVCO = (16+n_ring)* 8 * RingRef;
1204 R828_Arry[19]&=0xDF; //clear ring_se23
1205 R828_Arry[20]&=0xFC; //clear ring_seldiv
1206 R828_Arry[26]&=0xFC; //clear ring_att
1211 RingFreq = RingVCO/48;
1212 R828_Arry[19]|=0x20; // ring_se23 = 1
1213 R828_Arry[20]|=0x03; // ring_seldiv = 3
1214 R828_Arry[26]|=0x02; // ring_att 10
1217 RingFreq = RingVCO/16;
1218 R828_Arry[19]|=0x00; // ring_se23 = 0
1219 R828_Arry[20]|=0x02; // ring_seldiv = 2
1220 R828_Arry[26]|=0x00; // pw_ring 00
1223 RingFreq = RingVCO/8;
1224 R828_Arry[19]|=0x00; // ring_se23 = 0
1225 R828_Arry[20]|=0x01; // ring_seldiv = 1
1226 R828_Arry[26]|=0x03; // pw_ring 11
1229 RingFreq = RingVCO/6;
1230 R828_Arry[19]|=0x20; // ring_se23 = 1
1231 R828_Arry[20]|=0x00; // ring_seldiv = 0
1232 R828_Arry[26]|=0x03; // pw_ring 11
1235 RingFreq = RingVCO/4;
1236 R828_Arry[19]|=0x00; // ring_se23 = 0
1237 R828_Arry[20]|=0x00; // ring_seldiv = 0
1238 R828_Arry[26]|=0x01; // pw_ring 01
1241 RingFreq = RingVCO/4;
1242 R828_Arry[19]|=0x00; // ring_se23 = 0
1243 R828_Arry[20]|=0x00; // ring_seldiv = 0
1244 R828_Arry[26]|=0x01; // pw_ring 01
1249 //write pw_ring,n_ring,ringdiv2 to I2C
1251 //------------n_ring,ring_se23----------//
1252 R828_I2C.RegAddr = 0x18;
1253 R828_I2C.Data = R828_Arry[19];
1254 if(I2C_Write(pTuner, &R828_I2C) != RT_Success)
1256 //------------ring_sediv----------------//
1257 R828_I2C.RegAddr = 0x19;
1258 R828_I2C.Data = R828_Arry[20];
1259 if(I2C_Write(pTuner, &R828_I2C) != RT_Success)
1261 //------------pw_ring-------------------//
1262 R828_I2C.RegAddr = 0x1f;
1263 R828_I2C.Data = R828_Arry[26];
1264 if(I2C_Write(pTuner, &R828_I2C) != RT_Success)
1267 //Must do before PLL()
1268 if(R828_MUX(pTuner, RingFreq - 5300) != RT_Success) //MUX input freq ~ RF_in Freq
1271 if(R828_PLL(pTuner, (RingFreq - 5300) * 1000, STD_SIZE) != RT_Success) //set pll freq = ring freq - 6M
1276 if(R828_IQ(pTuner, &IMR_POINT) != RT_Success)
1281 IMR_POINT.Gain_X = IMR_Data[3].Gain_X;
1282 IMR_POINT.Phase_Y = IMR_Data[3].Phase_Y;
1283 IMR_POINT.Value = IMR_Data[3].Value;
1284 if(R828_F_IMR(pTuner, &IMR_POINT) != RT_Success)
1292 IMR_Data[0].Gain_X = IMR_POINT.Gain_X;
1293 IMR_Data[0].Phase_Y = IMR_POINT.Phase_Y;
1294 IMR_Data[0].Value = IMR_POINT.Value;
1297 IMR_Data[1].Gain_X = IMR_POINT.Gain_X;
1298 IMR_Data[1].Phase_Y = IMR_POINT.Phase_Y;
1299 IMR_Data[1].Value = IMR_POINT.Value;
1302 IMR_Data[2].Gain_X = IMR_POINT.Gain_X;
1303 IMR_Data[2].Phase_Y = IMR_POINT.Phase_Y;
1304 IMR_Data[2].Value = IMR_POINT.Value;
1307 IMR_Data[3].Gain_X = IMR_POINT.Gain_X;
1308 IMR_Data[3].Phase_Y = IMR_POINT.Phase_Y;
1309 IMR_Data[3].Value = IMR_POINT.Value;
1312 IMR_Data[4].Gain_X = IMR_POINT.Gain_X;
1313 IMR_Data[4].Phase_Y = IMR_POINT.Phase_Y;
1314 IMR_Data[4].Value = IMR_POINT.Value;
1317 IMR_Data[4].Gain_X = IMR_POINT.Gain_X;
1318 IMR_Data[4].Phase_Y = IMR_POINT.Phase_Y;
1319 IMR_Data[4].Value = IMR_POINT.Value;
1325 R828_ErrCode R828_PLL(void *pTuner, UINT32 LO_Freq, R828_Standard_Type R828_Standard)
1328 // R820T_EXTRA_MODULE *pExtra;
1339 UINT32 PLL_Ref; //Max 24000 (kHz)
1340 UINT32 VCO_Fra; //VCO contribution by SDM (kHz)
1346 UINT8 VCO_fine_tune;
1354 VCO_Min_kHz = 1770000;
1355 VCO_Max_kHz = VCO_Min_kHz*2;
1357 PLL_Ref = 0; //Max 24000 (kHz)
1358 VCO_Fra = 0; //VCO contribution by SDM (kHz)
1367 if ((Rafael_Chip==R620D) || (Rafael_Chip==R828D) || (Rafael_Chip==R828)) //X'tal can't not exceed 20MHz for ATV
1369 if(R828_Standard <= SECAM_L1) //ref set refdiv2, reffreq = Xtal/2 on ATV application
1371 R828_Arry[11] |= 0x10; //b4=1
1372 PLL_Ref = R828_Xtal /2;
1374 else //DTV, FilCal, IMR
1376 R828_Arry[11] &= 0xEF;
1377 PLL_Ref = R828_Xtal;
1382 if(R828_Xtal > 24000)
1384 R828_Arry[11] |= 0x10; //b4=1
1385 PLL_Ref = R828_Xtal /2;
1389 R828_Arry[11] &= 0xEF;
1390 PLL_Ref = R828_Xtal;
1395 R828_Arry[11] &= 0xEF;
1396 PLL_Ref = rtlsdr_get_tuner_clock(pTuner);
1398 R828_I2C.RegAddr = 0x10;
1399 R828_I2C.Data = R828_Arry[11];
1400 if(I2C_Write(pTuner, &R828_I2C) != RT_Success)
1403 //set pll autotune = 128kHz
1404 R828_I2C.RegAddr = 0x1A;
1405 R828_Arry[21] = R828_Arry[21] & 0xF3;
1406 R828_I2C.Data = R828_Arry[21];
1407 if(I2C_Write(pTuner, &R828_I2C) != RT_Success)
1410 //Set VCO current = 100
1411 R828_I2C.RegAddr = 0x12;
1412 R828_Arry[13] = (R828_Arry[13] & 0x1F) | 0x80;
1413 R828_I2C.Data = R828_Arry[13];
1414 if(I2C_Write(pTuner, &R828_I2C) != RT_Success)
1420 if((((LO_Freq/1000) * MixDiv) >= VCO_Min_kHz) && (((LO_Freq/1000) * MixDiv) < VCO_Max_kHz))
1425 DivBuf = DivBuf >> 1;
1430 MixDiv = MixDiv << 1;
1433 R828_I2C_Len.RegAddr = 0x00;
1434 R828_I2C_Len.Len = 5;
1435 if(I2C_Read_Len(pTuner, &R828_I2C_Len) != RT_Success)
1438 VCO_fine_tune = (R828_I2C_Len.Data[4] & 0x30)>>4;
1440 if(VCO_fine_tune > VCO_pwr_ref)
1441 DivNum = DivNum - 1;
1442 else if(VCO_fine_tune < VCO_pwr_ref)
1443 DivNum = DivNum + 1;
1445 R828_I2C.RegAddr = 0x10;
1446 R828_Arry[11] &= 0x1F;
1447 R828_Arry[11] |= (DivNum << 5);
1448 R828_I2C.Data = R828_Arry[11];
1449 if(I2C_Write(pTuner, &R828_I2C) != RT_Success)
1452 VCO_Freq = (uint64_t)(LO_Freq * (uint64_t)MixDiv);
1453 Nint = (UINT8) (VCO_Freq / 2 / PLL_Ref);
1454 VCO_Fra = (UINT16) ((VCO_Freq - 2 * PLL_Ref * Nint) / 1000);
1459 // printf("VCO_Freq = %lu, Nint= %u, VCO_Fra= %lu, LO_Freq= %u, MixDiv= %u\n", VCO_Freq, Nint, VCO_Fra, LO_Freq, MixDiv);
1461 //boundary spur prevention
1462 if (VCO_Fra < PLL_Ref/64) //2*PLL_Ref/128
1464 else if (VCO_Fra > PLL_Ref*127/64) //2*PLL_Ref*127/128
1469 else if((VCO_Fra > PLL_Ref*127/128) && (VCO_Fra < PLL_Ref)) //> 2*PLL_Ref*127/256, < 2*PLL_Ref*128/256
1470 VCO_Fra = PLL_Ref*127/128; // VCO_Fra = 2*PLL_Ref*127/256
1471 else if((VCO_Fra > PLL_Ref) && (VCO_Fra < PLL_Ref*129/128)) //> 2*PLL_Ref*128/256, < 2*PLL_Ref*129/256
1472 VCO_Fra = PLL_Ref*129/128; // VCO_Fra = 2*PLL_Ref*129/256
1477 fprintf(stderr, "[R820T] No valid PLL values for %u Hz!\n", LO_Freq);
1482 Ni = (Nint - 13) / 4;
1483 Si = Nint - 4 *Ni - 13;
1484 R828_I2C.RegAddr = 0x14;
1485 R828_Arry[15] = 0x00;
1486 R828_Arry[15] |= (Ni + (Si << 6));
1487 R828_I2C.Data = R828_Arry[15];
1489 if(I2C_Write(pTuner, &R828_I2C) != RT_Success)
1493 R828_I2C.RegAddr = 0x12;
1494 R828_Arry[13] &= 0xF7;
1496 R828_Arry[13] |= 0x08;
1497 R828_I2C.Data = R828_Arry[13];
1498 if(I2C_Write(pTuner, &R828_I2C) != RT_Success)
1504 if (VCO_Fra > (2*PLL_Ref / Nsdm))
1506 SDM = SDM + 32768 / (Nsdm/2);
1507 VCO_Fra = VCO_Fra - 2*PLL_Ref / Nsdm;
1514 SDM16to9 = SDM >> 8;
1515 SDM8to1 = SDM - (SDM16to9 << 8);
1517 R828_I2C.RegAddr = 0x16;
1518 R828_Arry[17] = (UINT8) SDM16to9;
1519 R828_I2C.Data = R828_Arry[17];
1520 if(I2C_Write(pTuner, &R828_I2C) != RT_Success)
1522 R828_I2C.RegAddr = 0x15;
1523 R828_Arry[16] = (UINT8) SDM8to1;
1524 R828_I2C.Data = R828_Arry[16];
1525 if(I2C_Write(pTuner, &R828_I2C) != RT_Success)
1528 // R828_Delay_MS(10);
1530 if ((Rafael_Chip==R620D) || (Rafael_Chip==R828D) || (Rafael_Chip==R828))
1532 if(R828_Standard <= SECAM_L1)
1533 R828_Delay_MS(pTuner, 20);
1535 R828_Delay_MS(pTuner, 10);
1539 R828_Delay_MS(pTuner, 10);
1542 //check PLL lock status
1543 R828_I2C_Len.RegAddr = 0x00;
1544 R828_I2C_Len.Len = 3;
1545 if(I2C_Read_Len(pTuner, &R828_I2C_Len) != RT_Success)
1548 if( (R828_I2C_Len.Data[2] & 0x40) == 0x00 )
1550 fprintf(stderr, "[R820T] PLL not locked for %u Hz!\n", LO_Freq);
1551 R828_I2C.RegAddr = 0x12;
1552 R828_Arry[13] = (R828_Arry[13] & 0x1F) | 0x60; //increase VCO current
1553 R828_I2C.Data = R828_Arry[13];
1554 if(I2C_Write(pTuner, &R828_I2C) != RT_Success)
1560 //set pll autotune = 8kHz
1561 R828_I2C.RegAddr = 0x1A;
1562 R828_Arry[21] = R828_Arry[21] | 0x08;
1563 R828_I2C.Data = R828_Arry[21];
1564 if(I2C_Write(pTuner, &R828_I2C) != RT_Success)
1570 R828_ErrCode R828_MUX(void *pTuner, UINT32 RF_KHz)
1578 //Freq_Info_Type Freq_Info1;
1579 Freq_Info1 = R828_Freq_Sel(RF_KHz);
1582 R828_I2C.RegAddr = 0x17;
1583 R828_Arry[18] = (R828_Arry[18] & 0xF7) | Freq_Info1.OPEN_D;
1584 R828_I2C.Data = R828_Arry[18];
1585 if(I2C_Write(pTuner, &R828_I2C) != RT_Success)
1589 R828_I2C.RegAddr = 0x1A;
1590 R828_Arry[21] = (R828_Arry[21] & 0x3C) | Freq_Info1.RF_MUX_PLOY;
1591 R828_I2C.Data = R828_Arry[21];
1592 if(I2C_Write(pTuner, &R828_I2C) != RT_Success)
1596 R828_I2C.RegAddr = 0x1B;
1597 R828_Arry[22] &= 0x00;
1598 R828_Arry[22] |= Freq_Info1.TF_C;
1599 R828_I2C.Data = R828_Arry[22];
1600 if(I2C_Write(pTuner, &R828_I2C) != RT_Success)
1604 R828_I2C.RegAddr = 0x10;
1605 R828_Arry[11] &= 0xF4;
1606 switch(Xtal_cap_sel)
1608 case XTAL_LOW_CAP_30P:
1609 case XTAL_LOW_CAP_20P:
1610 R828_Arry[11] = R828_Arry[11] | Freq_Info1.XTAL_CAP20P | 0x08;
1613 case XTAL_LOW_CAP_10P:
1614 R828_Arry[11] = R828_Arry[11] | Freq_Info1.XTAL_CAP10P | 0x08;
1617 case XTAL_LOW_CAP_0P:
1618 R828_Arry[11] = R828_Arry[11] | Freq_Info1.XTAL_CAP0P | 0x08;
1621 case XTAL_HIGH_CAP_0P:
1622 R828_Arry[11] = R828_Arry[11] | Freq_Info1.XTAL_CAP0P | 0x00;
1626 R828_Arry[11] = R828_Arry[11] | Freq_Info1.XTAL_CAP0P | 0x08;
1629 R828_I2C.Data = R828_Arry[11];
1630 if(I2C_Write(pTuner, &R828_I2C) != RT_Success)
1634 if(R828_IMR_done_flag == TRUE)
1636 RT_Reg08 = IMR_Data[Freq_Info1.IMR_MEM].Gain_X & 0x3F;
1637 RT_Reg09 = IMR_Data[Freq_Info1.IMR_MEM].Phase_Y & 0x3F;
1645 R828_I2C.RegAddr = 0x08;
1646 R828_Arry[3] = R828_iniArry[3] & 0xC0;
1647 R828_Arry[3] = R828_Arry[3] | RT_Reg08;
1648 R828_I2C.Data = R828_Arry[3];
1649 if(I2C_Write(pTuner, &R828_I2C) != RT_Success)
1652 R828_I2C.RegAddr = 0x09;
1653 R828_Arry[4] = R828_iniArry[4] & 0xC0;
1654 R828_Arry[4] = R828_Arry[4] | RT_Reg09;
1655 R828_I2C.Data =R828_Arry[4] ;
1656 if(I2C_Write(pTuner, &R828_I2C) != RT_Success)
1662 R828_ErrCode R828_IQ(void *pTuner, R828_SectType* IQ_Pont)
1664 R828_SectType Compare_IQ[3];
1665 // R828_SectType CompareTemp;
1666 // UINT8 IQ_Count = 0;
1669 UINT8 X_Direction; // 1:X, 0:Y
1674 // increase VGA power to let image significant
1675 for(VGA_Count = 12;VGA_Count < 16;VGA_Count ++)
1677 R828_I2C.RegAddr = 0x0C;
1678 R828_I2C.Data = (R828_Arry[7] & 0xF0) + VGA_Count;
1679 if(I2C_Write(pTuner, &R828_I2C) != RT_Success)
1682 R828_Delay_MS(pTuner, 10); //
1684 if(R828_Muti_Read(pTuner, 0x01, &VGA_Read) != RT_Success)
1691 //initial 0x08, 0x09
1692 //Compare_IQ[0].Gain_X = 0x40; //should be 0xC0 in R828, Jason
1693 //Compare_IQ[0].Phase_Y = 0x40; //should be 0x40 in R828
1694 Compare_IQ[0].Gain_X = R828_iniArry[3] & 0xC0; // Jason modified, clear b[5], b[4:0]
1695 Compare_IQ[0].Phase_Y = R828_iniArry[4] & 0xC0; //
1697 //while(IQ_Count < 3)
1700 if(R828_IMR_Cross(pTuner, &Compare_IQ[0], &X_Direction) != RT_Success)
1703 //if(X_Direction==1)
1705 // if(R828_IQ_Tree(Compare_IQ[0].Phase_Y, Compare_IQ[0].Gain_X, 0x09, &Compare_IQ[0]) != RT_Success) //X
1710 // if(R828_IQ_Tree(Compare_IQ[0].Gain_X, Compare_IQ[0].Phase_Y, 0x08, &Compare_IQ[0]) != RT_Success) //Y
1715 //--- X direction ---//
1717 if(R828_IQ_Tree(Compare_IQ[0].Phase_Y, Compare_IQ[0].Gain_X, 0x09, &Compare_IQ[0]) != RT_Success) //
1720 //compare and find min of 3 points. determine I/Q direction
1721 if(R828_CompreCor(&Compare_IQ[0]) != RT_Success)
1724 //increase step to find min value of this direction
1725 if(R828_CompreStep(&Compare_IQ[0], 0x08) != RT_Success)
1731 //compare and find min of 3 points. determine I/Q direction
1732 if(R828_CompreCor(&Compare_IQ[0]) != RT_Success)
1735 //increase step to find min value of this direction
1736 if(R828_CompreStep(pTuner, &Compare_IQ[0], 0x08) != RT_Success) //X
1741 //compare and find min of 3 points. determine I/Q direction
1742 if(R828_CompreCor(&Compare_IQ[0]) != RT_Success)
1745 //increase step to find min value of this direction
1746 if(R828_CompreStep(pTuner, &Compare_IQ[0], 0x09) != RT_Success) //Y
1750 //--- Y direction ---//
1752 if(R828_IQ_Tree(Compare_IQ[0].Gain_X, Compare_IQ[0].Phase_Y, 0x08, &Compare_IQ[0]) != RT_Success) //
1755 //compare and find min of 3 points. determine I/Q direction
1756 if(R828_CompreCor(&Compare_IQ[0]) != RT_Success)
1759 //increase step to find min value of this direction
1760 if(R828_CompreStep(&Compare_IQ[0], 0x09) != RT_Success)
1767 if(R828_IQ_Tree(pTuner, Compare_IQ[0].Gain_X, Compare_IQ[0].Phase_Y, 0x08, &Compare_IQ[0]) != RT_Success) //Y
1770 //compare and find min of 3 points. determine I/Q direction
1771 if(R828_CompreCor(&Compare_IQ[0]) != RT_Success)
1774 //increase step to find min value of this direction
1775 if(R828_CompreStep(pTuner, &Compare_IQ[0], 0x09) != RT_Success) //Y
1780 if(R828_IQ_Tree(pTuner, Compare_IQ[0].Phase_Y, Compare_IQ[0].Gain_X, 0x09, &Compare_IQ[0]) != RT_Success) //X
1783 //compare and find min of 3 points. determine I/Q direction
1784 if(R828_CompreCor(&Compare_IQ[0]) != RT_Success)
1787 //increase step to find min value of this direction
1788 if(R828_CompreStep(pTuner, &Compare_IQ[0], 0x08) != RT_Success) //X
1791 //CompareTemp = Compare_IQ[0];
1793 //--- Check 3 points again---//
1796 if(R828_IQ_Tree(pTuner, Compare_IQ[0].Phase_Y, Compare_IQ[0].Gain_X, 0x09, &Compare_IQ[0]) != RT_Success) //X
1801 if(R828_IQ_Tree(pTuner, Compare_IQ[0].Gain_X, Compare_IQ[0].Phase_Y, 0x08, &Compare_IQ[0]) != RT_Success) //Y
1805 //if(R828_IQ_Tree(Compare_IQ[0].Phase_Y, Compare_IQ[0].Gain_X, 0x09, &Compare_IQ[0]) != RT_Success) //
1808 if(R828_CompreCor(&Compare_IQ[0]) != RT_Success)
1811 //if((CompareTemp.Gain_X == Compare_IQ[0].Gain_X) && (CompareTemp.Phase_Y == Compare_IQ[0].Phase_Y))//Ben Check
1821 CompareTemp = Compare_IQ[0];
1822 for(IQ_Count = 0;IQ_Count < 5;IQ_Count ++)
1824 if(R828_Section(&Compare_IQ[0]) != RT_Success)
1827 if((CompareTemp.Gain_X == Compare_IQ[0].Gain_X) && (CompareTemp.Phase_Y == Compare_IQ[0].Phase_Y))
1833 //if(R828_F_IMR(&Compare_IQ[0]) != RT_Success)
1834 if(R828_Section(pTuner, &Compare_IQ[0]) != RT_Success)
1837 *IQ_Pont = Compare_IQ[0];
1839 //reset gain/phase control setting
1840 R828_I2C.RegAddr = 0x08;
1841 R828_I2C.Data = R828_iniArry[3] & 0xC0; //Jason
1842 if(I2C_Write(pTuner, &R828_I2C) != RT_Success)
1845 R828_I2C.RegAddr = 0x09;
1846 R828_I2C.Data = R828_iniArry[4] & 0xC0;
1847 if(I2C_Write(pTuner, &R828_I2C) != RT_Success)
1853 //--------------------------------------------------------------------------------------------
1854 // Purpose: record IMC results by input gain/phase location
1855 // then adjust gain or phase positive 1 step and negtive 1 step, both record results
1856 // input: FixPot: phase or gain
1857 // FlucPot phase or gain
1858 // PotReg: 0x08 or 0x09
1859 // CompareTree: 3 IMR trace and results
1860 // output: TREU or FALSE
1861 //--------------------------------------------------------------------------------------------
1862 R828_ErrCode R828_IQ_Tree(void *pTuner, UINT8 FixPot, UINT8 FlucPot, UINT8 PotReg, R828_SectType* CompareTree)
1875 PntReg = 0x09; //phase control
1877 PntReg = 0x08; //gain control
1879 for(TreeCount = 0;TreeCount < TreeTimes;TreeCount ++)
1881 R828_I2C.RegAddr = PotReg;
1882 R828_I2C.Data = FixPot;
1883 if(I2C_Write(pTuner, &R828_I2C) != RT_Success)
1886 R828_I2C.RegAddr = PntReg;
1887 R828_I2C.Data = FlucPot;
1888 if(I2C_Write(pTuner, &R828_I2C) != RT_Success)
1891 if(R828_Muti_Read(pTuner, 0x01, &CompareTree[TreeCount].Value) != RT_Success)
1896 CompareTree[TreeCount].Gain_X = FixPot;
1897 CompareTree[TreeCount].Phase_Y = FlucPot;
1901 CompareTree[TreeCount].Phase_Y = FixPot;
1902 CompareTree[TreeCount].Gain_X = FlucPot;
1905 if(TreeCount == 0) //try right-side point
1907 else if(TreeCount == 1) //try left-side point
1909 if((FlucPot & 0x1F) < 0x02) //if absolute location is 1, change I/Q direction
1911 TempPot = 2 - (FlucPot & 0x1F);
1912 if(FlucPot & 0x20) //b[5]:I/Q selection. 0:Q-path, 1:I-path
1919 FlucPot |= (0x20 | TempPot);
1930 //-----------------------------------------------------------------------------------/
1931 // Purpose: compare IMC result aray [0][1][2], find min value and store to CorArry[0]
1932 // input: CorArry: three IMR data array
1933 // output: TRUE or FALSE
1934 //-----------------------------------------------------------------------------------/
1935 R828_ErrCode R828_CompreCor(R828_SectType* CorArry)
1938 R828_SectType CorTemp;
1942 for(CompCount = 3;CompCount > 0;CompCount --)
1944 if(CorArry[0].Value > CorArry[CompCount - 1].Value) //compare IMC result [0][1][2], find min value
1946 CorTemp = CorArry[0];
1947 CorArry[0] = CorArry[CompCount - 1];
1948 CorArry[CompCount - 1] = CorTemp;
1955 //-------------------------------------------------------------------------------------//
1956 // Purpose: if (Gain<9 or Phase<9), Gain+1 or Phase+1 and compare with min value
1957 // new < min => update to min and continue
1958 // new > min => Exit
1959 // input: StepArry: three IMR data array
1960 // Pace: gain or phase register
1961 // output: TRUE or FALSE
1962 //-------------------------------------------------------------------------------------//
1963 R828_ErrCode R828_CompreStep(void *pTuner, R828_SectType* StepArry, UINT8 Pace)
1965 //UINT8 StepCount = 0;
1966 R828_SectType StepTemp;
1968 //min value already saved in StepArry[0]
1969 StepTemp.Phase_Y = StepArry[0].Phase_Y;
1970 StepTemp.Gain_X = StepArry[0].Gain_X;
1972 while(((StepTemp.Gain_X & 0x1F) < IMR_TRIAL) && ((StepTemp.Phase_Y & 0x1F) < IMR_TRIAL)) //5->10
1977 StepTemp.Phase_Y ++;
1979 R828_I2C.RegAddr = 0x08;
1980 R828_I2C.Data = StepTemp.Gain_X ;
1981 if(I2C_Write(pTuner, &R828_I2C) != RT_Success)
1984 R828_I2C.RegAddr = 0x09;
1985 R828_I2C.Data = StepTemp.Phase_Y;
1986 if(I2C_Write(pTuner, &R828_I2C) != RT_Success)
1989 if(R828_Muti_Read(pTuner, 0x01, &StepTemp.Value) != RT_Success)
1992 if(StepTemp.Value <= StepArry[0].Value)
1994 StepArry[0].Gain_X = StepTemp.Gain_X;
1995 StepArry[0].Phase_Y = StepTemp.Phase_Y;
1996 StepArry[0].Value = StepTemp.Value;
2008 //-----------------------------------------------------------------------------------/
2009 // Purpose: read multiple IMC results for stability
2010 // input: IMR_Reg: IMC result address
2011 // IMR_Result_Data: result
2012 // output: TRUE or FALSE
2013 //-----------------------------------------------------------------------------------/
2014 R828_ErrCode R828_Muti_Read(void *pTuner, UINT8 IMR_Reg, UINT16* IMR_Result_Data) //jason modified
2028 R828_Delay_MS(pTuner, 5);
2030 for(ReadCount = 0;ReadCount < 6;ReadCount ++)
2032 R828_I2C_Len.RegAddr = 0x00;
2033 R828_I2C_Len.Len = IMR_Reg + 1; //IMR_Reg = 0x01
2034 if(I2C_Read_Len(pTuner, &R828_I2C_Len) != RT_Success)
2037 ReadData = R828_I2C_Len.Data[1];
2039 ReadAmount = ReadAmount + (UINT16)ReadData;
2041 if(ReadData < ReadMin)
2044 if(ReadData > ReadMax)
2047 *IMR_Result_Data = ReadAmount - (UINT16)ReadMax - (UINT16)ReadMin;
2052 R828_ErrCode R828_Section(void *pTuner, R828_SectType* IQ_Pont)
2054 R828_SectType Compare_IQ[3];
2055 R828_SectType Compare_Bet[3];
2057 //Try X-1 column and save min result to Compare_Bet[0]
2058 if((IQ_Pont->Gain_X & 0x1F) == 0x00)
2061 if((IQ_Pont->Gain_X & 0xE0) == 0x40) //bug => only compare b[5],
2062 Compare_IQ[0].Gain_X = 0x61; // Gain=1, I-path //Jason
2064 Compare_IQ[0].Gain_X = 0x41; // Gain=1, Q-path
2066 Compare_IQ[0].Gain_X = ((IQ_Pont->Gain_X) & 0xDF) + 1; //Q-path, Gain=1
2069 Compare_IQ[0].Gain_X = IQ_Pont->Gain_X - 1; //left point
2070 Compare_IQ[0].Phase_Y = IQ_Pont->Phase_Y;
2072 if(R828_IQ_Tree(pTuner, Compare_IQ[0].Gain_X, Compare_IQ[0].Phase_Y, 0x08, &Compare_IQ[0]) != RT_Success) // y-direction
2075 if(R828_CompreCor(&Compare_IQ[0]) != RT_Success)
2078 Compare_Bet[0].Gain_X = Compare_IQ[0].Gain_X;
2079 Compare_Bet[0].Phase_Y = Compare_IQ[0].Phase_Y;
2080 Compare_Bet[0].Value = Compare_IQ[0].Value;
2082 //Try X column and save min result to Compare_Bet[1]
2083 Compare_IQ[0].Gain_X = IQ_Pont->Gain_X;
2084 Compare_IQ[0].Phase_Y = IQ_Pont->Phase_Y;
2086 if(R828_IQ_Tree(pTuner, Compare_IQ[0].Gain_X, Compare_IQ[0].Phase_Y, 0x08, &Compare_IQ[0]) != RT_Success)
2089 if(R828_CompreCor(&Compare_IQ[0]) != RT_Success)
2092 Compare_Bet[1].Gain_X = Compare_IQ[0].Gain_X;
2093 Compare_Bet[1].Phase_Y = Compare_IQ[0].Phase_Y;
2094 Compare_Bet[1].Value = Compare_IQ[0].Value;
2096 //Try X+1 column and save min result to Compare_Bet[2]
2097 if((IQ_Pont->Gain_X & 0x1F) == 0x00)
2098 Compare_IQ[0].Gain_X = ((IQ_Pont->Gain_X) | 0x20) + 1; //I-path, Gain=1
2100 Compare_IQ[0].Gain_X = IQ_Pont->Gain_X + 1;
2101 Compare_IQ[0].Phase_Y = IQ_Pont->Phase_Y;
2103 if(R828_IQ_Tree(pTuner, Compare_IQ[0].Gain_X, Compare_IQ[0].Phase_Y, 0x08, &Compare_IQ[0]) != RT_Success)
2106 if(R828_CompreCor(&Compare_IQ[0]) != RT_Success)
2109 Compare_Bet[2].Gain_X = Compare_IQ[0].Gain_X;
2110 Compare_Bet[2].Phase_Y = Compare_IQ[0].Phase_Y;
2111 Compare_Bet[2].Value = Compare_IQ[0].Value;
2113 if(R828_CompreCor(&Compare_Bet[0]) != RT_Success)
2116 *IQ_Pont = Compare_Bet[0];
2121 R828_ErrCode R828_IMR_Cross(void *pTuner, R828_SectType* IQ_Pont, UINT8* X_Direct)
2124 R828_SectType Compare_Cross[5]; //(0,0)(0,Q-1)(0,I-1)(Q-1,0)(I-1,0)
2125 R828_SectType Compare_Temp;
2131 Reg08 = R828_iniArry[3] & 0xC0;
2132 Reg09 = R828_iniArry[4] & 0xC0;
2134 //memset(&Compare_Temp,0, sizeof(R828_SectType));
2135 Compare_Temp.Gain_X = 0;
2136 Compare_Temp.Phase_Y = 0;
2137 Compare_Temp.Value = 0;
2139 Compare_Temp.Value = 255;
2141 for(CrossCount=0; CrossCount<5; CrossCount++)
2146 Compare_Cross[CrossCount].Gain_X = Reg08;
2147 Compare_Cross[CrossCount].Phase_Y = Reg09;
2149 else if(CrossCount==1)
2151 Compare_Cross[CrossCount].Gain_X = Reg08; //0
2152 Compare_Cross[CrossCount].Phase_Y = Reg09 + 1; //Q-1
2154 else if(CrossCount==2)
2156 Compare_Cross[CrossCount].Gain_X = Reg08; //0
2157 Compare_Cross[CrossCount].Phase_Y = (Reg09 | 0x20) + 1; //I-1
2159 else if(CrossCount==3)
2161 Compare_Cross[CrossCount].Gain_X = Reg08 + 1; //Q-1
2162 Compare_Cross[CrossCount].Phase_Y = Reg09;
2166 Compare_Cross[CrossCount].Gain_X = (Reg08 | 0x20) + 1; //I-1
2167 Compare_Cross[CrossCount].Phase_Y = Reg09;
2170 R828_I2C.RegAddr = 0x08;
2171 R828_I2C.Data = Compare_Cross[CrossCount].Gain_X;
2172 if(I2C_Write(pTuner, &R828_I2C) != RT_Success)
2175 R828_I2C.RegAddr = 0x09;
2176 R828_I2C.Data = Compare_Cross[CrossCount].Phase_Y;
2177 if(I2C_Write(pTuner, &R828_I2C) != RT_Success)
2180 if(R828_Muti_Read(pTuner, 0x01, &Compare_Cross[CrossCount].Value) != RT_Success)
2183 if( Compare_Cross[CrossCount].Value < Compare_Temp.Value)
2185 Compare_Temp.Value = Compare_Cross[CrossCount].Value;
2186 Compare_Temp.Gain_X = Compare_Cross[CrossCount].Gain_X;
2187 Compare_Temp.Phase_Y = Compare_Cross[CrossCount].Phase_Y;
2192 if((Compare_Temp.Phase_Y & 0x1F)==1) //y-direction
2194 *X_Direct = (UINT8) 0;
2195 IQ_Pont[0].Gain_X = Compare_Cross[0].Gain_X;
2196 IQ_Pont[0].Phase_Y = Compare_Cross[0].Phase_Y;
2197 IQ_Pont[0].Value = Compare_Cross[0].Value;
2199 IQ_Pont[1].Gain_X = Compare_Cross[1].Gain_X;
2200 IQ_Pont[1].Phase_Y = Compare_Cross[1].Phase_Y;
2201 IQ_Pont[1].Value = Compare_Cross[1].Value;
2203 IQ_Pont[2].Gain_X = Compare_Cross[2].Gain_X;
2204 IQ_Pont[2].Phase_Y = Compare_Cross[2].Phase_Y;
2205 IQ_Pont[2].Value = Compare_Cross[2].Value;
2207 else //(0,0) or x-direction
2209 *X_Direct = (UINT8) 1;
2210 IQ_Pont[0].Gain_X = Compare_Cross[0].Gain_X;
2211 IQ_Pont[0].Phase_Y = Compare_Cross[0].Phase_Y;
2212 IQ_Pont[0].Value = Compare_Cross[0].Value;
2214 IQ_Pont[1].Gain_X = Compare_Cross[3].Gain_X;
2215 IQ_Pont[1].Phase_Y = Compare_Cross[3].Phase_Y;
2216 IQ_Pont[1].Value = Compare_Cross[3].Value;
2218 IQ_Pont[2].Gain_X = Compare_Cross[4].Gain_X;
2219 IQ_Pont[2].Phase_Y = Compare_Cross[4].Phase_Y;
2220 IQ_Pont[2].Value = Compare_Cross[4].Value;
2225 //----------------------------------------------------------------------------------------//
2226 // purpose: search surrounding points from previous point
2227 // try (x-1), (x), (x+1) columns, and find min IMR result point
2228 // input: IQ_Pont: previous point data(IMR Gain, Phase, ADC Result, RefRreq)
2229 // will be updated to final best point
2230 // output: TRUE or FALSE
2231 //----------------------------------------------------------------------------------------//
2232 R828_ErrCode R828_F_IMR(void *pTuner, R828_SectType* IQ_Pont)
2234 R828_SectType Compare_IQ[3];
2235 R828_SectType Compare_Bet[3];
2243 for(VGA_Count = 12;VGA_Count < 16;VGA_Count ++)
2245 R828_I2C.RegAddr = 0x0C;
2246 R828_I2C.Data = (R828_Arry[7] & 0xF0) + VGA_Count;
2247 if(I2C_Write(pTuner, &R828_I2C) != RT_Success)
2250 R828_Delay_MS(pTuner, 10);
2252 if(R828_Muti_Read(pTuner, 0x01, &VGA_Read) != RT_Success)
2259 //Try X-1 column and save min result to Compare_Bet[0]
2260 if((IQ_Pont->Gain_X & 0x1F) == 0x00)
2262 Compare_IQ[0].Gain_X = ((IQ_Pont->Gain_X) & 0xDF) + 1; //Q-path, Gain=1
2265 Compare_IQ[0].Gain_X = IQ_Pont->Gain_X - 1; //left point
2266 Compare_IQ[0].Phase_Y = IQ_Pont->Phase_Y;
2268 if(R828_IQ_Tree(pTuner, Compare_IQ[0].Gain_X, Compare_IQ[0].Phase_Y, 0x08, &Compare_IQ[0]) != RT_Success) // y-direction
2271 if(R828_CompreCor(&Compare_IQ[0]) != RT_Success)
2274 Compare_Bet[0].Gain_X = Compare_IQ[0].Gain_X;
2275 Compare_Bet[0].Phase_Y = Compare_IQ[0].Phase_Y;
2276 Compare_Bet[0].Value = Compare_IQ[0].Value;
2278 //Try X column and save min result to Compare_Bet[1]
2279 Compare_IQ[0].Gain_X = IQ_Pont->Gain_X;
2280 Compare_IQ[0].Phase_Y = IQ_Pont->Phase_Y;
2282 if(R828_IQ_Tree(pTuner, Compare_IQ[0].Gain_X, Compare_IQ[0].Phase_Y, 0x08, &Compare_IQ[0]) != RT_Success)
2285 if(R828_CompreCor(&Compare_IQ[0]) != RT_Success)
2288 Compare_Bet[1].Gain_X = Compare_IQ[0].Gain_X;
2289 Compare_Bet[1].Phase_Y = Compare_IQ[0].Phase_Y;
2290 Compare_Bet[1].Value = Compare_IQ[0].Value;
2292 //Try X+1 column and save min result to Compare_Bet[2]
2293 if((IQ_Pont->Gain_X & 0x1F) == 0x00)
2294 Compare_IQ[0].Gain_X = ((IQ_Pont->Gain_X) | 0x20) + 1; //I-path, Gain=1
2296 Compare_IQ[0].Gain_X = IQ_Pont->Gain_X + 1;
2297 Compare_IQ[0].Phase_Y = IQ_Pont->Phase_Y;
2299 if(R828_IQ_Tree(pTuner, Compare_IQ[0].Gain_X, Compare_IQ[0].Phase_Y, 0x08, &Compare_IQ[0]) != RT_Success)
2302 if(R828_CompreCor(&Compare_IQ[0]) != RT_Success)
2305 Compare_Bet[2].Gain_X = Compare_IQ[0].Gain_X;
2306 Compare_Bet[2].Phase_Y = Compare_IQ[0].Phase_Y;
2307 Compare_Bet[2].Value = Compare_IQ[0].Value;
2309 if(R828_CompreCor(&Compare_Bet[0]) != RT_Success)
2312 *IQ_Pont = Compare_Bet[0];
2317 R828_ErrCode R828_GPIO(void *pTuner, R828_GPIO_Type R828_GPIO_Conrl)
2319 if(R828_GPIO_Conrl == HI_SIG)
2320 R828_Arry[10] |= 0x01;
2322 R828_Arry[10] &= 0xFE;
2324 R828_I2C.RegAddr = 0x0F;
2325 R828_I2C.Data = R828_Arry[10];
2326 if(I2C_Write(pTuner, &R828_I2C) != RT_Success)
2332 R828_ErrCode R828_SetStandard(void *pTuner, R828_Standard_Type RT_Standard)
2335 // Used Normal Arry to Modify
2339 for(ArrayNum=0;ArrayNum<27;ArrayNum++)
2341 R828_Arry[ArrayNum] = R828_iniArry[ArrayNum];
2345 // Record Init Flag & Xtal_check Result
2346 if(R828_IMR_done_flag == TRUE)
2347 R828_Arry[7] = (R828_Arry[7] & 0xF0) | 0x01 | (Xtal_cap_sel<<1);
2349 R828_Arry[7] = (R828_Arry[7] & 0xF0) | 0x00;
2351 R828_I2C.RegAddr = 0x0C;
2352 R828_I2C.Data = R828_Arry[7];
2353 if(I2C_Write(pTuner, &R828_I2C) != RT_Success)
2357 R828_I2C.RegAddr = 0x13;
2358 R828_Arry[14] = (R828_Arry[14] & 0xC0) | VER_NUM;
2359 R828_I2C.Data = R828_Arry[14];
2360 if(I2C_Write(pTuner, &R828_I2C) != RT_Success)
2365 if(RT_Standard > SECAM_L1)
2367 R828_I2C.RegAddr = 0x1D; //[5:3] LNA TOP
2368 R828_I2C.Data = (R828_Arry[24] & 0xC7) | 0x00;
2369 if(I2C_Write(pTuner, &R828_I2C) != RT_Success)
2375 // Look Up System Dependent Table
2376 Sys_Info1 = R828_Sys_Sel(RT_Standard);
2377 R828_IF_khz = Sys_Info1.IF_KHz;
2378 R828_CAL_LO_khz = Sys_Info1.FILT_CAL_LO;
2380 // Filter Calibration
2381 if(R828_Fil_Cal_flag[RT_Standard] == FALSE)
2383 // do filter calibration
2384 if(R828_Filt_Cal(pTuner, Sys_Info1.FILT_CAL_LO,Sys_Info1.BW) != RT_Success)
2388 // read and set filter code
2389 R828_I2C_Len.RegAddr = 0x00;
2390 R828_I2C_Len.Len = 5;
2391 if(I2C_Read_Len(pTuner, &R828_I2C_Len) != RT_Success)
2394 R828_Fil_Cal_code[RT_Standard] = R828_I2C_Len.Data[4] & 0x0F;
2396 //Filter Cali. Protection
2397 if(R828_Fil_Cal_code[RT_Standard]==0 || R828_Fil_Cal_code[RT_Standard]==15)
2399 if(R828_Filt_Cal(pTuner, Sys_Info1.FILT_CAL_LO,Sys_Info1.BW) != RT_Success)
2402 R828_I2C_Len.RegAddr = 0x00;
2403 R828_I2C_Len.Len = 5;
2404 if(I2C_Read_Len(pTuner, &R828_I2C_Len) != RT_Success)
2407 R828_Fil_Cal_code[RT_Standard] = R828_I2C_Len.Data[4] & 0x0F;
2409 if(R828_Fil_Cal_code[RT_Standard]==15) //narrowest
2410 R828_Fil_Cal_code[RT_Standard] = 0;
2413 R828_Fil_Cal_flag[RT_Standard] = TRUE;
2417 R828_Arry[5] = (R828_Arry[5] & 0xE0) | Sys_Info1.FILT_Q | R828_Fil_Cal_code[RT_Standard];
2418 R828_I2C.RegAddr = 0x0A;
2419 R828_I2C.Data = R828_Arry[5];
2420 if(I2C_Write(pTuner, &R828_I2C) != RT_Success)
2423 // Set BW, Filter_gain, & HP corner
2424 R828_Arry[6]= (R828_Arry[6] & 0x10) | Sys_Info1.HP_COR;
2425 R828_I2C.RegAddr = 0x0B;
2426 R828_I2C.Data = R828_Arry[6];
2427 if(I2C_Write(pTuner, &R828_I2C) != RT_Success)
2431 R828_Arry[2] = (R828_Arry[2] & 0x7F) | Sys_Info1.IMG_R;
2432 R828_I2C.RegAddr = 0x07;
2433 R828_I2C.Data = R828_Arry[2];
2434 if(I2C_Write(pTuner, &R828_I2C) != RT_Success)
2438 // Set filt_3dB, V6MHz
2439 R828_Arry[1] = (R828_Arry[1] & 0xCF) | Sys_Info1.FILT_GAIN;
2440 R828_I2C.RegAddr = 0x06;
2441 R828_I2C.Data = R828_Arry[1];
2442 if(I2C_Write(pTuner, &R828_I2C) != RT_Success)
2445 //channel filter extension
2446 R828_Arry[25] = (R828_Arry[25] & 0x9F) | Sys_Info1.EXT_ENABLE;
2447 R828_I2C.RegAddr = 0x1E;
2448 R828_I2C.Data = R828_Arry[25];
2449 if(I2C_Write(pTuner, &R828_I2C) != RT_Success)
2454 R828_Arry[0] = (R828_Arry[0] & 0x7F) | Sys_Info1.LOOP_THROUGH;
2455 R828_I2C.RegAddr = 0x05;
2456 R828_I2C.Data = R828_Arry[0];
2457 if(I2C_Write(pTuner, &R828_I2C) != RT_Success)
2460 //Loop through attenuation
2461 R828_Arry[26] = (R828_Arry[26] & 0x7F) | Sys_Info1.LT_ATT;
2462 R828_I2C.RegAddr = 0x1F;
2463 R828_I2C.Data = R828_Arry[26];
2464 if(I2C_Write(pTuner, &R828_I2C) != RT_Success)
2467 //filter extention widest
2468 R828_Arry[10] = (R828_Arry[10] & 0x7F) | Sys_Info1.FLT_EXT_WIDEST;
2469 R828_I2C.RegAddr = 0x0F;
2470 R828_I2C.Data = R828_Arry[10];
2471 if(I2C_Write(pTuner, &R828_I2C) != RT_Success)
2474 //RF poly filter current
2475 R828_Arry[20] = (R828_Arry[20] & 0x9F) | Sys_Info1.POLYFIL_CUR;
2476 R828_I2C.RegAddr = 0x19;
2477 R828_I2C.Data = R828_Arry[20];
2478 if(I2C_Write(pTuner, &R828_I2C) != RT_Success)
2484 R828_ErrCode R828_Filt_Cal(void *pTuner, UINT32 Cal_Freq,BW_Type R828_BW)
2488 if(R828_BW == BW_8M)
2490 //set filt_cap = no cap
2491 R828_I2C.RegAddr = 0x0B; //reg11
2492 R828_Arry[6] &= 0x9F; //filt_cap = no cap
2493 R828_I2C.Data = R828_Arry[6];
2495 else if(R828_BW == BW_7M)
2497 //set filt_cap = +1 cap
2498 R828_I2C.RegAddr = 0x0B; //reg11
2499 R828_Arry[6] &= 0x9F; //filt_cap = no cap
2500 R828_Arry[6] |= 0x20; //filt_cap = +1 cap
2501 R828_I2C.Data = R828_Arry[6];
2503 else if(R828_BW == BW_6M)
2505 //set filt_cap = +2 cap
2506 R828_I2C.RegAddr = 0x0B; //reg11
2507 R828_Arry[6] &= 0x9F; //filt_cap = no cap
2508 R828_Arry[6] |= 0x60; //filt_cap = +2 cap
2509 R828_I2C.Data = R828_Arry[6];
2513 if(I2C_Write(pTuner, &R828_I2C) != RT_Success)
2518 R828_I2C.RegAddr = 0x0B;
2519 R828_Arry[6]= (R828_Arry[6] & 0x9F) | (Sys_Info1.HP_COR & 0x60);
2520 R828_I2C.Data = R828_Arry[6];
2521 if(I2C_Write(pTuner, &R828_I2C) != RT_Success)
2526 R828_I2C.RegAddr = 0x0F; //reg15
2527 R828_Arry[10] |= 0x04; //calibration clk=on
2528 R828_I2C.Data = R828_Arry[10];
2529 if(I2C_Write(pTuner, &R828_I2C) != RT_Success)
2532 //X'tal cap 0pF for PLL
2533 R828_I2C.RegAddr = 0x10;
2534 R828_Arry[11] = (R828_Arry[11] & 0xFC) | 0x00;
2535 R828_I2C.Data = R828_Arry[11];
2536 if(I2C_Write(pTuner, &R828_I2C) != RT_Success)
2539 //Set PLL Freq = Filter Cali Freq
2540 if(R828_PLL(pTuner, Cal_Freq * 1000, STD_SIZE) != RT_Success)
2544 R828_I2C.RegAddr = 0x0B; //reg11
2545 R828_Arry[6] |= 0x10; //vstart=1
2546 R828_I2C.Data = R828_Arry[6];
2547 if(I2C_Write(pTuner, &R828_I2C) != RT_Success)
2551 R828_Delay_MS(pTuner, 1);
2554 R828_I2C.RegAddr = 0x0B;
2555 R828_Arry[6] &= 0xEF; //vstart=0
2556 R828_I2C.Data = R828_Arry[6];
2557 if(I2C_Write(pTuner, &R828_I2C) != RT_Success)
2562 R828_I2C.RegAddr = 0x0F; //reg15
2563 R828_Arry[10] &= 0xFB; //calibration clk=off
2564 R828_I2C.Data = R828_Arry[10];
2565 if(I2C_Write(pTuner, &R828_I2C) != RT_Success)
2572 R828_ErrCode R828_SetFrequency(void *pTuner, R828_Set_Info R828_INFO, R828_SetFreq_Type R828_SetFreqMode)
2577 // Check Input Frequency Range
2578 if((R828_INFO.RF_KHz<40000) || (R828_INFO.RF_KHz>900000))
2584 if(R828_INFO.R828_Standard==SECAM_L1)
2585 LO_Hz = R828_INFO.RF_Hz - (Sys_Info1.IF_KHz * 1000);
2587 LO_Hz = R828_INFO.RF_Hz + (Sys_Info1.IF_KHz * 1000);
2589 //Set MUX dependent var. Must do before PLL( )
2590 if(R828_MUX(pTuner, LO_Hz/1000) != RT_Success)
2594 if(R828_PLL(pTuner, LO_Hz, R828_INFO.R828_Standard) != RT_Success)
2597 R828_IMR_point_num = Freq_Info1.IMR_MEM;
2601 SysFreq_Info1 = R828_SysFreq_Sel(R828_INFO.R828_Standard, R828_INFO.RF_KHz);
2604 // write DectBW, pre_dect_TOP
2605 R828_Arry[24] = (R828_Arry[24] & 0x38) | (SysFreq_Info1.LNA_TOP & 0xC7);
2606 R828_I2C.RegAddr = 0x1D;
2607 R828_I2C.Data = R828_Arry[24];
2608 if(I2C_Write(pTuner, &R828_I2C) != RT_Success)
2611 // write MIXER TOP, TOP+-1
2612 R828_Arry[23] = (R828_Arry[23] & 0x07) | (SysFreq_Info1.MIXER_TOP & 0xF8);
2613 R828_I2C.RegAddr = 0x1C;
2614 R828_I2C.Data = R828_Arry[23];
2615 if(I2C_Write(pTuner, &R828_I2C) != RT_Success)
2620 R828_Arry[8] = (R828_Arry[8] & 0x00) | SysFreq_Info1.LNA_VTH_L;
2621 R828_I2C.RegAddr = 0x0D;
2622 R828_I2C.Data = R828_Arry[8];
2623 if(I2C_Write(pTuner, &R828_I2C) != RT_Success)
2627 R828_Arry[9] = (R828_Arry[9] & 0x00) | SysFreq_Info1.MIXER_VTH_L;
2628 R828_I2C.RegAddr = 0x0E;
2629 R828_I2C.Data = R828_Arry[9];
2630 if(I2C_Write(pTuner, &R828_I2C) != RT_Success)
2634 R828_I2C.RegAddr = 0x05;
2635 R828_Arry[0] &= 0x9F;
2636 R828_Arry[0] |= SysFreq_Info1.AIR_CABLE1_IN;
2637 R828_I2C.Data = R828_Arry[0];
2638 if(I2C_Write(pTuner, &R828_I2C) != RT_Success)
2642 R828_I2C.RegAddr = 0x06;
2643 R828_Arry[1] &= 0xF7;
2644 R828_Arry[1] |= SysFreq_Info1.CABLE2_IN;
2645 R828_I2C.Data = R828_Arry[1];
2646 if(I2C_Write(pTuner, &R828_I2C) != RT_Success)
2650 R828_I2C.RegAddr = 0x11;
2651 R828_Arry[12] &= 0xC7;
2652 R828_Arry[12] |= SysFreq_Info1.CP_CUR;
2653 R828_I2C.Data = R828_Arry[12];
2654 if(I2C_Write(pTuner, &R828_I2C) != RT_Success)
2657 //div buffer current
2658 R828_I2C.RegAddr = 0x17;
2659 R828_Arry[18] &= 0xCF;
2660 R828_Arry[18] |= SysFreq_Info1.DIV_BUF_CUR;
2661 R828_I2C.Data = R828_Arry[18];
2662 if(I2C_Write(pTuner, &R828_I2C) != RT_Success)
2665 // Set channel filter current
2666 R828_I2C.RegAddr = 0x0A;
2667 R828_Arry[5] = (R828_Arry[5] & 0x9F) | SysFreq_Info1.FILTER_CUR;
2668 R828_I2C.Data = R828_Arry[5];
2669 if(I2C_Write(pTuner, &R828_I2C) != RT_Success)
2672 //Air-In only for Astrometa
2673 R828_Arry[0] = (R828_Arry[0] & 0x9F) | 0x00;
2674 R828_Arry[1] = (R828_Arry[1] & 0xF7) | 0x00;
2676 R828_I2C.RegAddr = 0x05;
2677 R828_I2C.Data = R828_Arry[0];
2678 if(I2C_Write(pTuner, &R828_I2C) != RT_Success)
2681 R828_I2C.RegAddr = 0x06;
2682 R828_I2C.Data = R828_Arry[1];
2683 if(I2C_Write(pTuner, &R828_I2C) != RT_Success)
2687 if(R828_INFO.R828_Standard > SECAM_L1)
2690 if(R828_SetFreqMode==FAST_MODE) //FAST mode
2692 //R828_Arry[24] = (R828_Arry[24] & 0xC7) | 0x20; //LNA TOP:4
2693 R828_Arry[24] = (R828_Arry[24] & 0xC7) | 0x00; //LNA TOP:lowest
2694 R828_I2C.RegAddr = 0x1D;
2695 R828_I2C.Data = R828_Arry[24];
2696 if(I2C_Write(pTuner, &R828_I2C) != RT_Success)
2699 R828_Arry[23] = (R828_Arry[23] & 0xFB); // 0: normal mode
2700 R828_I2C.RegAddr = 0x1C;
2701 R828_I2C.Data = R828_Arry[23];
2702 if(I2C_Write(pTuner, &R828_I2C) != RT_Success)
2705 R828_Arry[1] = (R828_Arry[1] & 0xBF); //0: PRE_DECT off
2706 R828_I2C.RegAddr = 0x06;
2707 R828_I2C.Data = R828_Arry[1];
2708 if(I2C_Write(pTuner, &R828_I2C) != RT_Success)
2712 R828_Arry[21] = (R828_Arry[21] & 0xCF) | 0x30;
2713 R828_I2C.RegAddr = 0x1A;
2714 R828_I2C.Data = R828_Arry[21];
2715 if(I2C_Write(pTuner, &R828_I2C) != RT_Success)
2721 R828_Arry[24] = (R828_Arry[24] & 0xC7) | 0x00; //LNA TOP:lowest
2722 R828_I2C.RegAddr = 0x1D;
2723 R828_I2C.Data = R828_Arry[24];
2724 if(I2C_Write(pTuner, &R828_I2C) != RT_Success)
2727 R828_Arry[23] = (R828_Arry[23] & 0xFB); // 0: normal mode
2728 R828_I2C.RegAddr = 0x1C;
2729 R828_I2C.Data = R828_Arry[23];
2730 if(I2C_Write(pTuner, &R828_I2C) != RT_Success)
2733 R828_Arry[1] = (R828_Arry[1] & 0xBF); //0: PRE_DECT off
2734 R828_I2C.RegAddr = 0x06;
2735 R828_I2C.Data = R828_Arry[1];
2736 if(I2C_Write(pTuner, &R828_I2C) != RT_Success)
2740 R828_Arry[21] = (R828_Arry[21] & 0xCF) | 0x30; //250hz
2741 R828_I2C.RegAddr = 0x1A;
2742 R828_I2C.Data = R828_Arry[21];
2743 if(I2C_Write(pTuner, &R828_I2C) != RT_Success)
2746 R828_Delay_MS(pTuner, 250);
2750 R828_Arry[1] = (R828_Arry[1] & 0xBF) | SysFreq_Info1.PRE_DECT;
2751 R828_I2C.RegAddr = 0x06;
2752 R828_I2C.Data = R828_Arry[1];
2753 if(I2C_Write(pTuner, &R828_I2C) != RT_Success)
2756 // write LNA TOP = 3
2757 //R828_Arry[24] = (R828_Arry[24] & 0xC7) | (SysFreq_Info1.LNA_TOP & 0x38);
2758 R828_Arry[24] = (R828_Arry[24] & 0xC7) | 0x18; //TOP=3
2759 R828_I2C.RegAddr = 0x1D;
2760 R828_I2C.Data = R828_Arry[24];
2761 if(I2C_Write(pTuner, &R828_I2C) != RT_Success)
2764 // write discharge mode
2765 R828_Arry[23] = (R828_Arry[23] & 0xFB) | (SysFreq_Info1.MIXER_TOP & 0x04);
2766 R828_I2C.RegAddr = 0x1C;
2767 R828_I2C.Data = R828_Arry[23];
2768 if(I2C_Write(pTuner, &R828_I2C) != RT_Success)
2771 // LNA discharge current
2772 R828_Arry[25] = (R828_Arry[25] & 0xE0) | SysFreq_Info1.LNA_DISCHARGE;
2773 R828_I2C.RegAddr = 0x1E;
2774 R828_I2C.Data = R828_Arry[25];
2775 if(I2C_Write(pTuner, &R828_I2C) != RT_Success)
2779 R828_Arry[21] = (R828_Arry[21] & 0xCF) | 0x20;
2780 R828_I2C.RegAddr = 0x1A;
2781 R828_I2C.Data = R828_Arry[21];
2782 if(I2C_Write(pTuner, &R828_I2C) != RT_Success)
2788 if(R828_SetFreqMode==NORMAL_MODE || R828_SetFreqMode==FAST_MODE)
2792 R828_Arry[1] = (R828_Arry[1] & 0xBF) | SysFreq_Info1.PRE_DECT;
2793 R828_I2C.RegAddr = 0x06;
2794 R828_I2C.Data = R828_Arry[1];
2795 if(I2C_Write(pTuner, &R828_I2C) != RT_Success)
2799 R828_Arry[1] = (R828_Arry[1] & 0xBF); //0: PRE_DECT off
2800 R828_I2C.RegAddr = 0x06;
2801 R828_I2C.Data = R828_Arry[1];
2802 if(I2C_Write(pTuner, &R828_I2C) != RT_Success)
2806 R828_Arry[24] = (R828_Arry[24] & 0xC7) | (SysFreq_Info1.LNA_TOP & 0x38);
2807 R828_I2C.RegAddr = 0x1D;
2808 R828_I2C.Data = R828_Arry[24];
2809 if(I2C_Write(pTuner, &R828_I2C) != RT_Success)
2812 // write discharge mode
2813 R828_Arry[23] = (R828_Arry[23] & 0xFB) | (SysFreq_Info1.MIXER_TOP & 0x04);
2814 R828_I2C.RegAddr = 0x1C;
2815 R828_I2C.Data = R828_Arry[23];
2816 if(I2C_Write(pTuner, &R828_I2C) != RT_Success)
2819 // LNA discharge current
2820 R828_Arry[25] = (R828_Arry[25] & 0xE0) | SysFreq_Info1.LNA_DISCHARGE;
2821 R828_I2C.RegAddr = 0x1E;
2822 R828_I2C.Data = R828_Arry[25];
2823 if(I2C_Write(pTuner, &R828_I2C) != RT_Success)
2826 // agc clk 1Khz, external det1 cap 1u
2827 R828_Arry[21] = (R828_Arry[21] & 0xCF) | 0x00;
2828 R828_I2C.RegAddr = 0x1A;
2829 R828_I2C.Data = R828_Arry[21];
2830 if(I2C_Write(pTuner, &R828_I2C) != RT_Success)
2833 R828_Arry[11] = (R828_Arry[11] & 0xFB) | 0x00;
2834 R828_I2C.RegAddr = 0x10;
2835 R828_I2C.Data = R828_Arry[11];
2836 if(I2C_Write(pTuner, &R828_I2C) != RT_Success)
2845 R828_ErrCode R828_Standby(void *pTuner, R828_LoopThrough_Type R828_LoopSwitch)
2847 if(R828_LoopSwitch == LOOP_THROUGH)
2849 R828_I2C.RegAddr = 0x06;
2850 R828_I2C.Data = 0xB1;
2851 if(I2C_Write(pTuner, &R828_I2C) != RT_Success)
2853 R828_I2C.RegAddr = 0x05;
2854 R828_I2C.Data = 0x03;
2857 if(I2C_Write(pTuner, &R828_I2C) != RT_Success)
2862 R828_I2C.RegAddr = 0x05;
2863 R828_I2C.Data = 0xA3;
2864 if(I2C_Write(pTuner, &R828_I2C) != RT_Success)
2867 R828_I2C.RegAddr = 0x06;
2868 R828_I2C.Data = 0xB1;
2869 if(I2C_Write(pTuner, &R828_I2C) != RT_Success)
2873 R828_I2C.RegAddr = 0x07;
2874 R828_I2C.Data = 0x3A;
2875 if(I2C_Write(pTuner, &R828_I2C) != RT_Success)
2878 R828_I2C.RegAddr = 0x08;
2879 R828_I2C.Data = 0x40;
2880 if(I2C_Write(pTuner, &R828_I2C) != RT_Success)
2883 R828_I2C.RegAddr = 0x09;
2884 R828_I2C.Data = 0xC0; //polyfilter off
2885 if(I2C_Write(pTuner, &R828_I2C) != RT_Success)
2888 R828_I2C.RegAddr = 0x0A;
2889 R828_I2C.Data = 0x36;
2890 if(I2C_Write(pTuner, &R828_I2C) != RT_Success)
2893 R828_I2C.RegAddr = 0x0C;
2894 R828_I2C.Data = 0x35;
2895 if(I2C_Write(pTuner, &R828_I2C) != RT_Success)
2898 R828_I2C.RegAddr = 0x0F;
2899 R828_I2C.Data = 0x78;
2900 if(I2C_Write(pTuner, &R828_I2C) != RT_Success)
2903 R828_I2C.RegAddr = 0x11;
2904 R828_I2C.Data = 0x03;
2905 if(I2C_Write(pTuner, &R828_I2C) != RT_Success)
2908 R828_I2C.RegAddr = 0x17;
2909 R828_I2C.Data = 0xF4;
2910 if(I2C_Write(pTuner, &R828_I2C) != RT_Success)
2913 R828_I2C.RegAddr = 0x19;
2914 R828_I2C.Data = 0x0C;
2915 if(I2C_Write(pTuner, &R828_I2C) != RT_Success)
2922 R828_ErrCode R828_GetRfGain(void *pTuner, R828_RF_Gain_Info *pR828_rf_gain)
2925 R828_I2C_Len.RegAddr = 0x00;
2926 R828_I2C_Len.Len = 4;
2927 if(I2C_Read_Len(pTuner, &R828_I2C_Len) != RT_Success)
2930 pR828_rf_gain->RF_gain1 = (R828_I2C_Len.Data[3] & 0x0F);
2931 pR828_rf_gain->RF_gain2 = ((R828_I2C_Len.Data[3] & 0xF0) >> 4);
2932 pR828_rf_gain->RF_gain_comb = pR828_rf_gain->RF_gain1*2 + pR828_rf_gain->RF_gain2;
2938 /* measured with a Racal 6103E GSM test set at 928 MHz with -60 dBm
2939 * input power, for raw results see:
2940 * http://steve-m.de/projects/rtl-sdr/gain_measurement/r820t/
2943 #define VGA_BASE_GAIN -47
2944 static const int r820t_vga_gain_steps[] = {
2945 0, 26, 26, 30, 42, 35, 24, 13, 14, 32, 36, 34, 35, 37, 35, 36
2948 static const int r820t_lna_gain_steps[] = {
2949 0, 9, 13, 40, 38, 13, 31, 22, 26, 31, 26, 14, 19, 5, 35, 13
2952 static const int r820t_mixer_gain_steps[] = {
2953 0, 5, 10, 10, 19, 9, 10, 25, 17, 10, 8, 16, 13, 6, 3, -8
2956 R828_ErrCode R828_SetRfGain(void *pTuner, int gain)
2958 int i, total_gain = 0;
2959 uint8_t mix_index = 0, lna_index = 0;
2961 for (i = 0; i < 15; i++) {
2962 if (total_gain >= gain)
2965 total_gain += r820t_lna_gain_steps[++lna_index];
2967 if (total_gain >= gain)
2970 total_gain += r820t_mixer_gain_steps[++mix_index];
2974 R828_I2C.RegAddr = 0x05;
2975 R828_Arry[0] = (R828_Arry[0] & 0xF0) | lna_index;
2976 R828_I2C.Data = R828_Arry[0];
2977 if(I2C_Write(pTuner, &R828_I2C) != RT_Success)
2980 /* set Mixer gain */
2981 R828_I2C.RegAddr = 0x07;
2982 R828_Arry[2] = (R828_Arry[2] & 0xF0) | mix_index;
2983 R828_I2C.Data = R828_Arry[2];
2984 if(I2C_Write(pTuner, &R828_I2C) != RT_Success)
2990 R828_ErrCode R828_RfGainMode(void *pTuner, int manual)
3000 R828_I2C.RegAddr = 0x05;
3001 R828_Arry[0] = R828_Arry[0] | 0x10;
3002 R828_I2C.Data = R828_Arry[0];
3003 if(I2C_Write(pTuner, &R828_I2C) != RT_Success)
3007 R828_I2C.RegAddr = 0x07;
3008 R828_Arry[2] = R828_Arry[2] & 0xEF;
3009 R828_I2C.Data = R828_Arry[2];
3010 if(I2C_Write(pTuner, &R828_I2C) != RT_Success)
3013 R828_I2C_Len.RegAddr = 0x00;
3014 R828_I2C_Len.Len = 4;
3015 if(I2C_Read_Len(pTuner, &R828_I2C_Len) != RT_Success)
3018 /* set fixed VGA gain for now (16.3 dB) */
3019 R828_I2C.RegAddr = 0x0C;
3020 R828_Arry[7] = (R828_Arry[7] & 0x60) | 0x08;
3021 R828_I2C.Data = R828_Arry[7];
3022 if(I2C_Write(pTuner, &R828_I2C) != RT_Success)
3028 R828_I2C.RegAddr = 0x05;
3029 R828_Arry[0] = R828_Arry[0] & 0xEF;
3030 R828_I2C.Data = R828_Arry[0];
3031 if(I2C_Write(pTuner, &R828_I2C) != RT_Success)
3035 R828_I2C.RegAddr = 0x07;
3036 R828_Arry[2] = R828_Arry[2] | 0x10;
3037 R828_I2C.Data = R828_Arry[2];
3038 if(I2C_Write(pTuner, &R828_I2C) != RT_Success)
3041 /* set fixed VGA gain for now (26.5 dB) */
3042 R828_I2C.RegAddr = 0x0C;
3043 R828_Arry[7] = (R828_Arry[7] & 0x60) | 0x0B;
3044 R828_I2C.Data = R828_Arry[7];
3045 if(I2C_Write(pTuner, &R828_I2C) != RT_Success)