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_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
|
||||||
|
@ -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
|
||||||
|
@ -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)
|
||||||
|
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_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;
|
||||||
|
|
||||||
|
@ -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__
|
||||||
|
Reference in New Issue
Block a user