@@ -86,6 +86,11 @@ int gettimeofday(struct timeval *tv, void* ignored)
8686#define DEFAULT_FREQ_HZ (900000000ull) /* 900MHz */
8787#define FREQ_MIN_HZ (0ull) /* 0 Hz */
8888#define FREQ_MAX_HZ (7250000000ull) /* 7250MHz */
89+ #define IF_MIN_HZ (2150000000ull)
90+ #define IF_MAX_HZ (2750000000ull)
91+ #define LO_MIN_HZ (84375000ull)
92+ #define LO_MAX_HZ (5400000000ull)
93+ #define DEFAULT_LO_HZ (1000000000ull)
8994
9095#define DEFAULT_SAMPLE_RATE_HZ (10000000) /* 10MHz default sample rate */
9196
@@ -240,10 +245,19 @@ bool receive_wav = false;
240245bool transmit = false;
241246struct timeval time_start ;
242247struct timeval t_start ;
243-
244- bool freq = false;
248+
249+ bool automatic_tuning = false;
245250uint64_t freq_hz ;
246251
252+ bool if_freq = false;
253+ uint64_t if_freq_hz ;
254+
255+ bool lo_freq = false;
256+ uint64_t lo_freq_hz = DEFAULT_LO_HZ ;
257+
258+ bool image_reject = false;
259+ uint32_t image_reject_selection ;
260+
247261bool amp = false;
248262uint32_t amp_enable ;
249263
@@ -326,13 +340,16 @@ static void usage() {
326340 printf ("\t-t <filename> # Transmit data from file.\n" );
327341 printf ("\t-w # Receive data into file with WAV header and automatic name.\n" );
328342 printf ("\t # This is for SDR# compatibility and may not work with other software.\n" );
329- printf ("\t[-f set_freq_hz] # Set Freq in Hz between [%lluMHz, %lluMHz].\n" , FREQ_MIN_HZ /FREQ_ONE_MHZ , FREQ_MAX_HZ /FREQ_ONE_MHZ );
330- printf ("\t[-a set_amp] # Set Amp 1=Enable, 0=Disable.\n" );
331- printf ("\t[-p set_antenna] # Set antenna port power, 1=Enable, 0=Disable.\n" );
332- printf ("\t[-l gain_db] # Set lna gain, 0-40dB, 8dB steps\n" );
333- printf ("\t[-i gain_db] # Set vga(if) gain, 0-62dB, 2dB steps\n" );
334- printf ("\t[-x gain_db] # Set TX vga gain, 0-47dB, 1dB steps\n" );
335- printf ("\t[-s sample_rate_hz] # Set sample rate in Hz (8/10/12.5/16/20MHz, default %lldMHz).\n" , DEFAULT_SAMPLE_RATE_HZ /FREQ_ONE_MHZ );
343+ printf ("\t[-f freq_hz] # Frequency in Hz between [%lluMHz, %lluMHz].\n" , FREQ_MIN_HZ /FREQ_ONE_MHZ , FREQ_MAX_HZ /FREQ_ONE_MHZ );
344+ printf ("\t[-e if_freq_hz] # Intermediate Frequency (IF) in Hz [%lluMHz to %lluMHz].\n" , IF_MIN_HZ /FREQ_ONE_MHZ , IF_MAX_HZ /FREQ_ONE_MHZ );
345+ printf ("\t[-o lo_freq_hz] # Front-end Local Oscillator (LO) frequency in Hz [%lluMHz to %lluMHz].\n" , LO_MIN_HZ /FREQ_ONE_MHZ , LO_MAX_HZ /FREQ_ONE_MHZ );
346+ printf ("\t[-m image_reject] # Image rejection filter selection, 0=bypass, 1=low pass, 2=high pass.\n" );
347+ printf ("\t[-a amp_enable] # Amplifier 1=Enable, 0=Disable.\n" );
348+ printf ("\t[-p antenna_enable] # Antenna port power, 1=Enable, 0=Disable.\n" );
349+ printf ("\t[-l gain_db] # LNA gain, 0-40dB, 8dB steps\n" );
350+ printf ("\t[-i gain_db] # VGA(IF) gain, 0-62dB, 2dB steps\n" );
351+ printf ("\t[-x gain_db] # TX VGA gain, 0-47dB, 1dB steps\n" );
352+ printf ("\t[-s sample_rate_hz] # Sample rate in Hz (8/10/12.5/16/20MHz, default %lldMHz).\n" , DEFAULT_SAMPLE_RATE_HZ /FREQ_ONE_MHZ );
336353 printf ("\t[-n num_samples] # Number of samples to transfer (default is unlimited).\n" );
337354 printf ("\t[-b baseband_filter_bw_hz] # Set baseband filter bandwidth in MHz.\n\tPossible values: 1.75/2.5/3.5/5/5.5/6/7/8/9/10/12/14/15/20/24/28MHz, default < sample_rate_hz.\n" );
338355}
@@ -375,7 +392,7 @@ int main(int argc, char** argv) {
375392 float time_diff ;
376393 unsigned int lna_gain = 8 , vga_gain = 20 , txvga_gain = 0 ;
377394
378- while ( (opt = getopt (argc , argv , "wr:t:f:a:p:s:n:b:l:i:x:" )) != EOF )
395+ while ( (opt = getopt (argc , argv , "wr:t:f:e:o:m: a:p:s:n:b:l:i:x:" )) != EOF )
379396 {
380397 result = HACKRF_SUCCESS ;
381398 switch ( opt )
@@ -393,12 +410,27 @@ int main(int argc, char** argv) {
393410 transmit = true;
394411 path = optarg ;
395412 break ;
396-
413+
397414 case 'f' :
398- freq = true;
415+ automatic_tuning = true;
399416 result = parse_u64 (optarg , & freq_hz );
400417 break ;
401418
419+ case 'e' :
420+ if_freq = true;
421+ result = parse_u64 (optarg , & if_freq_hz );
422+ break ;
423+
424+ case 'o' :
425+ lo_freq = true;
426+ result = parse_u64 (optarg , & lo_freq_hz );
427+ break ;
428+
429+ case 'm' :
430+ image_reject = true;
431+ result = parse_u32 (optarg , & image_reject_selection );
432+ break ;
433+
402434 case 'a' :
403435 amp = true;
404436 result = parse_u32 (optarg , & amp_enable );
@@ -457,31 +489,82 @@ int main(int argc, char** argv) {
457489 return EXIT_FAILURE ;
458490 }
459491
460- if ( freq ) {
461- if ( (freq_hz >= FREQ_MAX_HZ ) || (freq_hz < FREQ_MIN_HZ ) )
492+ if (if_freq || lo_freq || image_reject ) {
493+ /* explicit tuning selected */
494+ if (!if_freq ) {
495+ printf ("argument error: if_freq_hz must be specified for explicit tuning.\n" );
496+ usage ();
497+ return EXIT_FAILURE ;
498+ }
499+ if (!image_reject ) {
500+ printf ("argument error: image_reject must be specified for explicit tuning.\n" );
501+ usage ();
502+ return EXIT_FAILURE ;
503+ }
504+ if (!lo_freq && (image_reject_selection != RF_PATH_FILTER_BYPASS )) {
505+ printf ("argument error: lo_freq_hz must be specified for explicit tuning unless image_reject is set to bypass.\n" );
506+ usage ();
507+ return EXIT_FAILURE ;
508+ }
509+ if ((if_freq_hz > IF_MAX_HZ ) || (if_freq_hz < IF_MIN_HZ )) {
510+ printf ("argument error: if_freq_hz shall be between %llu and %llu.\n" , IF_MIN_HZ , IF_MAX_HZ );
511+ usage ();
512+ return EXIT_FAILURE ;
513+ }
514+ if ((lo_freq_hz > LO_MAX_HZ ) || (lo_freq_hz < LO_MIN_HZ )) {
515+ printf ("argument error: lo_freq_hz shall be between %llu and %llu.\n" , LO_MIN_HZ , LO_MAX_HZ );
516+ usage ();
517+ return EXIT_FAILURE ;
518+ }
519+ if (image_reject_selection > 2 ) {
520+ printf ("argument error: image_reject must be 0, 1, or 2 .\n" );
521+ usage ();
522+ return EXIT_FAILURE ;
523+ }
524+ if (automatic_tuning ) {
525+ printf ("warning: freq_hz ignored by explicit tuning selection.\n" );
526+ automatic_tuning = false;
527+ }
528+ switch (image_reject_selection ) {
529+ case RF_PATH_FILTER_BYPASS :
530+ freq_hz = if_freq_hz ;
531+ break ;
532+ case RF_PATH_FILTER_LOW_PASS :
533+ freq_hz = abs (if_freq_hz - lo_freq_hz );
534+ break ;
535+ case RF_PATH_FILTER_HIGH_PASS :
536+ freq_hz = if_freq_hz + lo_freq_hz ;
537+ break ;
538+ default :
539+ freq_hz = DEFAULT_FREQ_HZ ;
540+ break ;
541+ }
542+ printf ("explicit tuning specified for %lu Hz.\n" , freq_hz );
543+ } else if (automatic_tuning ) {
544+ if ( (freq_hz > FREQ_MAX_HZ ) || (freq_hz < FREQ_MIN_HZ ) )
462545 {
463- printf ("argument error: set_freq_hz shall be between [ %llu, %llu[ .\n" , FREQ_MIN_HZ , FREQ_MAX_HZ );
546+ printf ("argument error: freq_hz shall be between %llu and %llu.\n" , FREQ_MIN_HZ , FREQ_MAX_HZ );
464547 usage ();
465548 return EXIT_FAILURE ;
466549 }
467- }else
468- {
550+ } else {
469551 /* Use default freq */
470552 freq_hz = DEFAULT_FREQ_HZ ;
553+ automatic_tuning = true;
471554 }
472555
473556 if ( amp ) {
474557 if ( amp_enable > 1 )
475558 {
476- printf ("argument error: set_amp shall be 0 or 1.\n" );
559+ printf ("argument error: amp_enable shall be 0 or 1.\n" );
477560 usage ();
478561 return EXIT_FAILURE ;
479562 }
480563 }
481564
482565 if (antenna ) {
483566 if (antenna_enable > 1 ) {
484- printf ("argument error: set_antenna shall be 0 or 1.\n" );
567+ printf ("argument error: antenna_enable shall be 0 or 1.\n" );
485568 usage ();
486569 return EXIT_FAILURE ;
487570 }
@@ -645,12 +728,25 @@ int main(int argc, char** argv) {
645728 return EXIT_FAILURE ;
646729 }
647730
648- printf ("call hackrf_set_freq(%lu Hz/%.03f MHz)\n" , freq_hz , ((double )freq_hz /(double )FREQ_ONE_MHZ ) );
649- result = hackrf_set_freq (device , freq_hz );
650- if ( result != HACKRF_SUCCESS ) {
651- printf ("hackrf_set_freq() failed: %s (%d)\n" , hackrf_error_name (result ), result );
652- usage ();
653- return EXIT_FAILURE ;
731+ if (automatic_tuning ) {
732+ printf ("call hackrf_set_freq(%lu Hz/%.03f MHz)\n" , freq_hz , ((double )freq_hz /(double )FREQ_ONE_MHZ ) );
733+ result = hackrf_set_freq (device , freq_hz );
734+ if ( result != HACKRF_SUCCESS ) {
735+ printf ("hackrf_set_freq() failed: %s (%d)\n" , hackrf_error_name (result ), result );
736+ usage ();
737+ return EXIT_FAILURE ;
738+ }
739+ } else {
740+ printf ("call hackrf_set_freq_explicit() with %lu Hz IF, %lu Hz LO, %s\n" ,
741+ if_freq_hz , lo_freq_hz , hackrf_filter_path_name (image_reject_selection ));
742+ result = hackrf_set_freq_explicit (device , if_freq_hz , lo_freq_hz ,
743+ image_reject_selection );
744+ if (result != HACKRF_SUCCESS ) {
745+ printf ("hackrf_set_freq_explicit() failed: %s (%d)\n" ,
746+ hackrf_error_name (result ), result );
747+ usage ();
748+ return EXIT_FAILURE ;
749+ }
654750 }
655751
656752 if ( amp ) {
0 commit comments