/* * 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 #include #include #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 inline void setup_gpios(const std::array& 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 inline void setup_pins(const std::array& 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__*/