Просмотр исходного кода

add initial support for the R820T tuner

Signed-off-by: Steve Markgraf <steve@steve-m.de>
Steve Markgraf лет назад: 12
Родитель
Сommit
5a26bd51e7
6 измененных файлов с 3238 добавлено и 5 удалено
  1. 2 1
      include/rtl-sdr.h
  2. 192 0
      include/tuner_r820t.h
  3. 2 0
      src/CMakeLists.txt
  4. 1 1
      src/Makefile.am
  5. 60 3
      src/librtlsdr.c
  6. 2981 0
      src/tuner_r820t.c

+ 2 - 1
include/rtl-sdr.h

@@ -131,7 +131,8 @@ enum rtlsdr_tuner {
 	RTLSDR_TUNER_E4000,
 	RTLSDR_TUNER_FC0012,
 	RTLSDR_TUNER_FC0013,
-	RTLSDR_TUNER_FC2580
+	RTLSDR_TUNER_FC2580,
+	RTLSDR_TUNER_R820T
 };
 
 /*!

+ 192 - 0
include/tuner_r820t.h

@@ -0,0 +1,192 @@
+#ifndef _R820T_TUNER_H
+#define _R820T_TUNER_H
+
+#define R820T_I2C_ADDR		0x34
+#define R820T_CHECK_ADDR	0x00
+#define R820T_CHECK_VAL		0x69
+
+//***************************************************************
+//*                       INCLUDES.H
+//***************************************************************
+#define VERSION   "R820T_v1.49_ASTRO"
+#define VER_NUM  49
+
+#define USE_16M_XTAL		FALSE
+#define R828_Xtal		28800
+
+#define USE_DIPLEXER		FALSE
+#define TUNER_CLK_OUT		TRUE
+
+#ifndef _UINT_X_
+#define _UINT_X_ 1
+typedef unsigned char  UINT8;
+typedef unsigned short UINT16;
+typedef unsigned int   UINT32;
+#endif
+
+#define TRUE	1
+#define FALSE	0
+
+#define FUNCTION_SUCCESS	0
+#define FUNCTION_ERROR		-1
+
+typedef enum _R828_ErrCode
+{
+	RT_Success,
+	RT_Fail
+}R828_ErrCode;
+
+typedef enum _Rafael_Chip_Type  //Don't modify chip list
+{
+	R828 = 0,
+	R828D,
+	R828S,
+	R820T,
+	R820C,
+	R620D,
+	R620S
+}Rafael_Chip_Type;
+//----------------------------------------------------------//
+//                   R828 Parameter                        //
+//----------------------------------------------------------//
+
+extern UINT8 R828_ADDRESS;
+
+#define DIP_FREQ  	  320000
+#define IMR_TRIAL    9
+#define VCO_pwr_ref   0x02
+
+extern UINT32 R828_IF_khz;
+extern UINT32 R828_CAL_LO_khz;
+extern UINT8  R828_IMR_point_num;
+extern UINT8  R828_IMR_done_flag;
+extern UINT8  Rafael_Chip;
+
+typedef enum _R828_Standard_Type  //Don't remove standand list!!
+{
+	NTSC_MN = 0,
+	PAL_I,
+	PAL_DK,
+	PAL_B_7M,       //no use
+	PAL_BGH_8M,     //for PAL B/G, PAL G/H
+	SECAM_L,
+	SECAM_L1_INV,   //for SECAM L'
+	SECAM_L1,       //no use
+	ATV_SIZE,
+	DVB_T_6M = ATV_SIZE,
+	DVB_T_7M,
+	DVB_T_7M_2,
+	DVB_T_8M,
+	DVB_T2_6M,
+	DVB_T2_7M,
+	DVB_T2_7M_2,
+	DVB_T2_8M,
+	DVB_T2_1_7M,
+	DVB_T2_10M,
+	DVB_C_8M,
+	DVB_C_6M,
+	ISDB_T,
+	DTMB,
+	R828_ATSC,
+	FM,
+	STD_SIZE
+}R828_Standard_Type;
+
+extern UINT8  R828_Fil_Cal_flag[STD_SIZE];
+
+typedef enum _R828_SetFreq_Type
+{
+	FAST_MODE = TRUE,
+	NORMAL_MODE = FALSE
+}R828_SetFreq_Type;
+
+typedef enum _R828_LoopThrough_Type
+{
+	LOOP_THROUGH = TRUE,
+	SIGLE_IN     = FALSE
+}R828_LoopThrough_Type;
+
+
+typedef enum _R828_InputMode_Type
+{
+	AIR_IN = 0,
+	CABLE_IN_1,
+	CABLE_IN_2
+}R828_InputMode_Type;
+
+typedef enum _R828_IfAgc_Type
+{
+	IF_AGC1 = 0,
+	IF_AGC2
+}R828_IfAgc_Type;
+
+typedef enum _R828_GPIO_Type
+{
+	HI_SIG = TRUE,
+	LO_SIG = FALSE
+}R828_GPIO_Type;
+
+typedef struct _R828_Set_Info
+{
+	UINT32        RF_KHz;
+	R828_Standard_Type R828_Standard;
+	R828_LoopThrough_Type RT_Input;
+	R828_InputMode_Type   RT_InputMode;
+	R828_IfAgc_Type R828_IfAgc_Select; 
+}R828_Set_Info;
+
+typedef struct _R828_RF_Gain_Info
+{
+	UINT8   RF_gain1;
+	UINT8   RF_gain2;
+	UINT8   RF_gain_comb;
+}R828_RF_Gain_Info;
+
+typedef enum _R828_RF_Gain_TYPE
+{
+	RF_AUTO = 0,
+	RF_MANUAL
+}R828_RF_Gain_TYPE;
+
+typedef struct _R828_I2C_LEN_TYPE
+{
+	UINT8 RegAddr;
+	UINT8 Data[50];
+	UINT8 Len;
+}R828_I2C_LEN_TYPE;
+
+typedef struct _R828_I2C_TYPE
+{
+	UINT8 RegAddr;
+	UINT8 Data;
+}R828_I2C_TYPE;
+//----------------------------------------------------------//
+//                   R828 Function                         //
+//----------------------------------------------------------//
+R828_ErrCode R828_Init(void *pTuner);
+R828_ErrCode R828_Standby(void *pTuner, R828_LoopThrough_Type R828_LoopSwitch);
+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);
+
+int
+r820t_SetRfFreqHz(
+	void *pTuner,
+	unsigned long RfFreqHz
+	);
+
+int
+r820t_SetStandardMode(
+	void *pTuner,
+	int StandardMode
+	);
+
+int
+r820t_SetStandby(
+	void *pTuner,
+	int LoopThroughType
+	);
+
+#endif /* _R820T_TUNER_H */

+ 2 - 0
src/CMakeLists.txt

@@ -26,6 +26,7 @@ add_library(rtlsdr_shared SHARED
     tuner_fc0012.c
     tuner_fc0013.c
     tuner_fc2580.c
+    tuner_r820t.c
 )
 
 target_link_libraries(rtlsdr_shared
@@ -42,6 +43,7 @@ add_library(rtlsdr_static STATIC
     tuner_fc0012.c
     tuner_fc0013.c
     tuner_fc2580.c
+    tuner_r820t.c
 )
 
 if(WIN32)

+ 1 - 1
src/Makefile.am

@@ -7,7 +7,7 @@ AM_CFLAGS = ${CFLAGS} -fPIC ${SYMBOL_VISIBILITY}
 
 lib_LTLIBRARIES = librtlsdr.la
 
-librtlsdr_la_SOURCES = librtlsdr.c tuner_e4k.c tuner_fc0012.c tuner_fc0013.c tuner_fc2580.c
+librtlsdr_la_SOURCES = librtlsdr.c tuner_e4k.c tuner_fc0012.c tuner_fc0013.c tuner_fc2580.c tuner_r820t.c
 librtlsdr_la_LDFLAGS = -version-info $(LIBVERSION)
 
 bin_PROGRAMS         = rtl_sdr rtl_tcp rtl_test rtl_fm

+ 60 - 3
src/librtlsdr.c

@@ -39,11 +39,15 @@
 #define LIBUSB_CALL
 #endif
 
+/* two raised to the power of n */
+#define TWO_POW(n)		((double)(1ULL<<(n)))
+
 #include "rtl-sdr.h"
 #include "tuner_e4k.h"
 #include "tuner_fc0012.h"
 #include "tuner_fc0013.h"
 #include "tuner_fc2580.h"
+#include "tuner_r820t.h"
 
 typedef struct rtlsdr_tuner_iface {
 	/* tuner interface */
@@ -160,6 +164,17 @@ int fc2580_set_bw(void *dev, int bw) { return fc2580_SetBandwidthMode(dev, 1); }
 int fc2580_set_gain(void *dev, int gain) { return 0; }
 int fc2580_set_gain_mode(void *dev, int manual) { return 0; }
 
+int r820t_init(void *dev) {
+	int r = R828_Init(dev);
+	r820t_SetStandardMode(dev, DVB_T_6M);
+	return r;
+}
+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; }
+
 /* definition order must match enum rtlsdr_tuner */
 static rtlsdr_tuner_iface_t tuners[] = {
 	{
@@ -185,6 +200,11 @@ static rtlsdr_tuner_iface_t tuners[] = {
 		_fc2580_set_freq, fc2580_set_bw, fc2580_set_gain, NULL,
 		fc2580_set_gain_mode
 	},
+	{
+		r820t_init, r820t_exit,
+		r820t_set_freq, r820t_set_bw, r820t_set_gain, NULL,
+		r820t_set_gain_mode
+	},
 };
 
 typedef struct rtlsdr_dongle {
@@ -540,6 +560,24 @@ int rtlsdr_deinit_baseband(rtlsdr_dev_t *dev)
 	return r;
 }
 
+int rtlsdr_set_if_freq(rtlsdr_dev_t *dev, uint32_t freq)
+{
+	int32_t if_freq;
+	uint8_t tmp;
+	int r;
+
+	if_freq = ((freq * TWO_POW(22)) / dev->rtl_xtal) * (-1);
+
+	tmp = (if_freq >> 16) & 0x3f;
+	r = rtlsdr_demod_write_reg(dev, 1, 0x19, tmp, 1);
+	tmp = (if_freq >> 8) & 0xff;
+	r |= rtlsdr_demod_write_reg(dev, 1, 0x1a, tmp, 1);
+	tmp = if_freq & 0xff;
+	r |= rtlsdr_demod_write_reg(dev, 1, 0x1b, tmp, 1);
+
+	return r;
+}
+
 int rtlsdr_set_xtal_freq(rtlsdr_dev_t *dev, uint32_t rtl_freq, uint32_t tuner_freq)
 {
 	int r = 0;
@@ -712,6 +750,7 @@ int rtlsdr_get_tuner_gains(rtlsdr_dev_t *dev, int *gains)
 	const int fc0012_gains[] = { -99, -40, 71, 179, 192 };
 	const int fc0013_gains[] = { -63, 71, 191, 197 };
 	const int fc2580_gains[] = { 0 /* no gain values */ };
+	const int r820t_gains[] = { 0 /* no gain values */ };
 
 	int *ptr = NULL;
 	int len = 0;
@@ -732,6 +771,9 @@ int rtlsdr_get_tuner_gains(rtlsdr_dev_t *dev, int *gains)
 	case RTLSDR_TUNER_FC2580:
 		ptr = (int *)fc2580_gains; len = sizeof(fc2580_gains);
 		break;
+	case RTLSDR_TUNER_R820T:
+		ptr = (int *)r820t_gains; len = sizeof(r820t_gains);
+		break;
 	default:
 		fprintf(stderr, "Invalid tuner type %d\n", dev->tuner_type);
 		break;
@@ -808,9 +850,6 @@ int rtlsdr_set_tuner_gain_mode(rtlsdr_dev_t *dev, int mode)
 	return r;
 }
 
-/* two raised to the power of n */
-#define TWO_POW(n)		((double)(1ULL<<(n)))
-
 int rtlsdr_set_sample_rate(rtlsdr_dev_t *dev, uint32_t samp_rate)
 {
 	uint16_t tmp;
@@ -1088,6 +1127,24 @@ int rtlsdr_open(rtlsdr_dev_t **out_dev, uint32_t index)
 		goto found;
 	}
 
+	reg = rtlsdr_i2c_read_reg(dev, R820T_I2C_ADDR, R820T_CHECK_ADDR);
+	if (reg == R820T_CHECK_VAL) {
+		fprintf(stderr, "Found Rafael Micro R820T tuner\n");
+		dev->tuner_type = RTLSDR_TUNER_R820T;
+
+		/* disable Zero-IF mode */
+		rtlsdr_demod_write_reg(dev, 1, 0xb1, 0x1a, 1);
+
+		/* the R820T uses 3.57 MHz IF for the DVB-T 6 MHz mode, and
+		 * 4.57 MHz for the 8 MHz mode */
+		rtlsdr_set_if_freq(dev, 3570000);
+
+		/* enable spectrum inversion */
+		rtlsdr_demod_write_reg(dev, 1, 0x15, 0x01, 1);
+
+		goto found;
+	}
+
 	/* initialise GPIOs */
 	rtlsdr_set_gpio_output(dev, 5);
 

Разница между файлами не показана из-за своего большого размера
+ 2981 - 0
src/tuner_r820t.c