Add USB vendor requests to read/write Si5351C registers.

This commit is contained in:
Jared Boone
2012-10-17 11:57:44 -07:00
parent 7fdfde9314
commit 6babcbe579
6 changed files with 259 additions and 0 deletions

View File

@ -45,6 +45,9 @@ void si5351c_configure_multisynth(const uint_fast8_t ms_number,
void si5351c_configure_clock_control(); void si5351c_configure_clock_control();
void si5351c_enable_clock_outputs(); void si5351c_enable_clock_outputs();
void si5351c_write_single(uint8_t reg, uint8_t val);
uint8_t si5351c_read_single(uint8_t reg);
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif

View File

@ -27,6 +27,7 @@
#include <libopencm3/lpc43xx/sgpio.h> #include <libopencm3/lpc43xx/sgpio.h>
#include <hackrf_core.h> #include <hackrf_core.h>
#include <si5351c.h>
#include <max5864.h> #include <max5864.h>
#include <max2837.h> #include <max2837.h>
#include <rffc5071.h> #include <rffc5071.h>
@ -252,6 +253,42 @@ bool usb_vendor_request_read_max2837(
} }
} }
bool usb_vendor_request_write_si5351c(
usb_endpoint_t* const endpoint,
const usb_transfer_stage_t stage
) {
if( stage == USB_TRANSFER_STAGE_SETUP ) {
if( endpoint->setup.index < 256 ) {
if( endpoint->setup.value < 256 ) {
si5351c_write_single(endpoint->setup.index, endpoint->setup.value);
usb_endpoint_schedule_ack(endpoint->in);
return true;
}
}
return false;
} else {
return true;
}
}
bool usb_vendor_request_read_si5351c(
usb_endpoint_t* const endpoint,
const usb_transfer_stage_t stage
) {
if( stage == USB_TRANSFER_STAGE_SETUP ) {
if( endpoint->setup.index < 256 ) {
const uint8_t value = si5351c_read_single(endpoint->setup.index);
endpoint->buffer[0] = value;
usb_endpoint_schedule(endpoint->in, &endpoint->buffer, 1);
usb_endpoint_schedule_ack(endpoint->out);
return true;
}
return false;
} else {
return true;
}
}
void usb_vendor_request( void usb_vendor_request(
usb_endpoint_t* const endpoint, usb_endpoint_t* const endpoint,
const usb_transfer_stage_t stage const usb_transfer_stage_t stage

View File

@ -24,9 +24,11 @@ option(EXAMPLES "Build example programs" ON)
IF( EXAMPLES ) IF( EXAMPLES )
add_executable(hackrf_max2837 hackrf_max2837.c) add_executable(hackrf_max2837 hackrf_max2837.c)
add_executable(hackrf_si5351c hackrf_si5351c.c)
add_executable(hackrf_transfer hackrf_transfer.c) add_executable(hackrf_transfer hackrf_transfer.c)
target_link_libraries(hackrf_max2837 hackrf) target_link_libraries(hackrf_max2837 hackrf)
target_link_libraries(hackrf_si5351c hackrf)
target_link_libraries(hackrf_transfer hackrf) target_link_libraries(hackrf_transfer hackrf)
include_directories(BEFORE ${CMAKE_SOURCE_DIR}/src) include_directories(BEFORE ${CMAKE_SOURCE_DIR}/src)

View File

@ -0,0 +1,161 @@
/*
* Copyright 2012 Jared Boone <jared@sharebrained.com>
*
* This file is part of HackRF.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2, or (at your option)
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; see the file COPYING. If not, write to
* the Free Software Foundation, Inc., 51 Franklin Street,
* Boston, MA 02110-1301, USA.
*/
#include <hackrf.h>
#include <stdio.h>
#include <stdlib.h>
#include <getopt.h>
static void usage() {
printf("\nUsage:\n");
printf("\t-n, --register <n>: set register number for subsequent read/write operations\n");
printf("\t-r, --read: read register specified by last -n argument, or all registers\n");
printf("\t-w, --write <v>: write register specified by last -n argument with value <v>\n");
printf("\nExamples:\n");
printf("\t<command> -n 12 -r # reads from register 12\n");
printf("\t<command> -r # reads all registers\n");
printf("\t<command> -n 10 -w 22 # writes register 10 with 22 decimal\n");
}
static struct option long_options[] = {
{ "register", required_argument, 0, 'n' },
{ "write", required_argument, 0, 'w' },
{ "read", no_argument, 0, 'r' },
{ 0, 0, 0, 0 },
};
int parse_int(char* const s, uint16_t* const value) {
char* s_end = s;
const long long_value = strtol(s, &s_end, 10);
if( (s != s_end) && (*s_end == 0) ) {
*value = long_value;
return HACKRF_SUCCESS;
} else {
return HACKRF_ERROR_INVALID_PARAM;
}
}
int dump_register(hackrf_device* device, const uint16_t register_number) {
uint16_t register_value;
int result = hackrf_si5351c_read(device, register_number, &register_value);
if( result == HACKRF_SUCCESS ) {
printf("[%3d] -> 0x%02x\n", register_number, register_value);
} else {
printf("hackrf_max2837_read() failed: %s (%d)\n", hackrf_error_name(result), result);
}
return result;
}
int dump_registers(hackrf_device* device) {
int result = HACKRF_SUCCESS;
for(uint16_t register_number=0; register_number<256; register_number++) {
result = dump_register(device, register_number);
if( result != HACKRF_SUCCESS ) {
break;
}
}
return result;
}
int write_register(
hackrf_device* device,
const uint16_t register_number,
const uint16_t register_value
) {
int result = HACKRF_SUCCESS;
result = hackrf_si5351c_write(device, register_number, register_value);
if( result == HACKRF_SUCCESS ) {
printf("0x%2x -> [%3d]\n", register_value, register_number);
} else {
printf("hackrf_max2837_write() failed: %s (%d)\n", hackrf_error_name(result), result);
}
return result;
}
#define REGISTER_INVALID 32767
int main(int argc, char** argv) {
int opt;
uint16_t register_number = REGISTER_INVALID;
uint16_t register_value;
int result = hackrf_init();
if( result ) {
printf("hackrf_init() failed: %s (%d)\n", hackrf_error_name(result), result);
return -1;
}
hackrf_device* device = NULL;
result = hackrf_open(&device);
if( result ) {
printf("hackrf_open() failed: %s (%d)\n", hackrf_error_name(result), result);
return -1;
}
int option_index = 0;
while( (opt = getopt_long(argc, argv, "n:rw:", long_options, &option_index)) != EOF ) {
switch( opt ) {
case 'n':
result = parse_int(optarg, &register_number);
break;
case 'w':
result = parse_int(optarg, &register_value);
if( result == HACKRF_SUCCESS ) {
result = write_register(device, register_number, register_value);
}
break;
case 'r':
if( register_number == REGISTER_INVALID ) {
result = dump_registers(device);
} else {
result = dump_register(device, register_number);
}
break;
default:
usage();
}
if( result != HACKRF_SUCCESS ) {
printf("argument error: %s (%d)\n", hackrf_error_name(result), result);
break;
}
}
result = hackrf_close(device);
if( result ) {
printf("hackrf_close() failed: %s (%d)\n", hackrf_error_name(result), result);
return -1;
}
hackrf_exit();
return 0;
}

View File

@ -32,6 +32,8 @@ typedef enum {
HACKRF_VENDOR_REQUEST_SET_TRANSCEIVER_MODE = 1, HACKRF_VENDOR_REQUEST_SET_TRANSCEIVER_MODE = 1,
HACKRF_VENDOR_REQUEST_MAX2837_WRITE = 2, HACKRF_VENDOR_REQUEST_MAX2837_WRITE = 2,
HACKRF_VENDOR_REQUEST_MAX2837_READ = 3, HACKRF_VENDOR_REQUEST_MAX2837_READ = 3,
HACKRF_VENDOR_REQUEST_SI5351C_WRITE = 4,
HACKRF_VENDOR_REQUEST_SI5351C_READ = 5,
} hackrf_vendor_request; } hackrf_vendor_request;
typedef enum { typedef enum {
@ -280,6 +282,57 @@ int hackrf_max2837_write(hackrf_device* device, uint8_t register_number, uint16_
} }
} }
int hackrf_si5351c_read(hackrf_device* device, uint16_t register_number, uint16_t* value) {
if( register_number >= 256 ) {
return HACKRF_ERROR_INVALID_PARAM;
}
uint8_t temp_value = 0;
int result = libusb_control_transfer(
device->usb_device,
LIBUSB_ENDPOINT_IN | LIBUSB_REQUEST_TYPE_VENDOR | LIBUSB_RECIPIENT_DEVICE,
HACKRF_VENDOR_REQUEST_SI5351C_READ,
0,
register_number,
(unsigned char*)&temp_value,
1,
0
);
if( result < 1 ) {
return HACKRF_ERROR_LIBUSB;
} else {
*value = temp_value;
return HACKRF_SUCCESS;
}
}
int hackrf_si5351c_write(hackrf_device* device, uint16_t register_number, uint16_t value) {
if( register_number >= 256 ) {
return HACKRF_ERROR_INVALID_PARAM;
}
if( value >= 256 ) {
return HACKRF_ERROR_INVALID_PARAM;
}
int result = libusb_control_transfer(
device->usb_device,
LIBUSB_ENDPOINT_OUT | LIBUSB_REQUEST_TYPE_VENDOR | LIBUSB_RECIPIENT_DEVICE,
HACKRF_VENDOR_REQUEST_SI5351C_WRITE,
value,
register_number,
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

@ -66,6 +66,9 @@ bool hackrf_is_streaming(hackrf_device* device);
int hackrf_max2837_read(hackrf_device* device, uint8_t register_number, uint16_t* value); int hackrf_max2837_read(hackrf_device* device, uint8_t register_number, uint16_t* value);
int hackrf_max2837_write(hackrf_device* device, uint8_t register_number, uint16_t value); int hackrf_max2837_write(hackrf_device* device, uint8_t register_number, uint16_t value);
int hackrf_si5351c_read(hackrf_device* device, uint16_t register_number, uint16_t* value);
int hackrf_si5351c_write(hackrf_device* device, uint16_t register_number, uint16_t value);
const char* hackrf_error_name(enum hackrf_error errcode); const char* hackrf_error_name(enum hackrf_error errcode);
#endif//__HACKRF_H__ #endif//__HACKRF_H__