@ -37,6 +37,7 @@ script:
|
|||||||
- cd ../..
|
- cd ../..
|
||||||
- mkdir firmware/build-hackrf-one
|
- mkdir firmware/build-hackrf-one
|
||||||
- mkdir firmware/build-jawbreaker
|
- mkdir firmware/build-jawbreaker
|
||||||
|
- mkdir firmware/build-rad1o
|
||||||
- cd firmware/libopencm3
|
- cd firmware/libopencm3
|
||||||
- make
|
- make
|
||||||
- cd ../build-hackrf-one
|
- cd ../build-hackrf-one
|
||||||
@ -45,6 +46,9 @@ script:
|
|||||||
- cd ../build-jawbreaker
|
- cd ../build-jawbreaker
|
||||||
- cmake -DBOARD=JAWBREAKER ..
|
- cmake -DBOARD=JAWBREAKER ..
|
||||||
- make
|
- make
|
||||||
|
- cd ../build-rad1o
|
||||||
|
- cmake -DBOARD=RAD1O ..
|
||||||
|
- make
|
||||||
|
|
||||||
addons:
|
addons:
|
||||||
apt:
|
apt:
|
||||||
|
@ -32,6 +32,7 @@ $ make
|
|||||||
$ hackrf_spiflash -w hackrf_usb.bin
|
$ hackrf_spiflash -w hackrf_usb.bin
|
||||||
|
|
||||||
If you have a Jawbreaker, add -DBOARD=JAWBREAKER to the cmake command.
|
If you have a Jawbreaker, add -DBOARD=JAWBREAKER to the cmake command.
|
||||||
|
If you have a rad1o, use -DBOARD=RAD1O instead.
|
||||||
|
|
||||||
|
|
||||||
It is possible to use a USB Device Firmware Upgrade (DFU) method to load
|
It is possible to use a USB Device Firmware Upgrade (DFU) method to load
|
||||||
|
17
firmware/common/hackrf-ui.h
Normal file
17
firmware/common/hackrf-ui.h
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
#ifndef HACKRF_UI_H
|
||||||
|
#define HACKRF_UI_H
|
||||||
|
|
||||||
|
#include <rf_path.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
void hackrf_ui_init(void) __attribute__((weak));
|
||||||
|
void hackrf_ui_setFrequency(uint64_t _freq) __attribute__((weak));
|
||||||
|
void hackrf_ui_setSampleRate(uint32_t _sample_rate) __attribute__((weak));
|
||||||
|
void hackrf_ui_setDirection(const rf_path_direction_t _direction) __attribute__((weak));
|
||||||
|
void hackrf_ui_setFilterBW(uint32_t bw) __attribute__((weak));
|
||||||
|
void hackrf_ui_setLNAPower(bool _lna_on) __attribute__((weak));
|
||||||
|
void hackrf_ui_setBBLNAGain(const uint32_t gain_db) __attribute__((weak));
|
||||||
|
void hackrf_ui_setBBVGAGain(const uint32_t gain_db) __attribute__((weak));
|
||||||
|
void hackrf_ui_setBBTXVGAGain(const uint32_t gain_db) __attribute__((weak));
|
||||||
|
|
||||||
|
#endif
|
@ -22,14 +22,13 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include "hackrf_core.h"
|
#include "hackrf_core.h"
|
||||||
|
#include "hackrf-ui.h"
|
||||||
#include "si5351c.h"
|
#include "si5351c.h"
|
||||||
#include "spi_ssp.h"
|
#include "spi_ssp.h"
|
||||||
#include "max2837.h"
|
#include "max2837.h"
|
||||||
#include "max2837_target.h"
|
#include "max2837_target.h"
|
||||||
#include "max5864.h"
|
#include "max5864.h"
|
||||||
#include "max5864_target.h"
|
#include "max5864_target.h"
|
||||||
#include "rffc5071.h"
|
|
||||||
#include "rffc5071_spi.h"
|
|
||||||
#include "w25q80bv.h"
|
#include "w25q80bv.h"
|
||||||
#include "w25q80bv_target.h"
|
#include "w25q80bv_target.h"
|
||||||
#include "i2c_bus.h"
|
#include "i2c_bus.h"
|
||||||
@ -47,10 +46,13 @@
|
|||||||
#define WAIT_CPU_CLOCK_INIT_DELAY (10000)
|
#define WAIT_CPU_CLOCK_INIT_DELAY (10000)
|
||||||
|
|
||||||
/* GPIO Output PinMux */
|
/* GPIO Output PinMux */
|
||||||
static struct gpio_t gpio_led[3] = {
|
static struct gpio_t gpio_led[] = {
|
||||||
GPIO(2, 1),
|
GPIO(2, 1),
|
||||||
GPIO(2, 2),
|
GPIO(2, 2),
|
||||||
GPIO(2, 8)
|
GPIO(2, 8),
|
||||||
|
#ifdef RAD1O
|
||||||
|
GPIO(5, 26),
|
||||||
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct gpio_t gpio_1v8_enable = GPIO(3, 6);
|
static struct gpio_t gpio_1v8_enable = GPIO(3, 6);
|
||||||
@ -74,19 +76,7 @@ static struct gpio_t gpio_max2837_b7 = GPIO(2, 15);
|
|||||||
/* MAX5864 SPI chip select (AD_CS) GPIO PinMux */
|
/* MAX5864 SPI chip select (AD_CS) GPIO PinMux */
|
||||||
static struct gpio_t gpio_max5864_select = GPIO(2, 7);
|
static struct gpio_t gpio_max5864_select = GPIO(2, 7);
|
||||||
|
|
||||||
/* RFFC5071 GPIO serial interface PinMux */
|
#if (defined JAWBREAKER || defined HACKRF_ONE || defined RAD1O)
|
||||||
#ifdef JELLYBEAN
|
|
||||||
static struct gpio_t gpio_rffc5072_select = GPIO(3, 8);
|
|
||||||
static struct gpio_t gpio_rffc5072_clock = GPIO(3, 9);
|
|
||||||
static struct gpio_t gpio_rffc5072_data = GPIO(3, 10);
|
|
||||||
static struct gpio_t gpio_rffc5072_reset = GPIO(3, 11);
|
|
||||||
#endif
|
|
||||||
#if (defined JAWBREAKER || defined HACKRF_ONE)
|
|
||||||
static struct gpio_t gpio_rffc5072_select = GPIO(2, 13);
|
|
||||||
static struct gpio_t gpio_rffc5072_clock = GPIO(5, 6);
|
|
||||||
static struct gpio_t gpio_rffc5072_data = GPIO(3, 3);
|
|
||||||
static struct gpio_t gpio_rffc5072_reset = GPIO(2, 14);
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
static struct gpio_t gpio_sync_in_a = GPIO(3, 8);
|
static struct gpio_t gpio_sync_in_a = GPIO(3, 8);
|
||||||
static struct gpio_t gpio_sync_in_b = GPIO(3, 9);
|
static struct gpio_t gpio_sync_in_b = GPIO(3, 9);
|
||||||
@ -108,6 +98,9 @@ static struct gpio_t gpio_sync_out_b = GPIO(3, 9);
|
|||||||
#ifdef HACKRF_ONE
|
#ifdef HACKRF_ONE
|
||||||
static struct gpio_t gpio_vaa_disable = GPIO(2, 9);
|
static struct gpio_t gpio_vaa_disable = GPIO(2, 9);
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef RAD1O
|
||||||
|
static struct gpio_t gpio_vaa_enable = GPIO(2, 9);
|
||||||
|
#endif
|
||||||
|
|
||||||
static struct gpio_t gpio_w25q80bv_hold = GPIO(1, 14);
|
static struct gpio_t gpio_w25q80bv_hold = GPIO(1, 14);
|
||||||
static struct gpio_t gpio_w25q80bv_wp = GPIO(1, 15);
|
static struct gpio_t gpio_w25q80bv_wp = GPIO(1, 15);
|
||||||
@ -129,6 +122,20 @@ static struct gpio_t gpio_amp_bypass = GPIO(0, 14);
|
|||||||
static struct gpio_t gpio_rx_amp = GPIO(1, 11);
|
static struct gpio_t gpio_rx_amp = GPIO(1, 11);
|
||||||
static struct gpio_t gpio_no_rx_amp_pwr = GPIO(1, 12);
|
static struct gpio_t gpio_no_rx_amp_pwr = GPIO(1, 12);
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef RAD1O
|
||||||
|
static struct gpio_t gpio_tx_rx_n = GPIO(0, 11);
|
||||||
|
static struct gpio_t gpio_tx_rx = GPIO(0, 14);
|
||||||
|
static struct gpio_t gpio_by_mix = GPIO(1, 12);
|
||||||
|
static struct gpio_t gpio_by_mix_n = GPIO(2, 10);
|
||||||
|
static struct gpio_t gpio_by_amp = GPIO(1, 0);
|
||||||
|
static struct gpio_t gpio_by_amp_n = GPIO(5, 5);
|
||||||
|
static struct gpio_t gpio_mixer_en = GPIO(5, 16);
|
||||||
|
static struct gpio_t gpio_low_high_filt = GPIO(2, 11);
|
||||||
|
static struct gpio_t gpio_low_high_filt_n = GPIO(2, 12);
|
||||||
|
static struct gpio_t gpio_tx_amp = GPIO(2, 15);
|
||||||
|
static struct gpio_t gpio_rx_lna = GPIO(5, 15);
|
||||||
|
#endif
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
/* GPIO Input */
|
/* GPIO Input */
|
||||||
static struct gpio_t gpio_boot[] = {
|
static struct gpio_t gpio_boot[] = {
|
||||||
@ -141,7 +148,7 @@ static struct gpio_t gpio_boot[] = {
|
|||||||
/* CPLD JTAG interface GPIO pins */
|
/* CPLD JTAG interface GPIO pins */
|
||||||
static struct gpio_t gpio_cpld_tdo = GPIO(5, 18);
|
static struct gpio_t gpio_cpld_tdo = GPIO(5, 18);
|
||||||
static struct gpio_t gpio_cpld_tck = GPIO(3, 0);
|
static struct gpio_t gpio_cpld_tck = GPIO(3, 0);
|
||||||
#ifdef HACKRF_ONE
|
#if defined HACKRF_ONE || defined RAD1O
|
||||||
static struct gpio_t gpio_cpld_tms = GPIO(3, 4);
|
static struct gpio_t gpio_cpld_tms = GPIO(3, 4);
|
||||||
static struct gpio_t gpio_cpld_tdi = GPIO(3, 1);
|
static struct gpio_t gpio_cpld_tdi = GPIO(3, 1);
|
||||||
#else
|
#else
|
||||||
@ -244,25 +251,6 @@ max5864_driver_t max5864 = {
|
|||||||
.target_init = max5864_target_init,
|
.target_init = max5864_target_init,
|
||||||
};
|
};
|
||||||
|
|
||||||
const rffc5071_spi_config_t rffc5071_spi_config = {
|
|
||||||
.gpio_select = &gpio_rffc5072_select,
|
|
||||||
.gpio_clock = &gpio_rffc5072_clock,
|
|
||||||
.gpio_data = &gpio_rffc5072_data,
|
|
||||||
};
|
|
||||||
|
|
||||||
spi_bus_t spi_bus_rffc5071 = {
|
|
||||||
.config = &rffc5071_spi_config,
|
|
||||||
.start = rffc5071_spi_start,
|
|
||||||
.stop = rffc5071_spi_stop,
|
|
||||||
.transfer = rffc5071_spi_transfer,
|
|
||||||
.transfer_gather = rffc5071_spi_transfer_gather,
|
|
||||||
};
|
|
||||||
|
|
||||||
rffc5071_driver_t rffc5072 = {
|
|
||||||
.bus = &spi_bus_rffc5071,
|
|
||||||
.gpio_reset = &gpio_rffc5072_reset,
|
|
||||||
};
|
|
||||||
|
|
||||||
const ssp_config_t ssp_config_w25q80bv = {
|
const ssp_config_t ssp_config_w25q80bv = {
|
||||||
.data_bits = SSP_DATA_8BITS,
|
.data_bits = SSP_DATA_8BITS,
|
||||||
.serial_clock_rate = 2,
|
.serial_clock_rate = 2,
|
||||||
@ -313,6 +301,19 @@ rf_path_t rf_path = {
|
|||||||
.gpio_rx_amp = &gpio_rx_amp,
|
.gpio_rx_amp = &gpio_rx_amp,
|
||||||
.gpio_no_rx_amp_pwr = &gpio_no_rx_amp_pwr,
|
.gpio_no_rx_amp_pwr = &gpio_no_rx_amp_pwr,
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef RAD1O
|
||||||
|
.gpio_tx_rx_n = &gpio_tx_rx_n,
|
||||||
|
.gpio_tx_rx = &gpio_tx_rx,
|
||||||
|
.gpio_by_mix = &gpio_by_mix,
|
||||||
|
.gpio_by_mix_n = &gpio_by_mix_n,
|
||||||
|
.gpio_by_amp = &gpio_by_amp,
|
||||||
|
.gpio_by_amp_n = &gpio_by_amp_n,
|
||||||
|
.gpio_mixer_en = &gpio_mixer_en,
|
||||||
|
.gpio_low_high_filt = &gpio_low_high_filt,
|
||||||
|
.gpio_low_high_filt_n = &gpio_low_high_filt_n,
|
||||||
|
.gpio_tx_amp = &gpio_tx_amp,
|
||||||
|
.gpio_rx_lna = &gpio_rx_lna,
|
||||||
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
jtag_gpio_t jtag_gpio_cpld = {
|
jtag_gpio_t jtag_gpio_cpld = {
|
||||||
@ -377,6 +378,8 @@ bool sample_rate_frac_set(uint32_t rate_num, uint32_t rate_denom)
|
|||||||
uint32_t a, b, c;
|
uint32_t a, b, c;
|
||||||
uint32_t rem;
|
uint32_t rem;
|
||||||
|
|
||||||
|
hackrf_ui_setSampleRate(rate_num/2);
|
||||||
|
|
||||||
/* Find best config */
|
/* Find best config */
|
||||||
a = (VCO_FREQ * rate_denom) / rate_num;
|
a = (VCO_FREQ * rate_denom) / rate_num;
|
||||||
|
|
||||||
@ -460,7 +463,9 @@ bool sample_rate_set(const uint32_t sample_rate_hz) {
|
|||||||
default:
|
default:
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
hackrf_ui_setSampleRate(sample_rate_hz);
|
||||||
|
|
||||||
/* NOTE: Because MS1, 2, 3 outputs are slaved to PLLA, the p1, p2, p3
|
/* NOTE: Because MS1, 2, 3 outputs are slaved to PLLA, the p1, p2, p3
|
||||||
* values are irrelevant. */
|
* values are irrelevant. */
|
||||||
|
|
||||||
@ -476,7 +481,7 @@ bool sample_rate_set(const uint32_t sample_rate_hz) {
|
|||||||
return true;
|
return true;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if (defined JAWBREAKER || defined HACKRF_ONE)
|
#if (defined JAWBREAKER || defined HACKRF_ONE || defined RAD1O)
|
||||||
uint32_t p1 = 4608;
|
uint32_t p1 = 4608;
|
||||||
uint32_t p2 = 0;
|
uint32_t p2 = 0;
|
||||||
uint32_t p3 = 0;
|
uint32_t p3 = 0;
|
||||||
@ -541,7 +546,11 @@ bool sample_rate_set(const uint32_t sample_rate_hz) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool baseband_filter_bandwidth_set(const uint32_t bandwidth_hz) {
|
bool baseband_filter_bandwidth_set(const uint32_t bandwidth_hz) {
|
||||||
return max2837_set_lpf_bandwidth(&max2837, bandwidth_hz);
|
uint32_t bandwidth_hz_real = max2837_set_lpf_bandwidth(&max2837, bandwidth_hz);
|
||||||
|
|
||||||
|
if(bandwidth_hz_real) hackrf_ui_setFilterBW(bandwidth_hz_real);
|
||||||
|
|
||||||
|
return bandwidth_hz_real != 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* clock startup for Jellybean with Lemondrop attached
|
/* clock startup for Jellybean with Lemondrop attached
|
||||||
@ -616,6 +625,33 @@ void cpu_clock_init(void)
|
|||||||
si5351c_write(&clock_gen, ms7data, sizeof(ms7data));
|
si5351c_write(&clock_gen, ms7data, sizeof(ms7data));
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef RAD1O
|
||||||
|
/* rad1o clocks:
|
||||||
|
* CLK0 -> MAX5864/CPLD
|
||||||
|
* CLK1 -> CPLD
|
||||||
|
* CLK2 -> SGPIO
|
||||||
|
* CLK3 -> External Clock Output
|
||||||
|
* CLK4 -> MAX2837
|
||||||
|
* CLK5 -> MAX2871
|
||||||
|
* CLK6 -> none
|
||||||
|
* CLK7 -> LPC4330 (but LPC4330 starts up on its own crystal) */
|
||||||
|
|
||||||
|
/* MS3/CLK3 is the source for the external clock output. */
|
||||||
|
si5351c_configure_multisynth(&clock_gen, 3, 80*128-512, 0, 1, 0); /* 800/80 = 10MHz */
|
||||||
|
|
||||||
|
/* MS4/CLK4 is the source for the MAX2837 clock input. */
|
||||||
|
si5351c_configure_multisynth(&clock_gen, 4, 20*128-512, 0, 1, 0); /* 800/20 = 40MHz */
|
||||||
|
|
||||||
|
/* MS5/CLK5 is the source for the RFFC5071 mixer. */
|
||||||
|
si5351c_configure_multisynth(&clock_gen, 5, 20*128-512, 0, 1, 0); /* 800/20 = 40MHz */
|
||||||
|
|
||||||
|
/* MS6/CLK6 is unused. */
|
||||||
|
|
||||||
|
/* MS7/CLK7 is the source for the LPC43xx microcontroller. */
|
||||||
|
uint8_t ms7data[] = { 90, 255, 20, 0 };
|
||||||
|
si5351c_write(&clock_gen, ms7data, sizeof(ms7data));
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Set to 10 MHz, the common rate between Jellybean and Jawbreaker. */
|
/* Set to 10 MHz, the common rate between Jellybean and Jawbreaker. */
|
||||||
sample_rate_set(10000000);
|
sample_rate_set(10000000);
|
||||||
|
|
||||||
@ -893,7 +929,10 @@ void pin_setup(void) {
|
|||||||
scu_pinmux(SCU_PINMUX_LED1, SCU_GPIO_NOPULL);
|
scu_pinmux(SCU_PINMUX_LED1, SCU_GPIO_NOPULL);
|
||||||
scu_pinmux(SCU_PINMUX_LED2, SCU_GPIO_NOPULL);
|
scu_pinmux(SCU_PINMUX_LED2, SCU_GPIO_NOPULL);
|
||||||
scu_pinmux(SCU_PINMUX_LED3, SCU_GPIO_NOPULL);
|
scu_pinmux(SCU_PINMUX_LED3, SCU_GPIO_NOPULL);
|
||||||
|
#ifdef RAD1O
|
||||||
|
scu_pinmux(SCU_PINMUX_LED4, SCU_GPIO_NOPULL | SCU_CONF_FUNCTION4);
|
||||||
|
#endif
|
||||||
|
|
||||||
scu_pinmux(SCU_PINMUX_EN1V8, SCU_GPIO_NOPULL);
|
scu_pinmux(SCU_PINMUX_EN1V8, SCU_GPIO_NOPULL);
|
||||||
|
|
||||||
/* Configure USB indicators */
|
/* Configure USB indicators */
|
||||||
@ -908,6 +947,9 @@ void pin_setup(void) {
|
|||||||
gpio_output(&gpio_led[0]);
|
gpio_output(&gpio_led[0]);
|
||||||
gpio_output(&gpio_led[1]);
|
gpio_output(&gpio_led[1]);
|
||||||
gpio_output(&gpio_led[2]);
|
gpio_output(&gpio_led[2]);
|
||||||
|
#ifdef RAD1O
|
||||||
|
gpio_output(&gpio_led[3]);
|
||||||
|
#endif
|
||||||
|
|
||||||
gpio_output(&gpio_1v8_enable);
|
gpio_output(&gpio_1v8_enable);
|
||||||
|
|
||||||
@ -928,11 +970,29 @@ void pin_setup(void) {
|
|||||||
gpio_output(&gpio_sync_out_b);
|
gpio_output(&gpio_sync_out_b);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef RAD1O
|
||||||
|
/* Configure RF power supply (VAA) switch control signal as output */
|
||||||
|
gpio_output(&gpio_vaa_enable);
|
||||||
|
|
||||||
|
/* Safe state: start with VAA turned off: */
|
||||||
|
disable_rf_power();
|
||||||
|
|
||||||
|
scu_pinmux(SCU_PINMUX_GPIO3_10, SCU_GPIO_PDN | SCU_CONF_FUNCTION0);
|
||||||
|
scu_pinmux(SCU_PINMUX_GPIO3_11, SCU_GPIO_PDN | SCU_CONF_FUNCTION0);
|
||||||
|
|
||||||
|
gpio_input(&gpio_sync_in_a);
|
||||||
|
gpio_input(&gpio_sync_in_b);
|
||||||
|
|
||||||
|
gpio_output(&gpio_sync_out_a);
|
||||||
|
gpio_output(&gpio_sync_out_b);
|
||||||
|
#endif
|
||||||
|
|
||||||
/* enable input on SCL and SDA pins */
|
/* enable input on SCL and SDA pins */
|
||||||
SCU_SFSI2C0 = SCU_I2C0_NOMINAL;
|
SCU_SFSI2C0 = SCU_I2C0_NOMINAL;
|
||||||
|
|
||||||
spi_bus_start(&spi_bus_ssp1, &ssp_config_max2837);
|
spi_bus_start(&spi_bus_ssp1, &ssp_config_max2837);
|
||||||
spi_bus_start(&spi_bus_rffc5071, &rffc5071_spi_config);
|
|
||||||
|
mixer_bus_setup(&mixer);
|
||||||
|
|
||||||
rf_path_pin_setup(&rf_path);
|
rf_path_pin_setup(&rf_path);
|
||||||
|
|
||||||
@ -960,6 +1020,16 @@ void disable_rf_power(void) {
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef RAD1O
|
||||||
|
void enable_rf_power(void) {
|
||||||
|
gpio_set(&gpio_vaa_enable);
|
||||||
|
}
|
||||||
|
|
||||||
|
void disable_rf_power(void) {
|
||||||
|
gpio_clear(&gpio_vaa_enable);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
void led_on(const led_t led) {
|
void led_on(const led_t led) {
|
||||||
gpio_set(&gpio_led[led]);
|
gpio_set(&gpio_led[led]);
|
||||||
}
|
}
|
||||||
@ -1001,4 +1071,3 @@ void hw_sync_copy_state() {
|
|||||||
bool hw_sync_ready() {
|
bool hw_sync_ready() {
|
||||||
return (gpio_read(&gpio_sync_in_a) && gpio_read(&gpio_sync_in_b));
|
return (gpio_read(&gpio_sync_in_a) && gpio_read(&gpio_sync_in_b));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -37,7 +37,7 @@ extern "C"
|
|||||||
|
|
||||||
#include "max2837.h"
|
#include "max2837.h"
|
||||||
#include "max5864.h"
|
#include "max5864.h"
|
||||||
#include "rffc5071.h"
|
#include "mixer.h"
|
||||||
#include "w25q80bv.h"
|
#include "w25q80bv.h"
|
||||||
#include "sgpio.h"
|
#include "sgpio.h"
|
||||||
#include "rf_path.h"
|
#include "rf_path.h"
|
||||||
@ -47,6 +47,7 @@ extern "C"
|
|||||||
#define BOARD_ID_JELLYBEAN 0
|
#define BOARD_ID_JELLYBEAN 0
|
||||||
#define BOARD_ID_JAWBREAKER 1
|
#define BOARD_ID_JAWBREAKER 1
|
||||||
#define BOARD_ID_HACKRF_ONE 2
|
#define BOARD_ID_HACKRF_ONE 2
|
||||||
|
#define BOARD_ID_RAD1O 3
|
||||||
|
|
||||||
#ifdef JELLYBEAN
|
#ifdef JELLYBEAN
|
||||||
#define BOARD_ID BOARD_ID_JELLYBEAN
|
#define BOARD_ID BOARD_ID_JELLYBEAN
|
||||||
@ -60,6 +61,10 @@ extern "C"
|
|||||||
#define BOARD_ID BOARD_ID_HACKRF_ONE
|
#define BOARD_ID BOARD_ID_HACKRF_ONE
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef RAD1O
|
||||||
|
#define BOARD_ID BOARD_ID_RAD1O
|
||||||
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* SCU PinMux
|
* SCU PinMux
|
||||||
*/
|
*/
|
||||||
@ -68,6 +73,9 @@ extern "C"
|
|||||||
#define SCU_PINMUX_LED1 (P4_1) /* GPIO2[1] on P4_1 */
|
#define SCU_PINMUX_LED1 (P4_1) /* GPIO2[1] on P4_1 */
|
||||||
#define SCU_PINMUX_LED2 (P4_2) /* GPIO2[2] on P4_2 */
|
#define SCU_PINMUX_LED2 (P4_2) /* GPIO2[2] on P4_2 */
|
||||||
#define SCU_PINMUX_LED3 (P6_12) /* GPIO2[8] on P6_12 */
|
#define SCU_PINMUX_LED3 (P6_12) /* GPIO2[8] on P6_12 */
|
||||||
|
#ifdef RAD1O
|
||||||
|
#define SCU_PINMUX_LED4 (PB_6) /* GPIO5[26] on PB_6 */
|
||||||
|
#endif
|
||||||
|
|
||||||
#define SCU_PINMUX_EN1V8 (P6_10) /* GPIO3[6] on P6_10 */
|
#define SCU_PINMUX_EN1V8 (P6_10) /* GPIO3[6] on P6_10 */
|
||||||
|
|
||||||
@ -92,7 +100,7 @@ extern "C"
|
|||||||
/* CPLD JTAG interface */
|
/* CPLD JTAG interface */
|
||||||
#define SCU_PINMUX_CPLD_TDO (P9_5) /* GPIO5[18] */
|
#define SCU_PINMUX_CPLD_TDO (P9_5) /* GPIO5[18] */
|
||||||
#define SCU_PINMUX_CPLD_TCK (P6_1) /* GPIO3[ 0] */
|
#define SCU_PINMUX_CPLD_TCK (P6_1) /* GPIO3[ 0] */
|
||||||
#ifdef HACKRF_ONE
|
#if (defined HACKRF_ONE || defined RAD1O)
|
||||||
#define SCU_PINMUX_CPLD_TMS (P6_5) /* GPIO3[ 4] */
|
#define SCU_PINMUX_CPLD_TMS (P6_5) /* GPIO3[ 4] */
|
||||||
#define SCU_PINMUX_CPLD_TDI (P6_2) /* GPIO3[ 1] */
|
#define SCU_PINMUX_CPLD_TDI (P6_2) /* GPIO3[ 1] */
|
||||||
#else
|
#else
|
||||||
@ -112,7 +120,7 @@ extern "C"
|
|||||||
#ifdef JELLYBEAN
|
#ifdef JELLYBEAN
|
||||||
#define SCU_PINMUX_SGPIO8 (P1_12)
|
#define SCU_PINMUX_SGPIO8 (P1_12)
|
||||||
#endif
|
#endif
|
||||||
#if (defined JAWBREAKER || defined HACKRF_ONE)
|
#if (defined JAWBREAKER || defined HACKRF_ONE || defined RAD1O)
|
||||||
#define SCU_PINMUX_SGPIO8 (P9_6)
|
#define SCU_PINMUX_SGPIO8 (P9_6)
|
||||||
#endif
|
#endif
|
||||||
#define SCU_PINMUX_SGPIO9 (P4_3)
|
#define SCU_PINMUX_SGPIO9 (P4_3)
|
||||||
@ -134,6 +142,12 @@ extern "C"
|
|||||||
#define SCU_XCVR_B6 (P5_5) /* GPIO2[14] on P5_5 */
|
#define SCU_XCVR_B6 (P5_5) /* GPIO2[14] on P5_5 */
|
||||||
#define SCU_XCVR_B7 (P5_6) /* GPIO2[15] on P5_6 */
|
#define SCU_XCVR_B7 (P5_6) /* GPIO2[15] on P5_6 */
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef RAD1O
|
||||||
|
#define SCU_XCVR_RXHP (P8_1) /* GPIO[] on P8_1 */
|
||||||
|
#define SCU_XCVR_B6 (P8_2) /* GPIO[] on P8_2 */
|
||||||
|
#define SCU_XCVR_B7 (P9_3) /* GPIO[] on P8_3 */
|
||||||
|
#endif
|
||||||
|
|
||||||
#define SCU_XCVR_ENABLE (P4_6) /* GPIO2[6] on P4_6 */
|
#define SCU_XCVR_ENABLE (P4_6) /* GPIO2[6] on P4_6 */
|
||||||
#define SCU_XCVR_RXENABLE (P4_5) /* GPIO2[5] on P4_5 */
|
#define SCU_XCVR_RXENABLE (P4_5) /* GPIO2[5] on P4_5 */
|
||||||
#define SCU_XCVR_TXENABLE (P4_4) /* GPIO2[4] on P4_4 */
|
#define SCU_XCVR_TXENABLE (P4_4) /* GPIO2[4] on P4_4 */
|
||||||
@ -155,6 +169,15 @@ extern "C"
|
|||||||
#define SCU_MIXER_SDATA (P6_4) /* GPIO3[3] on P6_4 */
|
#define SCU_MIXER_SDATA (P6_4) /* GPIO3[3] on P6_4 */
|
||||||
#define SCU_MIXER_RESETX (P5_5) /* GPIO2[14] on P5_5 */
|
#define SCU_MIXER_RESETX (P5_5) /* GPIO2[14] on P5_5 */
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef RAD1O
|
||||||
|
#define SCU_VCO_CE (P5_4) /* GPIO2[13] on P5_4 */
|
||||||
|
#define SCU_VCO_SCLK (P2_6) /* GPIO5[6] on P2_6 */
|
||||||
|
#define SCU_VCO_SDATA (P6_4) /* GPIO3[3] on P6_4 */
|
||||||
|
#define SCU_VCO_LE (P5_5) /* GPIO2[14] on P5_5 */
|
||||||
|
#define SCU_VCO_MUX (PB_5) /* GPIO5[25] on PB_5 */
|
||||||
|
#define SCU_MIXER_EN (P6_8) /* GPIO5[16] on P6_8 */
|
||||||
|
#define SCU_SYNT_RFOUT_EN (P6_9) /* GPIO3[5] on P6_9 */
|
||||||
|
#endif
|
||||||
|
|
||||||
/* RF LDO control */
|
/* RF LDO control */
|
||||||
#ifdef JAWBREAKER
|
#ifdef JAWBREAKER
|
||||||
@ -165,6 +188,10 @@ extern "C"
|
|||||||
#ifdef HACKRF_ONE
|
#ifdef HACKRF_ONE
|
||||||
#define SCU_NO_VAA_ENABLE (P5_0) /* GPIO2[9] on P5_0 */
|
#define SCU_NO_VAA_ENABLE (P5_0) /* GPIO2[9] on P5_0 */
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef RAD1O
|
||||||
|
#define SCU_VAA_ENABLE (P5_0) /* GPIO2[9] on P5_0 */
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
/* SPI flash */
|
/* SPI flash */
|
||||||
#define SCU_SSP0_MISO (P3_6)
|
#define SCU_SSP0_MISO (P3_6)
|
||||||
@ -190,6 +217,18 @@ extern "C"
|
|||||||
#define SCU_RX_AMP (P2_11) /* GPIO1[11] on P2_11 */
|
#define SCU_RX_AMP (P2_11) /* GPIO1[11] on P2_11 */
|
||||||
#define SCU_NO_RX_AMP_PWR (P2_12) /* GPIO1[12] on P2_12 */
|
#define SCU_NO_RX_AMP_PWR (P2_12) /* GPIO1[12] on P2_12 */
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef RAD1O
|
||||||
|
#define SCU_BY_AMP (P1_7) /* GPIO1[0] on P1_7 */
|
||||||
|
#define SCU_BY_AMP_N (P2_5) /* GPIO5[5] on P2_5 */
|
||||||
|
#define SCU_TX_RX (P2_10) /* GPIO0[14] on P2_10 */
|
||||||
|
#define SCU_TX_RX_N (P2_11) /* GPIO1[11] on P2_11 */
|
||||||
|
#define SCU_BY_MIX (P2_12) /* GPIO1[12] on P2_12 */
|
||||||
|
#define SCU_BY_MIX_N (P5_1) /* GPIO2[10] on P5_1 */
|
||||||
|
#define SCU_LOW_HIGH_FILT (P5_2) /* GPIO2[11] on P5_2 */
|
||||||
|
#define SCU_LOW_HIGH_FILT_N (P5_3) /* GPIO2[12] on P5_3 */
|
||||||
|
#define SCU_TX_AMP (P5_6) /* GPIO2[15] on P5_6 */
|
||||||
|
#define SCU_RX_LNA (P6_7) /* GPIO5[15] on P6_7 */
|
||||||
|
#endif
|
||||||
|
|
||||||
/* TODO add other Pins */
|
/* TODO add other Pins */
|
||||||
#define SCU_PINMUX_GPIO3_8 (P7_0) /* GPIO3[8] */
|
#define SCU_PINMUX_GPIO3_8 (P7_0) /* GPIO3[8] */
|
||||||
@ -240,7 +279,7 @@ extern const ssp_config_t ssp_config_max5864;
|
|||||||
|
|
||||||
extern max2837_driver_t max2837;
|
extern max2837_driver_t max2837;
|
||||||
extern max5864_driver_t max5864;
|
extern max5864_driver_t max5864;
|
||||||
extern rffc5071_driver_t rffc5072;
|
extern mixer_driver_t mixer;
|
||||||
extern w25q80bv_driver_t spi_flash;
|
extern w25q80bv_driver_t spi_flash;
|
||||||
extern sgpio_config_t sgpio_config;
|
extern sgpio_config_t sgpio_config;
|
||||||
extern rf_path_t rf_path;
|
extern rf_path_t rf_path;
|
||||||
@ -262,7 +301,7 @@ bool sample_rate_frac_set(uint32_t rate_num, uint32_t rate_denom);
|
|||||||
bool sample_rate_set(const uint32_t sampling_rate_hz);
|
bool sample_rate_set(const uint32_t sampling_rate_hz);
|
||||||
bool baseband_filter_bandwidth_set(const uint32_t bandwidth_hz);
|
bool baseband_filter_bandwidth_set(const uint32_t bandwidth_hz);
|
||||||
|
|
||||||
#ifdef HACKRF_ONE
|
#if (defined HACKRF_ONE || defined RAD1O)
|
||||||
void enable_rf_power(void);
|
void enable_rf_power(void);
|
||||||
void disable_rf_power(void);
|
void disable_rf_power(void);
|
||||||
#endif
|
#endif
|
||||||
@ -271,6 +310,7 @@ typedef enum {
|
|||||||
LED1 = 0,
|
LED1 = 0,
|
||||||
LED2 = 1,
|
LED2 = 1,
|
||||||
LED3 = 2,
|
LED3 = 2,
|
||||||
|
LED4 = 3,
|
||||||
} led_t;
|
} led_t;
|
||||||
|
|
||||||
void led_on(const led_t led);
|
void led_on(const led_t led);
|
||||||
|
@ -279,7 +279,7 @@ static const max2837_ft_t max2837_ft[] = {
|
|||||||
{ 0, 0 },
|
{ 0, 0 },
|
||||||
};
|
};
|
||||||
|
|
||||||
bool max2837_set_lpf_bandwidth(max2837_driver_t* const drv, const uint32_t bandwidth_hz) {
|
uint32_t max2837_set_lpf_bandwidth(max2837_driver_t* const drv, const uint32_t bandwidth_hz) {
|
||||||
const max2837_ft_t* p = max2837_ft;
|
const max2837_ft_t* p = max2837_ft;
|
||||||
while( p->bandwidth_hz != 0 ) {
|
while( p->bandwidth_hz != 0 ) {
|
||||||
if( p->bandwidth_hz >= bandwidth_hz ) {
|
if( p->bandwidth_hz >= bandwidth_hz ) {
|
||||||
@ -291,10 +291,9 @@ bool max2837_set_lpf_bandwidth(max2837_driver_t* const drv, const uint32_t bandw
|
|||||||
if( p->bandwidth_hz != 0 ) {
|
if( p->bandwidth_hz != 0 ) {
|
||||||
set_MAX2837_FT(drv, p->ft);
|
set_MAX2837_FT(drv, p->ft);
|
||||||
max2837_regs_commit(drv);
|
max2837_regs_commit(drv);
|
||||||
return true;
|
|
||||||
} else {
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return p->bandwidth_hz;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool max2837_set_lna_gain(max2837_driver_t* const drv, const uint32_t gain_db) {
|
bool max2837_set_lna_gain(max2837_driver_t* const drv, const uint32_t gain_db) {
|
||||||
|
@ -91,7 +91,7 @@ extern void max2837_stop(max2837_driver_t* const drv);
|
|||||||
/* Set frequency in Hz. Frequency setting is a multi-step function
|
/* Set frequency in Hz. Frequency setting is a multi-step function
|
||||||
* where order of register writes matters. */
|
* where order of register writes matters. */
|
||||||
extern void max2837_set_frequency(max2837_driver_t* const drv, uint32_t freq);
|
extern void max2837_set_frequency(max2837_driver_t* const drv, uint32_t freq);
|
||||||
bool max2837_set_lpf_bandwidth(max2837_driver_t* const drv, const uint32_t bandwidth_hz);
|
uint32_t max2837_set_lpf_bandwidth(max2837_driver_t* const drv, const uint32_t bandwidth_hz);
|
||||||
bool max2837_set_lna_gain(max2837_driver_t* const drv, const uint32_t gain_db);
|
bool max2837_set_lna_gain(max2837_driver_t* const drv, const uint32_t gain_db);
|
||||||
bool max2837_set_vga_gain(max2837_driver_t* const drv, const uint32_t gain_db);
|
bool max2837_set_vga_gain(max2837_driver_t* const drv, const uint32_t gain_db);
|
||||||
bool max2837_set_txvga_gain(max2837_driver_t* const drv, const uint32_t gain_db);
|
bool max2837_set_txvga_gain(max2837_driver_t* const drv, const uint32_t gain_db);
|
||||||
|
236
firmware/common/max2871.c
Normal file
236
firmware/common/max2871.c
Normal file
@ -0,0 +1,236 @@
|
|||||||
|
#include "max2871.h"
|
||||||
|
#include "max2871_regs.h"
|
||||||
|
|
||||||
|
#if (defined DEBUG)
|
||||||
|
#include <stdio.h>
|
||||||
|
#define LOG printf
|
||||||
|
#else
|
||||||
|
#define LOG(x,...)
|
||||||
|
#include <libopencm3/lpc43xx/ssp.h>
|
||||||
|
#include <libopencm3/lpc43xx/scu.h>
|
||||||
|
#include "hackrf_core.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
static void max2871_spi_write(max2871_driver_t* const drv, uint8_t r, uint32_t v);
|
||||||
|
static void max2871_write_registers(max2871_driver_t* const drv);
|
||||||
|
static void delay_ms(int ms);
|
||||||
|
|
||||||
|
void max2871_setup(max2871_driver_t* const drv)
|
||||||
|
{
|
||||||
|
/* Configure GPIO pins. */
|
||||||
|
scu_pinmux(SCU_VCO_CE, SCU_GPIO_FAST);
|
||||||
|
scu_pinmux(SCU_VCO_SCLK, SCU_GPIO_FAST | SCU_CONF_FUNCTION4);
|
||||||
|
/* Only used for the debug pin config: scu_pinmux(SCU_VCO_SCLK, SCU_GPIO_FAST); */
|
||||||
|
scu_pinmux(SCU_VCO_SDATA, SCU_GPIO_FAST);
|
||||||
|
scu_pinmux(SCU_VCO_LE, SCU_GPIO_FAST);
|
||||||
|
scu_pinmux(SCU_VCO_MUX, SCU_GPIO_FAST | SCU_CONF_FUNCTION4);
|
||||||
|
scu_pinmux(SCU_SYNT_RFOUT_EN, SCU_GPIO_FAST);
|
||||||
|
|
||||||
|
/* Set GPIO pins as outputs. */
|
||||||
|
gpio_output(drv->gpio_vco_ce);
|
||||||
|
gpio_output(drv->gpio_vco_sclk);
|
||||||
|
gpio_output(drv->gpio_vco_sdata);
|
||||||
|
gpio_output(drv->gpio_vco_le);
|
||||||
|
gpio_output(drv->gpio_synt_rfout_en);
|
||||||
|
|
||||||
|
/* MUX is an input */
|
||||||
|
gpio_input(drv->gpio_vco_mux);
|
||||||
|
|
||||||
|
/* set to known state */
|
||||||
|
gpio_set(drv->gpio_vco_ce); /* active high */
|
||||||
|
gpio_clear(drv->gpio_vco_sclk);
|
||||||
|
gpio_clear(drv->gpio_vco_sdata);
|
||||||
|
gpio_set(drv->gpio_vco_le); /* active low */
|
||||||
|
gpio_set(drv->gpio_synt_rfout_en); /* active high */
|
||||||
|
|
||||||
|
max2871_regs_init();
|
||||||
|
int i;
|
||||||
|
for(i = 5; i >= 0; i--) {
|
||||||
|
max2871_spi_write(drv, i, max2871_get_register(i));
|
||||||
|
delay_ms(20);
|
||||||
|
}
|
||||||
|
|
||||||
|
max2871_set_INT(1);
|
||||||
|
max2871_set_N(4500);
|
||||||
|
max2871_set_FRAC(0);
|
||||||
|
max2871_set_CPL(0);
|
||||||
|
max2871_set_CPT(0);
|
||||||
|
max2871_set_P(1);
|
||||||
|
max2871_set_M(0);
|
||||||
|
max2871_set_LDS(0);
|
||||||
|
max2871_set_SDN(0);
|
||||||
|
max2871_set_MUX(0x0C); /* Register 6 readback */
|
||||||
|
max2871_set_DBR(0);
|
||||||
|
max2871_set_RDIV2(0);
|
||||||
|
max2871_set_R(1); /* 40 MHz f_PFD */
|
||||||
|
max2871_set_REG4DB(1);
|
||||||
|
max2871_set_CP(15); /* ?: CP charge pump current 0-15 */
|
||||||
|
max2871_set_LDF(1); /* INT-N */
|
||||||
|
max2871_set_LDP(0); /* ?: Lock-Detect Precision */
|
||||||
|
max2871_set_PDP(1);
|
||||||
|
max2871_set_SHDN(0);
|
||||||
|
max2871_set_TRI(0);
|
||||||
|
max2871_set_RST(0);
|
||||||
|
max2871_set_VCO(0);
|
||||||
|
max2871_set_VAS_SHDN(0);
|
||||||
|
max2871_set_VAS_TEMP(1);
|
||||||
|
max2871_set_CSM(0);
|
||||||
|
max2871_set_MUTEDEL(1);
|
||||||
|
max2871_set_CDM(0);
|
||||||
|
max2871_set_CDIV(0);
|
||||||
|
max2871_set_SDLDO(0);
|
||||||
|
max2871_set_SDDIV(0);
|
||||||
|
max2871_set_SDREF(0);
|
||||||
|
max2871_set_BS(20*40); /* For 40 MHz f_PFD */
|
||||||
|
max2871_set_FB(1); /* Do not put DIVA into the feedback loop */
|
||||||
|
max2871_set_DIVA(0);
|
||||||
|
max2871_set_SDVCO(0);
|
||||||
|
max2871_set_MTLD(1);
|
||||||
|
max2871_set_BDIV(0);
|
||||||
|
max2871_set_RFB_EN(0);
|
||||||
|
max2871_set_BPWR(0);
|
||||||
|
max2871_set_RFA_EN(0);
|
||||||
|
max2871_set_APWR(3);
|
||||||
|
max2871_set_SDPLL(0);
|
||||||
|
max2871_set_F01(1);
|
||||||
|
max2871_set_LD(1);
|
||||||
|
max2871_set_ADCS(0);
|
||||||
|
max2871_set_ADCM(0);
|
||||||
|
|
||||||
|
max2871_write_registers(drv);
|
||||||
|
|
||||||
|
max2871_set_frequency(drv, 3500);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void delay_ms(int ms)
|
||||||
|
{
|
||||||
|
uint32_t i;
|
||||||
|
while(ms--) {
|
||||||
|
for (i = 0; i < 20000; i++) {
|
||||||
|
__asm__("nop");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void serial_delay(void)
|
||||||
|
{
|
||||||
|
uint32_t i;
|
||||||
|
|
||||||
|
for (i = 0; i < 2; i++)
|
||||||
|
__asm__("nop");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* SPI register write
|
||||||
|
*
|
||||||
|
* Send 32 bits:
|
||||||
|
* First 29 bits are data
|
||||||
|
* Last 3 bits are register number */
|
||||||
|
static void max2871_spi_write(max2871_driver_t* const drv, uint8_t r, uint32_t v) {
|
||||||
|
#if DEBUG
|
||||||
|
LOG("0x%04x -> reg%d\n", v, r);
|
||||||
|
#else
|
||||||
|
|
||||||
|
uint32_t bits = 32;
|
||||||
|
uint32_t msb = 1 << (bits -1);
|
||||||
|
uint32_t data = v | r;
|
||||||
|
|
||||||
|
/* make sure everything is starting in the correct state */
|
||||||
|
gpio_set(drv->gpio_vco_le);
|
||||||
|
gpio_clear(drv->gpio_vco_sclk);
|
||||||
|
gpio_clear(drv->gpio_vco_sdata);
|
||||||
|
|
||||||
|
/* start transaction by bringing LE low */
|
||||||
|
gpio_clear(drv->gpio_vco_le);
|
||||||
|
|
||||||
|
while (bits--) {
|
||||||
|
if (data & msb)
|
||||||
|
gpio_set(drv->gpio_vco_sdata);
|
||||||
|
else
|
||||||
|
gpio_clear(drv->gpio_vco_sdata);
|
||||||
|
data <<= 1;
|
||||||
|
|
||||||
|
serial_delay();
|
||||||
|
gpio_set(drv->gpio_vco_sclk);
|
||||||
|
|
||||||
|
serial_delay();
|
||||||
|
gpio_clear(drv->gpio_vco_sclk);
|
||||||
|
}
|
||||||
|
|
||||||
|
gpio_set(drv->gpio_vco_le);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
static uint32_t max2871_spi_read(max2871_driver_t* const drv)
|
||||||
|
{
|
||||||
|
uint32_t bits = 32;
|
||||||
|
uint32_t data = 0;
|
||||||
|
|
||||||
|
max2871_spi_write(drv, 0x06, 0x0);
|
||||||
|
|
||||||
|
serial_delay();
|
||||||
|
gpio_set(drv->gpio_vco_sclk);
|
||||||
|
serial_delay();
|
||||||
|
gpio_clear(drv->gpio_vco_sclk);
|
||||||
|
serial_delay();
|
||||||
|
|
||||||
|
while (bits--) {
|
||||||
|
gpio_set(drv->gpio_vco_sclk);
|
||||||
|
serial_delay();
|
||||||
|
|
||||||
|
gpio_clear(drv->gpio_vco_sclk);
|
||||||
|
serial_delay();
|
||||||
|
|
||||||
|
data <<= 1;
|
||||||
|
data |= gpio_read(drv->gpio_vco_mux) ? 1 : 0;
|
||||||
|
}
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void max2871_write_registers(max2871_driver_t* const drv)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
for(i = 5; i >= 0; i--) {
|
||||||
|
max2871_spi_write(drv, i, max2871_get_register(i));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Set frequency (MHz). */
|
||||||
|
uint64_t max2871_set_frequency(max2871_driver_t* const drv, uint16_t mhz)
|
||||||
|
{
|
||||||
|
int n = mhz / 40;
|
||||||
|
int diva = 0;
|
||||||
|
|
||||||
|
while(n * 40 < 3000) {
|
||||||
|
n *= 2;
|
||||||
|
diva += 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
max2871_set_RFA_EN(0);
|
||||||
|
max2871_write_registers(drv);
|
||||||
|
|
||||||
|
max2871_set_N(n);
|
||||||
|
max2871_set_DIVA(diva);
|
||||||
|
max2871_write_registers(drv);
|
||||||
|
|
||||||
|
while(max2871_spi_read(drv) & MAX2871_VASA);
|
||||||
|
|
||||||
|
max2871_set_RFA_EN(1);
|
||||||
|
max2871_write_registers(drv);
|
||||||
|
|
||||||
|
return (mhz/40)*40 * 1000000;
|
||||||
|
}
|
||||||
|
|
||||||
|
void max2871_enable(max2871_driver_t* const drv)
|
||||||
|
{
|
||||||
|
gpio_set(drv->gpio_vco_ce);
|
||||||
|
}
|
||||||
|
void max2871_disable(max2871_driver_t* const drv)
|
||||||
|
{
|
||||||
|
gpio_clear(drv->gpio_vco_ce);
|
||||||
|
}
|
||||||
|
|
21
firmware/common/max2871.h
Normal file
21
firmware/common/max2871.h
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
#ifndef MAX2871_H
|
||||||
|
#define MAX2871_H
|
||||||
|
|
||||||
|
#include "gpio.h"
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
gpio_t gpio_vco_ce;
|
||||||
|
gpio_t gpio_vco_sclk;
|
||||||
|
gpio_t gpio_vco_sdata;
|
||||||
|
gpio_t gpio_vco_le;
|
||||||
|
gpio_t gpio_synt_rfout_en;
|
||||||
|
gpio_t gpio_vco_mux;
|
||||||
|
} max2871_driver_t;
|
||||||
|
|
||||||
|
extern void max2871_setup(max2871_driver_t* const drv);
|
||||||
|
extern uint64_t max2871_set_frequency(max2871_driver_t* const drv, uint16_t mhz);
|
||||||
|
extern void max2871_enable(max2871_driver_t* const drv);
|
||||||
|
extern void max2871_disable(max2871_driver_t* const drv);
|
||||||
|
#endif
|
299
firmware/common/max2871_regs.c
Normal file
299
firmware/common/max2871_regs.c
Normal file
@ -0,0 +1,299 @@
|
|||||||
|
#include "max2871_regs.h"
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
static uint32_t registers[6];
|
||||||
|
|
||||||
|
void max2871_regs_init(void)
|
||||||
|
{
|
||||||
|
registers[0] = 0x007D0000;
|
||||||
|
registers[1] = 0x2000FFF9;
|
||||||
|
registers[2] = 0x00004042;
|
||||||
|
registers[3] = 0x0000000B;
|
||||||
|
registers[4] = 0x6180B23C;
|
||||||
|
registers[5] = 0x00400005;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t max2871_get_register(int reg)
|
||||||
|
{
|
||||||
|
return registers[reg];
|
||||||
|
}
|
||||||
|
|
||||||
|
void max2871_set_INT(uint32_t v)
|
||||||
|
{
|
||||||
|
registers[0] &= ~(0x1 << 31);
|
||||||
|
registers[0] |= v << 31;
|
||||||
|
}
|
||||||
|
|
||||||
|
void max2871_set_N(uint32_t v)
|
||||||
|
{
|
||||||
|
registers[0] &= ~(0xFFFF << 15);
|
||||||
|
registers[0] |= v << 15;
|
||||||
|
}
|
||||||
|
|
||||||
|
void max2871_set_FRAC(uint32_t v)
|
||||||
|
{
|
||||||
|
registers[0] &= ~(0xFFF << 3);
|
||||||
|
registers[0] |= v << 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
void max2871_set_CPL(uint32_t v)
|
||||||
|
{
|
||||||
|
registers[1] &= ~(0x3 << 29);
|
||||||
|
registers[1] |= v << 29;
|
||||||
|
}
|
||||||
|
|
||||||
|
void max2871_set_CPT(uint32_t v)
|
||||||
|
{
|
||||||
|
registers[1] &= ~(0x3 << 27);
|
||||||
|
registers[1] |= v << 27;
|
||||||
|
}
|
||||||
|
|
||||||
|
void max2871_set_P(uint32_t v)
|
||||||
|
{
|
||||||
|
registers[1] &= ~(0xFFF << 15);
|
||||||
|
registers[1] |= v << 15;
|
||||||
|
}
|
||||||
|
|
||||||
|
void max2871_set_M(uint32_t v)
|
||||||
|
{
|
||||||
|
registers[1] &= ~(0xFFF << 3);
|
||||||
|
registers[1] |= v << 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
void max2871_set_LDS(uint32_t v)
|
||||||
|
{
|
||||||
|
registers[2] &= ~(0x1 << 31);
|
||||||
|
registers[2] |= v << 31;
|
||||||
|
}
|
||||||
|
|
||||||
|
void max2871_set_SDN(uint32_t v)
|
||||||
|
{
|
||||||
|
registers[2] &= ~(0x3 << 29);
|
||||||
|
registers[2] |= v << 29;
|
||||||
|
}
|
||||||
|
|
||||||
|
void max2871_set_MUX(uint32_t v)
|
||||||
|
{
|
||||||
|
registers[2] &= ~(0x7 << 26);
|
||||||
|
registers[5] &= ~(0x1 << 18);
|
||||||
|
registers[2] |= (v & 0x7) << 26;
|
||||||
|
registers[5] |= ((v & 0x8) >> 3) << 18;
|
||||||
|
}
|
||||||
|
|
||||||
|
void max2871_set_DBR(uint32_t v)
|
||||||
|
{
|
||||||
|
registers[2] &= ~(0x1 << 25);
|
||||||
|
registers[2] |= v << 25;
|
||||||
|
}
|
||||||
|
|
||||||
|
void max2871_set_RDIV2(uint32_t v)
|
||||||
|
{
|
||||||
|
registers[2] &= ~(0x1 << 24);
|
||||||
|
registers[2] |= v << 24;
|
||||||
|
}
|
||||||
|
|
||||||
|
void max2871_set_R(uint32_t v)
|
||||||
|
{
|
||||||
|
registers[2] &= ~(0x3FF << 14);
|
||||||
|
registers[2] |= v << 14;
|
||||||
|
}
|
||||||
|
|
||||||
|
void max2871_set_REG4DB(uint32_t v)
|
||||||
|
{
|
||||||
|
registers[2] &= ~(0x1 << 13);
|
||||||
|
registers[2] |= v << 13;
|
||||||
|
}
|
||||||
|
|
||||||
|
void max2871_set_CP(uint32_t v)
|
||||||
|
{
|
||||||
|
registers[2] &= ~(0xF << 9);
|
||||||
|
registers[2] |= v << 9;
|
||||||
|
}
|
||||||
|
|
||||||
|
void max2871_set_LDF(uint32_t v)
|
||||||
|
{
|
||||||
|
registers[2] &= ~(0x1 << 8);
|
||||||
|
registers[2] |= v << 8;
|
||||||
|
}
|
||||||
|
|
||||||
|
void max2871_set_LDP(uint32_t v)
|
||||||
|
{
|
||||||
|
registers[2] &= ~(0x1 << 7);
|
||||||
|
registers[2] |= v << 7;
|
||||||
|
}
|
||||||
|
|
||||||
|
void max2871_set_PDP(uint32_t v)
|
||||||
|
{
|
||||||
|
registers[2] &= ~(0x1 << 6);
|
||||||
|
registers[2] |= v << 6;
|
||||||
|
}
|
||||||
|
|
||||||
|
void max2871_set_SHDN(uint32_t v)
|
||||||
|
{
|
||||||
|
registers[2] &= ~(0x1 << 5);
|
||||||
|
registers[2] |= v << 5;
|
||||||
|
}
|
||||||
|
|
||||||
|
void max2871_set_TRI(uint32_t v)
|
||||||
|
{
|
||||||
|
registers[2] &= ~(0x1 << 4);
|
||||||
|
registers[2] |= v << 4;
|
||||||
|
}
|
||||||
|
|
||||||
|
void max2871_set_RST(uint32_t v)
|
||||||
|
{
|
||||||
|
registers[2] &= ~(0x1 << 3);
|
||||||
|
registers[2] |= v << 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
void max2871_set_VCO(uint32_t v)
|
||||||
|
{
|
||||||
|
registers[3] &= ~(0x3F << 26);
|
||||||
|
registers[3] |= v << 26;
|
||||||
|
}
|
||||||
|
|
||||||
|
void max2871_set_VAS_SHDN(uint32_t v)
|
||||||
|
{
|
||||||
|
registers[3] &= ~(0x1 << 25);
|
||||||
|
registers[3] |= v << 25;
|
||||||
|
}
|
||||||
|
|
||||||
|
void max2871_set_VAS_TEMP(uint32_t v)
|
||||||
|
{
|
||||||
|
registers[3] &= ~(0x1 << 24);
|
||||||
|
registers[3] |= v << 24;
|
||||||
|
}
|
||||||
|
|
||||||
|
void max2871_set_CSM(uint32_t v)
|
||||||
|
{
|
||||||
|
registers[3] &= ~(0x1 << 18);
|
||||||
|
registers[3] |= v << 18;
|
||||||
|
}
|
||||||
|
|
||||||
|
void max2871_set_MUTEDEL(uint32_t v)
|
||||||
|
{
|
||||||
|
registers[3] &= ~(0x1 << 17);
|
||||||
|
registers[3] |= v << 17;
|
||||||
|
}
|
||||||
|
|
||||||
|
void max2871_set_CDM(uint32_t v)
|
||||||
|
{
|
||||||
|
registers[3] &= ~(0x3 << 15);
|
||||||
|
registers[3] |= v << 15;
|
||||||
|
}
|
||||||
|
|
||||||
|
void max2871_set_CDIV(uint32_t v)
|
||||||
|
{
|
||||||
|
registers[3] &= ~(0xFFF << 3);
|
||||||
|
registers[3] |= v << 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
void max2871_set_SDLDO(uint32_t v)
|
||||||
|
{
|
||||||
|
registers[4] &= ~(0x1 << 28);
|
||||||
|
registers[4] |= v << 28;
|
||||||
|
}
|
||||||
|
|
||||||
|
void max2871_set_SDDIV(uint32_t v)
|
||||||
|
{
|
||||||
|
registers[4] &= ~(0x1 << 27);
|
||||||
|
registers[4] |= v << 27;
|
||||||
|
}
|
||||||
|
|
||||||
|
void max2871_set_SDREF(uint32_t v)
|
||||||
|
{
|
||||||
|
registers[4] &= ~(0x1 << 26);
|
||||||
|
registers[4] |= v << 26;
|
||||||
|
}
|
||||||
|
|
||||||
|
void max2871_set_BS(uint32_t v)
|
||||||
|
{
|
||||||
|
registers[4] &= ~(0x3 << 24);
|
||||||
|
registers[4] &= ~(0xFF << 12);
|
||||||
|
registers[4] |= ((v & 0x300) >> 8) << 24;
|
||||||
|
registers[4] |= (v & 0xFF) << 12;
|
||||||
|
}
|
||||||
|
|
||||||
|
void max2871_set_FB(uint32_t v)
|
||||||
|
{
|
||||||
|
registers[4] &= ~(0x1 << 23);
|
||||||
|
registers[4] |= v << 23;
|
||||||
|
}
|
||||||
|
|
||||||
|
void max2871_set_DIVA(uint32_t v)
|
||||||
|
{
|
||||||
|
registers[4] &= ~(0x7 << 20);
|
||||||
|
registers[4] |= v << 20;
|
||||||
|
}
|
||||||
|
|
||||||
|
void max2871_set_SDVCO(uint32_t v)
|
||||||
|
{
|
||||||
|
registers[4] &= ~(0x1 << 11);
|
||||||
|
registers[4] |= v << 11;
|
||||||
|
}
|
||||||
|
|
||||||
|
void max2871_set_MTLD(uint32_t v)
|
||||||
|
{
|
||||||
|
registers[4] &= ~(0x1 << 10);
|
||||||
|
registers[4] |= v << 10;
|
||||||
|
}
|
||||||
|
|
||||||
|
void max2871_set_BDIV(uint32_t v)
|
||||||
|
{
|
||||||
|
registers[4] &= ~(0x1 << 9);
|
||||||
|
registers[4] |= v << 9;
|
||||||
|
}
|
||||||
|
|
||||||
|
void max2871_set_RFB_EN(uint32_t v)
|
||||||
|
{
|
||||||
|
registers[4] &= ~(0x1 << 8);
|
||||||
|
registers[4] |= v << 8;
|
||||||
|
}
|
||||||
|
|
||||||
|
void max2871_set_BPWR(uint32_t v)
|
||||||
|
{
|
||||||
|
registers[4] &= ~(0x3 << 6);
|
||||||
|
registers[4] |= v << 6;
|
||||||
|
}
|
||||||
|
|
||||||
|
void max2871_set_RFA_EN(uint32_t v)
|
||||||
|
{
|
||||||
|
registers[4] &= ~(0x1 << 5);
|
||||||
|
registers[4] |= v << 5;
|
||||||
|
}
|
||||||
|
|
||||||
|
void max2871_set_APWR(uint32_t v)
|
||||||
|
{
|
||||||
|
registers[4] &= ~(0x3 << 3);
|
||||||
|
registers[4] |= v << 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
void max2871_set_SDPLL(uint32_t v)
|
||||||
|
{
|
||||||
|
registers[5] &= ~(0x1 << 25);
|
||||||
|
registers[5] |= v << 25;
|
||||||
|
}
|
||||||
|
|
||||||
|
void max2871_set_F01(uint32_t v)
|
||||||
|
{
|
||||||
|
registers[5] &= ~(0x1 << 24);
|
||||||
|
registers[5] |= v << 24;
|
||||||
|
}
|
||||||
|
|
||||||
|
void max2871_set_LD(uint32_t v)
|
||||||
|
{
|
||||||
|
registers[5] &= ~(0x3 << 22);
|
||||||
|
registers[5] |= v << 22;
|
||||||
|
}
|
||||||
|
|
||||||
|
void max2871_set_ADCS(uint32_t v)
|
||||||
|
{
|
||||||
|
registers[5] &= ~(0x1 << 6);
|
||||||
|
registers[5] |= v << 6;
|
||||||
|
}
|
||||||
|
|
||||||
|
void max2871_set_ADCM(uint32_t v)
|
||||||
|
{
|
||||||
|
registers[5] &= ~(0x7 << 3);
|
||||||
|
registers[5] |= v << 3;
|
||||||
|
}
|
56
firmware/common/max2871_regs.h
Normal file
56
firmware/common/max2871_regs.h
Normal file
@ -0,0 +1,56 @@
|
|||||||
|
#ifndef MAX2871_REGS_H
|
||||||
|
#define MAX2871_REGS_H
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
#define MAX2871_VASA (1 << 9)
|
||||||
|
|
||||||
|
void max2871_regs_init(void);
|
||||||
|
uint32_t max2871_get_register(int reg);
|
||||||
|
|
||||||
|
void max2871_set_INT(uint32_t v);
|
||||||
|
void max2871_set_N(uint32_t v);
|
||||||
|
void max2871_set_FRAC(uint32_t v);
|
||||||
|
void max2871_set_CPL(uint32_t v);
|
||||||
|
void max2871_set_CPT(uint32_t v);
|
||||||
|
void max2871_set_P(uint32_t v);
|
||||||
|
void max2871_set_M(uint32_t v);
|
||||||
|
void max2871_set_LDS(uint32_t v);
|
||||||
|
void max2871_set_SDN(uint32_t v);
|
||||||
|
void max2871_set_MUX(uint32_t v);
|
||||||
|
void max2871_set_DBR(uint32_t v);
|
||||||
|
void max2871_set_RDIV2(uint32_t v);
|
||||||
|
void max2871_set_R(uint32_t v);
|
||||||
|
void max2871_set_REG4DB(uint32_t v);
|
||||||
|
void max2871_set_CP(uint32_t v);
|
||||||
|
void max2871_set_LDF(uint32_t v);
|
||||||
|
void max2871_set_LDP(uint32_t v);
|
||||||
|
void max2871_set_PDP(uint32_t v);
|
||||||
|
void max2871_set_SHDN(uint32_t v);
|
||||||
|
void max2871_set_TRI(uint32_t v);
|
||||||
|
void max2871_set_RST(uint32_t v);
|
||||||
|
void max2871_set_VCO(uint32_t v);
|
||||||
|
void max2871_set_VAS_SHDN(uint32_t v);
|
||||||
|
void max2871_set_VAS_TEMP(uint32_t v);
|
||||||
|
void max2871_set_CSM(uint32_t v);
|
||||||
|
void max2871_set_MUTEDEL(uint32_t v);
|
||||||
|
void max2871_set_CDM(uint32_t v);
|
||||||
|
void max2871_set_CDIV(uint32_t v);
|
||||||
|
void max2871_set_SDLDO(uint32_t v);
|
||||||
|
void max2871_set_SDDIV(uint32_t v);
|
||||||
|
void max2871_set_SDREF(uint32_t v);
|
||||||
|
void max2871_set_BS(uint32_t v);
|
||||||
|
void max2871_set_FB(uint32_t v);
|
||||||
|
void max2871_set_DIVA(uint32_t v);
|
||||||
|
void max2871_set_SDVCO(uint32_t v);
|
||||||
|
void max2871_set_MTLD(uint32_t v);
|
||||||
|
void max2871_set_BDIV(uint32_t v);
|
||||||
|
void max2871_set_RFB_EN(uint32_t v);
|
||||||
|
void max2871_set_BPWR(uint32_t v);
|
||||||
|
void max2871_set_RFA_EN(uint32_t v);
|
||||||
|
void max2871_set_APWR(uint32_t v);
|
||||||
|
void max2871_set_SDPLL(uint32_t v);
|
||||||
|
void max2871_set_F01(uint32_t v);
|
||||||
|
void max2871_set_LD(uint32_t v);
|
||||||
|
void max2871_set_ADCS(uint32_t v);
|
||||||
|
void max2871_set_ADCM(uint32_t v);
|
||||||
|
#endif
|
144
firmware/common/mixer.c
Normal file
144
firmware/common/mixer.c
Normal file
@ -0,0 +1,144 @@
|
|||||||
|
#include "mixer.h"
|
||||||
|
#include "rffc5071.h"
|
||||||
|
#include "rffc5071_spi.h"
|
||||||
|
#include "max2871.h"
|
||||||
|
#include "gpio_lpc.h"
|
||||||
|
|
||||||
|
/* RFFC5071 GPIO serial interface PinMux */
|
||||||
|
#if (defined JAWBREAKER || defined HACKRF_ONE)
|
||||||
|
static struct gpio_t gpio_rffc5072_select = GPIO(2, 13);
|
||||||
|
static struct gpio_t gpio_rffc5072_clock = GPIO(5, 6);
|
||||||
|
static struct gpio_t gpio_rffc5072_data = GPIO(3, 3);
|
||||||
|
static struct gpio_t gpio_rffc5072_reset = GPIO(2, 14);
|
||||||
|
#endif
|
||||||
|
#ifdef RAD1O
|
||||||
|
static struct gpio_t gpio_vco_ce = GPIO(2, 13);
|
||||||
|
static struct gpio_t gpio_vco_sclk = GPIO(5, 6);
|
||||||
|
static struct gpio_t gpio_vco_sdata = GPIO(3, 3);
|
||||||
|
static struct gpio_t gpio_vco_le = GPIO(2, 14);
|
||||||
|
static struct gpio_t gpio_vco_mux = GPIO(5, 25);
|
||||||
|
static struct gpio_t gpio_synt_rfout_en = GPIO(3, 5);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if (defined JAWBREAKER || defined HACKRF_ONE)
|
||||||
|
const rffc5071_spi_config_t rffc5071_spi_config = {
|
||||||
|
.gpio_select = &gpio_rffc5072_select,
|
||||||
|
.gpio_clock = &gpio_rffc5072_clock,
|
||||||
|
.gpio_data = &gpio_rffc5072_data,
|
||||||
|
};
|
||||||
|
|
||||||
|
spi_bus_t spi_bus_rffc5071 = {
|
||||||
|
.config = &rffc5071_spi_config,
|
||||||
|
.start = rffc5071_spi_start,
|
||||||
|
.stop = rffc5071_spi_stop,
|
||||||
|
.transfer = rffc5071_spi_transfer,
|
||||||
|
.transfer_gather = rffc5071_spi_transfer_gather,
|
||||||
|
};
|
||||||
|
|
||||||
|
mixer_driver_t mixer = {
|
||||||
|
.bus = &spi_bus_rffc5071,
|
||||||
|
.gpio_reset = &gpio_rffc5072_reset,
|
||||||
|
};
|
||||||
|
#endif
|
||||||
|
#ifdef RAD1O
|
||||||
|
mixer_driver_t mixer = {
|
||||||
|
.gpio_vco_ce = &gpio_vco_ce,
|
||||||
|
.gpio_vco_sclk = &gpio_vco_sclk,
|
||||||
|
.gpio_vco_sdata = &gpio_vco_sdata,
|
||||||
|
.gpio_vco_le = &gpio_vco_le,
|
||||||
|
.gpio_synt_rfout_en = &gpio_synt_rfout_en,
|
||||||
|
.gpio_vco_mux = &gpio_vco_mux,
|
||||||
|
};
|
||||||
|
#endif
|
||||||
|
|
||||||
|
void mixer_bus_setup(mixer_driver_t* const mixer)
|
||||||
|
{
|
||||||
|
#if (defined JAWBREAKER || defined HACKRF_ONE)
|
||||||
|
(void) mixer;
|
||||||
|
spi_bus_start(&spi_bus_rffc5071, &rffc5071_spi_config);
|
||||||
|
#endif
|
||||||
|
#ifdef RAD1O
|
||||||
|
(void) mixer;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
void mixer_setup(mixer_driver_t* const mixer)
|
||||||
|
{
|
||||||
|
#if (defined JAWBREAKER || defined HACKRF_ONE)
|
||||||
|
rffc5071_setup(mixer);
|
||||||
|
#endif
|
||||||
|
#ifdef RAD1O
|
||||||
|
max2871_setup(mixer);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
uint64_t mixer_set_frequency(mixer_driver_t* const mixer, uint16_t mhz)
|
||||||
|
{
|
||||||
|
#if (defined JAWBREAKER || defined HACKRF_ONE)
|
||||||
|
return rffc5071_set_frequency(mixer, mhz);
|
||||||
|
#endif
|
||||||
|
#ifdef RAD1O
|
||||||
|
return max2871_set_frequency(mixer, mhz);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
void mixer_tx(mixer_driver_t* const mixer)
|
||||||
|
{
|
||||||
|
#if (defined JAWBREAKER || defined HACKRF_ONE)
|
||||||
|
rffc5071_tx(mixer);
|
||||||
|
#endif
|
||||||
|
#ifdef RAD1O
|
||||||
|
(void) mixer;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
void mixer_rx(mixer_driver_t* const mixer)
|
||||||
|
{
|
||||||
|
#if (defined JAWBREAKER || defined HACKRF_ONE)
|
||||||
|
rffc5071_rx(mixer);
|
||||||
|
#endif
|
||||||
|
#ifdef RAD1O
|
||||||
|
(void) mixer;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
void mixer_rxtx(mixer_driver_t* const mixer)
|
||||||
|
{
|
||||||
|
#if (defined JAWBREAKER || defined HACKRF_ONE)
|
||||||
|
rffc5071_rxtx(mixer);
|
||||||
|
#endif
|
||||||
|
#ifdef RAD1O
|
||||||
|
(void) mixer;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
void mixer_enable(mixer_driver_t* const mixer)
|
||||||
|
{
|
||||||
|
#if (defined JAWBREAKER || defined HACKRF_ONE)
|
||||||
|
rffc5071_enable(mixer);
|
||||||
|
#endif
|
||||||
|
#ifdef RAD1O
|
||||||
|
(void) mixer;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
void mixer_disable(mixer_driver_t* const mixer)
|
||||||
|
{
|
||||||
|
#if (defined JAWBREAKER || defined HACKRF_ONE)
|
||||||
|
rffc5071_disable(mixer);
|
||||||
|
#endif
|
||||||
|
#ifdef RAD1O
|
||||||
|
(void) mixer;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
void mixer_set_gpo(mixer_driver_t* const mixer, uint8_t gpo)
|
||||||
|
{
|
||||||
|
#if (defined JAWBREAKER || defined HACKRF_ONE)
|
||||||
|
rffc5071_set_gpo(mixer, gpo);
|
||||||
|
#endif
|
||||||
|
#ifdef RAD1O
|
||||||
|
(void) mixer;
|
||||||
|
(void) gpo;
|
||||||
|
#endif
|
||||||
|
}
|
52
firmware/common/mixer.h
Normal file
52
firmware/common/mixer.h
Normal file
@ -0,0 +1,52 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2012 Michael Ossmann
|
||||||
|
* Copyright 2014 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __MIXER_H
|
||||||
|
#define __MIXER_H
|
||||||
|
|
||||||
|
#if (defined JAWBREAKER || defined HACKRF_ONE)
|
||||||
|
#include "rffc5071.h"
|
||||||
|
typedef rffc5071_driver_t mixer_driver_t;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef RAD1O
|
||||||
|
#include "max2871.h"
|
||||||
|
typedef max2871_driver_t mixer_driver_t;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
extern void mixer_bus_setup(mixer_driver_t* const mixer);
|
||||||
|
extern void mixer_setup(mixer_driver_t* const mixer);
|
||||||
|
|
||||||
|
/* Set frequency (MHz). */
|
||||||
|
extern uint64_t mixer_set_frequency(mixer_driver_t* const mixer, uint16_t mhz);
|
||||||
|
|
||||||
|
/* Set up rx only, tx only, or full duplex. Chip should be disabled
|
||||||
|
* before _tx, _rx, or _rxtx are called. */
|
||||||
|
extern void mixer_tx(mixer_driver_t* const mixer);
|
||||||
|
extern void mixer_rx(mixer_driver_t* const mixer);
|
||||||
|
extern void mixer_rxtx(mixer_driver_t* const mixer);
|
||||||
|
extern void mixer_enable(mixer_driver_t* const mixer);
|
||||||
|
extern void mixer_disable(mixer_driver_t* const mixer);
|
||||||
|
extern void mixer_set_gpo(mixer_driver_t* const drv, uint8_t gpo);
|
||||||
|
|
||||||
|
#endif // __MIXER_H
|
@ -26,12 +26,14 @@
|
|||||||
|
|
||||||
#include <hackrf_core.h>
|
#include <hackrf_core.h>
|
||||||
|
|
||||||
#include <rffc5071.h>
|
#include "hackrf-ui.h"
|
||||||
|
|
||||||
|
#include <mixer.h>
|
||||||
#include <max2837.h>
|
#include <max2837.h>
|
||||||
#include <max5864.h>
|
#include <max5864.h>
|
||||||
#include <sgpio.h>
|
#include <sgpio.h>
|
||||||
|
|
||||||
#if (defined JAWBREAKER || defined HACKRF_ONE)
|
#if (defined JAWBREAKER || defined HACKRF_ONE || defined RAD1O)
|
||||||
/*
|
/*
|
||||||
* RF switches on Jawbreaker are controlled by General Purpose Outputs (GPO) on
|
* RF switches on Jawbreaker are controlled by General Purpose Outputs (GPO) on
|
||||||
* the RFFC5072.
|
* the RFFC5072.
|
||||||
@ -40,6 +42,9 @@
|
|||||||
* SWITCHCTRL_NO_TX_AMP_PWR and SWITCHCTRL_NO_RX_AMP_PWR are not normally used
|
* SWITCHCTRL_NO_TX_AMP_PWR and SWITCHCTRL_NO_RX_AMP_PWR are not normally used
|
||||||
* on HackRF One as the amplifier power is instead controlled only by
|
* on HackRF One as the amplifier power is instead controlled only by
|
||||||
* SWITCHCTRL_AMP_BYPASS.
|
* SWITCHCTRL_AMP_BYPASS.
|
||||||
|
*
|
||||||
|
* The rad1o also uses GPIO pins to control the different switches. The amplifiers
|
||||||
|
* are also connected to the LPC.
|
||||||
*/
|
*/
|
||||||
#define SWITCHCTRL_NO_TX_AMP_PWR (1 << 0) /* GPO1 turn off TX amp power */
|
#define SWITCHCTRL_NO_TX_AMP_PWR (1 << 0) /* GPO1 turn off TX amp power */
|
||||||
#define SWITCHCTRL_AMP_BYPASS (1 << 1) /* GPO2 bypass amp section */
|
#define SWITCHCTRL_AMP_BYPASS (1 << 1) /* GPO2 bypass amp section */
|
||||||
@ -148,9 +153,73 @@ static void switchctrl_set_hackrf_one(rf_path_t* const rf_path, uint8_t ctrl) {
|
|||||||
gpio_set(rf_path->gpio_no_rx_amp_pwr);
|
gpio_set(rf_path->gpio_no_rx_amp_pwr);
|
||||||
|
|
||||||
if (ctrl & SWITCHCTRL_ANT_PWR) {
|
if (ctrl & SWITCHCTRL_ANT_PWR) {
|
||||||
rffc5071_set_gpo(&rffc5072, 0x00); /* turn on antenna power by clearing GPO1 */
|
mixer_set_gpo(&mixer, 0x00); /* turn on antenna power by clearing GPO1 */
|
||||||
} else {
|
} else {
|
||||||
rffc5071_set_gpo(&rffc5072, 0x01); /* turn off antenna power by setting GPO1 */
|
mixer_set_gpo(&mixer, 0x01); /* turn off antenna power by setting GPO1 */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef RAD1O
|
||||||
|
static void switchctrl_set_rad1o(rf_path_t* const rf_path, uint8_t ctrl) {
|
||||||
|
if (ctrl & SWITCHCTRL_TX) {
|
||||||
|
gpio_set(rf_path->gpio_tx_rx_n);
|
||||||
|
gpio_clear(rf_path->gpio_tx_rx);
|
||||||
|
} else {
|
||||||
|
gpio_clear(rf_path->gpio_tx_rx_n);
|
||||||
|
gpio_set(rf_path->gpio_tx_rx);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ctrl & SWITCHCTRL_MIX_BYPASS) {
|
||||||
|
gpio_clear(rf_path->gpio_by_mix);
|
||||||
|
gpio_set(rf_path->gpio_by_mix_n);
|
||||||
|
gpio_clear(rf_path->gpio_mixer_en);
|
||||||
|
} else {
|
||||||
|
gpio_set(rf_path->gpio_by_mix);
|
||||||
|
gpio_clear(rf_path->gpio_by_mix_n);
|
||||||
|
gpio_set(rf_path->gpio_mixer_en);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ctrl & SWITCHCTRL_HP) {
|
||||||
|
gpio_set(rf_path->gpio_low_high_filt);
|
||||||
|
gpio_clear(rf_path->gpio_low_high_filt_n);
|
||||||
|
} else {
|
||||||
|
gpio_clear(rf_path->gpio_low_high_filt);
|
||||||
|
gpio_set(rf_path->gpio_low_high_filt_n);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ctrl & SWITCHCTRL_AMP_BYPASS) {
|
||||||
|
gpio_clear(rf_path->gpio_by_amp);
|
||||||
|
gpio_set(rf_path->gpio_by_amp_n);
|
||||||
|
|
||||||
|
gpio_clear(rf_path->gpio_tx_amp);
|
||||||
|
gpio_clear(rf_path->gpio_rx_lna);
|
||||||
|
|
||||||
|
} else if (ctrl & SWITCHCTRL_TX) {
|
||||||
|
gpio_set(rf_path->gpio_by_amp);
|
||||||
|
gpio_clear(rf_path->gpio_by_amp_n);
|
||||||
|
|
||||||
|
gpio_set(rf_path->gpio_tx_amp);
|
||||||
|
gpio_clear(rf_path->gpio_rx_lna);
|
||||||
|
|
||||||
|
} else {
|
||||||
|
gpio_set(rf_path->gpio_by_amp);
|
||||||
|
gpio_clear(rf_path->gpio_by_amp_n);
|
||||||
|
|
||||||
|
gpio_clear(rf_path->gpio_tx_amp);
|
||||||
|
gpio_set(rf_path->gpio_rx_lna);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* These normally shouldn't be set post-Jawbreaker, but they can be
|
||||||
|
* used to explicitly turn off power to the amplifiers while AMP_BYPASS
|
||||||
|
* is unset:
|
||||||
|
*/
|
||||||
|
if (ctrl & SWITCHCTRL_NO_TX_AMP_PWR) {
|
||||||
|
gpio_clear(rf_path->gpio_tx_amp);
|
||||||
|
}
|
||||||
|
if (ctrl & SWITCHCTRL_NO_RX_AMP_PWR) {
|
||||||
|
gpio_clear(rf_path->gpio_rx_lna);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@ -158,9 +227,11 @@ static void switchctrl_set_hackrf_one(rf_path_t* const rf_path, uint8_t ctrl) {
|
|||||||
static void switchctrl_set(rf_path_t* const rf_path, const uint8_t gpo) {
|
static void switchctrl_set(rf_path_t* const rf_path, const uint8_t gpo) {
|
||||||
#ifdef JAWBREAKER
|
#ifdef JAWBREAKER
|
||||||
(void) rf_path; /* silence unused param warning */
|
(void) rf_path; /* silence unused param warning */
|
||||||
rffc5071_set_gpo(&rffc5072, gpo);
|
mixer_set_gpo(&mixer, gpo);
|
||||||
#elif HACKRF_ONE
|
#elif HACKRF_ONE
|
||||||
switchctrl_set_hackrf_one(rf_path, gpo);
|
switchctrl_set_hackrf_one(rf_path, gpo);
|
||||||
|
#elif RAD1O
|
||||||
|
switchctrl_set_rad1o(rf_path, gpo);
|
||||||
#else
|
#else
|
||||||
(void)gpo;
|
(void)gpo;
|
||||||
#endif
|
#endif
|
||||||
@ -201,6 +272,41 @@ void rf_path_pin_setup(rf_path_t* const rf_path) {
|
|||||||
gpio_output(rf_path->gpio_mix_bypass);
|
gpio_output(rf_path->gpio_mix_bypass);
|
||||||
gpio_output(rf_path->gpio_rx);
|
gpio_output(rf_path->gpio_rx);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Safe (initial) switch settings turn off both amplifiers and antenna port
|
||||||
|
* power and enable both amp bypass and mixer bypass.
|
||||||
|
*/
|
||||||
|
switchctrl_set(rf_path, SWITCHCTRL_AMP_BYPASS | SWITCHCTRL_MIX_BYPASS);
|
||||||
|
#elif RAD1O
|
||||||
|
/* Configure RF switch control signals */
|
||||||
|
scu_pinmux(SCU_BY_AMP, SCU_GPIO_FAST | SCU_CONF_FUNCTION0);
|
||||||
|
scu_pinmux(SCU_BY_AMP_N, SCU_GPIO_FAST | SCU_CONF_FUNCTION4);
|
||||||
|
scu_pinmux(SCU_TX_RX, SCU_GPIO_FAST | SCU_CONF_FUNCTION0);
|
||||||
|
scu_pinmux(SCU_TX_RX_N, SCU_GPIO_FAST | SCU_CONF_FUNCTION0);
|
||||||
|
scu_pinmux(SCU_BY_MIX, SCU_GPIO_FAST | SCU_CONF_FUNCTION0);
|
||||||
|
scu_pinmux(SCU_BY_MIX_N, SCU_GPIO_FAST | SCU_CONF_FUNCTION0);
|
||||||
|
scu_pinmux(SCU_LOW_HIGH_FILT, SCU_GPIO_FAST | SCU_CONF_FUNCTION0);
|
||||||
|
scu_pinmux(SCU_LOW_HIGH_FILT_N,SCU_GPIO_FAST | SCU_CONF_FUNCTION0);
|
||||||
|
scu_pinmux(SCU_TX_AMP, SCU_GPIO_FAST | SCU_CONF_FUNCTION0);
|
||||||
|
scu_pinmux(SCU_RX_LNA, SCU_GPIO_FAST | SCU_CONF_FUNCTION4);
|
||||||
|
scu_pinmux(SCU_MIXER_EN, SCU_GPIO_FAST | SCU_CONF_FUNCTION4);
|
||||||
|
|
||||||
|
/* Configure RF power supply (VAA) switch */
|
||||||
|
scu_pinmux(SCU_VAA_ENABLE, SCU_GPIO_FAST | SCU_CONF_FUNCTION0);
|
||||||
|
|
||||||
|
/* Configure RF switch control signals as outputs */
|
||||||
|
gpio_output(rf_path->gpio_tx_rx_n);
|
||||||
|
gpio_output(rf_path->gpio_tx_rx);
|
||||||
|
gpio_output(rf_path->gpio_by_mix);
|
||||||
|
gpio_output(rf_path->gpio_by_mix_n);
|
||||||
|
gpio_output(rf_path->gpio_by_amp);
|
||||||
|
gpio_output(rf_path->gpio_by_amp_n);
|
||||||
|
gpio_output(rf_path->gpio_mixer_en);
|
||||||
|
gpio_output(rf_path->gpio_low_high_filt);
|
||||||
|
gpio_output(rf_path->gpio_low_high_filt_n);
|
||||||
|
gpio_output(rf_path->gpio_tx_amp);
|
||||||
|
gpio_output(rf_path->gpio_rx_lna);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Safe (initial) switch settings turn off both amplifiers and antenna port
|
* Safe (initial) switch settings turn off both amplifiers and antenna port
|
||||||
* power and enable both amp bypass and mixer bypass.
|
* power and enable both amp bypass and mixer bypass.
|
||||||
@ -220,7 +326,7 @@ void rf_path_init(rf_path_t* const rf_path) {
|
|||||||
max2837_setup(&max2837);
|
max2837_setup(&max2837);
|
||||||
max2837_start(&max2837);
|
max2837_start(&max2837);
|
||||||
|
|
||||||
rffc5071_setup(&rffc5072);
|
mixer_setup(&mixer);
|
||||||
switchctrl_set(rf_path, switchctrl);
|
switchctrl_set(rf_path, switchctrl);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -234,11 +340,11 @@ void rf_path_set_direction(rf_path_t* const rf_path, const rf_path_direction_t d
|
|||||||
/* TX amplifier is in path, be sure to enable TX amplifier. */
|
/* TX amplifier is in path, be sure to enable TX amplifier. */
|
||||||
rf_path->switchctrl &= ~SWITCHCTRL_NO_TX_AMP_PWR;
|
rf_path->switchctrl &= ~SWITCHCTRL_NO_TX_AMP_PWR;
|
||||||
}
|
}
|
||||||
rffc5071_tx(&rffc5072);
|
mixer_tx(&mixer);
|
||||||
if( rf_path->switchctrl & SWITCHCTRL_MIX_BYPASS ) {
|
if( rf_path->switchctrl & SWITCHCTRL_MIX_BYPASS ) {
|
||||||
rffc5071_disable(&rffc5072);
|
mixer_disable(&mixer);
|
||||||
} else {
|
} else {
|
||||||
rffc5071_enable(&rffc5072);
|
mixer_enable(&mixer);
|
||||||
}
|
}
|
||||||
ssp1_set_mode_max5864();
|
ssp1_set_mode_max5864();
|
||||||
max5864_tx(&max5864);
|
max5864_tx(&max5864);
|
||||||
@ -253,11 +359,11 @@ void rf_path_set_direction(rf_path_t* const rf_path, const rf_path_direction_t d
|
|||||||
/* RX amplifier is in path, be sure to enable RX amplifier. */
|
/* RX amplifier is in path, be sure to enable RX amplifier. */
|
||||||
rf_path->switchctrl &= ~SWITCHCTRL_NO_RX_AMP_PWR;
|
rf_path->switchctrl &= ~SWITCHCTRL_NO_RX_AMP_PWR;
|
||||||
}
|
}
|
||||||
rffc5071_rx(&rffc5072);
|
mixer_rx(&mixer);
|
||||||
if( rf_path->switchctrl & SWITCHCTRL_MIX_BYPASS ) {
|
if( rf_path->switchctrl & SWITCHCTRL_MIX_BYPASS ) {
|
||||||
rffc5071_disable(&rffc5072);
|
mixer_disable(&mixer);
|
||||||
} else {
|
} else {
|
||||||
rffc5071_enable(&rffc5072);
|
mixer_enable(&mixer);
|
||||||
}
|
}
|
||||||
ssp1_set_mode_max5864();
|
ssp1_set_mode_max5864();
|
||||||
max5864_rx(&max5864);
|
max5864_rx(&max5864);
|
||||||
@ -274,7 +380,7 @@ void rf_path_set_direction(rf_path_t* const rf_path, const rf_path_direction_t d
|
|||||||
rf_path_set_lna(rf_path, 0);
|
rf_path_set_lna(rf_path, 0);
|
||||||
/* Set RF path to receive direction when "off" */
|
/* Set RF path to receive direction when "off" */
|
||||||
rf_path->switchctrl &= ~SWITCHCTRL_TX;
|
rf_path->switchctrl &= ~SWITCHCTRL_TX;
|
||||||
rffc5071_disable(&rffc5072);
|
mixer_disable(&mixer);
|
||||||
ssp1_set_mode_max5864();
|
ssp1_set_mode_max5864();
|
||||||
max5864_standby(&max5864);
|
max5864_standby(&max5864);
|
||||||
ssp1_set_mode_max2837();
|
ssp1_set_mode_max2837();
|
||||||
@ -284,6 +390,8 @@ void rf_path_set_direction(rf_path_t* const rf_path, const rf_path_direction_t d
|
|||||||
}
|
}
|
||||||
|
|
||||||
switchctrl_set(rf_path, rf_path->switchctrl);
|
switchctrl_set(rf_path, rf_path->switchctrl);
|
||||||
|
|
||||||
|
hackrf_ui_setDirection(direction);
|
||||||
}
|
}
|
||||||
|
|
||||||
void rf_path_set_filter(rf_path_t* const rf_path, const rf_path_filter_t filter) {
|
void rf_path_set_filter(rf_path_t* const rf_path, const rf_path_filter_t filter) {
|
||||||
@ -291,18 +399,18 @@ void rf_path_set_filter(rf_path_t* const rf_path, const rf_path_filter_t filter)
|
|||||||
default:
|
default:
|
||||||
case RF_PATH_FILTER_BYPASS:
|
case RF_PATH_FILTER_BYPASS:
|
||||||
rf_path->switchctrl |= SWITCHCTRL_MIX_BYPASS;
|
rf_path->switchctrl |= SWITCHCTRL_MIX_BYPASS;
|
||||||
rffc5071_disable(&rffc5072);
|
mixer_disable(&mixer);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case RF_PATH_FILTER_LOW_PASS:
|
case RF_PATH_FILTER_LOW_PASS:
|
||||||
rf_path->switchctrl &= ~(SWITCHCTRL_HP | SWITCHCTRL_MIX_BYPASS);
|
rf_path->switchctrl &= ~(SWITCHCTRL_HP | SWITCHCTRL_MIX_BYPASS);
|
||||||
rffc5071_enable(&rffc5072);
|
mixer_enable(&mixer);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case RF_PATH_FILTER_HIGH_PASS:
|
case RF_PATH_FILTER_HIGH_PASS:
|
||||||
rf_path->switchctrl &= ~SWITCHCTRL_MIX_BYPASS;
|
rf_path->switchctrl &= ~SWITCHCTRL_MIX_BYPASS;
|
||||||
rf_path->switchctrl |= SWITCHCTRL_HP;
|
rf_path->switchctrl |= SWITCHCTRL_HP;
|
||||||
rffc5071_enable(&rffc5072);
|
mixer_enable(&mixer);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -326,6 +434,8 @@ void rf_path_set_lna(rf_path_t* const rf_path, const uint_fast8_t enable) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
switchctrl_set(rf_path, rf_path->switchctrl);
|
switchctrl_set(rf_path, rf_path->switchctrl);
|
||||||
|
|
||||||
|
hackrf_ui_setLNAPower(enable);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* antenna port power control */
|
/* antenna port power control */
|
||||||
|
@ -56,6 +56,19 @@ typedef struct rf_path_t {
|
|||||||
gpio_t gpio_rx_amp;
|
gpio_t gpio_rx_amp;
|
||||||
gpio_t gpio_no_rx_amp_pwr;
|
gpio_t gpio_no_rx_amp_pwr;
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef RAD1O
|
||||||
|
gpio_t gpio_tx_rx_n;
|
||||||
|
gpio_t gpio_tx_rx;
|
||||||
|
gpio_t gpio_by_mix;
|
||||||
|
gpio_t gpio_by_mix_n;
|
||||||
|
gpio_t gpio_by_amp;
|
||||||
|
gpio_t gpio_by_amp_n;
|
||||||
|
gpio_t gpio_mixer_en;
|
||||||
|
gpio_t gpio_low_high_filt;
|
||||||
|
gpio_t gpio_low_high_filt_n;
|
||||||
|
gpio_t gpio_tx_amp;
|
||||||
|
gpio_t gpio_rx_lna;
|
||||||
|
#endif
|
||||||
} rf_path_t;
|
} rf_path_t;
|
||||||
|
|
||||||
void rf_path_pin_setup(rf_path_t* const rf_path);
|
void rf_path_pin_setup(rf_path_t* const rf_path);
|
||||||
|
@ -27,6 +27,10 @@
|
|||||||
|
|
||||||
#include <sgpio.h>
|
#include <sgpio.h>
|
||||||
|
|
||||||
|
#ifdef RAD1O
|
||||||
|
static void update_q_invert(sgpio_config_t* const config);
|
||||||
|
#endif
|
||||||
|
|
||||||
void sgpio_configure_pin_functions(sgpio_config_t* const config) {
|
void sgpio_configure_pin_functions(sgpio_config_t* const config) {
|
||||||
scu_pinmux(SCU_PINMUX_SGPIO0, SCU_GPIO_FAST | SCU_CONF_FUNCTION3);
|
scu_pinmux(SCU_PINMUX_SGPIO0, SCU_GPIO_FAST | SCU_CONF_FUNCTION3);
|
||||||
scu_pinmux(SCU_PINMUX_SGPIO1, SCU_GPIO_FAST | SCU_CONF_FUNCTION3);
|
scu_pinmux(SCU_PINMUX_SGPIO1, SCU_GPIO_FAST | SCU_CONF_FUNCTION3);
|
||||||
@ -88,6 +92,12 @@ void sgpio_configure(
|
|||||||
| (1L << 10) // disable codec data stream during configuration (Output SGPIO10 High)
|
| (1L << 10) // disable codec data stream during configuration (Output SGPIO10 High)
|
||||||
;
|
;
|
||||||
|
|
||||||
|
#ifdef RAD1O
|
||||||
|
/* The data direction might have changed. Check if we need to
|
||||||
|
* adjust the q inversion. */
|
||||||
|
update_q_invert(config);
|
||||||
|
#endif
|
||||||
|
|
||||||
// Enable SGPIO pin outputs.
|
// Enable SGPIO pin outputs.
|
||||||
const uint_fast16_t sgpio_gpio_data_direction =
|
const uint_fast16_t sgpio_gpio_data_direction =
|
||||||
(direction == SGPIO_DIRECTION_TX)
|
(direction == SGPIO_DIRECTION_TX)
|
||||||
@ -264,6 +274,48 @@ bool sgpio_cpld_stream_rx_set_decimation(sgpio_config_t* const config, const uin
|
|||||||
return (skip_n < 8);
|
return (skip_n < 8);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef RAD1O
|
||||||
|
/* The rad1o hardware has a bug which makes it
|
||||||
|
* necessary to also switch between the two options based
|
||||||
|
* on TX or RX mode.
|
||||||
|
*
|
||||||
|
* We use the state of the pin to determine which way we
|
||||||
|
* have to go.
|
||||||
|
*
|
||||||
|
* As TX/RX can change without sgpio_cpld_stream_rx_set_q_invert
|
||||||
|
* being called, we store a local copy of its parameter. */
|
||||||
|
static bool sgpio_invert = false;
|
||||||
|
|
||||||
|
/* Called when TX/RX changes od sgpio_cpld_stream_rx_set_q_invert
|
||||||
|
* gets called. */
|
||||||
|
static void update_q_invert(sgpio_config_t* const config) {
|
||||||
|
/* 1=Output SGPIO11 High(TX mode), 0=Output SGPIO11 Low(RX mode) */
|
||||||
|
bool tx_mode = (SGPIO_GPIO_OUTREG & (1 << 11)) > 0;
|
||||||
|
|
||||||
|
/* 0.13: P1_18 */
|
||||||
|
if( !sgpio_invert & !tx_mode) {
|
||||||
|
gpio_write(config->gpio_rx_q_invert, 1);
|
||||||
|
} else if( !sgpio_invert & tx_mode) {
|
||||||
|
gpio_write(config->gpio_rx_q_invert, 0);
|
||||||
|
} else if( sgpio_invert & !tx_mode) {
|
||||||
|
gpio_write(config->gpio_rx_q_invert, 0);
|
||||||
|
} else if( sgpio_invert & tx_mode) {
|
||||||
|
gpio_write(config->gpio_rx_q_invert, 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void sgpio_cpld_stream_rx_set_q_invert(sgpio_config_t* const config, const uint_fast8_t invert) {
|
||||||
|
if( invert ) {
|
||||||
|
sgpio_invert = true;
|
||||||
|
} else {
|
||||||
|
sgpio_invert = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
update_q_invert(config);
|
||||||
|
}
|
||||||
|
|
||||||
|
#else
|
||||||
void sgpio_cpld_stream_rx_set_q_invert(sgpio_config_t* const config, const uint_fast8_t invert) {
|
void sgpio_cpld_stream_rx_set_q_invert(sgpio_config_t* const config, const uint_fast8_t invert) {
|
||||||
gpio_write(config->gpio_rx_q_invert, invert);
|
gpio_write(config->gpio_rx_q_invert, invert);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
@ -243,10 +243,42 @@ void si5351c_configure_clock_control(si5351c_driver_t* const drv, const enum pll
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Enable CLK outputs 0, 1, 2, 3, 4, 5, 7 only. */
|
#ifdef RAD1O
|
||||||
|
void si5351c_configure_clock_control(si5351c_driver_t* const drv, const enum pll_sources source)
|
||||||
|
{
|
||||||
|
(void) source;
|
||||||
|
uint8_t pll;
|
||||||
|
|
||||||
|
/* PLLA on XTAL */
|
||||||
|
pll = SI5351C_CLK_PLL_SRC_A;
|
||||||
|
|
||||||
|
/* Clock to CPU is deactivated as it is not used and creates noise */
|
||||||
|
/* External clock output is deactivated as it is not used and creates noise */
|
||||||
|
uint8_t data[] = {16
|
||||||
|
,SI5351C_CLK_FRAC_MODE | SI5351C_CLK_PLL_SRC(pll) | SI5351C_CLK_SRC(SI5351C_CLK_SRC_MULTISYNTH_SELF) | SI5351C_CLK_IDRV(SI5351C_CLK_IDRV_2MA)
|
||||||
|
,SI5351C_CLK_INT_MODE | SI5351C_CLK_PLL_SRC(pll) | SI5351C_CLK_SRC(SI5351C_CLK_SRC_MULTISYNTH_0_4) | SI5351C_CLK_IDRV(SI5351C_CLK_IDRV_2MA)
|
||||||
|
,SI5351C_CLK_INT_MODE | SI5351C_CLK_PLL_SRC(pll) | SI5351C_CLK_SRC(SI5351C_CLK_SRC_MULTISYNTH_0_4) | SI5351C_CLK_IDRV(SI5351C_CLK_IDRV_2MA)
|
||||||
|
,SI5351C_CLK_POWERDOWN | SI5351C_CLK_INT_MODE /*not connected, but: plla int mode*/
|
||||||
|
,SI5351C_CLK_INT_MODE | SI5351C_CLK_PLL_SRC(pll) | SI5351C_CLK_SRC(SI5351C_CLK_SRC_MULTISYNTH_SELF) | SI5351C_CLK_IDRV(SI5351C_CLK_IDRV_6MA)
|
||||||
|
,SI5351C_CLK_INT_MODE | SI5351C_CLK_PLL_SRC(pll) | SI5351C_CLK_SRC(SI5351C_CLK_SRC_MULTISYNTH_SELF) | SI5351C_CLK_IDRV(SI5351C_CLK_IDRV_4MA)
|
||||||
|
,SI5351C_CLK_POWERDOWN | SI5351C_CLK_INT_MODE /*not connected, but: plla int mode*/
|
||||||
|
,SI5351C_CLK_POWERDOWN | SI5351C_CLK_INT_MODE /*not connected, but: plla int mode*/
|
||||||
|
};
|
||||||
|
si5351c_write(drv, data, sizeof(data));
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
void si5351c_enable_clock_outputs(si5351c_driver_t* const drv)
|
void si5351c_enable_clock_outputs(si5351c_driver_t* const drv)
|
||||||
{
|
{
|
||||||
|
#ifdef RAD1O
|
||||||
|
/* Enable CLK outputs 0, 1, 2, 4, 5 only. */
|
||||||
|
/* 7: Clock to CPU is deactivated as it is not used and creates noise */
|
||||||
|
/* 3: External clock output is deactivated as it is not used and creates noise */
|
||||||
|
uint8_t data[] = { 3, ~((1 << 0) | (1 << 1) | (1 << 2) | (1 << 4) | (1 << 5))};
|
||||||
|
#else
|
||||||
|
/* Enable CLK outputs 0, 1, 2, 3, 4, 5, 7 only. */
|
||||||
uint8_t data[] = { 3, 0x40 };
|
uint8_t data[] = { 3, 0x40 };
|
||||||
|
#endif
|
||||||
si5351c_write(drv, data, sizeof(data));
|
si5351c_write(drv, data, sizeof(data));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -22,8 +22,10 @@
|
|||||||
|
|
||||||
#include "tuning.h"
|
#include "tuning.h"
|
||||||
|
|
||||||
|
#include "hackrf-ui.h"
|
||||||
|
|
||||||
#include <hackrf_core.h>
|
#include <hackrf_core.h>
|
||||||
#include <rffc5071.h>
|
#include <mixer.h>
|
||||||
#include <max2837.h>
|
#include <max2837.h>
|
||||||
#include <sgpio.h>
|
#include <sgpio.h>
|
||||||
|
|
||||||
@ -54,9 +56,9 @@ uint64_t freq_cache = 100000000;
|
|||||||
bool set_freq(const uint64_t freq)
|
bool set_freq(const uint64_t freq)
|
||||||
{
|
{
|
||||||
bool success;
|
bool success;
|
||||||
uint32_t RFFC5071_freq_mhz;
|
uint32_t mixer_freq_mhz;
|
||||||
uint32_t MAX2837_freq_hz;
|
uint32_t MAX2837_freq_hz;
|
||||||
uint64_t real_RFFC5071_freq_hz;
|
uint64_t real_mixer_freq_hz;
|
||||||
|
|
||||||
const uint32_t freq_mhz = freq / 1000000;
|
const uint32_t freq_mhz = freq / 1000000;
|
||||||
const uint32_t freq_hz = freq % 1000000;
|
const uint32_t freq_hz = freq % 1000000;
|
||||||
@ -68,18 +70,22 @@ bool set_freq(const uint64_t freq)
|
|||||||
if(freq_mhz < MAX_LP_FREQ_MHZ)
|
if(freq_mhz < MAX_LP_FREQ_MHZ)
|
||||||
{
|
{
|
||||||
rf_path_set_filter(&rf_path, RF_PATH_FILTER_LOW_PASS);
|
rf_path_set_filter(&rf_path, RF_PATH_FILTER_LOW_PASS);
|
||||||
|
#ifdef RAD1O
|
||||||
|
max2837_freq_nominal_hz = 2300000000;
|
||||||
|
#else
|
||||||
/* IF is graduated from 2650 MHz to 2343 MHz */
|
/* IF is graduated from 2650 MHz to 2343 MHz */
|
||||||
max2837_freq_nominal_hz = 2650000000 - (freq / 7);
|
max2837_freq_nominal_hz = 2650000000 - (freq / 7);
|
||||||
RFFC5071_freq_mhz = (max2837_freq_nominal_hz / FREQ_ONE_MHZ) + freq_mhz;
|
#endif
|
||||||
|
mixer_freq_mhz = (max2837_freq_nominal_hz / FREQ_ONE_MHZ) + freq_mhz;
|
||||||
/* Set Freq and read real freq */
|
/* Set Freq and read real freq */
|
||||||
real_RFFC5071_freq_hz = rffc5071_set_frequency(&rffc5072, RFFC5071_freq_mhz);
|
real_mixer_freq_hz = mixer_set_frequency(&mixer, mixer_freq_mhz);
|
||||||
max2837_set_frequency(&max2837, real_RFFC5071_freq_hz - freq);
|
max2837_set_frequency(&max2837, real_mixer_freq_hz - freq);
|
||||||
sgpio_cpld_stream_rx_set_q_invert(&sgpio_config, 1);
|
sgpio_cpld_stream_rx_set_q_invert(&sgpio_config, 1);
|
||||||
}else if( (freq_mhz >= MIN_BYPASS_FREQ_MHZ) && (freq_mhz < MAX_BYPASS_FREQ_MHZ) )
|
}else if( (freq_mhz >= MIN_BYPASS_FREQ_MHZ) && (freq_mhz < MAX_BYPASS_FREQ_MHZ) )
|
||||||
{
|
{
|
||||||
rf_path_set_filter(&rf_path, RF_PATH_FILTER_BYPASS);
|
rf_path_set_filter(&rf_path, RF_PATH_FILTER_BYPASS);
|
||||||
MAX2837_freq_hz = (freq_mhz * FREQ_ONE_MHZ) + freq_hz;
|
MAX2837_freq_hz = (freq_mhz * FREQ_ONE_MHZ) + freq_hz;
|
||||||
/* RFFC5071_freq_mhz <= not used in Bypass mode */
|
/* mixer_freq_mhz <= not used in Bypass mode */
|
||||||
max2837_set_frequency(&max2837, MAX2837_freq_hz);
|
max2837_set_frequency(&max2837, MAX2837_freq_hz);
|
||||||
sgpio_cpld_stream_rx_set_q_invert(&sgpio_config, 0);
|
sgpio_cpld_stream_rx_set_q_invert(&sgpio_config, 0);
|
||||||
}else if( (freq_mhz >= MIN_HP_FREQ_MHZ) && (freq_mhz <= MAX_HP_FREQ_MHZ) )
|
}else if( (freq_mhz >= MIN_HP_FREQ_MHZ) && (freq_mhz <= MAX_HP_FREQ_MHZ) )
|
||||||
@ -95,10 +101,10 @@ bool set_freq(const uint64_t freq)
|
|||||||
max2837_freq_nominal_hz = 2500000000 + ((freq - 5100000000) / 9);
|
max2837_freq_nominal_hz = 2500000000 + ((freq - 5100000000) / 9);
|
||||||
}
|
}
|
||||||
rf_path_set_filter(&rf_path, RF_PATH_FILTER_HIGH_PASS);
|
rf_path_set_filter(&rf_path, RF_PATH_FILTER_HIGH_PASS);
|
||||||
RFFC5071_freq_mhz = freq_mhz - (max2837_freq_nominal_hz / FREQ_ONE_MHZ);
|
mixer_freq_mhz = freq_mhz - (max2837_freq_nominal_hz / FREQ_ONE_MHZ);
|
||||||
/* Set Freq and read real freq */
|
/* Set Freq and read real freq */
|
||||||
real_RFFC5071_freq_hz = rffc5071_set_frequency(&rffc5072, RFFC5071_freq_mhz);
|
real_mixer_freq_hz = mixer_set_frequency(&mixer, mixer_freq_mhz);
|
||||||
max2837_set_frequency(&max2837, freq - real_RFFC5071_freq_hz);
|
max2837_set_frequency(&max2837, freq - real_mixer_freq_hz);
|
||||||
sgpio_cpld_stream_rx_set_q_invert(&sgpio_config, 0);
|
sgpio_cpld_stream_rx_set_q_invert(&sgpio_config, 0);
|
||||||
}else
|
}else
|
||||||
{
|
{
|
||||||
@ -108,6 +114,7 @@ bool set_freq(const uint64_t freq)
|
|||||||
max2837_set_mode(&max2837, prior_max2837_mode);
|
max2837_set_mode(&max2837, prior_max2837_mode);
|
||||||
if( success ) {
|
if( success ) {
|
||||||
freq_cache = freq;
|
freq_cache = freq;
|
||||||
|
hackrf_ui_setFrequency(freq);
|
||||||
}
|
}
|
||||||
return success;
|
return success;
|
||||||
}
|
}
|
||||||
@ -137,7 +144,7 @@ bool set_freq_explicit(const uint64_t if_freq_hz, const uint64_t lo_freq_hz,
|
|||||||
sgpio_cpld_stream_rx_set_q_invert(&sgpio_config, 0);
|
sgpio_cpld_stream_rx_set_q_invert(&sgpio_config, 0);
|
||||||
}
|
}
|
||||||
if (path != RF_PATH_FILTER_BYPASS) {
|
if (path != RF_PATH_FILTER_BYPASS) {
|
||||||
(void)rffc5071_set_frequency(&rffc5072, lo_freq_hz / FREQ_ONE_MHZ);
|
(void)mixer_set_frequency(&mixer, lo_freq_hz / FREQ_ONE_MHZ);
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -72,7 +72,7 @@ void usb_peripheral_reset() {
|
|||||||
while( (RESET_ACTIVE_STATUS0 & RESET_CTRL0_USB0_RST) == 0 );
|
while( (RESET_ACTIVE_STATUS0 & RESET_CTRL0_USB0_RST) == 0 );
|
||||||
}
|
}
|
||||||
|
|
||||||
static void usb_phy_enable() {
|
void usb_phy_enable() {
|
||||||
CREG_CREG0 &= ~CREG_CREG0_USB0PHY;
|
CREG_CREG0 &= ~CREG_CREG0_USB0PHY;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -29,6 +29,7 @@
|
|||||||
#include "usb_type.h"
|
#include "usb_type.h"
|
||||||
|
|
||||||
void usb_peripheral_reset();
|
void usb_peripheral_reset();
|
||||||
|
void usb_phy_enable();
|
||||||
|
|
||||||
void usb_device_init(
|
void usb_device_init(
|
||||||
const uint_fast8_t device_ordinal,
|
const uint_fast8_t device_ordinal,
|
||||||
|
@ -61,11 +61,10 @@ void w25q80bv_setup(w25q80bv_driver_t* const drv)
|
|||||||
|
|
||||||
drv->target_init(drv);
|
drv->target_init(drv);
|
||||||
|
|
||||||
device_id = 0;
|
do {
|
||||||
while(device_id != W25Q80BV_DEVICE_ID_RES)
|
|
||||||
{
|
|
||||||
device_id = w25q80bv_get_device_id(drv);
|
device_id = w25q80bv_get_device_id(drv);
|
||||||
}
|
} while(device_id != W25Q80BV_DEVICE_ID_RES &&
|
||||||
|
device_id != W25Q16DV_DEVICE_ID_RES);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t w25q80bv_get_status(w25q80bv_driver_t* const drv)
|
uint8_t w25q80bv_get_status(w25q80bv_driver_t* const drv)
|
||||||
@ -117,11 +116,10 @@ void w25q80bv_chip_erase(w25q80bv_driver_t* const drv)
|
|||||||
{
|
{
|
||||||
uint8_t device_id;
|
uint8_t device_id;
|
||||||
|
|
||||||
device_id = 0;
|
do {
|
||||||
while(device_id != W25Q80BV_DEVICE_ID_RES)
|
|
||||||
{
|
|
||||||
device_id = w25q80bv_get_device_id(drv);
|
device_id = w25q80bv_get_device_id(drv);
|
||||||
}
|
} while(device_id != W25Q80BV_DEVICE_ID_RES &&
|
||||||
|
device_id != W25Q16DV_DEVICE_ID_RES);
|
||||||
|
|
||||||
w25q80bv_write_enable(drv);
|
w25q80bv_write_enable(drv);
|
||||||
w25q80bv_wait_while_busy(drv);
|
w25q80bv_wait_while_busy(drv);
|
||||||
@ -165,11 +163,10 @@ void w25q80bv_program(w25q80bv_driver_t* const drv, uint32_t addr, uint32_t len,
|
|||||||
uint16_t first_block_len;
|
uint16_t first_block_len;
|
||||||
uint8_t device_id;
|
uint8_t device_id;
|
||||||
|
|
||||||
device_id = 0;
|
do {
|
||||||
while(device_id != W25Q80BV_DEVICE_ID_RES)
|
|
||||||
{
|
|
||||||
device_id = w25q80bv_get_device_id(drv);
|
device_id = w25q80bv_get_device_id(drv);
|
||||||
}
|
} while(device_id != W25Q80BV_DEVICE_ID_RES &&
|
||||||
|
device_id != W25Q16DV_DEVICE_ID_RES);
|
||||||
|
|
||||||
/* do nothing if we would overflow the flash */
|
/* do nothing if we would overflow the flash */
|
||||||
if ((len > drv->num_bytes) || (addr > drv->num_bytes)
|
if ((len > drv->num_bytes) || (addr > drv->num_bytes)
|
||||||
|
@ -27,6 +27,8 @@
|
|||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
|
|
||||||
|
#define W25Q80BV_DEVICE_ID_RES 0x13 /* Expected device_id for W25Q80BV */
|
||||||
|
#define W25Q16DV_DEVICE_ID_RES 0x14 /* Expected device_id for W25Q16DV */
|
||||||
#include "spi_bus.h"
|
#include "spi_bus.h"
|
||||||
#include "gpio.h"
|
#include "gpio.h"
|
||||||
|
|
||||||
|
@ -104,10 +104,9 @@ macro(DeclareTargets)
|
|||||||
${PATH_HACKRF_FIRMWARE_COMMON}/max2837_target.c
|
${PATH_HACKRF_FIRMWARE_COMMON}/max2837_target.c
|
||||||
${PATH_HACKRF_FIRMWARE_COMMON}/max5864.c
|
${PATH_HACKRF_FIRMWARE_COMMON}/max5864.c
|
||||||
${PATH_HACKRF_FIRMWARE_COMMON}/max5864_target.c
|
${PATH_HACKRF_FIRMWARE_COMMON}/max5864_target.c
|
||||||
${PATH_HACKRF_FIRMWARE_COMMON}/rffc5071.c
|
${PATH_HACKRF_FIRMWARE_COMMON}/mixer.c
|
||||||
${PATH_HACKRF_FIRMWARE_COMMON}/i2c_bus.c
|
${PATH_HACKRF_FIRMWARE_COMMON}/i2c_bus.c
|
||||||
${PATH_HACKRF_FIRMWARE_COMMON}/i2c_lpc.c
|
${PATH_HACKRF_FIRMWARE_COMMON}/i2c_lpc.c
|
||||||
${PATH_HACKRF_FIRMWARE_COMMON}/rffc5071_spi.c
|
|
||||||
${PATH_HACKRF_FIRMWARE_COMMON}/w25q80bv.c
|
${PATH_HACKRF_FIRMWARE_COMMON}/w25q80bv.c
|
||||||
${PATH_HACKRF_FIRMWARE_COMMON}/w25q80bv_target.c
|
${PATH_HACKRF_FIRMWARE_COMMON}/w25q80bv_target.c
|
||||||
${PATH_HACKRF_FIRMWARE_COMMON}/spi_bus.c
|
${PATH_HACKRF_FIRMWARE_COMMON}/spi_bus.c
|
||||||
@ -115,6 +114,20 @@ macro(DeclareTargets)
|
|||||||
${PATH_HACKRF_FIRMWARE_COMMON}/gpio_lpc.c
|
${PATH_HACKRF_FIRMWARE_COMMON}/gpio_lpc.c
|
||||||
)
|
)
|
||||||
|
|
||||||
|
if(BOARD STREQUAL "RAD1O")
|
||||||
|
SET(SRC_M4
|
||||||
|
${SRC_M4}
|
||||||
|
${PATH_HACKRF_FIRMWARE_COMMON}/max2871.c
|
||||||
|
${PATH_HACKRF_FIRMWARE_COMMON}/max2871_regs.c
|
||||||
|
)
|
||||||
|
else()
|
||||||
|
SET(SRC_M4
|
||||||
|
${SRC_M4}
|
||||||
|
${PATH_HACKRF_FIRMWARE_COMMON}/rffc5071.c
|
||||||
|
${PATH_HACKRF_FIRMWARE_COMMON}/rffc5071_spi.c
|
||||||
|
)
|
||||||
|
endif()
|
||||||
|
|
||||||
configure_file(
|
configure_file(
|
||||||
${PATH_HACKRF_FIRMWARE_COMMON}/m0_bin.s.cmake
|
${PATH_HACKRF_FIRMWARE_COMMON}/m0_bin.s.cmake
|
||||||
m0_bin.s
|
m0_bin.s
|
||||||
|
@ -46,6 +46,8 @@
|
|||||||
#include "usb_api_transceiver.h"
|
#include "usb_api_transceiver.h"
|
||||||
#include "usb_bulk_buffer.h"
|
#include "usb_bulk_buffer.h"
|
||||||
|
|
||||||
|
#include "hackrf-ui.h"
|
||||||
|
|
||||||
static const usb_request_handler_fn vendor_request_handler[] = {
|
static const usb_request_handler_fn vendor_request_handler[] = {
|
||||||
NULL,
|
NULL,
|
||||||
usb_vendor_request_set_transceiver_mode,
|
usb_vendor_request_set_transceiver_mode,
|
||||||
@ -55,8 +57,13 @@ static const usb_request_handler_fn vendor_request_handler[] = {
|
|||||||
usb_vendor_request_read_si5351c,
|
usb_vendor_request_read_si5351c,
|
||||||
usb_vendor_request_set_sample_rate_frac,
|
usb_vendor_request_set_sample_rate_frac,
|
||||||
usb_vendor_request_set_baseband_filter_bandwidth,
|
usb_vendor_request_set_baseband_filter_bandwidth,
|
||||||
|
#ifdef RAD1O
|
||||||
|
NULL, // write_rffc5071 not used
|
||||||
|
NULL, // read_rffc5071 not used
|
||||||
|
#else
|
||||||
usb_vendor_request_write_rffc5071,
|
usb_vendor_request_write_rffc5071,
|
||||||
usb_vendor_request_read_rffc5071,
|
usb_vendor_request_read_rffc5071,
|
||||||
|
#endif
|
||||||
usb_vendor_request_erase_spiflash,
|
usb_vendor_request_erase_spiflash,
|
||||||
usb_vendor_request_write_spiflash,
|
usb_vendor_request_write_spiflash,
|
||||||
usb_vendor_request_read_spiflash,
|
usb_vendor_request_read_spiflash,
|
||||||
@ -154,8 +161,11 @@ void usb_set_descriptor_by_serial_number(void)
|
|||||||
int main(void) {
|
int main(void) {
|
||||||
pin_setup();
|
pin_setup();
|
||||||
enable_1v8_power();
|
enable_1v8_power();
|
||||||
#ifdef HACKRF_ONE
|
#if (defined HACKRF_ONE || defined RAD1O)
|
||||||
enable_rf_power();
|
enable_rf_power();
|
||||||
|
|
||||||
|
/* Let the voltage stabilize */
|
||||||
|
delay(1000000);
|
||||||
#endif
|
#endif
|
||||||
cpu_clock_init();
|
cpu_clock_init();
|
||||||
|
|
||||||
@ -176,6 +186,8 @@ int main(void) {
|
|||||||
|
|
||||||
nvic_set_priority(NVIC_USB0_IRQ, 255);
|
nvic_set_priority(NVIC_USB0_IRQ, 255);
|
||||||
|
|
||||||
|
hackrf_ui_init();
|
||||||
|
|
||||||
usb_run(&usb_device);
|
usb_run(&usb_device);
|
||||||
|
|
||||||
rf_path_init(&rf_path);
|
rf_path_init(&rf_path);
|
||||||
|
@ -107,6 +107,7 @@ usb_request_status_t usb_vendor_request_read_si5351c(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifndef RAD1O
|
||||||
usb_request_status_t usb_vendor_request_write_rffc5071(
|
usb_request_status_t usb_vendor_request_write_rffc5071(
|
||||||
usb_endpoint_t* const endpoint,
|
usb_endpoint_t* const endpoint,
|
||||||
const usb_transfer_stage_t stage
|
const usb_transfer_stage_t stage
|
||||||
@ -115,7 +116,7 @@ usb_request_status_t usb_vendor_request_write_rffc5071(
|
|||||||
{
|
{
|
||||||
if( endpoint->setup.index < RFFC5071_NUM_REGS )
|
if( endpoint->setup.index < RFFC5071_NUM_REGS )
|
||||||
{
|
{
|
||||||
rffc5071_reg_write(&rffc5072, endpoint->setup.index, endpoint->setup.value);
|
rffc5071_reg_write(&mixer, endpoint->setup.index, endpoint->setup.value);
|
||||||
usb_transfer_schedule_ack(endpoint->in);
|
usb_transfer_schedule_ack(endpoint->in);
|
||||||
return USB_REQUEST_STATUS_OK;
|
return USB_REQUEST_STATUS_OK;
|
||||||
}
|
}
|
||||||
@ -134,7 +135,7 @@ usb_request_status_t usb_vendor_request_read_rffc5071(
|
|||||||
{
|
{
|
||||||
if( endpoint->setup.index < RFFC5071_NUM_REGS )
|
if( endpoint->setup.index < RFFC5071_NUM_REGS )
|
||||||
{
|
{
|
||||||
value = rffc5071_reg_read(&rffc5072, endpoint->setup.index);
|
value = rffc5071_reg_read(&mixer, endpoint->setup.index);
|
||||||
endpoint->buffer[0] = value & 0xff;
|
endpoint->buffer[0] = value & 0xff;
|
||||||
endpoint->buffer[1] = value >> 8;
|
endpoint->buffer[1] = value >> 8;
|
||||||
usb_transfer_schedule_block(endpoint->in, &endpoint->buffer, 2,
|
usb_transfer_schedule_block(endpoint->in, &endpoint->buffer, 2,
|
||||||
@ -147,3 +148,4 @@ usb_request_status_t usb_vendor_request_read_rffc5071(
|
|||||||
return USB_REQUEST_STATUS_OK;
|
return USB_REQUEST_STATUS_OK;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
@ -22,6 +22,7 @@
|
|||||||
|
|
||||||
#include "usb_api_transceiver.h"
|
#include "usb_api_transceiver.h"
|
||||||
|
|
||||||
|
#include "hackrf-ui.h"
|
||||||
#include <libopencm3/cm3/vector.h>
|
#include <libopencm3/cm3/vector.h>
|
||||||
#include <libopencm3/lpc43xx/m4/nvic.h>
|
#include <libopencm3/lpc43xx/m4/nvic.h>
|
||||||
#include "sgpio_isr.h"
|
#include "sgpio_isr.h"
|
||||||
@ -152,6 +153,7 @@ usb_request_status_t usb_vendor_request_set_lna_gain(
|
|||||||
if( stage == USB_TRANSFER_STAGE_SETUP ) {
|
if( stage == USB_TRANSFER_STAGE_SETUP ) {
|
||||||
const uint8_t value = max2837_set_lna_gain(&max2837, endpoint->setup.index);
|
const uint8_t value = max2837_set_lna_gain(&max2837, endpoint->setup.index);
|
||||||
endpoint->buffer[0] = value;
|
endpoint->buffer[0] = value;
|
||||||
|
if(value) hackrf_ui_setBBLNAGain(endpoint->setup.index);
|
||||||
usb_transfer_schedule_block(endpoint->in, &endpoint->buffer, 1,
|
usb_transfer_schedule_block(endpoint->in, &endpoint->buffer, 1,
|
||||||
NULL, NULL);
|
NULL, NULL);
|
||||||
usb_transfer_schedule_ack(endpoint->out);
|
usb_transfer_schedule_ack(endpoint->out);
|
||||||
@ -166,6 +168,7 @@ usb_request_status_t usb_vendor_request_set_vga_gain(
|
|||||||
if( stage == USB_TRANSFER_STAGE_SETUP ) {
|
if( stage == USB_TRANSFER_STAGE_SETUP ) {
|
||||||
const uint8_t value = max2837_set_vga_gain(&max2837, endpoint->setup.index);
|
const uint8_t value = max2837_set_vga_gain(&max2837, endpoint->setup.index);
|
||||||
endpoint->buffer[0] = value;
|
endpoint->buffer[0] = value;
|
||||||
|
if(value) hackrf_ui_setBBVGAGain(endpoint->setup.index);
|
||||||
usb_transfer_schedule_block(endpoint->in, &endpoint->buffer, 1,
|
usb_transfer_schedule_block(endpoint->in, &endpoint->buffer, 1,
|
||||||
NULL, NULL);
|
NULL, NULL);
|
||||||
usb_transfer_schedule_ack(endpoint->out);
|
usb_transfer_schedule_ack(endpoint->out);
|
||||||
@ -180,6 +183,7 @@ usb_request_status_t usb_vendor_request_set_txvga_gain(
|
|||||||
if( stage == USB_TRANSFER_STAGE_SETUP ) {
|
if( stage == USB_TRANSFER_STAGE_SETUP ) {
|
||||||
const uint8_t value = max2837_set_txvga_gain(&max2837, endpoint->setup.index);
|
const uint8_t value = max2837_set_txvga_gain(&max2837, endpoint->setup.index);
|
||||||
endpoint->buffer[0] = value;
|
endpoint->buffer[0] = value;
|
||||||
|
if(value) hackrf_ui_setBBTXVGAGain(endpoint->setup.index);
|
||||||
usb_transfer_schedule_block(endpoint->in, &endpoint->buffer, 1,
|
usb_transfer_schedule_block(endpoint->in, &endpoint->buffer, 1,
|
||||||
NULL, NULL);
|
NULL, NULL);
|
||||||
usb_transfer_schedule_ack(endpoint->out);
|
usb_transfer_schedule_ack(endpoint->out);
|
||||||
|
@ -30,6 +30,8 @@
|
|||||||
#define USB_PRODUCT_ID (0x6089)
|
#define USB_PRODUCT_ID (0x6089)
|
||||||
#elif JAWBREAKER
|
#elif JAWBREAKER
|
||||||
#define USB_PRODUCT_ID (0x604B)
|
#define USB_PRODUCT_ID (0x604B)
|
||||||
|
#elif RAD1O
|
||||||
|
#define USB_PRODUCT_ID (0xCC15)
|
||||||
#else
|
#else
|
||||||
#define USB_PRODUCT_ID (0xFFFF)
|
#define USB_PRODUCT_ID (0xFFFF)
|
||||||
#endif
|
#endif
|
||||||
|
@ -36,7 +36,7 @@ int main(void)
|
|||||||
|
|
||||||
ssp1_set_mode_max2837();
|
ssp1_set_mode_max2837();
|
||||||
max2837_setup(&max2837);
|
max2837_setup(&max2837);
|
||||||
rffc5071_setup(&rffc5072);
|
mixer_setup(&mixer);
|
||||||
led_on(LED2);
|
led_on(LED2);
|
||||||
|
|
||||||
max2837_set_frequency(&max2837, freq);
|
max2837_set_frequency(&max2837, freq);
|
||||||
|
Reference in New Issue
Block a user