Merge pull request #35 from TitanMKD/master
set_freq for firmware & host to be tested with jawbreaker.
This commit is contained in:
@ -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 (less than 16bits really used)
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
@ -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
|
||||||
|
@ -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];
|
uint8_t spiflash_buffer[W25Q80BV_PAGE_LEN];
|
||||||
char version_string[] = VERSION_STRING;
|
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;
|
uint8_t switchctrl = 0;
|
||||||
|
|
||||||
static void usb_init_buffers_bulk() {
|
static void usb_init_buffers_bulk() {
|
||||||
@ -495,6 +504,28 @@ 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)
|
||||||
|
{
|
||||||
|
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
|
||||||
|
{
|
||||||
|
return USB_REQUEST_STATUS_OK;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
usb_request_status_t usb_vendor_request_set_amp_enable(
|
usb_request_status_t usb_vendor_request_set_amp_enable(
|
||||||
usb_endpoint_t* const endpoint, const usb_transfer_stage_t stage)
|
usb_endpoint_t* const endpoint, const usb_transfer_stage_t stage)
|
||||||
{
|
{
|
||||||
@ -543,6 +574,7 @@ static const usb_request_handler_fn vendor_request_handler[] = {
|
|||||||
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,
|
||||||
usb_vendor_request_set_amp_enable
|
usb_vendor_request_set_amp_enable
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -42,6 +42,9 @@
|
|||||||
#include <sys/time.h>
|
#include <sys/time.h>
|
||||||
#include <signal.h>
|
#include <signal.h>
|
||||||
|
|
||||||
|
#define FREQ_MIN_HZ (30000000ull) /* 30MHz */
|
||||||
|
#define FREQ_MAX_HZ (6000000000ull) /* 6000MHz */
|
||||||
|
|
||||||
#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_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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
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;
|
||||||
|
uint64_t freq_hz;
|
||||||
|
|
||||||
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 [%lld, %lld[).\n", FREQ_MIN_HZ, FREQ_MAX_HZ);
|
||||||
}
|
}
|
||||||
|
|
||||||
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_u64(optarg, &freq_hz);
|
||||||
|
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_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 )
|
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(%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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
gettimeofday(&t_start, NULL);
|
gettimeofday(&t_start, NULL);
|
||||||
gettimeofday(&time_start, NULL);
|
gettimeofday(&time_start, NULL);
|
||||||
|
|
||||||
|
@ -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,45 @@ int hackrf_version_string_read(hackrf_device* device, char* version,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
(unsigned char*)&set_freq_params,
|
||||||
|
length,
|
||||||
|
0
|
||||||
|
);
|
||||||
|
|
||||||
|
if (result < length) {
|
||||||
|
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;
|
||||||
|
|
||||||
|
@ -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 uint64_t freq_hz);
|
||||||
|
|
||||||
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);
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user