Draft in progress (not tested at all) set_freq().

This commit is contained in:
TitanMKD
2013-02-26 00:17:18 +01:00
parent f150732215
commit e2c05fbfe2
6 changed files with 195 additions and 4 deletions

View File

@ -1,6 +1,7 @@
/* /*
* Copyright 2012 Michael Ossmann <mike@ossmann.com> * Copyright 2012 Michael Ossmann <mike@ossmann.com>
* Copyright 2012 Jared Boone <jared@sharebrained.com> * Copyright 2012 Jared Boone <jared@sharebrained.com>
* Copyright 2013 Benjamin Vernoux <titanmkd@gmail.com>
* *
* This file is part of HackRF. * This file is part of HackRF.
* *
@ -23,12 +24,28 @@
#include "hackrf_core.h" #include "hackrf_core.h"
#include "si5351c.h" #include "si5351c.h"
#include "max2837.h" #include "max2837.h"
#include "rffc5071.h"
#include <libopencm3/lpc43xx/i2c.h> #include <libopencm3/lpc43xx/i2c.h>
#include <libopencm3/lpc43xx/cgu.h> #include <libopencm3/lpc43xx/cgu.h>
#include <libopencm3/lpc43xx/gpio.h> #include <libopencm3/lpc43xx/gpio.h>
#include <libopencm3/lpc43xx/scu.h> #include <libopencm3/lpc43xx/scu.h>
#include <libopencm3/lpc43xx/ssp.h> #include <libopencm3/lpc43xx/ssp.h>
/* 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) void delay(uint32_t duration)
{ {
uint32_t i; uint32_t i;
@ -391,3 +408,76 @@ void pin_setup(void) {
void enable_1v8_power(void) { void enable_1v8_power(void) {
gpio_set(PORT_EN1V8, PIN_EN1V8); 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;
}

View File

@ -258,6 +258,8 @@ void enable_1v8_power(void);
bool sample_rate_set(const uint32_t sampling_rate_hz); bool sample_rate_set(const uint32_t sampling_rate_hz);
bool baseband_filter_bandwidth_set(const uint32_t bandwidth_hz); bool baseband_filter_bandwidth_set(const uint32_t bandwidth_hz);
bool set_freq(uint32_t freq_mhz, uint32_t freq_hz);
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif

View File

@ -491,6 +491,23 @@ usb_request_status_t usb_vendor_request_read_version_string(
return USB_REQUEST_STATUS_OK; 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[] = { static const usb_request_handler_fn vendor_request_handler[] = {
NULL, NULL,
usb_vendor_request_set_transceiver_mode, 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_read_spiflash,
usb_vendor_request_write_cpld, usb_vendor_request_write_cpld,
usb_vendor_request_read_board_id, 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 = static const uint32_t vendor_request_handler_count =

View File

@ -42,6 +42,9 @@
#include <sys/time.h> #include <sys/time.h>
#include <signal.h> #include <signal.h>
#define FREQ_MIN_MHZ (30)
#define FREQ_MAX_MHZ (6000)
#if defined _WIN32 #if defined _WIN32
#define sleep(a) Sleep( (a*1000) ) #define sleep(a) Sleep( (a*1000) )
#endif #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); 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; FILE* fd = NULL;
volatile uint32_t byte_count = 0; volatile uint32_t byte_count = 0;
@ -67,6 +94,9 @@ bool transmit = false;
struct timeval time_start; struct timeval time_start;
struct timeval t_start; struct timeval t_start;
bool freq = false;
uint32_t freq_mhz;
int rx_callback(hackrf_transfer* transfer) { int rx_callback(hackrf_transfer* transfer) {
if( fd != NULL ) if( fd != NULL )
{ {
@ -105,6 +135,7 @@ static void usage() {
printf("Usage:\n"); printf("Usage:\n");
printf("\t-r <filename> # Receive data into file.\n"); printf("\t-r <filename> # Receive data into file.\n");
printf("\t-t <filename> # Transmit data from file.\n"); printf("\t-t <filename> # Transmit data from file.\n");
printf("\t-f <set_freq_MHz> # Set Frequency in MHz (between [%ld, %ld[).\n", FREQ_MIN_MHZ, FREQ_MAX_MHZ);
} }
static hackrf_device* device = NULL; static hackrf_device* device = NULL;
@ -168,8 +199,10 @@ void sigint_callback_handler(int signum)
int main(int argc, char** argv) { int main(int argc, char** argv) {
int opt; int opt;
const char* path = NULL; 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 ) { switch( opt ) {
case 'r': case 'r':
receive = true; receive = true;
@ -181,10 +214,26 @@ int main(int argc, char** argv) {
path = optarg; path = optarg;
break; break;
case 'f':
freq = true;
result = parse_int(optarg, &freq_mhz);
break;
default: default:
usage(); usage();
return EXIT_FAILURE; 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 ) if( transmit == receive )
@ -213,7 +262,7 @@ int main(int argc, char** argv) {
return EXIT_FAILURE; return EXIT_FAILURE;
} }
int result = hackrf_init(); result = hackrf_init();
if( result != HACKRF_SUCCESS ) { if( result != HACKRF_SUCCESS ) {
printf("hackrf_init() failed: %s (%d)\n", hackrf_error_name(result), result); printf("hackrf_init() failed: %s (%d)\n", hackrf_error_name(result), result);
usage(); usage();
@ -262,6 +311,15 @@ int main(int argc, char** argv) {
return EXIT_FAILURE; 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(&t_start, NULL);
gettimeofday(&time_start, NULL); gettimeofday(&time_start, NULL);

View File

@ -44,7 +44,8 @@ typedef enum {
HACKRF_VENDOR_REQUEST_SPIFLASH_READ = 12, HACKRF_VENDOR_REQUEST_SPIFLASH_READ = 12,
HACKRF_VENDOR_REQUEST_CPLD_WRITE = 13, HACKRF_VENDOR_REQUEST_CPLD_WRITE = 13,
HACKRF_VENDOR_REQUEST_BOARD_ID_READ = 14, 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; } hackrf_vendor_request;
typedef enum { 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) { static void* transfer_threadproc(void* arg) {
hackrf_device* device = (hackrf_device*)arg; hackrf_device* device = (hackrf_device*)arg;

View File

@ -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, int hackrf_version_string_read(hackrf_device* device, char* version,
uint8_t length); 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_error_name(enum hackrf_error errcode);
const char* hackrf_board_id_name(enum hackrf_board_id board_id); const char* hackrf_board_id_name(enum hackrf_board_id board_id);