summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChristian Daniel <cd@maintech.de>2012-03-05 18:48:13 +0100
committerChristian Daniel <cd@maintech.de>2012-03-05 18:48:13 +0100
commit956debafb88a59f83affc27888834d3fa627f723 (patch)
tree8b6d8ff263eeb6ad2e731f9d5481d5b38e15b053
parentbd2b9a96979a82f5022c69453907c102e99185f8 (diff)
add sweep tool (Linux only)
-rw-r--r--utils/osmosdr-sweep/Makefile85
-rw-r--r--utils/osmosdr-sweep/portaudio.diff12
-rw-r--r--utils/osmosdr-sweep/src/main.c234
-rw-r--r--utils/osmosdr-sweep/src/serial.c338
-rw-r--r--utils/osmosdr-sweep/src/serial.h16
-rw-r--r--utils/osmosdr-sweep/src/utils.c11
-rw-r--r--utils/osmosdr-sweep/src/utils.h11
7 files changed, 707 insertions, 0 deletions
diff --git a/utils/osmosdr-sweep/Makefile b/utils/osmosdr-sweep/Makefile
new file mode 100644
index 0000000..223b164
--- /dev/null
+++ b/utils/osmosdr-sweep/Makefile
@@ -0,0 +1,85 @@
+# binary file name
+TARGET=osdr-sweep
+
+# CROSS_COMPILE=
+QUIET=@
+
+# N = build release version
+# y = optimize but include debugger info
+# Y = build debug version
+DEBUG=N
+
+C_SOURCES=\
+ src/main.c \
+ src/serial.c \
+ src/utils.c
+
+# general compiler flags
+CFLAGS=-Wall
+LDFLAGS=-Wl,-Map=$(FULLTARGET).map
+LIBS=-lrt libportaudio.a -lasound -lm -lpthread
+
+##############################################################################
+
+SUBDIRS=$(sort $(dir $(C_SOURCES)))
+
+DEPDIR=deps
+OBJDIR=objs
+BINDIR=bin
+DEPDIRS=$(addprefix $(DEPDIR)/,$(SUBDIRS))
+OBJDIRS=$(addprefix $(OBJDIR)/,$(SUBDIRS))
+
+CC=$(CROSS_COMPILE)gcc
+LD=$(CROSS_COMPILE)gcc
+
+COBJS=$(C_SOURCES:%.c=%.o)
+DEPS=$(C_SOURCES:%.c=%.dep)
+FULLDEPS=$(addprefix $(DEPDIR)/,$(DEPS))
+FULLCOBJS=$(addprefix $(OBJDIR)/,$(COBJS))
+FULLTARGET=$(addprefix $(BINDIR)/,$(TARGET))
+
+ifeq ($(DEBUG),Y)
+ # debug version
+ CFLAGS+=-O0 -g3
+ LDFLAGS+=-g3
+else ifeq ($(DEBUG),y)
+ # optimized version with debugger info
+ CFLAGS+=-O2 -g3 -Werror -ffunction-sections -fdata-sections
+ LDFLAGS+=-g3 -Wl,--gc-sections
+else
+ # release version
+ CFLAGS+=-O2 -s -Werror -ffunction-sections -fdata-sections
+ LDFLAGS+=-s -Wl,--gc-sections
+endif
+
+.PHONY: all build clean distclean
+
+all: build
+
+build: $(FULLTARGET)
+
+-include $(FULLDEPS)
+
+$(FULLTARGET): $(DEPDIRS) $(OBJDIRS) $(BINDIR) $(FULLCOBJS)
+ @echo LD \ $(TARGET)
+ $(QUIET)$(LD) $(LDFLAGS) -o $(FULLTARGET) -Wl,--start-group $(FULLCOBJS) $(LIBS) -Wl,--end-group
+ $(QUIET)ln -sf $(FULLTARGET) $(TARGET)
+
+$(FULLCOBJS):
+ @echo C\ \ \ $(patsubst $(OBJDIR)/%,%,$(patsubst %.o,%.c, $@))
+ $(QUIET)$(CC) $(CFLAGS) $(CFLAGS_$(subst /,_,$(patsubst %.o,%,$@))) -MD -MP -MF $(patsubst %.o,$(DEPDIR)/%.dep,$(patsubst $(OBJDIR)/%,%,$@)) -c $(patsubst $(OBJDIR)/%,%,$(patsubst %.o,%.c, $@)) -o $@
+
+$(DEPDIRS):
+ $(QUIET)mkdir -p $@
+
+$(OBJDIRS):
+ $(QUIET)mkdir -p $@
+
+$(BINDIR):
+ $(QUIET)mkdir -p $@
+
+clean:
+ $(QUIET)echo CLEAN
+ $(QUIET)rm -Rf $(DEPDIR) $(OBJDIR) $(BINDIR) $(TARGET) $(TARGET).map *~ *.s *.ss
+
+distclean: clean
diff --git a/utils/osmosdr-sweep/portaudio.diff b/utils/osmosdr-sweep/portaudio.diff
new file mode 100644
index 0000000..15bd249
--- /dev/null
+++ b/utils/osmosdr-sweep/portaudio.diff
@@ -0,0 +1,12 @@
+diff -ur portaudio/src/common/pa_front.c portaudio-osmosdr/src/common/pa_front.c
+--- portaudio/src/common/pa_front.c 2011-08-18 05:43:51.000000000 +0200
++++ portaudio-osmosdr/src/common/pa_front.c 2012-02-29 18:29:40.100609445 +0100
+@@ -965,7 +965,7 @@
+
+
+ /* Check for absurd sample rates. */
+- if( (sampleRate < 1000.0) || (sampleRate > 200000.0) )
++ if( (sampleRate < 1000.0) || (sampleRate > 1500000.0) )
+ return paInvalidSampleRate;
+
+ if( ((streamFlags & ~paPlatformSpecificFlags) & ~(paClipOff | paDitherOff | paNeverDropInput | paPrimeOutputBuffersUsingStreamCallback ) ) != 0 )
diff --git a/utils/osmosdr-sweep/src/main.c b/utils/osmosdr-sweep/src/main.c
new file mode 100644
index 0000000..774da4b
--- /dev/null
+++ b/utils/osmosdr-sweep/src/main.c
@@ -0,0 +1,234 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <math.h>
+#include <portaudio.h>
+#include "serial.h"
+#include "utils.h"
+
+struct SweepState {
+ int serialFd;
+ int settleTime;
+ int sampleTime;
+ uint64_t freq;
+ double acc;
+ double num;
+ double start;
+ double stop;
+};
+
+static int printSyntax()
+{
+ fprintf(stderr, "Error: Invalid command line!\n\n"
+ "syntax: sdr-sweep /dev/ttyUSB0 start stop"
+ " - start = start frequency in MHz, e.g 88.5\n"
+ " - stop = stop frequency in MHz, e.g. 108\n"
+ "frequency range of OsmoSDR is 64MHz - 1700MHz\n");
+
+ return EXIT_FAILURE;
+}
+
+static void setFreq(int fd, uint64_t freq)
+{
+ char str[128];
+ char* c;
+ char str2[2] = { '\0', '\0' };
+
+ while(serialGetS(fd, str, sizeof(str), 1) >= 0)
+ ;
+
+ sprintf(str, "tuner.freq=%llu\r", freq);
+
+ for(c = str; *c != '\0'; c++) {
+ serialPutC(fd, *c);
+ if(*c == '\r')
+ str2[0] = '\n';
+ else str2[0] = *c;
+ if(serialExpect(fd, str2, 1) < 0) {
+ serialPutC(fd, *c);
+ if(serialExpect(fd, str2, 1) < 0) {
+ fprintf(stderr, "serial port broken (%d = %c)\n", *c, *c);
+ return;
+ }
+ }
+ }
+}
+
+static int audioCallback(const void* inputBuffer, void* outputBuffer,
+ unsigned long framesPerBuffer,
+ const PaStreamCallbackTimeInfo* timeInfo,
+ PaStreamCallbackFlags statusFlags,
+ void* userData)
+{
+ struct SweepState* state = (struct SweepState*)userData;
+ int i;
+ const int16_t* input = (const int16_t*)inputBuffer;
+ uint8_t c;
+ double v;
+ int max;
+
+ //fprintf(stderr, "block %lu\n", framesPerBuffer);
+
+ while(serialGetC(state->serialFd, &c, 0) >= 0)
+ //fprintf(stderr, "%c", c);
+ ;
+
+ if(state->settleTime > 0) {
+ state->settleTime -= framesPerBuffer;
+ if(state->settleTime <= 0) {
+ state->sampleTime = 100000;
+ state->acc = 0.0;
+ state->num = 0.0;
+ }
+ return 0;
+ }
+
+ if(state->sampleTime > 0) {
+ max = 0;
+ for(i = 0; i < framesPerBuffer; i++) {
+ if(abs(*input) > max)
+ max = abs(*input);
+ v = *input / 32768.0;
+ state->acc += v * v;
+ input++;
+ if(abs(*input) > max)
+ max = abs(*input);
+ v = *input / 32768.0;
+ state->acc += v * v;
+ input++;
+ state->num += 2;
+ }
+ //fprintf(stderr, "-> %d\n", max);
+
+ state->sampleTime -= framesPerBuffer;
+ if(state->sampleTime <= 0) {
+ printf("%.1f\t%.1f\n", state->freq / 1000000.0, 20.0 * log10(sqrt(state->acc / state->num)));
+ fflush(stdout);
+ state->freq += 100000;
+ setFreq(state->serialFd, state->freq);
+ state->settleTime = 500000;
+ }
+ }
+
+ return 0;
+}
+
+static PaStream* audioOpen(struct SweepState* state)
+{
+ int numDevices;
+ const PaDeviceInfo* deviceInfo;
+ PaError err;
+ int i;
+ int dev = -1;
+ PaStream* stream = NULL;
+ PaStreamParameters inputParameters;
+
+ err = Pa_Initialize();
+ if(err != paNoError)
+ goto error_noinit;
+
+ numDevices = Pa_GetDeviceCount();
+ if(numDevices < 0) {
+ err = numDevices;
+ goto error;
+ }
+
+ for(i = 0; i < numDevices; i++) {
+ deviceInfo = Pa_GetDeviceInfo(i);
+ fprintf(stderr, "#%02d -> [%s]\n", i, deviceInfo->name);
+ if(strncmp(deviceInfo->name, "OsmoSDR", 7) == 0)
+ dev = i;
+ }
+ if(dev < 0) {
+ fprintf(stderr, "OsmoSDR not found!\n");
+ Pa_Terminate();
+ return NULL;
+ }
+
+ fprintf(stderr, "Using device #%02d (sample rate %.0f Hz)\n", dev, Pa_GetDeviceInfo(dev)->defaultSampleRate);
+
+ bzero(&inputParameters, sizeof(inputParameters));
+ inputParameters.channelCount = 2;
+ inputParameters.device = dev;
+ inputParameters.hostApiSpecificStreamInfo = NULL;
+ inputParameters.sampleFormat = paInt16;
+ inputParameters.suggestedLatency = Pa_GetDeviceInfo(dev)->defaultHighInputLatency ;
+ inputParameters.hostApiSpecificStreamInfo = NULL;
+
+ err = Pa_OpenStream(&stream, &inputParameters, NULL, Pa_GetDeviceInfo(dev)->defaultSampleRate, 20000,
+ paClipOff | paDitherOff, audioCallback, state);
+ if(err != paNoError)
+ goto error_noinit;
+
+ err = Pa_StartStream(stream);
+ if(err != paNoError)
+ goto error_noinit;
+
+ return stream;
+
+error:
+ Pa_Terminate();
+
+error_noinit:
+ fprintf(stderr, "PortAudio error: %s\n", Pa_GetErrorText(err));
+ return NULL;
+}
+
+static void audioClose(PaStream* stream)
+{
+ PaError err;
+
+ err = Pa_StopStream(stream);
+ if(err != paNoError)
+ fprintf(stderr, "PortAudio error: %s\n", Pa_GetErrorText(err));
+
+ err = Pa_CloseStream(stream);
+ if(err != paNoError)
+ fprintf(stderr, "PortAudio error: %s\n", Pa_GetErrorText(err));
+
+ err = Pa_Terminate();
+ if(err != paNoError)
+ fprintf(stderr, "PortAudio error: %s\n", Pa_GetErrorText(err));
+}
+
+int main(int argc, char* argv[])
+{
+ HANDLE fd;
+ PaStream* stream;
+ struct SweepState state;
+
+ if(argc < 4)
+ return printSyntax();
+
+ if((fd = serialOpen(argv[1])) == INVALID_HANDLE_VALUE)
+ return EXIT_FAILURE;
+
+ memset(&state, 0x00, sizeof(struct SweepState));
+ state.serialFd = fd;
+ state.settleTime = 100000;
+ state.start = atof(argv[2]);
+ state.stop = atof(argv[3]);
+ state.freq = state.start * 1000000.0;
+ serialPutS(fd, "\r\r\rtuner.init!\r\r\r");
+ setFreq(fd, state.freq);
+
+ if((stream = audioOpen(&state)) == NULL) {
+ serialClose(fd);
+ return EXIT_FAILURE;
+ }
+
+ fprintf(stderr, "sweep running...\n");
+
+ while(1) {
+ sleep(1);
+ if(state.freq > state.stop * 1000000.0)
+ break;
+ fprintf(stderr, "...%.1f MHz...\n", state.freq / 1000000.0);
+ }
+
+ audioClose(stream);
+ serialClose(fd);
+
+ return EXIT_FAILURE;
+}
diff --git a/utils/osmosdr-sweep/src/serial.c b/utils/osmosdr-sweep/src/serial.c
new file mode 100644
index 0000000..d237a74
--- /dev/null
+++ b/utils/osmosdr-sweep/src/serial.c
@@ -0,0 +1,338 @@
+#ifdef WINDOWS
+
+#include <stdio.h>
+#include "serial.h"
+
+static void printErr(const char* text, int err)
+{
+ char errorBuf[256];
+ char* buf = errorBuf;
+ size_t max = sizeof(errorBuf) - 1;
+ memset(errorBuf, 0x00, sizeof(errorBuf));
+
+ FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, GetLastError(), LANG_NEUTRAL, buf, (DWORD)max, NULL);
+ fprintf(stderr, "%s: %s\n", text, errorBuf);
+ fflush(stderr);
+}
+
+HANDLE serialOpen(const char* dev)
+{
+ char str[64];
+ HANDLE fd;
+ int err;
+
+ snprintf(str, sizeof(str), "\\\\.\\%s", dev);
+ fd = CreateFileA(str, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
+ if(fd == INVALID_HANDLE_VALUE) {
+ err = GetLastError();
+ if(err == ERROR_FILE_NOT_FOUND) {
+ fprintf(stderr, "could not open %s: serial port does not exist\n", dev);
+ } else {
+ snprintf(str, sizeof(str), "could not open %s", dev);
+ printErr(str, err);
+ }
+ goto failed;
+ }
+
+ if(serialSetBaudrate(fd, 115200) < 0)
+ goto failed;
+
+ return fd;
+
+failed:
+ if(fd != INVALID_HANDLE_VALUE)
+ CloseHandle(fd);
+ return INVALID_HANDLE_VALUE;
+}
+
+void serialClose(HANDLE fd)
+{
+ if(fd != INVALID_HANDLE_VALUE)
+ CloseHandle(fd);
+}
+
+int serialSetBaudrate(HANDLE fd, int baudrate)
+{
+ DCB dcb;
+
+ memset(&dcb, 0x00, sizeof(dcb));
+ dcb.DCBlength = sizeof(dcb);
+ if(!GetCommState(fd, &dcb)) {
+ printErr("error getting serial port state", GetLastError());
+ return -1;
+ }
+ dcb.BaudRate = baudrate;
+ dcb.ByteSize = 8;
+ dcb.StopBits = ONESTOPBIT;
+ dcb.Parity = NOPARITY;
+ dcb.fBinary = 1;
+ dcb.fOutxCtsFlow = 0;
+ dcb.fOutxDsrFlow = 0;
+ dcb.fOutX = 0;
+ dcb.fInX = 0;
+ dcb.fNull = 0;
+ dcb.fTXContinueOnXoff = 0;
+ dcb.fDtrControl = DTR_CONTROL_DISABLE;
+ dcb.fDsrSensitivity = 0;
+ dcb.fRtsControl = RTS_CONTROL_DISABLE;
+ if(!SetCommState(fd, &dcb)) {
+ printErr("error setting serial port state", GetLastError());
+ return -1;
+ }
+
+ return 0;
+}
+
+int serialPutC(HANDLE fd, uint8_t c)
+{
+ DWORD bytesWritten;
+
+ if(!WriteFile(fd, &c, 1, &bytesWritten, NULL)) {
+ printErr("error writing to serial port", GetLastError());
+ return -1;
+ }
+
+ return 1;
+}
+
+int serialGetC(HANDLE fd, uint8_t* c, int timeout)
+{
+ COMMTIMEOUTS timeouts;
+ unsigned long res;
+ COMSTAT comStat;
+ DWORD errors;
+
+ if(!ClearCommError(fd, &errors, &comStat)) {
+ printErr("could not reset comm errors", GetLastError());
+ return -1;
+ }
+
+ if(!GetCommTimeouts(fd, &timeouts)) {
+ printErr("error getting comm timeouts", GetLastError());
+ return -1;
+ }
+ timeouts.ReadIntervalTimeout = timeout;
+ timeouts.ReadTotalTimeoutConstant = timeout;
+ timeouts.ReadTotalTimeoutMultiplier = 10;
+ if(!SetCommTimeouts(fd, &timeouts)) {
+ printErr("error setting comm timeouts", GetLastError());
+ return -1;
+ }
+
+ if(!ReadFile(fd, c, 1, &res, NULL)) {
+ printErr("error reading from serial port", GetLastError());
+ return -1;
+ }
+
+ if(res != 1)
+ return -1;
+
+ return *c;
+}
+
+#else // #ifdef WINDOWS
+
+#include <stdio.h>
+#include <string.h>
+#include <errno.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <termios.h>
+#include <poll.h>
+#include "serial.h"
+
+HANDLE serialOpen(const char* dev)
+{
+ HANDLE fd;
+
+ if((fd = open(dev, O_RDWR | O_NOCTTY | O_NDELAY)) < 0) {
+ fprintf(stderr, "could not open %s: %s\n", dev, strerror(errno));
+ goto failed;
+ }
+ if(tcflush(fd, TCIOFLUSH) < 0) {
+ fprintf(stderr, "tcflush() failed: %s\n", strerror(errno));
+ goto failed;
+ }
+ if(serialSetBaudrate(fd, 115200) < 0)
+ goto failed;
+
+ return fd;
+
+failed:
+ if(fd >= 0)
+ close(fd);
+ return INVALID_HANDLE_VALUE;
+}
+
+void serialClose(HANDLE fd)
+{
+ if(fd != INVALID_HANDLE_VALUE)
+ close(fd);
+}
+
+int serialSetBaudrate(HANDLE fd, int baudrate)
+{
+ struct termios tios;
+
+ bzero(&tios, sizeof(tios));
+ switch(baudrate) {
+ case 230400:
+ tios.c_cflag = B230400;
+ break;
+
+ case 460800:
+ tios.c_cflag = B460800;
+ break;
+
+ case 921600:
+ tios.c_cflag = B921600;
+ break;
+
+ default:
+ tios.c_cflag = B115200;
+ break;
+ }
+ tios.c_cflag |= CS8 | CLOCAL | CREAD;
+ tios.c_iflag = IGNPAR;
+ tios.c_oflag = 0;
+ tios.c_lflag = ICANON;
+ tios.c_cc[VMIN] = 1;
+ cfmakeraw(&tios);
+
+ if(tcsetattr(fd, TCSAFLUSH, &tios) < 0) {
+ fprintf(stderr, "tcsetattr() failed: %s\n", strerror(errno));
+ return -1;
+ }
+ if(tcflush(fd, TCIOFLUSH) < 0) {
+ fprintf(stderr, "tcflush() failed: %s\n", strerror(errno));
+ return -1;
+ }
+
+ return 0;
+}
+
+int serialPutC(HANDLE fd, uint8_t c)
+{
+ if(write(fd, &c, sizeof(uint8_t)) != sizeof(uint8_t)) {
+ if(errno == EAGAIN) {
+ struct pollfd pollfd;
+ int res;
+ pollfd.fd = fd;
+ pollfd.events = POLLOUT;
+ pollfd.revents = 0;
+ do {
+ res = poll(&pollfd, 1, 250);
+ } while((res < 0) && (errno == EINTR));
+ if(res > 0) {
+ if(write(fd, &c, sizeof(char)) != sizeof(char)) {
+ fprintf(stderr, "write failed: %s\n", strerror(errno));
+ return -1;
+ } else {
+ return 0;
+ }
+ } else if(res == 0) {
+ fprintf(stderr, "write failed: %s\n", strerror(errno));
+ return -1;
+ } else {
+ fprintf(stderr, "poll failed: %s\n", strerror(errno));
+ return -1;
+ }
+ } else {
+ fprintf(stderr, "write failed: %s\n", strerror(errno));
+ return -1;
+ }
+ } else {
+ return 0;
+ }
+}
+
+int serialGetC(HANDLE fd, uint8_t* c, int timeout)
+{
+ struct pollfd pollfd;
+ int res;
+
+ pollfd.fd = fd;
+ pollfd.events = POLLIN;
+ pollfd.revents = 0;
+
+ do {
+ res = poll(&pollfd, 1, timeout);
+ } while((res < 0) && (errno == EINTR));
+
+ if(res > 0) {
+ if(read(fd, c, sizeof(char)) != sizeof(char)) {
+ fprintf(stderr, "read failed: %s\n", strerror(errno));
+ return -1;
+ } else {
+ return 0;
+ }
+ } else if(res == 0) {
+ // timeout
+ return -1;
+ }
+
+ fprintf(stderr, "poll failed: %s\n", strerror(errno));
+ return -1;
+}
+
+#endif // #ifdef WINDOWS
+
+int serialPutS(HANDLE fd, const char* str)
+{
+ while(*str != '\0') {
+ if(serialPutC(fd, *((uint8_t*)str)) < 0)
+ return -1;
+ str++;
+ }
+ return 0;
+}
+
+int serialGetS(HANDLE fd, char* str, int len, int timeout)
+{
+ int todo = len;
+ uint64_t endTime = getTickCount() + timeout;
+
+ while(todo > 0) {
+ uint64_t now = getTickCount();
+
+ if(now < endTime) {
+ uint8_t c;
+ if(serialGetC(fd, &c, endTime - now) < 0)
+ return -1;
+ *((uint8_t*)str) = c;
+ str++;
+ todo--;
+ } else {
+ break;
+ }
+ }
+
+ return (todo > 0) ? -1 : 0;
+}
+
+int serialExpect(HANDLE fd, const char* str, int timeout)
+{
+ int todo = strlen(str);
+ uint64_t endTime = getTickCount() + timeout;
+
+ while(todo > 0) {
+ uint64_t now = getTickCount();
+
+ if(now < endTime) {
+ uint8_t c;
+ if(serialGetC(fd, &c, endTime - now) < 0)
+ return -1;
+ //fprintf(stderr, "{%c}", c);
+ if(c == (uint8_t)(*str++)) {
+ todo--;
+ continue;
+ } else {
+ return -1;
+ }
+ } else {
+ break;
+ }
+ }
+
+ return (todo > 0) ? -1 : 0;
+}
diff --git a/utils/osmosdr-sweep/src/serial.h b/utils/osmosdr-sweep/src/serial.h
new file mode 100644
index 0000000..c31e281
--- /dev/null
+++ b/utils/osmosdr-sweep/src/serial.h
@@ -0,0 +1,16 @@
+#ifndef INCLUDE_SERIAL_H
+#define INCLUDE_SERIAL_H
+
+#include "utils.h"
+
+HANDLE serialOpen(const char* dev);
+void serialClose(HANDLE fd);
+int serialSetBaudrate(HANDLE fd, int baudrate);
+int serialPutC(HANDLE fd, uint8_t c);
+int serialGetC(HANDLE fd, uint8_t* c, int timeout);
+
+int serialPutS(HANDLE fd, const char* str);
+int serialGetS(HANDLE fd, char* str, int len, int timeout);
+int serialExpect(HANDLE fd, const char* str, int timeout);
+
+#endif // INCLUDE_SERIAL_H
diff --git a/utils/osmosdr-sweep/src/utils.c b/utils/osmosdr-sweep/src/utils.c
new file mode 100644
index 0000000..1888b73
--- /dev/null
+++ b/utils/osmosdr-sweep/src/utils.c
@@ -0,0 +1,11 @@
+#include <time.h>
+#include "utils.h"
+
+uint64_t getTickCount()
+{
+ struct timespec t;
+
+ if(clock_gettime(CLOCK_MONOTONIC, &t) != 0)
+ return 0;
+ return (((uint64_t)t.tv_sec) * 1000) + (((uint64_t)t.tv_nsec) / 1000000);
+}
diff --git a/utils/osmosdr-sweep/src/utils.h b/utils/osmosdr-sweep/src/utils.h
new file mode 100644
index 0000000..0084832
--- /dev/null
+++ b/utils/osmosdr-sweep/src/utils.h
@@ -0,0 +1,11 @@
+#ifndef INCLUDE_UTILS_H
+#define INCLUDE_UTILS_H
+
+#include <stdint.h>
+
+uint64_t getTickCount();
+
+typedef int HANDLE;
+#define INVALID_HANDLE_VALUE (-1)
+
+#endif // INCLUDE_UTILS_H