Files
mayhem-firmware/firmware/common/gpio.hpp
T
Pezsma 9ab367f2e0 Add praline gpio (#3218)
* Implement antenna bias control for Praline and update GPIO configurations
* Add GPIO power management functions and update board initialization for Praline
* Refactor power management functions for Praline and update GPIO configurations
* Update GPIO configurations for Praline and enable power control pins. AA_EN enabled
* Refactor GPIO configuration for Praline: update array size definitions and clean up comments
* Add P1 and P2 control functions for PRALINE
* Introduced P1_Function and P2_Function enums in ClockManager to manage multiplexer control.
* mplemented set_p1_control and set_p2_control methods for configuring P1 and P2 control pins based on specified functions.
* Updated clock_manager.hpp and clock_manager.cpp to include new functionality.
* Modified MAX2837 and MAX2839 initialization to conditionally configure GPIO based on PRALINE.
* Adjusted RFFC507x and RFFC507x_SPI initialization to include GPIO setup for PRALINE.
- Refactored RF path initialization to remove unnecessary GPIO setup.
- Updated board configuration for PRALINE to reflect new GPIO settings and pin configurations.
- Cleaned up FPGA bridge code by removing unused pin configuration functions.
- Adjusted SCU array size in pal_lld.h for PRALINE.
- Enhanced hackrf_gpio.hpp to define multiplexer control pins for PRALINE.
- Modified LED setup to accommodate active-low configuration for PRALINE.

* Refactor GPIO and power control functions

- Removed unused power control function declarations from board.h.
- Enhanced gpio.hpp with new pin setup functions and GPIO control structures for PRALINE.
- Consolidated multiplexer control pin definitions into gpio_control namespace.
- Moved power control function implementations to gpio.cpp, including detailed VAA power management logic.
- Updated power control functions to handle both PRALINE and HackRF R9 configurations.
- Cleaned up hackrf_gpio.hpp by removing redundant multiplexer control definitions.

* Refactor GPIO control for PRALINE: update MAX2831 and RFFC507x configurations, add new GPIO mappings

* Refactor GPIO configurations for PRALINE: update anti-aliasing filter pin mapping, enhance LED setup logic, and add placeholder GPIO entries.

* Refactor GPIO configurations for PRALINE: update LED mappings and remove unused anti-aliasing filter GPIO entry.
2026-06-11 13:24:42 +02:00

392 lines
12 KiB
C++

/*
* Copyright (C) 2014 Jared Boone, ShareBrained Technology, Inc.
*
* This file is part of PortaPack.
*
* 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 __GPIO_H__
#define __GPIO_H__
#include <array>
#include <cstddef>
#include <cstdint>
#include "ch.h"
#include "hal.h"
#include "pal.h"
struct PinConfig {
const uint32_t mode;
const uint32_t pd;
const uint32_t pu;
const uint32_t fast;
const uint32_t input;
const uint32_t ifilt;
constexpr operator uint16_t() const {
return (((~ifilt) & 1) << 7) | ((input & 1) << 6) | ((fast & 1) << 5) | (((~pu) & 1) << 4) | ((pd & 1) << 3) | ((mode & 7) << 0);
}
/*
constexpr operator uint32_t() {
return scu::sfs::mode::value(mode)
<< scu::sfs::epd::value(pd)
<< scu::sfs::epun::value(~pu)
<< scu::sfs::ehs::value(fast)
<< scu::sfs::ezi::value(input)
<< scu::sfs::zif::value(~ifilt)
;
}
*/
static constexpr PinConfig reset() {
return {.mode = 0, .pd = 0, .pu = 1, .fast = 0, .input = 0, .ifilt = 1};
}
static constexpr PinConfig floating(
const uint32_t mode) {
return {
.mode = mode,
.pd = 0,
.pu = 0,
.fast = 0,
.input = 0,
.ifilt = 1};
}
static constexpr PinConfig floating_input(
const uint32_t mode) {
return {
.mode = mode,
.pd = 0,
.pu = 0,
.fast = 0,
.input = 1,
.ifilt = 1};
}
static constexpr PinConfig floating_input_with_pull(
const uint32_t pull_direction,
const uint32_t mode) {
return {
.mode = mode,
.pd = (pull_direction == 0) ? 1U : 0U,
.pu = (pull_direction == 1) ? 1U : 0U,
.fast = 0,
.input = 1,
.ifilt = 1};
}
static constexpr PinConfig gpio_led(const uint32_t mode) {
return {.mode = mode, .pd = 0, .pu = 0, .fast = 0, .input = 0, .ifilt = 1};
}
static constexpr PinConfig gpio_inout_with_pull(
const uint32_t mode,
const uint32_t pull_direction) {
return {
.mode = mode,
.pd = (pull_direction == 0) ? 1U : 0U,
.pu = (pull_direction == 1) ? 1U : 0U,
.fast = 0,
.input = 1,
.ifilt = 1};
}
static constexpr PinConfig gpio_inout_with_pullup(const uint32_t mode) {
return gpio_inout_with_pull(mode, 1);
}
static constexpr PinConfig gpio_inout_with_pulldown(const uint32_t mode) {
return gpio_inout_with_pull(mode, 0);
}
static constexpr PinConfig gpio_out_with_pull(
const uint32_t mode,
const uint32_t pull_direction) {
return {
.mode = mode,
.pd = (pull_direction == 0) ? 1U : 0U,
.pu = (pull_direction == 1) ? 1U : 0U,
.fast = 0,
.input = 0,
.ifilt = 1};
}
static constexpr PinConfig gpio_out_with_pulldown(const uint32_t mode) {
return gpio_out_with_pull(mode, 0);
}
static constexpr PinConfig gpio_out_with_pullup(const uint32_t mode) {
return gpio_out_with_pull(mode, 1);
}
static constexpr PinConfig sgpio_in_fast(const uint32_t mode) {
return {.mode = mode, .pd = 0, .pu = 0, .fast = 0, .input = 1, .ifilt = 0};
}
static constexpr PinConfig sgpio_out_fast_with_pull(
const uint32_t mode,
const uint32_t pull_direction) {
return {
.mode = mode,
.pd = (pull_direction == 0) ? 1U : 0U,
.pu = (pull_direction == 1) ? 1U : 0U,
.fast = 1,
.input = 0,
.ifilt = 1};
}
static constexpr PinConfig sgpio_out_fast_with_pullup(const uint32_t mode) {
return sgpio_out_fast_with_pull(mode, 1);
}
static constexpr PinConfig sgpio_inout_fast(const uint32_t mode) {
return {.mode = mode, .pd = 0, .pu = 0, .fast = 1, .input = 1, .ifilt = 0};
}
static constexpr PinConfig i2c(const uint32_t mode) {
return {.mode = mode, .pd = 0, .pu = 0, .fast = 0, .input = 1, .ifilt = 1};
}
static constexpr PinConfig spifi_sck(const uint32_t mode) {
return {.mode = mode, .pd = 0, .pu = 0, .fast = 1, .input = 1, .ifilt = 0};
}
static constexpr PinConfig spifi_inout(const uint32_t mode) {
return {.mode = mode, .pd = 0, .pu = 0, .fast = 1, .input = 1, .ifilt = 0};
}
static constexpr PinConfig spifi_cs(const uint32_t mode) {
return {.mode = mode, .pd = 0, .pu = 0, .fast = 1, .input = 1, .ifilt = 0};
}
};
struct Pin {
// Pin() = delete;
// Pin(const Pin&) = delete;
// Pin(Pin&&) = delete;
constexpr Pin(
const uint8_t port,
const uint8_t pad)
: _pin_port{port},
_pin_pad{pad} {
}
void mode(const uint_fast16_t mode) const {
LPC_SCU->SFSP[_pin_port][_pin_pad] =
(LPC_SCU->SFSP[_pin_port][_pin_pad] & 0xfffffff8) | mode;
}
void configure(const PinConfig config) const {
LPC_SCU->SFSP[_pin_port][_pin_pad] = config;
}
uint8_t _pin_port;
uint8_t _pin_pad;
};
struct GPIO {
// GPIO() = delete;
// GPIO(const GPIO& gpio) = delete;
// GPIO(GPIO&&) = delete;
constexpr GPIO(
const Pin& pin,
const ioportid_t gpio_port,
const iopadid_t gpio_pad,
const uint16_t gpio_mode)
: _pin{pin},
_gpio_port{gpio_port},
_gpio_pad{gpio_pad},
_gpio_mode{gpio_mode} {
}
/*
constexpr GPIO(
const GPIO& gpio
) : _pin { gpio._pin },
_gpio_port { gpio._gpio_port },
_gpio_pad { gpio._gpio_pad },
_gpio_mode { gpio._gpio_mode }
{
}
*/
constexpr ioportid_t port() const {
return _gpio_port;
}
constexpr iopadid_t pad() const {
return _gpio_pad;
}
constexpr Pin pin() const {
return _pin;
}
void configure() const {
_pin.mode(_gpio_mode);
}
uint_fast16_t mode() const {
return _gpio_mode;
}
void set() const {
palSetPad(_gpio_port, _gpio_pad);
}
void clear() const {
palClearPad(_gpio_port, _gpio_pad);
}
void toggle() const {
palTogglePad(_gpio_port, _gpio_pad);
}
void output() const {
palSetPadMode(_gpio_port, _gpio_pad, PAL_MODE_OUTPUT_PUSHPULL);
}
void input() const {
palSetPadMode(_gpio_port, _gpio_pad, PAL_MODE_INPUT);
}
void write(const bool value) const {
palWritePad(_gpio_port, _gpio_pad, value);
}
bool read() const {
return palReadPad(_gpio_port, _gpio_pad);
}
bool operator!=(const GPIO& other) const {
return (port() != other.port()) || (pad() != other.pad());
}
const Pin _pin;
const ioportid_t _gpio_port;
const iopadid_t _gpio_pad;
const uint16_t _gpio_mode;
};
constexpr uint32_t boot_bit(const GPIO& pin, bool state) {
return (state ? 1UL : 0UL) << pin.pad();
}
inline void setup_pin(const scu_setup_t& pin_setup) {
LPC_SCU->SFSP[pin_setup.port][pin_setup.pin] = pin_setup.config;
}
template <size_t N>
inline void setup_gpios(const std::array<gpio_setup_t, N>& pins_setup) {
for (size_t i = 0; i < N; i++) {
LPC_GPIO->PIN[i] |= pins_setup[i].data;
LPC_GPIO->DIR[i] |= pins_setup[i].dir;
}
}
template <size_t N>
inline void setup_pins(const std::array<scu_setup_t, N>& pins_setup) {
for (const auto& pin_setup : pins_setup) {
setup_pin(pin_setup);
}
}
#ifdef PRALINE
namespace gpio_control {
struct PinMap {
uint8_t scu_port;
uint8_t scu_pin;
uint8_t gpio_port;
uint8_t gpio_pad;
};
constexpr PinMap map_p1_ctrl0{2, 10, 0, 14}; // SCU: 2, 10 | GPIO: 0, 14
constexpr PinMap map_p1_ctrl1{6, 8, 5, 16};
constexpr PinMap map_p1_ctrl2{6, 9, 3, 5};
constexpr PinMap map_p2_ctrl0{8, 3, 7, 3};
constexpr PinMap map_p2_ctrl1{8, 4, 7, 4};
constexpr PinMap map_trigger_out{2, 6, 5, 6};
constexpr PinMap map_trigger_in{13, 12, 6, 26};
constexpr PinMap map_rf5072_mix_en{9, 0, 4, 12};
constexpr PinMap map_aa_en{1, 14, 1, 7}; // Anti-Aliasing filter
// P1 Multiplexer control pins
constexpr Pin pin_p1_ctrl0{map_p1_ctrl0.scu_port, map_p1_ctrl0.scu_pin}; // SCU: P2_10
constexpr GPIO p1_ctrl0{pin_p1_ctrl0, map_p1_ctrl0.gpio_port, map_p1_ctrl0.gpio_pad, PAL_MODE_OUTPUT_PUSHPULL}; // GPIO[0]14
constexpr Pin pin_p1_ctrl1{map_p1_ctrl1.scu_port, map_p1_ctrl1.scu_pin}; // SCU: P6_8
constexpr GPIO p1_ctrl1{pin_p1_ctrl1, map_p1_ctrl1.gpio_port, map_p1_ctrl1.gpio_pad, PAL_MODE_OUTPUT_PUSHPULL}; // GPIO[5]16
constexpr Pin pin_p1_ctrl2{map_p1_ctrl2.scu_port, map_p1_ctrl2.scu_pin}; // SCU: P6_9
constexpr GPIO p1_ctrl2{pin_p1_ctrl2, map_p1_ctrl2.gpio_port, map_p1_ctrl2.gpio_pad, PAL_MODE_OUTPUT_PUSHPULL}; // GPIO[3]5
// P2 Multiplexer control pins
constexpr Pin pin_p2_ctrl0{map_p2_ctrl0.scu_port, map_p2_ctrl0.scu_pin}; // SCU: PE_3
constexpr GPIO p2_ctrl0{pin_p2_ctrl0, map_p2_ctrl0.gpio_port, map_p2_ctrl0.gpio_pad, PAL_MODE_OUTPUT_PUSHPULL}; // GPIO[7]3
constexpr Pin pin_p2_ctrl1{map_p2_ctrl1.scu_port, map_p2_ctrl1.scu_pin}; // SCU: PE_4
constexpr GPIO p2_ctrl1{pin_p2_ctrl1, map_p2_ctrl1.gpio_port, map_p2_ctrl1.gpio_pad, PAL_MODE_OUTPUT_PUSHPULL}; // GPIO[7]4
// Trigger pins
constexpr Pin trigger_out_pin{map_trigger_out.scu_port, map_trigger_out.scu_pin}; // SCU: P2_6
constexpr GPIO trigger_out{trigger_out_pin, map_trigger_out.gpio_port, map_trigger_out.gpio_pad, PAL_MODE_OUTPUT_PUSHPULL}; // GPIO[5]6
constexpr Pin trigger_in_pin{map_trigger_in.scu_port, map_trigger_in.scu_pin}; // SCU: PD_12
constexpr GPIO trigger_in{trigger_in_pin, map_trigger_in.gpio_port, map_trigger_in.gpio_pad, PAL_MODE_INPUT}; // GPIO[6]26
// RF507x
constexpr Pin pin_rf5072_mix_en{map_rf5072_mix_en.scu_port, map_rf5072_mix_en.scu_pin};
constexpr GPIO rf5072_mix_en{pin_rf5072_mix_en, map_rf5072_mix_en.gpio_port, map_rf5072_mix_en.gpio_pad, 0};
// Anti-Aliasing filter
constexpr Pin pin_aa_en{map_aa_en.scu_port, map_aa_en.scu_pin};
constexpr GPIO aa_en{pin_aa_en, map_aa_en.gpio_port, map_aa_en.gpio_pad, 0};
} // namespace gpio_control
#endif
namespace power_control {
void vaa_power_on(void);
void vaa_power_off(void);
#ifdef PRALINE
void aux_power_on(void);
void aux_power_off(void);
#endif
void core_power_on(void);
void core_power_off(void);
static const motocon_pwm_resources_t motocon_pwm_resources = {
.base = {.clk = &LPC_CGU->BASE_APB1_CLK, .stat = &LPC_CCU1->BASE_STAT, .stat_mask = (1 << 1)},
.branch = {.cfg = &LPC_CCU1->CLK_APB1_MOTOCON_PWM_CFG, .stat = &LPC_CCU1->CLK_APB1_MOTOCON_PWM_STAT},
.reset = {.output_index = 38},
};
static const scu_setup_t pin_setup_vaa_enablex_pwm = {5, 0, scu_config_normal_drive_t{.mode = 1, .epd = 0, .epun = 1, .ehs = 0, .ezi = 0, .zif = 0}};
static const scu_setup_t pin_setup_vaa_enablex_gpio_og = {5, 0, scu_config_normal_drive_t{.mode = 0, .epd = 0, .epun = 1, .ehs = 0, .ezi = 0, .zif = 0}};
static const scu_setup_t pin_setup_vaa_enablex_gpio_r9 = {6, 10, scu_config_normal_drive_t{.mode = 0, .epd = 0, .epun = 1, .ehs = 0, .ezi = 0, .zif = 0}};
} // namespace power_control
#endif /*__GPIO_H__*/