From bf964e769df631435019de0395ed1f814f33fe29 Mon Sep 17 00:00:00 2001 From: TitanMKD Date: Fri, 17 May 2013 00:00:46 +0200 Subject: [PATCH 1/3] New license for libhackrf based on http://opensource.org/licenses/BSD-3-Clause --- host/libhackrf/src/CMakeLists.txt | 39 +++++++++++++++-------------- host/libhackrf/src/hackrf.c | 41 ++++++++++++++++--------------- host/libhackrf/src/hackrf.h | 41 ++++++++++++++++--------------- 3 files changed, 62 insertions(+), 59 deletions(-) diff --git a/host/libhackrf/src/CMakeLists.txt b/host/libhackrf/src/CMakeLists.txt index 8e15b8b0..56fb50ef 100644 --- a/host/libhackrf/src/CMakeLists.txt +++ b/host/libhackrf/src/CMakeLists.txt @@ -1,24 +1,25 @@ -# Copyright 2012 Jared Boone -# Copyright 2013 Benjamin Vernoux # -# This file is part of HackRF. +# Copyright (c) 2012, Jared Boone +# Copyright (c) 2013, Benjamin Vernoux +# Copyright (c) 2013, Michael Ossmann +# +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: +# +# Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. +# Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# Neither the name of Great Scott Gadgets nor the names of its contributors may be used to endorse or promote products derived from this software +# without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, +# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +# IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # -# 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. # Targets diff --git a/host/libhackrf/src/hackrf.c b/host/libhackrf/src/hackrf.c index 610ad301..c520e63e 100644 --- a/host/libhackrf/src/hackrf.c +++ b/host/libhackrf/src/hackrf.c @@ -1,24 +1,25 @@ /* - * 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. - */ +Copyright (c) 2012, Jared Boone +Copyright (c) 2013, Benjamin Vernoux +Copyright (c) 2013, Michael Ossmann + +All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: + + Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. + Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + Neither the name of Great Scott Gadgets nor the names of its contributors may be used to endorse or promote products derived from this software + without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, +THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ #include "hackrf.h" diff --git a/host/libhackrf/src/hackrf.h b/host/libhackrf/src/hackrf.h index 64320d7c..b05a555e 100644 --- a/host/libhackrf/src/hackrf.h +++ b/host/libhackrf/src/hackrf.h @@ -1,24 +1,25 @@ /* - * 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. - */ +Copyright (c) 2012, Jared Boone +Copyright (c) 2013, Benjamin Vernoux +Copyright (c) 2013, Michael Ossmann + +All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: + + Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. + Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + Neither the name of Great Scott Gadgets nor the names of its contributors may be used to endorse or promote products derived from this software + without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, +THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ #ifndef __HACKRF_H__ #define __HACKRF_H__ From 345794fdb9b3c9801181e904dd1733603b79b216 Mon Sep 17 00:00:00 2001 From: TitanMKD Date: Fri, 17 May 2013 01:13:24 +0200 Subject: [PATCH 2/3] Moved host/libhackrf/examples to host/hackrf-tools --- host/hackrf-tools/CMakeLists.txt | 43 ++ host/hackrf-tools/FindUSB1.cmake | 38 ++ host/hackrf-tools/Readme.md | 34 ++ host/hackrf-tools/src/CMakeLists.txt | 44 ++ host/hackrf-tools/src/hackrf_cpldjtag.c | 198 +++++++ host/hackrf-tools/src/hackrf_info.c | 95 ++++ host/hackrf-tools/src/hackrf_max2837.c | 176 +++++++ host/hackrf-tools/src/hackrf_rffc5071.c | 178 +++++++ host/hackrf-tools/src/hackrf_si5351c.c | 224 ++++++++ host/hackrf-tools/src/hackrf_spiflash.c | 275 ++++++++++ host/hackrf-tools/src/hackrf_transfer.c | 668 ++++++++++++++++++++++++ 11 files changed, 1973 insertions(+) create mode 100644 host/hackrf-tools/CMakeLists.txt create mode 100644 host/hackrf-tools/FindUSB1.cmake create mode 100644 host/hackrf-tools/Readme.md create mode 100644 host/hackrf-tools/src/CMakeLists.txt create mode 100644 host/hackrf-tools/src/hackrf_cpldjtag.c create mode 100644 host/hackrf-tools/src/hackrf_info.c create mode 100644 host/hackrf-tools/src/hackrf_max2837.c create mode 100644 host/hackrf-tools/src/hackrf_rffc5071.c create mode 100644 host/hackrf-tools/src/hackrf_si5351c.c create mode 100644 host/hackrf-tools/src/hackrf_spiflash.c create mode 100644 host/hackrf-tools/src/hackrf_transfer.c diff --git a/host/hackrf-tools/CMakeLists.txt b/host/hackrf-tools/CMakeLists.txt new file mode 100644 index 00000000..c970f1c4 --- /dev/null +++ b/host/hackrf-tools/CMakeLists.txt @@ -0,0 +1,43 @@ +# 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. + +project(hackrf-tools) +set(MAJOR_VERSION 0) +set(MINOR_VERSION 1) +set(PACKAGE hackrf-tools) +set(VERSION_STRING ${MAJOR_VERSION}.${MINOR_VERSION}) +set(VERSION ${VERSION_STRING}) +set(CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}") + +cmake_minimum_required(VERSION 2.8) + +add_definitions(-Wall) +set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -std=c99") +set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++98") + +find_package(USB1 REQUIRED) +include_directories(${LIBUSB_INCLUDE_DIR}) + +include_directories(${CMAKE_SOURCE_DIR}/../libhackrf/src) +link_directories(${CMAKE_SOURCE_DIR}/../libhackrf/src) + +add_subdirectory(src) diff --git a/host/hackrf-tools/FindUSB1.cmake b/host/hackrf-tools/FindUSB1.cmake new file mode 100644 index 00000000..0cbf8022 --- /dev/null +++ b/host/hackrf-tools/FindUSB1.cmake @@ -0,0 +1,38 @@ +# - Try to find the freetype library +# Once done this defines +# +# LIBUSB_FOUND - system has libusb +# LIBUSB_INCLUDE_DIR - the libusb include directory +# LIBUSB_LIBRARIES - Link these to use libusb + +# Copyright (c) 2006, 2008 Laurent Montel, +# +# Redistribution and use is allowed according to the terms of the BSD license. +# For details see the accompanying COPYING-CMAKE-SCRIPTS file. + + +if (LIBUSB_INCLUDE_DIR AND LIBUSB_LIBRARIES) + + # in cache already + set(LIBUSB_FOUND TRUE) + +else (LIBUSB_INCLUDE_DIR AND LIBUSB_LIBRARIES) + IF (NOT WIN32) + # use pkg-config to get the directories and then use these values + # in the FIND_PATH() and FIND_LIBRARY() calls + find_package(PkgConfig) + pkg_check_modules(PC_LIBUSB libusb-1.0) + ENDIF(NOT WIN32) + + FIND_PATH(LIBUSB_INCLUDE_DIR libusb.h + PATHS ${PC_LIBUSB_INCLUDEDIR} ${PC_LIBUSB_INCLUDE_DIRS}) + + FIND_LIBRARY(LIBUSB_LIBRARIES NAMES usb-1.0 + PATHS ${PC_LIBUSB_LIBDIR} ${PC_LIBUSB_LIBRARY_DIRS}) + + include(FindPackageHandleStandardArgs) + FIND_PACKAGE_HANDLE_STANDARD_ARGS(LIBUSB DEFAULT_MSG LIBUSB_LIBRARIES LIBUSB_INCLUDE_DIR) + + MARK_AS_ADVANCED(LIBUSB_INCLUDE_DIR LIBUSB_LIBRARIES) + +endif (LIBUSB_INCLUDE_DIR AND LIBUSB_LIBRARIES) \ No newline at end of file diff --git a/host/hackrf-tools/Readme.md b/host/hackrf-tools/Readme.md new file mode 100644 index 00000000..beb0c947 --- /dev/null +++ b/host/hackrf-tools/Readme.md @@ -0,0 +1,34 @@ +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. +* Build libhackrf before to build this library, see host/libhackrf/Readme.md. + +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/hackrf-tools/src/CMakeLists.txt b/host/hackrf-tools/src/CMakeLists.txt new file mode 100644 index 00000000..097a8ad2 --- /dev/null +++ b/host/hackrf-tools/src/CMakeLists.txt @@ -0,0 +1,44 @@ +# 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) + add_executable(hackrf_spiflash hackrf_spiflash.c) + add_executable(hackrf_cpldjtag hackrf_cpldjtag.c) + add_executable(hackrf_info hackrf_info.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) + target_link_libraries(hackrf_spiflash hackrf) + target_link_libraries(hackrf_cpldjtag hackrf) + target_link_libraries(hackrf_info hackrf) + + include_directories(BEFORE ${CMAKE_SOURCE_DIR}/../libhackrf/src) +endif(EXAMPLES) diff --git a/host/hackrf-tools/src/hackrf_cpldjtag.c b/host/hackrf-tools/src/hackrf_cpldjtag.c new file mode 100644 index 00000000..da4293e0 --- /dev/null +++ b/host/hackrf-tools/src/hackrf_cpldjtag.c @@ -0,0 +1,198 @@ +/* + * Copyright 2012 Jared Boone + * Copyright 2013 Benjamin Vernoux + * Copyright 2013 Michael Ossmann + * + * 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 +#include + +/* input file shouldn't be any longer than this */ +#define MAX_XSVF_LENGTH 0x10000 +#define PACKET_LEN 4096 + +uint8_t data[MAX_XSVF_LENGTH]; + +static struct option long_options[] = { + { "xsvf", required_argument, 0, 'x' }, + { 0, 0, 0, 0 }, +}; + +int parse_int(char* s, uint32_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; + } +} + +static void usage() +{ + printf("Usage:\n"); + printf("\t-x : XSVF file to be written to CPLD.\n"); +} + +int main(int argc, char** argv) +{ + int opt; + uint32_t length = 0; + uint32_t total_length = 0; + const char* path = NULL; + hackrf_device* device = NULL; + int result = HACKRF_SUCCESS; + int option_index = 0; + FILE* fd = NULL; + ssize_t bytes_read; + uint16_t xfer_len = 0; + uint8_t* pdata = &data[0]; + + while ((opt = getopt_long(argc, argv, "x:", long_options, + &option_index)) != EOF) { + switch (opt) { + case 'x': + path = optarg; + break; + + default: + usage(); + return EXIT_FAILURE; + } + + if (result != HACKRF_SUCCESS) { + fprintf(stderr, "argument error: %s (%d)\n", + hackrf_error_name(result), result); + usage(); + return EXIT_FAILURE; + } + } + + if (path == NULL) { + fprintf(stderr, "Specify a path to a file.\n"); + usage(); + return EXIT_FAILURE; + } + + fd = fopen(path, "rb"); + if (fd == NULL) + { + fprintf(stderr, "Failed to open file: %s\n", path); + return EXIT_FAILURE; + } + /* Get size of the file */ + fseek(fd, 0, SEEK_END); /* Not really portable but work on major OS Linux/Win32 */ + length = ftell(fd); + /* Move to start */ + rewind(fd); + printf("File size %d bytes.\n", length); + + if (length > MAX_XSVF_LENGTH) { + fprintf(stderr, "XSVF file too large.\n"); + usage(); + return EXIT_FAILURE; + } + + total_length = length; + bytes_read = fread(data, 1, total_length, fd); + if (bytes_read != total_length) + { + fprintf(stderr, "Failed to read all bytes (read %d bytes instead of %d bytes).\n", + (int)bytes_read, total_length); + fclose(fd); + fd = NULL; + return EXIT_FAILURE; + } + + result = hackrf_init(); + if (result != HACKRF_SUCCESS) { + fprintf(stderr, "hackrf_init() failed: %s (%d)\n", + hackrf_error_name(result), result); + return EXIT_FAILURE; + } + + result = hackrf_open(&device); + if (result != HACKRF_SUCCESS) { + fprintf(stderr, "hackrf_open() failed: %s (%d)\n", + hackrf_error_name(result), result); + return EXIT_FAILURE; + } + + printf("LED1/2/3 blinking means CPLD program success.\nLED3/RED steady means error.\n"); + printf("Wait message 'Write finished' or in case of LED3/RED steady, Power OFF/Disconnect the Jawbreaker.\n"); + while( length ) + { + xfer_len = (length > PACKET_LEN) ? PACKET_LEN : length; + result = hackrf_cpld_write(device, xfer_len, pdata, total_length); + if (result != HACKRF_SUCCESS) + { + fprintf(stderr, "hackrf_cpld_write() failed: %s (%d)\n", + hackrf_error_name(result), result); + fclose(fd); + fd = NULL; + return EXIT_FAILURE; + } + pdata += xfer_len; + length -= xfer_len; + printf("hackrf_cpld_write() Writing %d bytes, remaining %d bytes.\n", + xfer_len, length); + } + printf("Write finished.\n"); + printf("Please Power OFF/Disconnect the Jawbreaker.\n"); + fflush(stdout); + + result = hackrf_close(device); + if( result != HACKRF_SUCCESS ) + { + fprintf(stderr, "hackrf_close() failed: %s (%d)\n", + hackrf_error_name(result), result); + fclose(fd); + fd = NULL; + return EXIT_FAILURE; + } + + hackrf_exit(); + + if (fd != NULL) { + fclose(fd); + } + + return EXIT_SUCCESS; +} diff --git a/host/hackrf-tools/src/hackrf_info.c b/host/hackrf-tools/src/hackrf_info.c new file mode 100644 index 00000000..d83b9696 --- /dev/null +++ b/host/hackrf-tools/src/hackrf_info.c @@ -0,0 +1,95 @@ +/* + * Copyright 2012 Jared Boone + * Copyright 2013 Benjamin Vernoux + * Copyright 2013 Michael Ossmann + * + * 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 + +int main(int argc, char** argv) +{ + hackrf_device* device = NULL; + int result = HACKRF_SUCCESS; + uint8_t board_id = BOARD_ID_INVALID; + char version[255 + 1]; + read_partid_serialno_t read_partid_serialno; + + result = hackrf_init(); + if (result != HACKRF_SUCCESS) { + fprintf(stderr, "hackrf_init() failed: %s (%d)\n", + hackrf_error_name(result), result); + return EXIT_FAILURE; + } + + result = hackrf_open(&device); + if (result != HACKRF_SUCCESS) { + fprintf(stderr, "hackrf_open() failed: %s (%d)\n", + hackrf_error_name(result), result); + return EXIT_FAILURE; + } + + printf("Found HackRF board.\n"); + + result = hackrf_board_id_read(device, &board_id); + if (result != HACKRF_SUCCESS) { + fprintf(stderr, "hackrf_board_id_read() failed: %s (%d)\n", + hackrf_error_name(result), result); + return EXIT_FAILURE; + } + printf("Board ID Number: %d (%s)\n", board_id, + hackrf_board_id_name(board_id)); + + result = hackrf_version_string_read(device, &version[0], 255); + if (result != HACKRF_SUCCESS) { + fprintf(stderr, "hackrf_version_string_read() failed: %s (%d)\n", + hackrf_error_name(result), result); + return EXIT_FAILURE; + } + printf("Firmware Version: %s\n", version); + + result = hackrf_board_partid_serialno_read(device, &read_partid_serialno); + if (result != HACKRF_SUCCESS) { + fprintf(stderr, "hackrf_board_partid_serialno_read() failed: %s (%d)\n", + hackrf_error_name(result), result); + return EXIT_FAILURE; + } + printf("Part ID Number: 0x%08x 0x%08x\n", + read_partid_serialno.part_id[0], + read_partid_serialno.part_id[1]); + printf("Serial Number: 0x%08x 0x%08x 0x%08x 0x%08x\n", + read_partid_serialno.serial_no[0], + read_partid_serialno.serial_no[1], + read_partid_serialno.serial_no[2], + read_partid_serialno.serial_no[3]); + + result = hackrf_close(device); + if (result != HACKRF_SUCCESS) { + fprintf(stderr, "hackrf_close() failed: %s (%d)\n", + hackrf_error_name(result), result); + return EXIT_FAILURE; + } + + hackrf_exit(); + + return EXIT_SUCCESS; +} diff --git a/host/hackrf-tools/src/hackrf_max2837.c b/host/hackrf-tools/src/hackrf_max2837.c new file mode 100644 index 00000000..e780dba6 --- /dev/null +++ b/host/hackrf-tools/src/hackrf_max2837.c @@ -0,0 +1,176 @@ +/* + * 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. + */ + +#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 22 # writes register 10 with 22 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_max2837_read(device, register_number, ®ister_value); + + if( result == HACKRF_SUCCESS ) { + printf("[%2d] -> 0x%03x\n", register_number, register_value); + } else { + printf("hackrf_max2837_read() failed: %s (%d)\n", hackrf_error_name(result), result); + } + + return result; +} + +int dump_registers(hackrf_device* device) { + uint16_t register_number; + int result = HACKRF_SUCCESS; + + for(register_number=0; register_number<32; 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_max2837_write(device, register_number, register_value); + + if( result == HACKRF_SUCCESS ) { + printf("0x%03x -> [%2d]\n", register_value, register_number); + } else { + printf("hackrf_max2837_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); + 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/hackrf-tools/src/hackrf_rffc5071.c b/host/hackrf-tools/src/hackrf_rffc5071.c new file mode 100644 index 00000000..f3d5fdcd --- /dev/null +++ b/host/hackrf-tools/src/hackrf_rffc5071.c @@ -0,0 +1,178 @@ +/* + * 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) { + uint16_t register_number; + int result = HACKRF_SUCCESS; + + for(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/hackrf-tools/src/hackrf_si5351c.c b/host/hackrf-tools/src/hackrf_si5351c.c new file mode 100644 index 00000000..d5373df6 --- /dev/null +++ b/host/hackrf-tools/src/hackrf_si5351c.c @@ -0,0 +1,224 @@ +/* + * 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. + */ + +#include + +#include +#include +#include + +static void usage() { + printf("\nUsage:\n"); + printf("\t-c, --config: print textual configuration information\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 22 # writes register 10 with 22 decimal\n"); +} + +static struct option long_options[] = { + { "config", no_argument, 0, 'c' }, + { "register", required_argument, 0, 'n' }, + { "write", required_argument, 0, 'w' }, + { "read", no_argument, 0, 'r' }, + { 0, 0, 0, 0 }, +}; + +int parse_int(char* const s, uint16_t* const value) { + char* s_end = s; + const long long_value = strtol(s, &s_end, 10); + 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_si5351c_read(device, register_number, ®ister_value); + + if( result == HACKRF_SUCCESS ) { + printf("[%3d] -> 0x%02x\n", register_number, register_value); + } else { + printf("hackrf_max2837_read() failed: %s (%d)\n", hackrf_error_name(result), result); + } + + return result; +} + +int dump_registers(hackrf_device* device) { + uint16_t register_number; + int result = HACKRF_SUCCESS; + + for(register_number=0; register_number<256; 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_si5351c_write(device, register_number, register_value); + + if( result == HACKRF_SUCCESS ) { + printf("0x%2x -> [%3d]\n", register_value, register_number); + } else { + printf("hackrf_max2837_write() failed: %s (%d)\n", hackrf_error_name(result), result); + } + + return result; +} + +#define REGISTER_INVALID 32767 + +int dump_multisynth_config(hackrf_device* device, const uint_fast8_t ms_number) { + uint_fast8_t i; + uint_fast8_t reg_base; + uint16_t parameters[8]; + + reg_base = 42 + (ms_number * 8); + for(i=0; i<8; i++) { + uint_fast8_t reg_number = reg_base + i; + int result = hackrf_si5351c_read(device, reg_number, ¶meters[i]); + if( result != HACKRF_SUCCESS ) { + return result; + } + } + + const uint32_t p1 = + (parameters[2] & 0x03 << 16) + | (parameters[3] << 8) + | parameters[4] + ; + const uint32_t p2 = + (parameters[5] & 0x0F << 16) + | (parameters[6] << 8) + | parameters[7] + ; + const uint32_t p3 = + (parameters[5] & 0xF0 << 12) + | (parameters[0] << 8) + | parameters[1] + ; + const uint32_t r_div = + (parameters[2] >> 4) & 0x7 + ; + + printf("MS%d:", ms_number); + printf("\tp1 = %u\n", p1); + printf("\tp2 = %u\n", p2); + printf("\tp3 = %u\n", p3); + printf("\toutput divider = %u\n", 1 << r_div); + + return HACKRF_SUCCESS; +} + +int dump_configuration(hackrf_device* device) { + uint_fast8_t ms_number; + int result; + + for(ms_number=0; ms_number<8; ms_number++) { + result = dump_multisynth_config(device, ms_number); + if( result != HACKRF_SUCCESS ) { + return result; + } + } + + return HACKRF_SUCCESS; +} + +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, "cn: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; + + case 'c': + dump_configuration(device); + break; + + default: + usage(); + } + + if( result != HACKRF_SUCCESS ) { + printf("argument error: %s (%d)\n", hackrf_error_name(result), result); + 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/hackrf-tools/src/hackrf_spiflash.c b/host/hackrf-tools/src/hackrf_spiflash.c new file mode 100644 index 00000000..4e42d870 --- /dev/null +++ b/host/hackrf-tools/src/hackrf_spiflash.c @@ -0,0 +1,275 @@ +/* + * Copyright 2012 Jared Boone + * Copyright 2013 Benjamin Vernoux + * Copyright 2013 Michael Ossmann + * + * 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 +#include +#include + +/* 8 Mbit flash */ +#define MAX_LENGTH 0x100000 + +static struct option long_options[] = { + { "address", required_argument, 0, 'a' }, + { "length", required_argument, 0, 'l' }, + { "read", required_argument, 0, 'r' }, + { "write", required_argument, 0, 'w' }, + { 0, 0, 0, 0 }, +}; + +int parse_u32(char* s, uint32_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 uint32_t u32_value = strtoul(s, &s_end, base); + if ((s != s_end) && (*s_end == 0)) { + *value = u32_value; + return HACKRF_SUCCESS; + } else { + return HACKRF_ERROR_INVALID_PARAM; + } +} + +static void usage() +{ + printf("Usage:\n"); + printf("\t-a, --address : starting address (default: 0)\n"); + printf("\t-l, --length : number of bytes to read (default: 0)\n"); + printf("\t-r : Read data into file.\n"); + printf("\t-w : Write data from file.\n"); +} + +int main(int argc, char** argv) +{ + int opt; + uint32_t address = 0; + uint32_t length = 0; + uint32_t tmp_length; + uint16_t xfer_len = 0; + const char* path = NULL; + hackrf_device* device = NULL; + int result = HACKRF_SUCCESS; + int option_index = 0; + static uint8_t data[MAX_LENGTH]; + uint8_t* pdata = &data[0]; + FILE* fd = NULL; + bool read = false; + bool write = false; + + while ((opt = getopt_long(argc, argv, "a:l:r:w:", long_options, + &option_index)) != EOF) { + switch (opt) { + case 'a': + result = parse_u32(optarg, &address); + break; + + case 'l': + result = parse_u32(optarg, &length); + break; + + case 'r': + read = true; + path = optarg; + break; + + case 'w': + write = true; + path = optarg; + break; + + default: + fprintf(stderr, "opt error: %d\n", opt); + usage(); + return EXIT_FAILURE; + } + + if (result != HACKRF_SUCCESS) { + fprintf(stderr, "argument error: %s (%d)\n", + hackrf_error_name(result), result); + usage(); + return EXIT_FAILURE; + } + } + + if (write == read) { + if (write == true) { + fprintf(stderr, "Read and write options are mutually exclusive.\n"); + } else { + fprintf(stderr, "Specify either read or write option.\n"); + } + usage(); + return EXIT_FAILURE; + } + + if (path == NULL) { + fprintf(stderr, "Specify a path to a file.\n"); + usage(); + return EXIT_FAILURE; + } + + if( write ) + { + fd = fopen(path, "rb"); + /* Get size of the file */ + fseek(fd, 0, SEEK_END); /* Not really portable but work on major OS Linux/Win32 */ + length = ftell(fd); + /* Move to start */ + rewind(fd); + printf("File size %d bytes.\n", length); + } + + if (length == 0) { + fprintf(stderr, "Requested transfer of zero bytes.\n"); + if(fd != NULL) + fclose(fd); + usage(); + return EXIT_FAILURE; + } + + if ((length > MAX_LENGTH) || (address > MAX_LENGTH) + || ((address + length) > MAX_LENGTH)) { + fprintf(stderr, "Request exceeds size of flash memory.\n"); + if(fd != NULL) + fclose(fd); + usage(); + return EXIT_FAILURE; + } + + if (read) { + fd = fopen(path, "wb"); + } + + if (fd == NULL) { + fprintf(stderr, "Failed to open file: %s\n", path); + return EXIT_FAILURE; + } + + result = hackrf_init(); + if (result != HACKRF_SUCCESS) { + fprintf(stderr, "hackrf_init() failed: %s (%d)\n", + hackrf_error_name(result), result); + return EXIT_FAILURE; + } + + result = hackrf_open(&device); + if (result != HACKRF_SUCCESS) { + fprintf(stderr, "hackrf_open() failed: %s (%d)\n", + hackrf_error_name(result), result); + return EXIT_FAILURE; + } + + if (read) + { + tmp_length = length; + while (tmp_length) + { + xfer_len = (tmp_length > 256) ? 256 : tmp_length; + printf("Reading %d bytes from 0x%06x.\n", xfer_len, address); + result = hackrf_spiflash_read(device, address, xfer_len, pdata); + if (result != HACKRF_SUCCESS) { + fprintf(stderr, "hackrf_spiflash_read() failed: %s (%d)\n", + hackrf_error_name(result), result); + fclose(fd); + fd = NULL; + return EXIT_FAILURE; + } + address += xfer_len; + pdata += xfer_len; + tmp_length -= xfer_len; + } + const ssize_t bytes_written = fwrite(data, 1, length, fd); + if (bytes_written != length) { + fprintf(stderr, "Failed write to file (wrote %d bytes).\n", + (int)bytes_written); + fclose(fd); + fd = NULL; + return EXIT_FAILURE; + } + } else { + const ssize_t bytes_read = fread(data, 1, length, fd); + if (bytes_read != length) { + fprintf(stderr, "Failed read file (read %d bytes).\n", + (int)bytes_read); + fclose(fd); + fd = NULL; + return EXIT_FAILURE; + } + printf("Erasing SPI flash.\n"); + result = hackrf_spiflash_erase(device); + if (result != HACKRF_SUCCESS) { + fprintf(stderr, "hackrf_spiflash_erase() failed: %s (%d)\n", + hackrf_error_name(result), result); + fclose(fd); + fd = NULL; + return EXIT_FAILURE; + } + while (length) { + xfer_len = (length > 256) ? 256 : length; + printf("Writing %d bytes at 0x%06x.\n", xfer_len, address); + result = hackrf_spiflash_write(device, address, xfer_len, pdata); + if (result != HACKRF_SUCCESS) { + fprintf(stderr, "hackrf_spiflash_write() failed: %s (%d)\n", + hackrf_error_name(result), result); + fclose(fd); + fd = NULL; + return EXIT_FAILURE; + } + address += xfer_len; + pdata += xfer_len; + length -= xfer_len; + } + } + + result = hackrf_close(device); + if (result != HACKRF_SUCCESS) { + fprintf(stderr, "hackrf_close() failed: %s (%d)\n", + hackrf_error_name(result), result); + fclose(fd); + fd = NULL; + return EXIT_FAILURE; + } + + hackrf_exit(); + + if (fd != NULL) { + fclose(fd); + } + + return EXIT_SUCCESS; +} diff --git a/host/hackrf-tools/src/hackrf_transfer.c b/host/hackrf-tools/src/hackrf_transfer.c new file mode 100644 index 00000000..2136eba1 --- /dev/null +++ b/host/hackrf-tools/src/hackrf_transfer.c @@ -0,0 +1,668 @@ +/* + * 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 +#include +#include + +#include +#include +#include +#include + +#ifdef _WIN32 +#include +#else +#include +#endif + +#include +#include + +#define FD_BUFFER_SIZE (8*1024) + +#define FREQ_ONE_MHZ (1000000ull) + +#define DEFAULT_FREQ_HZ (900000000ull) /* 900MHz */ +#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 */ + +#define BASEBAND_FILTER_BW_MIN (1750000) /* 1.75 MHz min value */ +#define BASEBAND_FILTER_BW_MAX (28000000) /* 28 MHz max value */ + +#if defined _WIN32 + #define sleep(a) Sleep( (a*1000) ) +#endif + +/* WAVE or RIFF WAVE file format containing IQ 2x8bits data for HackRF compatible with SDR# Wav IQ file */ +typedef struct +{ + char groupID[4]; /* 'RIFF' */ + uint32_t size; /* File size + 8bytes */ + char riffType[4]; /* 'WAVE'*/ +} t_WAVRIFF_hdr; + +#define FormatID "fmt " /* chunkID for Format Chunk. NOTE: There is a space at the end of this ID. */ + +typedef struct { + char chunkID[4]; /* 'fmt ' */ + uint32_t chunkSize; /* 16 fixed */ + + uint16_t wFormatTag; /* 1 fixed */ + uint16_t wChannels; /* 2 fixed */ + uint32_t dwSamplesPerSec; /* Freq Hz sampling */ + uint32_t dwAvgBytesPerSec; /* Freq Hz sampling x 2 */ + uint16_t wBlockAlign; /* 2 fixed */ + uint16_t wBitsPerSample; /* 8 fixed */ +} t_FormatChunk; + +typedef struct +{ + char chunkID[4]; /* 'data' */ + uint32_t chunkSize; /* Size of data in bytes */ + /* Samples I(8bits) then Q(8bits), I, Q ... */ +} t_DataChunk; + +typedef struct +{ + t_WAVRIFF_hdr hdr; + t_FormatChunk fmt_chunk; + t_DataChunk data_chunk; +} t_wav_file_hdr; + +t_wav_file_hdr wave_file_hdr = +{ + /* t_WAVRIFF_hdr */ + { + { 'R', 'I', 'F', 'F' }, /* groupID */ + 0, /* size to update later */ + { 'W', 'A', 'V', 'E' } + }, + /* t_FormatChunk */ + { + { 'f', 'm', 't', ' ' }, /* char chunkID[4]; */ + 16, /* uint32_t chunkSize; */ + 1, /* uint16_t wFormatTag; 1 fixed */ + 2, /* uint16_t wChannels; 2 fixed */ + 0, /* uint32_t dwSamplesPerSec; Freq Hz sampling to update later */ + 0, /* uint32_t dwAvgBytesPerSec; Freq Hz sampling x 2 to update later */ + 2, /* uint16_t wBlockAlign; 2 fixed */ + 8, /* uint16_t wBitsPerSample; 8 fixed */ + }, + /* t_DataChunk */ + { + { 'd', 'a', 't', 'a' }, /* char chunkID[4]; */ + 0, /* uint32_t chunkSize; to update later */ + } +}; + +typedef enum { + TRANSCEIVER_MODE_OFF = 0, + TRANSCEIVER_MODE_RX = 1, + TRANSCEIVER_MODE_TX = 2 +} transceiver_mode_t; +static transceiver_mode_t transceiver_mode = TRANSCEIVER_MODE_RX; + +static float +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 parse_u64(char* s, uint64_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 unsigned long long u64_value = strtoull(s, &s_end, base); + if( (s != s_end) && (*s_end == 0) ) { + *value = u64_value; + return HACKRF_SUCCESS; + } else { + return HACKRF_ERROR_INVALID_PARAM; + } +} + +int parse_u32(char* s, uint32_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 unsigned long ulong_value = strtoul(s, &s_end, base); + if( (s != s_end) && (*s_end == 0) ) { + *value = ulong_value; + return HACKRF_SUCCESS; + } else { + return HACKRF_ERROR_INVALID_PARAM; + } +} + +volatile bool do_exit = false; + +FILE* fd = NULL; +volatile uint32_t byte_count = 0; + +bool receive = false; +bool receive_wav = false; + +bool transmit = false; +struct timeval time_start; +struct timeval t_start; + +bool freq = false; +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; + +bool baseband_filter_bw = false; +uint32_t baseband_filter_bw_hz = 0; + +int rx_callback(hackrf_transfer* transfer) { + int bytes_to_write; + + if( fd != NULL ) + { + byte_count += transfer->valid_length; + bytes_to_write = transfer->valid_length; + if (limit_num_samples) { + if (bytes_to_write >= bytes_to_xfer) { + bytes_to_write = bytes_to_xfer; + } + bytes_to_xfer -= bytes_to_write; + } + const ssize_t bytes_written = fwrite(transfer->buffer, 1, bytes_to_write, fd); + if ((bytes_written != bytes_to_write) + || (limit_num_samples && (bytes_to_xfer == 0))) { + fclose(fd); + fd = NULL; + return -1; + } else { + return 0; + } + } else { + return -1; + } +} + +int tx_callback(hackrf_transfer* transfer) { + int bytes_to_read; + + if( fd != NULL ) + { + byte_count += transfer->valid_length; + bytes_to_read = transfer->valid_length; + if (limit_num_samples) { + if (bytes_to_read >= bytes_to_xfer) { + /* + * In this condition, we probably tx some of the previous + * buffer contents at the end. :-( + */ + bytes_to_read = bytes_to_xfer; + } + bytes_to_xfer -= bytes_to_read; + } + const ssize_t bytes_read = fread(transfer->buffer, 1, bytes_to_read, fd); + if ((bytes_read != bytes_to_read) + || (limit_num_samples && (bytes_to_xfer == 0))) { + fclose(fd); + fd = NULL; + return -1; + } else { + return 0; + } + } else { + return -1; + } +} + +static void usage() { + printf("Usage:\n"); + printf("\t-w # Receive data into file with WAV header and automatic name.\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 [%lluMHz, %lluMHz[.\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 %lldMHz).\n", DEFAULT_SAMPLE_RATE_HZ/FREQ_ONE_MHZ); + printf("\t[-n num_samples] # Number of samples to transfer (default is unlimited).\n"); + printf("\t[-b baseband_filter_bw_hz] # Set baseband filter bandwidth in MHz.\n\tPossible values: 1.75/2.5/3.5/5/5.5/6/7/8/9/10/12/14/15/20/24/28MHz, default < sample_rate_hz.\n" ); +} + +static hackrf_device* device = NULL; + +void sigint_callback_handler(int signum) +{ + fprintf(stdout, "Caught signal %d\n", signum); + do_exit = true; +} + +#define PATH_FILE_MAX_LEN (FILENAME_MAX) +#define DATE_TIME_MAX_LEN (32) + +int main(int argc, char** argv) { + int opt; + char path_file[PATH_FILE_MAX_LEN]; + char date_time[DATE_TIME_MAX_LEN]; + const char* path = NULL; + int result; + time_t rawtime; + struct tm * timeinfo; + long int file_pos; + int exit_code = EXIT_SUCCESS; + + while( (opt = getopt(argc, argv, "wr:t:f:a:s:n:b:")) != EOF ) + { + result = HACKRF_SUCCESS; + switch( opt ) + { + case 'w': + receive_wav = true; + break; + + case 'r': + receive = true; + path = optarg; + break; + + case 't': + transmit = true; + path = optarg; + break; + + case 'f': + freq = true; + result = parse_u64(optarg, &freq_hz); + break; + + case 'a': + amp = true; + 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 * 2ull; + break; + + case 'b': + baseband_filter_bw = true; + result = parse_u32(optarg, &baseband_filter_bw_hz); + break; + + default: + printf("unknown argument '-%c %s'\n", opt, optarg); + usage(); + return EXIT_FAILURE; + } + + if( result != HACKRF_SUCCESS ) { + printf("argument error: '-%c %s' %s (%d)\n", opt, optarg, hackrf_error_name(result), result); + usage(); + return EXIT_FAILURE; + } + } + + 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; + } + + if( freq ) { + if( (freq_hz >= FREQ_MAX_HZ) || (freq_hz < FREQ_MIN_HZ) ) + { + printf("argument error: set_freq_hz shall be between [%llu, %llu[.\n", FREQ_MIN_HZ, FREQ_MAX_HZ); + usage(); + return EXIT_FAILURE; + } + }else + { + /* Use default freq */ + freq_hz = DEFAULT_FREQ_HZ; + } + + if( amp ) { + if( amp_enable > 1 ) + { + printf("argument error: set_amp shall be 0 or 1.\n"); + usage(); + return EXIT_FAILURE; + } + } + + if( sample_rate == false ) + { + sample_rate_hz = DEFAULT_SAMPLE_RATE_HZ; + } + + if( baseband_filter_bw ) + { + /* Compute nearest freq for bw filter */ + baseband_filter_bw_hz = hackrf_compute_baseband_filter_bw(baseband_filter_bw_hz); + }else + { + /* Compute default value depending on sample rate */ + baseband_filter_bw_hz = hackrf_compute_baseband_filter_bw_round_down_lt(sample_rate_hz); + } + + if (baseband_filter_bw_hz > BASEBAND_FILTER_BW_MAX) { + printf("argument error: baseband_filter_bw_hz must be less or equal to %u Hz/%.03f MHz\n", + BASEBAND_FILTER_BW_MAX, (float)(BASEBAND_FILTER_BW_MAX/FREQ_ONE_MHZ)); + usage(); + return EXIT_FAILURE; + } + + if (baseband_filter_bw_hz < BASEBAND_FILTER_BW_MIN) { + printf("argument error: baseband_filter_bw_hz must be greater or equal to %u Hz/%.03f MHz\n", + BASEBAND_FILTER_BW_MIN, (float)(BASEBAND_FILTER_BW_MIN/FREQ_ONE_MHZ)); + usage(); + return EXIT_FAILURE; + } + + if( (transmit == false) && (receive == receive_wav) ) + { + printf("receive -r and receive_wav -w options are mutually exclusive\n"); + usage(); + return EXIT_FAILURE; + } + + if( receive_wav == false ) + { + if( transmit == receive ) + { + if( transmit == true ) + { + printf("receive -r and transmit -t options are mutually exclusive\n"); + } else + { + printf("specify either transmit -t or receive -r or receive_wav -w option\n"); + } + usage(); + return EXIT_FAILURE; + } + } + + if( receive ) { + transceiver_mode = TRANSCEIVER_MODE_RX; + } + + if( transmit ) { + transceiver_mode = TRANSCEIVER_MODE_TX; + } + + if( receive_wav ) + { + time (&rawtime); + timeinfo = localtime (&rawtime); + transceiver_mode = TRANSCEIVER_MODE_RX; + /* File format HackRF Year(2013), Month(11), Day(28), Hour Min Sec+Z, Freq kHz, IQ.wav */ + strftime(date_time, DATE_TIME_MAX_LEN, "%Y%m%d_%H%M%S", timeinfo); + snprintf(path_file, PATH_FILE_MAX_LEN, "HackRF_%sZ_%ukHz_IQ.wav", date_time, (uint32_t)(freq_hz/(1000ull)) ); + path = path_file; + printf("Receive wav file: %s\n", path); + } + + if( path == NULL ) { + printf("specify a path to a file to transmit/receive\n"); + usage(); + return EXIT_FAILURE; + } + + result = hackrf_init(); + if( result != HACKRF_SUCCESS ) { + printf("hackrf_init() failed: %s (%d)\n", hackrf_error_name(result), result); + usage(); + return EXIT_FAILURE; + } + + result = hackrf_open(&device); + if( result != HACKRF_SUCCESS ) { + printf("hackrf_open() failed: %s (%d)\n", hackrf_error_name(result), result); + usage(); + return EXIT_FAILURE; + } + + if( transceiver_mode == TRANSCEIVER_MODE_RX ) + { + fd = fopen(path, "wb"); + } else { + fd = fopen(path, "rb"); + } + + if( fd == NULL ) { + printf("Failed to open file: %s\n", path); + return EXIT_FAILURE; + } + /* Change fd buffer to have bigger one to store or read data on/to HDD */ + result = setvbuf(fd , NULL , _IOFBF , FD_BUFFER_SIZE); + if( result != 0 ) { + printf("setvbuf() failed: %d\n", result); + usage(); + return EXIT_FAILURE; + } + + /* Write Wav header */ + if( receive_wav ) + { + fwrite(&wave_file_hdr, 1, sizeof(t_wav_file_hdr), fd); + } + + 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); + + printf("call hackrf_sample_rate_set(%u Hz/%.03f MHz)\n", sample_rate_hz,((float)sample_rate_hz/(float)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); + usage(); + return EXIT_FAILURE; + } + + printf("call hackrf_baseband_filter_bandwidth_set(%d Hz/%.03f MHz)\n", + baseband_filter_bw_hz, ((float)baseband_filter_bw_hz/(float)FREQ_ONE_MHZ)); + result = hackrf_baseband_filter_bandwidth_set(device, baseband_filter_bw_hz); + if( result != HACKRF_SUCCESS ) { + printf("hackrf_baseband_filter_bandwidth_set() failed: %s (%d)\n", hackrf_error_name(result), result); + usage(); + return EXIT_FAILURE; + } + + if( transceiver_mode == TRANSCEIVER_MODE_RX ) { + result = hackrf_start_rx(device, rx_callback, NULL); + } else { + result = hackrf_start_tx(device, tx_callback, NULL); + } + if( result != HACKRF_SUCCESS ) { + printf("hackrf_start_?x() failed: %s (%d)\n", hackrf_error_name(result), result); + usage(); + return EXIT_FAILURE; + } + + printf("call hackrf_set_freq(%llu Hz/%.03f MHz)\n", freq_hz, ((float)freq_hz/(float)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); + usage(); + return EXIT_FAILURE; + } + + if( amp ) { + printf("call hackrf_set_amp_enable(%u)\n", amp_enable); + result = hackrf_set_amp_enable(device, (uint8_t)amp_enable); + if( result != HACKRF_SUCCESS ) { + printf("hackrf_set_amp_enable() failed: %s (%d)\n", hackrf_error_name(result), result); + usage(); + return EXIT_FAILURE; + } + } + + 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); + + printf("Stop with Ctrl-C\n"); + while( (hackrf_is_streaming(device) == HACKRF_TRUE) && + (do_exit == false) ) + { + sleep(1); + + 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) ); + + time_start = time_now; + + if (byte_count_now == 0) { + exit_code = EXIT_FAILURE; + printf("\nCouldn't transfer any bytes for one second.\n"); + break; + } + } + + result = hackrf_is_streaming(device); + if (do_exit) + { + printf("\nUser cancel, exiting...\n"); + } else { + printf("\nExiting... hackrf_is_streaming() result: %s (%d)\n", hackrf_error_name(result), result); + } + + 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"); + } + + if(fd != NULL) + { + if( receive_wav ) + { + /* Get size of file */ + file_pos = ftell(fd); + /* Update Wav Header */ + wave_file_hdr.hdr.size = file_pos+8; + wave_file_hdr.fmt_chunk.dwSamplesPerSec = sample_rate_hz; + wave_file_hdr.fmt_chunk.dwAvgBytesPerSec = wave_file_hdr.fmt_chunk.dwSamplesPerSec*2; + wave_file_hdr.data_chunk.chunkSize = file_pos - sizeof(t_wav_file_hdr); + /* Overwrite header with updated data */ + rewind(fd); + fwrite(&wave_file_hdr, 1, sizeof(t_wav_file_hdr), fd); + } + fclose(fd); + fd = NULL; + printf("fclose(fd) done\n"); + } + printf("exit\n"); + return exit_code; +} From 221337793cd8d5b4af6b4cb489ac9eaaeeaf6d56 Mon Sep 17 00:00:00 2001 From: TitanMKD Date: Fri, 17 May 2013 01:14:34 +0200 Subject: [PATCH 3/3] Moved host/libhackrf/examples to host/hackrf-tools --- host/libhackrf/CMakeLists.txt | 83 ++- host/libhackrf/examples/CMakeLists.txt | 44 -- host/libhackrf/examples/hackrf_cpldjtag.c | 198 ------- host/libhackrf/examples/hackrf_info.c | 95 --- host/libhackrf/examples/hackrf_max2837.c | 176 ------ host/libhackrf/examples/hackrf_rffc5071.c | 178 ------ host/libhackrf/examples/hackrf_si5351c.c | 224 -------- host/libhackrf/examples/hackrf_spiflash.c | 275 --------- host/libhackrf/examples/hackrf_transfer.c | 668 ---------------------- 9 files changed, 41 insertions(+), 1900 deletions(-) delete mode 100644 host/libhackrf/examples/CMakeLists.txt delete mode 100644 host/libhackrf/examples/hackrf_cpldjtag.c delete mode 100644 host/libhackrf/examples/hackrf_info.c delete mode 100644 host/libhackrf/examples/hackrf_max2837.c delete mode 100644 host/libhackrf/examples/hackrf_rffc5071.c delete mode 100644 host/libhackrf/examples/hackrf_si5351c.c delete mode 100644 host/libhackrf/examples/hackrf_spiflash.c delete mode 100644 host/libhackrf/examples/hackrf_transfer.c diff --git a/host/libhackrf/CMakeLists.txt b/host/libhackrf/CMakeLists.txt index 000a4326..ec3dd39e 100644 --- a/host/libhackrf/CMakeLists.txt +++ b/host/libhackrf/CMakeLists.txt @@ -1,42 +1,41 @@ -# 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. - -project(libhackrf) -set(MAJOR_VERSION 0) -set(MINOR_VERSION 1) -set(PACKAGE libhackrf) -set(VERSION_STRING ${MAJOR_VERSION}.${MINOR_VERSION}) -set(VERSION ${VERSION_STRING}) -set(CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}") - -cmake_minimum_required(VERSION 2.8) - -add_definitions(-Wall) -set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -std=c99") -set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++98") - -find_package(USB1 REQUIRED) -include_directories(${LIBUSB_INCLUDE_DIR}) - -add_subdirectory(src) -add_subdirectory(examples) - +# 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. + +project(libhackrf) +set(MAJOR_VERSION 0) +set(MINOR_VERSION 1) +set(PACKAGE libhackrf) +set(VERSION_STRING ${MAJOR_VERSION}.${MINOR_VERSION}) +set(VERSION ${VERSION_STRING}) +set(CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}") + +cmake_minimum_required(VERSION 2.8) + +add_definitions(-Wall) +set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -std=c99") +set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++98") + +find_package(USB1 REQUIRED) +include_directories(${LIBUSB_INCLUDE_DIR}) + +add_subdirectory(src) + diff --git a/host/libhackrf/examples/CMakeLists.txt b/host/libhackrf/examples/CMakeLists.txt deleted file mode 100644 index 09f0acd2..00000000 --- a/host/libhackrf/examples/CMakeLists.txt +++ /dev/null @@ -1,44 +0,0 @@ -# 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) - add_executable(hackrf_spiflash hackrf_spiflash.c) - add_executable(hackrf_cpldjtag hackrf_cpldjtag.c) - add_executable(hackrf_info hackrf_info.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) - target_link_libraries(hackrf_spiflash hackrf) - target_link_libraries(hackrf_cpldjtag hackrf) - target_link_libraries(hackrf_info hackrf) - - include_directories(BEFORE ${CMAKE_SOURCE_DIR}/src) -endif(EXAMPLES) diff --git a/host/libhackrf/examples/hackrf_cpldjtag.c b/host/libhackrf/examples/hackrf_cpldjtag.c deleted file mode 100644 index da4293e0..00000000 --- a/host/libhackrf/examples/hackrf_cpldjtag.c +++ /dev/null @@ -1,198 +0,0 @@ -/* - * Copyright 2012 Jared Boone - * Copyright 2013 Benjamin Vernoux - * Copyright 2013 Michael Ossmann - * - * 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 -#include - -/* input file shouldn't be any longer than this */ -#define MAX_XSVF_LENGTH 0x10000 -#define PACKET_LEN 4096 - -uint8_t data[MAX_XSVF_LENGTH]; - -static struct option long_options[] = { - { "xsvf", required_argument, 0, 'x' }, - { 0, 0, 0, 0 }, -}; - -int parse_int(char* s, uint32_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; - } -} - -static void usage() -{ - printf("Usage:\n"); - printf("\t-x : XSVF file to be written to CPLD.\n"); -} - -int main(int argc, char** argv) -{ - int opt; - uint32_t length = 0; - uint32_t total_length = 0; - const char* path = NULL; - hackrf_device* device = NULL; - int result = HACKRF_SUCCESS; - int option_index = 0; - FILE* fd = NULL; - ssize_t bytes_read; - uint16_t xfer_len = 0; - uint8_t* pdata = &data[0]; - - while ((opt = getopt_long(argc, argv, "x:", long_options, - &option_index)) != EOF) { - switch (opt) { - case 'x': - path = optarg; - break; - - default: - usage(); - return EXIT_FAILURE; - } - - if (result != HACKRF_SUCCESS) { - fprintf(stderr, "argument error: %s (%d)\n", - hackrf_error_name(result), result); - usage(); - return EXIT_FAILURE; - } - } - - if (path == NULL) { - fprintf(stderr, "Specify a path to a file.\n"); - usage(); - return EXIT_FAILURE; - } - - fd = fopen(path, "rb"); - if (fd == NULL) - { - fprintf(stderr, "Failed to open file: %s\n", path); - return EXIT_FAILURE; - } - /* Get size of the file */ - fseek(fd, 0, SEEK_END); /* Not really portable but work on major OS Linux/Win32 */ - length = ftell(fd); - /* Move to start */ - rewind(fd); - printf("File size %d bytes.\n", length); - - if (length > MAX_XSVF_LENGTH) { - fprintf(stderr, "XSVF file too large.\n"); - usage(); - return EXIT_FAILURE; - } - - total_length = length; - bytes_read = fread(data, 1, total_length, fd); - if (bytes_read != total_length) - { - fprintf(stderr, "Failed to read all bytes (read %d bytes instead of %d bytes).\n", - (int)bytes_read, total_length); - fclose(fd); - fd = NULL; - return EXIT_FAILURE; - } - - result = hackrf_init(); - if (result != HACKRF_SUCCESS) { - fprintf(stderr, "hackrf_init() failed: %s (%d)\n", - hackrf_error_name(result), result); - return EXIT_FAILURE; - } - - result = hackrf_open(&device); - if (result != HACKRF_SUCCESS) { - fprintf(stderr, "hackrf_open() failed: %s (%d)\n", - hackrf_error_name(result), result); - return EXIT_FAILURE; - } - - printf("LED1/2/3 blinking means CPLD program success.\nLED3/RED steady means error.\n"); - printf("Wait message 'Write finished' or in case of LED3/RED steady, Power OFF/Disconnect the Jawbreaker.\n"); - while( length ) - { - xfer_len = (length > PACKET_LEN) ? PACKET_LEN : length; - result = hackrf_cpld_write(device, xfer_len, pdata, total_length); - if (result != HACKRF_SUCCESS) - { - fprintf(stderr, "hackrf_cpld_write() failed: %s (%d)\n", - hackrf_error_name(result), result); - fclose(fd); - fd = NULL; - return EXIT_FAILURE; - } - pdata += xfer_len; - length -= xfer_len; - printf("hackrf_cpld_write() Writing %d bytes, remaining %d bytes.\n", - xfer_len, length); - } - printf("Write finished.\n"); - printf("Please Power OFF/Disconnect the Jawbreaker.\n"); - fflush(stdout); - - result = hackrf_close(device); - if( result != HACKRF_SUCCESS ) - { - fprintf(stderr, "hackrf_close() failed: %s (%d)\n", - hackrf_error_name(result), result); - fclose(fd); - fd = NULL; - return EXIT_FAILURE; - } - - hackrf_exit(); - - if (fd != NULL) { - fclose(fd); - } - - return EXIT_SUCCESS; -} diff --git a/host/libhackrf/examples/hackrf_info.c b/host/libhackrf/examples/hackrf_info.c deleted file mode 100644 index d83b9696..00000000 --- a/host/libhackrf/examples/hackrf_info.c +++ /dev/null @@ -1,95 +0,0 @@ -/* - * Copyright 2012 Jared Boone - * Copyright 2013 Benjamin Vernoux - * Copyright 2013 Michael Ossmann - * - * 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 - -int main(int argc, char** argv) -{ - hackrf_device* device = NULL; - int result = HACKRF_SUCCESS; - uint8_t board_id = BOARD_ID_INVALID; - char version[255 + 1]; - read_partid_serialno_t read_partid_serialno; - - result = hackrf_init(); - if (result != HACKRF_SUCCESS) { - fprintf(stderr, "hackrf_init() failed: %s (%d)\n", - hackrf_error_name(result), result); - return EXIT_FAILURE; - } - - result = hackrf_open(&device); - if (result != HACKRF_SUCCESS) { - fprintf(stderr, "hackrf_open() failed: %s (%d)\n", - hackrf_error_name(result), result); - return EXIT_FAILURE; - } - - printf("Found HackRF board.\n"); - - result = hackrf_board_id_read(device, &board_id); - if (result != HACKRF_SUCCESS) { - fprintf(stderr, "hackrf_board_id_read() failed: %s (%d)\n", - hackrf_error_name(result), result); - return EXIT_FAILURE; - } - printf("Board ID Number: %d (%s)\n", board_id, - hackrf_board_id_name(board_id)); - - result = hackrf_version_string_read(device, &version[0], 255); - if (result != HACKRF_SUCCESS) { - fprintf(stderr, "hackrf_version_string_read() failed: %s (%d)\n", - hackrf_error_name(result), result); - return EXIT_FAILURE; - } - printf("Firmware Version: %s\n", version); - - result = hackrf_board_partid_serialno_read(device, &read_partid_serialno); - if (result != HACKRF_SUCCESS) { - fprintf(stderr, "hackrf_board_partid_serialno_read() failed: %s (%d)\n", - hackrf_error_name(result), result); - return EXIT_FAILURE; - } - printf("Part ID Number: 0x%08x 0x%08x\n", - read_partid_serialno.part_id[0], - read_partid_serialno.part_id[1]); - printf("Serial Number: 0x%08x 0x%08x 0x%08x 0x%08x\n", - read_partid_serialno.serial_no[0], - read_partid_serialno.serial_no[1], - read_partid_serialno.serial_no[2], - read_partid_serialno.serial_no[3]); - - result = hackrf_close(device); - if (result != HACKRF_SUCCESS) { - fprintf(stderr, "hackrf_close() failed: %s (%d)\n", - hackrf_error_name(result), result); - return EXIT_FAILURE; - } - - hackrf_exit(); - - return EXIT_SUCCESS; -} diff --git a/host/libhackrf/examples/hackrf_max2837.c b/host/libhackrf/examples/hackrf_max2837.c deleted file mode 100644 index e780dba6..00000000 --- a/host/libhackrf/examples/hackrf_max2837.c +++ /dev/null @@ -1,176 +0,0 @@ -/* - * 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. - */ - -#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 22 # writes register 10 with 22 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_max2837_read(device, register_number, ®ister_value); - - if( result == HACKRF_SUCCESS ) { - printf("[%2d] -> 0x%03x\n", register_number, register_value); - } else { - printf("hackrf_max2837_read() failed: %s (%d)\n", hackrf_error_name(result), result); - } - - return result; -} - -int dump_registers(hackrf_device* device) { - uint16_t register_number; - int result = HACKRF_SUCCESS; - - for(register_number=0; register_number<32; 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_max2837_write(device, register_number, register_value); - - if( result == HACKRF_SUCCESS ) { - printf("0x%03x -> [%2d]\n", register_value, register_number); - } else { - printf("hackrf_max2837_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); - 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_rffc5071.c b/host/libhackrf/examples/hackrf_rffc5071.c deleted file mode 100644 index 15ca6e71..00000000 --- a/host/libhackrf/examples/hackrf_rffc5071.c +++ /dev/null @@ -1,178 +0,0 @@ -/* - * 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) { - uint16_t register_number; - int result = HACKRF_SUCCESS; - - for(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_si5351c.c b/host/libhackrf/examples/hackrf_si5351c.c deleted file mode 100644 index d5373df6..00000000 --- a/host/libhackrf/examples/hackrf_si5351c.c +++ /dev/null @@ -1,224 +0,0 @@ -/* - * 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. - */ - -#include - -#include -#include -#include - -static void usage() { - printf("\nUsage:\n"); - printf("\t-c, --config: print textual configuration information\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 22 # writes register 10 with 22 decimal\n"); -} - -static struct option long_options[] = { - { "config", no_argument, 0, 'c' }, - { "register", required_argument, 0, 'n' }, - { "write", required_argument, 0, 'w' }, - { "read", no_argument, 0, 'r' }, - { 0, 0, 0, 0 }, -}; - -int parse_int(char* const s, uint16_t* const value) { - char* s_end = s; - const long long_value = strtol(s, &s_end, 10); - 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_si5351c_read(device, register_number, ®ister_value); - - if( result == HACKRF_SUCCESS ) { - printf("[%3d] -> 0x%02x\n", register_number, register_value); - } else { - printf("hackrf_max2837_read() failed: %s (%d)\n", hackrf_error_name(result), result); - } - - return result; -} - -int dump_registers(hackrf_device* device) { - uint16_t register_number; - int result = HACKRF_SUCCESS; - - for(register_number=0; register_number<256; 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_si5351c_write(device, register_number, register_value); - - if( result == HACKRF_SUCCESS ) { - printf("0x%2x -> [%3d]\n", register_value, register_number); - } else { - printf("hackrf_max2837_write() failed: %s (%d)\n", hackrf_error_name(result), result); - } - - return result; -} - -#define REGISTER_INVALID 32767 - -int dump_multisynth_config(hackrf_device* device, const uint_fast8_t ms_number) { - uint_fast8_t i; - uint_fast8_t reg_base; - uint16_t parameters[8]; - - reg_base = 42 + (ms_number * 8); - for(i=0; i<8; i++) { - uint_fast8_t reg_number = reg_base + i; - int result = hackrf_si5351c_read(device, reg_number, ¶meters[i]); - if( result != HACKRF_SUCCESS ) { - return result; - } - } - - const uint32_t p1 = - (parameters[2] & 0x03 << 16) - | (parameters[3] << 8) - | parameters[4] - ; - const uint32_t p2 = - (parameters[5] & 0x0F << 16) - | (parameters[6] << 8) - | parameters[7] - ; - const uint32_t p3 = - (parameters[5] & 0xF0 << 12) - | (parameters[0] << 8) - | parameters[1] - ; - const uint32_t r_div = - (parameters[2] >> 4) & 0x7 - ; - - printf("MS%d:", ms_number); - printf("\tp1 = %u\n", p1); - printf("\tp2 = %u\n", p2); - printf("\tp3 = %u\n", p3); - printf("\toutput divider = %u\n", 1 << r_div); - - return HACKRF_SUCCESS; -} - -int dump_configuration(hackrf_device* device) { - uint_fast8_t ms_number; - int result; - - for(ms_number=0; ms_number<8; ms_number++) { - result = dump_multisynth_config(device, ms_number); - if( result != HACKRF_SUCCESS ) { - return result; - } - } - - return HACKRF_SUCCESS; -} - -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, "cn: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; - - case 'c': - dump_configuration(device); - break; - - default: - usage(); - } - - if( result != HACKRF_SUCCESS ) { - printf("argument error: %s (%d)\n", hackrf_error_name(result), result); - 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_spiflash.c b/host/libhackrf/examples/hackrf_spiflash.c deleted file mode 100644 index 4e42d870..00000000 --- a/host/libhackrf/examples/hackrf_spiflash.c +++ /dev/null @@ -1,275 +0,0 @@ -/* - * Copyright 2012 Jared Boone - * Copyright 2013 Benjamin Vernoux - * Copyright 2013 Michael Ossmann - * - * 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 -#include -#include - -/* 8 Mbit flash */ -#define MAX_LENGTH 0x100000 - -static struct option long_options[] = { - { "address", required_argument, 0, 'a' }, - { "length", required_argument, 0, 'l' }, - { "read", required_argument, 0, 'r' }, - { "write", required_argument, 0, 'w' }, - { 0, 0, 0, 0 }, -}; - -int parse_u32(char* s, uint32_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 uint32_t u32_value = strtoul(s, &s_end, base); - if ((s != s_end) && (*s_end == 0)) { - *value = u32_value; - return HACKRF_SUCCESS; - } else { - return HACKRF_ERROR_INVALID_PARAM; - } -} - -static void usage() -{ - printf("Usage:\n"); - printf("\t-a, --address : starting address (default: 0)\n"); - printf("\t-l, --length : number of bytes to read (default: 0)\n"); - printf("\t-r : Read data into file.\n"); - printf("\t-w : Write data from file.\n"); -} - -int main(int argc, char** argv) -{ - int opt; - uint32_t address = 0; - uint32_t length = 0; - uint32_t tmp_length; - uint16_t xfer_len = 0; - const char* path = NULL; - hackrf_device* device = NULL; - int result = HACKRF_SUCCESS; - int option_index = 0; - static uint8_t data[MAX_LENGTH]; - uint8_t* pdata = &data[0]; - FILE* fd = NULL; - bool read = false; - bool write = false; - - while ((opt = getopt_long(argc, argv, "a:l:r:w:", long_options, - &option_index)) != EOF) { - switch (opt) { - case 'a': - result = parse_u32(optarg, &address); - break; - - case 'l': - result = parse_u32(optarg, &length); - break; - - case 'r': - read = true; - path = optarg; - break; - - case 'w': - write = true; - path = optarg; - break; - - default: - fprintf(stderr, "opt error: %d\n", opt); - usage(); - return EXIT_FAILURE; - } - - if (result != HACKRF_SUCCESS) { - fprintf(stderr, "argument error: %s (%d)\n", - hackrf_error_name(result), result); - usage(); - return EXIT_FAILURE; - } - } - - if (write == read) { - if (write == true) { - fprintf(stderr, "Read and write options are mutually exclusive.\n"); - } else { - fprintf(stderr, "Specify either read or write option.\n"); - } - usage(); - return EXIT_FAILURE; - } - - if (path == NULL) { - fprintf(stderr, "Specify a path to a file.\n"); - usage(); - return EXIT_FAILURE; - } - - if( write ) - { - fd = fopen(path, "rb"); - /* Get size of the file */ - fseek(fd, 0, SEEK_END); /* Not really portable but work on major OS Linux/Win32 */ - length = ftell(fd); - /* Move to start */ - rewind(fd); - printf("File size %d bytes.\n", length); - } - - if (length == 0) { - fprintf(stderr, "Requested transfer of zero bytes.\n"); - if(fd != NULL) - fclose(fd); - usage(); - return EXIT_FAILURE; - } - - if ((length > MAX_LENGTH) || (address > MAX_LENGTH) - || ((address + length) > MAX_LENGTH)) { - fprintf(stderr, "Request exceeds size of flash memory.\n"); - if(fd != NULL) - fclose(fd); - usage(); - return EXIT_FAILURE; - } - - if (read) { - fd = fopen(path, "wb"); - } - - if (fd == NULL) { - fprintf(stderr, "Failed to open file: %s\n", path); - return EXIT_FAILURE; - } - - result = hackrf_init(); - if (result != HACKRF_SUCCESS) { - fprintf(stderr, "hackrf_init() failed: %s (%d)\n", - hackrf_error_name(result), result); - return EXIT_FAILURE; - } - - result = hackrf_open(&device); - if (result != HACKRF_SUCCESS) { - fprintf(stderr, "hackrf_open() failed: %s (%d)\n", - hackrf_error_name(result), result); - return EXIT_FAILURE; - } - - if (read) - { - tmp_length = length; - while (tmp_length) - { - xfer_len = (tmp_length > 256) ? 256 : tmp_length; - printf("Reading %d bytes from 0x%06x.\n", xfer_len, address); - result = hackrf_spiflash_read(device, address, xfer_len, pdata); - if (result != HACKRF_SUCCESS) { - fprintf(stderr, "hackrf_spiflash_read() failed: %s (%d)\n", - hackrf_error_name(result), result); - fclose(fd); - fd = NULL; - return EXIT_FAILURE; - } - address += xfer_len; - pdata += xfer_len; - tmp_length -= xfer_len; - } - const ssize_t bytes_written = fwrite(data, 1, length, fd); - if (bytes_written != length) { - fprintf(stderr, "Failed write to file (wrote %d bytes).\n", - (int)bytes_written); - fclose(fd); - fd = NULL; - return EXIT_FAILURE; - } - } else { - const ssize_t bytes_read = fread(data, 1, length, fd); - if (bytes_read != length) { - fprintf(stderr, "Failed read file (read %d bytes).\n", - (int)bytes_read); - fclose(fd); - fd = NULL; - return EXIT_FAILURE; - } - printf("Erasing SPI flash.\n"); - result = hackrf_spiflash_erase(device); - if (result != HACKRF_SUCCESS) { - fprintf(stderr, "hackrf_spiflash_erase() failed: %s (%d)\n", - hackrf_error_name(result), result); - fclose(fd); - fd = NULL; - return EXIT_FAILURE; - } - while (length) { - xfer_len = (length > 256) ? 256 : length; - printf("Writing %d bytes at 0x%06x.\n", xfer_len, address); - result = hackrf_spiflash_write(device, address, xfer_len, pdata); - if (result != HACKRF_SUCCESS) { - fprintf(stderr, "hackrf_spiflash_write() failed: %s (%d)\n", - hackrf_error_name(result), result); - fclose(fd); - fd = NULL; - return EXIT_FAILURE; - } - address += xfer_len; - pdata += xfer_len; - length -= xfer_len; - } - } - - result = hackrf_close(device); - if (result != HACKRF_SUCCESS) { - fprintf(stderr, "hackrf_close() failed: %s (%d)\n", - hackrf_error_name(result), result); - fclose(fd); - fd = NULL; - return EXIT_FAILURE; - } - - hackrf_exit(); - - if (fd != NULL) { - fclose(fd); - } - - return EXIT_SUCCESS; -} diff --git a/host/libhackrf/examples/hackrf_transfer.c b/host/libhackrf/examples/hackrf_transfer.c deleted file mode 100644 index 2136eba1..00000000 --- a/host/libhackrf/examples/hackrf_transfer.c +++ /dev/null @@ -1,668 +0,0 @@ -/* - * 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 -#include -#include - -#include -#include -#include -#include - -#ifdef _WIN32 -#include -#else -#include -#endif - -#include -#include - -#define FD_BUFFER_SIZE (8*1024) - -#define FREQ_ONE_MHZ (1000000ull) - -#define DEFAULT_FREQ_HZ (900000000ull) /* 900MHz */ -#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 */ - -#define BASEBAND_FILTER_BW_MIN (1750000) /* 1.75 MHz min value */ -#define BASEBAND_FILTER_BW_MAX (28000000) /* 28 MHz max value */ - -#if defined _WIN32 - #define sleep(a) Sleep( (a*1000) ) -#endif - -/* WAVE or RIFF WAVE file format containing IQ 2x8bits data for HackRF compatible with SDR# Wav IQ file */ -typedef struct -{ - char groupID[4]; /* 'RIFF' */ - uint32_t size; /* File size + 8bytes */ - char riffType[4]; /* 'WAVE'*/ -} t_WAVRIFF_hdr; - -#define FormatID "fmt " /* chunkID for Format Chunk. NOTE: There is a space at the end of this ID. */ - -typedef struct { - char chunkID[4]; /* 'fmt ' */ - uint32_t chunkSize; /* 16 fixed */ - - uint16_t wFormatTag; /* 1 fixed */ - uint16_t wChannels; /* 2 fixed */ - uint32_t dwSamplesPerSec; /* Freq Hz sampling */ - uint32_t dwAvgBytesPerSec; /* Freq Hz sampling x 2 */ - uint16_t wBlockAlign; /* 2 fixed */ - uint16_t wBitsPerSample; /* 8 fixed */ -} t_FormatChunk; - -typedef struct -{ - char chunkID[4]; /* 'data' */ - uint32_t chunkSize; /* Size of data in bytes */ - /* Samples I(8bits) then Q(8bits), I, Q ... */ -} t_DataChunk; - -typedef struct -{ - t_WAVRIFF_hdr hdr; - t_FormatChunk fmt_chunk; - t_DataChunk data_chunk; -} t_wav_file_hdr; - -t_wav_file_hdr wave_file_hdr = -{ - /* t_WAVRIFF_hdr */ - { - { 'R', 'I', 'F', 'F' }, /* groupID */ - 0, /* size to update later */ - { 'W', 'A', 'V', 'E' } - }, - /* t_FormatChunk */ - { - { 'f', 'm', 't', ' ' }, /* char chunkID[4]; */ - 16, /* uint32_t chunkSize; */ - 1, /* uint16_t wFormatTag; 1 fixed */ - 2, /* uint16_t wChannels; 2 fixed */ - 0, /* uint32_t dwSamplesPerSec; Freq Hz sampling to update later */ - 0, /* uint32_t dwAvgBytesPerSec; Freq Hz sampling x 2 to update later */ - 2, /* uint16_t wBlockAlign; 2 fixed */ - 8, /* uint16_t wBitsPerSample; 8 fixed */ - }, - /* t_DataChunk */ - { - { 'd', 'a', 't', 'a' }, /* char chunkID[4]; */ - 0, /* uint32_t chunkSize; to update later */ - } -}; - -typedef enum { - TRANSCEIVER_MODE_OFF = 0, - TRANSCEIVER_MODE_RX = 1, - TRANSCEIVER_MODE_TX = 2 -} transceiver_mode_t; -static transceiver_mode_t transceiver_mode = TRANSCEIVER_MODE_RX; - -static float -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 parse_u64(char* s, uint64_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 unsigned long long u64_value = strtoull(s, &s_end, base); - if( (s != s_end) && (*s_end == 0) ) { - *value = u64_value; - return HACKRF_SUCCESS; - } else { - return HACKRF_ERROR_INVALID_PARAM; - } -} - -int parse_u32(char* s, uint32_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 unsigned long ulong_value = strtoul(s, &s_end, base); - if( (s != s_end) && (*s_end == 0) ) { - *value = ulong_value; - return HACKRF_SUCCESS; - } else { - return HACKRF_ERROR_INVALID_PARAM; - } -} - -volatile bool do_exit = false; - -FILE* fd = NULL; -volatile uint32_t byte_count = 0; - -bool receive = false; -bool receive_wav = false; - -bool transmit = false; -struct timeval time_start; -struct timeval t_start; - -bool freq = false; -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; - -bool baseband_filter_bw = false; -uint32_t baseband_filter_bw_hz = 0; - -int rx_callback(hackrf_transfer* transfer) { - int bytes_to_write; - - if( fd != NULL ) - { - byte_count += transfer->valid_length; - bytes_to_write = transfer->valid_length; - if (limit_num_samples) { - if (bytes_to_write >= bytes_to_xfer) { - bytes_to_write = bytes_to_xfer; - } - bytes_to_xfer -= bytes_to_write; - } - const ssize_t bytes_written = fwrite(transfer->buffer, 1, bytes_to_write, fd); - if ((bytes_written != bytes_to_write) - || (limit_num_samples && (bytes_to_xfer == 0))) { - fclose(fd); - fd = NULL; - return -1; - } else { - return 0; - } - } else { - return -1; - } -} - -int tx_callback(hackrf_transfer* transfer) { - int bytes_to_read; - - if( fd != NULL ) - { - byte_count += transfer->valid_length; - bytes_to_read = transfer->valid_length; - if (limit_num_samples) { - if (bytes_to_read >= bytes_to_xfer) { - /* - * In this condition, we probably tx some of the previous - * buffer contents at the end. :-( - */ - bytes_to_read = bytes_to_xfer; - } - bytes_to_xfer -= bytes_to_read; - } - const ssize_t bytes_read = fread(transfer->buffer, 1, bytes_to_read, fd); - if ((bytes_read != bytes_to_read) - || (limit_num_samples && (bytes_to_xfer == 0))) { - fclose(fd); - fd = NULL; - return -1; - } else { - return 0; - } - } else { - return -1; - } -} - -static void usage() { - printf("Usage:\n"); - printf("\t-w # Receive data into file with WAV header and automatic name.\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 [%lluMHz, %lluMHz[.\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 %lldMHz).\n", DEFAULT_SAMPLE_RATE_HZ/FREQ_ONE_MHZ); - printf("\t[-n num_samples] # Number of samples to transfer (default is unlimited).\n"); - printf("\t[-b baseband_filter_bw_hz] # Set baseband filter bandwidth in MHz.\n\tPossible values: 1.75/2.5/3.5/5/5.5/6/7/8/9/10/12/14/15/20/24/28MHz, default < sample_rate_hz.\n" ); -} - -static hackrf_device* device = NULL; - -void sigint_callback_handler(int signum) -{ - fprintf(stdout, "Caught signal %d\n", signum); - do_exit = true; -} - -#define PATH_FILE_MAX_LEN (FILENAME_MAX) -#define DATE_TIME_MAX_LEN (32) - -int main(int argc, char** argv) { - int opt; - char path_file[PATH_FILE_MAX_LEN]; - char date_time[DATE_TIME_MAX_LEN]; - const char* path = NULL; - int result; - time_t rawtime; - struct tm * timeinfo; - long int file_pos; - int exit_code = EXIT_SUCCESS; - - while( (opt = getopt(argc, argv, "wr:t:f:a:s:n:b:")) != EOF ) - { - result = HACKRF_SUCCESS; - switch( opt ) - { - case 'w': - receive_wav = true; - break; - - case 'r': - receive = true; - path = optarg; - break; - - case 't': - transmit = true; - path = optarg; - break; - - case 'f': - freq = true; - result = parse_u64(optarg, &freq_hz); - break; - - case 'a': - amp = true; - 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 * 2ull; - break; - - case 'b': - baseband_filter_bw = true; - result = parse_u32(optarg, &baseband_filter_bw_hz); - break; - - default: - printf("unknown argument '-%c %s'\n", opt, optarg); - usage(); - return EXIT_FAILURE; - } - - if( result != HACKRF_SUCCESS ) { - printf("argument error: '-%c %s' %s (%d)\n", opt, optarg, hackrf_error_name(result), result); - usage(); - return EXIT_FAILURE; - } - } - - 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; - } - - if( freq ) { - if( (freq_hz >= FREQ_MAX_HZ) || (freq_hz < FREQ_MIN_HZ) ) - { - printf("argument error: set_freq_hz shall be between [%llu, %llu[.\n", FREQ_MIN_HZ, FREQ_MAX_HZ); - usage(); - return EXIT_FAILURE; - } - }else - { - /* Use default freq */ - freq_hz = DEFAULT_FREQ_HZ; - } - - if( amp ) { - if( amp_enable > 1 ) - { - printf("argument error: set_amp shall be 0 or 1.\n"); - usage(); - return EXIT_FAILURE; - } - } - - if( sample_rate == false ) - { - sample_rate_hz = DEFAULT_SAMPLE_RATE_HZ; - } - - if( baseband_filter_bw ) - { - /* Compute nearest freq for bw filter */ - baseband_filter_bw_hz = hackrf_compute_baseband_filter_bw(baseband_filter_bw_hz); - }else - { - /* Compute default value depending on sample rate */ - baseband_filter_bw_hz = hackrf_compute_baseband_filter_bw_round_down_lt(sample_rate_hz); - } - - if (baseband_filter_bw_hz > BASEBAND_FILTER_BW_MAX) { - printf("argument error: baseband_filter_bw_hz must be less or equal to %u Hz/%.03f MHz\n", - BASEBAND_FILTER_BW_MAX, (float)(BASEBAND_FILTER_BW_MAX/FREQ_ONE_MHZ)); - usage(); - return EXIT_FAILURE; - } - - if (baseband_filter_bw_hz < BASEBAND_FILTER_BW_MIN) { - printf("argument error: baseband_filter_bw_hz must be greater or equal to %u Hz/%.03f MHz\n", - BASEBAND_FILTER_BW_MIN, (float)(BASEBAND_FILTER_BW_MIN/FREQ_ONE_MHZ)); - usage(); - return EXIT_FAILURE; - } - - if( (transmit == false) && (receive == receive_wav) ) - { - printf("receive -r and receive_wav -w options are mutually exclusive\n"); - usage(); - return EXIT_FAILURE; - } - - if( receive_wav == false ) - { - if( transmit == receive ) - { - if( transmit == true ) - { - printf("receive -r and transmit -t options are mutually exclusive\n"); - } else - { - printf("specify either transmit -t or receive -r or receive_wav -w option\n"); - } - usage(); - return EXIT_FAILURE; - } - } - - if( receive ) { - transceiver_mode = TRANSCEIVER_MODE_RX; - } - - if( transmit ) { - transceiver_mode = TRANSCEIVER_MODE_TX; - } - - if( receive_wav ) - { - time (&rawtime); - timeinfo = localtime (&rawtime); - transceiver_mode = TRANSCEIVER_MODE_RX; - /* File format HackRF Year(2013), Month(11), Day(28), Hour Min Sec+Z, Freq kHz, IQ.wav */ - strftime(date_time, DATE_TIME_MAX_LEN, "%Y%m%d_%H%M%S", timeinfo); - snprintf(path_file, PATH_FILE_MAX_LEN, "HackRF_%sZ_%ukHz_IQ.wav", date_time, (uint32_t)(freq_hz/(1000ull)) ); - path = path_file; - printf("Receive wav file: %s\n", path); - } - - if( path == NULL ) { - printf("specify a path to a file to transmit/receive\n"); - usage(); - return EXIT_FAILURE; - } - - result = hackrf_init(); - if( result != HACKRF_SUCCESS ) { - printf("hackrf_init() failed: %s (%d)\n", hackrf_error_name(result), result); - usage(); - return EXIT_FAILURE; - } - - result = hackrf_open(&device); - if( result != HACKRF_SUCCESS ) { - printf("hackrf_open() failed: %s (%d)\n", hackrf_error_name(result), result); - usage(); - return EXIT_FAILURE; - } - - if( transceiver_mode == TRANSCEIVER_MODE_RX ) - { - fd = fopen(path, "wb"); - } else { - fd = fopen(path, "rb"); - } - - if( fd == NULL ) { - printf("Failed to open file: %s\n", path); - return EXIT_FAILURE; - } - /* Change fd buffer to have bigger one to store or read data on/to HDD */ - result = setvbuf(fd , NULL , _IOFBF , FD_BUFFER_SIZE); - if( result != 0 ) { - printf("setvbuf() failed: %d\n", result); - usage(); - return EXIT_FAILURE; - } - - /* Write Wav header */ - if( receive_wav ) - { - fwrite(&wave_file_hdr, 1, sizeof(t_wav_file_hdr), fd); - } - - 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); - - printf("call hackrf_sample_rate_set(%u Hz/%.03f MHz)\n", sample_rate_hz,((float)sample_rate_hz/(float)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); - usage(); - return EXIT_FAILURE; - } - - printf("call hackrf_baseband_filter_bandwidth_set(%d Hz/%.03f MHz)\n", - baseband_filter_bw_hz, ((float)baseband_filter_bw_hz/(float)FREQ_ONE_MHZ)); - result = hackrf_baseband_filter_bandwidth_set(device, baseband_filter_bw_hz); - if( result != HACKRF_SUCCESS ) { - printf("hackrf_baseband_filter_bandwidth_set() failed: %s (%d)\n", hackrf_error_name(result), result); - usage(); - return EXIT_FAILURE; - } - - if( transceiver_mode == TRANSCEIVER_MODE_RX ) { - result = hackrf_start_rx(device, rx_callback, NULL); - } else { - result = hackrf_start_tx(device, tx_callback, NULL); - } - if( result != HACKRF_SUCCESS ) { - printf("hackrf_start_?x() failed: %s (%d)\n", hackrf_error_name(result), result); - usage(); - return EXIT_FAILURE; - } - - printf("call hackrf_set_freq(%llu Hz/%.03f MHz)\n", freq_hz, ((float)freq_hz/(float)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); - usage(); - return EXIT_FAILURE; - } - - if( amp ) { - printf("call hackrf_set_amp_enable(%u)\n", amp_enable); - result = hackrf_set_amp_enable(device, (uint8_t)amp_enable); - if( result != HACKRF_SUCCESS ) { - printf("hackrf_set_amp_enable() failed: %s (%d)\n", hackrf_error_name(result), result); - usage(); - return EXIT_FAILURE; - } - } - - 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); - - printf("Stop with Ctrl-C\n"); - while( (hackrf_is_streaming(device) == HACKRF_TRUE) && - (do_exit == false) ) - { - sleep(1); - - 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) ); - - time_start = time_now; - - if (byte_count_now == 0) { - exit_code = EXIT_FAILURE; - printf("\nCouldn't transfer any bytes for one second.\n"); - break; - } - } - - result = hackrf_is_streaming(device); - if (do_exit) - { - printf("\nUser cancel, exiting...\n"); - } else { - printf("\nExiting... hackrf_is_streaming() result: %s (%d)\n", hackrf_error_name(result), result); - } - - 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"); - } - - if(fd != NULL) - { - if( receive_wav ) - { - /* Get size of file */ - file_pos = ftell(fd); - /* Update Wav Header */ - wave_file_hdr.hdr.size = file_pos+8; - wave_file_hdr.fmt_chunk.dwSamplesPerSec = sample_rate_hz; - wave_file_hdr.fmt_chunk.dwAvgBytesPerSec = wave_file_hdr.fmt_chunk.dwSamplesPerSec*2; - wave_file_hdr.data_chunk.chunkSize = file_pos - sizeof(t_wav_file_hdr); - /* Overwrite header with updated data */ - rewind(fd); - fwrite(&wave_file_hdr, 1, sizeof(t_wav_file_hdr), fd); - } - fclose(fd); - fd = NULL; - printf("fclose(fd) done\n"); - } - printf("exit\n"); - return exit_code; -}