[PATCH] rtl_sdr: Direct sampling mode + RTL AGC

This is merely a historical archive of years 2008-2021, before the migration to mailman3.

A maintained and still updated list archive can be found at https://lists.osmocom.org/hyperkitty/list/osmocom-sdr@lists.osmocom.org/.

psb hlw psbhlw at mail.ru
Sun Sep 15 20:07:08 UTC 2013


Hi,

I didn't find rtl_sdr with implemented direct sampling mode, so I made the patch. Also it has an option to set RTL AGC on.

This feature allows to use tuners as cheap data loggers without changing the schematic of the tuners. You can just connect wires directly to pins 1-2 of RTL2832 (I channel, diff. input) or pins 3-4 (Q channel, diff. input). When direct sampling mode is on - tuner's chip outputs are disabled and doesn't affect external signal.

For example, this command will write 8 bit samples to file 'mydata' at 2.4 MHz sampling rate with automatic gain:

        rtl_sdr.exe -f 0 -s 2400000 -i -G mydata

Hope this will be useful for somebody as it was for me.

If you will accept the patch - please, update the windows binaries.

Thanks,
psb.

-------------------------------------------------------------------------------
diff --git a/src/rtl_sdr.c b/src/rtl_sdr.c
index eeb6dba..3564329 100644
--- a/src/rtl_sdr.c
+++ b/src/rtl_sdr.c
@@ -42,6 +42,7 @@
 static int do_exit = 0;
 static uint32_t bytes_to_read = 0;
 static rtlsdr_dev_t *dev = NULL;
+static int samp_mode = 0;
 
 void usage(void)
 {
@@ -54,6 +55,9 @@ void usage(void)
 		"\t[-b output_block_size (default: 16 * 16384)]\n"
 		"\t[-n number of samples to read (default: 0, infinite)]\n"
 		"\t[-S force sync output (default: async)]\n"
+		"\t[-i set direct sampling mode (I)]\n"
+		"\t[-q set direct sampling mode (Q)]\n"
+		"\t[-G use RTL automatic gain]\n"
 		"\tfilename (a '-' dumps samples to stdout)\n\n");
 	exit(1);
 }
@@ -81,6 +85,8 @@ static void sighandler(int signum)
 
 static void rtlsdr_callback(unsigned char *buf, uint32_t len, void *ctx)
 {
+	uint32_t i, r;
+	unsigned char *p1, *p2;
 	if (ctx) {
 		if (do_exit)
 			return;
@@ -91,7 +97,16 @@ static void rtlsdr_callback(unsigned char *buf, uint32_t len, void *ctx)
 			rtlsdr_cancel_async(dev);
 		}
 
-		if (fwrite(buf, 1, len, (FILE*)ctx) != len) {
+		if (samp_mode) {
+			// For direct sampling mode we throw out each 2nd value,
+			// i.e., save only one channel data - I or Q.
+			for (i=0, p1=buf, p2=buf; i<len; i+=2, p2++)
+				*p1++ = *p2++;
+			r = (fwrite(buf, 1, len/2, (FILE*)ctx) == len/2);
+		} else
+			r = (fwrite(buf, 1, len, (FILE*)ctx) == len);
+
+		if (!r) {
 			fprintf(stderr, "Short write, samples lost, exiting!\n");
 			rtlsdr_cancel_async(dev);
 		}
@@ -119,8 +134,10 @@ int main(int argc, char **argv)
 	uint32_t out_block_size = DEFAULT_BUF_LENGTH;
 	int device_count;
 	char vendor[256], product[256], serial[256];
+	uint32_t use_rtlagc = 0;
+	unsigned char *p1, *p2;
 
-	while ((opt = getopt(argc, argv, "d:f:g:s:b:n:S::")) != -1) {
+	while ((opt = getopt(argc, argv, "d:f:g:s:b:n:S::Gqi")) != -1) {
 		switch (opt) {
 		case 'd':
 			dev_index = atoi(optarg);
@@ -143,6 +160,15 @@ int main(int argc, char **argv)
 		case 'S':
 			sync_mode = 1;
 			break;
+		case 'q':
+			samp_mode = 2;
+			break;
+		case 'i':
+			samp_mode = 1;
+			break;
+		case 'G':
+			use_rtlagc = 1;
+			break;
 		default:
 			usage();
 			break;
@@ -205,6 +231,15 @@ int main(int argc, char **argv)
 	if (r < 0)
 		fprintf(stderr, "WARNING: Failed to set sample rate.\n");
 
+	/* Set direct sampling */
+	if (samp_mode) {
+		r = rtlsdr_set_direct_sampling(dev, samp_mode);
+		if (r < 0)
+			fprintf(stderr, "WARNING: Failed to set direct sampling mode.\n");
+		else
+			fprintf(stderr, "Tuner set to direct sampling mode (%c).\n", (samp_mode==1)?'I':'Q');
+	}
+
 	/* Set the frequency */
 	r = rtlsdr_set_center_freq(dev, frequency);
 	if (r < 0)
@@ -231,6 +266,21 @@ int main(int argc, char **argv)
 			fprintf(stderr, "Tuner gain set to %f dB.\n", gain/10.0);
 	}
 
+	/* Set RTL automatic gain */
+	if (1 == use_rtlagc) {
+		/* Enable automatic RTL gain */
+		r = rtlsdr_set_agc_mode(dev, 1);
+		if (r < 0)
+			fprintf(stderr, "WARNING: Failed to enable RTL automatic gain.\n");
+		else
+			fprintf(stderr, "RTL automatic gain enabled.\n");
+	} else {
+		/* Disable automatic RTL gain */
+		r = rtlsdr_set_agc_mode(dev, 0);
+		if (r < 0)
+			fprintf(stderr, "WARNING: Failed to disable RTL automatic gain.\n");
+	}
+
 	if(strcmp(filename, "-") == 0) { /* Write samples to stdout */
 		file = stdout;
 #ifdef _WIN32
@@ -263,7 +313,16 @@ int main(int argc, char **argv)
 				do_exit = 1;
 			}
 
-			if (fwrite(buffer, 1, n_read, file) != (size_t)n_read) {
+			if (samp_mode) {
+				// For direct sampling mode we throw out each 2nd value,
+				// i.e., save only one channel data - I or Q.
+				for (i=0, p1=buffer, p2=buffer; i<n_read; i+=2, p2++)
+					*p1++ = *p2++;
+				r = (fwrite(buffer, 1, n_read/2, file)== n_read/2);
+			} else
+				r = (fwrite(buffer, 1, n_read, file) == n_read);
+
+			if (!r) {
 				fprintf(stderr, "Short write, samples lost, exiting!\n");
 				break;
 			}




More information about the osmocom-sdr mailing list