@@ -194,6 +194,12 @@ typedef struct {
194194
195195t_u64toa ascii_u64_data [4 ];
196196
197+ typedef struct {
198+ char data [U64TOA_MAX_DIGIT + 1 ];
199+ } t_fp64toa ;
200+
201+ t_fp64toa ascii_fp64_data [4 ];
202+
197203static float TimevalDiff (const struct timeval * a , const struct timeval * b )
198204{
199205 return (a -> tv_sec - b -> tv_sec ) + 1e-6f * (a -> tv_usec - b -> tv_usec );
@@ -255,23 +261,23 @@ int parse_u32(char* s, uint32_t* const value)
255261 }
256262}
257263
258- /* Parse frequencies as doubles to take advantage of notation parsing */
259- int parse_frequency_i64 (char * optarg , char * endptr , int64_t * value )
264+ int parse_frequency_u32 (char * optarg , char * endptr , uint32_t * value )
260265{
261- * value = (int64_t ) strtod (optarg , & endptr );
266+ * value = (uint32_t ) strtod (optarg , & endptr );
262267 if (optarg == endptr ) {
263268 return HACKRF_ERROR_INVALID_PARAM ;
264269 }
265270 return HACKRF_SUCCESS ;
266271}
267272
268- int parse_frequency_u32 (char * optarg , char * endptr , uint32_t * value )
273+ int parse_frequency_fp (char * optarg , char * endptr , fp_40_24_t * value )
269274{
270- * value = (uint32_t ) strtod (optarg , & endptr );
271- if (optarg == endptr ) {
272- return HACKRF_ERROR_INVALID_PARAM ;
273- }
274- return HACKRF_SUCCESS ;
275+ return hackrf_str_to_fp64 (24 , optarg , endptr , value );
276+ }
277+
278+ int parse_sample_rate_fp (char * optarg , char * endptr , fp_28_36_t * value )
279+ {
280+ return hackrf_str_to_fp64 (36 , optarg , endptr , value );
275281}
276282
277283static char * stringrev (char * str )
@@ -319,6 +325,51 @@ char* u64toa(uint64_t val, t_u64toa* str)
319325 return res ;
320326}
321327
328+ char * fp64toa (uint8_t Qn , uint64_t value , t_fp64toa * str )
329+ {
330+ uint64_t mask = (1ULL << Qn ) - 1 ;
331+ uint64_t m = value >> Qn ;
332+ uint64_t n = (Qn == 0 ) ? 0 : value & mask ;
333+ uint8_t precision = ceil ((double ) Qn * log10 (2.0 ));
334+
335+ // format integer component
336+ char * p = str -> data ;
337+ p += sprintf (p , "%" PRIu64 , m );
338+
339+ if (precision == 0 || n == 0 ) {
340+ * p = '\0' ;
341+ return str -> data ;
342+ }
343+ * p ++ = '.' ;
344+
345+ // format fractional component
346+ uint8_t i ;
347+ for (i = 0 ; i < precision ; i ++ ) {
348+ n *= 10 ;
349+ char c = '0' + (n >> Qn );
350+ * p ++ = c ;
351+ n &= mask ;
352+ }
353+
354+ // trim trailing zeros
355+ while (p > str -> data && p [-1 ] == '0' ) {
356+ -- p ;
357+ }
358+ * p = '\0' ;
359+
360+ return str -> data ;
361+ }
362+
363+ char * frequency_fp64toa (uint64_t value , t_fp64toa * str )
364+ {
365+ return fp64toa (24 , value , str );
366+ }
367+
368+ char * sample_rate_fp64toa (uint64_t value , t_fp64toa * str )
369+ {
370+ return fp64toa (36 , value , str );
371+ }
372+
322373static volatile bool do_exit = false;
323374static volatile bool interrupted = false;
324375static volatile bool tx_complete = false;
@@ -351,13 +402,13 @@ struct timeval time_start;
351402struct timeval t_start ;
352403
353404bool automatic_tuning = false;
354- int64_t freq_hz ;
405+ fp_40_24_t freq_fp_hz ;
355406
356407bool if_freq = false;
357- int64_t if_freq_hz ;
408+ fp_40_24_t if_freq_fp_hz ;
358409
359410bool lo_freq = false;
360- int64_t lo_freq_hz = DEFAULT_LO_HZ ;
411+ fp_40_24_t lo_freq_fp_hz = FREQ_FP_HZ ( DEFAULT_LO_HZ ) ;
361412
362413bool image_reject = false;
363414uint32_t image_reject_selection ;
@@ -369,7 +420,7 @@ bool antenna = false;
369420uint32_t antenna_enable ;
370421
371422bool sample_rate = false;
372- uint32_t sample_rate_hz ;
423+ fp_28_36_t sample_rate_fp_hz ;
373424
374425bool force_ranges = false;
375426
@@ -778,17 +829,17 @@ int main(int argc, char** argv)
778829 break ;
779830
780831 case 'f' :
781- result = parse_frequency_i64 (optarg , endptr , & freq_hz );
832+ result = parse_frequency_fp (optarg , endptr , & freq_fp_hz );
782833 automatic_tuning = true;
783834 break ;
784835
785836 case 'i' :
786- result = parse_frequency_i64 (optarg , endptr , & if_freq_hz );
837+ result = parse_frequency_fp (optarg , endptr , & if_freq_fp_hz );
787838 if_freq = true;
788839 break ;
789840
790841 case 'o' :
791- result = parse_frequency_i64 (optarg , endptr , & lo_freq_hz );
842+ result = parse_frequency_fp (optarg , endptr , & lo_freq_fp_hz );
792843 lo_freq = true;
793844 break ;
794845
@@ -820,7 +871,7 @@ int main(int argc, char** argv)
820871 break ;
821872
822873 case 's' :
823- result = parse_frequency_u32 (optarg , endptr , & sample_rate_hz );
874+ result = parse_sample_rate_fp (optarg , endptr , & sample_rate_fp_hz );
824875 sample_rate = true;
825876 break ;
826877
@@ -919,7 +970,8 @@ int main(int argc, char** argv)
919970 usage ();
920971 return EXIT_FAILURE ;
921972 }
922- if (((if_freq_hz > IF_MAX_HZ ) || (if_freq_hz < IF_MIN_HZ )) &&
973+ if (((FP_FREQ_HZ (if_freq_fp_hz ) > IF_MAX_HZ ) ||
974+ (FP_FREQ_HZ (if_freq_fp_hz ) < IF_MIN_HZ )) &&
923975 !force_ranges ) {
924976 fprintf (stderr ,
925977 "argument error: if_freq_hz should be between %s and %s.\n" ,
@@ -928,15 +980,17 @@ int main(int argc, char** argv)
928980 usage ();
929981 return EXIT_FAILURE ;
930982 }
931- if ((if_freq_hz > IF_ABS_MAX_HZ ) || (if_freq_hz < IF_ABS_MIN_HZ )) {
983+ if ((FP_FREQ_HZ (if_freq_fp_hz ) > IF_ABS_MAX_HZ ) ||
984+ (FP_FREQ_HZ (if_freq_fp_hz ) < IF_ABS_MIN_HZ )) {
932985 fprintf (stderr ,
933986 "argument error: if_freq_hz must be between %s and %s.\n" ,
934987 u64toa (IF_ABS_MIN_HZ , & ascii_u64_data [0 ]),
935988 u64toa (IF_ABS_MAX_HZ , & ascii_u64_data [1 ]));
936989 usage ();
937990 return EXIT_FAILURE ;
938991 }
939- if ((lo_freq_hz > LO_MAX_HZ ) || (lo_freq_hz < LO_MIN_HZ )) {
992+ if ((FP_FREQ_HZ (lo_freq_fp_hz ) > LO_MAX_HZ ) ||
993+ (FP_FREQ_HZ (lo_freq_fp_hz ) < LO_MIN_HZ )) {
940994 fprintf (stderr ,
941995 "argument error: lo_freq_hz shall be between %s and %s.\n" ,
942996 u64toa (LO_MIN_HZ , & ascii_u64_data [0 ]),
@@ -957,24 +1011,27 @@ int main(int argc, char** argv)
9571011 }
9581012 switch (image_reject_selection ) {
9591013 case RF_PATH_FILTER_BYPASS :
960- freq_hz = if_freq_hz ;
1014+ freq_fp_hz = if_freq_fp_hz ;
9611015 break ;
9621016 case RF_PATH_FILTER_LOW_PASS :
963- freq_hz = (int64_t ) labs ((long int ) (if_freq_hz - lo_freq_hz ));
1017+ freq_fp_hz = (if_freq_fp_hz > lo_freq_fp_hz ) ?
1018+ if_freq_fp_hz - lo_freq_fp_hz :
1019+ lo_freq_fp_hz - if_freq_fp_hz ;
9641020 break ;
9651021 case RF_PATH_FILTER_HIGH_PASS :
966- freq_hz = if_freq_hz + lo_freq_hz ;
1022+ freq_fp_hz = if_freq_fp_hz + lo_freq_fp_hz ;
9671023 break ;
9681024 default :
969- freq_hz = DEFAULT_FREQ_HZ ;
1025+ freq_fp_hz = FREQ_FP_HZ ( DEFAULT_FREQ_HZ ) ;
9701026 break ;
9711027 }
9721028 fprintf (stderr ,
9731029 "explicit tuning specified for %s Hz.\n" ,
974- u64toa ( freq_hz , & ascii_u64_data [0 ]));
1030+ frequency_fp64toa ( freq_fp_hz , & ascii_fp64_data [0 ]));
9751031
9761032 } else if (automatic_tuning ) {
977- if (((freq_hz > FREQ_MAX_HZ ) || (freq_hz < FREQ_MIN_HZ )) &&
1033+ if (((FP_FREQ_HZ (freq_fp_hz ) > FREQ_MAX_HZ ) ||
1034+ (FP_FREQ_HZ (freq_fp_hz ) < FREQ_MIN_HZ )) &&
9781035 !force_ranges ) {
9791036 fprintf (stderr ,
9801037 "argument error: freq_hz should be between %s and %s.\n" ,
@@ -983,7 +1040,7 @@ int main(int argc, char** argv)
9831040 usage ();
9841041 return EXIT_FAILURE ;
9851042 }
986- if (freq_hz > FREQ_ABS_MAX_HZ ) {
1043+ if (FP_FREQ_HZ ( freq_fp_hz ) > FREQ_ABS_MAX_HZ ) {
9871044 fprintf (stderr ,
9881045 "argument error: freq_hz must be between %s and %s.\n" ,
9891046 u64toa (FREQ_ABS_MIN_HZ , & ascii_u64_data [0 ]),
@@ -993,7 +1050,7 @@ int main(int argc, char** argv)
9931050 }
9941051 } else {
9951052 /* Use default freq */
996- freq_hz = DEFAULT_FREQ_HZ ;
1053+ freq_fp_hz = FREQ_FP_HZ ( DEFAULT_FREQ_HZ ) ;
9971054 automatic_tuning = true;
9981055 }
9991056
@@ -1015,15 +1072,18 @@ int main(int argc, char** argv)
10151072 }
10161073
10171074 if (sample_rate ) {
1018- if (sample_rate_hz > SAMPLE_RATE_MAX_HZ && !force_ranges ) {
1075+ fprintf (stderr ,
1076+ "Setting sample rate to: %s Hz\n" ,
1077+ sample_rate_fp64toa (sample_rate_fp_hz , & ascii_fp64_data [0 ]));
1078+ if (FP_SR_HZ (sample_rate_fp_hz ) > SAMPLE_RATE_MAX_HZ && !force_ranges ) {
10191079 fprintf (stderr ,
10201080 "argument error: sample_rate_hz should be less than or equal to %u Hz/%.03f MHz\n" ,
10211081 SAMPLE_RATE_MAX_HZ ,
10221082 (float ) (SAMPLE_RATE_MAX_HZ / FREQ_ONE_MHZ ));
10231083 usage ();
10241084 return EXIT_FAILURE ;
10251085 }
1026- if (sample_rate_hz < SAMPLE_RATE_MIN_HZ && !force_ranges ) {
1086+ if (FP_SR_HZ ( sample_rate_fp_hz ) < SAMPLE_RATE_MIN_HZ && !force_ranges ) {
10271087 fprintf (stderr ,
10281088 "argument error: sample_rate_hz should be greater than or equal to %u Hz/%.03f MHz\n" ,
10291089 SAMPLE_RATE_MIN_HZ ,
@@ -1032,7 +1092,7 @@ int main(int argc, char** argv)
10321092 return EXIT_FAILURE ;
10331093 }
10341094 } else {
1035- sample_rate_hz = DEFAULT_SAMPLE_RATE_HZ ;
1095+ sample_rate_fp_hz = SR_FP_HZ ( DEFAULT_SAMPLE_RATE_HZ ) ;
10361096 }
10371097
10381098 if (baseband_filter_bw ) {
@@ -1100,7 +1160,7 @@ int main(int argc, char** argv)
11001160 PATH_FILE_MAX_LEN ,
11011161 "HackRF_%sZ_%ukHz_IQ.wav" ,
11021162 date_time ,
1103- (uint32_t ) (freq_hz / (1000ull )));
1163+ (uint32_t ) (FP_FREQ_HZ ( freq_fp_hz ) / (1000ull )));
11041164 path = path_file ;
11051165 fprintf (stderr , "Receive wav file: %s\n" , path );
11061166 }
@@ -1116,9 +1176,12 @@ int main(int argc, char** argv)
11161176
11171177 // Change the freq and sample rate to correct the crystal clock error.
11181178 if (crystal_correct ) {
1119- sample_rate_hz =
1120- (uint32_t ) ((double ) sample_rate_hz * (1000000 - crystal_correct_ppm ) / 1000000 + 0.5 );
1121- freq_hz = freq_hz * (1000000 - crystal_correct_ppm ) / 1000000 ;
1179+ sample_rate_fp_hz =
1180+ (fp_28_36_t ) ((__uint128_t ) sample_rate_fp_hz * (1000000 - crystal_correct_ppm )) /
1181+ 1000000 ;
1182+ freq_fp_hz =
1183+ (fp_40_24_t ) ((__uint128_t ) freq_fp_hz * (1000000 - crystal_correct_ppm )) /
1184+ 1000000 ;
11221185 }
11231186
11241187 result = hackrf_init ();
@@ -1192,13 +1255,13 @@ int main(int argc, char** argv)
11921255#endif
11931256
11941257 fprintf (stderr ,
1195- "call hackrf_set_sample_rate(%u Hz/%.03f MHz)\n" ,
1196- sample_rate_hz ,
1197- ((float ) sample_rate_hz / (float ) FREQ_ONE_MHZ ));
1198- result = hackrf_set_sample_rate (device , sample_rate_hz );
1258+ "call hackrf_radio_set_sample_rate(%s Hz/%.03f MHz)\n" ,
1259+ sample_rate_fp64toa ( sample_rate_fp_hz , & ascii_fp64_data [ 0 ]) ,
1260+ ((float ) FP_SR_HZ ( sample_rate_fp_hz ) / (float ) FREQ_ONE_MHZ ));
1261+ result = hackrf_radio_set_sample_rate (device , sample_rate_fp_hz );
11991262 if (result != HACKRF_SUCCESS ) {
12001263 fprintf (stderr ,
1201- "hackrf_set_sample_rate () failed: %s (%d)\n" ,
1264+ "hackrf_radio_set_sample_rate () failed: %s (%d)\n" ,
12021265 hackrf_error_name (result ),
12031266 result );
12041267 usage ();
@@ -1246,13 +1309,13 @@ int main(int argc, char** argv)
12461309
12471310 if (automatic_tuning ) {
12481311 fprintf (stderr ,
1249- "call hackrf_set_freq (%s Hz/%.03f MHz)\n" ,
1250- u64toa ( freq_hz , & ascii_u64_data [0 ]),
1251- ((double ) freq_hz / (double ) FREQ_ONE_MHZ ));
1252- result = hackrf_set_freq (device , freq_hz );
1312+ "call hackrf_radio_set_frequency (%s Hz/%.03f MHz)\n" ,
1313+ frequency_fp64toa ( freq_fp_hz , & ascii_fp64_data [0 ]),
1314+ ((float ) FP_FREQ_HZ ( freq_fp_hz ) / (float ) FREQ_ONE_MHZ ));
1315+ result = hackrf_radio_set_frequency (device , freq_fp_hz );
12531316 if (result != HACKRF_SUCCESS ) {
12541317 fprintf (stderr ,
1255- "hackrf_set_freq () failed: %s (%d)\n" ,
1318+ "hackrf_radio_set_frequency () failed: %s (%d)\n" ,
12561319 hackrf_error_name (result ),
12571320 result );
12581321 usage ();
@@ -1261,13 +1324,13 @@ int main(int argc, char** argv)
12611324 } else {
12621325 fprintf (stderr ,
12631326 "call hackrf_set_freq_explicit() with %s Hz IF, %s Hz LO, %s\n" ,
1264- u64toa ( if_freq_hz , & ascii_u64_data [0 ]),
1265- u64toa ( lo_freq_hz , & ascii_u64_data [ 1 ]),
1327+ frequency_fp64toa ( if_freq_fp_hz , & ascii_fp64_data [0 ]),
1328+ frequency_fp64toa ( lo_freq_fp_hz , & ascii_fp64_data [ 0 ]),
12661329 hackrf_filter_path_name (image_reject_selection ));
1267- result = hackrf_set_freq_explicit (
1330+ result = hackrf_radio_set_frequency_explicit (
12681331 device ,
1269- if_freq_hz ,
1270- lo_freq_hz ,
1332+ if_freq_fp_hz ,
1333+ lo_freq_fp_hz ,
12711334 image_reject_selection );
12721335 if (result != HACKRF_SUCCESS ) {
12731336 fprintf (stderr ,
@@ -1532,7 +1595,8 @@ int main(int argc, char** argv)
15321595 file_pos = ftell (file );
15331596 /* Update Wav Header */
15341597 wave_file_hdr .hdr .size = file_pos - 8 ;
1535- wave_file_hdr .fmt_chunk .dwSamplesPerSec = sample_rate_hz ;
1598+ wave_file_hdr .fmt_chunk .dwSamplesPerSec =
1599+ FP_SR_HZ (sample_rate_fp_hz );
15361600 wave_file_hdr .fmt_chunk .dwAvgBytesPerSec =
15371601 wave_file_hdr .fmt_chunk .dwSamplesPerSec * 2 ;
15381602 wave_file_hdr .data_chunk .chunkSize =
0 commit comments