diff --git a/dependencies.yaml b/dependencies.yaml index 6cf44cb06f..a3ba48800d 100644 --- a/dependencies.yaml +++ b/dependencies.yaml @@ -60,7 +60,7 @@ libevse-security: # OCPP libocpp: git: https://github.com/EVerest/libocpp.git - git_tag: v0.16.2 + git_tag: 3fef09231f0033a4af5d0af97d35851ecc00d399 cmake_condition: "EVEREST_DEPENDENCY_ENABLED_LIBOCPP" # Josev Josev: diff --git a/interfaces/ev_board_support.yaml b/interfaces/ev_board_support.yaml index 33f551c976..b1dfb4e819 100644 --- a/interfaces/ev_board_support.yaml +++ b/interfaces/ev_board_support.yaml @@ -15,8 +15,7 @@ cmds: $ref: /ev_board_support#/EvCpState allow_power_on: description: >- - Sets allow_power_on flag. If false, contactor must never be switched - on. Onyly for dc charging + Sets allow_power_on flag. If false, contactor must never be switched on. arguments: value: description: 'True: allow power on, false: do not allow power on.' diff --git a/modules/EvManager/main/car_simulation.cpp b/modules/EvManager/main/car_simulation.cpp index 79c041e926..a0de3f33b8 100644 --- a/modules/EvManager/main/car_simulation.cpp +++ b/modules/EvManager/main/car_simulation.cpp @@ -38,8 +38,10 @@ void CarSimulation::state_machine() { // do not draw power if EVSE paused by stopping PWM if (sim_data.pwm_duty_cycle > 7.0 && sim_data.pwm_duty_cycle < 97.0) { r_ev_board_support->call_set_cp_state(EvCpState::C); + r_ev_board_support->call_allow_power_on(true); } else { r_ev_board_support->call_set_cp_state(EvCpState::B); + r_ev_board_support->call_allow_power_on(false); } } break; @@ -49,6 +51,7 @@ void CarSimulation::state_machine() { // Also draw power if EVSE stopped PWM - this is a break the rules simulator->mode to test the charging // implementation! r_ev_board_support->call_set_cp_state(EvCpState::C); + r_ev_board_support->call_allow_power_on(true); } break; @@ -72,6 +75,7 @@ void CarSimulation::state_machine() { case SimState::ISO_CHARGING_REGULATED: if (state_has_changed) { r_ev_board_support->call_set_cp_state(EvCpState::C); + r_ev_board_support->call_allow_power_on(true); } break; case SimState::BCB_TOGGLE: diff --git a/modules/EvManager/main/car_simulatorImpl.cpp b/modules/EvManager/main/car_simulatorImpl.cpp index 32bea566d7..e42ed07809 100644 --- a/modules/EvManager/main/car_simulatorImpl.cpp +++ b/modules/EvManager/main/car_simulatorImpl.cpp @@ -11,13 +11,13 @@ namespace module::main { void car_simulatorImpl::init() { loop_interval_ms = constants::DEFAULT_LOOP_INTERVAL_MS; register_all_commands(); - subscribe_to_external_mqtt(); subscribe_to_variables_on_init(); std::thread(&car_simulatorImpl::run, this).detach(); } void car_simulatorImpl::ready() { + subscribe_to_external_mqtt(); car_simulation = std::make_unique(mod->r_ev_board_support, mod->r_ev, mod->r_slac); diff --git a/modules/OCPP/main/ocpp_1_6_charge_pointImpl.cpp b/modules/OCPP/main/ocpp_1_6_charge_pointImpl.cpp index 696e79d3de..548a3e1f32 100644 --- a/modules/OCPP/main/ocpp_1_6_charge_pointImpl.cpp +++ b/modules/OCPP/main/ocpp_1_6_charge_pointImpl.cpp @@ -12,7 +12,7 @@ void ocpp_1_6_charge_pointImpl::ready() { } bool ocpp_1_6_charge_pointImpl::handle_stop() { - std::lock_guard(this->m); + std::lock_guard lock(this->m); mod->charging_schedules_timer->stop(); bool success = mod->charge_point->stop(); if (success) { @@ -21,7 +21,7 @@ bool ocpp_1_6_charge_pointImpl::handle_stop() { return success; } bool ocpp_1_6_charge_pointImpl::handle_restart() { - std::lock_guard(this->m); + std::lock_guard lock(this->m); mod->charging_schedules_timer->interval(std::chrono::seconds(this->mod->config.PublishChargingScheduleIntervalS)); bool success = mod->charge_point->restart(); if (success) { diff --git a/modules/OCPP/ocpp_generic/ocppImpl.cpp b/modules/OCPP/ocpp_generic/ocppImpl.cpp index 47198d37fc..ca8d57f07f 100644 --- a/modules/OCPP/ocpp_generic/ocppImpl.cpp +++ b/modules/OCPP/ocpp_generic/ocppImpl.cpp @@ -102,7 +102,7 @@ void ocppImpl::ready() { } bool ocppImpl::handle_stop() { - std::lock_guard(this->chargepoint_state_mutex); + std::lock_guard lock(this->chargepoint_state_mutex); mod->charging_schedules_timer->stop(); bool success = mod->charge_point->stop(); if (success) { @@ -112,7 +112,7 @@ bool ocppImpl::handle_stop() { } bool ocppImpl::handle_restart() { - std::lock_guard(this->chargepoint_state_mutex); + std::lock_guard lock(this->chargepoint_state_mutex); mod->charging_schedules_timer->interval(std::chrono::seconds(this->mod->config.PublishChargingScheduleIntervalS)); bool success = mod->charge_point->restart(); if (success) { diff --git a/modules/OCPP201/conversions.cpp b/modules/OCPP201/conversions.cpp index 4cabf6620d..95a22d3ce3 100644 --- a/modules/OCPP201/conversions.cpp +++ b/modules/OCPP201/conversions.cpp @@ -156,6 +156,7 @@ to_ocpp_meter_value(const types::powermeter::Powermeter& power_meter, if (power_meter.energy_Wh_import_signed.has_value()) { sampled_value = to_ocpp_sampled_value(reading_context, ocpp::v201::MeasurandEnum::Energy_Active_Import_Register, "Wh", std::nullopt); + sampled_value.value = power_meter.energy_Wh_import.total; const auto& energy_Wh_import_signed = power_meter.energy_Wh_import_signed.value(); if (energy_Wh_import_signed.total.has_value()) { sampled_value.signedMeterValue = to_ocpp_signed_meter_value(energy_Wh_import_signed.total.value()); diff --git a/modules/PhyVersoBSP/BUILD.bazel b/modules/PhyVersoBSP/BUILD.bazel index 37976252a7..11e28279a5 100644 --- a/modules/PhyVersoBSP/BUILD.bazel +++ b/modules/PhyVersoBSP/BUILD.bazel @@ -15,6 +15,7 @@ IMPLS = [ cc_everest_module( name = "PhyVersoBSP", deps = [ + "//modules/PhyVersoBSP/phyverso_gpio", "//modules/PhyVersoBSP/phyverso_mcu_comms", ], impls = IMPLS, diff --git a/modules/PhyVersoBSP/CMakeLists.txt b/modules/PhyVersoBSP/CMakeLists.txt index b6304c4fc0..318a7febe6 100644 --- a/modules/PhyVersoBSP/CMakeLists.txt +++ b/modules/PhyVersoBSP/CMakeLists.txt @@ -11,6 +11,7 @@ ev_setup_cpp_module() # insert your custom targets and additional config variables here add_subdirectory(phyverso_mcu_comms) add_subdirectory(phyverso_cli) +add_subdirectory(phyverso_gpio) target_include_directories(${MODULE_NAME} PRIVATE @@ -19,13 +20,16 @@ target_include_directories(${MODULE_NAME} "phyverso_mcu_comms/nanopb" "phyverso_mcu_comms/protobuf" "phyverso_config" + "phyverso_gpio" ) target_link_libraries(${MODULE_NAME} PRIVATE Pal::Sigslot + everest::gpio phyverso_mcu_comms phyverso_config + phyverso_gpio ) # ev@bcc62523-e22b-41d7-ba2f-825b493a3c97:v1 diff --git a/modules/PhyVersoBSP/PhyVersoBSP.cpp b/modules/PhyVersoBSP/PhyVersoBSP.cpp index 0cce9bb924..2d331acbc5 100644 --- a/modules/PhyVersoBSP/PhyVersoBSP.cpp +++ b/modules/PhyVersoBSP/PhyVersoBSP.cpp @@ -16,6 +16,12 @@ void PhyVersoBSP::init() { return; } + // init user gpios + if (not gpio.init_gpios()) { + EVLOG_error << "Could not initialize user GPIOs. Terminating."; + return; + } + invoke_init(*p_connector_1); invoke_init(*p_connector_2); invoke_init(*p_rcd_1); @@ -26,10 +32,6 @@ void PhyVersoBSP::init() { invoke_init(*p_system_specific_data_1); invoke_init(*p_system_specific_data_2); - // pass PhyVersoBSP module config values to evConfig (everest/standalone json config bridge to evSerial that is - // talking to MCU) - everest_config_to_verso_config(); - serial.signal_config_request.connect([&]() { serial.send_config(); EVLOG_info << "Sent config packet to MCU"; @@ -38,6 +40,7 @@ void PhyVersoBSP::init() { void PhyVersoBSP::ready() { serial.run(); + gpio.run(); invoke_ready(*p_connector_1); invoke_ready(*p_connector_2); @@ -61,13 +64,20 @@ void PhyVersoBSP::ready() { // fills evConfig bridge with config values from manifest/everest config void PhyVersoBSP::everest_config_to_verso_config() { - // TODO: fill evConfig Conf struct with this modules conf structure values verso_config.conf.serial_port = this->config.serial_port; verso_config.conf.baud_rate = this->config.baud_rate; verso_config.conf.reset_gpio_bank = this->config.reset_gpio_bank; verso_config.conf.reset_gpio_pin = this->config.reset_gpio_pin; verso_config.conf.conn1_motor_lock_type = this->config.conn1_motor_lock_type; verso_config.conf.conn2_motor_lock_type = this->config.conn2_motor_lock_type; + verso_config.conf.conn1_gpio_stop_button_enabled = this->config.conn1_gpio_stop_button_enabled; + verso_config.conf.conn1_gpio_stop_button_bank = this->config.conn1_gpio_stop_button_bank; + verso_config.conf.conn1_gpio_stop_button_pin = this->config.conn1_gpio_stop_button_pin; + verso_config.conf.conn1_gpio_stop_button_invert = this->config.conn1_gpio_stop_button_invert; + verso_config.conf.conn2_gpio_stop_button_enabled = this->config.conn2_gpio_stop_button_enabled; + verso_config.conf.conn2_gpio_stop_button_bank = this->config.conn2_gpio_stop_button_bank; + verso_config.conf.conn2_gpio_stop_button_pin = this->config.conn2_gpio_stop_button_pin; + verso_config.conf.conn2_gpio_stop_button_invert = this->config.conn2_gpio_stop_button_invert; } } // namespace module diff --git a/modules/PhyVersoBSP/PhyVersoBSP.hpp b/modules/PhyVersoBSP/PhyVersoBSP.hpp index 4c928e1c8e..aef1257092 100644 --- a/modules/PhyVersoBSP/PhyVersoBSP.hpp +++ b/modules/PhyVersoBSP/PhyVersoBSP.hpp @@ -19,6 +19,7 @@ // ev@4bf81b14-a215-475c-a1d3-0a484ae48918:v1 // insert your custom include headers here +#include "phyverso_gpio/evGpio.h" #include "phyverso_mcu_comms/evSerial.h" // ev@4bf81b14-a215-475c-a1d3-0a484ae48918:v1 @@ -52,6 +53,14 @@ struct Conf { int reset_gpio_pin; int conn1_motor_lock_type; int conn2_motor_lock_type; + bool conn1_gpio_stop_button_enabled; + std::string conn1_gpio_stop_button_bank; + int conn1_gpio_stop_button_pin; + bool conn1_gpio_stop_button_invert; + bool conn2_gpio_stop_button_enabled; + std::string conn2_gpio_stop_button_bank; + int conn2_gpio_stop_button_pin; + bool conn2_gpio_stop_button_invert; }; class PhyVersoBSP : public Everest::ModuleBase { @@ -78,7 +87,8 @@ class PhyVersoBSP : public Everest::ModuleBase { p_system_specific_data_1(std::move(p_system_specific_data_1)), p_system_specific_data_2(std::move(p_system_specific_data_2)), config(config), - serial(verso_config){}; + serial(verso_config), + gpio(verso_config){}; Everest::MqttProvider& mqtt; Everest::TelemetryProvider& telemetry; @@ -96,6 +106,8 @@ class PhyVersoBSP : public Everest::ModuleBase { // ev@1fce4c5e-0ab8-41bb-90f7-14277703d2ac:v1 // insert your public definitions here evSerial serial; + evConfig verso_config; + evGpio gpio; // ev@1fce4c5e-0ab8-41bb-90f7-14277703d2ac:v1 protected: @@ -110,7 +122,6 @@ class PhyVersoBSP : public Everest::ModuleBase { // ev@211cfdbe-f69a-4cd6-a4ec-f8aaa3d1b6c8:v1 // insert your private definitions here - evConfig verso_config; void everest_config_to_verso_config(); // ev@211cfdbe-f69a-4cd6-a4ec-f8aaa3d1b6c8:v1 }; diff --git a/modules/PhyVersoBSP/connector_1/evse_board_supportImpl.cpp b/modules/PhyVersoBSP/connector_1/evse_board_supportImpl.cpp index c07cf77fac..77a1c468d9 100644 --- a/modules/PhyVersoBSP/connector_1/evse_board_supportImpl.cpp +++ b/modules/PhyVersoBSP/connector_1/evse_board_supportImpl.cpp @@ -54,6 +54,16 @@ void evse_board_supportImpl::init() { } last_pp_state = s; }); + + mod->gpio.signal_stop_button_state.connect([this](int connector, bool state) { + if (connector == 1 && (state != last_stop_button_state)) { + types::evse_manager::StopTransactionRequest request; + request.reason = types::evse_manager::StopTransactionReason::Local; + this->publish_request_stop_transaction(request); + EVLOG_info << "[1] Request stop button state: " << (state ? "PUSHED" : "RELEASED"); + last_stop_button_state = state; + } + }); } void evse_board_supportImpl::ready() { diff --git a/modules/PhyVersoBSP/connector_1/evse_board_supportImpl.hpp b/modules/PhyVersoBSP/connector_1/evse_board_supportImpl.hpp index 79bfe7c206..0ba87f7aa2 100644 --- a/modules/PhyVersoBSP/connector_1/evse_board_supportImpl.hpp +++ b/modules/PhyVersoBSP/connector_1/evse_board_supportImpl.hpp @@ -15,6 +15,7 @@ // ev@75ac1216-19eb-4182-a85c-820f1fc2c091:v1 // insert your custom include headers here #include "board_support_common.hpp" +#include "evGpio.h" // ev@75ac1216-19eb-4182-a85c-820f1fc2c091:v1 namespace module { @@ -60,6 +61,7 @@ class evse_board_supportImpl : public evse_board_supportImplBase { std::mutex caps_mutex; CpState last_cp_state; PpState last_pp_state; ///< The last pp state received from the MCU. + bool last_stop_button_state; // ev@3370e4dd-95f4-47a9-aaec-ea76f34a66c9:v1 }; diff --git a/modules/PhyVersoBSP/connector_2/evse_board_supportImpl.cpp b/modules/PhyVersoBSP/connector_2/evse_board_supportImpl.cpp index 35fe7efec3..f5637a32a4 100644 --- a/modules/PhyVersoBSP/connector_2/evse_board_supportImpl.cpp +++ b/modules/PhyVersoBSP/connector_2/evse_board_supportImpl.cpp @@ -54,6 +54,16 @@ void evse_board_supportImpl::init() { } last_pp_state = s; }); + + mod->gpio.signal_stop_button_state.connect([this](int connector, bool state) { + if (connector == 2 && (state != last_stop_button_state)) { + types::evse_manager::StopTransactionRequest request; + request.reason = types::evse_manager::StopTransactionReason::Local; + this->publish_request_stop_transaction(request); + EVLOG_info << "[2] Request stop button state: " << (state ? "PUSHED" : "RELEASED"); + last_stop_button_state = state; + } + }); } void evse_board_supportImpl::ready() { diff --git a/modules/PhyVersoBSP/connector_2/evse_board_supportImpl.hpp b/modules/PhyVersoBSP/connector_2/evse_board_supportImpl.hpp index 8296511fea..fde416dabe 100644 --- a/modules/PhyVersoBSP/connector_2/evse_board_supportImpl.hpp +++ b/modules/PhyVersoBSP/connector_2/evse_board_supportImpl.hpp @@ -60,6 +60,7 @@ class evse_board_supportImpl : public evse_board_supportImplBase { std::mutex caps_mutex; CpState last_cp_state; PpState last_pp_state; ///< The last pp state received from the MCU. + bool last_stop_button_state; // ev@3370e4dd-95f4-47a9-aaec-ea76f34a66c9:v1 }; diff --git a/modules/PhyVersoBSP/manifest.yaml b/modules/PhyVersoBSP/manifest.yaml index b81f48c3db..2688df8113 100644 --- a/modules/PhyVersoBSP/manifest.yaml +++ b/modules/PhyVersoBSP/manifest.yaml @@ -140,6 +140,38 @@ config: description: Connector 2 motor lock type; 1 == Hella Style time-based lock, 2 == Valeo potentiometer feedback based type: integer default: 2 + conn1_gpio_stop_button_enabled: + description: Set to true to enable external charging stop button for connector 1 on a GPIO connected to the SOM + type: boolean + default: false + conn1_gpio_stop_button_bank: + description: GPIO peripheral bank for connector 1 stop button + type: string + default: gpiochip1 + conn1_gpio_stop_button_pin: + description: GPIO peripheral pin for connector 1 stop button + type: integer + default: 36 + conn1_gpio_stop_button_invert: + description: Set to true to invert pin logic + type: boolean + default: false + conn2_gpio_stop_button_enabled: + description: Set to true to enable external charging stop button for connector 2 on a GPIO connected to the SOM + type: boolean + default: false + conn2_gpio_stop_button_bank: + description: GPIO peripheral bank for connector 2 stop button + type: string + default: gpiochip1 + conn2_gpio_stop_button_pin: + description: GPIO peripheral pin for connector 2 stop button + type: integer + default: 37 + conn2_gpio_stop_button_invert: + description: Set to true to invert pin logic + type: boolean + default: false provides: connector_1: interface: evse_board_support diff --git a/modules/PhyVersoBSP/phyverso_gpio/BUILD.bazel b/modules/PhyVersoBSP/phyverso_gpio/BUILD.bazel new file mode 100644 index 0000000000..b96898e9ce --- /dev/null +++ b/modules/PhyVersoBSP/phyverso_gpio/BUILD.bazel @@ -0,0 +1,18 @@ +cc_library( + name = "phyverso_gpio", + deps = [ + "//modules/PhyVersoBSP/phyverso_mcu_comms", + "//lib/staging/gpio", + "@sigslot//:sigslot", + ], + srcs = glob([ + "**/*.h", + "**/*.c", + "**/*.cpp", + ]), + visibility = ["//visibility:public"], + includes = [ + ".", + ], + copts = ["-std=c++17"], +) \ No newline at end of file diff --git a/modules/PhyVersoBSP/phyverso_gpio/CMakeLists.txt b/modules/PhyVersoBSP/phyverso_gpio/CMakeLists.txt new file mode 100644 index 0000000000..2166c4a916 --- /dev/null +++ b/modules/PhyVersoBSP/phyverso_gpio/CMakeLists.txt @@ -0,0 +1,31 @@ +cmake_minimum_required(VERSION 3.10) + +# set the project name +project(phyverso_gpio VERSION 0.1) +# specify the C++ standard +set(CMAKE_CXX_STANDARD 17) +set(CMAKE_CXX_STANDARD_REQUIRED True) + +add_library(phyverso_gpio STATIC) +target_sources(phyverso_gpio + PRIVATE + evGpio.cpp +) + +target_include_directories(phyverso_gpio + PUBLIC + "${PROJECT_BINARY_DIR}" + "../phyverso_mcu_comms" +) + +target_link_libraries(phyverso_gpio + PUBLIC + date::date-tz + everest::nanopb + PRIVATE + Pal::Sigslot + everest::framework + everest::gpio + phyverso_config + fmt::fmt +) diff --git a/modules/PhyVersoBSP/phyverso_gpio/evGpio.cpp b/modules/PhyVersoBSP/phyverso_gpio/evGpio.cpp new file mode 100644 index 0000000000..58c59e2842 --- /dev/null +++ b/modules/PhyVersoBSP/phyverso_gpio/evGpio.cpp @@ -0,0 +1,89 @@ +// SPDX-License-Identifier: Apache-2.0 +// Copyright Pionix GmbH and Contributors to EVerest + +#include "evGpio.h" +#include +#include + +evGpio::evGpio(evConfig& _verso_config) : verso_config(_verso_config) { +} + +evGpio::~evGpio() { + // TODO: deinit gpios? +} + +bool evGpio::init_gpios() { + push_buttons[CONN1_PB_STOP].set_enabled(verso_config.conf.conn1_gpio_stop_button_enabled); + push_buttons[CONN2_PB_STOP].set_enabled(verso_config.conf.conn2_gpio_stop_button_enabled); + + if (push_buttons[CONN1_PB_STOP].get_enabled()) { + Everest::GpioSettings settings; + settings.chip_name = verso_config.conf.conn1_gpio_stop_button_bank; + settings.line_number = verso_config.conf.conn1_gpio_stop_button_pin; + settings.inverted = verso_config.conf.conn1_gpio_stop_button_invert; + push_buttons[CONN1_PB_STOP].init_gpio(settings); + if (not push_buttons[CONN1_PB_STOP].ready()) { + EVLOG_error << "Could not initialize Connector 1 push button"; + return false; + } + } + + if (push_buttons[CONN2_PB_STOP].get_enabled()) { + Everest::GpioSettings settings; + settings.chip_name = verso_config.conf.conn2_gpio_stop_button_bank; + settings.line_number = verso_config.conf.conn2_gpio_stop_button_pin; + settings.inverted = verso_config.conf.conn2_gpio_stop_button_invert; + push_buttons[CONN2_PB_STOP].init_gpio(settings); + if (not push_buttons[CONN2_PB_STOP].ready()) { + EVLOG_error << "Could not initialize Connector 2 push button"; + return false; + } + } + + return true; +} + +void evGpio::run() { + poll_thread_handle = std::thread(&evGpio::poll_thread, this); +} + +void evGpio::poll_thread() { + while (true) { + if (poll_thread_handle.shouldExit()) + break; + + // iterate over button list + for (int i = 0; i < NUM_PB_NAMES; i++) { + PushButton& button = push_buttons[i]; + if (not button.get_enabled()) + continue; + + // check if GPIO is still usable + if (not button.ready()) { + EVLOG_error << fmt::format("Push button {} not ready. Stopping thread.", i + 1); + goto cleanup; // break out of polling loop immediatly and terminate thread + } + + button.read(); + + if (button.get_state_changed()) { + // select which signal to send depending on button name + switch (i) { + case CONN1_PB_STOP: + signal_stop_button_state(1, button.get_state()); + break; + case CONN2_PB_STOP: + signal_stop_button_state(2, button.get_state()); + break; + default: + break; + } + } + } + + // sleep the nominal polling interval time + std::this_thread::sleep_for(std::chrono::milliseconds(poll_time_ms)); + } + +cleanup : {} +} \ No newline at end of file diff --git a/modules/PhyVersoBSP/phyverso_gpio/evGpio.h b/modules/PhyVersoBSP/phyverso_gpio/evGpio.h new file mode 100644 index 0000000000..081e49ad1e --- /dev/null +++ b/modules/PhyVersoBSP/phyverso_gpio/evGpio.h @@ -0,0 +1,103 @@ +// SPDX-License-Identifier: Apache-2.0 +// Copyright Pionix GmbH and Contributors to EVerest + +#ifndef PHYVERSO_GPIO_EV_GPIO_H +#define PHYVERSO_GPIO_EV_GPIO_H + +#include "evConfig.h" +#include +#include +#include +#include +#include +#include +#include +#include + +class evGpio { + +public: + evGpio(evConfig& _verso_config); + ~evGpio(); + + void poll_thread(); + void run(); + bool init_gpios(); + + // Read thread for serial port + Everest::Thread poll_thread_handle; + + // Signals to communicate state changes to other modules + sigslot::signal signal_stop_button_state; + + // List of used buttons/gpios + enum PushButtonName { + CONN1_PB_STOP, + CONN2_PB_STOP, + NUM_PB_NAMES, + }; + +private: + static constexpr uint32_t poll_time_ms = 10; //< time in ms between polled gpio input readings/debouncing + + // structure to encapsulate Everest::Gpio and corresponding debounce shift register + // for now we will use 16 consecutive 0's or 1's to correspond to a stable input level (could be 8/32/64 aswell, + // just needs adjusting in bitmasks and bitwidths) + struct PushButton { + void init_gpio(const Everest::GpioSettings& settings) { + gpio.open(settings); + gpio.set_input(); + }; + + bool ready() { + return gpio.is_ready(); + }; + + void read() { + debounce_shift_reg = (debounce_shift_reg << 1) | gpio.read(); + switch (debounce_shift_reg) { + case 0xFFFF: + state = true; + break; + case 0x0000: + state = false; + break; + default: + break; + } + + state_changed = (last_state != state); + + last_state = state; + }; + + bool get_state() { + return state; + }; + + bool get_state_changed() { + return state_changed; + }; + + void set_enabled(bool _enabled) { + enabled = _enabled; + }; + + bool get_enabled() { + return enabled; + }; + + private: + Everest::Gpio gpio; + bool state, last_state, state_changed = false; + bool enabled = false; + uint16_t debounce_shift_reg = 0; + }; + + PushButton push_buttons[NUM_PB_NAMES]; + + // config bridge (filled by json or everest module config) + evConfig& verso_config; +}; + +#endif // PHYVERSO_GPIO_EV_GPIO_H diff --git a/modules/PhyVersoBSP/phyverso_mcu_comms/evConfig.h b/modules/PhyVersoBSP/phyverso_mcu_comms/evConfig.h index 9a43c5b21c..215d6f4cb3 100644 --- a/modules/PhyVersoBSP/phyverso_mcu_comms/evConfig.h +++ b/modules/PhyVersoBSP/phyverso_mcu_comms/evConfig.h @@ -43,6 +43,14 @@ class evConfig { int reset_gpio_pin = 23; int conn1_motor_lock_type = 2; int conn2_motor_lock_type = 2; + bool conn1_gpio_stop_button_enabled = false; + std::string conn1_gpio_stop_button_bank = "gpiochip1"; + int conn1_gpio_stop_button_pin = 36; + bool conn1_gpio_stop_button_invert = false; + bool conn2_gpio_stop_button_enabled = false; + std::string conn2_gpio_stop_button_bank = "gpiochip1"; + int conn2_gpio_stop_button_pin = 37; + bool conn2_gpio_stop_button_invert = false; } conf; evConfig();