Add USB vendor requests to read/write Si5351C registers.
This commit is contained in:
@ -45,6 +45,9 @@ void si5351c_configure_multisynth(const uint_fast8_t ms_number,
|
||||
void si5351c_configure_clock_control();
|
||||
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
|
||||
}
|
||||
#endif
|
||||
|
@ -27,6 +27,7 @@
|
||||
#include <libopencm3/lpc43xx/sgpio.h>
|
||||
|
||||
#include <hackrf_core.h>
|
||||
#include <si5351c.h>
|
||||
#include <max5864.h>
|
||||
#include <max2837.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(
|
||||
usb_endpoint_t* const endpoint,
|
||||
const usb_transfer_stage_t stage
|
||||
|
@ -24,9 +24,11 @@ option(EXAMPLES "Build example programs" ON)
|
||||
|
||||
IF( EXAMPLES )
|
||||
add_executable(hackrf_max2837 hackrf_max2837.c)
|
||||
add_executable(hackrf_si5351c hackrf_si5351c.c)
|
||||
add_executable(hackrf_transfer hackrf_transfer.c)
|
||||
|
||||
target_link_libraries(hackrf_max2837 hackrf)
|
||||
target_link_libraries(hackrf_si5351c hackrf)
|
||||
target_link_libraries(hackrf_transfer hackrf)
|
||||
|
||||
include_directories(BEFORE ${CMAKE_SOURCE_DIR}/src)
|
||||
|
161
host/libhackrf/examples/hackrf_si5351c.c
Normal file
161
host/libhackrf/examples/hackrf_si5351c.c
Normal 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, ®ister_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, ®ister_number);
|
||||
break;
|
||||
|
||||
case 'w':
|
||||
result = parse_int(optarg, ®ister_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;
|
||||
}
|
@ -32,6 +32,8 @@ typedef enum {
|
||||
HACKRF_VENDOR_REQUEST_SET_TRANSCEIVER_MODE = 1,
|
||||
HACKRF_VENDOR_REQUEST_MAX2837_WRITE = 2,
|
||||
HACKRF_VENDOR_REQUEST_MAX2837_READ = 3,
|
||||
HACKRF_VENDOR_REQUEST_SI5351C_WRITE = 4,
|
||||
HACKRF_VENDOR_REQUEST_SI5351C_READ = 5,
|
||||
} hackrf_vendor_request;
|
||||
|
||||
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) {
|
||||
hackrf_device* device = (hackrf_device*)arg;
|
||||
|
||||
|
@ -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_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);
|
||||
|
||||
#endif//__HACKRF_H__
|
||||
|
Reference in New Issue
Block a user