@@ -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,16 @@ struct timeval time_start;
351402struct timeval t_start ;
352403
353404bool automatic_tuning = false;
354- int64_t freq_hz ;
405+ uint64_t freq_hz ;
406+ fp_40_24_t freq_fp_hz ;
355407
356408bool if_freq = false;
357- int64_t if_freq_hz ;
409+ uint64_t if_freq_hz ;
410+ fp_40_24_t if_freq_fp_hz ;
358411
359412bool lo_freq = false;
360- int64_t lo_freq_hz = DEFAULT_LO_HZ ;
413+ uint64_t lo_freq_hz = DEFAULT_LO_HZ ;
414+ fp_40_24_t lo_freq_fp_hz = FREQ_FP_HZ (DEFAULT_LO_HZ );
361415
362416bool image_reject = false;
363417uint32_t image_reject_selection ;
@@ -369,7 +423,8 @@ bool antenna = false;
369423uint32_t antenna_enable ;
370424
371425bool sample_rate = false;
372- uint32_t sample_rate_hz ;
426+ fp_28_36_t sample_rate_fp_hz ;
427+ uint64_t sample_rate_hz ;
373428
374429bool force_ranges = false;
375430
@@ -778,17 +833,20 @@ int main(int argc, char** argv)
778833 break ;
779834
780835 case 'f' :
781- result = parse_frequency_i64 (optarg , endptr , & freq_hz );
836+ result = parse_frequency_fp (optarg , endptr , & freq_fp_hz );
837+ freq_hz = FP_FREQ_HZ (freq_fp_hz );
782838 automatic_tuning = true;
783839 break ;
784840
785841 case 'i' :
786- result = parse_frequency_i64 (optarg , endptr , & if_freq_hz );
842+ result = parse_frequency_fp (optarg , endptr , & if_freq_fp_hz );
843+ if_freq_hz = FP_FREQ_HZ (if_freq_fp_hz );
787844 if_freq = true;
788845 break ;
789846
790847 case 'o' :
791- result = parse_frequency_i64 (optarg , endptr , & lo_freq_hz );
848+ result = parse_frequency_fp (optarg , endptr , & lo_freq_fp_hz );
849+ lo_freq_hz = FP_FREQ_HZ (lo_freq_fp_hz );
792850 lo_freq = true;
793851 break ;
794852
@@ -820,7 +878,8 @@ int main(int argc, char** argv)
820878 break ;
821879
822880 case 's' :
823- result = parse_frequency_u32 (optarg , endptr , & sample_rate_hz );
881+ result = parse_sample_rate_fp (optarg , endptr , & sample_rate_fp_hz );
882+ sample_rate_hz = FP_SR_HZ (sample_rate_fp_hz );
824883 sample_rate = true;
825884 break ;
826885
@@ -919,7 +978,8 @@ int main(int argc, char** argv)
919978 usage ();
920979 return EXIT_FAILURE ;
921980 }
922- if (((if_freq_hz > IF_MAX_HZ ) || (if_freq_hz < IF_MIN_HZ )) &&
981+ if (((FP_FREQ_HZ (if_freq_fp_hz ) > IF_MAX_HZ ) ||
982+ (FP_FREQ_HZ (if_freq_fp_hz ) < IF_MIN_HZ )) &&
923983 !force_ranges ) {
924984 fprintf (stderr ,
925985 "argument error: if_freq_hz should be between %s and %s.\n" ,
@@ -928,15 +988,17 @@ int main(int argc, char** argv)
928988 usage ();
929989 return EXIT_FAILURE ;
930990 }
931- if ((if_freq_hz > IF_ABS_MAX_HZ ) || (if_freq_hz < IF_ABS_MIN_HZ )) {
991+ if ((FP_FREQ_HZ (if_freq_fp_hz ) > IF_ABS_MAX_HZ ) ||
992+ (FP_FREQ_HZ (if_freq_fp_hz ) < IF_ABS_MIN_HZ )) {
932993 fprintf (stderr ,
933994 "argument error: if_freq_hz must be between %s and %s.\n" ,
934995 u64toa (IF_ABS_MIN_HZ , & ascii_u64_data [0 ]),
935996 u64toa (IF_ABS_MAX_HZ , & ascii_u64_data [1 ]));
936997 usage ();
937998 return EXIT_FAILURE ;
938999 }
939- if ((lo_freq_hz > LO_MAX_HZ ) || (lo_freq_hz < LO_MIN_HZ )) {
1000+ if ((FP_FREQ_HZ (lo_freq_fp_hz ) > LO_MAX_HZ ) ||
1001+ (FP_FREQ_HZ (lo_freq_fp_hz ) < LO_MIN_HZ )) {
9401002 fprintf (stderr ,
9411003 "argument error: lo_freq_hz shall be between %s and %s.\n" ,
9421004 u64toa (LO_MIN_HZ , & ascii_u64_data [0 ]),
@@ -958,23 +1020,31 @@ int main(int argc, char** argv)
9581020 switch (image_reject_selection ) {
9591021 case RF_PATH_FILTER_BYPASS :
9601022 freq_hz = if_freq_hz ;
1023+ freq_fp_hz = if_freq_fp_hz ;
9611024 break ;
9621025 case RF_PATH_FILTER_LOW_PASS :
9631026 freq_hz = (int64_t ) labs ((long int ) (if_freq_hz - lo_freq_hz ));
1027+ // TODO check
1028+ freq_fp_hz = (if_freq_fp_hz > lo_freq_fp_hz ) ?
1029+ if_freq_fp_hz - lo_freq_fp_hz :
1030+ lo_freq_fp_hz - if_freq_fp_hz ;
9641031 break ;
9651032 case RF_PATH_FILTER_HIGH_PASS :
9661033 freq_hz = if_freq_hz + lo_freq_hz ;
1034+ freq_fp_hz = if_freq_fp_hz + lo_freq_fp_hz ;
9671035 break ;
9681036 default :
9691037 freq_hz = DEFAULT_FREQ_HZ ;
1038+ freq_fp_hz = FREQ_FP_HZ (DEFAULT_FREQ_HZ );
9701039 break ;
9711040 }
9721041 fprintf (stderr ,
9731042 "explicit tuning specified for %s Hz.\n" ,
974- u64toa ( freq_hz , & ascii_u64_data [0 ]));
1043+ frequency_fp64toa ( freq_fp_hz , & ascii_fp64_data [0 ]));
9751044
9761045 } else if (automatic_tuning ) {
977- if (((freq_hz > FREQ_MAX_HZ ) || (freq_hz < FREQ_MIN_HZ )) &&
1046+ if (((FP_FREQ_HZ (freq_fp_hz ) > FREQ_MAX_HZ ) ||
1047+ (FP_FREQ_HZ (freq_fp_hz ) < FREQ_MIN_HZ )) &&
9781048 !force_ranges ) {
9791049 fprintf (stderr ,
9801050 "argument error: freq_hz should be between %s and %s.\n" ,
@@ -983,7 +1053,7 @@ int main(int argc, char** argv)
9831053 usage ();
9841054 return EXIT_FAILURE ;
9851055 }
986- if (freq_hz > FREQ_ABS_MAX_HZ ) {
1056+ if (FP_FREQ_HZ ( freq_fp_hz ) > FREQ_ABS_MAX_HZ ) {
9871057 fprintf (stderr ,
9881058 "argument error: freq_hz must be between %s and %s.\n" ,
9891059 u64toa (FREQ_ABS_MIN_HZ , & ascii_u64_data [0 ]),
@@ -994,6 +1064,7 @@ int main(int argc, char** argv)
9941064 } else {
9951065 /* Use default freq */
9961066 freq_hz = DEFAULT_FREQ_HZ ;
1067+ freq_fp_hz = FREQ_FP_HZ (DEFAULT_FREQ_HZ );
9971068 automatic_tuning = true;
9981069 }
9991070
@@ -1015,15 +1086,18 @@ int main(int argc, char** argv)
10151086 }
10161087
10171088 if (sample_rate ) {
1018- if (sample_rate_hz > SAMPLE_RATE_MAX_HZ && !force_ranges ) {
1089+ fprintf (stderr ,
1090+ "Setting sample rate to: %s Hz\n" ,
1091+ sample_rate_fp64toa (sample_rate_fp_hz , & ascii_fp64_data [0 ]));
1092+ if (FP_SR_HZ (sample_rate_fp_hz ) > SAMPLE_RATE_MAX_HZ && !force_ranges ) {
10191093 fprintf (stderr ,
10201094 "argument error: sample_rate_hz should be less than or equal to %u Hz/%.03f MHz\n" ,
10211095 SAMPLE_RATE_MAX_HZ ,
10221096 (float ) (SAMPLE_RATE_MAX_HZ / FREQ_ONE_MHZ ));
10231097 usage ();
10241098 return EXIT_FAILURE ;
10251099 }
1026- if (sample_rate_hz < SAMPLE_RATE_MIN_HZ && !force_ranges ) {
1100+ if (FP_SR_HZ ( sample_rate_fp_hz ) < SAMPLE_RATE_MIN_HZ && !force_ranges ) {
10271101 fprintf (stderr ,
10281102 "argument error: sample_rate_hz should be greater than or equal to %u Hz/%.03f MHz\n" ,
10291103 SAMPLE_RATE_MIN_HZ ,
@@ -1033,6 +1107,7 @@ int main(int argc, char** argv)
10331107 }
10341108 } else {
10351109 sample_rate_hz = DEFAULT_SAMPLE_RATE_HZ ;
1110+ sample_rate_fp_hz = SR_FP_HZ (DEFAULT_SAMPLE_RATE_HZ );
10361111 }
10371112
10381113 if (baseband_filter_bw ) {
@@ -1100,7 +1175,7 @@ int main(int argc, char** argv)
11001175 PATH_FILE_MAX_LEN ,
11011176 "HackRF_%sZ_%ukHz_IQ.wav" ,
11021177 date_time ,
1103- (uint32_t ) (freq_hz / (1000ull )));
1178+ (uint32_t ) (FP_FREQ_HZ ( freq_fp_hz ) / (1000ull )));
11041179 path = path_file ;
11051180 fprintf (stderr , "Receive wav file: %s\n" , path );
11061181 }
@@ -1116,6 +1191,7 @@ int main(int argc, char** argv)
11161191
11171192 // Change the freq and sample rate to correct the crystal clock error.
11181193 if (crystal_correct ) {
1194+ // TODO this needs to be implemented for FP
11191195 sample_rate_hz =
11201196 (uint32_t ) ((double ) sample_rate_hz * (1000000 - crystal_correct_ppm ) / 1000000 + 0.5 );
11211197 freq_hz = freq_hz * (1000000 - crystal_correct_ppm ) / 1000000 ;
@@ -1192,13 +1268,13 @@ int main(int argc, char** argv)
11921268#endif
11931269
11941270 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 );
1271+ "call hackrf_radio_set_sample_rate(%s Hz/%.03f MHz)\n" ,
1272+ sample_rate_fp64toa ( sample_rate_fp_hz , & ascii_fp64_data [ 0 ]) ,
1273+ ((float ) FP_SR_HZ ( sample_rate_fp_hz ) / (float ) FREQ_ONE_MHZ ));
1274+ result = hackrf_radio_set_sample_rate (device , sample_rate_fp_hz );
11991275 if (result != HACKRF_SUCCESS ) {
12001276 fprintf (stderr ,
1201- "hackrf_set_sample_rate () failed: %s (%d)\n" ,
1277+ "hackrf_radio_set_sample_rate () failed: %s (%d)\n" ,
12021278 hackrf_error_name (result ),
12031279 result );
12041280 usage ();
@@ -1246,13 +1322,13 @@ int main(int argc, char** argv)
12461322
12471323 if (automatic_tuning ) {
12481324 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 );
1325+ "call hackrf_radio_set_frequency (%s Hz/%.03f MHz)\n" ,
1326+ frequency_fp64toa ( freq_fp_hz , & ascii_fp64_data [0 ]),
1327+ ((float ) FP_FREQ_HZ ( freq_fp_hz ) / (float ) FREQ_ONE_MHZ ));
1328+ result = hackrf_radio_set_frequency (device , freq_fp_hz );
12531329 if (result != HACKRF_SUCCESS ) {
12541330 fprintf (stderr ,
1255- "hackrf_set_freq () failed: %s (%d)\n" ,
1331+ "hackrf_radio_set_frequency () failed: %s (%d)\n" ,
12561332 hackrf_error_name (result ),
12571333 result );
12581334 usage ();
@@ -1261,13 +1337,13 @@ int main(int argc, char** argv)
12611337 } else {
12621338 fprintf (stderr ,
12631339 "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 ]),
1340+ frequency_fp64toa ( if_freq_fp_hz , & ascii_fp64_data [0 ]),
1341+ frequency_fp64toa ( lo_freq_fp_hz , & ascii_fp64_data [ 0 ]),
12661342 hackrf_filter_path_name (image_reject_selection ));
1267- result = hackrf_set_freq_explicit (
1343+ result = hackrf_radio_set_frequency_explicit (
12681344 device ,
1269- if_freq_hz ,
1270- lo_freq_hz ,
1345+ if_freq_fp_hz ,
1346+ lo_freq_fp_hz ,
12711347 image_reject_selection );
12721348 if (result != HACKRF_SUCCESS ) {
12731349 fprintf (stderr ,
@@ -1532,7 +1608,8 @@ int main(int argc, char** argv)
15321608 file_pos = ftell (file );
15331609 /* Update Wav Header */
15341610 wave_file_hdr .hdr .size = file_pos - 8 ;
1535- wave_file_hdr .fmt_chunk .dwSamplesPerSec = sample_rate_hz ;
1611+ wave_file_hdr .fmt_chunk .dwSamplesPerSec =
1612+ FP_SR_HZ (sample_rate_fp_hz );
15361613 wave_file_hdr .fmt_chunk .dwAvgBytesPerSec =
15371614 wave_file_hdr .fmt_chunk .dwSamplesPerSec * 2 ;
15381615 wave_file_hdr .data_chunk .chunkSize =
0 commit comments