h1r9: initial GPIO definitions

This commit is contained in:
Michael Ossmann
2022-09-06 07:28:15 -04:00
committed by Mike Walters
parent 8aa79e9fe5
commit 6d48671084
5 changed files with 142 additions and 18 deletions

View File

@ -35,6 +35,7 @@
#include "i2c_bus.h"
#include "i2c_lpc.h"
#include "cpld_jtag.h"
#include "platform_detect.h"
#include <libopencm3/lpc43xx/cgu.h>
#include <libopencm3/lpc43xx/ccu.h>
#include <libopencm3/lpc43xx/scu.h>
@ -134,8 +135,15 @@ static struct gpio_t gpio_cpld_pp_tms = GPIO(1, 1);
static struct gpio_t gpio_cpld_pp_tdo = GPIO(1, 8);
#endif
static struct gpio_t gpio_hw_sync_enable = GPIO(5,12);
/* other CPLD interface GPIO pins */
static struct gpio_t gpio_hw_sync_enable = GPIO(5, 12);
static struct gpio_t gpio_rx_q_invert = GPIO(0, 13);
/* HackRF One r9 */
#ifdef HACKRF_ONE
static struct gpio_t gpio_h1r9_rx = GPIO(0, 7);
static struct gpio_t gpio_h1r9_no_rx_amp_pwr = GPIO(3, 6);
#endif
// clang-format on
i2c_bus_t i2c0 = {
@ -578,6 +586,7 @@ void cpu_clock_init(void)
i2c_bus_start(clock_gen.bus, &i2c_config_si5351c_fast_clock);
si5351c_init(&clock_gen);
si5351c_disable_all_outputs(&clock_gen);
si5351c_disable_oeb_pin_control(&clock_gen);
si5351c_power_down_all_clocks(&clock_gen);
@ -811,6 +820,13 @@ void pin_setup(void)
/* Configure all GPIO as Input (safe state) */
gpio_init();
detect_hardware_platform();
#ifdef HACKRF_ONE
if (detected_platform() < BOARD_ID_HACKRF1_OG) {
halt_and_flash(6000000);
}
#endif
/* TDI and TMS pull-ups are required in all JTAG-compliant devices.
*
* The HackRF CPLD is always present, so let the CPLD pull up its TDI and TMS.
@ -855,9 +871,16 @@ void pin_setup(void)
gpio_output(&gpio_led[3]);
#endif
disable_1v8_power();
gpio_output(&gpio_1v8_enable);
scu_pinmux(SCU_PINMUX_EN1V8, SCU_GPIO_NOPULL | SCU_CONF_FUNCTION0);
if (detected_platform() == BOARD_ID_HACKRF1_R9) {
//gpio_1v8_enable = GPIO(1, 12);
disable_1v8_power();
gpio_output(&gpio_1v8_enable);
scu_pinmux(P2_12, SCU_GPIO_FAST | SCU_CONF_FUNCTION0);
} else {
disable_1v8_power();
gpio_output(&gpio_1v8_enable);
scu_pinmux(SCU_PINMUX_EN1V8, SCU_GPIO_FAST | SCU_CONF_FUNCTION0);
}
#ifdef HACKRF_ONE
/* Safe state: start with VAA turned off: */
@ -890,6 +913,8 @@ void pin_setup(void)
mixer_bus_setup(&mixer);
rf_path.gpio_rx = &gpio_h1r9_rx;
rf_path.gpio_no_rx_amp_pwr = &gpio_h1r9_no_rx_amp_pwr;
rf_path_pin_setup(&rf_path);
/* Configure external clock in */

View File

@ -232,6 +232,14 @@ extern "C" {
#define SCU_PINMUX_GP_CLKIN (P4_7)
/* HackRF One r9 */
#define SCU_H1R9_CLKIN_EN (P6_7) /* GPIO5[15] on P6_7 */
#define SCU_H1R9_CLKOUT_EN (P1_2) /* GPIO0[9] on P1_2 (has boot pull-down) */
#define SCU_H1R9_MCU_CLK_EN (P1_1) /* GPIO0[8] on P1_1 (has boot pull-up) */
#define SCU_H1R9_RX (P2_7) /* GPIO0[7] on P4_4 (has boot pull-up) */
#define SCU_H1R9_NO_RX_AMP_PWR (P6_10) /* GPIO3[6] on P6_10 */
#define SCU_H1R9_NO_ANT_PWR (P4_4) /* GPIO2[4] on P4_4 */
typedef enum {
TRANSCEIVER_MODE_OFF = 0,
TRANSCEIVER_MODE_RX = 1,

View File

@ -28,6 +28,8 @@
#include <hackrf_core.h>
#include "hackrf_ui.h"
#include "gpio_lpc.h"
#include "platform_detect.h"
#include <mixer.h>
#include <max2837.h>
@ -81,21 +83,33 @@
#endif
/*
* Antenna port power on HackRF One is controlled by GPO1 on the RFFC5072.
* This is the only thing we use RFFC5072 GPO for on HackRF One. The value of
* SWITCHCTRL_NO_ANT_PWR does not correspond to the GPO1 bit in the gpo
* register.
* Antenna port power on HackRF One (prior to r9) is controlled by GPO1 on the
* RFFC5072. This is the only thing we use RFFC5072 GPO for on HackRF One.
* The value of SWITCHCTRL_NO_ANT_PWR does not correspond to the GPO1 bit in
* the gpo register.
*/
#define SWITCHCTRL_ANT_PWR (1 << 6) /* turn on antenna port power */
/*
* Starting with HackRF One r9 this control signal has been moved to the
* microcontroller.
*/
static struct gpio_t gpio_h1r9_no_ant_pwr = GPIO(2, 4); //FIXME max2837_tx_enable conflict
#ifdef HACKRF_ONE
static void switchctrl_set_hackrf_one(rf_path_t* const rf_path, uint8_t ctrl)
{
if (ctrl & SWITCHCTRL_TX) {
gpio_set(rf_path->gpio_tx);
if (detected_platform() != BOARD_ID_HACKRF1_R9) {
gpio_set(rf_path->gpio_tx);
}
gpio_clear(rf_path->gpio_rx);
} else {
gpio_clear(rf_path->gpio_tx);
if (detected_platform() != BOARD_ID_HACKRF1_R9) {
gpio_clear(rf_path->gpio_tx);
}
gpio_set(rf_path->gpio_rx);
}
@ -156,10 +170,22 @@ static void switchctrl_set_hackrf_one(rf_path_t* const rf_path, uint8_t ctrl)
gpio_set(rf_path->gpio_no_rx_amp_pwr);
}
if (ctrl & SWITCHCTRL_ANT_PWR) {
mixer_set_gpo(&mixer, 0x00); /* turn on antenna power by clearing GPO1 */
if (detected_platform() == BOARD_ID_HACKRF1_R9) {
if (ctrl & SWITCHCTRL_ANT_PWR) {
gpio_clear(&gpio_h1r9_no_ant_pwr);
} else {
gpio_set(&gpio_h1r9_no_ant_pwr);
}
} else {
mixer_set_gpo(&mixer, 0x01); /* turn off antenna power by setting GPO1 */
if (ctrl & SWITCHCTRL_ANT_PWR) {
mixer_set_gpo(
&mixer,
0x00); /* turn on antenna power by clearing GPO1 */
} else {
mixer_set_gpo(
&mixer,
0x01); /* turn off antenna power by setting GPO1 */
}
}
}
#endif
@ -256,12 +282,20 @@ void rf_path_pin_setup(rf_path_t* const rf_path)
scu_pinmux(SCU_TX_AMP, SCU_GPIO_FAST | SCU_CONF_FUNCTION0);
scu_pinmux(SCU_TX, SCU_GPIO_FAST | SCU_CONF_FUNCTION4);
scu_pinmux(SCU_MIX_BYPASS, SCU_GPIO_FAST | SCU_CONF_FUNCTION4);
scu_pinmux(SCU_RX, SCU_GPIO_FAST | SCU_CONF_FUNCTION4);
scu_pinmux(SCU_NO_TX_AMP_PWR, SCU_GPIO_FAST | SCU_CONF_FUNCTION0);
scu_pinmux(SCU_AMP_BYPASS, SCU_GPIO_FAST | SCU_CONF_FUNCTION0);
scu_pinmux(SCU_RX_AMP, SCU_GPIO_FAST | SCU_CONF_FUNCTION0);
scu_pinmux(SCU_NO_RX_AMP_PWR, SCU_GPIO_FAST | SCU_CONF_FUNCTION0);
// clang-format on
if (detected_platform() == BOARD_ID_HACKRF1_R9) {
scu_pinmux(SCU_H1R9_RX, SCU_GPIO_FAST | SCU_CONF_FUNCTION0);
scu_pinmux(SCU_H1R9_NO_RX_AMP_PWR, SCU_GPIO_FAST | SCU_CONF_FUNCTION0);
scu_pinmux(SCU_H1R9_NO_ANT_PWR, SCU_GPIO_FAST | SCU_CONF_FUNCTION0);
gpio_clear(&gpio_h1r9_no_ant_pwr);
gpio_output(&gpio_h1r9_no_ant_pwr);
} else {
scu_pinmux(SCU_RX, SCU_GPIO_FAST | SCU_CONF_FUNCTION4);
scu_pinmux(SCU_NO_RX_AMP_PWR, SCU_GPIO_FAST | SCU_CONF_FUNCTION0);
}
/* Configure RF power supply (VAA) switch */
scu_pinmux(SCU_NO_VAA_ENABLE, SCU_GPIO_FAST | SCU_CONF_FUNCTION0);

View File

@ -21,6 +21,18 @@
*/
#include "si5351c.h"
#include "clkin.h"
#include "platform_detect.h"
#include "gpio_lpc.h"
#include "hackrf_core.h"
#include <libopencm3/lpc43xx/scu.h>
/* HackRF One r9 clock control */
// clang-format off
static struct gpio_t gpio_h1r9_clkin_en = GPIO(5, 15);
static struct gpio_t gpio_h1r9_clkout_en = GPIO(0, 9);
static struct gpio_t gpio_h1r9_mcu_clk_en = GPIO(0, 8);
// clang-format on
#include <stdbool.h>
@ -189,11 +201,23 @@ void si5351c_configure_clock_control(
#if (defined JAWBREAKER || defined HACKRF_ONE)
if (source == PLL_SOURCE_CLKIN) {
/* PLLB on CLKIN */
pll = SI5351C_CLK_PLL_SRC_B;
if (detected_platform() < BOARD_ID_HACKRF1_R9) {
/*
* HackRF One r9 always uses PLL A on the XTAL input
* but externally switches that input to CLKIN.
*/
pll = SI5351C_CLK_PLL_SRC_A;
gpio_set(&gpio_h1r9_clkin_en);
} else {
/* PLLB on CLKIN */
pll = SI5351C_CLK_PLL_SRC_B;
}
} else {
/* PLLA on XTAL */
pll = SI5351C_CLK_PLL_SRC_A;
if (detected_platform() < BOARD_ID_HACKRF1_R9) {
gpio_clear(&gpio_h1r9_clkin_en);
}
}
#endif
if (clkout_enabled) {
@ -250,6 +274,12 @@ void si5351c_enable_clock_outputs(si5351c_driver_t* const drv)
value |= (clkout_enabled) ? SI5351C_CLK_ENABLE(3) : SI5351C_CLK_DISABLE(3);
uint8_t data[] = {SI5351C_REG_OUTPUT_EN, value};
si5351c_write(drv, data, sizeof(data));
if ((clkout_enabled) && (detected_platform() == BOARD_ID_HACKRF1_R9)) {
gpio_set(&gpio_h1r9_clkout_en);
} else {
gpio_clear(&gpio_h1r9_clkout_en);
}
}
void si5351c_set_int_mode(
@ -283,7 +313,12 @@ void si5351c_set_clock_source(si5351c_driver_t* const drv, const enum pll_source
bool si5351c_clkin_signal_valid(si5351c_driver_t* const drv)
{
return (si5351c_read_single(drv, 0) & SI5351C_LOS) == 0;
if (detected_platform() == BOARD_ID_HACKRF1_R9) {
uint32_t f = clkin_frequency();
return (f > 9000000) && (f < 11000000);
} else {
return (si5351c_read_single(drv, 0) & SI5351C_LOS) == 0;
}
}
void si5351c_clkout_enable(si5351c_driver_t* const drv, uint8_t enable)
@ -296,3 +331,24 @@ void si5351c_clkout_enable(si5351c_driver_t* const drv, uint8_t enable)
si5351c_configure_clock_control(drv, active_clock_source);
si5351c_enable_clock_outputs(drv);
}
void si5351c_init(si5351c_driver_t* const drv)
{
if (detected_platform() == BOARD_ID_HACKRF1_R9) {
/* CLKIN_EN */
scu_pinmux(SCU_H1R9_CLKIN_EN, SCU_GPIO_FAST | SCU_CONF_FUNCTION4);
gpio_clear(&gpio_h1r9_clkin_en);
gpio_output(&gpio_h1r9_clkin_en);
/* CLKOUT_EN */
scu_pinmux(SCU_H1R9_CLKIN_EN, SCU_GPIO_FAST | SCU_CONF_FUNCTION0);
gpio_clear(&gpio_h1r9_clkin_en);
gpio_output(&gpio_h1r9_clkin_en);
/* MCU_CLK_EN */
scu_pinmux(SCU_H1R9_MCU_CLK_EN, SCU_GPIO_FAST | SCU_CONF_FUNCTION0);
gpio_clear(&gpio_h1r9_mcu_clk_en);
gpio_output(&gpio_h1r9_mcu_clk_en);
}
(void) drv;
}

View File

@ -102,6 +102,7 @@ void si5351c_write(
const uint8_t* const data,
const size_t data_count);
void si5351c_clkout_enable(si5351c_driver_t* const drv, uint8_t enable);
void si5351c_init(si5351c_driver_t* const drv);
#ifdef __cplusplus
}