From bd4ca5032280fd791a8e6594e9e3ea3ff759e476 Mon Sep 17 00:00:00 2001 From: Cornelius Claussen Date: Thu, 13 Jun 2024 11:01:09 +0200 Subject: [PATCH 1/3] uMWC: adapt driver to new firmware Signed-off-by: Cornelius Claussen --- modules/MicroMegaWattBSP/MicroMegaWattBSP.cpp | 16 +- modules/MicroMegaWattBSP/MicroMegaWattBSP.hpp | 1 + .../board_support/evse_board_supportImpl.cpp | 110 +++++----- .../board_support/evse_board_supportImpl.hpp | 3 + .../dc_supply/power_supply_DCImpl.cpp | 18 +- modules/MicroMegaWattBSP/manifest.yaml | 17 +- .../powermeter/powermeterImpl.cpp | 40 +--- .../umwc_comms/CMakeLists.txt | 1 + .../MicroMegaWattBSP/umwc_comms/evSerial.cpp | 30 ++- .../MicroMegaWattBSP/umwc_comms/evSerial.h | 4 +- .../umwc_comms/protobuf/umwc.pb.c | 7 +- .../umwc_comms/protobuf/umwc.pb.h | 191 +++++++----------- .../umwc_comms/protobuf/umwc.proto | 24 +-- .../umwc_fwupdate/CMakeLists.txt | 2 +- .../MicroMegaWattBSP/umwc_fwupdate/main.cpp | 10 + 15 files changed, 208 insertions(+), 266 deletions(-) diff --git a/modules/MicroMegaWattBSP/MicroMegaWattBSP.cpp b/modules/MicroMegaWattBSP/MicroMegaWattBSP.cpp index b0848ce68..68b9c2ff8 100644 --- a/modules/MicroMegaWattBSP/MicroMegaWattBSP.cpp +++ b/modules/MicroMegaWattBSP/MicroMegaWattBSP.cpp @@ -11,7 +11,6 @@ void MicroMegaWattBSP::init() { return; } - invoke_init(*p_powermeter); invoke_init(*p_board_support); invoke_init(*p_dc_supply); } @@ -19,23 +18,24 @@ void MicroMegaWattBSP::init() { void MicroMegaWattBSP::ready() { serial.run(); - if (!serial.reset(config.reset_gpio)) { - EVLOG_error << "uMWC reset not successful."; + if (not config.reset_gpio_chip.empty()) { + EVLOG_info << "Perform HW reset with gpio chip " << config.reset_gpio_chip << " line " << config.reset_gpio; + if (!serial.reset(config.reset_gpio_chip, config.reset_gpio)) { + EVLOG_error << "uMWC reset not successful."; + } } - serial.signalSpuriousReset.connect([this]() { EVLOG_error << "uMWC uC spurious reset!"; }); - serial.signalConnectionTimeout.connect([this]() { EVLOG_error << "uMWC UART timeout!"; }); + serial.signalSpuriousReset.connect([this]() { EVLOG_warning << "uMWC uC spurious reset!"; }); + serial.signalConnectionTimeout.connect([this]() { EVLOG_warning << "uMWC UART timeout!"; }); serial.signalTelemetry.connect([this](Telemetry t) { mqtt.publish("everest_external/umwc/cp_hi", t.cp_hi); mqtt.publish("everest_external/umwc/cp_lo", t.cp_lo); mqtt.publish("everest_external/umwc/pwm_dc", t.pwm_dc); mqtt.publish("everest_external/umwc/relais_on", t.relais_on); + mqtt.publish("everest_external/umwc/output_voltage", t.voltage); }); - serial.signalPowerMeter.connect( - [this](PowerMeter p) { mqtt.publish("everest_external/umwc/output_voltage", p.voltage); }); - invoke_ready(*p_powermeter); invoke_ready(*p_board_support); invoke_ready(*p_dc_supply); diff --git a/modules/MicroMegaWattBSP/MicroMegaWattBSP.hpp b/modules/MicroMegaWattBSP/MicroMegaWattBSP.hpp index d6ea3c4cf..bbd2b694f 100644 --- a/modules/MicroMegaWattBSP/MicroMegaWattBSP.hpp +++ b/modules/MicroMegaWattBSP/MicroMegaWattBSP.hpp @@ -25,6 +25,7 @@ namespace module { struct Conf { std::string serial_port; int baud_rate; + std::string reset_gpio_chip; int reset_gpio; int dc_max_voltage; }; diff --git a/modules/MicroMegaWattBSP/board_support/evse_board_supportImpl.cpp b/modules/MicroMegaWattBSP/board_support/evse_board_supportImpl.cpp index f1a394901..769980db1 100644 --- a/modules/MicroMegaWattBSP/board_support/evse_board_supportImpl.cpp +++ b/modules/MicroMegaWattBSP/board_support/evse_board_supportImpl.cpp @@ -5,73 +5,85 @@ namespace module { namespace board_support { - -/* - - -static types::board_support::Event cast_event_type(const Event& e) { -switch (e.type) { -case Event_InterfaceEvent_CAR_PLUGGED_IN: - return types::board_support::Event::CarPluggedIn; -case Event_InterfaceEvent_CAR_REQUESTED_POWER: - return types::board_support::Event::CarRequestedPower; -case Event_InterfaceEvent_POWER_ON: - return types::board_support::Event::PowerOn; -case Event_InterfaceEvent_POWER_OFF: - return types::board_support::Event::PowerOff; -case Event_InterfaceEvent_CAR_REQUESTED_STOP_POWER: - return types::board_support::Event::CarRequestedStopPower; -case Event_InterfaceEvent_CAR_UNPLUGGED: - return types::board_support::Event::CarUnplugged; -case Event_InterfaceEvent_ERROR_E: - return types::board_support::Event::ErrorE; -case Event_InterfaceEvent_ERROR_DF: - return types::board_support::Event::ErrorDF; -case Event_InterfaceEvent_ERROR_RELAIS: - return types::board_support::Event::ErrorRelais; -case Event_InterfaceEvent_ERROR_RCD: - return types::board_support::Event::ErrorRCD; -case Event_InterfaceEvent_ERROR_VENTILATION_NOT_AVAILABLE: - return types::board_support::Event::ErrorVentilationNotAvailable; -case Event_InterfaceEvent_ERROR_OVER_CURRENT: - return types::board_support::Event::ErrorOverCurrent; -case Event_InterfaceEvent_ENTER_BCD: - return types::board_support::Event::EFtoBCD; -case Event_InterfaceEvent_LEAVE_BCD: - return types::board_support::Event::BCDtoEF; -case Event_InterfaceEvent_PERMANENT_FAULT: - return types::board_support::Event::PermanentFault; -case Event_InterfaceEvent_EVSE_REPLUG_STARTED: - return types::board_support::Event::EvseReplugStarted; -case Event_InterfaceEvent_EVSE_REPLUG_FINISHED: - return types::board_support::Event::EvseReplugFinished; +static types::board_support_common::BspEvent cast_event_type(CpState cp_state) { + types::board_support_common::BspEvent event; + switch (cp_state) { + case CpState_STATE_A: + event.event = types::board_support_common::Event::A; + break; + case CpState_STATE_B: + event.event = types::board_support_common::Event::B; + break; + case CpState_STATE_C: + event.event = types::board_support_common::Event::C; + break; + case CpState_STATE_D: + event.event = types::board_support_common::Event::D; + break; + case CpState_STATE_E: + event.event = types::board_support_common::Event::E; + break; + case CpState_STATE_F: + event.event = types::board_support_common::Event::F; + break; + } + return event; } -EVLOG_error << "Received an unknown interface event from uMWC: " << (int)e.type; -return types::board_support::Event::ErrorVentilationNotAvailable; +static types::board_support_common::BspEvent cast_event_type(bool relais_state) { + types::board_support_common::BspEvent event; + if (relais_state) { + event.event = types::board_support_common::Event::PowerOn; + } else { + event.event = types::board_support_common::Event::PowerOff; + } + return event; } -*/ void evse_board_supportImpl::init() { { std::lock_guard lock(capsMutex); caps.min_current_A_import = 0; - caps.max_current_A_import = 6; + caps.max_current_A_import = 100; caps.min_phase_count_import = 1; caps.max_phase_count_import = 3; caps.supports_changing_phases_during_charging = false; + caps.connector_type = types::evse_board_support::Connector_type::IEC62196Type2Cable; caps.min_current_A_export = 0; - caps.max_current_A_export = 6; + caps.max_current_A_export = 100; caps.min_phase_count_export = 1; caps.max_phase_count_export = 3; } - /* mod->serial.signalEvent.connect([this](Event e) { - EVLOG_info << "CP EVENT: " << types::board_support::event_to_string(cast_event_type(e)); - publish_event(cast_event_type(e)); - });*/ + mod->serial.signalKeepAliveLo.connect([this](KeepAliveLo l) { + if (not keep_alive_printed) { + EVLOG_info << "uMWC Controller Configuration:"; + EVLOG_info << " Hardware revision: " << l.hw_revision; + EVLOG_info << " Firmware version: " << l.sw_version_string; + } + keep_alive_printed = true; + }); + + mod->serial.signalCPState.connect([this](CpState cp_state) { + if (cp_state not_eq last_cp_state) { + auto event_cp_state = cast_event_type(cp_state); + EVLOG_info << "CP state changed: " << types::board_support_common::event_to_string(event_cp_state.event); + publish_event(event_cp_state); + + /*if (cp_state == CpState_STATE_A) { + mod->clear_errors_on_unplug(); + }*/ + last_cp_state = cp_state; + } + }); + mod->serial.signalRelaisState.connect([this](bool relais_state) { + if (last_relais_state not_eq relais_state) { + publish_event(cast_event_type(relais_state)); + last_relais_state = relais_state; + } + }); } void evse_board_supportImpl::ready() { diff --git a/modules/MicroMegaWattBSP/board_support/evse_board_supportImpl.hpp b/modules/MicroMegaWattBSP/board_support/evse_board_supportImpl.hpp index c149ac48e..daa58f1f5 100644 --- a/modules/MicroMegaWattBSP/board_support/evse_board_supportImpl.hpp +++ b/modules/MicroMegaWattBSP/board_support/evse_board_supportImpl.hpp @@ -61,6 +61,9 @@ class evse_board_supportImpl : public evse_board_supportImplBase { // insert your private definitions here types::evse_board_support::HardwareCapabilities caps; std::mutex capsMutex; + std::atomic_bool keep_alive_printed{false}; + CpState last_cp_state{CpState::CpState_STATE_E}; + bool last_relais_state{false}; // ev@3370e4dd-95f4-47a9-aaec-ea76f34a66c9:v1 }; diff --git a/modules/MicroMegaWattBSP/dc_supply/power_supply_DCImpl.cpp b/modules/MicroMegaWattBSP/dc_supply/power_supply_DCImpl.cpp index ffd6ace7c..98c253264 100644 --- a/modules/MicroMegaWattBSP/dc_supply/power_supply_DCImpl.cpp +++ b/modules/MicroMegaWattBSP/dc_supply/power_supply_DCImpl.cpp @@ -8,12 +8,22 @@ namespace module { namespace dc_supply { void power_supply_DCImpl::init() { - - mod->serial.signalPowerMeter.connect([this](const PowerMeter& p) { + mod->serial.signalTelemetry.connect([this](Telemetry t) { types::power_supply_DC::VoltageCurrent vc; - vc.voltage_V = p.voltage; - vc.current_A = 0.; + vc.current_A = 0; + vc.voltage_V = t.voltage; publish_voltage_current(vc); + + types::powermeter::Powermeter p; + p.timestamp = Everest::Date::to_rfc3339(date::utc_clock::now()); + p.meter_id = "UMWC"; + types::units::Energy e; + e.total = 0.; + p.energy_Wh_import = e; + types::units::Voltage v; + v.DC = t.voltage; + p.voltage_V = v; + mod->p_powermeter->publish_powermeter(p); }); } diff --git a/modules/MicroMegaWattBSP/manifest.yaml b/modules/MicroMegaWattBSP/manifest.yaml index b32d4d542..6e5414c8a 100644 --- a/modules/MicroMegaWattBSP/manifest.yaml +++ b/modules/MicroMegaWattBSP/manifest.yaml @@ -1,21 +1,24 @@ description: Driver module for the Micro Mega Watt DC Charging Tester v1.0 config: serial_port: - description: Serial port the Yeti hardware is connected to + description: Serial port the uMWC hardware is connected to type: string default: /dev/ttyUSB0 baud_rate: - description: Serial baud rate to use when communicating with Yeti hardware + description: Serial baud rate to use when communicating with uMWC hardware type: integer minimum: 9600 maximum: 230400 default: 115200 + reset_gpio_chip: + description: >- + Reset GPIO chip to use to HW reset uMWC. If set to empty string, it is disabled. + type: string + default: 'gpiochip0' reset_gpio: - description: Reset GPIO number to use to HW reset uMWC. If set <0 it is disabled. + description: GPIO line to use to reset uMWC type: integer - minimum: -1 - maximum: 1000 - default: -1 + default: 27 dc_max_voltage: description: Maximum voltage to support type: integer @@ -28,7 +31,7 @@ provides: description: Interface for the DC/DC output supply powermeter: interface: powermeter - description: provides the Yeti Internal Power Meter + description: Interface for the powermeter board_support: interface: evse_board_support description: provides the board support Interface to low level control control pilot, relais, rcd, motor lock diff --git a/modules/MicroMegaWattBSP/powermeter/powermeterImpl.cpp b/modules/MicroMegaWattBSP/powermeter/powermeterImpl.cpp index 02af0b841..b20a4b0f6 100644 --- a/modules/MicroMegaWattBSP/powermeter/powermeterImpl.cpp +++ b/modules/MicroMegaWattBSP/powermeter/powermeterImpl.cpp @@ -6,47 +6,21 @@ namespace module { namespace powermeter { -static types::powermeter::Powermeter umwc_to_everest(const PowerMeter& p) { - types::powermeter::Powermeter j; - - j.timestamp = Everest::Date::to_rfc3339(date::utc_clock::now()); - j.meter_id = "UMWC_POWERMETER"; - - j.energy_Wh_import.total = 0; - - types::units::Power pwr; - pwr.total = 0; - j.power_W = pwr; - - types::units::Voltage volt; - volt.DC = p.voltage; - j.voltage_V = volt; - - types::units::Current amp; - amp.DC = 0; - j.current_A = amp; - - return j; -} - void powermeterImpl::init() { - mod->serial.signalPowerMeter.connect([this](const PowerMeter& p) { publish_powermeter(umwc_to_everest(p)); }); } void powermeterImpl::ready() { } -types::powermeter::TransactionStopResponse powermeterImpl::handle_stop_transaction(std::string& transaction_id) { - return {types::powermeter::TransactionRequestStatus::NOT_SUPPORTED, - {}, - {}, - "MicroMegaWattBSP powermeter does not support the stop_transaction command"}; -}; - types::powermeter::TransactionStartResponse powermeterImpl::handle_start_transaction(types::powermeter::TransactionReq& value) { - return {types::powermeter::TransactionRequestStatus::NOT_SUPPORTED, - "MicroMegaWattBSP powermeter does not support the start_transaction command"}; + // your code for cmd start_transaction goes here + return {}; +} + +types::powermeter::TransactionStopResponse powermeterImpl::handle_stop_transaction(std::string& transaction_id) { + // your code for cmd stop_transaction goes here + return {}; } } // namespace powermeter diff --git a/modules/MicroMegaWattBSP/umwc_comms/CMakeLists.txt b/modules/MicroMegaWattBSP/umwc_comms/CMakeLists.txt index 395eda75e..133b91bbf 100644 --- a/modules/MicroMegaWattBSP/umwc_comms/CMakeLists.txt +++ b/modules/MicroMegaWattBSP/umwc_comms/CMakeLists.txt @@ -30,4 +30,5 @@ target_link_libraries(umwc_comms PRIVATE Pal::Sigslot everest::framework + everest::gpio ) diff --git a/modules/MicroMegaWattBSP/umwc_comms/evSerial.cpp b/modules/MicroMegaWattBSP/umwc_comms/evSerial.cpp index 810e6728a..a1fc87b43 100644 --- a/modules/MicroMegaWattBSP/umwc_comms/evSerial.cpp +++ b/modules/MicroMegaWattBSP/umwc_comms/evSerial.cpp @@ -18,6 +18,8 @@ #include #include +#include + #include "umwc.pb.h" evSerial::evSerial() { @@ -151,10 +153,6 @@ void evSerial::handlePacket(uint8_t* buf, int len) { // detect connection timeout if keep_alive packets stop coming... last_keep_alive_lo_timestamp = date::utc_clock::now(); break; - case McuToEverest_power_meter_tag: - // printf("Received power_meter %i\n", (int)(msg_in.payload.power_meter.voltage)); - signalPowerMeter(msg_in.payload.power_meter); - break; case McuToEverest_telemetry_tag: /*printf("Received telemetry cp_hi %f cp_lo %f relais_on %i pwm_dc %f\n", msg_in.payload.telemetry.cp_hi, msg_in.payload.telemetry.cp_lo, (int)msg_in.payload.telemetry.relais_on, @@ -164,9 +162,6 @@ void evSerial::handlePacket(uint8_t* buf, int len) { case McuToEverest_cp_state_tag: signalCPState(msg_in.payload.cp_state); break; - case McuToEverest_pp_state_tag: - signalPPState(msg_in.payload.pp_state); - break; case McuToEverest_relais_state_tag: signalRelaisState(msg_in.payload.relais_state); break; @@ -362,22 +357,21 @@ void evSerial::setOutputVoltageCurrent(float v, float c) { linkWrite(&msg_out); } -bool evSerial::reset(const int reset_pin) { +bool evSerial::reset(const std::string& reset_chip, const int reset_line) { reset_done_flag = false; forced_reset = true; - if (reset_pin > 0) { + if (not reset_chip.empty()) { // Try to hardware reset Yeti controller to be in a known state - char cmd[100]; - sprintf(cmd, "echo %i >/sys/class/gpio/export", reset_pin); - system(cmd); - sprintf(cmd, "echo out > /sys/class/gpio/gpio%i/direction", reset_pin); - system(cmd); - sprintf(cmd, "echo 0 > /sys/class/gpio/gpio%i/value", reset_pin); - system(cmd); - sprintf(cmd, "echo 1 > /sys/class/gpio/gpio%i/value", reset_pin); - system(cmd); + Everest::Gpio reset_gpio; + reset_gpio.open(reset_chip, reset_line); + reset_gpio.set_output(true); + reset_gpio.set(true); + std::this_thread::sleep_for(std::chrono::milliseconds(10)); + reset_gpio.set(false); + std::this_thread::sleep_for(std::chrono::milliseconds(10)); + reset_gpio.set(true); } else { // Try to soft reset Yeti controller to be in a known state EverestToMcu msg_out = EverestToMcu_init_default; diff --git a/modules/MicroMegaWattBSP/umwc_comms/evSerial.h b/modules/MicroMegaWattBSP/umwc_comms/evSerial.h index 741416d4c..93e9d4b72 100644 --- a/modules/MicroMegaWattBSP/umwc_comms/evSerial.h +++ b/modules/MicroMegaWattBSP/umwc_comms/evSerial.h @@ -28,7 +28,7 @@ class evSerial { void enable(bool en); void disable(); void replug(); - bool reset(const int reset_pin); + bool reset(const std::string& reset_chip, const int reset_line); void firmwareUpdate(bool rom); void keepAlive(); @@ -38,11 +38,9 @@ class evSerial { void setOutputVoltageCurrent(float v, float c); sigslot::signal signalKeepAliveLo; - sigslot::signal signalPowerMeter; sigslot::signal signalTelemetry; sigslot::signal signalCPState; - sigslot::signal signalPPState; sigslot::signal signalErrorFlags; sigslot::signal signalRelaisState; diff --git a/modules/MicroMegaWattBSP/umwc_comms/protobuf/umwc.pb.c b/modules/MicroMegaWattBSP/umwc_comms/protobuf/umwc.pb.c index 74b0f0260..520292025 100644 --- a/modules/MicroMegaWattBSP/umwc_comms/protobuf/umwc.pb.c +++ b/modules/MicroMegaWattBSP/umwc_comms/protobuf/umwc.pb.c @@ -1,5 +1,5 @@ /* Automatically generated nanopb constant definitions */ -/* Generated by nanopb-0.4.6 */ +/* Generated by nanopb-0.4.8 */ #include "umwc.pb.h" #if PB_PROTO_HEADER_VERSION != 40 @@ -27,14 +27,9 @@ PB_BIND(KeepAlive, KeepAlive, AUTO) PB_BIND(Telemetry, Telemetry, AUTO) -PB_BIND(PowerMeter, PowerMeter, AUTO) - - PB_BIND(FirmwareUpdate, FirmwareUpdate, AUTO) - - diff --git a/modules/MicroMegaWattBSP/umwc_comms/protobuf/umwc.pb.h b/modules/MicroMegaWattBSP/umwc_comms/protobuf/umwc.pb.h index edd5e9e78..89e64847c 100644 --- a/modules/MicroMegaWattBSP/umwc_comms/protobuf/umwc.pb.h +++ b/modules/MicroMegaWattBSP/umwc_comms/protobuf/umwc.pb.h @@ -1,5 +1,5 @@ /* Automatically generated nanopb header */ -/* Generated by nanopb-0.4.6 */ +/* Generated by nanopb-0.4.8 */ #ifndef PB_UMWC_PB_H_INCLUDED #define PB_UMWC_PB_H_INCLUDED @@ -10,53 +10,32 @@ #endif /* Enum definitions */ -typedef enum _CpState { - CpState_STATE_A = 0, - CpState_STATE_B = 1, - CpState_STATE_C = 2, - CpState_STATE_D = 3, - CpState_STATE_E = 4, - CpState_STATE_F = 5 +typedef enum _CpState { + CpState_STATE_A = 0, + CpState_STATE_B = 1, + CpState_STATE_C = 2, + CpState_STATE_D = 3, + CpState_STATE_E = 4, + CpState_STATE_F = 5 } CpState; -typedef enum _ResetReason { - ResetReason_USER = 0, - ResetReason_WATCHDOG = 1 +typedef enum _ResetReason { + ResetReason_USER = 0, + ResetReason_WATCHDOG = 1 } ResetReason; -typedef enum _PpState { - PpState_STATE_NC = 0, - PpState_STATE_13A = 1, - PpState_STATE_20A = 2, - PpState_STATE_32A = 3, - PpState_STATE_70A = 4, - PpState_STATE_FAULT = 5 -} PpState; - -typedef enum _LockState { - LockState_UNDEFINED = 0, - LockState_UNLOCKED = 1, - LockState_LOCKED = 2 -} LockState; - /* Struct definitions */ -typedef struct _ErrorFlags { +typedef struct _SetOutputVoltageCurrent { + float voltage; + float current; +} SetOutputVoltageCurrent; + +typedef struct _ErrorFlags { bool diode_fault; bool cp_signal_fault; } ErrorFlags; -typedef struct _FirmwareUpdate { - bool invoke_rom_bootloader; -} FirmwareUpdate; - -typedef struct _KeepAlive { - uint32_t time_stamp; - uint32_t hw_type; - uint32_t hw_revision; - char sw_version_string[51]; -} KeepAlive; - -typedef struct _KeepAliveLo { +typedef struct _KeepAliveLo { uint32_t time_stamp; uint32_t hw_type; uint32_t hw_revision; @@ -70,24 +49,42 @@ typedef struct _KeepAliveLo { bool supports_changing_phases_during_charging; } KeepAliveLo; -typedef struct _PowerMeter { - float voltage; -} PowerMeter; - -typedef struct _SetOutputVoltageCurrent { - float voltage; - float current; -} SetOutputVoltageCurrent; +typedef struct _KeepAlive { + uint32_t time_stamp; + uint32_t hw_type; + uint32_t hw_revision; + char sw_version_string[51]; +} KeepAlive; -typedef struct _Telemetry { +typedef struct _Telemetry { float cp_hi; float cp_lo; float pwm_dc; float relais_on; + float voltage; } Telemetry; +/* This container message is send from MCU to EVerest and may contain any allowed message in that direction. */ +typedef struct _McuToEverest { + pb_size_t which_payload; + union { + /* Needs to remain the same to allow firmware updates of older versions */ + KeepAliveLo keep_alive; + /* Other IDs are 100+ to avoid compatibility issues with older firmware versions */ + ResetReason reset; + CpState cp_state; + bool relais_state; /* false: relais are off, true: relais are on */ + ErrorFlags error_flags; + Telemetry telemetry; + } payload; +} McuToEverest; + +typedef struct _FirmwareUpdate { + bool invoke_rom_bootloader; +} FirmwareUpdate; + /* This container message is send from EVerest to MCU and may contain any allowed message in that direction. */ -typedef struct _EverestToMcu { +typedef struct _EverestToMcu { pb_size_t which_payload; union { /* Needs to remain the same to allow firmware updates of older versions */ @@ -95,7 +92,6 @@ typedef struct _EverestToMcu { SetOutputVoltageCurrent set_output_voltage_current; /* Other IDs are 100+ to avoid compatibility issues with older firmware versions */ KeepAlive keep_alive; - bool connector_lock; /* false: unlock, true: lock */ uint32_t pwm_duty_cycle; /* in 0.01 %, 0 = State F, 10000 = X1 */ bool allow_power_on; bool reset; @@ -104,24 +100,10 @@ typedef struct _EverestToMcu { } payload; } EverestToMcu; -/* This container message is send from MCU to EVerest and may contain any allowed message in that direction. */ -typedef struct _McuToEverest { - pb_size_t which_payload; - union { - /* Needs to remain the same to allow firmware updates of older versions */ - KeepAliveLo keep_alive; - /* Other IDs are 100+ to avoid compatibility issues with older firmware versions */ - ResetReason reset; - CpState cp_state; - bool relais_state; /* false: relais are off, true: relais are on */ - ErrorFlags error_flags; - Telemetry telemetry; - PpState pp_state; - LockState lock_state; - PowerMeter power_meter; - } payload; -} McuToEverest; +#ifdef __cplusplus +extern "C" { +#endif /* Helper constants for enums */ #define _CpState_MIN CpState_STATE_A @@ -132,18 +114,16 @@ typedef struct _McuToEverest { #define _ResetReason_MAX ResetReason_WATCHDOG #define _ResetReason_ARRAYSIZE ((ResetReason)(ResetReason_WATCHDOG+1)) -#define _PpState_MIN PpState_STATE_NC -#define _PpState_MAX PpState_STATE_FAULT -#define _PpState_ARRAYSIZE ((PpState)(PpState_STATE_FAULT+1)) -#define _LockState_MIN LockState_UNDEFINED -#define _LockState_MAX LockState_LOCKED -#define _LockState_ARRAYSIZE ((LockState)(LockState_LOCKED+1)) +#define McuToEverest_payload_reset_ENUMTYPE ResetReason +#define McuToEverest_payload_cp_state_ENUMTYPE CpState + + + + + -#ifdef __cplusplus -extern "C" { -#endif /* Initializer values for message structs */ #define EverestToMcu_init_default {0, {FirmwareUpdate_init_default}} @@ -152,8 +132,7 @@ extern "C" { #define ErrorFlags_init_default {0, 0} #define KeepAliveLo_init_default {0, 0, 0, 0, 0, "", 0, 0, 0, 0, 0} #define KeepAlive_init_default {0, 0, 0, ""} -#define Telemetry_init_default {0, 0, 0, 0} -#define PowerMeter_init_default {0} +#define Telemetry_init_default {0, 0, 0, 0, 0} #define FirmwareUpdate_init_default {0} #define EverestToMcu_init_zero {0, {FirmwareUpdate_init_zero}} #define McuToEverest_init_zero {0, {KeepAliveLo_init_zero}} @@ -161,18 +140,14 @@ extern "C" { #define ErrorFlags_init_zero {0, 0} #define KeepAliveLo_init_zero {0, 0, 0, 0, 0, "", 0, 0, 0, 0, 0} #define KeepAlive_init_zero {0, 0, 0, ""} -#define Telemetry_init_zero {0, 0, 0, 0} -#define PowerMeter_init_zero {0} +#define Telemetry_init_zero {0, 0, 0, 0, 0} #define FirmwareUpdate_init_zero {0} /* Field tags (for use in manual encoding/decoding) */ +#define SetOutputVoltageCurrent_voltage_tag 1 +#define SetOutputVoltageCurrent_current_tag 2 #define ErrorFlags_diode_fault_tag 1 #define ErrorFlags_cp_signal_fault_tag 6 -#define FirmwareUpdate_invoke_rom_bootloader_tag 1 -#define KeepAlive_time_stamp_tag 1 -#define KeepAlive_hw_type_tag 2 -#define KeepAlive_hw_revision_tag 3 -#define KeepAlive_sw_version_string_tag 6 #define KeepAliveLo_time_stamp_tag 1 #define KeepAliveLo_hw_type_tag 2 #define KeepAliveLo_hw_revision_tag 3 @@ -184,38 +159,36 @@ extern "C" { #define KeepAliveLo_hwcap_max_phase_count_tag 9 #define KeepAliveLo_hwcap_min_phase_count_tag 10 #define KeepAliveLo_supports_changing_phases_during_charging_tag 11 -#define PowerMeter_voltage_tag 2 -#define SetOutputVoltageCurrent_voltage_tag 1 -#define SetOutputVoltageCurrent_current_tag 2 +#define KeepAlive_time_stamp_tag 1 +#define KeepAlive_hw_type_tag 2 +#define KeepAlive_hw_revision_tag 3 +#define KeepAlive_sw_version_string_tag 6 #define Telemetry_cp_hi_tag 1 #define Telemetry_cp_lo_tag 2 #define Telemetry_pwm_dc_tag 3 #define Telemetry_relais_on_tag 4 +#define Telemetry_voltage_tag 5 +#define McuToEverest_keep_alive_tag 3 +#define McuToEverest_reset_tag 101 +#define McuToEverest_cp_state_tag 102 +#define McuToEverest_relais_state_tag 103 +#define McuToEverest_error_flags_tag 104 +#define McuToEverest_telemetry_tag 105 +#define FirmwareUpdate_invoke_rom_bootloader_tag 1 #define EverestToMcu_firmware_update_tag 16 #define EverestToMcu_set_output_voltage_current_tag 50 #define EverestToMcu_keep_alive_tag 100 -#define EverestToMcu_connector_lock_tag 102 #define EverestToMcu_pwm_duty_cycle_tag 103 #define EverestToMcu_allow_power_on_tag 104 #define EverestToMcu_reset_tag 105 #define EverestToMcu_enable_tag 106 #define EverestToMcu_replug_tag 107 -#define McuToEverest_keep_alive_tag 3 -#define McuToEverest_reset_tag 101 -#define McuToEverest_cp_state_tag 102 -#define McuToEverest_relais_state_tag 103 -#define McuToEverest_error_flags_tag 104 -#define McuToEverest_telemetry_tag 105 -#define McuToEverest_pp_state_tag 106 -#define McuToEverest_lock_state_tag 107 -#define McuToEverest_power_meter_tag 108 /* Struct field encoding specification for nanopb */ #define EverestToMcu_FIELDLIST(X, a) \ X(a, STATIC, ONEOF, MESSAGE, (payload,firmware_update,payload.firmware_update), 16) \ X(a, STATIC, ONEOF, MESSAGE, (payload,set_output_voltage_current,payload.set_output_voltage_current), 50) \ X(a, STATIC, ONEOF, MESSAGE, (payload,keep_alive,payload.keep_alive), 100) \ -X(a, STATIC, ONEOF, BOOL, (payload,connector_lock,payload.connector_lock), 102) \ X(a, STATIC, ONEOF, UINT32, (payload,pwm_duty_cycle,payload.pwm_duty_cycle), 103) \ X(a, STATIC, ONEOF, BOOL, (payload,allow_power_on,payload.allow_power_on), 104) \ X(a, STATIC, ONEOF, BOOL, (payload,reset,payload.reset), 105) \ @@ -233,16 +206,12 @@ X(a, STATIC, ONEOF, UENUM, (payload,reset,payload.reset), 101) \ X(a, STATIC, ONEOF, UENUM, (payload,cp_state,payload.cp_state), 102) \ X(a, STATIC, ONEOF, BOOL, (payload,relais_state,payload.relais_state), 103) \ X(a, STATIC, ONEOF, MESSAGE, (payload,error_flags,payload.error_flags), 104) \ -X(a, STATIC, ONEOF, MESSAGE, (payload,telemetry,payload.telemetry), 105) \ -X(a, STATIC, ONEOF, UENUM, (payload,pp_state,payload.pp_state), 106) \ -X(a, STATIC, ONEOF, UENUM, (payload,lock_state,payload.lock_state), 107) \ -X(a, STATIC, ONEOF, MESSAGE, (payload,power_meter,payload.power_meter), 108) +X(a, STATIC, ONEOF, MESSAGE, (payload,telemetry,payload.telemetry), 105) #define McuToEverest_CALLBACK NULL #define McuToEverest_DEFAULT NULL #define McuToEverest_payload_keep_alive_MSGTYPE KeepAliveLo #define McuToEverest_payload_error_flags_MSGTYPE ErrorFlags #define McuToEverest_payload_telemetry_MSGTYPE Telemetry -#define McuToEverest_payload_power_meter_MSGTYPE PowerMeter #define SetOutputVoltageCurrent_FIELDLIST(X, a) \ X(a, STATIC, SINGULAR, FLOAT, voltage, 1) \ @@ -283,15 +252,11 @@ X(a, STATIC, SINGULAR, STRING, sw_version_string, 6) X(a, STATIC, SINGULAR, FLOAT, cp_hi, 1) \ X(a, STATIC, SINGULAR, FLOAT, cp_lo, 2) \ X(a, STATIC, SINGULAR, FLOAT, pwm_dc, 3) \ -X(a, STATIC, SINGULAR, FLOAT, relais_on, 4) +X(a, STATIC, SINGULAR, FLOAT, relais_on, 4) \ +X(a, STATIC, SINGULAR, FLOAT, voltage, 5) #define Telemetry_CALLBACK NULL #define Telemetry_DEFAULT NULL -#define PowerMeter_FIELDLIST(X, a) \ -X(a, STATIC, SINGULAR, FLOAT, voltage, 2) -#define PowerMeter_CALLBACK NULL -#define PowerMeter_DEFAULT NULL - #define FirmwareUpdate_FIELDLIST(X, a) \ X(a, STATIC, SINGULAR, BOOL, invoke_rom_bootloader, 1) #define FirmwareUpdate_CALLBACK NULL @@ -304,7 +269,6 @@ extern const pb_msgdesc_t ErrorFlags_msg; extern const pb_msgdesc_t KeepAliveLo_msg; extern const pb_msgdesc_t KeepAlive_msg; extern const pb_msgdesc_t Telemetry_msg; -extern const pb_msgdesc_t PowerMeter_msg; extern const pb_msgdesc_t FirmwareUpdate_msg; /* Defines for backwards compatibility with code written before nanopb-0.4.0 */ @@ -315,7 +279,6 @@ extern const pb_msgdesc_t FirmwareUpdate_msg; #define KeepAliveLo_fields &KeepAliveLo_msg #define KeepAlive_fields &KeepAlive_msg #define Telemetry_fields &Telemetry_msg -#define PowerMeter_fields &PowerMeter_msg #define FirmwareUpdate_fields &FirmwareUpdate_msg /* Maximum encoded size of messages (where known) */ @@ -325,9 +288,9 @@ extern const pb_msgdesc_t FirmwareUpdate_msg; #define KeepAliveLo_size 106 #define KeepAlive_size 70 #define McuToEverest_size 108 -#define PowerMeter_size 5 #define SetOutputVoltageCurrent_size 10 -#define Telemetry_size 20 +#define Telemetry_size 25 +#define UMWC_PB_H_MAX_SIZE McuToEverest_size #ifdef __cplusplus } /* extern "C" */ diff --git a/modules/MicroMegaWattBSP/umwc_comms/protobuf/umwc.proto b/modules/MicroMegaWattBSP/umwc_comms/protobuf/umwc.proto index d757e449a..8d709b5d6 100644 --- a/modules/MicroMegaWattBSP/umwc_comms/protobuf/umwc.proto +++ b/modules/MicroMegaWattBSP/umwc_comms/protobuf/umwc.proto @@ -12,7 +12,6 @@ message EverestToMcu { // Other IDs are 100+ to avoid compatibility issues with older firmware versions KeepAlive keep_alive = 100; - bool connector_lock = 102; // false: unlock, true: lock uint32 pwm_duty_cycle = 103; // in 0.01 %, 0 = State F, 10000 = X1 bool allow_power_on = 104; bool reset = 105; @@ -35,9 +34,6 @@ message McuToEverest { bool relais_state = 103; // false: relais are off, true: relais are on ErrorFlags error_flags = 104; Telemetry telemetry = 105; - PpState pp_state = 106; - LockState lock_state = 107; - PowerMeter power_meter = 108; } } @@ -91,25 +87,7 @@ message Telemetry { float cp_lo = 2; float pwm_dc = 3; float relais_on = 4; -} - -enum PpState { - STATE_NC = 0; - STATE_13A = 1; - STATE_20A = 2; - STATE_32A = 3; - STATE_70A = 4; - STATE_FAULT = 5; -} - -enum LockState { - UNDEFINED = 0; - UNLOCKED = 1; - LOCKED = 2; -} - -message PowerMeter { - float voltage = 2; + float voltage = 5; } message FirmwareUpdate { diff --git a/modules/MicroMegaWattBSP/umwc_fwupdate/CMakeLists.txt b/modules/MicroMegaWattBSP/umwc_fwupdate/CMakeLists.txt index e4e1f2064..18ea6f836 100644 --- a/modules/MicroMegaWattBSP/umwc_fwupdate/CMakeLists.txt +++ b/modules/MicroMegaWattBSP/umwc_fwupdate/CMakeLists.txt @@ -9,7 +9,7 @@ set(CMAKE_CXX_STANDARD_REQUIRED True) # add the executable add_executable(umwc_fwupdate main.cpp) target_include_directories(umwc_fwupdate PUBLIC "${PROJECT_BINARY_DIR}" PUBLIC "../umwc_comms/nanopb" PUBLIC "../umwc_comms/protobuf" PUBLIC "../umwc_comms") -target_link_libraries(umwc_fwupdate PRIVATE Pal::Sigslot Threads::Threads umwc_comms everest::framework) +target_link_libraries(umwc_fwupdate PRIVATE Pal::Sigslot Threads::Threads umwc_comms everest::framework everest::gpio) install(TARGETS umwc_fwupdate DESTINATION ${EVEREST_MOD_YETIDRIVER_DESTINATION}) diff --git a/modules/MicroMegaWattBSP/umwc_fwupdate/main.cpp b/modules/MicroMegaWattBSP/umwc_fwupdate/main.cpp index ca7a71b74..96e116625 100644 --- a/modules/MicroMegaWattBSP/umwc_fwupdate/main.cpp +++ b/modules/MicroMegaWattBSP/umwc_fwupdate/main.cpp @@ -10,6 +10,7 @@ #include #include "umwc.pb.h" +#include using namespace std::chrono_literals; @@ -56,6 +57,15 @@ int main(int argc, char* argv[]) { delete p; sleep(1); + // Try to hardware reset Yeti controller to be in a known state + Everest::Gpio reset_gpio; + reset_gpio.open("gpiochip0", 27); + reset_gpio.set_output(true); + reset_gpio.set(true); + std::this_thread::sleep_for(std::chrono::milliseconds(10)); + reset_gpio.set(false); + std::this_thread::sleep_for(std::chrono::milliseconds(10)); + reset_gpio.set(true); char cmd[1000]; sprintf(cmd, "stm32flash -b 115200 %.100s -v -w %.100s -R", device, filename); // sprintf(cmd, "stm32flash -b115200 %.100s", device); From d1f8c99693f9799fa9e0cee954ed369d90d5cbb3 Mon Sep 17 00:00:00 2001 From: Cornelius Claussen Date: Mon, 24 Jun 2024 14:51:22 +0200 Subject: [PATCH 2/3] Review comments Signed-off-by: Cornelius Claussen --- modules/MicroMegaWattBSP/MicroMegaWattBSP.cpp | 2 ++ .../MicroMegaWattBSP/board_support/evse_board_supportImpl.cpp | 4 ---- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/modules/MicroMegaWattBSP/MicroMegaWattBSP.cpp b/modules/MicroMegaWattBSP/MicroMegaWattBSP.cpp index 68b9c2ff8..541f0d7f4 100644 --- a/modules/MicroMegaWattBSP/MicroMegaWattBSP.cpp +++ b/modules/MicroMegaWattBSP/MicroMegaWattBSP.cpp @@ -13,6 +13,7 @@ void MicroMegaWattBSP::init() { invoke_init(*p_board_support); invoke_init(*p_dc_supply); + invoke_init(*p_powermeter); } void MicroMegaWattBSP::ready() { @@ -38,6 +39,7 @@ void MicroMegaWattBSP::ready() { invoke_ready(*p_board_support); invoke_ready(*p_dc_supply); + invoke_ready(*p_powermeter); if (not serial.is_open()) { auto err = p_board_support->error_factory->create_error("evse_board_support/CommunicationFault", "", diff --git a/modules/MicroMegaWattBSP/board_support/evse_board_supportImpl.cpp b/modules/MicroMegaWattBSP/board_support/evse_board_supportImpl.cpp index 769980db1..05ba66dbf 100644 --- a/modules/MicroMegaWattBSP/board_support/evse_board_supportImpl.cpp +++ b/modules/MicroMegaWattBSP/board_support/evse_board_supportImpl.cpp @@ -71,10 +71,6 @@ void evse_board_supportImpl::init() { auto event_cp_state = cast_event_type(cp_state); EVLOG_info << "CP state changed: " << types::board_support_common::event_to_string(event_cp_state.event); publish_event(event_cp_state); - - /*if (cp_state == CpState_STATE_A) { - mod->clear_errors_on_unplug(); - }*/ last_cp_state = cp_state; } }); From df695a5a0f6d57c9556369a2cc583106ae31a19d Mon Sep 17 00:00:00 2001 From: Cornelius Claussen Date: Tue, 25 Jun 2024 14:19:50 +0200 Subject: [PATCH 3/3] Powermeter proper start/stop reply Signed-off-by: Cornelius Claussen --- modules/MicroMegaWattBSP/powermeter/powermeterImpl.cpp | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/modules/MicroMegaWattBSP/powermeter/powermeterImpl.cpp b/modules/MicroMegaWattBSP/powermeter/powermeterImpl.cpp index b20a4b0f6..b8441e7e9 100644 --- a/modules/MicroMegaWattBSP/powermeter/powermeterImpl.cpp +++ b/modules/MicroMegaWattBSP/powermeter/powermeterImpl.cpp @@ -15,12 +15,15 @@ void powermeterImpl::ready() { types::powermeter::TransactionStartResponse powermeterImpl::handle_start_transaction(types::powermeter::TransactionReq& value) { // your code for cmd start_transaction goes here - return {}; + return {types::powermeter::TransactionRequestStatus::NOT_SUPPORTED, + "MicroMegaWattBSP powermeter does not support the start_transaction command"}; } types::powermeter::TransactionStopResponse powermeterImpl::handle_stop_transaction(std::string& transaction_id) { - // your code for cmd stop_transaction goes here - return {}; + return {types::powermeter::TransactionRequestStatus::NOT_SUPPORTED, + {}, + {}, + "MicroMegaWattBSP powermeter does not support the stop_transaction command"}; } } // namespace powermeter