Adding "sample_rate_hz" option, Ctrl C exit shall be fixed with also minor fix in hackrf lib (manage do_exit in thread).

Need more test on linux.
This commit is contained in:
TitanMKD
2013-03-23 18:14:49 +01:00
parent d509489fff
commit cb2b82e9c4
2 changed files with 113 additions and 75 deletions

View File

@ -37,14 +37,22 @@
#include <windows.h> #include <windows.h>
#else #else
#include <unistd.h> #include <unistd.h>
#include <io.h>
#include <fcntl.h>
#endif #endif
#include <sys/time.h> #include <sys/time.h>
#include <signal.h> #include <signal.h>
#define FREQ_ONE_MHZ (1000000)
#define FREQ_MIN_HZ (30000000ull) /* 30MHz */ #define FREQ_MIN_HZ (30000000ull) /* 30MHz */
#define FREQ_MAX_HZ (6000000000ull) /* 6000MHz */ #define FREQ_MAX_HZ (6000000000ull) /* 6000MHz */
#define DEFAULT_SAMPLE_RATE_HZ (10000000) /* 10MHz default sample rate */
#define DEFAULT_BASEBAND_FILTER_BANDWIDTH (5000000) /* 5MHz default */
#if defined _WIN32 #if defined _WIN32
#define sleep(a) Sleep( (a*1000) ) #define sleep(a) Sleep( (a*1000) )
#endif #endif
@ -86,7 +94,7 @@ int parse_u64(char* s, uint64_t* const value) {
} }
} }
int parse_int(char* s, uint32_t* const value) { int parse_u32(char* s, uint32_t* const value) {
uint_fast8_t base = 10; uint_fast8_t base = 10;
if( strlen(s) > 2 ) { if( strlen(s) > 2 ) {
if( s[0] == '0' ) { if( s[0] == '0' ) {
@ -110,6 +118,8 @@ int parse_int(char* s, uint32_t* const value) {
} }
} }
volatile bool do_exit = false;
FILE* fd = NULL; FILE* fd = NULL;
volatile uint32_t byte_count = 0; volatile uint32_t byte_count = 0;
@ -124,6 +134,9 @@ uint64_t freq_hz;
bool amp = false; bool amp = false;
uint32_t amp_enable; uint32_t amp_enable;
bool sample_rate = false;
uint32_t sample_rate_hz;
int rx_callback(hackrf_transfer* transfer) { int rx_callback(hackrf_transfer* transfer) {
if( fd != NULL ) if( fd != NULL )
{ {
@ -162,74 +175,28 @@ static void usage() {
printf("Usage:\n"); printf("Usage:\n");
printf("\t-r <filename> # Receive data into file.\n"); printf("\t-r <filename> # Receive data into file.\n");
printf("\t-t <filename> # Transmit data from file.\n"); printf("\t-t <filename> # Transmit data from file.\n");
printf("\t[-f set_freq_hz] # Set Freq in Hz (between [%lld, %lld[).\n", FREQ_MIN_HZ, FREQ_MAX_HZ); printf("\t[-f set_freq_hz] # Set Freq in Hz between [%lldMHz, %lldMHz[.\n", FREQ_MIN_HZ/FREQ_ONE_MHZ, FREQ_MAX_HZ/FREQ_ONE_MHZ);
printf("\t[-a set_amp] # Set Amp 1=Enable, 0=Disable.\n"); printf("\t[-a set_amp] # Set Amp 1=Enable, 0=Disable.\n");
printf("\t[-s sample_rate_hz] # Set sample rate in Hz (5/10/12.5/16/20MHz, default %dMHz).\n", DEFAULT_SAMPLE_RATE_HZ/FREQ_ONE_MHZ);
} }
static hackrf_device* device = NULL; static hackrf_device* device = NULL;
void sigint_callback_handler(int signum) void sigint_callback_handler(int signum)
{ {
int result; fprintf(stdout, "Caught signal %d\n", signum);
printf("Caught signal %d\n", signum); do_exit = true;
struct timeval t_end;
gettimeofday(&t_end, NULL);
const float time_diff = TimevalDiff(&t_end, &t_start);
printf("Total time: %5.5f s\n", time_diff);
if(device != NULL)
{
if( receive )
{
printf("hackrf_stop_rx \n");
result = hackrf_stop_rx(device);
if( result != HACKRF_SUCCESS ) {
printf("hackrf_stop_rx() failed: %s (%d)\n", hackrf_error_name(result), result);
}else {
printf("hackrf_stop_rx() done\n");
}
}
if( transmit )
{
result = hackrf_stop_tx(device);
if( result != HACKRF_SUCCESS ) {
printf("hackrf_stop_tx() failed: %s (%d)\n", hackrf_error_name(result), result);
}else {
printf("hackrf_stop_tx() done\n");
}
}
result = hackrf_close(device);
if( result != HACKRF_SUCCESS )
{
printf("hackrf_close() failed: %s (%d)\n", hackrf_error_name(result), result);
}
printf("hackrf_close() done\n");
hackrf_exit();
}
if(fd != NULL)
{
fclose(fd);
fd = NULL;
printf("fclose() file handle done\n");
}
printf("Exit\n");
/* Terminate program */
exit(signum);
} }
int main(int argc, char** argv) { int main(int argc, char** argv) {
int opt; int opt;
const char* path = NULL; const char* path = NULL;
int result; int result;
#ifndef _WIN32
struct sigaction sigact;
#endif
while( (opt = getopt(argc, argv, "r:t:f:a:")) != EOF ) { while( (opt = getopt(argc, argv, "r:t:f:a:s:")) != EOF ) {
result = HACKRF_SUCCESS; result = HACKRF_SUCCESS;
switch( opt ) { switch( opt ) {
case 'r': case 'r':
@ -249,7 +216,12 @@ int main(int argc, char** argv) {
case 'a': case 'a':
amp = true; amp = true;
result = parse_int(optarg, &amp_enable); result = parse_u32(optarg, &amp_enable);
break;
case 's':
sample_rate = true;
result = parse_u32(optarg, &sample_rate_hz);
break; break;
default: default:
@ -280,7 +252,7 @@ int main(int argc, char** argv) {
usage(); usage();
return EXIT_FAILURE; return EXIT_FAILURE;
} }
} }
if( transmit == receive ) if( transmit == receive )
{ {
@ -333,15 +305,35 @@ int main(int argc, char** argv) {
return EXIT_FAILURE; return EXIT_FAILURE;
} }
signal(SIGINT, sigint_callback_handler); signal(SIGINT, &sigint_callback_handler);
signal(SIGILL, &sigint_callback_handler);
signal(SIGFPE, &sigint_callback_handler);
signal(SIGSEGV, &sigint_callback_handler);
signal(SIGTERM, &sigint_callback_handler);
signal(SIGBREAK, &sigint_callback_handler);
signal(SIGABRT, &sigint_callback_handler);
result = hackrf_sample_rate_set(device, 10000000); if( sample_rate )
if( result != HACKRF_SUCCESS ) { {
printf("hackrf_sample_rate_set() failed: %s (%d)\n", hackrf_error_name(result), result); printf("call hackrf_sample_rate_set(%ld Hz/%ld MHz)\n", sample_rate_hz, sample_rate_hz/FREQ_ONE_MHZ);
return EXIT_FAILURE; result = hackrf_sample_rate_set(device, sample_rate_hz);
if( result != HACKRF_SUCCESS ) {
printf("hackrf_sample_rate_set() failed: %s (%d)\n", hackrf_error_name(result), result);
return EXIT_FAILURE;
}
}else
{
printf("call hackrf_sample_rate_set(%ld Hz/%ld MHz)\n", DEFAULT_SAMPLE_RATE_HZ, DEFAULT_SAMPLE_RATE_HZ/FREQ_ONE_MHZ);
result = hackrf_sample_rate_set(device, DEFAULT_SAMPLE_RATE_HZ);
if( result != HACKRF_SUCCESS ) {
printf("hackrf_sample_rate_set() failed: %s (%d)\n", hackrf_error_name(result), result);
return EXIT_FAILURE;
}
} }
result = hackrf_baseband_filter_bandwidth_set(device, 5000000); printf("call hackrf_baseband_filter_bandwidth_set(%ld Hz/%ld MHz)\n",
DEFAULT_BASEBAND_FILTER_BANDWIDTH, DEFAULT_BASEBAND_FILTER_BANDWIDTH/FREQ_ONE_MHZ);
result = hackrf_baseband_filter_bandwidth_set(device, DEFAULT_BASEBAND_FILTER_BANDWIDTH);
if( result != HACKRF_SUCCESS ) { if( result != HACKRF_SUCCESS ) {
printf("hackrf_baseband_filter_bandwidth_set() failed: %s (%d)\n", hackrf_error_name(result), result); printf("hackrf_baseband_filter_bandwidth_set() failed: %s (%d)\n", hackrf_error_name(result), result);
return EXIT_FAILURE; return EXIT_FAILURE;
@ -358,7 +350,7 @@ int main(int argc, char** argv) {
} }
if( freq ) { if( freq ) {
printf("call hackrf_set_freq(%lld Hz)\n", freq_hz); printf("call hackrf_set_freq(%lld Hz/%ld MHz)\n", freq_hz, (freq_hz/FREQ_ONE_MHZ) );
result = hackrf_set_freq(device, freq_hz); result = hackrf_set_freq(device, freq_hz);
if( result != HACKRF_SUCCESS ) { if( result != HACKRF_SUCCESS ) {
printf("hackrf_set_freq() failed: %s (%d)\n", hackrf_error_name(result), result); printf("hackrf_set_freq() failed: %s (%d)\n", hackrf_error_name(result), result);
@ -378,7 +370,9 @@ int main(int argc, char** argv) {
gettimeofday(&t_start, NULL); gettimeofday(&t_start, NULL);
gettimeofday(&time_start, NULL); gettimeofday(&time_start, NULL);
while( hackrf_is_streaming(device) ) printf("Stop with Ctrl-C\n");
while( (hackrf_is_streaming(device)) &&
(do_exit == false) )
{ {
sleep(1); sleep(1);
@ -396,18 +390,57 @@ int main(int argc, char** argv) {
time_start = time_now; time_start = time_now;
} }
result = hackrf_close(device); if (do_exit)
if( result != HACKRF_SUCCESS ) { printf("\nUser cancel, exiting...\n");
printf("hackrf_close() failed: %s (%d)\n", hackrf_error_name(result), result); else
return -1; printf("\nhackrf library error, exiting...\n");
struct timeval t_end;
gettimeofday(&t_end, NULL);
const float time_diff = TimevalDiff(&t_end, &t_start);
printf("Total time: %5.5f s\n", time_diff);
if(device != NULL)
{
if( receive )
{
printf("hackrf_stop_rx \n");
result = hackrf_stop_rx(device);
if( result != HACKRF_SUCCESS ) {
printf("hackrf_stop_rx() failed: %s (%d)\n", hackrf_error_name(result), result);
}else {
printf("hackrf_stop_rx() done\n");
}
}
if( transmit )
{
result = hackrf_stop_tx(device);
if( result != HACKRF_SUCCESS ) {
printf("hackrf_stop_tx() failed: %s (%d)\n", hackrf_error_name(result), result);
}else {
printf("hackrf_stop_tx() done\n");
}
}
result = hackrf_close(device);
if( result != HACKRF_SUCCESS )
{
printf("hackrf_close() failed: %s (%d)\n", hackrf_error_name(result), result);
}else {
printf("hackrf_close() done\n");
}
hackrf_exit();
printf("hackrf_exit() done\n");
} }
hackrf_exit();
if(fd != NULL) if(fd != NULL)
{ {
fclose(fd); fclose(fd);
fd = NULL;
printf("fclose(fd) done\n");
} }
printf("exit\n");
return EXIT_SUCCESS; return EXIT_SUCCESS;
} }

View File

@ -67,6 +67,8 @@ struct hackrf_device {
bool streaming; bool streaming;
}; };
volatile bool do_exit = false;
static const uint16_t hackrf_usb_vid = 0x1d50; static const uint16_t hackrf_usb_vid = 0x1d50;
static const uint16_t hackrf_usb_pid = 0x604b; static const uint16_t hackrf_usb_pid = 0x604b;
@ -221,6 +223,7 @@ int hackrf_open(hackrf_device** device) {
lib_device->transfer_count = 4; lib_device->transfer_count = 4;
lib_device->buffer_size = 262144; /* 1048576; */ lib_device->buffer_size = 262144; /* 1048576; */
lib_device->streaming = false; lib_device->streaming = false;
do_exit = false;
result = allocate_transfers(lib_device); result = allocate_transfers(lib_device);
if( result != 0 ) { if( result != 0 ) {
@ -659,7 +662,8 @@ static void* transfer_threadproc(void* arg) {
struct timeval timeout = { 0, 500000 }; struct timeval timeout = { 0, 500000 };
while( device->streaming ) { while( (device->streaming) && (do_exit == false) )
{
int error = libusb_handle_events_timeout(g_libusb_context, &timeout); int error = libusb_handle_events_timeout(g_libusb_context, &timeout);
if( error != 0 ) { if( error != 0 ) {
device->streaming = false; device->streaming = false;
@ -691,6 +695,7 @@ static void hackrf_libusb_transfer_callback(struct libusb_transfer* usb_transfer
static int kill_transfer_thread(hackrf_device* device) { static int kill_transfer_thread(hackrf_device* device) {
device->streaming = false; device->streaming = false;
do_exit = true;
if( device->transfer_thread_started != false ) { if( device->transfer_thread_started != false ) {
void* value = NULL; void* value = NULL;