diff --git a/firmware/common/fault_handler.c b/firmware/common/fault_handler.c index 7dce1f3e..50331335 100644 --- a/firmware/common/fault_handler.c +++ b/firmware/common/fault_handler.c @@ -1,5 +1,6 @@ /* * Copyright 2012 Jared Boone + * Copyright 2013 Benjamin Vernoux * * This file is part of HackRF. * @@ -23,6 +24,18 @@ #include "fault_handler.h" +typedef struct +{ + uint32_t r0; + uint32_t r1; + uint32_t r2; + uint32_t r3; + uint32_t r12; + uint32_t lr; /* Link Register. */ + uint32_t pc; /* Program Counter. */ + uint32_t psr;/* Program Status Register. */ +} hard_fault_stack_t; + __attribute__((naked)) void hard_fault_handler(void) { __asm__("TST LR, #4"); @@ -32,9 +45,13 @@ void hard_fault_handler(void) { __asm__("B hard_fault_handler_c"); } +volatile hard_fault_stack_t* hard_fault_stack_pt; -void hard_fault_handler_c(uint32_t* args) { - (void)args; +void hard_fault_handler_c(uint32_t* args) +{ + /* hard_fault_stack_pt contains registers saved before the hard fault */ + hard_fault_stack_pt = (hard_fault_stack_t*)args; + // args[0-7]: r0, r1, r2, r3, r12, lr, pc, psr // Other interesting registers to examine: // CFSR: Configurable Fault Status Register diff --git a/firmware/common/hackrf_core.c b/firmware/common/hackrf_core.c index d1e7e0b7..0b719ccf 100644 --- a/firmware/common/hackrf_core.c +++ b/firmware/common/hackrf_core.c @@ -312,9 +312,15 @@ void ssp1_init(void) void ssp1_set_mode_max2837(void) { /* FIXME speed up once everything is working reliably */ + /* + // Freq About 0.0498MHz / 49.8KHz => Freq = PCLK / (CPSDVSR * [SCR+1]) with PCLK=PLL1=204MHz const uint8_t serial_clock_rate = 32; const uint8_t clock_prescale_rate = 128; - + */ + // Freq About 4.857MHz => Freq = PCLK / (CPSDVSR * [SCR+1]) with PCLK=PLL1=204MHz + const uint8_t serial_clock_rate = 21; + const uint8_t clock_prescale_rate = 2; + ssp_init(SSP1_NUM, SSP_DATA_16BITS, SSP_FRAME_SPI, @@ -329,9 +335,15 @@ void ssp1_set_mode_max2837(void) void ssp1_set_mode_max5864(void) { /* FIXME speed up once everything is working reliably */ + /* + // Freq About 0.0498MHz / 49.8KHz => Freq = PCLK / (CPSDVSR * [SCR+1]) with PCLK=PLL1=204MHz const uint8_t serial_clock_rate = 32; const uint8_t clock_prescale_rate = 128; - + */ + // Freq About 4.857MHz => Freq = PCLK / (CPSDVSR * [SCR+1]) with PCLK=PLL1=204MHz + const uint8_t serial_clock_rate = 21; + const uint8_t clock_prescale_rate = 2; + ssp_init(SSP1_NUM, SSP_DATA_8BITS, SSP_FRAME_SPI, diff --git a/host/libhackrf/examples/hackrf_transfer.c b/host/libhackrf/examples/hackrf_transfer.c index b55f9387..38794e32 100644 --- a/host/libhackrf/examples/hackrf_transfer.c +++ b/host/libhackrf/examples/hackrf_transfer.c @@ -42,9 +42,17 @@ #include #include +#define FREQ_ONE_MHZ (1000000) + #define FREQ_MIN_HZ (30000000ull) /* 30MHz */ #define FREQ_MAX_HZ (6000000000ull) /* 6000MHz */ +#define DEFAULT_SAMPLE_RATE_HZ (10000000) /* 10MHz default sample rate */ + +#define DEFAULT_BASEBAND_FILTER_BANDWIDTH (5000000) /* 5MHz default */ + +#define SAMPLES_TO_XFER_MAX (0x8000000000000000ull) /* Max value */ + #if defined _WIN32 #define sleep(a) Sleep( (a*1000) ) #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; if( strlen(s) > 2 ) { 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; volatile uint32_t byte_count = 0; @@ -124,6 +134,10 @@ uint64_t freq_hz; bool amp = false; uint32_t amp_enable; + +bool sample_rate = false; +uint32_t sample_rate_hz; + bool limit_num_samples = false; uint64_t samples_to_xfer = 0; uint64_t bytes_to_xfer = 0; @@ -190,8 +204,9 @@ static void usage() { printf("Usage:\n"); printf("\t-r # Receive data into file.\n"); printf("\t-t # 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[-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); printf("\t[-n num_samples] # Number of samples to transfer (default is unlimited).\n"); } @@ -199,58 +214,8 @@ static hackrf_device* device = NULL; void sigint_callback_handler(int signum) { - int result; - printf("Caught signal %d\n", signum); - - 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); + fprintf(stdout, "Caught signal %d\n", signum); + do_exit = true; } int main(int argc, char** argv) { @@ -258,7 +223,8 @@ int main(int argc, char** argv) { const char* path = NULL; int result; - while( (opt = getopt(argc, argv, "r:t:f:a:n:")) != EOF ) { + while( (opt = getopt(argc, argv, "r:t:f:a:s:n:")) != EOF ) + { result = HACKRF_SUCCESS; switch( opt ) { case 'r': @@ -278,13 +244,18 @@ int main(int argc, char** argv) { case 'a': amp = true; - result = parse_int(optarg, &_enable); + result = parse_u32(optarg, &_enable); + break; + + case 's': + sample_rate = true; + result = parse_u32(optarg, &sample_rate_hz); break; case 'n': limit_num_samples = true; result = parse_u64(optarg, &samples_to_xfer); - bytes_to_xfer = samples_to_xfer * 2; + bytes_to_xfer = samples_to_xfer * 2ull; break; default: @@ -293,14 +264,14 @@ int main(int argc, char** argv) { } if( result != HACKRF_SUCCESS ) { - printf("argument error: %s (%d)\n", hackrf_error_name(result), result); + printf("argument error: '-%c %s' %s (%d)\n", opt, optarg, hackrf_error_name(result), result); usage(); - break; + return EXIT_FAILURE; } } - if (samples_to_xfer >= 0x8000000000000000ul) { - printf("argument error: num_samples must be less than %lu\n", 0x8000000000000000ul); + if (samples_to_xfer >= SAMPLES_TO_XFER_MAX) { + printf("argument error: num_samples must be less than %llu/%lluMio\n", SAMPLES_TO_XFER_MAX, SAMPLES_TO_XFER_MAX/FREQ_ONE_MHZ); usage(); return EXIT_FAILURE; } @@ -308,7 +279,7 @@ int main(int argc, char** argv) { if( freq ) { if( (freq_hz >= FREQ_MAX_HZ) || (freq_hz < FREQ_MIN_HZ) ) { - printf("argument error: set_freq_hz shall be between [%lld, %lld[.\n", FREQ_MIN_HZ, FREQ_MAX_HZ); + printf("argument error: set_freq_hz shall be between [%llu, %llu[.\n", FREQ_MIN_HZ, FREQ_MAX_HZ); usage(); return EXIT_FAILURE; } @@ -321,7 +292,7 @@ int main(int argc, char** argv) { usage(); return EXIT_FAILURE; } - } + } if( transmit == receive ) { @@ -374,15 +345,34 @@ int main(int argc, char** argv) { 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(SIGABRT, &sigint_callback_handler); - result = hackrf_sample_rate_set(device, 10000000); - if( result != HACKRF_SUCCESS ) { - printf("hackrf_sample_rate_set() failed: %s (%d)\n", hackrf_error_name(result), result); - return EXIT_FAILURE; + if( sample_rate ) + { + printf("call hackrf_sample_rate_set(%u Hz/%u MHz)\n", sample_rate_hz, sample_rate_hz/FREQ_ONE_MHZ); + 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(%u Hz/%u 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(%d Hz/%d 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 ) { printf("hackrf_baseband_filter_bandwidth_set() failed: %s (%d)\n", hackrf_error_name(result), result); return EXIT_FAILURE; @@ -399,7 +389,7 @@ int main(int argc, char** argv) { } if( freq ) { - printf("call hackrf_set_freq(%lu Hz)\n", freq_hz); + printf("call hackrf_set_freq(%llu Hz/%llu MHz)\n", freq_hz, (freq_hz/FREQ_ONE_MHZ) ); result = hackrf_set_freq(device, freq_hz); if( result != HACKRF_SUCCESS ) { printf("hackrf_set_freq() failed: %s (%d)\n", hackrf_error_name(result), result); @@ -416,10 +406,16 @@ int main(int argc, char** argv) { } } + if( limit_num_samples ) { + printf("samples_to_xfer %llu/%lluMio\n", samples_to_xfer, (samples_to_xfer/FREQ_ONE_MHZ) ); + } + gettimeofday(&t_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); @@ -437,18 +433,56 @@ int main(int argc, char** argv) { time_start = time_now; } - result = hackrf_close(device); - if( result != HACKRF_SUCCESS ) { - printf("hackrf_close() failed: %s (%d)\n", hackrf_error_name(result), result); - return -1; + if (do_exit) + printf("\nUser cancel, exiting...\n"); + else + printf("\nExiting...\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 ) + { + 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) { fclose(fd); + fd = NULL; + printf("fclose(fd) done\n"); } - + printf("exit\n"); return EXIT_SUCCESS; } diff --git a/host/libhackrf/src/hackrf.c b/host/libhackrf/src/hackrf.c index bb323cde..e81f18c7 100644 --- a/host/libhackrf/src/hackrf.c +++ b/host/libhackrf/src/hackrf.c @@ -67,6 +67,8 @@ struct hackrf_device { bool streaming; }; +volatile bool do_exit = false; + static const uint16_t hackrf_usb_vid = 0x1d50; 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->buffer_size = 262144; /* 1048576; */ lib_device->streaming = false; + do_exit = false; result = allocate_transfers(lib_device); if( result != 0 ) { @@ -659,7 +662,8 @@ static void* transfer_threadproc(void* arg) { struct timeval timeout = { 0, 500000 }; - while( device->streaming ) { + while( (device->streaming) && (do_exit == false) ) + { int error = libusb_handle_events_timeout(g_libusb_context, &timeout); if( error != 0 ) { 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) { device->streaming = false; + do_exit = true; if( device->transfer_thread_started != false ) { void* value = NULL;