diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/CMakeLists.txt | 6 | ||||
-rw-r--r-- | src/fl2k_file.c | 26 | ||||
-rw-r--r-- | src/fl2k_tcp.c | 18 | ||||
-rw-r--r-- | src/fl2k_test.c | 14 | ||||
-rw-r--r-- | src/libosmo-fl2k.c | 144 |
5 files changed, 161 insertions, 47 deletions
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 1d788de..f63780a 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -15,6 +15,8 @@ # You should have received a copy of the GNU General Public License # along with this program. If not, see <http://www.gnu.org/licenses/>. +include(GNUInstallDirs) + MACRO(LIBFL2K_APPEND_SRCS) LIST(APPEND libosmo-fl2k_srcs ${ARGV}) ENDMACRO(LIBFL2K_APPEND_SRCS) @@ -124,7 +126,7 @@ endif() # Install built library files & utilities ######################################################################## install(TARGETS ${INSTALL_TARGETS} - LIBRARY DESTINATION ${LIB_INSTALL_DIR} # .so/.dylib file - ARCHIVE DESTINATION ${LIB_INSTALL_DIR} # .lib file + LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} # .so/.dylib file + ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} # .lib file RUNTIME DESTINATION bin # .dll file ) diff --git a/src/fl2k_file.c b/src/fl2k_file.c index 0da1cbc..2cea6ff 100644 --- a/src/fl2k_file.c +++ b/src/fl2k_file.c @@ -28,11 +28,13 @@ #ifndef _WIN32 #include <unistd.h> +#define sleep_ms(ms) usleep(ms*1000) #else #include <windows.h> #include <io.h> #include <fcntl.h> #include "getopt/getopt.h" +#define sleep_ms(ms) Sleep(ms) #endif #include "osmo-fl2k.h" @@ -156,10 +158,17 @@ int main(int argc, char **argv) if (dev_index < 0) exit(1); - file = fopen(filename, "rb"); - if (!file) { - fprintf(stderr, "Failed to open %s\n", filename); - goto out; + if (strcmp(filename, "-") == 0) { /* Read samples from stdin */ + file = stdin; +#ifdef _WIN32 + _setmode(_fileno(stdin), _O_BINARY); +#endif + } else { + file = fopen(filename, "rb"); + if (!file) { + fprintf(stderr, "Failed to open %s\n", filename); + return -ENOENT; + } } txbuf = malloc(FL2K_BUF_LEN * (interleaved ? 2 : 1)); @@ -195,13 +204,8 @@ int main(int argc, char **argv) SetConsoleCtrlHandler( (PHANDLER_ROUTINE) sighandler, TRUE ); #endif - while (!do_exit) { -#ifndef _WIN32 - usleep(500000); -#else - Sleep(0.5); -#endif - } + while (!do_exit) + sleep_ms(500); fl2k_close(dev); diff --git a/src/fl2k_tcp.c b/src/fl2k_tcp.c index ad0aa18..bd01758 100644 --- a/src/fl2k_tcp.c +++ b/src/fl2k_tcp.c @@ -36,9 +36,12 @@ #include <netinet/in.h> #include <netinet/tcp.h> /* for TCP_NODELAY */ #include <fcntl.h> +#define sleep_ms(ms) usleep(ms*1000) #else +#include <windows.h> #include <winsock2.h> #include "getopt/getopt.h" +#define sleep_ms(ms) Sleep(ms) #endif #include "osmo-fl2k.h" @@ -217,11 +220,7 @@ int main(int argc, char **argv) fprintf(stderr, "Connecting to %s:%d...\n", addr, port); while (connect(sock, (struct sockaddr *)&remote, sizeof(remote)) != 0) { -#ifndef _WIN32 - usleep(500000); -#else - Sleep(0.5); -#endif + sleep_ms(500); if (do_exit) goto out; } @@ -230,13 +229,8 @@ int main(int argc, char **argv) fprintf(stderr, "Connected\n"); connected = 1; - while (!do_exit) { -#ifndef _WIN32 - usleep(500000); -#else - Sleep(0.5); -#endif - } + while (!do_exit) + sleep_ms(500); out: free(txbuf); diff --git a/src/fl2k_test.c b/src/fl2k_test.c index c9a6048..6d82922 100644 --- a/src/fl2k_test.c +++ b/src/fl2k_test.c @@ -41,9 +41,11 @@ #ifndef _WIN32 #include <unistd.h> +#define sleep_ms(ms) usleep(ms*1000) #else #include <windows.h> #include "getopt/getopt.h" +#define sleep_ms(ms) Sleep(ms) #endif #include "osmo-fl2k.h" @@ -290,17 +292,11 @@ int main(int argc, char **argv) fprintf(stderr, "Reporting PPM error measurement every %u seconds...\n", ppm_duration); fprintf(stderr, "Press ^C after a few minutes.\n"); - while (!do_exit) { -#ifndef _WIN32 - usleep(500000); -#else - Sleep(0.5); -#endif - } + while (!do_exit) + sleep_ms(500); - if (do_exit) { + if (do_exit) fprintf(stderr, "\nUser cancel, exiting...\n"); - } exit: fl2k_close(dev); diff --git a/src/libosmo-fl2k.c b/src/libosmo-fl2k.c index 09380b6..c5959c3 100644 --- a/src/libosmo-fl2k.c +++ b/src/libosmo-fl2k.c @@ -25,15 +25,18 @@ #include <string.h> #include <stdio.h> #include <stdlib.h> +#include <math.h> +#include <libusb.h> +#include <pthread.h> #ifndef _WIN32 #include <unistd.h> +#define sleep_ms(ms) usleep(ms*1000) +#else +#include <windows.h> +#define sleep_ms(ms) Sleep(ms) #endif -#include <math.h> -#include <libusb.h> -#include <pthread.h> - /* * All libusb callback functions should be marked with the LIBUSB_CALL macro * to ensure that they are compiled with the same calling convention as libusb. @@ -381,7 +384,11 @@ int fl2k_open(fl2k_dev_t **out_dev, uint32_t index) return -1; } +#if LIBUSB_API_VERSION >= 0x01000106 + libusb_set_option(dev->ctx, LIBUSB_OPTION_LOG_LEVEL, 3); +#else libusb_set_debug(dev->ctx, 3); +#endif dev->dev_lost = 1; @@ -472,13 +479,8 @@ int fl2k_close(fl2k_dev_t *dev) if(!dev->dev_lost) { /* block until all async operations have been completed (if any) */ - while (FL2K_INACTIVE != dev->async_status) { -#ifdef _WIN32 - Sleep(1); -#else - usleep(1000); -#endif - } + while (FL2K_INACTIVE != dev->async_status) + sleep_ms(100); fl2k_deinit_device(dev); } @@ -589,11 +591,26 @@ static int fl2k_alloc_submit_transfers(fl2k_dev_t *dev) for (i = 0; i < dev->xfer_buf_num; ++i) { dev->xfer_buf[i] = libusb_dev_mem_alloc(dev->devh, dev->xfer_buf_len); - if (!dev->xfer_buf[i]) { + if (dev->xfer_buf[i]) { + /* Check if Kernel usbfs mmap() bug is present: if the + * mapping is correct, the buffers point to memory that + * was memset to 0 by the Kernel, otherwise, they point + * to random memory. We check if the buffers are zeroed + * and otherwise fall back to buffers in userspace. + */ + if (dev->xfer_buf[i][0] || memcmp(dev->xfer_buf[i], + dev->xfer_buf[i] + 1, + dev->xfer_buf_len - 1)) { + fprintf(stderr, "Detected Kernel usbfs mmap() " + "bug, falling back to buffers " + "in userspace\n"); + dev->use_zerocopy = 0; + break; + } + } else { fprintf(stderr, "Failed to allocate zero-copy " "buffer for transfer %d\nFalling " "back to buffers in userspace\n", i); - dev->use_zerocopy = 0; break; } @@ -1020,3 +1037,104 @@ int fl2k_stop_tx(fl2k_dev_t *dev) return FL2K_ERROR_BUSY; } + +int fl2k_i2c_read(fl2k_dev_t *dev, uint8_t i2c_addr, uint8_t reg_addr, uint8_t *data) +{ + int i, r, timeout = 1; + uint32_t reg; + + if (!dev) + return FL2K_ERROR_INVALID_PARAM; + + r = fl2k_read_reg(dev, 0x8020, ®); + if (r < 0) + return r; + + /* apply mask, clearing bit 30 disables periodic repetition of read */ + reg &= 0x3ffc0000; + + /* set I2C register and address, select I2C read (bit 7) */ + reg |= (1 << 28) | (reg_addr << 8) | (1 << 7) | (i2c_addr & 0x7f); + + r = fl2k_write_reg(dev, 0x8020, reg); + if (r < 0) + return r; + + for (i = 0; i < 10; i++) { + sleep_ms(10); + + r = fl2k_read_reg(dev, 0x8020, ®); + if (r < 0) + return r; + + /* check if operation completed */ + if (reg & (1 << 31)) { + timeout = 0; + break; + } + } + + if (timeout) + return FL2K_ERROR_TIMEOUT; + + /* check if slave responded and all data was read */ + if (reg & (0x0f << 24)) + return FL2K_ERROR_NOT_FOUND; + + /* read data from register 0x8024 */ + return libusb_control_transfer(dev->devh, CTRL_IN, 0x40, + 0, 0x8024, data, 4, CTRL_TIMEOUT); +} + +int fl2k_i2c_write(fl2k_dev_t *dev, uint8_t i2c_addr, uint8_t reg_addr, uint8_t *data) +{ + int i, r, timeout = 1; + uint32_t reg; + + if (!dev) + return FL2K_ERROR_INVALID_PARAM; + + /* write data to register 0x8028 */ + r = libusb_control_transfer(dev->devh, CTRL_OUT, 0x41, + 0, 0x8028, data, 4, CTRL_TIMEOUT); + + if (r < 0) + return r; + + r = fl2k_read_reg(dev, 0x8020, ®); + if (r < 0) + return r; + + /* apply mask, clearing bit 30 disables periodic repetition of read */ + reg &= 0x3ffc0000; + + /* set I2C register and address */ + reg |= (1 << 28) | (reg_addr << 8) | (i2c_addr & 0x7f); + + r = fl2k_write_reg(dev, 0x8020, reg); + if (r < 0) + return r; + + for (i = 0; i < 10; i++) { + sleep_ms(10); + + r = fl2k_read_reg(dev, 0x8020, ®); + if (r < 0) + return r; + + /* check if operation completed */ + if (reg & (1 << 31)) { + timeout = 0; + break; + } + } + + if (timeout) + return FL2K_ERROR_TIMEOUT; + + /* check if slave responded and all data was written */ + if (reg & (0x0f << 24)) + return FL2K_ERROR_NOT_FOUND; + + return FL2K_SUCCESS; +} |