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_bus.h"
#include "i2c_lpc.h" #include "i2c_lpc.h"
#include "cpld_jtag.h" #include "cpld_jtag.h"
#include "platform_detect.h"
#include <libopencm3/lpc43xx/cgu.h> #include <libopencm3/lpc43xx/cgu.h>
#include <libopencm3/lpc43xx/ccu.h> #include <libopencm3/lpc43xx/ccu.h>
#include <libopencm3/lpc43xx/scu.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); static struct gpio_t gpio_cpld_pp_tdo = GPIO(1, 8);
#endif #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); 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 // clang-format on
i2c_bus_t i2c0 = { i2c_bus_t i2c0 = {
@ -578,6 +586,7 @@ void cpu_clock_init(void)
i2c_bus_start(clock_gen.bus, &i2c_config_si5351c_fast_clock); i2c_bus_start(clock_gen.bus, &i2c_config_si5351c_fast_clock);
si5351c_init(&clock_gen);
si5351c_disable_all_outputs(&clock_gen); si5351c_disable_all_outputs(&clock_gen);
si5351c_disable_oeb_pin_control(&clock_gen); si5351c_disable_oeb_pin_control(&clock_gen);
si5351c_power_down_all_clocks(&clock_gen); si5351c_power_down_all_clocks(&clock_gen);
@ -811,6 +820,13 @@ void pin_setup(void)
/* Configure all GPIO as Input (safe state) */ /* Configure all GPIO as Input (safe state) */
gpio_init(); 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. /* 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. * 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]); gpio_output(&gpio_led[3]);
#endif #endif
disable_1v8_power(); if (detected_platform() == BOARD_ID_HACKRF1_R9) {
gpio_output(&gpio_1v8_enable); //gpio_1v8_enable = GPIO(1, 12);
scu_pinmux(SCU_PINMUX_EN1V8, SCU_GPIO_NOPULL | SCU_CONF_FUNCTION0); 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 #ifdef HACKRF_ONE
/* Safe state: start with VAA turned off: */ /* Safe state: start with VAA turned off: */
@ -890,6 +913,8 @@ void pin_setup(void)
mixer_bus_setup(&mixer); 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); rf_path_pin_setup(&rf_path);
/* Configure external clock in */ /* Configure external clock in */

View File

@ -232,6 +232,14 @@ extern "C" {
#define SCU_PINMUX_GP_CLKIN (P4_7) #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 { typedef enum {
TRANSCEIVER_MODE_OFF = 0, TRANSCEIVER_MODE_OFF = 0,
TRANSCEIVER_MODE_RX = 1, TRANSCEIVER_MODE_RX = 1,

View File

@ -28,6 +28,8 @@
#include <hackrf_core.h> #include <hackrf_core.h>
#include "hackrf_ui.h" #include "hackrf_ui.h"
#include "gpio_lpc.h"
#include "platform_detect.h"
#include <mixer.h> #include <mixer.h>
#include <max2837.h> #include <max2837.h>
@ -81,21 +83,33 @@
#endif #endif
/* /*
* Antenna port power on HackRF One is controlled by GPO1 on the RFFC5072. * Antenna port power on HackRF One (prior to r9) is controlled by GPO1 on the
* This is the only thing we use RFFC5072 GPO for on HackRF One. The value of * RFFC5072. This is the only thing we use RFFC5072 GPO for on HackRF One.
* SWITCHCTRL_NO_ANT_PWR does not correspond to the GPO1 bit in the gpo * The value of SWITCHCTRL_NO_ANT_PWR does not correspond to the GPO1 bit in
* register. * the gpo register.
*/ */
#define SWITCHCTRL_ANT_PWR (1 << 6) /* turn on antenna port power */ #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 #ifdef HACKRF_ONE
static void switchctrl_set_hackrf_one(rf_path_t* const rf_path, uint8_t ctrl) static void switchctrl_set_hackrf_one(rf_path_t* const rf_path, uint8_t ctrl)
{ {
if (ctrl & SWITCHCTRL_TX) { 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); gpio_clear(rf_path->gpio_rx);
} else { } 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); 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); gpio_set(rf_path->gpio_no_rx_amp_pwr);
} }
if (ctrl & SWITCHCTRL_ANT_PWR) { if (detected_platform() == BOARD_ID_HACKRF1_R9) {
mixer_set_gpo(&mixer, 0x00); /* turn on antenna power by clearing GPO1 */ if (ctrl & SWITCHCTRL_ANT_PWR) {
gpio_clear(&gpio_h1r9_no_ant_pwr);
} else {
gpio_set(&gpio_h1r9_no_ant_pwr);
}
} else { } 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 #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_AMP, SCU_GPIO_FAST | SCU_CONF_FUNCTION0);
scu_pinmux(SCU_TX, SCU_GPIO_FAST | SCU_CONF_FUNCTION4); scu_pinmux(SCU_TX, SCU_GPIO_FAST | SCU_CONF_FUNCTION4);
scu_pinmux(SCU_MIX_BYPASS, 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_NO_TX_AMP_PWR, SCU_GPIO_FAST | SCU_CONF_FUNCTION0);
scu_pinmux(SCU_AMP_BYPASS, 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_RX_AMP, SCU_GPIO_FAST | SCU_CONF_FUNCTION0);
scu_pinmux(SCU_NO_RX_AMP_PWR, SCU_GPIO_FAST | SCU_CONF_FUNCTION0);
// clang-format on // 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 */ /* Configure RF power supply (VAA) switch */
scu_pinmux(SCU_NO_VAA_ENABLE, SCU_GPIO_FAST | SCU_CONF_FUNCTION0); scu_pinmux(SCU_NO_VAA_ENABLE, SCU_GPIO_FAST | SCU_CONF_FUNCTION0);

View File

@ -21,6 +21,18 @@
*/ */
#include "si5351c.h" #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> #include <stdbool.h>
@ -189,11 +201,23 @@ void si5351c_configure_clock_control(
#if (defined JAWBREAKER || defined HACKRF_ONE) #if (defined JAWBREAKER || defined HACKRF_ONE)
if (source == PLL_SOURCE_CLKIN) { if (source == PLL_SOURCE_CLKIN) {
/* PLLB on CLKIN */ if (detected_platform() < BOARD_ID_HACKRF1_R9) {
pll = SI5351C_CLK_PLL_SRC_B; /*
* 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 { } else {
/* PLLA on XTAL */ /* PLLA on XTAL */
pll = SI5351C_CLK_PLL_SRC_A; pll = SI5351C_CLK_PLL_SRC_A;
if (detected_platform() < BOARD_ID_HACKRF1_R9) {
gpio_clear(&gpio_h1r9_clkin_en);
}
} }
#endif #endif
if (clkout_enabled) { 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); value |= (clkout_enabled) ? SI5351C_CLK_ENABLE(3) : SI5351C_CLK_DISABLE(3);
uint8_t data[] = {SI5351C_REG_OUTPUT_EN, value}; uint8_t data[] = {SI5351C_REG_OUTPUT_EN, value};
si5351c_write(drv, data, sizeof(data)); 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( 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) 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) 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_configure_clock_control(drv, active_clock_source);
si5351c_enable_clock_outputs(drv); 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 uint8_t* const data,
const size_t data_count); const size_t data_count);
void si5351c_clkout_enable(si5351c_driver_t* const drv, uint8_t enable); void si5351c_clkout_enable(si5351c_driver_t* const drv, uint8_t enable);
void si5351c_init(si5351c_driver_t* const drv);
#ifdef __cplusplus #ifdef __cplusplus
} }