This commit is contained in:
Jared Boone
2013-02-27 16:46:16 -08:00
18 changed files with 403 additions and 62 deletions

View File

@ -34,12 +34,15 @@ HACKRF_OPTS = -D$(BOARD)
# comment to disable RF transmission
HACKRF_OPTS += -DTX_ENABLE
# automatic git version when working out of git
VERSION_STRING ?= -D'VERSION_STRING="git-$(shell git log -n 1 --format=%h)"'
HACKRF_OPTS += $(VERSION_STRING)
LDSCRIPT ?= ../common/LPC4330_M4.ld
LIBOPENCM3 ?= /usr/local/arm-none-eabi
PREFIX ?= arm-none-eabi
#PREFIX ?= arm-elf
CC = $(PREFIX)-gcc
LD = $(PREFIX)-gcc
OBJCOPY = $(PREFIX)-objcopy
@ -51,7 +54,6 @@ CFLAGS += -std=c99 -Os -g3 -Wall -Wextra -I$(LIBOPENCM3)/include -I../common \
-fno-common -mcpu=cortex-m4 -mthumb -MD \
-mfloat-abi=hard -mfpu=fpv4-sp-d16 \
$(HACKRF_OPTS)
#LDSCRIPT ?= $(BINARY).ld
LDFLAGS += -L$(TOOLCHAIN_DIR)/lib/armv7e-m/fpu \
-L../common \
-L$(LIBOPENCM3)/lib -L$(LIBOPENCM3)/lib/lpc43xx \

View File

@ -57,12 +57,16 @@ void cpld_jtag_release(void) {
GPIO_DIR(PORT_CPLD_TDI) &= ~PIN_CPLD_TDI;
}
void cpld_jtag_program(const uint32_t len, unsigned char* const data) {
/* return 0 if success else return error code see xsvfExecute() */
int cpld_jtag_program(const uint32_t len, unsigned char* const data) {
int error;
cpld_jtag_setup();
xsvf_data = data;
xsvf_len = len;
xsvfExecute();
error = xsvfExecute();
cpld_jtag_release();
return error;
}
/* this gets called by the XAPP058 code */

View File

@ -25,7 +25,8 @@
#include <stdint.h>
void cpld_jtag_release(void);
void cpld_jtag_program(const uint32_t len, unsigned char* const data);
/* return 0 if success else return error code see xsvfExecute() see micro.h */
int cpld_jtag_program(const uint32_t len, unsigned char* const data);
unsigned char cpld_jtag_get_next_byte(void);
#endif//__CPLD_JTAG_H__

View File

@ -239,8 +239,9 @@ extern "C"
/* TODO add other Pins */
typedef enum {
TRANSCEIVER_MODE_RX,
TRANSCEIVER_MODE_TX,
TRANSCEIVER_MODE_OFF = 0,
TRANSCEIVER_MODE_RX = 1,
TRANSCEIVER_MODE_TX = 2
} transceiver_mode_t;
void delay(uint32_t duration);

View File

@ -222,6 +222,7 @@ void max2837_start(void)
set_MAX2837_EN_SPI(1);
max2837_regs_commit();
#if !defined TEST
gpio_clear(PORT_XCVR_ENABLE, (PIN_XCVR_RXENABLE | PIN_XCVR_TXENABLE));
gpio_set(PORT_XCVR_ENABLE, PIN_XCVR_ENABLE);
#endif
}
@ -234,6 +235,7 @@ void max2837_tx(void)
set_MAX2837_ModeCtrl(MAX2837_ModeCtrl_TxLPF);
max2837_regs_commit();
gpio_clear(PORT_XCVR_ENABLE, PIN_XCVR_RXENABLE);
gpio_set(PORT_XCVR_ENABLE, PIN_XCVR_TXENABLE);
#endif
}
@ -246,6 +248,7 @@ void max2837_rx(void)
max2837_regs_commit();
#if !defined TEST
gpio_clear(PORT_XCVR_ENABLE, PIN_XCVR_TXENABLE);
gpio_set(PORT_XCVR_ENABLE, PIN_XCVR_RXENABLE);
#endif
}

View File

@ -160,7 +160,7 @@ void serial_delay(void)
{
uint32_t i;
for (i = 0; i < 1000; i++)
for (i = 0; i < 2; i++)
__asm__("nop");
}

View File

@ -22,6 +22,28 @@
//static int g_iTMS = 0; /* For xapp058_example .exe */
//static int g_iTDI = 0; /* For xapp058_example .exe */
void delay_jtag(uint32_t duration)
{
#define DIVISOR (1024)
#define MIN_NOP (8)
uint32_t i;
uint32_t delay_nop;
/* @204Mhz duration of about 400ns for delay_nop=20 */
if(duration < DIVISOR)
{
delay_nop = MIN_NOP;
}else
{
delay_nop = (duration / DIVISOR) + MIN_NOP;
}
for (i = 0; i < delay_nop; i++)
__asm__("nop");
}
#ifdef WIN95PP
#include "conio.h"
@ -127,7 +149,7 @@ void setPort(short p,short val)
}
/* conservative delay */
delay(20000);
delay_jtag(20000);
}
@ -135,9 +157,9 @@ void setPort(short p,short val)
void pulseClock()
{
setPort(TCK,0); /* set the TCK port to low */
delay(200);
delay_jtag(200);
setPort(TCK,1); /* set the TCK port to high */
delay(200);
delay_jtag(200);
}
@ -169,7 +191,7 @@ unsigned char readTDOBit()
/* You must return the current value of the JTAG TDO signal. */
//return( (unsigned char) 0 );
delay(2000);
delay_jtag(2000);
return CPLD_TDO_STATE;
}

View File

@ -26,26 +26,45 @@
#include "cpld_jtag.h"
#include "sgpio_if_xsvf.h"
#define WAIT_LOOP_DELAY (6000000)
#define ALL_LEDS (PIN_LED1|PIN_LED2|PIN_LED3)
int main(void)
{
int i;
int error;
int LED;
pin_setup();
/* Set 1V8 */
gpio_set(PORT_EN1V8, PIN_EN1V8);
cpu_clock_init();
/* program test bitstream to CPLD */
cpld_jtag_program(sgpio_if_xsvf_len, &sgpio_if_xsvf[0]);
error = cpld_jtag_program(sgpio_if_xsvf_len, &sgpio_if_xsvf[0]);
/* blink LED1 and LED3 */
while (1)
if(error == 0)
{
gpio_set(PORT_LED1_3, (PIN_LED1|PIN_LED3)); /* LEDs on */
for (i = 0; i < 2000000; i++) /* Wait a bit. */
/* blink only LED1 (Green) on success */
LED = PIN_LED1;
}else
{
/* blink LED3 (Red) on error */
LED = PIN_LED3;
}
gpio_clear(PORT_LED1_3, ALL_LEDS); /* All LEDs off */
while (1)
{
gpio_set(PORT_LED1_3, LED); /* LEDs on */
for (i = 0; i < WAIT_LOOP_DELAY; i++) /* Wait a bit. */
__asm__("nop");
gpio_clear(PORT_LED1_3, (PIN_LED1|PIN_LED3)); /* LED off */
for (i = 0; i < 2000000; i++) /* Wait a bit. */
gpio_clear(PORT_LED1_3, LED); /* LED off */
for (i = 0; i < WAIT_LOOP_DELAY; i++) /* Wait a bit. */
__asm__("nop");
}

View File

@ -0,0 +1,36 @@
# Hey Emacs, this is a -*- makefile -*-
#
# Copyright 2012 Michael Ossmann <mike@ossmann.com>
# 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.
#
BINARY = cpldjtagprog_rom_to_ram
SRC = $(BINARY).c \
../common/hackrf_core.c \
../common/si5351c.c \
../common/max2837.c \
../common/cpld_jtag.c \
../common/xapp058/lenval.c \
../common/xapp058/micro.c \
../common/xapp058/ports.c
LDSCRIPT = ../common/LPC4330_M4_rom_to_ram.ld
include ../common/Makefile_inc.mk

View File

@ -0,0 +1 @@
This is a test program for CPLD JTAG programming.

View File

@ -0,0 +1,72 @@
/*
* Copyright 2010 - 2013 Michael Ossmann
*
* 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 <libopencm3/lpc43xx/gpio.h>
#include <libopencm3/lpc43xx/scu.h>
#include "hackrf_core.h"
#include "cpld_jtag.h"
#include "../cpldjtagprog/sgpio_if_xsvf.h"
#define WAIT_LOOP_DELAY (6000000)
#define ALL_LEDS (PIN_LED1|PIN_LED2|PIN_LED3)
int main(void)
{
int i;
int error;
int LED;
pin_setup();
/* Set 1V8 */
gpio_set(PORT_EN1V8, PIN_EN1V8);
cpu_clock_init();
/* program test bitstream to CPLD */
error = cpld_jtag_program(sgpio_if_xsvf_len, &sgpio_if_xsvf[0]);
if(error == 0)
{
/* blink only LED1 (Green) on success */
LED = PIN_LED1;
}else
{
/* blink LED3 (Red) on error */
LED = PIN_LED3;
}
gpio_clear(PORT_LED1_3, ALL_LEDS); /* All LEDs off */
while (1)
{
gpio_set(PORT_LED1_3, LED); /* LEDs on */
for (i = 0; i < WAIT_LOOP_DELAY; i++) /* Wait a bit. */
__asm__("nop");
gpio_clear(PORT_LED1_3, LED); /* LED off */
for (i = 0; i < WAIT_LOOP_DELAY; i++) /* Wait a bit. */
__asm__("nop");
}
return 0;
}

View File

@ -0,0 +1,44 @@
# Hey Emacs, this is a -*- makefile -*-
#
# 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.
#
BINARY = usb_performance_rom_to_ram
SRC = usb_performance.c \
usb.c \
usb_request.c \
usb_standard_request.c \
usb_descriptor.c \
../common/fault_handler.c \
../common/hackrf_core.c \
../common/sgpio.c \
../common/si5351c.c \
../common/max2837.c \
../common/max5864.c \
../common/rffc5071.c \
../common/w25q80bv.c \
../common/cpld_jtag.c \
../common/xapp058/lenval.c \
../common/xapp058/micro.c \
../common/xapp058/ports.c
LDSCRIPT = ../common/LPC4330_M4_rom_to_ram.ld
include ../common/Makefile_inc.mk

View File

@ -41,7 +41,7 @@
#include "usb_descriptor.h"
#include "usb_standard_request.h"
static volatile transceiver_mode_t transceiver_mode = TRANSCEIVER_MODE_RX;
static volatile transceiver_mode_t transceiver_mode = TRANSCEIVER_MODE_OFF;
uint8_t* const usb_bulk_buffer = (uint8_t*)0x20004000;
static volatile uint32_t usb_bulk_buffer_offset = 0;
@ -50,6 +50,11 @@ static const uint32_t usb_bulk_buffer_mask = 32768 - 1;
usb_transfer_descriptor_t usb_td_bulk[2] ATTR_ALIGNED(64);
const uint_fast8_t usb_td_bulk_count = sizeof(usb_td_bulk) / sizeof(usb_td_bulk[0]);
uint8_t spiflash_buffer[W25Q80BV_PAGE_LEN];
char version_string[] = VERSION_STRING;
uint8_t switchctrl = 0;
static void usb_init_buffers_bulk() {
usb_td_bulk[0].next_dtd_pointer = USB_TD_NEXT_DTD_POINTER_TERMINATE;
usb_td_bulk[0].total_bytes
@ -179,14 +184,23 @@ void set_transceiver_mode(const transceiver_mode_t new_transceiver_mode) {
if( transceiver_mode == TRANSCEIVER_MODE_RX ) {
gpio_clear(PORT_LED1_3, PIN_LED3);
gpio_set(PORT_LED1_3, PIN_LED2);
usb_endpoint_init(&usb_endpoint_bulk_in);
max2837_start();
max2837_rx();
} else {
} else if (transceiver_mode == TRANSCEIVER_MODE_TX) {
gpio_clear(PORT_LED1_3, PIN_LED2);
gpio_set(PORT_LED1_3, PIN_LED3);
usb_endpoint_init(&usb_endpoint_bulk_out);
max2837_start();
max2837_tx();
} else {
gpio_clear(PORT_LED1_3, PIN_LED2);
gpio_clear(PORT_LED1_3, PIN_LED3);
max2837_stop();
return;
}
sgpio_configure(transceiver_mode, true);
@ -204,16 +218,12 @@ usb_request_status_t usb_vendor_request_set_transceiver_mode(
) {
if( stage == USB_TRANSFER_STAGE_SETUP ) {
switch( endpoint->setup.value ) {
case 1:
set_transceiver_mode(TRANSCEIVER_MODE_RX);
case TRANSCEIVER_MODE_OFF:
case TRANSCEIVER_MODE_RX:
case TRANSCEIVER_MODE_TX:
set_transceiver_mode(endpoint->setup.value);
usb_endpoint_schedule_ack(endpoint->in);
return USB_REQUEST_STATUS_OK;
case 2:
set_transceiver_mode(TRANSCEIVER_MODE_TX);
usb_endpoint_schedule_ack(endpoint->in);
return USB_REQUEST_STATUS_OK;
default:
return USB_REQUEST_STATUS_STALL;
}
@ -367,44 +377,68 @@ usb_request_status_t usb_vendor_request_read_rffc5071(
}
}
usb_request_status_t usb_vendor_request_erase_spiflash(
usb_endpoint_t* const endpoint, const usb_transfer_stage_t stage)
{
//FIXME This should refuse to run if executing from SPI flash.
if (stage == USB_TRANSFER_STAGE_SETUP) {
w25q80bv_setup();
/* only chip erase is implemented */
w25q80bv_chip_erase();
usb_endpoint_schedule_ack(endpoint->in);
//FIXME probably should undo w25q80bv_setup()
}
return USB_REQUEST_STATUS_OK;
}
usb_request_status_t usb_vendor_request_write_spiflash(
usb_endpoint_t* const endpoint, const usb_transfer_stage_t stage)
{
static uint32_t addr;
static uint16_t len;
static uint8_t spiflash_buffer[0xffff];
uint32_t addr = 0;
uint16_t len = 0;
//FIXME This should refuse to run if executing from SPI flash.
if (stage == USB_TRANSFER_STAGE_SETUP) {
addr = (endpoint->setup.value << 16) | endpoint->setup.index;
len = endpoint->setup.length;
if ((len > W25Q80BV_NUM_BYTES) || (addr > W25Q80BV_NUM_BYTES)
if ((len > W25Q80BV_PAGE_LEN) || (addr > W25Q80BV_NUM_BYTES)
|| ((addr + len) > W25Q80BV_NUM_BYTES)) {
return USB_REQUEST_STATUS_STALL;
} else {
usb_endpoint_schedule(endpoint->out, &spiflash_buffer[0], len);
w25q80bv_setup();
return USB_REQUEST_STATUS_OK;
}
} else if (stage == USB_TRANSFER_STAGE_DATA) {
//FIXME still trying to make this work
addr = (endpoint->setup.value << 16) | endpoint->setup.index;
len = endpoint->setup.length;
/* This check is redundant but makes me feel better. */
if ((len > W25Q80BV_PAGE_LEN) || (addr > W25Q80BV_NUM_BYTES)
|| ((addr + len) > W25Q80BV_NUM_BYTES)) {
return USB_REQUEST_STATUS_STALL;
} else {
w25q80bv_program(addr, len, &spiflash_buffer[0]);
usb_endpoint_schedule_ack(endpoint->in);
//FIXME probably should undo w25q80bv_setup()
return USB_REQUEST_STATUS_OK;
}
} else {
return USB_REQUEST_STATUS_OK;
}
}
usb_request_status_t usb_vendor_request_read_spiflash(
usb_endpoint_t* const endpoint,
const usb_transfer_stage_t stage
) {
usb_endpoint_t* const endpoint, const usb_transfer_stage_t stage)
{
uint32_t addr;
uint16_t len;
if( stage == USB_TRANSFER_STAGE_SETUP )
{
if (stage == USB_TRANSFER_STAGE_SETUP) {
addr = (endpoint->setup.value << 16) | endpoint->setup.index;
len = endpoint->setup.length;
if ((len > W25Q80BV_NUM_BYTES) || (addr > W25Q80BV_NUM_BYTES)
if ((len > W25Q80BV_PAGE_LEN) || (addr > W25Q80BV_NUM_BYTES)
|| ((addr + len) > W25Q80BV_NUM_BYTES)) {
return USB_REQUEST_STATUS_STALL;
} else {
@ -440,7 +474,19 @@ usb_request_status_t usb_vendor_request_read_board_id(
endpoint->buffer[0] = BOARD_ID;
usb_endpoint_schedule(endpoint->in, &endpoint->buffer, 1);
usb_endpoint_schedule_ack(endpoint->out);
return USB_REQUEST_STATUS_OK;
}
return USB_REQUEST_STATUS_OK;
}
usb_request_status_t usb_vendor_request_read_version_string(
usb_endpoint_t* const endpoint, const usb_transfer_stage_t stage)
{
uint8_t length;
if (stage == USB_TRANSFER_STAGE_SETUP) {
length = (uint8_t)strlen(version_string);
usb_endpoint_schedule(endpoint->in, version_string, length);
usb_endpoint_schedule_ack(endpoint->out);
}
return USB_REQUEST_STATUS_OK;
}
@ -456,10 +502,12 @@ static const usb_request_handler_fn vendor_request_handler[] = {
usb_vendor_request_set_baseband_filter_bandwidth,
usb_vendor_request_write_rffc5071,
usb_vendor_request_read_rffc5071,
usb_vendor_request_erase_spiflash,
usb_vendor_request_write_spiflash,
usb_vendor_request_read_spiflash,
usb_vendor_request_write_cpld,
usb_vendor_request_read_board_id
usb_vendor_request_read_board_id,
usb_vendor_request_read_version_string
};
static const uint32_t vendor_request_handler_count =
@ -589,7 +637,6 @@ void sgpio_irqhandler() {
int main(void) {
const uint32_t ifreq = 2600000000U;
uint8_t switchctrl = 0;
pin_setup();
enable_1v8_power();
@ -612,19 +659,16 @@ int main(void) {
ssp1_set_mode_max2837();
max2837_setup();
max2837_set_frequency(ifreq);
rffc5071_setup();
#ifdef JAWBREAKER
switchctrl = SWITCHCTRL_AMP_BYPASS;
#endif
rffc5071_rx(switchctrl);
rffc5071_set_frequency(1700, 0); // 2600 MHz IF - 1700 MHz LO = 900 MHz RF
max2837_set_frequency(ifreq);
max2837_start();
max2837_rx();
while(true) {
// Wait until buffer 0 is transmitted/received.
while( usb_bulk_buffer_offset < 16384 );

View File

@ -31,6 +31,7 @@ int main(int argc, char** argv)
hackrf_device* device = NULL;
int result = HACKRF_SUCCESS;
uint8_t board_id = BOARD_ID_INVALID;
char version[255 + 1];
result = hackrf_init();
if (result != HACKRF_SUCCESS) {
@ -58,6 +59,15 @@ int main(int argc, char** argv)
printf("Board ID Number: %d (%s)\n", board_id,
hackrf_board_id_name(board_id));
result = hackrf_version_string_read(device, &version[0], 255);
if (result != HACKRF_SUCCESS) {
fprintf(stderr, "hackrf_version_string_read() failed: %s (%d)\n",
hackrf_error_name(result), result);
return EXIT_FAILURE;
}
printf("Firmware Version: %s\n", version);
result = hackrf_close(device);
if (result != HACKRF_SUCCESS) {
fprintf(stderr, "hackrf_close() failed: %s (%d)\n",

View File

@ -80,11 +80,13 @@ int main(int argc, char** argv)
int opt;
uint32_t address = 0;
uint32_t length = 0;
uint16_t xfer_len = 0;
const char* path = NULL;
hackrf_device* device = NULL;
int result = HACKRF_SUCCESS;
int option_index = 0;
uint8_t data[MAX_LENGTH];
uint8_t* pdata = &data[0];
FILE* fd = NULL;
bool read = false;
bool write = false;
@ -133,6 +135,12 @@ int main(int argc, char** argv)
return EXIT_FAILURE;
}
if (length == 0) {
fprintf(stderr, "Requested transfer of zero bytes.\n");
usage();
return EXIT_FAILURE;
}
if ((length > MAX_LENGTH) || (address > MAX_LENGTH)
|| ((address + length) > MAX_LENGTH)) {
fprintf(stderr, "Request exceeds size of flash memory.\n");
@ -197,14 +205,30 @@ int main(int argc, char** argv)
fd = NULL;
return EXIT_FAILURE;
}
result = hackrf_spiflash_write(device, address, length, data);
printf("Erasing SPI flash.\n");
result = hackrf_spiflash_erase(device);
if (result != HACKRF_SUCCESS) {
fprintf(stderr, "hackrf_spiflash_write() failed: %s (%d)\n",
fprintf(stderr, "hackrf_spiflash_erase() failed: %s (%d)\n",
hackrf_error_name(result), result);
fclose(fd);
fd = NULL;
return EXIT_FAILURE;
}
while (length) {
xfer_len = (length > 256) ? 256 : length;
printf("Writing %d bytes at 0x%06x.\n", xfer_len, address);
result = hackrf_spiflash_write(device, address, xfer_len, pdata);
if (result != HACKRF_SUCCESS) {
fprintf(stderr, "hackrf_spiflash_write() failed: %s (%d)\n",
hackrf_error_name(result), result);
fclose(fd);
fd = NULL;
return EXIT_FAILURE;
}
address += xfer_len;
pdata += xfer_len;
length -= xfer_len;
}
}
result = hackrf_close(device);

View File

@ -47,8 +47,9 @@
#endif
typedef enum {
TRANSCEIVER_MODE_RX,
TRANSCEIVER_MODE_TX,
TRANSCEIVER_MODE_OFF = 0,
TRANSCEIVER_MODE_RX = 1,
TRANSCEIVER_MODE_TX = 2
} transceiver_mode_t;
static transceiver_mode_t transceiver_mode = TRANSCEIVER_MODE_RX;

View File

@ -39,13 +39,16 @@ typedef enum {
HACKRF_VENDOR_REQUEST_BASEBAND_FILTER_BANDWIDTH_SET = 7,
HACKRF_VENDOR_REQUEST_RFFC5071_WRITE = 8,
HACKRF_VENDOR_REQUEST_RFFC5071_READ = 9,
HACKRF_VENDOR_REQUEST_SPIFLASH_WRITE = 10,
HACKRF_VENDOR_REQUEST_SPIFLASH_READ = 11,
HACKRF_VENDOR_REQUEST_CPLD_WRITE = 12,
HACKRF_VENDOR_REQUEST_BOARD_ID_READ = 13
HACKRF_VENDOR_REQUEST_SPIFLASH_ERASE = 10,
HACKRF_VENDOR_REQUEST_SPIFLASH_WRITE = 11,
HACKRF_VENDOR_REQUEST_SPIFLASH_READ = 12,
HACKRF_VENDOR_REQUEST_CPLD_WRITE = 13,
HACKRF_VENDOR_REQUEST_BOARD_ID_READ = 14,
HACKRF_VENDOR_REQUEST_VERSION_STRING_READ = 15
} hackrf_vendor_request;
typedef enum {
HACKRF_TRANSCEIVER_MODE_OFF = 0,
HACKRF_TRANSCEIVER_MODE_RECEIVE = 1,
HACKRF_TRANSCEIVER_MODE_TRANSMIT = 2,
} hackrf_transceiver_mode;
@ -435,6 +438,25 @@ int hackrf_rffc5071_write(hackrf_device* device, uint8_t register_number, uint16
}
}
int hackrf_spiflash_erase(hackrf_device* device) {
int result = libusb_control_transfer(
device->usb_device,
LIBUSB_ENDPOINT_OUT | LIBUSB_REQUEST_TYPE_VENDOR | LIBUSB_RECIPIENT_DEVICE,
HACKRF_VENDOR_REQUEST_SPIFLASH_ERASE,
0,
0,
NULL,
0,
0
);
if (result != 0) {
return HACKRF_ERROR_LIBUSB;
} else {
return HACKRF_SUCCESS;
}
}
int hackrf_spiflash_write(hackrf_device* device, const uint32_t address,
const uint16_t length, unsigned char* const data)
{
@ -453,7 +475,7 @@ int hackrf_spiflash_write(hackrf_device* device, const uint32_t address,
0
);
if( result != 0 ) {
if (result < length) {
return HACKRF_ERROR_LIBUSB;
} else {
return HACKRF_SUCCESS;
@ -478,7 +500,7 @@ int hackrf_spiflash_read(hackrf_device* device, const uint32_t address,
0
);
if( result < 2 ) {
if (result < length) {
return HACKRF_ERROR_LIBUSB;
} else {
return HACKRF_SUCCESS;
@ -499,7 +521,7 @@ int hackrf_cpld_write(hackrf_device* device, const uint16_t length,
0
);
if( result != 0 ) {
if (result < length) {
return HACKRF_ERROR_LIBUSB;
} else {
return HACKRF_SUCCESS;
@ -525,6 +547,28 @@ int hackrf_board_id_read(hackrf_device* device, uint8_t* value) {
}
}
int hackrf_version_string_read(hackrf_device* device, char* version,
uint8_t length)
{
int result = libusb_control_transfer(
device->usb_device,
LIBUSB_ENDPOINT_IN | LIBUSB_REQUEST_TYPE_VENDOR | LIBUSB_RECIPIENT_DEVICE,
HACKRF_VENDOR_REQUEST_VERSION_STRING_READ,
0,
0,
(unsigned char*)version,
length,
0
);
if (result < 0) {
return HACKRF_ERROR_LIBUSB;
} else {
version[result] = '\0';
return HACKRF_SUCCESS;
}
}
static void* transfer_threadproc(void* arg) {
hackrf_device* device = (hackrf_device*)arg;
@ -619,7 +663,12 @@ int hackrf_start_rx(hackrf_device* device, hackrf_sample_block_cb_fn callback) {
}
int hackrf_stop_rx(hackrf_device* device) {
return kill_transfer_thread(device);
int result1, result2;
result1 = kill_transfer_thread(device);
result2 = hackrf_set_transceiver_mode(device, HACKRF_TRANSCEIVER_MODE_OFF);
if (result2 != HACKRF_SUCCESS)
return result2;
return result1;
}
int hackrf_start_tx(hackrf_device* device, hackrf_sample_block_cb_fn callback) {
@ -632,7 +681,12 @@ int hackrf_start_tx(hackrf_device* device, hackrf_sample_block_cb_fn callback) {
}
int hackrf_stop_tx(hackrf_device* device) {
return kill_transfer_thread(device);
int result1, result2;
result1 = kill_transfer_thread(device);
result2 = hackrf_set_transceiver_mode(device, HACKRF_TRANSCEIVER_MODE_OFF);
if (result2 != HACKRF_SUCCESS)
return result2;
return result1;
}
int hackrf_close(hackrf_device* device) {

View File

@ -80,6 +80,7 @@ int hackrf_baseband_filter_bandwidth_set(hackrf_device* device, const uint32_t b
int hackrf_rffc5071_read(hackrf_device* device, uint8_t register_number, uint16_t* value);
int hackrf_rffc5071_write(hackrf_device* device, uint8_t register_number, uint16_t value);
int hackrf_spiflash_erase(hackrf_device* device);
int hackrf_spiflash_write(hackrf_device* device, const uint32_t address,
const uint16_t length, unsigned char* const data);
int hackrf_spiflash_read(hackrf_device* device, const uint32_t address,
@ -89,6 +90,8 @@ int hackrf_cpld_write(hackrf_device* device, const uint16_t length,
unsigned char* const data);
int hackrf_board_id_read(hackrf_device* device, uint8_t* value);
int hackrf_version_string_read(hackrf_device* device, char* version,
uint8_t length);
const char* hackrf_error_name(enum hackrf_error errcode);
const char* hackrf_board_id_name(enum hackrf_board_id board_id);