From 07f5500019ee6400de320622a000fdb12a894751 Mon Sep 17 00:00:00 2001 From: Cornelius Claussen Date: Fri, 15 Mar 2024 10:37:51 +0100 Subject: [PATCH] Fix YetiDriver and include binary firmware image. Manually update Yeti with: yeti_fwupdate /dev/serial0 /usr/share/everest/modules/YetiDriver/firmware/yetiR1_2.0-1_firmware.bin Signed-off-by: Cornelius Claussen --- modules/YetiDriver/CMakeLists.txt | 2 + .../board_support/evse_board_supportImpl.cpp | 46 +++++--- .../board_support/evse_board_supportImpl.hpp | 7 +- modules/YetiDriver/yetiR1_2.0-1_firmware.bin | Bin 0 -> 114728 bytes modules/YetiDriver/yeti_comms/evSerial.cpp | 4 + .../yeti_comms/firmware_version.hpp | 111 ++++++++++++++++++ .../YetiDriver/yeti_fwupdate/CMakeLists.txt | 3 +- modules/YetiDriver/yeti_fwupdate/main.cpp | 25 +++- 8 files changed, 175 insertions(+), 23 deletions(-) create mode 100755 modules/YetiDriver/yetiR1_2.0-1_firmware.bin create mode 100644 modules/YetiDriver/yeti_comms/firmware_version.hpp diff --git a/modules/YetiDriver/CMakeLists.txt b/modules/YetiDriver/CMakeLists.txt index f7a826a2f0..3948560755 100644 --- a/modules/YetiDriver/CMakeLists.txt +++ b/modules/YetiDriver/CMakeLists.txt @@ -36,4 +36,6 @@ target_sources(${MODULE_NAME} # ev@c55432ab-152c-45a9-9d2e-7281d50c69c3:v1 # insert other things like install cmds etc here +install(FILES yetiR1_2.0-1_firmware.bin DESTINATION ${CMAKE_INSTALL_DATADIR}/everest/modules/YetiDriver/firmware) + # ev@c55432ab-152c-45a9-9d2e-7281d50c69c3:v1 diff --git a/modules/YetiDriver/board_support/evse_board_supportImpl.cpp b/modules/YetiDriver/board_support/evse_board_supportImpl.cpp index bcf12ed44f..0d1dfb4c7f 100644 --- a/modules/YetiDriver/board_support/evse_board_supportImpl.cpp +++ b/modules/YetiDriver/board_support/evse_board_supportImpl.cpp @@ -71,28 +71,39 @@ void evse_board_supportImpl::init() { std::lock_guard lock(capsMutex); caps.min_current_A_import = mod->config.caps_min_current_A; - caps.max_current_A_import = 6; + caps.max_current_A_import = 16; 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 = mod->config.caps_min_current_A; - caps.max_current_A_export = 6; + caps.max_current_A_export = 16; caps.min_phase_count_export = 1; caps.max_phase_count_export = 3; caps.supports_changing_phases_during_charging = false; } mod->serial.signalCPState.connect([this](CpState cp_state) { - publish_event(cast_event_type(cp_state)); - - if (cp_state == CpState_STATE_A) { - mod->clear_errors_on_unplug(); + 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; } }); - mod->serial.signalRelaisState.connect([this](bool relais_state) { publish_event(cast_event_type(relais_state)); }); + mod->serial.signalPPState.connect([this](PpState pp_state) { - std::lock_guard lock(capsMutex); last_pp = cast_pp_type(pp_state); publish_ac_pp_ampacity(last_pp); }); @@ -113,20 +124,26 @@ void evse_board_supportImpl::init() { caps.max_phase_count_export = l.hwcap_max_phase_count; caps.supports_changing_phases_during_charging = l.supports_changing_phases_during_charging; + if (not caps_received) { + EVLOG_info << "Yeti Controller Configuration:"; + EVLOG_info << " Hardware revision: " << l.hw_revision; + EVLOG_info << " Firmware version: " << l.sw_version_string; + EVLOG_info << " Current Limit: " << l.hwcap_max_current; + } caps_received = true; }); } void evse_board_supportImpl::ready() { + wait_for_caps(); +} + +void evse_board_supportImpl::wait_for_caps() { // Wait for caps to be received at least once int i; for (i = 0; i < 50; i++) { - { - std::lock_guard lock(capsMutex); - if (caps_received) - break; - } - + if (caps_received) + break; std::this_thread::sleep_for(std::chrono::milliseconds(100)); } if (i == 49) { @@ -136,6 +153,7 @@ void evse_board_supportImpl::ready() { } types::evse_board_support::HardwareCapabilities evse_board_supportImpl::handle_get_hw_capabilities() { + wait_for_caps(); std::lock_guard lock(capsMutex); return caps; } diff --git a/modules/YetiDriver/board_support/evse_board_supportImpl.hpp b/modules/YetiDriver/board_support/evse_board_supportImpl.hpp index 636a4bd1d5..259cbdca12 100644 --- a/modules/YetiDriver/board_support/evse_board_supportImpl.hpp +++ b/modules/YetiDriver/board_support/evse_board_supportImpl.hpp @@ -59,9 +59,12 @@ class evse_board_supportImpl : public evse_board_supportImplBase { // ev@3370e4dd-95f4-47a9-aaec-ea76f34a66c9:v1 // insert your private definitions here types::evse_board_support::HardwareCapabilities caps; - bool caps_received{false}; + std::atomic_bool caps_received{false}; std::mutex capsMutex; - types::board_support_common::ProximityPilot last_pp; + CpState last_cp_state{CpState::CpState_STATE_E}; + bool last_relais_state{false}; + types::board_support_common::ProximityPilot last_pp{types::board_support_common::Ampacity::None}; + void wait_for_caps(); // ev@3370e4dd-95f4-47a9-aaec-ea76f34a66c9:v1 }; diff --git a/modules/YetiDriver/yetiR1_2.0-1_firmware.bin b/modules/YetiDriver/yetiR1_2.0-1_firmware.bin new file mode 100755 index 0000000000000000000000000000000000000000..0a15174efe872c0d55614e4b2c8f33c744b0b69c GIT binary patch literal 114728 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 UsH`kqY@RpoA5iO`rALeYZ{MaU+5i9m literal 0 HcmV?d00001 diff --git a/modules/YetiDriver/yeti_comms/evSerial.cpp b/modules/YetiDriver/yeti_comms/evSerial.cpp index b353405ff0..d9bf59b95a 100644 --- a/modules/YetiDriver/yeti_comms/evSerial.cpp +++ b/modules/YetiDriver/yeti_comms/evSerial.cpp @@ -348,6 +348,10 @@ bool evSerial::reset(const int reset_pin) { system(cmd); sprintf(cmd, "echo 0 > /sys/class/gpio/gpio%i/value", reset_pin); system(cmd); + + // clear uart input and output buffer + //tcflush(fd, TCIOFLUSH); + sprintf(cmd, "echo 1 > /sys/class/gpio/gpio%i/value", reset_pin); system(cmd); } else { diff --git a/modules/YetiDriver/yeti_comms/firmware_version.hpp b/modules/YetiDriver/yeti_comms/firmware_version.hpp new file mode 100644 index 0000000000..c818faa1c2 --- /dev/null +++ b/modules/YetiDriver/yeti_comms/firmware_version.hpp @@ -0,0 +1,111 @@ +// SPDX-License-Identifier: Apache-2.0 +// Copyright Pionix GmbH and Contributors to EVerest +#ifndef YETI_FIRMWARE_VERSION +#define YETI_FIRMWARE_VERSION + +#include +#include + +/* + Helper class to handle yeti Firmware Versions of the following style: + + Reported by MCU: 2.0-1-g2d51638 + Included in file name: yetiR1_2.0-1_firmware.bin + +*/ + +static std::vector split_by_delimeters(const std::string& s, const std::string& delimeters) { + std::regex re("[" + delimeters + "]"); + std::sregex_token_iterator first{s.begin(), s.end(), re, -1}, last; + return {first, last}; +} + +// parse version string from filename +static std::string from_filename(const std::string& v) { + auto tokens = split_by_delimeters(v, "_"); + if (tokens.size() >= 2) { + return tokens[1]; + } + return "0.0-0"; +} + +class YetiFirmwareVersion { + +public: + YetiFirmwareVersion() { + } + + YetiFirmwareVersion(const std::string& _version_string) { + from_string(_version_string); + } + + std::string to_string() { + return std::to_string(major) + "." + std::to_string(minor) + "-" + std::to_string(revision); + } + + void from_string(const std::string& _version_string) { + std::string version_string; + // Is it a full filename or just a version string from the MCU? + if (_version_string.rfind("yetiR", 0) == 0) { + version_string = from_filename(_version_string); + } else { + version_string = _version_string; + } + + auto tokens = split_by_delimeters(version_string, ".-"); + + // parse into major, minor and revision + if (tokens.size() >= 1) { + major = std::stoi(tokens[0]); + } + + if (tokens.size() >= 2) { + minor = std::stoi(tokens[1]); + } + + if (tokens.size() >= 3) { + revision = std::stoi(tokens[2]); + } + } + + YetiFirmwareVersion& operator=(const std::string& s) { + from_string(s); + return *this; + } + + friend bool operator<(const YetiFirmwareVersion& l, const YetiFirmwareVersion& r) { + if (l.major < r.major) { + return true; + } else if (l.major > r.major) { + return false; + } else if (l.minor < r.minor) { + return true; + } else if (l.minor > r.minor) { + return false; + } else if (l.revision < r.revision) { + return true; + } else if (l.revision > r.revision) { + return false; + } + // they are identical + return false; + } + + friend bool operator>(const YetiFirmwareVersion& lhs, const YetiFirmwareVersion& rhs) { + return rhs < lhs; + } + + friend bool operator<=(const YetiFirmwareVersion& lhs, const YetiFirmwareVersion& rhs) { + return not(lhs > rhs); + } + friend bool operator>=(const YetiFirmwareVersion& lhs, const YetiFirmwareVersion& rhs) { + return not(lhs < rhs); + } + +private: + int major{0}; + int minor{0}; + int revision{0}; +}; + +#endif diff --git a/modules/YetiDriver/yeti_fwupdate/CMakeLists.txt b/modules/YetiDriver/yeti_fwupdate/CMakeLists.txt index f9a8276ef1..69e0d93b65 100644 --- a/modules/YetiDriver/yeti_fwupdate/CMakeLists.txt +++ b/modules/YetiDriver/yeti_fwupdate/CMakeLists.txt @@ -11,7 +11,6 @@ add_executable(yeti_fwupdate main.cpp) target_include_directories(yeti_fwupdate PUBLIC "${PROJECT_BINARY_DIR}" PUBLIC "../yeti_comms/nanopb" PUBLIC "../yeti_comms/protobuf" PUBLIC "../yeti_comms") target_link_libraries(yeti_fwupdate PRIVATE Pal::Sigslot Threads::Threads yeti_comms everest::framework) -install(TARGETS yeti_fwupdate - DESTINATION ${EVEREST_MOD_YETIDRIVER_DESTINATION}) +install(TARGETS yeti_fwupdate) diff --git a/modules/YetiDriver/yeti_fwupdate/main.cpp b/modules/YetiDriver/yeti_fwupdate/main.cpp index 2a4b7ccbb9..f3ddf18d86 100644 --- a/modules/YetiDriver/yeti_fwupdate/main.cpp +++ b/modules/YetiDriver/yeti_fwupdate/main.cpp @@ -4,16 +4,20 @@ #include #include "evSerial.h" +#include #include +#include "firmware_version.hpp" #include "yeti.pb.h" #include -volatile bool sw_version_received = false; +std::atomic_bool sw_version_received = false; +YetiFirmwareVersion installed_fw_version; +std::string installed_fw_version_orig; void recvKeepAliveLo(KeepAliveLo s) { - printf("Current Yeti SW Version: %s (Protocol %i.%i)\n", s.sw_version_string, s.protocol_version_major, - s.protocol_version_minor); + installed_fw_version = s.sw_version_string; + installed_fw_version_orig = s.sw_version_string; sw_version_received = true; } @@ -29,7 +33,7 @@ int main(int argc, char* argv[]) { exit(0); } const char* device = argv[1]; - const char* filename = argv[2]; + std::filesystem::path filename = argv[2]; evSerial* p = new evSerial(); @@ -42,6 +46,17 @@ int main(int argc, char* argv[]) { break; usleep(100); } + + YetiFirmwareVersion update_file_fw_version{filename.filename()}; + printf("Installed Yeti Firmware Version: %s (%s)\n", installed_fw_version.to_string().c_str(), + installed_fw_version_orig.c_str()); + printf("Update File Firmware Version: %s\n", update_file_fw_version.to_string().c_str()); + + if (installed_fw_version >= update_file_fw_version) { + printf("Latest version already installed. Exiting.\n"); + exit(1); + } + printf("\nRebooting Yeti in ROM Bootloader mode...\n"); // send some dummy commands to make sure protocol is in sync p->keepAlive(); @@ -54,7 +69,7 @@ int main(int argc, char* argv[]) { sleep(1); char cmd[1000]; - sprintf(cmd, "stm32flash -b 115200 %.100s -v -w %.100s -R", device, filename); + sprintf(cmd, "stm32flash -b 115200 %.100s -v -w %.100s -R", device, filename.string().c_str()); // sprintf(cmd, "stm32flash -b115200 %.100s", device); printf("Executing %s ...\n", cmd); system(cmd);