From e2c05fbfe21c831478d66cda7edc152b3ac2dbeb Mon Sep 17 00:00:00 2001 From: TitanMKD Date: Tue, 26 Feb 2013 00:17:18 +0100 Subject: [PATCH 1/2] Draft in progress (not tested at all) set_freq(). --- firmware/common/hackrf_core.c | 90 ++++++++++++++++++++++ firmware/common/hackrf_core.h | 2 + firmware/usb_performance/usb_performance.c | 20 ++++- host/libhackrf/examples/hackrf_transfer.c | 62 ++++++++++++++- host/libhackrf/src/hackrf.c | 23 +++++- host/libhackrf/src/hackrf.h | 2 + 6 files changed, 195 insertions(+), 4 deletions(-) diff --git a/firmware/common/hackrf_core.c b/firmware/common/hackrf_core.c index 5f312bee..ca19304f 100644 --- a/firmware/common/hackrf_core.c +++ b/firmware/common/hackrf_core.c @@ -1,6 +1,7 @@ /* * Copyright 2012 Michael Ossmann * Copyright 2012 Jared Boone + * Copyright 2013 Benjamin Vernoux * * This file is part of HackRF. * @@ -23,12 +24,28 @@ #include "hackrf_core.h" #include "si5351c.h" #include "max2837.h" +#include "rffc5071.h" #include #include #include #include #include +/* Define for set_tune_freq() */ +#define FREQ_ONE_MHZ (1000*1000) + +#define MIN_LP_FREQ_MHZ (30) +#define MAX_LP_FREQ_MHZ (2300) + +#define MIN_BYPASS_FREQ_MHZ (2300) +#define MAX_BYPASS_FREQ_MHZ (2700) + +#define MIN_HP_FREQ_MHZ (2700) +#define MAX_HP_FREQ_MHZ (6000) + +#define MAX2837_FREQ_NOMINAL_HZ (2600000000) +#define MAX2837_FREQ_NOMINAL_MHZ (MAX2837_FREQ_NOMINAL_HZ / FREQ_ONE_MHZ) + void delay(uint32_t duration) { uint32_t i; @@ -391,3 +408,76 @@ void pin_setup(void) { void enable_1v8_power(void) { gpio_set(PORT_EN1V8, PIN_EN1V8); } + +/* +Set freq/tuning between 30MHz to 6000 MHz +hz between 0 to 999999 Hz (not checked) +return false on error or true if success. +*/ +bool set_freq(uint32_t freq_mhz, uint32_t freq_hz) +{ + bool success; + uint32_t RFFC5071_freq_mhz; + uint32_t MAX2837_freq_hz; + uint32_t real_RFFC5071_freq_mhz; + uint32_t tmp_hz; + + success = true; + + if(freq_mhz >= MIN_LP_FREQ_MHZ) + { + if(freq_mhz < MAX_LP_FREQ_MHZ) + { + /* TODO fix/check Switch to LP mode (shall not change RX/TX mode) */ + rffc5071_set_gpo(0); /* SWITCHCTRL_LP = 0 */ + + RFFC5071_freq_mhz = MAX2837_FREQ_NOMINAL_MHZ - freq_mhz; + /* Set Freq and read real freq */ + real_RFFC5071_freq_mhz = rffc5071_set_frequency(RFFC5071_freq_mhz, 0); + if(real_RFFC5071_freq_mhz < RFFC5071_freq_mhz) + { + tmp_hz = -((RFFC5071_freq_mhz - real_RFFC5071_freq_mhz) * FREQ_ONE_MHZ); + }else + { + tmp_hz = ((real_RFFC5071_freq_mhz - RFFC5071_freq_mhz) * FREQ_ONE_MHZ); + } + MAX2837_freq_hz = MAX2837_FREQ_NOMINAL_HZ + tmp_hz + freq_hz; + max2837_set_frequency(MAX2837_freq_hz); + }else if( (freq_mhz >= MIN_BYPASS_FREQ_MHZ) && (freq_mhz < MAX_BYPASS_FREQ_MHZ) ) + { + /* TODO fix/check Switch to SWITCHCTRL_MIX_BYPASS mode (shall not change RX/TX mode) */ + rffc5071_set_gpo(SWITCHCTRL_MIX_BYPASS); + + MAX2837_freq_hz = (freq_mhz * FREQ_ONE_MHZ) + freq_hz; + /* RFFC5071_freq_mhz <= not used in Bypass mode */ + max2837_set_frequency(MAX2837_freq_hz); + }else if( (freq_mhz >= MIN_HP_FREQ_MHZ) && (freq_mhz < MAX_HP_FREQ_MHZ) ) + { + /* TODO fix/check Switch to SWITCHCTRL_HP mode (shall not change RX/TX mode) */ + rffc5071_set_gpo(SWITCHCTRL_HP); + + //switch_ctrl = SWITCHCTRL_HP; + RFFC5071_freq_mhz = freq_mhz - MAX2837_FREQ_NOMINAL_MHZ; + /* Set Freq and read real freq */ + real_RFFC5071_freq_mhz = rffc5071_set_frequency(RFFC5071_freq_mhz, 0); + if(real_RFFC5071_freq_mhz < RFFC5071_freq_mhz) + { + tmp_hz = ((RFFC5071_freq_mhz - real_RFFC5071_freq_mhz) * FREQ_ONE_MHZ); + }else + { + tmp_hz = -((real_RFFC5071_freq_mhz - RFFC5071_freq_mhz) * FREQ_ONE_MHZ); + } + MAX2837_freq_hz = MAX2837_FREQ_NOMINAL_HZ + tmp_hz + freq_hz; + max2837_set_frequency(MAX2837_freq_hz); + }else + { + /* Error freq_mhz too high */ + success = false; + } + }else + { + /* Error freq_mhz too low */ + success = false; + } + return success; +} diff --git a/firmware/common/hackrf_core.h b/firmware/common/hackrf_core.h index 71f017da..2d04be8f 100644 --- a/firmware/common/hackrf_core.h +++ b/firmware/common/hackrf_core.h @@ -258,6 +258,8 @@ void enable_1v8_power(void); bool sample_rate_set(const uint32_t sampling_rate_hz); bool baseband_filter_bandwidth_set(const uint32_t bandwidth_hz); +bool set_freq(uint32_t freq_mhz, uint32_t freq_hz); + #ifdef __cplusplus } #endif diff --git a/firmware/usb_performance/usb_performance.c b/firmware/usb_performance/usb_performance.c index 2bb56aaa..a4dfd69d 100644 --- a/firmware/usb_performance/usb_performance.c +++ b/firmware/usb_performance/usb_performance.c @@ -491,6 +491,23 @@ usb_request_status_t usb_vendor_request_read_version_string( return USB_REQUEST_STATUS_OK; } +usb_request_status_t usb_vendor_request_set_freq( + usb_endpoint_t* const endpoint, + const usb_transfer_stage_t stage +) { + if( stage == USB_TRANSFER_STAGE_SETUP ) { + const uint32_t freq_mhz = (endpoint->setup.index << 16) | endpoint->setup.value; + const uint32_t freq_hz = 0; /* TODO fix this and retrieve a 32bits */ + if( set_freq(freq_mhz, freq_hz) ) { + usb_endpoint_schedule_ack(endpoint->in); + return USB_REQUEST_STATUS_OK; + } + return USB_REQUEST_STATUS_STALL; + } else { + return USB_REQUEST_STATUS_OK; + } +} + static const usb_request_handler_fn vendor_request_handler[] = { NULL, usb_vendor_request_set_transceiver_mode, @@ -507,7 +524,8 @@ static const usb_request_handler_fn vendor_request_handler[] = { usb_vendor_request_read_spiflash, usb_vendor_request_write_cpld, usb_vendor_request_read_board_id, - usb_vendor_request_read_version_string + usb_vendor_request_read_version_string, + usb_vendor_request_set_freq }; static const uint32_t vendor_request_handler_count = diff --git a/host/libhackrf/examples/hackrf_transfer.c b/host/libhackrf/examples/hackrf_transfer.c index dd3dc1f1..99724805 100644 --- a/host/libhackrf/examples/hackrf_transfer.c +++ b/host/libhackrf/examples/hackrf_transfer.c @@ -42,6 +42,9 @@ #include #include +#define FREQ_MIN_MHZ (30) +#define FREQ_MAX_MHZ (6000) + #if defined _WIN32 #define sleep(a) Sleep( (a*1000) ) #endif @@ -59,6 +62,30 @@ 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_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 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; + } +} + FILE* fd = NULL; volatile uint32_t byte_count = 0; @@ -67,6 +94,9 @@ bool transmit = false; struct timeval time_start; struct timeval t_start; +bool freq = false; +uint32_t freq_mhz; + int rx_callback(hackrf_transfer* transfer) { if( fd != NULL ) { @@ -105,6 +135,7 @@ static void usage() { printf("Usage:\n"); printf("\t-r # Receive data into file.\n"); printf("\t-t # Transmit data from file.\n"); + printf("\t-f # Set Frequency in MHz (between [%ld, %ld[).\n", FREQ_MIN_MHZ, FREQ_MAX_MHZ); } static hackrf_device* device = NULL; @@ -168,8 +199,10 @@ void sigint_callback_handler(int signum) int main(int argc, char** argv) { int opt; const char* path = NULL; + int result; - while( (opt = getopt(argc, argv, "r:t:")) != EOF ) { + while( (opt = getopt(argc, argv, "r:t:f:")) != EOF ) { + result = HACKRF_SUCCESS; switch( opt ) { case 'r': receive = true; @@ -181,10 +214,26 @@ int main(int argc, char** argv) { path = optarg; break; + case 'f': + freq = true; + result = parse_int(optarg, &freq_mhz); + break; + default: usage(); return EXIT_FAILURE; } + + if( result != HACKRF_SUCCESS ) { + printf("argument error: %s (%d)\n", hackrf_error_name(result), result); + usage(); + break; + } + } + + if( freq ) { + if( (freq_mhz >= 6000) || (freq_mhz < 30) ) + printf("argument error: frequency shall be between [%ld, %ld[.\n", FREQ_MIN_MHZ, FREQ_MAX_MHZ); } if( transmit == receive ) @@ -213,7 +262,7 @@ int main(int argc, char** argv) { return EXIT_FAILURE; } - int result = hackrf_init(); + result = hackrf_init(); if( result != HACKRF_SUCCESS ) { printf("hackrf_init() failed: %s (%d)\n", hackrf_error_name(result), result); usage(); @@ -262,6 +311,15 @@ int main(int argc, char** argv) { return EXIT_FAILURE; } + if( freq ) { + printf("call hackrf_set_freq(%ld MHz)\n", freq_mhz); + result = hackrf_set_freq(device, freq_mhz); + if( result != HACKRF_SUCCESS ) { + printf("hackrf_set_freq() failed: %s (%d)\n", hackrf_error_name(result), result); + return EXIT_FAILURE; + } + } + gettimeofday(&t_start, NULL); gettimeofday(&time_start, NULL); diff --git a/host/libhackrf/src/hackrf.c b/host/libhackrf/src/hackrf.c index a5e7872c..a069f896 100644 --- a/host/libhackrf/src/hackrf.c +++ b/host/libhackrf/src/hackrf.c @@ -44,7 +44,8 @@ typedef enum { HACKRF_VENDOR_REQUEST_SPIFLASH_READ = 12, HACKRF_VENDOR_REQUEST_CPLD_WRITE = 13, HACKRF_VENDOR_REQUEST_BOARD_ID_READ = 14, - HACKRF_VENDOR_REQUEST_VERSION_STRING_READ = 15 + HACKRF_VENDOR_REQUEST_VERSION_STRING_READ = 15, + HACKRF_VENDOR_REQUEST_SET_FREQ = 16 } hackrf_vendor_request; typedef enum { @@ -569,6 +570,26 @@ int hackrf_version_string_read(hackrf_device* device, char* version, } } +int hackrf_set_freq(hackrf_device* device, const uint32_t freq_mhz) { + /* TODO add freq_hz in addition from 0 to 999999Hz */ + int result = libusb_control_transfer( + device->usb_device, + LIBUSB_ENDPOINT_OUT | LIBUSB_REQUEST_TYPE_VENDOR | LIBUSB_RECIPIENT_DEVICE, + HACKRF_VENDOR_REQUEST_SET_FREQ, + freq_mhz & 0xffff, + freq_mhz >> 16, + NULL, + 0, + 0 + ); + + if( result != 0 ) { + return HACKRF_ERROR_LIBUSB; + } else { + return HACKRF_SUCCESS; + } +} + static void* transfer_threadproc(void* arg) { hackrf_device* device = (hackrf_device*)arg; diff --git a/host/libhackrf/src/hackrf.h b/host/libhackrf/src/hackrf.h index 67f18e1b..601ad12c 100644 --- a/host/libhackrf/src/hackrf.h +++ b/host/libhackrf/src/hackrf.h @@ -93,6 +93,8 @@ int hackrf_board_id_read(hackrf_device* device, uint8_t* value); int hackrf_version_string_read(hackrf_device* device, char* version, uint8_t length); +int hackrf_set_freq(hackrf_device* device, const uint32_t freq_mhz); + const char* hackrf_error_name(enum hackrf_error errcode); const char* hackrf_board_id_name(enum hackrf_board_id board_id); From e3784c886ecc505f643f294cd79955424aefa1b9 Mon Sep 17 00:00:00 2001 From: TitanMKD Date: Thu, 7 Mar 2013 23:24:00 +0100 Subject: [PATCH 2/2] set_freq for firmware & host. tested basicly checking with debugger value mhz/hz from host to fw. --- firmware/common/hackrf_core.c | 2 +- firmware/usb_performance/usb_performance.c | 28 ++++++++++++++----- host/libhackrf/examples/hackrf_transfer.c | 24 ++++++++--------- host/libhackrf/src/hackrf.c | 31 +++++++++++++++++----- host/libhackrf/src/hackrf.h | 4 +-- 5 files changed, 61 insertions(+), 28 deletions(-) diff --git a/firmware/common/hackrf_core.c b/firmware/common/hackrf_core.c index ca19304f..cfcabfa8 100644 --- a/firmware/common/hackrf_core.c +++ b/firmware/common/hackrf_core.c @@ -410,7 +410,7 @@ void enable_1v8_power(void) { } /* -Set freq/tuning between 30MHz to 6000 MHz +Set freq/tuning between 30MHz to 6000 MHz (less than 16bits really used) hz between 0 to 999999 Hz (not checked) return false on error or true if success. */ diff --git a/firmware/usb_performance/usb_performance.c b/firmware/usb_performance/usb_performance.c index 3243e94d..06e0c111 100644 --- a/firmware/usb_performance/usb_performance.c +++ b/firmware/usb_performance/usb_performance.c @@ -53,6 +53,15 @@ const uint_fast8_t usb_td_bulk_count = sizeof(usb_td_bulk) / sizeof(usb_td_bulk[ uint8_t spiflash_buffer[W25Q80BV_PAGE_LEN]; char version_string[] = VERSION_STRING; +typedef struct { + uint32_t freq_mhz; + uint32_t freq_hz; +} set_freq_params_t; + +set_freq_params_t set_freq_params; + +uint8_t spiflash_buffer[W25Q80BV_PAGE_LEN]; + uint8_t switchctrl = 0; static void usb_init_buffers_bulk() { @@ -497,17 +506,22 @@ usb_request_status_t usb_vendor_request_read_version_string( usb_request_status_t usb_vendor_request_set_freq( usb_endpoint_t* const endpoint, - const usb_transfer_stage_t stage -) { - if( stage == USB_TRANSFER_STAGE_SETUP ) { - const uint32_t freq_mhz = (endpoint->setup.index << 16) | endpoint->setup.value; - const uint32_t freq_hz = 0; /* TODO fix this and retrieve a 32bits */ - if( set_freq(freq_mhz, freq_hz) ) { + const usb_transfer_stage_t stage) +{ + if (stage == USB_TRANSFER_STAGE_SETUP) + { + usb_endpoint_schedule(endpoint->out, &set_freq_params, sizeof(set_freq_params_t)); + return USB_REQUEST_STATUS_OK; + } else if (stage == USB_TRANSFER_STAGE_DATA) + { + if( set_freq(set_freq_params.freq_mhz, set_freq_params.freq_hz) ) + { usb_endpoint_schedule_ack(endpoint->in); return USB_REQUEST_STATUS_OK; } return USB_REQUEST_STATUS_STALL; - } else { + } else + { return USB_REQUEST_STATUS_OK; } } diff --git a/host/libhackrf/examples/hackrf_transfer.c b/host/libhackrf/examples/hackrf_transfer.c index 99724805..8f6b8595 100644 --- a/host/libhackrf/examples/hackrf_transfer.c +++ b/host/libhackrf/examples/hackrf_transfer.c @@ -42,8 +42,8 @@ #include #include -#define FREQ_MIN_MHZ (30) -#define FREQ_MAX_MHZ (6000) +#define FREQ_MIN_HZ (30000000ull) /* 30MHz */ +#define FREQ_MAX_HZ (6000000000ull) /* 6000MHz */ #if defined _WIN32 #define sleep(a) Sleep( (a*1000) ) @@ -62,7 +62,7 @@ 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_int(char* s, uint32_t* const value) { +int parse_u64(char* s, uint64_t* const value) { uint_fast8_t base = 10; if( strlen(s) > 2 ) { if( s[0] == '0' ) { @@ -77,9 +77,9 @@ int parse_int(char* s, uint32_t* const value) { } char* s_end = s; - const unsigned long ulong_value = strtoul(s, &s_end, base); + const unsigned long long u64_value = strtoull(s, &s_end, base); if( (s != s_end) && (*s_end == 0) ) { - *value = ulong_value; + *value = u64_value; return HACKRF_SUCCESS; } else { return HACKRF_ERROR_INVALID_PARAM; @@ -95,7 +95,7 @@ struct timeval time_start; struct timeval t_start; bool freq = false; -uint32_t freq_mhz; +uint64_t freq_hz; int rx_callback(hackrf_transfer* transfer) { if( fd != NULL ) @@ -135,7 +135,7 @@ static void usage() { printf("Usage:\n"); printf("\t-r # Receive data into file.\n"); printf("\t-t # Transmit data from file.\n"); - printf("\t-f # Set Frequency in MHz (between [%ld, %ld[).\n", FREQ_MIN_MHZ, FREQ_MAX_MHZ); + printf("\t-f # Set Frequency in MHz (between [%lld, %lld[).\n", FREQ_MIN_HZ, FREQ_MAX_HZ); } static hackrf_device* device = NULL; @@ -216,7 +216,7 @@ int main(int argc, char** argv) { case 'f': freq = true; - result = parse_int(optarg, &freq_mhz); + result = parse_u64(optarg, &freq_hz); break; default: @@ -232,8 +232,8 @@ int main(int argc, char** argv) { } if( freq ) { - if( (freq_mhz >= 6000) || (freq_mhz < 30) ) - printf("argument error: frequency shall be between [%ld, %ld[.\n", FREQ_MIN_MHZ, FREQ_MAX_MHZ); + if( (freq_hz >= FREQ_MAX_HZ) || (freq_hz < FREQ_MIN_HZ) ) + printf("argument error: frequency shall be between [%lld, %lld[.\n", FREQ_MIN_HZ, FREQ_MAX_HZ); } if( transmit == receive ) @@ -312,8 +312,8 @@ int main(int argc, char** argv) { } if( freq ) { - printf("call hackrf_set_freq(%ld MHz)\n", freq_mhz); - result = hackrf_set_freq(device, freq_mhz); + printf("call hackrf_set_freq(%lld Hz)\n", freq_hz); + result = hackrf_set_freq(device, freq_hz); if( result != HACKRF_SUCCESS ) { printf("hackrf_set_freq() failed: %s (%d)\n", hackrf_error_name(result), result); return EXIT_FAILURE; diff --git a/host/libhackrf/src/hackrf.c b/host/libhackrf/src/hackrf.c index a069f896..379da48a 100644 --- a/host/libhackrf/src/hackrf.c +++ b/host/libhackrf/src/hackrf.c @@ -570,20 +570,39 @@ int hackrf_version_string_read(hackrf_device* device, char* version, } } -int hackrf_set_freq(hackrf_device* device, const uint32_t freq_mhz) { - /* TODO add freq_hz in addition from 0 to 999999Hz */ +typedef struct { + uint32_t freq_mhz; /* From 30 to 6000MHz */ + uint32_t freq_hz; /* From 0 to 999999Hz */ + /* Final Freq = freq_mhz+freq_hz */ +} set_freq_params_t; +#define FREQ_ONE_MHZ (1000*1000ull) + +int hackrf_set_freq(hackrf_device* device, const uint64_t freq_hz) +{ + uint32_t l_freq_mhz; + uint32_t l_freq_hz; + set_freq_params_t set_freq_params; + uint8_t length; + + /* Convert Freq Hz 64bits to Freq MHz (32bits) & Freq Hz (32bits) */ + l_freq_mhz = (uint32_t)(freq_hz / FREQ_ONE_MHZ); + l_freq_hz = (uint32_t)(freq_hz - (((uint64_t)l_freq_mhz) * FREQ_ONE_MHZ)); + set_freq_params.freq_mhz = l_freq_mhz; + set_freq_params.freq_hz = l_freq_hz; + length = sizeof(set_freq_params_t); + int result = libusb_control_transfer( device->usb_device, LIBUSB_ENDPOINT_OUT | LIBUSB_REQUEST_TYPE_VENDOR | LIBUSB_RECIPIENT_DEVICE, HACKRF_VENDOR_REQUEST_SET_FREQ, - freq_mhz & 0xffff, - freq_mhz >> 16, - NULL, 0, + 0, + (unsigned char*)&set_freq_params, + length, 0 ); - if( result != 0 ) { + if (result < length) { return HACKRF_ERROR_LIBUSB; } else { return HACKRF_SUCCESS; diff --git a/host/libhackrf/src/hackrf.h b/host/libhackrf/src/hackrf.h index 601ad12c..31775142 100644 --- a/host/libhackrf/src/hackrf.h +++ b/host/libhackrf/src/hackrf.h @@ -93,8 +93,8 @@ int hackrf_board_id_read(hackrf_device* device, uint8_t* value); int hackrf_version_string_read(hackrf_device* device, char* version, uint8_t length); -int hackrf_set_freq(hackrf_device* device, const uint32_t freq_mhz); - +int hackrf_set_freq(hackrf_device* device, const uint64_t freq_hz); + const char* hackrf_error_name(enum hackrf_error errcode); const char* hackrf_board_id_name(enum hackrf_board_id board_id);