From 25789493c678f20bb8b58c7f60e06e96bf314c18 Mon Sep 17 00:00:00 2001 From: Steve Markgraf Date: Fri, 19 Oct 2012 01:17:28 +0200 Subject: [PATCH] tuner_r820t: add manual RF gain setting Signed-off-by: Steve Markgraf --- include/tuner_r820t.h | 3 +- src/librtlsdr.c | 9 +++-- src/tuner_r820t.c | 89 +++++++++++++++++++++++++++++++++---------- 3 files changed, 77 insertions(+), 24 deletions(-) diff --git a/include/tuner_r820t.h b/include/tuner_r820t.h index 10b8a1e..f9bd4cf 100644 --- a/include/tuner_r820t.h +++ b/include/tuner_r820t.h @@ -172,7 +172,8 @@ R828_ErrCode R828_GPIO(void *pTuner, R828_GPIO_Type R828_GPIO_Conrl); R828_ErrCode R828_SetStandard(void *pTuner, R828_Standard_Type RT_Standard); R828_ErrCode R828_SetFrequency(void *pTuner, R828_Set_Info R828_INFO, R828_SetFreq_Type R828_SetFreqMode); R828_ErrCode R828_GetRfGain(void *pTuner, R828_RF_Gain_Info *pR828_rf_gain); -R828_ErrCode R828_RfGainMode(void *pTuner, R828_RF_Gain_TYPE R828_RfGainType); +R828_ErrCode R828_SetRfGain(void *pTuner, int gain); +R828_ErrCode R828_RfGainMode(void *pTuner, int manual); int r820t_SetRfFreqHz( diff --git a/src/librtlsdr.c b/src/librtlsdr.c index 0aeda94..6efd3aa 100644 --- a/src/librtlsdr.c +++ b/src/librtlsdr.c @@ -180,8 +180,8 @@ int r820t_init(void *dev) { int r820t_exit(void *dev) { return 0; } int r820t_set_freq(void *dev, uint32_t freq) { return r820t_SetRfFreqHz(dev, freq); } int r820t_set_bw(void *dev, int bw) { return 0; } -int r820t_set_gain(void *dev, int gain) { return 0; } -int r820t_set_gain_mode(void *dev, int manual) { return 0; } +int r820t_set_gain(void *dev, int gain) { return R828_SetRfGain(dev, gain); } +int r820t_set_gain_mode(void *dev, int manual) { return R828_RfGainMode(dev, manual); } /* definition order must match enum rtlsdr_tuner */ static rtlsdr_tuner_iface_t tuners[] = { @@ -788,7 +788,10 @@ int rtlsdr_get_tuner_gains(rtlsdr_dev_t *dev, int *gains) 63, 65, 67, 68, 70, 71, 179, 181, 182, 184, 186, 188, 191, 197 }; const int fc2580_gains[] = { 0 /* no gain values */ }; - const int r820t_gains[] = { 0 /* no gain values */ }; + const int r820t_gains[] = { 0, 9, 14, 27, 37, 77, 87, 125, 144, 157, + 166, 197, 207, 229, 254, 280, 297, 328, + 338, 364, 372, 386, 402, 421, 434, 439, + 445, 480, 496 }; const int unknown_gains[] = { 0 /* no gain values */ }; int *ptr = NULL; diff --git a/src/tuner_r820t.c b/src/tuner_r820t.c index 3adca2e..553fbbc 100644 --- a/src/tuner_r820t.c +++ b/src/tuner_r820t.c @@ -2929,7 +2929,60 @@ R828_ErrCode R828_GetRfGain(void *pTuner, R828_RF_Gain_Info *pR828_rf_gain) return RT_Success; } -R828_ErrCode R828_RfGainMode(void *pTuner, R828_RF_Gain_TYPE R828_RfGainType) + +/* measured with a Racal 6103E GSM test set at 928 MHz with -60 dBm + * input power, for raw results see: + * http://steve-m.de/projects/rtl-sdr/gain_measurement/r820t/ + */ + +#define VGA_BASE_GAIN -47 +static const int r820t_vga_gain_steps[] = { + 0, 26, 26, 30, 42, 35, 24, 13, 14, 32, 36, 34, 35, 37, 35, 36 +}; + +static const int r820t_lna_gain_steps[] = { + 0, 9, 13, 40, 38, 13, 31, 22, 26, 31, 26, 14, 19, 5, 35, 13 +}; + +static const int r820t_mixer_gain_steps[] = { + 0, 5, 10, 10, 19, 9, 10, 25, 17, 10, 8, 16, 13, 6, 3, -8 +}; + +R828_ErrCode R828_SetRfGain(void *pTuner, int gain) +{ + int i, total_gain = 0; + uint8_t mix_index = 0, lna_index = 0; + + for (i = 0; i < 15; i++) { + if (total_gain >= gain) + break; + + total_gain += r820t_lna_gain_steps[++lna_index]; + + if (total_gain >= gain) + break; + + total_gain += r820t_mixer_gain_steps[++mix_index]; + } + + /* set LNA gain */ + R828_I2C.RegAddr = 0x05; + R828_Arry[0] = (R828_Arry[0] & 0xF0) | lna_index; + R828_I2C.Data = R828_Arry[0]; + if(I2C_Write(pTuner, &R828_I2C) != RT_Success) + return RT_Fail; + + /* set Mixer gain */ + R828_I2C.RegAddr = 0x07; + R828_Arry[2] = (R828_Arry[2] & 0xF0) | mix_index; + R828_I2C.Data = R828_Arry[2]; + if(I2C_Write(pTuner, &R828_I2C) != RT_Success) + return RT_Fail; + + return RT_Success; +} + +R828_ErrCode R828_RfGainMode(void *pTuner, int manual) { UINT8 MixerGain; UINT8 LnaGain; @@ -2937,8 +2990,7 @@ R828_ErrCode R828_RfGainMode(void *pTuner, R828_RF_Gain_TYPE R828_RfGainType) MixerGain = 0; LnaGain = 0; - if(R828_RfGainType==RF_MANUAL) - { + if (manual) { //LNA auto off R828_I2C.RegAddr = 0x05; R828_Arry[0] = R828_Arry[0] | 0x10; @@ -2958,25 +3010,15 @@ R828_ErrCode R828_RfGainMode(void *pTuner, R828_RF_Gain_TYPE R828_RfGainType) if(I2C_Read_Len(pTuner, &R828_I2C_Len) != RT_Success) return RT_Fail; - MixerGain = (R828_I2C_Len.Data[3] & 0xF0) >> 4; - LnaGain = R828_I2C_Len.Data[3] & 0x0F; + /* set fixed VGA gain for now (16.3 dB) */ + R828_I2C.RegAddr = 0x0C; + R828_Arry[7] = (R828_Arry[7] & 0x60) | 0x08; + R828_I2C.Data = R828_Arry[7]; + if(I2C_Write(pTuner, &R828_I2C) != RT_Success) + return RT_Fail; - //set LNA gain - R828_I2C.RegAddr = 0x05; - R828_Arry[0] = (R828_Arry[0] & 0xF0) | LnaGain; - R828_I2C.Data = R828_Arry[0]; - if(I2C_Write(pTuner, &R828_I2C) != RT_Success) - return RT_Fail; - //set Mixer gain - R828_I2C.RegAddr = 0x07; - R828_Arry[2] = (R828_Arry[2] & 0xF0) | MixerGain; - R828_I2C.Data = R828_Arry[2]; - if(I2C_Write(pTuner, &R828_I2C) != RT_Success) - return RT_Fail; - } - else - { + } else { //LNA R828_I2C.RegAddr = 0x05; R828_Arry[0] = R828_Arry[0] & 0xEF; @@ -2990,6 +3032,13 @@ R828_ErrCode R828_RfGainMode(void *pTuner, R828_RF_Gain_TYPE R828_RfGainType) R828_I2C.Data = R828_Arry[2]; if(I2C_Write(pTuner, &R828_I2C) != RT_Success) return RT_Fail; + + /* set fixed VGA gain for now (26.5 dB) */ + R828_I2C.RegAddr = 0x0C; + R828_Arry[7] = (R828_Arry[7] & 0x60) | 0x0B; + R828_I2C.Data = R828_Arry[7]; + if(I2C_Write(pTuner, &R828_I2C) != RT_Success) + return RT_Fail; } return RT_Success;