diff --git a/firmware/blinky_rom_to_ram/Makefile b/firmware/blinky_rom_to_ram/Makefile index b93e84e6..26e1f889 100644 --- a/firmware/blinky_rom_to_ram/Makefile +++ b/firmware/blinky_rom_to_ram/Makefile @@ -25,7 +25,8 @@ BINARY = blinky SRC = $(BINARY).c \ ../common/hackrf_core.c \ - ../common/si5351c.c + ../common/si5351c.c \ + ../common/max2837.c LDSCRIPT = ../common/LPC4330_M4_rom_to_ram.ld include ../common/Makefile_inc.mk diff --git a/firmware/common/Makefile_inc.mk b/firmware/common/Makefile_inc.mk index 2145fabd..a903515d 100644 --- a/firmware/common/Makefile_inc.mk +++ b/firmware/common/Makefile_inc.mk @@ -26,7 +26,8 @@ # derived primarily from Makefiles in libopencm3 -BOARD ?= JELLYBEAN +#BOARD ?= JELLYBEAN +BOARD ?= JAWBREAKER HACKRF_OPTS = -D$(BOARD) diff --git a/firmware/common/max2837.h b/firmware/common/max2837.h index 4983ca7e..acfc59be 100644 --- a/firmware/common/max2837.h +++ b/firmware/common/max2837.h @@ -8,6 +8,7 @@ /* 32 registers, each containing 10 bits of data. */ #define MAX2837_NUM_REGS 32 +#define MAX2837_DATA_REGS_MAX_VALUE 1024 /* TODO - these externs will be local to max2837.c ... don't define here? */ extern uint16_t max2837_regs[MAX2837_NUM_REGS]; diff --git a/firmware/sgpio_passthrough_rom_to_ram/Makefile b/firmware/sgpio_passthrough_rom_to_ram/Makefile index 073a583b..004c19a8 100644 --- a/firmware/sgpio_passthrough_rom_to_ram/Makefile +++ b/firmware/sgpio_passthrough_rom_to_ram/Makefile @@ -25,7 +25,8 @@ BINARY = sgpio_passthrough SRC = $(BINARY).c \ ../common/hackrf_core.c \ - ../common/si5351c.c + ../common/si5351c.c \ + ../common/max2837.c LDSCRIPT = ../common/LPC4330_M4_rom_to_ram.ld include ../common/Makefile_inc.mk diff --git a/firmware/startup_systick_perfo_rom_to_ram/Makefile b/firmware/startup_systick_perfo_rom_to_ram/Makefile index a52531e6..18d40799 100644 --- a/firmware/startup_systick_perfo_rom_to_ram/Makefile +++ b/firmware/startup_systick_perfo_rom_to_ram/Makefile @@ -5,7 +5,8 @@ BINARY = startup_systick_perfo_rom_to_ram SRC = startup_systick.c \ perf_mips.c \ ../common/hackrf_core.c \ - ../common/si5351c.c + ../common/si5351c.c \ + ../common/max2837.c LDSCRIPT = ../common/LPC4330_M4_rom_to_ram.ld include ../common/Makefile_inc.mk diff --git a/firmware/usb_performance/usb_performance.c b/firmware/usb_performance/usb_performance.c index 4c74acf7..7175a3db 100644 --- a/firmware/usb_performance/usb_performance.c +++ b/firmware/usb_performance/usb_performance.c @@ -225,8 +225,8 @@ usb_request_status_t usb_vendor_request_write_max2837( const usb_transfer_stage_t stage ) { if( stage == USB_TRANSFER_STAGE_SETUP ) { - if( endpoint->setup.index < 32 ) { - if( endpoint->setup.value < 0x3ff ) { + if( endpoint->setup.index < MAX2837_NUM_REGS ) { + if( endpoint->setup.value < MAX2837_DATA_REGS_MAX_VALUE ) { max2837_reg_write(endpoint->setup.index, endpoint->setup.value); usb_endpoint_schedule_ack(endpoint->in); return USB_REQUEST_STATUS_OK; @@ -243,7 +243,7 @@ usb_request_status_t usb_vendor_request_read_max2837( const usb_transfer_stage_t stage ) { if( stage == USB_TRANSFER_STAGE_SETUP ) { - if( endpoint->setup.index < 32 ) { + if( endpoint->setup.index < MAX2837_NUM_REGS ) { const uint16_t value = max2837_reg_read(endpoint->setup.index); endpoint->buffer[0] = value & 0xff; endpoint->buffer[1] = value >> 8; @@ -325,6 +325,46 @@ usb_request_status_t usb_vendor_request_set_baseband_filter_bandwidth( } } +usb_request_status_t usb_vendor_request_write_rffc5071( + usb_endpoint_t* const endpoint, + const usb_transfer_stage_t stage +) { + if( stage == USB_TRANSFER_STAGE_SETUP ) + { + if( endpoint->setup.index < RFFC5071_NUM_REGS ) + { + rffc5071_reg_write(endpoint->setup.index, endpoint->setup.value); + usb_endpoint_schedule_ack(endpoint->in); + return USB_REQUEST_STATUS_OK; + } + return USB_REQUEST_STATUS_STALL; + } else { + return USB_REQUEST_STATUS_OK; + } +} + +usb_request_status_t usb_vendor_request_read_rffc5071( + usb_endpoint_t* const endpoint, + const usb_transfer_stage_t stage +) { + uint16_t value; + if( stage == USB_TRANSFER_STAGE_SETUP ) + { + if( endpoint->setup.index < RFFC5071_NUM_REGS ) + { + value = rffc5071_reg_read(endpoint->setup.index); + endpoint->buffer[0] = value & 0xff; + endpoint->buffer[1] = value >> 8; + usb_endpoint_schedule(endpoint->in, &endpoint->buffer, 2); + usb_endpoint_schedule_ack(endpoint->out); + return USB_REQUEST_STATUS_OK; + } + return USB_REQUEST_STATUS_STALL; + } else { + return USB_REQUEST_STATUS_OK; + } +} + static const usb_request_handler_fn vendor_request_handler[] = { NULL, usb_vendor_request_set_transceiver_mode, @@ -334,6 +374,8 @@ static const usb_request_handler_fn vendor_request_handler[] = { usb_vendor_request_read_si5351c, usb_vendor_request_set_sample_rate, usb_vendor_request_set_baseband_filter_bandwidth, + usb_vendor_request_write_rffc5071, + usb_vendor_request_read_rffc5071 }; static const uint32_t vendor_request_handler_count = @@ -488,11 +530,17 @@ int main(void) { max2837_setup(); rffc5071_setup(); + #ifdef JAWBREAKER switchctrl = (SWITCHCTRL_AMP_BYPASS | SWITCHCTRL_HP); #endif rffc5071_rx(switchctrl); - rffc5071_set_frequency(500, 0); // 500 MHz, 0 Hz (Hz ignored) + +#ifdef JAWBREAKER + rffc5071_set_frequency(900, 0); // 900 MHz, 0 Hz (Hz ignored) default antenna +#else + rffc5071_set_frequency(500, 0); // 500 MHz, 0 Hz (Hz ignored) +#endif max2837_set_frequency(freq); max2837_start(); diff --git a/host/libhackrf/Readme.md b/host/libhackrf/Readme.md new file mode 100644 index 00000000..40321c82 --- /dev/null +++ b/host/libhackrf/Readme.md @@ -0,0 +1,33 @@ +This repository contains hardware designs and software for HackRF, a project to +produce a low cost, open source software radio platform. + +![Jawbreaker](https://raw.github.com/mossmann/hackrf/master/doc/jawbreaker.jpeg) + +How to build host software on Windows: +prerequisite for cygwin or mingw: +* cmake-2.8.10.2 or more see http://www.cmake.org/cmake/resources/software.html +* libusbx-1.0.14 or more see http://sourceforge.net/projects/libusbx/files/latest/download?source=files +* Install Windows driver for HackRF hardware or use Zadig see http://sourceforge.net/projects/libwdi/files/zadig + - If you want to use Zadig select HackRF USB device and just install/replace it with WinUSB driver. + +For Cygwin: +cmake -G "Unix Makefiles" -DCMAKE_LEGACY_CYGWIN_WIN32=1 -DLIBUSB_INCLUDE_DIR=/usr/local/include/libusb-1.0/ +make +make install + +For Mingw: +#normal version +cmake -G "MSYS Makefiles" -DLIBUSB_INCLUDE_DIR=/usr/local/include/libusb-1.0/ +#debug version +cmake -G "MSYS Makefiles" -DCMAKE_BUILD_TYPE=Debug -DLIBUSB_INCLUDE_DIR=/usr/local/include/libusb-1.0/ +make +make install + +How to build host software on Linux: +cmake ./ +make +make install + +principal author: Michael Ossmann + +http://greatscottgadgets.com/hackrf/ diff --git a/host/libhackrf/examples/CMakeLists.txt b/host/libhackrf/examples/CMakeLists.txt index 3ab34119..b4d7feda 100644 --- a/host/libhackrf/examples/CMakeLists.txt +++ b/host/libhackrf/examples/CMakeLists.txt @@ -1,35 +1,38 @@ -# Copyright 2012 Jared Boone -# -# This file is part of HackRF. -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2, or (at your option) -# any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; see the file COPYING. If not, write to -# the Free Software Foundation, Inc., 51 Franklin Street, -# Boston, MA 02110-1301, USA. -# - -# Based heavily upon the libftdi cmake setup. - -option(EXAMPLES "Build example programs" ON) - -IF( EXAMPLES ) - add_executable(hackrf_max2837 hackrf_max2837.c) - add_executable(hackrf_si5351c hackrf_si5351c.c) - add_executable(hackrf_transfer hackrf_transfer.c) - - target_link_libraries(hackrf_max2837 hackrf) - target_link_libraries(hackrf_si5351c hackrf) - target_link_libraries(hackrf_transfer hackrf) - - include_directories(BEFORE ${CMAKE_SOURCE_DIR}/src) -endif(EXAMPLES) +# Copyright 2012 Jared Boone +# Copyright 2013 Benjamin Vernoux +# +# This file is part of HackRF. +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2, or (at your option) +# any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; see the file COPYING. If not, write to +# the Free Software Foundation, Inc., 51 Franklin Street, +# Boston, MA 02110-1301, USA. +# + +# Based heavily upon the libftdi cmake setup. + +option(EXAMPLES "Build example programs" ON) + +IF( EXAMPLES ) + add_executable(hackrf_max2837 hackrf_max2837.c) + add_executable(hackrf_si5351c hackrf_si5351c.c) + add_executable(hackrf_transfer hackrf_transfer.c) + add_executable(hackrf_rffc5071 hackrf_rffc5071.c) + + target_link_libraries(hackrf_max2837 hackrf) + target_link_libraries(hackrf_si5351c hackrf) + target_link_libraries(hackrf_transfer hackrf) + target_link_libraries(hackrf_rffc5071 hackrf) + + include_directories(BEFORE ${CMAKE_SOURCE_DIR}/src) +endif(EXAMPLES) diff --git a/host/libhackrf/examples/hackrf_rffc5071.c b/host/libhackrf/examples/hackrf_rffc5071.c new file mode 100644 index 00000000..0808f7fb --- /dev/null +++ b/host/libhackrf/examples/hackrf_rffc5071.c @@ -0,0 +1,177 @@ +/* + * Copyright 2012 Jared Boone + * Copyright 2013 Benjamin Vernoux + * + * This file is part of HackRF. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#include + +#include +#include +#include +#include + +static void usage() { + printf("\nUsage:\n"); + printf("\t-n, --register : set register number for subsequent read/write operations\n"); + printf("\t-r, --read: read register specified by last -n argument, or all registers\n"); + printf("\t-w, --write : write register specified by last -n argument with value \n"); + printf("\nExamples:\n"); + printf("\t -n 12 -r # reads from register 12\n"); + printf("\t -r # reads all registers\n"); + printf("\t -n 10 -w 514 # writes register 10 with 514 decimal\n"); +} + +static struct option long_options[] = { + { "register", required_argument, 0, 'n' }, + { "write", required_argument, 0, 'w' }, + { "read", no_argument, 0, 'r' }, + { 0, 0, 0, 0 }, +}; + +int parse_int(char* s, uint16_t* const value) { + uint_fast8_t base = 10; + if( strlen(s) > 2 ) { + if( s[0] == '0' ) { + if( (s[1] == 'x') || (s[1] == 'X') ) { + base = 16; + s += 2; + } else if( (s[1] == 'b') || (s[1] == 'B') ) { + base = 2; + s += 2; + } + } + } + + char* s_end = s; + const long long_value = strtol(s, &s_end, base); + if( (s != s_end) && (*s_end == 0) ) { + *value = long_value; + return HACKRF_SUCCESS; + } else { + return HACKRF_ERROR_INVALID_PARAM; + } +} + +int dump_register(hackrf_device* device, const uint16_t register_number) { + uint16_t register_value; + int result = hackrf_rffc5071_read(device, register_number, ®ister_value); + + if( result == HACKRF_SUCCESS ) { + printf("[%2d] -> 0x%03x\n", register_number, register_value); + } else { + printf("hackrf_rffc5071_read() failed: %s (%d)\n", hackrf_error_name(result), result); + } + + return result; +} + +int dump_registers(hackrf_device* device) { + int result = HACKRF_SUCCESS; + + for(uint16_t register_number=0; register_number<31; register_number++) { + result = dump_register(device, register_number); + if( result != HACKRF_SUCCESS ) { + break; + } + } + + return result; +} + +int write_register( + hackrf_device* device, + const uint16_t register_number, + const uint16_t register_value +) { + int result = HACKRF_SUCCESS; + result = hackrf_rffc5071_write(device, register_number, register_value); + + if( result == HACKRF_SUCCESS ) { + printf("0x%03x -> [%2d]\n", register_value, register_number); + } else { + printf("hackrf_rffc5071_write() failed: %s (%d)\n", hackrf_error_name(result), result); + } + + return result; +} + +#define REGISTER_INVALID 32767 + +int main(int argc, char** argv) { + int opt; + uint16_t register_number = REGISTER_INVALID; + uint16_t register_value; + + int result = hackrf_init(); + if( result ) { + printf("hackrf_init() failed: %s (%d)\n", hackrf_error_name(result), result); + return -1; + } + + hackrf_device* device = NULL; + result = hackrf_open(&device); + if( result ) { + printf("hackrf_open() failed: %s (%d)\n", hackrf_error_name(result), result); + return -1; + } + + int option_index = 0; + while( (opt = getopt_long(argc, argv, "n:rw:", long_options, &option_index)) != EOF ) { + switch( opt ) { + case 'n': + result = parse_int(optarg, ®ister_number); + break; + + case 'w': + result = parse_int(optarg, ®ister_value); + if( result == HACKRF_SUCCESS ) { + result = write_register(device, register_number, register_value); + } + break; + + case 'r': + if( register_number == REGISTER_INVALID ) { + result = dump_registers(device); + } else { + result = dump_register(device, register_number); + } + break; + + default: + usage(); + } + + if( result != HACKRF_SUCCESS ) { + printf("argument error: %s (%d)\n", hackrf_error_name(result), result); + usage(); + break; + } + } + + result = hackrf_close(device); + if( result ) { + printf("hackrf_close() failed: %s (%d)\n", hackrf_error_name(result), result); + return -1; + } + + hackrf_exit(); + + return 0; +} diff --git a/host/libhackrf/examples/hackrf_transfer.c b/host/libhackrf/examples/hackrf_transfer.c index 36ef463b..2f099d6d 100644 --- a/host/libhackrf/examples/hackrf_transfer.c +++ b/host/libhackrf/examples/hackrf_transfer.c @@ -1,5 +1,6 @@ /* * Copyright 2012 Jared Boone + * Copyright 2013 Benjamin Vernoux * * This file is part of HackRF. * @@ -31,10 +32,20 @@ #include #include #include + +#ifdef _WIN32 +#include +#else #include +#endif + #include #include +#if defined _WIN32 + #define sleep(a) Sleep( (a*1000) ) +#endif + typedef enum { TRANSCEIVER_MODE_RX, TRANSCEIVER_MODE_TX, @@ -47,18 +58,24 @@ TimevalDiff(const struct timeval *a, const struct timeval *b) return (a->tv_sec - b->tv_sec) + 1e-6f * (a->tv_usec - b->tv_usec); } -int fd = -1; +FILE* fd = NULL; volatile uint32_t byte_count = 0; +bool receive = false; +bool transmit = false; +struct timeval time_start; +struct timeval t_start; + int rx_callback(hackrf_transfer* transfer) { - if( fd != -1 ) { + if( fd != NULL ) + { byte_count += transfer->valid_length; - const ssize_t bytes_written = write(fd, transfer->buffer, transfer->valid_length); + const ssize_t bytes_written = fwrite(transfer->buffer, 1, transfer->valid_length, fd); if( bytes_written == transfer->valid_length ) { return 0; } else { - close(fd); - fd = -1; + fclose(fd); + fd = NULL; return -1; } } else { @@ -67,14 +84,15 @@ int rx_callback(hackrf_transfer* transfer) { } int tx_callback(hackrf_transfer* transfer) { - if( fd != -1 ) { + if( fd != NULL ) + { byte_count += transfer->valid_length; - const ssize_t bytes_read = read(fd, transfer->buffer, transfer->valid_length); + const ssize_t bytes_read = fread(transfer->buffer, 1, transfer->valid_length, fd); if( bytes_read == transfer->valid_length ) { return 0; } else { - close(fd); - fd = -1; + fclose(fd); + fd = NULL; return -1; } } else { @@ -90,15 +108,64 @@ static void usage() { static hackrf_device* device = NULL; -void sigint_callback_handler(int signum) { - hackrf_stop_rx(device); - hackrf_stop_tx(device); +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); } int main(int argc, char** argv) { int opt; - bool receive = false; - bool transmit = false; const char* path = NULL; while( (opt = getopt(argc, argv, "r:t:")) != EOF ) { @@ -115,17 +182,20 @@ int main(int argc, char** argv) { default: usage(); - return 1; + return EXIT_FAILURE; } } - if( transmit == receive ) { - if( transmit == true ) { + if( transmit == receive ) + { + if( transmit == true ) + { fprintf(stderr, "receive and transmit options are mutually exclusive\n"); } else { fprintf(stderr, "specify either transmit or receive option\n"); } - return 1; + usage(); + return EXIT_FAILURE; } if( receive ) { @@ -138,31 +208,33 @@ int main(int argc, char** argv) { if( path == NULL ) { fprintf(stderr, "specify a path to a file to transmit/receive\n"); - return 1; + usage(); + return EXIT_FAILURE; } int result = hackrf_init(); if( result != HACKRF_SUCCESS ) { printf("hackrf_init() failed: %s (%d)\n", hackrf_error_name(result), result); - return -1; + usage(); + return EXIT_FAILURE; } result = hackrf_open(&device); if( result != HACKRF_SUCCESS ) { printf("hackrf_open() failed: %s (%d)\n", hackrf_error_name(result), result); - return -1; + return EXIT_FAILURE; } - fd = -1; - if( transceiver_mode == TRANSCEIVER_MODE_RX ) { - fd = open(path, O_WRONLY | O_CREAT | O_TRUNC, S_IRWXU | S_IRWXG | S_IRWXO); + if( transceiver_mode == TRANSCEIVER_MODE_RX ) + { + fd = fopen(path, "wb"); } else { - fd = open(path, O_RDONLY, S_IRWXU | S_IRWXG | S_IRWXO); + fd = fopen(path, "rb"); } - if( fd == -1 ) { - printf("Failed to open file: errno %d\n", errno); - return fd; + if( fd == NULL ) { + printf("Failed to open file: %s\n", path); + return EXIT_FAILURE; } signal(SIGINT, sigint_callback_handler); @@ -170,13 +242,13 @@ int main(int argc, char** argv) { 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 -1; + return EXIT_FAILURE; } result = hackrf_baseband_filter_bandwidth_set(device, 5000000); if( result != HACKRF_SUCCESS ) { printf("hackrf_baseband_filter_bandwidth_set() failed: %s (%d)\n", hackrf_error_name(result), result); - return -1; + return EXIT_FAILURE; } if( transceiver_mode == TRANSCEIVER_MODE_RX ) { @@ -186,32 +258,30 @@ int main(int argc, char** argv) { } if( result != HACKRF_SUCCESS ) { printf("hackrf_start_?x() failed: %s (%d)\n", hackrf_error_name(result), result); - return -1; + return EXIT_FAILURE; } - - struct timeval time_start; - gettimeofday(&time_start, NULL); - while( hackrf_is_streaming(device) ) { + gettimeofday(&t_start, NULL); + gettimeofday(&time_start, NULL); + + while( hackrf_is_streaming(device) ) + { sleep(1); - - struct timeval time_now; + + struct timeval time_now; gettimeofday(&time_now, NULL); uint32_t byte_count_now = byte_count; byte_count = 0; const float time_difference = TimevalDiff(&time_now, &time_start); - const float rate = (float)byte_count_now / time_difference; - printf("%4.1f MiB / %5.3f sec = %4.1f MiB/second\n", - byte_count_now / 1e6f, - time_difference, - rate / 1e6f - ); + const float rate = (float)byte_count_now / time_difference; + printf("%4.1f MiB / %5.3f sec = %4.1f MiB/second\n", + (byte_count_now / 1e6f), time_difference, (rate / 1e6f) ); - time_start = time_now; + time_start = time_now; } - + result = hackrf_close(device); if( result != HACKRF_SUCCESS ) { printf("hackrf_close() failed: %s (%d)\n", hackrf_error_name(result), result); @@ -219,6 +289,11 @@ int main(int argc, char** argv) { } hackrf_exit(); - - return 0; + + if(fd != NULL) + { + fclose(fd); + } + + return EXIT_SUCCESS; } diff --git a/host/libhackrf/src/CMakeLists.txt b/host/libhackrf/src/CMakeLists.txt index 223d034c..02cd40e6 100644 --- a/host/libhackrf/src/CMakeLists.txt +++ b/host/libhackrf/src/CMakeLists.txt @@ -1,4 +1,5 @@ # Copyright 2012 Jared Boone +# Copyright 2013 Benjamin Vernoux # # This file is part of HackRF. # @@ -36,7 +37,13 @@ set_target_properties(hackrf PROPERTIES CLEAN_DIRECT_OUTPUT 1) set_target_properties(hackrf-static PROPERTIES CLEAN_DIRECT_OUTPUT 1) # Dependencies -target_link_libraries(hackrf ${LIBUSB_LIBRARIES}) +target_link_libraries(hackrf ${LIBUSB_LIBRARIES} pthread) + +# For cygwin just force UNIX OFF and WIN32 ON +if( ${CYGWIN} ) + SET(UNIX OFF) + SET(WIN32 ON) +endif( ${CYGWIN} ) if( ${UNIX} ) install(TARGETS hackrf diff --git a/host/libhackrf/src/hackrf.c b/host/libhackrf/src/hackrf.c index a3efcf82..68dcfb2f 100644 --- a/host/libhackrf/src/hackrf.c +++ b/host/libhackrf/src/hackrf.c @@ -1,5 +1,6 @@ /* * Copyright 2012 Jared Boone + * Copyright 2013 Benjamin Vernoux * * This file is part of HackRF. * @@ -36,6 +37,8 @@ typedef enum { HACKRF_VENDOR_REQUEST_SI5351C_READ = 5, HACKRF_VENDOR_REQUEST_SAMPLE_RATE_SET = 6, HACKRF_VENDOR_REQUEST_BASEBAND_FILTER_BANDWIDTH_SET = 7, + HACKRF_VENDOR_REQUEST_RFFC5071_WRITE = 8, + HACKRF_VENDOR_REQUEST_RFFC5071_READ = 9 } hackrf_vendor_request; typedef enum { @@ -47,6 +50,7 @@ struct hackrf_device { libusb_device_handle* usb_device; struct libusb_transfer** transfers; hackrf_sample_block_cb_fn callback; + bool transfer_thread_started; pthread_t transfer_thread; uint32_t transfer_count; uint32_t buffer_size; @@ -198,9 +202,14 @@ int hackrf_open(hackrf_device** device) { lib_device->usb_device = usb_device; lib_device->transfers = NULL; lib_device->callback = NULL; - lib_device->transfer_thread = 0; + //lib_device->transfer_thread = (pthread_t)NULL; + lib_device->transfer_thread_started = false; + /* lib_device->transfer_count = 1024; lib_device->buffer_size = 16384; + */ + lib_device->transfer_count = 4; + lib_device->buffer_size = 262144; /* 1048576; */ lib_device->streaming = false; result = allocate_transfers(lib_device); @@ -373,6 +382,55 @@ int hackrf_baseband_filter_bandwidth_set(hackrf_device* device, const uint32_t b } } + +int hackrf_rffc5071_read(hackrf_device* device, uint8_t register_number, uint16_t* value) +{ + if( register_number >= 31 ) { + return HACKRF_ERROR_INVALID_PARAM; + } + + int result = libusb_control_transfer( + device->usb_device, + LIBUSB_ENDPOINT_IN | LIBUSB_REQUEST_TYPE_VENDOR | LIBUSB_RECIPIENT_DEVICE, + HACKRF_VENDOR_REQUEST_RFFC5071_READ, + 0, + register_number, + (unsigned char*)value, + 2, + 0 + ); + + if( result < 2 ) { + return HACKRF_ERROR_LIBUSB; + } else { + return HACKRF_SUCCESS; + } +} + +int hackrf_rffc5071_write(hackrf_device* device, uint8_t register_number, uint16_t value) +{ + if( register_number >= 31 ) { + return HACKRF_ERROR_INVALID_PARAM; + } + + int result = libusb_control_transfer( + device->usb_device, + LIBUSB_ENDPOINT_OUT | LIBUSB_REQUEST_TYPE_VENDOR | LIBUSB_RECIPIENT_DEVICE, + HACKRF_VENDOR_REQUEST_RFFC5071_WRITE, + value, + register_number, + NULL, + 0, + 0 + ); + + if( result != 0 ) { + return HACKRF_ERROR_LIBUSB; + } else { + return HACKRF_SUCCESS; + } +} + static void* transfer_threadproc(void* arg) { hackrf_device* device = (hackrf_device*)arg; @@ -411,13 +469,13 @@ static void hackrf_libusb_transfer_callback(struct libusb_transfer* usb_transfer static int kill_transfer_thread(hackrf_device* device) { device->streaming = false; - if( device->transfer_thread != 0 ) { + if( device->transfer_thread_started != false ) { void* value = NULL; int result = pthread_join(device->transfer_thread, &value); if( result != 0 ) { return HACKRF_ERROR_THREAD; } - device->transfer_thread = 0; + device->transfer_thread_started = false; } return HACKRF_SUCCESS; @@ -428,10 +486,10 @@ static int create_transfer_thread( const uint8_t endpoint_address, hackrf_sample_block_cb_fn callback ) { - if( device->transfer_thread == 0 ) { + if( device->transfer_thread_started == false ) { int result = prepare_transfers( device, endpoint_address, - hackrf_libusb_transfer_callback + (libusb_transfer_cb_fn)hackrf_libusb_transfer_callback ); if( result != HACKRF_SUCCESS ) { return result; @@ -440,8 +498,10 @@ static int create_transfer_thread( device->callback = callback; device->streaming = true; + device->transfer_thread_started = true; result = pthread_create(&device->transfer_thread, 0, transfer_threadproc, device); if( result != 0 ) { + device->transfer_thread_started = false; return HACKRF_ERROR_THREAD; } } else { diff --git a/host/libhackrf/src/hackrf.h b/host/libhackrf/src/hackrf.h index 8c288ebd..7b87df34 100644 --- a/host/libhackrf/src/hackrf.h +++ b/host/libhackrf/src/hackrf.h @@ -1,5 +1,6 @@ /* * Copyright 2012 Jared Boone + * Copyright 2013 Benjamin Vernoux * * This file is part of HackRF. * @@ -70,6 +71,9 @@ int hackrf_si5351c_write(hackrf_device* device, uint16_t register_number, uint16 int hackrf_sample_rate_set(hackrf_device* device, const uint32_t sampling_rate_hz); int hackrf_baseband_filter_bandwidth_set(hackrf_device* device, const uint32_t bandwidth_hz); +int hackrf_rffc5071_read(hackrf_device* device, uint8_t register_number, uint16_t* value); +int hackrf_rffc5071_write(hackrf_device* device, uint8_t register_number, uint16_t value); + const char* hackrf_error_name(enum hackrf_error errcode); #endif//__HACKRF_H__