Merge branch 'master' of git://github.com/jboone/hackrf
This commit is contained in:
@ -200,6 +200,11 @@ extern "C"
|
|||||||
|
|
||||||
/* TODO add other Pins */
|
/* TODO add other Pins */
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
TRANSCEIVER_MODE_RX,
|
||||||
|
TRANSCEIVER_MODE_TX,
|
||||||
|
} transceiver_mode_t;
|
||||||
|
|
||||||
void delay(uint32_t duration);
|
void delay(uint32_t duration);
|
||||||
|
|
||||||
void cpu_clock_init(void);
|
void cpu_clock_init(void);
|
||||||
|
@ -59,17 +59,23 @@ void sgpio_test_interface() {
|
|||||||
|
|
||||||
// Make all SGPIO controlled by SGPIO's "GPIO" registers
|
// Make all SGPIO controlled by SGPIO's "GPIO" registers
|
||||||
for (uint_fast8_t i = 0; i < 16; i++) {
|
for (uint_fast8_t i = 0; i < 16; i++) {
|
||||||
SGPIO_OUT_MUX_CFG(i) = (0L << 4) | (4L << 0);
|
SGPIO_OUT_MUX_CFG(i) =
|
||||||
|
SGPIO_OUT_MUX_CFG_P_OE_CFG(0)
|
||||||
|
| SGPIO_OUT_MUX_CFG_P_OUT_CFG(4);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set SGPIO output values.
|
// Set SGPIO output values.
|
||||||
SGPIO_GPIO_OUTREG = (1L << host_direction_sgpio_pin)
|
SGPIO_GPIO_OUTREG =
|
||||||
| (1L << host_disable_sgpio_pin);
|
(1L << host_direction_sgpio_pin)
|
||||||
|
| (1L << host_disable_sgpio_pin);
|
||||||
|
|
||||||
// Enable SGPIO pin outputs.
|
// Enable SGPIO pin outputs.
|
||||||
SGPIO_GPIO_OENREG = (1L << host_direction_sgpio_pin)
|
SGPIO_GPIO_OENREG =
|
||||||
| (1L << host_disable_sgpio_pin) | (0L << host_capture_sgpio_pin)
|
(1L << host_direction_sgpio_pin)
|
||||||
| (0L << host_clock_sgpio_pin) | (0xFF << 0);
|
| (1L << host_disable_sgpio_pin)
|
||||||
|
| (0L << host_capture_sgpio_pin)
|
||||||
|
| (0L << host_clock_sgpio_pin)
|
||||||
|
| (0xFF << 0);
|
||||||
|
|
||||||
// Configure SGPIO slices.
|
// Configure SGPIO slices.
|
||||||
|
|
||||||
@ -83,159 +89,61 @@ void sgpio_test_interface() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void sgpio_configure_for_tx() {
|
void sgpio_configure(
|
||||||
|
const transceiver_mode_t transceiver_mode,
|
||||||
|
const bool multi_slice
|
||||||
|
) {
|
||||||
// Disable all counters during configuration
|
// Disable all counters during configuration
|
||||||
SGPIO_CTRL_ENABLE = 0;
|
SGPIO_CTRL_ENABLE = 0;
|
||||||
|
|
||||||
sgpio_configure_pin_functions();
|
sgpio_configure_pin_functions();
|
||||||
|
|
||||||
// Set SGPIO output values.
|
// Set SGPIO output values.
|
||||||
|
const uint_fast8_t cpld_direction =
|
||||||
|
(transceiver_mode == TRANSCEIVER_MODE_TX) ? 1 : 0;
|
||||||
SGPIO_GPIO_OUTREG =
|
SGPIO_GPIO_OUTREG =
|
||||||
(1L << 11) | // direction
|
(cpld_direction << 11)
|
||||||
(1L << 10); // disable
|
| (1L << 10) // disable
|
||||||
|
;
|
||||||
|
|
||||||
// Enable SGPIO pin outputs.
|
// Enable SGPIO pin outputs.
|
||||||
|
const uint_fast16_t sgpio_gpio_data_direction =
|
||||||
|
(transceiver_mode == TRANSCEIVER_MODE_TX)
|
||||||
|
? (0xFF << 0)
|
||||||
|
: (0x00 << 0);
|
||||||
SGPIO_GPIO_OENREG =
|
SGPIO_GPIO_OENREG =
|
||||||
(1L << 11) | // direction: TX: data to CPLD
|
(1L << 11) // direction
|
||||||
(1L << 10) | // disable
|
| (1L << 10) // disable
|
||||||
(0L << 9) | // capture
|
| (0L << 9) // capture
|
||||||
(0L << 8) | // clock
|
| (0L << 8) // clock
|
||||||
0xFF; // data: output
|
| sgpio_gpio_data_direction
|
||||||
|
;
|
||||||
|
|
||||||
SGPIO_OUT_MUX_CFG( 8) = 0; // SGPIO: Input: clock
|
SGPIO_OUT_MUX_CFG( 8) = // SGPIO: Input: clock
|
||||||
SGPIO_OUT_MUX_CFG( 9) = 0; // SGPIO: Input: qualifier
|
SGPIO_OUT_MUX_CFG_P_OE_CFG(0)
|
||||||
SGPIO_OUT_MUX_CFG(10) = (0L << 4) | (4L << 0); // GPIO: Output: disable
|
| SGPIO_OUT_MUX_CFG_P_OUT_CFG(0)
|
||||||
SGPIO_OUT_MUX_CFG(11) = (0L << 4) | (4L << 0); // GPIO: Output: direction
|
;
|
||||||
|
SGPIO_OUT_MUX_CFG( 9) = // SGPIO: Input: qualifier
|
||||||
|
SGPIO_OUT_MUX_CFG_P_OE_CFG(0)
|
||||||
|
| SGPIO_OUT_MUX_CFG_P_OUT_CFG(0)
|
||||||
|
;
|
||||||
|
SGPIO_OUT_MUX_CFG(10) = // GPIO: Output: disable
|
||||||
|
SGPIO_OUT_MUX_CFG_P_OE_CFG(0)
|
||||||
|
| SGPIO_OUT_MUX_CFG_P_OUT_CFG(4)
|
||||||
|
;
|
||||||
|
SGPIO_OUT_MUX_CFG(11) = // GPIO: Output: direction
|
||||||
|
SGPIO_OUT_MUX_CFG_P_OE_CFG(0)
|
||||||
|
| SGPIO_OUT_MUX_CFG_P_OUT_CFG(4)
|
||||||
|
;
|
||||||
|
|
||||||
|
const uint_fast8_t output_multiplexing_mode =
|
||||||
|
multi_slice ? 11 : 9;
|
||||||
for(uint_fast8_t i=0; i<8; i++) {
|
for(uint_fast8_t i=0; i<8; i++) {
|
||||||
// SGPIO pin 0 outputs slice A bit "i".
|
// SGPIO pin 0 outputs slice A bit "i".
|
||||||
SGPIO_OUT_MUX_CFG(i) =
|
SGPIO_OUT_MUX_CFG(i) =
|
||||||
(0L << 4) | // P_OE_CFG = 0
|
SGPIO_OUT_MUX_CFG_P_OE_CFG(0)
|
||||||
(9L << 0); // P_OUT_CFG = 9, dout_doutm8a (8-bit mode 8a)
|
| SGPIO_OUT_MUX_CFG_P_OUT_CFG(output_multiplexing_mode)
|
||||||
}
|
;
|
||||||
|
|
||||||
// Slice A
|
|
||||||
SGPIO_MUX_CFG(SGPIO_SLICE_A) =
|
|
||||||
(0L << 12) | // CONCAT_ORDER = 0 (self-loop)
|
|
||||||
(1L << 11) | // CONCAT_ENABLE = 1 (concatenate data)
|
|
||||||
(0L << 9) | // QUALIFIER_SLICE_MODE = X
|
|
||||||
(1L << 7) | // QUALIFIER_PIN_MODE = 1 (SGPIO9)
|
|
||||||
(3L << 5) | // QUALIFIER_MODE = 3 (external SGPIO pin)
|
|
||||||
(0L << 3) | // CLK_SOURCE_SLICE_MODE = X
|
|
||||||
(0L << 1) | // CLK_SOURCE_PIN_MODE = 0 (SGPIO8)
|
|
||||||
(1L << 0); // EXT_CLK_ENABLE = 1, external clock signal (slice)
|
|
||||||
|
|
||||||
SGPIO_SLICE_MUX_CFG(SGPIO_SLICE_A) =
|
|
||||||
(0L << 8) | // INV_QUALIFIER = 0 (use normal qualifier)
|
|
||||||
(3L << 6) | // PARALLEL_MODE = 3 (shift 8 bits per clock)
|
|
||||||
(0L << 4) | // DATA_CAPTURE_MODE = 0 (detect rising edge)
|
|
||||||
(0L << 3) | // INV_OUT_CLK = 0 (normal clock)
|
|
||||||
(1L << 2) | // CLKGEN_MODE = 1 (use external pin clock)
|
|
||||||
(0L << 1) | // CLK_CAPTURE_MODE = 0 (use rising clock edge)
|
|
||||||
(0L << 0); // MATCH_MODE = 0 (do not match data)
|
|
||||||
|
|
||||||
SGPIO_PRESET(SGPIO_SLICE_A) = 0;
|
|
||||||
SGPIO_COUNT(SGPIO_SLICE_A) = 0;
|
|
||||||
SGPIO_POS(SGPIO_SLICE_A) = (0x3L << 8) | (0x3L << 0);
|
|
||||||
SGPIO_REG(SGPIO_SLICE_A) = 0x80808080; // Primary output data register
|
|
||||||
SGPIO_REG_SS(SGPIO_SLICE_A) = 0x80808080; // Shadow output data register
|
|
||||||
|
|
||||||
// Start SGPIO operation by enabling slice clocks.
|
|
||||||
SGPIO_CTRL_ENABLE =
|
|
||||||
(1L << SGPIO_SLICE_A)
|
|
||||||
;
|
|
||||||
}
|
|
||||||
|
|
||||||
void sgpio_configure_for_rx() {
|
|
||||||
// Disable all counters during configuration
|
|
||||||
SGPIO_CTRL_ENABLE = 0;
|
|
||||||
|
|
||||||
sgpio_configure_pin_functions();
|
|
||||||
|
|
||||||
// Set SGPIO output values.
|
|
||||||
SGPIO_GPIO_OUTREG =
|
|
||||||
(0L << 11) | // direction
|
|
||||||
(1L << 10); // disable
|
|
||||||
|
|
||||||
// Enable SGPIO pin outputs.
|
|
||||||
SGPIO_GPIO_OENREG =
|
|
||||||
(1L << 11) | // direction: RX: data from CPLD
|
|
||||||
(1L << 10) | // disable
|
|
||||||
(0L << 9) | // capture
|
|
||||||
(0L << 8) | // clock
|
|
||||||
0x00; // data: input
|
|
||||||
|
|
||||||
SGPIO_OUT_MUX_CFG( 8) = 0; // SGPIO: Input: clock
|
|
||||||
SGPIO_OUT_MUX_CFG( 9) = 0; // SGPIO: Input: qualifier
|
|
||||||
SGPIO_OUT_MUX_CFG(10) = (0L << 4) | (4L << 0); // GPIO: Output: disable
|
|
||||||
SGPIO_OUT_MUX_CFG(11) = (0L << 4) | (4L << 0); // GPIO: Output: direction
|
|
||||||
|
|
||||||
for(uint_fast8_t i=0; i<8; i++) {
|
|
||||||
SGPIO_OUT_MUX_CFG(i) =
|
|
||||||
(0L << 4) | // P_OE_CFG = 0
|
|
||||||
(9L << 0); // P_OUT_CFG = 9, dout_doutm8a (8-bit mode 8a)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Slice A
|
|
||||||
SGPIO_MUX_CFG(SGPIO_SLICE_A) =
|
|
||||||
(0L << 12) | // CONCAT_ORDER = X
|
|
||||||
(0L << 11) | // CONCAT_ENABLE = 0 (concatenate data)
|
|
||||||
(0L << 9) | // QUALIFIER_SLICE_MODE = X
|
|
||||||
(1L << 7) | // QUALIFIER_PIN_MODE = 1 (SGPIO9)
|
|
||||||
(3L << 5) | // QUALIFIER_MODE = 3 (external SGPIO pin)
|
|
||||||
(0L << 3) | // CLK_SOURCE_SLICE_MODE = X
|
|
||||||
(0L << 1) | // CLK_SOURCE_PIN_MODE = 0 (SGPIO8)
|
|
||||||
(1L << 0); // EXT_CLK_ENABLE = 1, external clock signal (slice)
|
|
||||||
|
|
||||||
SGPIO_SLICE_MUX_CFG(SGPIO_SLICE_A) =
|
|
||||||
(0L << 8) | // INV_QUALIFIER = 0 (use normal qualifier)
|
|
||||||
(3L << 6) | // PARALLEL_MODE = 3 (shift 8 bits per clock)
|
|
||||||
(0L << 4) | // DATA_CAPTURE_MODE = 0 (detect rising edge)
|
|
||||||
(0L << 3) | // INV_OUT_CLK = X
|
|
||||||
(1L << 2) | // CLKGEN_MODE = 1 (use external pin clock)
|
|
||||||
(1L << 1) | // CLK_CAPTURE_MODE = 1 (use falling clock edge)
|
|
||||||
(0L << 0); // MATCH_MODE = 0 (do not match data)
|
|
||||||
|
|
||||||
SGPIO_PRESET(SGPIO_SLICE_A) = 0;
|
|
||||||
SGPIO_COUNT(SGPIO_SLICE_A) = 0;
|
|
||||||
SGPIO_POS(SGPIO_SLICE_A) = (0 << 8) | (0 << 0);
|
|
||||||
SGPIO_REG(SGPIO_SLICE_A) = 0xCAFEBABE; // Primary output data register
|
|
||||||
SGPIO_REG_SS(SGPIO_SLICE_A) = 0xDEADBEEF; // Shadow output data register
|
|
||||||
|
|
||||||
// Start SGPIO operation by enabling slice clocks.
|
|
||||||
SGPIO_CTRL_ENABLE =
|
|
||||||
(1L << SGPIO_SLICE_A)
|
|
||||||
;
|
|
||||||
}
|
|
||||||
|
|
||||||
void sgpio_configure_for_rx_deep() {
|
|
||||||
// Disable all counters during configuration
|
|
||||||
SGPIO_CTRL_ENABLE = 0;
|
|
||||||
|
|
||||||
sgpio_configure_pin_functions();
|
|
||||||
|
|
||||||
// Set SGPIO output values.
|
|
||||||
SGPIO_GPIO_OUTREG =
|
|
||||||
(0L << 11) | // direction
|
|
||||||
(1L << 10); // disable
|
|
||||||
|
|
||||||
// Enable SGPIO pin outputs.
|
|
||||||
SGPIO_GPIO_OENREG =
|
|
||||||
(1L << 11) | // direction: RX: data from CPLD
|
|
||||||
(1L << 10) | // disable
|
|
||||||
(0L << 9) | // capture
|
|
||||||
(0L << 8) | // clock
|
|
||||||
0x00; // data: input
|
|
||||||
|
|
||||||
SGPIO_OUT_MUX_CFG( 8) = 0; // SGPIO: Input: clock
|
|
||||||
SGPIO_OUT_MUX_CFG( 9) = 0; // SGPIO: Input: qualifier
|
|
||||||
SGPIO_OUT_MUX_CFG(10) = (0L << 4) | (4L << 0); // GPIO: Output: disable
|
|
||||||
SGPIO_OUT_MUX_CFG(11) = (0L << 4) | (4L << 0); // GPIO: Output: direction
|
|
||||||
|
|
||||||
for(uint_fast8_t i=0; i<8; i++) {
|
|
||||||
SGPIO_OUT_MUX_CFG(i) =
|
|
||||||
(0L << 4) | // P_OE_CFG = 0
|
|
||||||
(9L << 0); // P_OUT_CFG = 9, dout_doutm8a (8-bit mode 8a)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const uint_fast8_t slice_indices[] = {
|
const uint_fast8_t slice_indices[] = {
|
||||||
@ -249,35 +157,46 @@ void sgpio_configure_for_rx_deep() {
|
|||||||
SGPIO_SLICE_L,
|
SGPIO_SLICE_L,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const uint_fast8_t pos = multi_slice ? 0x1f : 0x03;
|
||||||
|
const bool single_slice = !multi_slice;
|
||||||
|
const uint_fast8_t slice_count = multi_slice ? 8 : 1;
|
||||||
|
|
||||||
uint32_t slice_enable_mask = 0;
|
uint32_t slice_enable_mask = 0;
|
||||||
for(uint_fast8_t i=0; i<8; i++) {
|
for(uint_fast8_t i=0; i<slice_count; i++) {
|
||||||
uint_fast8_t slice_index = slice_indices[i];
|
const uint_fast8_t slice_index = slice_indices[i];
|
||||||
const uint_fast8_t concat_order = (slice_index == SGPIO_SLICE_A) ? 0 : 3;
|
const bool input_slice = (i == 0) && (transceiver_mode == TRANSCEIVER_MODE_RX);
|
||||||
const uint_fast8_t concat_enable = (slice_index == SGPIO_SLICE_A) ? 0 : 1;
|
const uint_fast8_t concat_order = (input_slice || single_slice) ? 0 : 3;
|
||||||
|
const uint_fast8_t concat_enable = (input_slice || single_slice) ? 0 : 1;
|
||||||
|
|
||||||
SGPIO_MUX_CFG(slice_index) =
|
SGPIO_MUX_CFG(slice_index) =
|
||||||
(concat_order << 12) | // CONCAT_ORDER = 3 (eight slices)
|
SGPIO_MUX_CFG_CONCAT_ORDER(concat_order)
|
||||||
(concat_enable << 11) | // CONCAT_ENABLE = 1 (concatenate data)
|
| SGPIO_MUX_CFG_CONCAT_ENABLE(concat_enable)
|
||||||
(0L << 9) | // QUALIFIER_SLICE_MODE = X
|
| SGPIO_MUX_CFG_QUALIFIER_SLICE_MODE(0)
|
||||||
(1L << 7) | // QUALIFIER_PIN_MODE = 1 (SGPIO9)
|
| SGPIO_MUX_CFG_QUALIFIER_PIN_MODE(1)
|
||||||
(3L << 5) | // QUALIFIER_MODE = 3 (external SGPIO pin)
|
| SGPIO_MUX_CFG_QUALIFIER_MODE(3)
|
||||||
(0L << 3) | // CLK_SOURCE_SLICE_MODE = X
|
| SGPIO_MUX_CFG_CLK_SOURCE_SLICE_MODE(0)
|
||||||
(0L << 1) | // CLK_SOURCE_PIN_MODE = 0 (SGPIO8)
|
| SGPIO_MUX_CFG_CLK_SOURCE_PIN_MODE(0)
|
||||||
(1L << 0); // EXT_CLK_ENABLE = 1, external clock signal (slice)
|
| SGPIO_MUX_CFG_EXT_CLK_ENABLE(1)
|
||||||
|
;
|
||||||
|
|
||||||
SGPIO_SLICE_MUX_CFG(slice_index) =
|
SGPIO_SLICE_MUX_CFG(slice_index) =
|
||||||
(0L << 8) | // INV_QUALIFIER = 0 (use normal qualifier)
|
SGPIO_SLICE_MUX_CFG_INV_QUALIFIER(0)
|
||||||
(3L << 6) | // PARALLEL_MODE = 3 (shift 8 bits per clock)
|
| SGPIO_SLICE_MUX_CFG_PARALLEL_MODE(3)
|
||||||
(0L << 4) | // DATA_CAPTURE_MODE = 0 (detect rising edge)
|
| SGPIO_SLICE_MUX_CFG_DATA_CAPTURE_MODE(0)
|
||||||
(0L << 3) | // INV_OUT_CLK = X
|
| SGPIO_SLICE_MUX_CFG_INV_OUT_CLK(0)
|
||||||
(1L << 2) | // CLKGEN_MODE = 1 (use external pin clock)
|
| SGPIO_SLICE_MUX_CFG_CLKGEN_MODE(1)
|
||||||
(1L << 1) | // CLK_CAPTURE_MODE = 1 (use falling clock edge)
|
| SGPIO_SLICE_MUX_CFG_CLK_CAPTURE_MODE(1)
|
||||||
(0L << 0); // MATCH_MODE = 0 (do not match data)
|
| SGPIO_SLICE_MUX_CFG_MATCH_MODE(0)
|
||||||
|
;
|
||||||
|
|
||||||
SGPIO_PRESET(slice_index) = 0; // External clock, don't care
|
SGPIO_PRESET(slice_index) = 0; // External clock, don't care
|
||||||
SGPIO_COUNT(slice_index) = 0; // External clock, don't care
|
SGPIO_COUNT(slice_index) = 0; // External clock, don't care
|
||||||
SGPIO_POS(slice_index) = (0x1f << 8) | (0x1f << 0);
|
SGPIO_POS(slice_index) =
|
||||||
SGPIO_REG(slice_index) = 0xFFFFFFFF; // Primary output data register
|
SGPIO_POS_POS_RESET(pos)
|
||||||
SGPIO_REG_SS(slice_index) = 0xFFFFFFFF; // Shadow output data register
|
| SGPIO_POS_POS(pos)
|
||||||
|
;
|
||||||
|
SGPIO_REG(slice_index) = 0x80808080; // Primary output data register
|
||||||
|
SGPIO_REG_SS(slice_index) = 0x80808080; // Shadow output data register
|
||||||
|
|
||||||
slice_enable_mask |= (1 << slice_index);
|
slice_enable_mask |= (1 << slice_index);
|
||||||
}
|
}
|
||||||
|
@ -22,11 +22,14 @@
|
|||||||
#ifndef __SGPIO_H__
|
#ifndef __SGPIO_H__
|
||||||
#define __SGPIO_H__
|
#define __SGPIO_H__
|
||||||
|
|
||||||
|
#include <hackrf_core.h>
|
||||||
|
|
||||||
void sgpio_configure_pin_functions();
|
void sgpio_configure_pin_functions();
|
||||||
void sgpio_test_interface();
|
void sgpio_test_interface();
|
||||||
void sgpio_configure_for_tx();
|
void sgpio_configure(
|
||||||
void sgpio_configure_for_rx();
|
const transceiver_mode_t transceiver_mode,
|
||||||
void sgpio_configure_for_rx_deep();
|
const bool multi_slice
|
||||||
|
);
|
||||||
void sgpio_cpld_stream_enable();
|
void sgpio_cpld_stream_enable();
|
||||||
void sgpio_cpld_stream_disable();
|
void sgpio_cpld_stream_disable();
|
||||||
bool sgpio_cpld_stream_is_enabled();
|
bool sgpio_cpld_stream_is_enabled();
|
||||||
|
@ -33,7 +33,7 @@
|
|||||||
#include <sgpio.h>
|
#include <sgpio.h>
|
||||||
|
|
||||||
void tx_test() {
|
void tx_test() {
|
||||||
sgpio_configure_for_tx();
|
sgpio_configure(TRANSCEIVER_MODE_TX, false);
|
||||||
|
|
||||||
// LSB goes out first, samples are 0x<Q1><I1><Q0><I0>
|
// LSB goes out first, samples are 0x<Q1><I1><Q0><I0>
|
||||||
volatile uint32_t buffer[] = {
|
volatile uint32_t buffer[] = {
|
||||||
@ -54,7 +54,7 @@ void tx_test() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void rx_test() {
|
void rx_test() {
|
||||||
sgpio_configure_for_rx();
|
sgpio_configure(TRANSCEIVER_MODE_RX, false);
|
||||||
|
|
||||||
volatile uint32_t buffer[4096];
|
volatile uint32_t buffer[4096];
|
||||||
uint32_t i = 0;
|
uint32_t i = 0;
|
||||||
|
@ -31,7 +31,7 @@
|
|||||||
#include <sgpio.h>
|
#include <sgpio.h>
|
||||||
|
|
||||||
void tx_test() {
|
void tx_test() {
|
||||||
sgpio_configure_for_tx();
|
sgpio_configure(TRANSCEIVER_MODE_TX, false);
|
||||||
|
|
||||||
// LSB goes out first, samples are 0x<Q1><I1><Q0><I0>
|
// LSB goes out first, samples are 0x<Q1><I1><Q0><I0>
|
||||||
volatile uint32_t buffer[] = {
|
volatile uint32_t buffer[] = {
|
||||||
@ -52,7 +52,7 @@ void tx_test() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void rx_test() {
|
void rx_test() {
|
||||||
sgpio_configure_for_rx();
|
sgpio_configure(TRANSCEIVER_MODE_RX, false);
|
||||||
|
|
||||||
volatile uint32_t buffer[4096];
|
volatile uint32_t buffer[4096];
|
||||||
uint32_t i = 0;
|
uint32_t i = 0;
|
||||||
|
@ -38,6 +38,8 @@
|
|||||||
#include "usb_descriptor.h"
|
#include "usb_descriptor.h"
|
||||||
#include "usb_standard_request.h"
|
#include "usb_standard_request.h"
|
||||||
|
|
||||||
|
static volatile transceiver_mode_t transceiver_mode = TRANSCEIVER_MODE_TX;
|
||||||
|
|
||||||
uint8_t* const usb_bulk_buffer = (uint8_t*)0x20004000;
|
uint8_t* const usb_bulk_buffer = (uint8_t*)0x20004000;
|
||||||
static volatile uint32_t usb_bulk_buffer_offset = 0;
|
static volatile uint32_t usb_bulk_buffer_offset = 0;
|
||||||
static const uint32_t usb_bulk_buffer_mask = 32768 - 1;
|
static const uint32_t usb_bulk_buffer_mask = 32768 - 1;
|
||||||
@ -202,13 +204,16 @@ bool usb_set_configuration(
|
|||||||
// hard-coding, this whole function can move into a shared/reusable
|
// hard-coding, this whole function can move into a shared/reusable
|
||||||
// library.
|
// library.
|
||||||
if( device->configuration && (device->configuration->number == 1) ) {
|
if( device->configuration && (device->configuration->number == 1) ) {
|
||||||
usb_endpoint_init(&usb_endpoint_bulk_in);
|
if( transceiver_mode == TRANSCEIVER_MODE_RX ) {
|
||||||
usb_endpoint_init(&usb_endpoint_bulk_out);
|
sgpio_configure(transceiver_mode, true);
|
||||||
|
usb_endpoint_init(&usb_endpoint_bulk_in);
|
||||||
|
} else {
|
||||||
|
sgpio_configure(transceiver_mode, true);
|
||||||
|
usb_endpoint_init(&usb_endpoint_bulk_out);
|
||||||
|
}
|
||||||
|
|
||||||
usb_init_buffers_bulk();
|
usb_init_buffers_bulk();
|
||||||
|
|
||||||
sgpio_configure_for_rx_deep();
|
|
||||||
|
|
||||||
nvic_set_priority(NVIC_M4_SGPIO_IRQ, 0);
|
nvic_set_priority(NVIC_M4_SGPIO_IRQ, 0);
|
||||||
nvic_enable_irq(NVIC_M4_SGPIO_IRQ);
|
nvic_enable_irq(NVIC_M4_SGPIO_IRQ);
|
||||||
SGPIO_SET_EN_1 = (1 << SGPIO_SLICE_A);
|
SGPIO_SET_EN_1 = (1 << SGPIO_SLICE_A);
|
||||||
@ -237,14 +242,25 @@ void sgpio_irqhandler() {
|
|||||||
SGPIO_CLR_STATUS_1 = 0xFFFFFFFF;
|
SGPIO_CLR_STATUS_1 = 0xFFFFFFFF;
|
||||||
|
|
||||||
uint32_t* const p = (uint32_t*)&usb_bulk_buffer[usb_bulk_buffer_offset];
|
uint32_t* const p = (uint32_t*)&usb_bulk_buffer[usb_bulk_buffer_offset];
|
||||||
p[7] = SGPIO_REG_SS(SGPIO_SLICE_A);
|
if( transceiver_mode == TRANSCEIVER_MODE_RX ) {
|
||||||
p[6] = SGPIO_REG_SS(SGPIO_SLICE_I);
|
p[7] = SGPIO_REG_SS(SGPIO_SLICE_A);
|
||||||
p[5] = SGPIO_REG_SS(SGPIO_SLICE_E);
|
p[6] = SGPIO_REG_SS(SGPIO_SLICE_I);
|
||||||
p[4] = SGPIO_REG_SS(SGPIO_SLICE_J);
|
p[5] = SGPIO_REG_SS(SGPIO_SLICE_E);
|
||||||
p[3] = SGPIO_REG_SS(SGPIO_SLICE_C);
|
p[4] = SGPIO_REG_SS(SGPIO_SLICE_J);
|
||||||
p[2] = SGPIO_REG_SS(SGPIO_SLICE_K);
|
p[3] = SGPIO_REG_SS(SGPIO_SLICE_C);
|
||||||
p[1] = SGPIO_REG_SS(SGPIO_SLICE_F);
|
p[2] = SGPIO_REG_SS(SGPIO_SLICE_K);
|
||||||
p[0] = SGPIO_REG_SS(SGPIO_SLICE_L);
|
p[1] = SGPIO_REG_SS(SGPIO_SLICE_F);
|
||||||
|
p[0] = SGPIO_REG_SS(SGPIO_SLICE_L);
|
||||||
|
} else {
|
||||||
|
SGPIO_REG_SS(SGPIO_SLICE_A) = p[7];
|
||||||
|
SGPIO_REG_SS(SGPIO_SLICE_I) = p[6];
|
||||||
|
SGPIO_REG_SS(SGPIO_SLICE_E) = p[5];
|
||||||
|
SGPIO_REG_SS(SGPIO_SLICE_J) = p[4];
|
||||||
|
SGPIO_REG_SS(SGPIO_SLICE_C) = p[3];
|
||||||
|
SGPIO_REG_SS(SGPIO_SLICE_K) = p[2];
|
||||||
|
SGPIO_REG_SS(SGPIO_SLICE_F) = p[1];
|
||||||
|
SGPIO_REG_SS(SGPIO_SLICE_L) = p[0];
|
||||||
|
}
|
||||||
|
|
||||||
usb_bulk_buffer_offset = (usb_bulk_buffer_offset + 32) & usb_bulk_buffer_mask;
|
usb_bulk_buffer_offset = (usb_bulk_buffer_offset + 32) & usb_bulk_buffer_mask;
|
||||||
}
|
}
|
||||||
@ -292,11 +308,25 @@ int main(void) {
|
|||||||
max5864_xcvr();
|
max5864_xcvr();
|
||||||
|
|
||||||
while(true) {
|
while(true) {
|
||||||
|
// Wait until buffer 0 is transmitted/received.
|
||||||
while( usb_bulk_buffer_offset < 16384 );
|
while( usb_bulk_buffer_offset < 16384 );
|
||||||
usb_endpoint_schedule_no_int(&usb_endpoint_bulk_in, &usb_td_bulk[0]);
|
|
||||||
|
|
||||||
|
// Set up IN transfer of buffer 0.
|
||||||
|
usb_endpoint_schedule_no_int(
|
||||||
|
(transceiver_mode == TRANSCEIVER_MODE_RX)
|
||||||
|
? &usb_endpoint_bulk_in : &usb_endpoint_bulk_out,
|
||||||
|
&usb_td_bulk[0]
|
||||||
|
);
|
||||||
|
|
||||||
|
// Wait until buffer 1 is transmitted/received.
|
||||||
while( usb_bulk_buffer_offset >= 16384 );
|
while( usb_bulk_buffer_offset >= 16384 );
|
||||||
usb_endpoint_schedule_no_int(&usb_endpoint_bulk_in, &usb_td_bulk[1]);
|
|
||||||
|
// Set up IN transfer of buffer 1.
|
||||||
|
usb_endpoint_schedule_no_int(
|
||||||
|
(transceiver_mode == TRANSCEIVER_MODE_RX)
|
||||||
|
? &usb_endpoint_bulk_in : &usb_endpoint_bulk_out,
|
||||||
|
&usb_td_bulk[1]
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -21,13 +21,25 @@
|
|||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
#include <stdbool.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
#include <getopt.h>
|
||||||
|
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
|
#include <errno.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|
||||||
#include <libusb-1.0/libusb.h>
|
#include <libusb-1.0/libusb.h>
|
||||||
|
|
||||||
|
const uint16_t hackrf_usb_pid = 0x1d50;
|
||||||
|
const uint16_t hackrf_usb_vid = 0x604b;
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
TRANSCEIVER_MODE_RX,
|
||||||
|
TRANSCEIVER_MODE_TX,
|
||||||
|
} transceiver_mode_t;
|
||||||
|
static transceiver_mode_t transceiver_mode = TRANSCEIVER_MODE_RX;
|
||||||
|
|
||||||
static float
|
static float
|
||||||
TimevalDiff(const struct timeval *a, const struct timeval *b)
|
TimevalDiff(const struct timeval *a, const struct timeval *b)
|
||||||
{
|
{
|
||||||
@ -48,31 +60,27 @@ void write_callback(struct libusb_transfer* transfer) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int main(int argc, char** argv) {
|
void read_callback(struct libusb_transfer* transfer) {
|
||||||
if( argc != 2 ) {
|
if( transfer->status == LIBUSB_TRANSFER_COMPLETED ) {
|
||||||
printf("Usage: usb_test <file to capture to>\n");
|
byte_count += transfer->actual_length;
|
||||||
return -1;
|
read(fd, transfer->buffer, transfer->actual_length);
|
||||||
}
|
libusb_submit_transfer(transfer);
|
||||||
|
} else {
|
||||||
const uint32_t buffer_size = 16384;
|
printf("transfer status was not 'completed'\n");
|
||||||
|
|
||||||
fd = open(argv[1], O_RDWR | O_CREAT | O_TRUNC, S_IRWXU | S_IRWXG | S_IRWXO);
|
|
||||||
if( fd == -1 ) {
|
|
||||||
printf("Failed to open file for write\n");
|
|
||||||
return -2;
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
libusb_context* context = NULL;
|
libusb_device_handle* open_device(libusb_context* const context) {
|
||||||
int result = libusb_init(NULL);
|
int result = libusb_init(NULL);
|
||||||
if( result != 0 ) {
|
if( result != 0 ) {
|
||||||
printf("libusb_init() failed: %d\n", result);
|
printf("libusb_init() failed: %d\n", result);
|
||||||
return -4;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
libusb_device_handle* device = libusb_open_device_with_vid_pid(context, 0x1d50, 0x604b);
|
libusb_device_handle* device = libusb_open_device_with_vid_pid(context, hackrf_usb_pid, hackrf_usb_vid);
|
||||||
if( device == NULL ) {
|
if( device == NULL ) {
|
||||||
printf("libusb_open_device_with_vid_pid() failed\n");
|
printf("libusb_open_device_with_vid_pid() failed\n");
|
||||||
return -5;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
//int speed = libusb_get_device_speed(device);
|
//int speed = libusb_get_device_speed(device);
|
||||||
@ -80,26 +88,46 @@ int main(int argc, char** argv) {
|
|||||||
|
|
||||||
result = libusb_set_configuration(device, 1);
|
result = libusb_set_configuration(device, 1);
|
||||||
if( result != 0 ) {
|
if( result != 0 ) {
|
||||||
|
libusb_close(device);
|
||||||
printf("libusb_set_configuration() failed: %d\n", result);
|
printf("libusb_set_configuration() failed: %d\n", result);
|
||||||
return -6;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
result = libusb_claim_interface(device, 0);
|
result = libusb_claim_interface(device, 0);
|
||||||
if( result != 0 ) {
|
if( result != 0 ) {
|
||||||
|
libusb_close(device);
|
||||||
printf("libusb_claim_interface() failed: %d\n", result);
|
printf("libusb_claim_interface() failed: %d\n", result);
|
||||||
return -7;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned char endpoint_address = 0x81;
|
return device;
|
||||||
//unsigned char endpoint_address = 0x02;
|
}
|
||||||
|
|
||||||
|
void free_transfers(struct libusb_transfer** const transfers, const uint32_t transfer_count) {
|
||||||
|
for(uint32_t transfer_index=0; transfer_index<transfer_count; transfer_index++) {
|
||||||
|
libusb_free_transfer(transfers[transfer_index]);
|
||||||
|
}
|
||||||
|
free(transfers);
|
||||||
|
}
|
||||||
|
|
||||||
|
struct libusb_transfer** prepare_transfers(
|
||||||
|
libusb_device_handle* const device,
|
||||||
|
const uint_fast8_t endpoint_address,
|
||||||
|
const uint32_t transfer_count,
|
||||||
|
const uint32_t buffer_size,
|
||||||
|
libusb_transfer_cb_fn callback
|
||||||
|
) {
|
||||||
|
struct libusb_transfer** const transfers = calloc(transfer_count, sizeof(struct libusb_transfer));
|
||||||
|
if( transfers == NULL ) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
const uint32_t transfer_count = 1024;
|
|
||||||
struct libusb_transfer* transfers[transfer_count];
|
|
||||||
for(uint32_t transfer_index=0; transfer_index<transfer_count; transfer_index++) {
|
for(uint32_t transfer_index=0; transfer_index<transfer_count; transfer_index++) {
|
||||||
transfers[transfer_index] = libusb_alloc_transfer(0);
|
transfers[transfer_index] = libusb_alloc_transfer(0);
|
||||||
if( transfers[transfer_index] == 0 ) {
|
if( transfers[transfer_index] == NULL ) {
|
||||||
|
free_transfers(transfers, transfer_count);
|
||||||
printf("libusb_alloc_transfer() failed\n");
|
printf("libusb_alloc_transfer() failed\n");
|
||||||
return -6;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
libusb_fill_bulk_transfer(
|
libusb_fill_bulk_transfer(
|
||||||
@ -108,23 +136,113 @@ int main(int argc, char** argv) {
|
|||||||
endpoint_address,
|
endpoint_address,
|
||||||
(unsigned char*)malloc(buffer_size),
|
(unsigned char*)malloc(buffer_size),
|
||||||
buffer_size,
|
buffer_size,
|
||||||
&write_callback,
|
callback,
|
||||||
NULL,
|
NULL,
|
||||||
0
|
0
|
||||||
);
|
);
|
||||||
|
|
||||||
if( transfers[transfer_index]->buffer == 0 ) {
|
if( transfers[transfer_index]->buffer == NULL ) {
|
||||||
|
free_transfers(transfers, transfer_count);
|
||||||
printf("malloc() failed\n");
|
printf("malloc() failed\n");
|
||||||
return -7;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
int error = libusb_submit_transfer(transfers[transfer_index]);
|
int error = libusb_submit_transfer(transfers[transfer_index]);
|
||||||
if( error != 0 ) {
|
if( error != 0 ) {
|
||||||
|
free_transfers(transfers, transfer_count);
|
||||||
printf("libusb_submit_transfer() failed: %d\n", error);
|
printf("libusb_submit_transfer() failed: %d\n", error);
|
||||||
return -8;
|
return NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return transfers;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void usage() {
|
||||||
|
printf("Usage:\n");
|
||||||
|
printf("\tGo fish.\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(int argc, char** argv) {
|
||||||
|
int opt;
|
||||||
|
bool receive = false;
|
||||||
|
bool transmit = false;
|
||||||
|
const char* path = NULL;
|
||||||
|
|
||||||
|
while( (opt = getopt(argc, argv, "r:t:")) != EOF ) {
|
||||||
|
switch( opt ) {
|
||||||
|
case 'r':
|
||||||
|
receive = true;
|
||||||
|
path = optarg;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 't':
|
||||||
|
transmit = true;
|
||||||
|
path = optarg;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
usage();
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if( transmit == receive ) {
|
||||||
|
if( transmit == true ) {
|
||||||
|
fprintf(stderr, "receive and transmit options are mutually exclusive\n");
|
||||||
|
} else {
|
||||||
|
fprintf(stderr, "specify either transmit or receive option\n");
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( receive ) {
|
||||||
|
transceiver_mode = TRANSCEIVER_MODE_RX;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( transmit ) {
|
||||||
|
transceiver_mode = TRANSCEIVER_MODE_TX;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( path == NULL ) {
|
||||||
|
fprintf(stderr, "specify a path to a file to transmit/receive\n");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
fd = -1;
|
||||||
|
uint_fast8_t endpoint_address = 0;
|
||||||
|
libusb_transfer_cb_fn callback = NULL;
|
||||||
|
|
||||||
|
if( transceiver_mode == TRANSCEIVER_MODE_RX ) {
|
||||||
|
fd = open(path, O_WRONLY | O_CREAT | O_TRUNC, S_IRWXU | S_IRWXG | S_IRWXO);
|
||||||
|
endpoint_address = 0x81;
|
||||||
|
callback = &write_callback;
|
||||||
|
} else {
|
||||||
|
fd = open(path, O_RDONLY, S_IRWXU | S_IRWXG | S_IRWXO);
|
||||||
|
endpoint_address = 0x02;
|
||||||
|
callback = &read_callback;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( fd == -1 ) {
|
||||||
|
printf("Failed to open file: errno %d\n", errno);
|
||||||
|
return fd;
|
||||||
|
}
|
||||||
|
|
||||||
|
libusb_context* const context = NULL;
|
||||||
|
libusb_device_handle* const device = open_device(context);
|
||||||
|
if( device == NULL ) {
|
||||||
|
return -3;
|
||||||
|
}
|
||||||
|
|
||||||
|
const uint32_t transfer_count = 1024;
|
||||||
|
const uint32_t buffer_size = 16384;
|
||||||
|
struct libusb_transfer** const transfers = prepare_transfers(
|
||||||
|
device, endpoint_address, transfer_count, buffer_size, callback
|
||||||
|
);
|
||||||
|
if( transfers == NULL ) {
|
||||||
|
return -4;
|
||||||
|
}
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
struct timeval timeout = { 0, 500000 };
|
struct timeval timeout = { 0, 500000 };
|
||||||
@ -158,7 +276,9 @@ int main(int argc, char** argv) {
|
|||||||
call_count += 1;
|
call_count += 1;
|
||||||
} while(1);
|
} while(1);
|
||||||
|
|
||||||
result = libusb_release_interface(device, 0);
|
free_transfers(transfers, transfer_count);
|
||||||
|
|
||||||
|
int result = libusb_release_interface(device, 0);
|
||||||
if( result != 0 ) {
|
if( result != 0 ) {
|
||||||
printf("libusb_release_interface() failed: %d\n", result);
|
printf("libusb_release_interface() failed: %d\n", result);
|
||||||
return -2000;
|
return -2000;
|
||||||
|
Reference in New Issue
Block a user