Merge pull request #1 from schneider42/rad1o

rad1o
This commit is contained in:
schneider42
2015-06-07 23:38:09 +02:00
14 changed files with 1020 additions and 80 deletions

View File

@ -185,7 +185,7 @@ bool sample_rate_set(const uint32_t sample_rate_hz) {
return true;
#endif
#if (defined JAWBREAKER || defined HACKRF_ONE)
#if (defined JAWBREAKER || defined HACKRF_ONE || defined RAD1O)
uint32_t p1 = 4608;
uint32_t p2 = 0;
uint32_t p3 = 0;
@ -297,7 +297,7 @@ void cpu_clock_init(void)
si5351c_configure_multisynth(5, 1536, 0, 1, 0); /* 50MHz */
#endif
#if (defined JAWBREAKER || defined HACKRF_ONE)
#if (defined JAWBREAKER || defined HACKRF_ONE || defined RAD1O)
/*
* Jawbreaker clocks:
* CLK0 -> MAX5864/CPLD
@ -642,3 +642,13 @@ void disable_rf_power(void) {
gpio_set(PORT_NO_VAA_ENABLE, PIN_NO_VAA_ENABLE);
}
#endif
#ifdef RAD1O
void enable_rf_power(void) {
gpio_set(PORT_VAA_ENABLE, PIN_VAA_ENABLE);
}
void disable_rf_power(void) {
gpio_clear(PORT_VAA_ENABLE, PIN_VAA_ENABLE);
}
#endif

View File

@ -36,6 +36,7 @@ extern "C"
#define BOARD_ID_JELLYBEAN 0
#define BOARD_ID_JAWBREAKER 1
#define BOARD_ID_HACKRF_ONE 2
#define BOARD_ID_RAD1O 3
#ifdef JELLYBEAN
#define BOARD_ID BOARD_ID_JELLYBEAN
@ -49,6 +50,10 @@ extern "C"
#define BOARD_ID BOARD_ID_HACKRF_ONE
#endif
#ifdef RAD1O
#define BOARD_ID BOARD_ID_RAD1O
#endif
/*
* SCU PinMux
*/
@ -57,6 +62,9 @@ extern "C"
#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_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 */
@ -81,7 +89,7 @@ extern "C"
/* CPLD JTAG interface */
#define SCU_PINMUX_CPLD_TDO (P9_5) /* GPIO5[18] */
#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_TDI (P6_2) /* GPIO3[ 1] */
#else
@ -101,7 +109,7 @@ extern "C"
#ifdef JELLYBEAN
#define SCU_PINMUX_SGPIO8 (P1_12)
#endif
#if (defined JAWBREAKER || defined HACKRF_ONE)
#if (defined JAWBREAKER || defined HACKRF_ONE || defined RAD1O)
#define SCU_PINMUX_SGPIO8 (P9_6)
#endif
#define SCU_PINMUX_SGPIO9 (P4_3)
@ -123,6 +131,13 @@ extern "C"
#define SCU_XCVR_B6 (P5_5) /* GPIO2[14] on P5_5 */
#define SCU_XCVR_B7 (P5_6) /* GPIO2[15] on P5_6 */
#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_RXENABLE (P4_5) /* GPIO2[5] on P4_5 */
#define SCU_XCVR_TXENABLE (P4_4) /* GPIO2[4] on P4_4 */
@ -144,6 +159,14 @@ extern "C"
#define SCU_MIXER_SDATA (P6_4) /* GPIO3[3] on P6_4 */
#define SCU_MIXER_RESETX (P5_5) /* GPIO2[14] on P5_5 */
#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_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 */
#ifdef JAWBREAKER
@ -155,6 +178,11 @@ extern "C"
#define SCU_NO_VAA_ENABLE (P5_0) /* GPIO2[9] on P5_0 */
#endif
#ifdef RAD1O
#define SCU_VAA_ENABLE (P5_0) /* GPIO2[9] on P5_0 */
#endif
/* SPI flash */
#define SCU_SSP0_MISO (P3_6)
#define SCU_SSP0_MOSI (P3_7)
@ -180,6 +208,19 @@ extern "C"
#define SCU_NO_RX_AMP_PWR (P2_12) /* GPIO1[12] on P2_12 */
#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 */
#define SCU_PINMUX_GPIO3_8 (P7_0) /* GPIO3[8] */
#define SCU_PINMUX_GPIO3_9 (P7_1) /* GPIO3[9] */
@ -216,6 +257,11 @@ extern "C"
#define PIN_LED3 (BIT8) /* GPIO2[8] on P6_12 */
#define PORT_LED1_3 (GPIO2) /* PORT for LED1, 2 & 3 */
#ifdef RAD1O
#define PIN_LED4 (BIT26) /* GPIO5[26] on PB_6 */
#define PORT_LED4 (GPIO5) /* PORT for LED4 */
#endif
#define PIN_EN1V8 (BIT6) /* GPIO3[6] on P6_10 */
#define PORT_EN1V8 (GPIO3)
@ -238,6 +284,14 @@ extern "C"
#define PORT_XCVR_B (GPIO2)
#endif
#ifdef RAD1O
#define PIN_XCVR_RXHP (BIT1) /* GPIO4[1] on P8_1 */
#define PORT_XCVR_RXHP (GPIO4)
#define PIN_XCVR_B6 (BIT2) /* GPIO4[2] on P8_2 */
#define PIN_XCVR_B7 (BIT3) /* GPIO4[3] on P8_3 */
#define PORT_XCVR_B (GPIO4)
#endif
#define PIN_AD_CS (BIT7) /* GPIO2[7] on P5_7 */
#define PORT_AD_CS (GPIO2) /* PORT for AD_CS */
@ -261,6 +315,20 @@ extern "C"
#define PIN_MIXER_RESETX (BIT14) /* GPIO2[14] on P5_5 */
#define PORT_MIXER_RESETX (GPIO2)
#endif
#ifdef RAD1O
#define PIN_VCO_CE (BIT13) /* GPIO2[13] on P5_4 */
#define PORT_VCO_CE (GPIO2)
#define PIN_VCO_SCLK (BIT6) /* GPIO5[6] on P2_6 */
#define PORT_VCO_SCLK (GPIO5)
#define PIN_VCO_SDATA (BIT3) /* GPIO3[3] on P6_4 */
#define PORT_VCO_SDATA (GPIO3)
#define PIN_VCO_LE (BIT14) /* GPIO2[14] on P5_5 */
#define PORT_VCO_LE (GPIO2)
#define PIN_MIXER_EN (BIT16) /* GPIO5[16] on P6_8 */
#define PORT_MIXER_EN (GPIO5)
#define PIN_SYNT_RFOUT_EN (BIT5) /* GPIO3[5] on P6_9 */
#define PORT_SYNT_RFOUT_EN (GPIO3)
#endif
#ifdef JAWBREAKER
#define PIN_RF_LDO_ENABLE (BIT9) /* GPIO2[9] on P5_0 */
@ -272,6 +340,11 @@ extern "C"
#define PORT_NO_VAA_ENABLE (GPIO2) /* PORT for NO_VAA_ENABLE */
#endif
#ifdef RAD1O
#define PIN_VAA_ENABLE (BIT9) /* GPIO2[9] on P5_0 */
#define PORT_VAA_ENABLE (GPIO2) /* PORT for VAA_ENABLE */
#endif
#define PIN_FLASH_HOLD (BIT14) /* GPIO1[14] on P3_4 */
#define PIN_FLASH_WP (BIT15) /* GPIO1[15] on P3_5 */
#define PORT_FLASH (GPIO1)
@ -308,6 +381,29 @@ extern "C"
#define PORT_NO_RX_AMP_PWR (GPIO1)
#endif
#ifdef RAD1O
#define PIN_BY_AMP (GPIOPIN0) /* GPIO1[0] on P1_7 */
#define PORT_BY_AMP (GPIO1)
#define PIN_BY_AMP_N (GPIOPIN5) /* GPIO5[5] on P2_5 */
#define PORT_BY_AMP_N (GPIO5)
#define PIN_TX_RX (GPIOPIN14) /* GPIO0[14] on P2_10 */
#define PORT_TX_RX (GPIO0)
#define PIN_TX_RX_N (GPIOPIN11) /* GPIO1[11] on P2_11 */
#define PORT_TX_RX_N (GPIO1)
#define PIN_BY_MIX (GPIOPIN12) /* GPIO1[12] on P2_12 */
#define PORT_BY_MIX (GPIO1)
#define PIN_BY_MIX_N (GPIOPIN10) /* GPIO2[10] on P5_1 */
#define PORT_BY_MIX_N (GPIO2)
#define PIN_LOW_HIGH_FILT (GPIOPIN11) /* GPIO2[11] on P5_2 */
#define PORT_LOW_HIGH_FILT (GPIO2)
#define PIN_LOW_HIGH_FILT_N (GPIOPIN12) /* GPIO2[12] on P5_3 */
#define PORT_LOW_HIGH_FILT_N (GPIO2)
#define PIN_TX_AMP (GPIOPIN15) /* GPIO2[15] on P5_6 */
#define PORT_TX_AMP (GPIO2)
#define PIN_RX_LNA (GPIOPIN15) /* GPIO5[15] on P6_7 */
#define PORT_RX_LNA (GPIO5)
#endif
/* GPIO Input */
#define PIN_BOOT0 (BIT8) /* GPIO0[8] on P1_1 */
#define PIN_BOOT1 (BIT9) /* GPIO0[9] on P1_2 */
@ -319,7 +415,7 @@ extern "C"
#define PORT_CPLD_TDO (GPIO5)
#define PIN_CPLD_TCK (GPIOPIN0)
#define PORT_CPLD_TCK (GPIO3)
#ifdef HACKRF_ONE
#if (defined HACKRF_ONE || defined RAD1O)
#define PIN_CPLD_TMS (GPIOPIN4)
#define PORT_CPLD_TMS (GPIO3)
#define PIN_CPLD_TDI (GPIOPIN1)
@ -366,7 +462,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 baseband_filter_bandwidth_set(const uint32_t bandwidth_hz);
#ifdef HACKRF_ONE
#if (defined HACKRF_ONE || defined RAD1O)
void enable_rf_power(void);
void disable_rf_power(void);
#endif

313
firmware/common/max2871.c Normal file
View File

@ -0,0 +1,313 @@
#include "mixer.h"
//#include "max2871.h"
// TODO: put max2871_regs.c into the build system
#include "max2871_regs.c"
#if (defined DEBUG)
#include <stdio.h>
#define LOG printf
#else
#define LOG(x,...)
#include <libopencm3/lpc43xx/ssp.h>
#include <libopencm3/lpc43xx/scu.h>
#include <libopencm3/lpc43xx/gpio.h>
#include "hackrf_core.h"
#endif
#include <stdint.h>
#include <string.h>
static void max2871_spi_write(uint8_t r, uint32_t v);
static void max2871_write_registers(void);
static void delay_ms(int ms);
/*
* - The input is fixed to 50 MHz
* f_REF = 50 MHz
*
* - The VCO must operate between 3 GHz and 6 GHz
* f_VCO range: 3 GHz - 6 GHz
*
* Phase Detector Clock:
* - We configure the phase detector to not change the
* input signal
* f_PFD = f_REF x [(1 + DBR)/(R x (1 + RDIV2))]
* R = 1
* DBR = 0
* RDIV2 = 0
*
* => f_PFD = 50 MHz
*
*
* f_RFOUT < 3 GHz:
* - To go to < 3 GHz, f_VCO has to be divided.
* f_RFOUT = f_VCO / DIVA
*
* - We just divide by 2 for now
* DIVA = 2
* => f_RFOUT = f_VCO / 2
*
* - Relationship between f_PFD (fixed) and f_VCO (variable)
* N + (F/M) = f_VCO/ f_PFD
*
* - Insert relationship between f_RFOUT and f_VCO:
* N + (F/M) = (f_RFOUT * 2) / f_PFD
* f_RFOUT = (N + F/M) * f_PFD / 2
*
* - Limits for N, M and F from the datasheet:
* 19 <= N <= 4091
* 2 <= M <= 4095
* F < M
*
* - Plug in constants:
* f_RFOUT = (N + F/M) / 2 * 50 MHz
*
* - Given the range of N, we can go to:
* f_RFOUT range: 475 MHz - 3 GHz
*
* - N steps in 25 MHz increments:
* N = floor(f_RFOUT / 50 MHz * 2)
* => N = (f_RFOUT * 2) / 50 MHz (uses integer math)
*
* - Calculate the error:
* f_int_ERROR = f_RFOUT - (N * 50 MHz) / 2
* f_int_ERROR range: 0 MHz - 24 MHz
*
* - Use the fraction to get to the correct frequency:
* (F/M) / 2 * 50 MHz = f_int_ERROR
*
* - Fix M:
* M = 25
*
* - Calculate F:
* (F/25) / 2 * 50 MHz = f_int_ERROR
* F = f_int_ERROR / 1 MHz
*
* - Calculate the new error:
*
* f_ERROR = f_RFOUT - (N + F/M) / 2 * 50 MHz
* f_ERROR range: 0 MHz - 1 MHz
*
*
* f_RFOUT > 3 GHz:
* - Do not divide the VCO output
* DIVA = 1
* => f_RFOUT = f_VCO
*
* - Relationship between f_PFD (fixed) and f_VCO (variable)
* N + (F/M) = f_VCO/ f_PFD
*
* - Insert relationship between f_RFOUT and f_VCO:
* N + (F/M) = f_RFOUT / f_PFD
* f_RFOUT = (N + F/M) * f_PFD
*
* - Limits for N, M and F from the datasheet:
* 19 <= N <= 4091
* 2 <= M <= 4095
* F < M
*
* - Plug in constants:
* f_RFOUT = (N + F/M) * 50 MHz
*
* - Given the range of N and the VCO limits, we can go to:
* f_RFOUT range: 3000 MHz - 6000 MHz
*
* - N steps in 50 MHz increments:
* N = floor(f_RFOUT / 50 MHz)
* => N = f_RFOUT / 50 MHz (uses integer math)
*
* - Calculate the error:
* f_int_ERROR = f_RFOUT - N * 50 MHz
* f_int_ERROR range: 0 MHz - 49 MHz
*
* - Use the fraction to get to the correct frequency:
* (F/M) * 50 MHz = f_int_ERROR
*
* - Fix M:
* M = 50
*
* - Calculate F:
* (F/50) * 50 MHz = f_int_ERROR
* F = f_int_ERROR / 1 MHz
*
* - Calculate the new error:
*
* f_ERROR = f_RFOUT - (N + F/M) * 50 MHz
* f_ERROR range: 0 MHz - 1 MHz
*
*/
void mixer_setup(void)
{
/* 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_SYNT_RFOUT_EN, SCU_GPIO_FAST);
/* Set GPIO pins as outputs. */
GPIO_DIR(PORT_VCO_CE) |= PIN_VCO_CE;
GPIO_DIR(PORT_VCO_SCLK) |= PIN_VCO_SCLK;
GPIO_DIR(PORT_VCO_SDATA) |= PIN_VCO_SDATA;
GPIO_DIR(PORT_VCO_LE) |= PIN_VCO_LE;
GPIO_DIR(PORT_SYNT_RFOUT_EN) |= PIN_SYNT_RFOUT_EN;
/* set to known state */
gpio_set(PORT_VCO_CE, PIN_VCO_CE); /* active high */
gpio_clear(PORT_VCO_SCLK, PIN_VCO_SCLK);
gpio_clear(PORT_VCO_SDATA, PIN_VCO_SDATA);
gpio_set(PORT_VCO_LE, PIN_VCO_LE); /* active low */
gpio_set(PORT_SYNT_RFOUT_EN, PIN_SYNT_RFOUT_EN); /* active high */
max2871_regs_init();
int i;
for(i = 5; i >= 0; i--) {
max2871_spi_write(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(3);
max2871_set_DBR(0);
max2871_set_RDIV2(0);
max2871_set_R(50); // 1 MHz f_PFD
max2871_set_REG4DB(0);
max2871_set_CP(3); // ?: CP current up 0-3
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(0);
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); // For 1 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(1);
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();
}
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(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(PORT_VCO_LE, PIN_VCO_LE);
gpio_clear(PORT_VCO_SCLK, PIN_VCO_SCLK);
gpio_clear(PORT_VCO_SDATA, PIN_VCO_SDATA);
/* start transaction by bringing LE low */
gpio_clear(PORT_VCO_LE, PIN_VCO_LE);
while (bits--) {
if (data & msb)
gpio_set(PORT_VCO_SDATA, PIN_VCO_SDATA);
else
gpio_clear(PORT_VCO_SDATA, PIN_VCO_SDATA);
data <<= 1;
serial_delay();
gpio_set(PORT_VCO_SCLK, PIN_VCO_SCLK);
serial_delay();
gpio_clear(PORT_VCO_SCLK, PIN_VCO_SCLK);
}
gpio_set(PORT_VCO_LE, PIN_VCO_LE);
#endif
}
static void max2871_write_registers(void)
{
int i;
for(i = 5; i >= 0; i--) {
max2871_spi_write(i, max2871_get_register(i));
}
}
/* Set frequency (MHz). */
uint64_t mixer_set_frequency(uint16_t mhz)
{
(void) mhz;
return mhz;
}
void mixer_tx(void)
{}
void mixer_rx(void)
{}
void mixer_rxtx(void)
{}
void mixer_enable(void)
{}
void mixer_disable(void)
{}
void mixer_set_gpo(uint8_t gpo)
{
(void) gpo;
}

View 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;
}

View File

@ -0,0 +1,54 @@
#ifndef MAX2871_H
#define MAX2871_H
#include <stdint.h>
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

45
firmware/common/mixer.h Normal file
View File

@ -0,0 +1,45 @@
/*
* 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
#include <stdint.h>
/* Initialize chip. Call _setup() externally, as it calls _init(). */
extern void mixer_init(void);
extern void mixer_setup(void);
/* Set frequency (MHz). */
extern uint64_t mixer_set_frequency(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(void);
extern void mixer_rx(void);
extern void mixer_rxtx(void);
extern void mixer_enable(void);
extern void mixer_disable(void);
extern void mixer_set_gpo(uint8_t);
#endif // __MIXER_H

View File

@ -27,12 +27,12 @@
#include <hackrf_core.h>
#include <rffc5071.h>
#include <mixer.h>
#include <max2837.h>
#include <max5864.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
* the RFFC5072.
@ -41,6 +41,9 @@
* 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
* 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_AMP_BYPASS (1 << 1) /* GPO2 bypass amp section */
@ -83,6 +86,86 @@ uint8_t switchctrl = SWITCHCTRL_SAFE;
*/
#define SWITCHCTRL_ANT_PWR (1 << 6) /* turn on antenna port power */
#ifdef RAD1O
static void switchctrl_set_rad1o(uint8_t ctrl) {
if (ctrl & SWITCHCTRL_TX) {
gpio_set(PORT_TX_RX_N, PIN_TX_RX_N);
gpio_clear(PORT_TX_RX, PIN_TX_RX);
} else {
gpio_clear(PORT_TX_RX_N, PIN_TX_RX_N);
gpio_set(PORT_TX_RX, PIN_TX_RX);
}
if (ctrl & SWITCHCTRL_MIX_BYPASS) {
gpio_clear(PORT_BY_MIX, PIN_BY_MIX);
gpio_set(PORT_BY_MIX_N, PIN_BY_MIX_N);
gpio_clear(PORT_MIXER_EN, PIN_MIXER_EN);
} else {
gpio_set(PORT_BY_MIX, PIN_BY_MIX);
gpio_clear(PORT_BY_MIX_N, PIN_BY_MIX_N);
gpio_set(PORT_MIXER_EN, PIN_MIXER_EN);
}
if (ctrl & SWITCHCTRL_HP) {
gpio_set(PORT_LOW_HIGH_FILT, PIN_LOW_HIGH_FILT);
gpio_clear(PORT_LOW_HIGH_FILT_N, PIN_LOW_HIGH_FILT_N);
} else {
gpio_clear(PORT_LOW_HIGH_FILT, PIN_LOW_HIGH_FILT);
gpio_set(PORT_LOW_HIGH_FILT_N, PIN_LOW_HIGH_FILT_N);
}
if (ctrl & SWITCHCTRL_AMP_BYPASS) {
gpio_clear(PORT_BY_AMP, PIN_BY_AMP);
gpio_set(PORT_BY_AMP_N, PIN_BY_AMP_N);
gpio_clear(PORT_TX_RX, PIN_TX_RX);
gpio_set(PORT_TX_RX_N, PIN_TX_RX_N);
gpio_clear(PORT_TX_AMP, PIN_TX_AMP);
gpio_clear(PORT_RX_LNA, PIN_RX_LNA);
} else if (ctrl & SWITCHCTRL_TX) {
gpio_set(PORT_BY_AMP, PIN_BY_AMP);
gpio_clear(PORT_BY_AMP_N, PIN_BY_AMP_N);
gpio_clear(PORT_TX_RX, PIN_TX_RX);
gpio_set(PORT_TX_RX_N, PIN_TX_RX_N);
gpio_set(PORT_TX_AMP, PIN_TX_AMP);
gpio_clear(PORT_RX_LNA, PIN_RX_LNA);
} else {
gpio_set(PORT_BY_AMP, PIN_BY_AMP);
gpio_clear(PORT_BY_AMP_N, PIN_BY_AMP_N);
gpio_set(PORT_TX_RX, PIN_TX_RX);
gpio_clear(PORT_TX_RX_N, PIN_TX_RX_N);
gpio_clear(PORT_TX_AMP, PIN_TX_AMP);
gpio_set(PORT_RX_LNA, PIN_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(PORT_TX_AMP, PIN_TX_AMP);
}
if (ctrl & SWITCHCTRL_NO_RX_AMP_PWR) {
gpio_clear(PORT_RX_LNA, PIN_RX_LNA);
}
if (ctrl & SWITCHCTRL_ANT_PWR) {
// TODO
}
}
#endif
#ifdef HACKRF_ONE
static void switchctrl_set_hackrf_one(uint8_t ctrl) {
if (ctrl & SWITCHCTRL_TX) {
@ -149,18 +232,20 @@ static void switchctrl_set_hackrf_one(uint8_t ctrl) {
gpio_set(PORT_NO_RX_AMP_PWR, PIN_NO_RX_AMP_PWR);
if (ctrl & SWITCHCTRL_ANT_PWR) {
rffc5071_set_gpo(0x00); /* turn on antenna power by clearing GPO1 */
mixer_set_gpo(0x00); /* turn on antenna power by clearing GPO1 */
} else {
rffc5071_set_gpo(0x01); /* turn off antenna power by setting GPO1 */
mixer_set_gpo(0x01); /* turn off antenna power by setting GPO1 */
}
}
#endif
static void switchctrl_set(const uint8_t gpo) {
#ifdef JAWBREAKER
rffc5071_set_gpo(gpo);
mixer_set_gpo(gpo);
#elif HACKRF_ONE
switchctrl_set_hackrf_one(gpo);
#elif RAD1O
switchctrl_set_rad1o(gpo);
#else
(void)gpo;
#endif
@ -205,6 +290,44 @@ void rf_path_pin_setup() {
/* Safe state: start with VAA turned off: */
disable_rf_power();
#endif
#ifdef 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 */
GPIO0_DIR |= PIN_TX_RX;
GPIO1_DIR |= PIN_BY_AMP | PIN_TX_RX_N | PIN_BY_MIX;
GPIO2_DIR |= PIN_BY_MIX_N | PIN_LOW_HIGH_FILT | PIN_LOW_HIGH_FILT_N | PIN_TX_AMP;
GPIO5_DIR |= PIN_BY_AMP_N | PIN_RX_LNA;
GPIO_DIR(PORT_MIXER_EN) |= PIN_MIXER_EN;
/*
* Safe (initial) switch settings turn off both amplifiers and antenna port
* power and enable both amp bypass and mixer bypass.
*/
switchctrl_set(SWITCHCTRL_AMP_BYPASS | SWITCHCTRL_MIX_BYPASS);
/* Configure RF power supply (VAA) switch control signal as output */
GPIO_DIR(PORT_VAA_ENABLE) |= PIN_VAA_ENABLE;
/* Safe state: start with VAA turned off: */
disable_rf_power();
#endif
}
void rf_path_init(void) {
@ -215,7 +338,7 @@ void rf_path_init(void) {
max2837_setup();
max2837_start();
rffc5071_setup();
mixer_setup();
switchctrl_set(switchctrl);
}
@ -229,11 +352,11 @@ void rf_path_set_direction(const rf_path_direction_t direction) {
/* TX amplifier is in path, be sure to enable TX amplifier. */
switchctrl &= ~SWITCHCTRL_NO_TX_AMP_PWR;
}
rffc5071_tx();
mixer_tx();
if( switchctrl & SWITCHCTRL_MIX_BYPASS ) {
rffc5071_disable();
mixer_disable();
} else {
rffc5071_enable();
mixer_enable();
}
ssp1_set_mode_max5864();
max5864_tx();
@ -248,11 +371,11 @@ void rf_path_set_direction(const rf_path_direction_t direction) {
/* RX amplifier is in path, be sure to enable RX amplifier. */
switchctrl &= ~SWITCHCTRL_NO_RX_AMP_PWR;
}
rffc5071_rx();
mixer_rx();
if( switchctrl & SWITCHCTRL_MIX_BYPASS ) {
rffc5071_disable();
mixer_disable();
} else {
rffc5071_enable();
mixer_enable();
}
ssp1_set_mode_max5864();
max5864_rx();
@ -268,7 +391,7 @@ void rf_path_set_direction(const rf_path_direction_t direction) {
#endif
/* Set RF path to receive direction when "off" */
switchctrl &= ~SWITCHCTRL_TX;
rffc5071_disable();
mixer_disable();
ssp1_set_mode_max5864();
max5864_standby();
ssp1_set_mode_max2837();
@ -285,18 +408,18 @@ void rf_path_set_filter(const rf_path_filter_t filter) {
default:
case RF_PATH_FILTER_BYPASS:
switchctrl |= SWITCHCTRL_MIX_BYPASS;
rffc5071_disable();
mixer_disable();
break;
case RF_PATH_FILTER_LOW_PASS:
switchctrl &= ~(SWITCHCTRL_HP | SWITCHCTRL_MIX_BYPASS);
rffc5071_enable();
mixer_enable();
break;
case RF_PATH_FILTER_HIGH_PASS:
switchctrl &= ~SWITCHCTRL_MIX_BYPASS;
switchctrl |= SWITCHCTRL_HP;
rffc5071_enable();
mixer_enable();
break;
}

View File

@ -33,6 +33,7 @@
#include <stdint.h>
#include <string.h>
#include "mixer.h"
#include "rffc5071.h"
#include "rffc5071_regs.def" // private register def macros
@ -87,9 +88,9 @@ uint16_t rffc5071_regs[RFFC5071_NUM_REGS];
uint32_t rffc5071_regs_dirty = 0x7fffffff;
/* Set up all registers according to defaults specified in docs. */
void rffc5071_init(void)
void mixer_init(void)
{
LOG("# rffc5071_init\n");
LOG("# mixer_init\n");
memcpy(rffc5071_regs, rffc5071_regs_default, sizeof(rffc5071_regs));
rffc5071_regs_dirty = 0x7fffffff;
@ -101,10 +102,10 @@ void rffc5071_init(void)
* Set up pins for GPIO and SPI control, configure SSP peripheral for SPI, and
* set our own default register configuration.
*/
void rffc5071_setup(void)
void mixer_setup(void)
{
rffc5071_init();
LOG("# rffc5071_setup\n");
mixer_init();
LOG("# mixer_setup\n");
#if !defined TEST
/* Configure GPIO pins. */
scu_pinmux(SCU_MIXER_ENX, SCU_GPIO_FAST);
@ -363,7 +364,7 @@ void rffc5071_regs_commit(void)
}
}
void rffc5071_tx(void) {
void mixer_tx(void) {
LOG("# rffc5071_tx\n");
set_RFFC5071_ENBL(0);
set_RFFC5071_FULLD(0);
@ -371,7 +372,7 @@ void rffc5071_tx(void) {
rffc5071_regs_commit();
}
void rffc5071_rx(void) {
void mixer_rx(void) {
LOG("# rfc5071_rx\n");
set_RFFC5071_ENBL(0);
set_RFFC5071_FULLD(0);
@ -383,22 +384,22 @@ void rffc5071_rx(void) {
* This function turns on both mixer (full-duplex) on the RFFC5071, but our
* current hardware designs do not support full-duplex operation.
*/
void rffc5071_rxtx(void) {
void mixer_rxtx(void) {
LOG("# rfc5071_rxtx\n");
set_RFFC5071_ENBL(0);
set_RFFC5071_FULLD(1); /* mixer 1 and mixer 2 (RXTX) */
rffc5071_regs_commit();
rffc5071_enable();
mixer_enable();
}
void rffc5071_disable(void) {
void mixer_disable(void) {
LOG("# rfc5071_disable\n");
set_RFFC5071_ENBL(0);
rffc5071_regs_commit();
}
void rffc5071_enable(void) {
void mixer_enable(void) {
LOG("# rfc5071_enable\n");
set_RFFC5071_ENBL(1);
rffc5071_regs_commit();
@ -475,17 +476,17 @@ uint64_t rffc5071_config_synth_int(uint16_t lo) {
}
/* !!!!!!!!!!! hz is currently ignored !!!!!!!!!!! */
uint64_t rffc5071_set_frequency(uint16_t mhz) {
uint64_t mixer_set_frequency(uint16_t mhz) {
uint32_t tune_freq;
rffc5071_disable();
mixer_disable();
tune_freq = rffc5071_config_synth_int(mhz);
rffc5071_enable();
mixer_enable();
return tune_freq;
}
void rffc5071_set_gpo(uint8_t gpo)
void mixer_set_gpo(uint8_t gpo)
{
/* We set GPO for both paths just in case. */
set_RFFC5071_P1GPO(gpo);
@ -497,18 +498,18 @@ void rffc5071_set_gpo(uint8_t gpo)
#ifdef TEST
int main(int ac, char **av)
{
rffc5071_setup();
mixer_setup();
rffc5071_tx(0);
rffc5071_set_frequency(500, 0);
rffc5071_set_frequency(525, 0);
rffc5071_set_frequency(550, 0);
rffc5071_set_frequency(1500, 0);
rffc5071_set_frequency(1525, 0);
rffc5071_set_frequency(1550, 0);
rffc5071_disable();
rffc5071_rx(0);
rffc5071_disable();
rffc5071_rxtx();
rffc5071_disable();
mixer_set_frequency(500, 0);
mixer_set_frequency(525, 0);
mixer_set_frequency(550, 0);
mixer_set_frequency(1500, 0);
mixer_set_frequency(1525, 0);
mixer_set_frequency(1550, 0);
mixer_disable();
mixer_rx(0);
mixer_disable();
mixer_rxtx();
mixer_disable();
}
#endif //TEST

View File

@ -32,10 +32,6 @@ extern uint32_t rffc5071_regs_dirty;
#define RFFC5071_REG_SET_CLEAN(r) rffc5071_regs_dirty &= ~(1UL<<r)
#define RFFC5071_REG_SET_DIRTY(r) rffc5071_regs_dirty |= (1UL<<r)
/* Initialize chip. Call _setup() externally, as it calls _init(). */
extern void rffc5071_init(void);
extern void rffc5071_setup(void);
/* Read a register via SPI. Save a copy to memory and return
* value. Discard any uncommited changes and mark CLEAN. */
extern uint16_t rffc5071_reg_read(uint8_t r);
@ -49,17 +45,4 @@ extern void rffc5071_reg_write(uint8_t r, uint16_t v);
* provided routines for those operations. */
extern void rffc5071_regs_commit(void);
/* Set frequency (MHz). */
extern uint64_t rffc5071_set_frequency(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 rffc5071_tx(void);
extern void rffc5071_rx(void);
extern void rffc5071_rxtx(void);
extern void rffc5071_enable(void);
extern void rffc5071_disable(void);
extern void rffc5071_set_gpo(uint8_t);
#endif // __RFFC5071_H

View File

@ -239,7 +239,7 @@ void si5351c_configure_clock_control()
}
#endif
#if (defined JAWBREAKER || defined HACKRF_ONE)
#if (defined JAWBREAKER || defined HACKRF_ONE || defined RAD1O)
void si5351c_configure_clock_control(const enum pll_sources source)
{
uint8_t pll;

View File

@ -22,7 +22,7 @@
#include "tuning.h"
#include <rffc5071.h>
#include <mixer.h>
#include <max2837.h>
#include <sgpio.h>
@ -53,9 +53,9 @@ uint64_t freq_cache = 100000000;
bool set_freq(const uint64_t freq)
{
bool success;
uint32_t RFFC5071_freq_mhz;
uint32_t mixer_freq_mhz;
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_hz = freq % 1000000;
@ -69,16 +69,16 @@ bool set_freq(const uint64_t freq)
rf_path_set_filter(RF_PATH_FILTER_LOW_PASS);
/* IF is graduated from 2650 MHz to 2343 MHz */
max2837_freq_nominal_hz = 2650000000 - (freq / 7);
RFFC5071_freq_mhz = (max2837_freq_nominal_hz / FREQ_ONE_MHZ) + freq_mhz;
mixer_freq_mhz = (max2837_freq_nominal_hz / FREQ_ONE_MHZ) + freq_mhz;
/* Set Freq and read real freq */
real_RFFC5071_freq_hz = rffc5071_set_frequency(RFFC5071_freq_mhz);
max2837_set_frequency(real_RFFC5071_freq_hz - freq);
real_mixer_freq_hz = mixer_set_frequency(mixer_freq_mhz);
max2837_set_frequency(real_mixer_freq_hz - freq);
sgpio_cpld_stream_rx_set_q_invert(1);
}else if( (freq_mhz >= MIN_BYPASS_FREQ_MHZ) && (freq_mhz < MAX_BYPASS_FREQ_MHZ) )
{
rf_path_set_filter(RF_PATH_FILTER_BYPASS);
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_freq_hz);
sgpio_cpld_stream_rx_set_q_invert(0);
}else if( (freq_mhz >= MIN_HP_FREQ_MHZ) && (freq_mhz <= MAX_HP_FREQ_MHZ) )
@ -94,10 +94,10 @@ bool set_freq(const uint64_t freq)
max2837_freq_nominal_hz = 2500000000 + ((freq - 5100000000) / 9);
}
rf_path_set_filter(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 */
real_RFFC5071_freq_hz = rffc5071_set_frequency(RFFC5071_freq_mhz);
max2837_set_frequency(freq - real_RFFC5071_freq_hz);
real_mixer_freq_hz = mixer_set_frequency(mixer_freq_mhz);
max2837_set_frequency(freq - real_mixer_freq_hz);
sgpio_cpld_stream_rx_set_q_invert(0);
}else
{
@ -136,7 +136,7 @@ bool set_freq_explicit(const uint64_t if_freq_hz, const uint64_t lo_freq_hz,
sgpio_cpld_stream_rx_set_q_invert(0);
}
if (path != RF_PATH_FILTER_BYPASS) {
(void)rffc5071_set_frequency(lo_freq_hz / FREQ_ONE_MHZ);
(void)mixer_set_frequency(lo_freq_hz / FREQ_ONE_MHZ);
}
return true;
}

View File

@ -59,6 +59,12 @@ else()
set(MCU_PARTNO LPC4330)
endif()
if(BOARD STREQUAL "RAD1O")
set(MIXER max2871)
else()
set(MIXER rffc5071)
endif()
if(NOT DEFINED SRC_M0)
set(SRC_M0 "${PATH_HACKRF_FIRMWARE_COMMON}/m0_sleep.c")
endif()
@ -136,7 +142,7 @@ macro(DeclareTargets)
${PATH_HACKRF_FIRMWARE_COMMON}/si5351c.c
${PATH_HACKRF_FIRMWARE_COMMON}/max2837.c
${PATH_HACKRF_FIRMWARE_COMMON}/max5864.c
${PATH_HACKRF_FIRMWARE_COMMON}/rffc5071.c
${PATH_HACKRF_FIRMWARE_COMMON}/${MIXER}.c
m0_bin.s
)

View File

@ -116,8 +116,13 @@ static const usb_request_handler_fn vendor_request_handler[] = {
usb_vendor_request_read_si5351c,
usb_vendor_request_set_sample_rate_frac,
usb_vendor_request_set_baseband_filter_bandwidth,
#ifdef RAD1O
NULL,
NULL,
#else
usb_vendor_request_write_rffc5071,
usb_vendor_request_read_rffc5071,
#endif
usb_vendor_request_erase_spiflash,
usb_vendor_request_write_spiflash,
usb_vendor_request_read_spiflash,
@ -214,7 +219,7 @@ void usb_set_descriptor_by_serial_number(void)
int main(void) {
pin_setup();
enable_1v8_power();
#ifdef HACKRF_ONE
#if (defined HACKRF_ONE || defined RAD1O)
enable_rf_power();
#endif
cpu_clock_init();

View File

@ -25,7 +25,10 @@
#include <usb_queue.h>
#include <max2837.h>
#include <si5351c.h>
#ifndef RAD1O
#include <rffc5071.h>
#endif
#include <stddef.h>
#include <stdint.h>
@ -105,6 +108,7 @@ usb_request_status_t usb_vendor_request_read_si5351c(
}
}
#ifndef RAD1O
usb_request_status_t usb_vendor_request_write_rffc5071(
usb_endpoint_t* const endpoint,
const usb_transfer_stage_t stage
@ -145,3 +149,4 @@ usb_request_status_t usb_vendor_request_read_rffc5071(
return USB_REQUEST_STATUS_OK;
}
}
#endif