diff --git a/esp-idf b/esp-idf index c779440..4e7f7e7 160000 --- a/esp-idf +++ b/esp-idf @@ -1 +1 @@ -Subproject commit c779440a3e55fad39f28041eed6bb97181f7ddc8 +Subproject commit 4e7f7e7b524687b99ed98d12bab75de12a19b4b2 diff --git a/main/CMakeLists.txt b/main/CMakeLists.txt index 251131d..5c8c061 100644 --- a/main/CMakeLists.txt +++ b/main/CMakeLists.txt @@ -126,6 +126,7 @@ set(headers displays/menus/bmsmenu.h displays/menus/boardcomputerhardwaresettingsmenu.h displays/menus/buzzermenu.h + displays/menus/candebugmenu.h displays/menus/cloudsettingsmenu.h displays/menus/commanddebugmenu.h displays/menus/controllerhardwaresettingsmenu.h @@ -351,6 +352,7 @@ set(sources displays/menus/bmsmenu.cpp displays/menus/boardcomputerhardwaresettingsmenu.cpp displays/menus/buzzermenu.cpp + displays/menus/candebugmenu.cpp displays/menus/cloudsettingsmenu.cpp displays/menus/commanddebugmenu.cpp displays/menus/controllerhardwaresettingsmenu.cpp diff --git a/main/can.cpp b/main/can.cpp index 6831a72..788ee21 100644 --- a/main/can.cpp +++ b/main/can.cpp @@ -6,8 +6,8 @@ #include // esp-idf -#include #include +#include #include // 3rdparty lib includes @@ -27,6 +27,8 @@ namespace can { uint32_t can_total_error_cnt; namespace { constexpr const char * const TAG = "BOBBYCAN"; + +bool tryParseCanInput(); } // namespace std::optional can_gas, can_brems; @@ -77,6 +79,13 @@ void initCan() } } +void updateCan() +{ + for (int i = 0; i < 4; i++) + if (!tryParseCanInput()) + break; +} + namespace { template @@ -189,7 +198,6 @@ bool parseBoardcomputerCanMessage(const twai_message_t &message) return false; } -} // namespace bool tryParseCanInput() { @@ -249,12 +257,7 @@ bool tryParseCanInput() return true; } -void parseCanInput() -{ - for (int i = 0; i < 4; i++) - if (!tryParseCanInput()) - break; -} +} // namespace void sendCanCommands() { diff --git a/main/can.h b/main/can.h index bd0b571..e501dc3 100644 --- a/main/can.h +++ b/main/can.h @@ -18,22 +18,9 @@ extern uint32_t can_total_error_cnt; extern std::optional can_gas, can_brems; extern espchrono::millis_clock::time_point last_can_gas, last_can_brems; -struct CanButtonsState -{ - bool up{}; - bool down{}; - bool confirm{}; - bool back{}; - bool profile0{}; - bool profile1{}; - bool profile2{}; - bool profile3{}; -}; -extern CanButtonsState lastButtonsState; - void initCan(); -bool tryParseCanInput(); -void parseCanInput(); +void updateCan(); + void sendCanCommands(); } // namespace can #endif diff --git a/main/displays/menus/candebugmenu.cpp b/main/displays/menus/candebugmenu.cpp new file mode 100644 index 0000000..b8f2792 --- /dev/null +++ b/main/displays/menus/candebugmenu.cpp @@ -0,0 +1,225 @@ +#ifdef FEATURE_CAN + +#include "candebugmenu.h" + +// esp-idf includes +#include + +// 3rdparty lib includes +#include + +// 3rdparty lib includes +#include +#include +#include +#include +#include + +// local includes +#include "displays/menus/debugmenu.h" + +namespace { +constexpr char TAG[] = "CANDEBUG"; + +constexpr char TEXT_CANDEBUG[] = "CAN Debug"; +constexpr char TEXT_BACK[] = "Back"; + +class CanStatusText : public virtual espgui::TextInterface +{ +public: + explicit CanStatusText(const tl::expected &last_can_status_info) : + m_last_can_status_info{last_can_status_info} + { + } + + std::string text() const override + { + if (m_last_can_status_info) + return fmt::format("{}: &f{}", canStatusName(), canStatusText(*m_last_can_status_info)); + else + return fmt::format("{}: &f&1{}", canStatusName(), esp_err_to_name(m_last_can_status_info.error())); + } + +protected: + virtual std::string canStatusName() const = 0; + virtual std::string canStatusText(const twai_status_info_t &can_status_info) const = 0; + +private: + const tl::expected &m_last_can_status_info; +}; + +class CanStatusStateText : public CanStatusText +{ +public: + using CanStatusText::CanStatusText; + +protected: + std::string canStatusName() const override { return "state"; } + std::string canStatusText(const twai_status_info_t &can_status_info) const override { return std::to_string(can_status_info.state); } +}; + +class CanStatusMsgsToTxText : public CanStatusText +{ +public: + using CanStatusText::CanStatusText; + +protected: + std::string canStatusName() const override { return "msgs_to_tx"; } + std::string canStatusText(const twai_status_info_t &can_status_info) const override { return std::to_string(can_status_info.msgs_to_tx); } +}; + +class CanStatusMsgsToRxText : public CanStatusText +{ +public: + using CanStatusText::CanStatusText; + +protected: + std::string canStatusName() const override { return "msgs_to_rx"; } + std::string canStatusText(const twai_status_info_t &can_status_info) const override { return std::to_string(can_status_info.msgs_to_rx); } +}; + +class CanStatusTxErrorCounterText : public CanStatusText +{ +public: + using CanStatusText::CanStatusText; + +protected: + std::string canStatusName() const override { return "&stx_error_counter"; } + std::string canStatusText(const twai_status_info_t &can_status_info) const override { return std::to_string(can_status_info.tx_error_counter); } +}; + +class CanStatusRxErrorCounterText : public CanStatusText +{ +public: + using CanStatusText::CanStatusText; + +protected: + std::string canStatusName() const override { return "&srx_error_counter"; } + std::string canStatusText(const twai_status_info_t &can_status_info) const override { return std::to_string(can_status_info.rx_error_counter); } +}; + +class CanStatusTxFailedCountText : public CanStatusText +{ +public: + using CanStatusText::CanStatusText; + +protected: + std::string canStatusName() const override { return "&stx_failed_count"; } + std::string canStatusText(const twai_status_info_t &can_status_info) const override { return std::to_string(can_status_info.tx_failed_count); } +}; + +class CanStatusRxFailedCountText : public CanStatusText +{ +public: + using CanStatusText::CanStatusText; + +protected: + std::string canStatusName() const override { return "&srx_missed_count"; } + std::string canStatusText(const twai_status_info_t &can_status_info) const override { return std::to_string(can_status_info.rx_missed_count); } +}; + +class CanStatusRxOverrunCountText : public CanStatusText +{ +public: + using CanStatusText::CanStatusText; + +protected: + std::string canStatusName() const override { return "&srx_overrun_count"; } + std::string canStatusText(const twai_status_info_t &can_status_info) const override { return std::to_string(can_status_info.rx_overrun_count); } +}; + +class CanStatusArbLostCountText : public CanStatusText +{ +public: + using CanStatusText::CanStatusText; + +protected: + std::string canStatusName() const override { return "&sarb_lost_count"; } + std::string canStatusText(const twai_status_info_t &can_status_info) const override { return std::to_string(can_status_info.arb_lost_count); } +}; + +class CanStatusBusErrorCountText : public CanStatusText +{ +public: + using CanStatusText::CanStatusText; + +protected: + std::string canStatusName() const override { return "&sbus_error_count"; } + std::string canStatusText(const twai_status_info_t &can_status_info) const override { return std::to_string(can_status_info.bus_error_count); } +}; + +class CanPendingTxCountText : public virtual espgui::TextInterface +{ +public: + std::string text() const override + { + unsigned pending{}; + if (const auto result = twai_get_pending_tx(&pending); result == ESP_OK) + return fmt::format("pending_TX: {}", pending); + else + return fmt::format("pending_TX: &1{}", esp_err_to_name(result)); + } +}; + +class CanPendingRxCountText : public virtual espgui::TextInterface +{ +public: + std::string text() const override + { + unsigned pending{}; + if (const auto result = twai_get_pending_rx(&pending); result == ESP_OK) + return fmt::format("pending_RX: {}", pending); + else + return fmt::format("pending_RX: &1{}", esp_err_to_name(result)); + } +}; +} // namespace + +CanDebugMenu::CanDebugMenu() +{ + using namespace espgui; + constructMenuItem>(m_last_can_status_info); + constructMenuItem>(m_last_can_status_info); + constructMenuItem>(m_last_can_status_info); + constructMenuItem>(m_last_can_status_info); + constructMenuItem>(m_last_can_status_info); + constructMenuItem>(m_last_can_status_info); + constructMenuItem>(m_last_can_status_info); + constructMenuItem>(m_last_can_status_info); + constructMenuItem>(m_last_can_status_info); + constructMenuItem>(m_last_can_status_info); + constructMenuItem>(); + constructMenuItem>(); + constructMenuItem, SwitchScreenAction, StaticMenuItemIcon<&espgui::icons::back>>>(); +} + +std::string CanDebugMenu::text() const +{ + return TEXT_CANDEBUG; +} + +void CanDebugMenu::update() +{ + Base::update(); + + twai_status_info_t status_info; + if (const auto result = twai_get_status_info(&status_info); result != ESP_OK) + { + ESP_LOGE(TAG, "twai_get_status_info() failed with %s", esp_err_to_name(result)); + m_last_can_status_info = tl::make_unexpected(result); + } + else + { + ESP_LOGD(TAG, "state=%i msgs_to_tx=%u tx_error_counter=%u tx_failed_count=%u arb_lost_count=%u bus_error_count=%u", + status_info.state, status_info.msgs_to_tx, status_info.tx_error_counter, + status_info.tx_failed_count, status_info.arb_lost_count, status_info.bus_error_count); + m_last_can_status_info = status_info; + } +} + +void CanDebugMenu::back() +{ + espgui::switchScreen(); +} + +#endif diff --git a/main/displays/menus/candebugmenu.h b/main/displays/menus/candebugmenu.h new file mode 100644 index 0000000..cd9cf32 --- /dev/null +++ b/main/displays/menus/candebugmenu.h @@ -0,0 +1,31 @@ +#pragma once + +// local includes +#include "displays/bobbymenudisplay.h" + +#ifdef FEATURE_CAN + +// esp-idf includes +#include + +// 3rdparty lib includes +#include + +class CanDebugMenu : public BobbyMenuDisplay +{ + using Base = BobbyMenuDisplay; + +public: + CanDebugMenu(); + + std::string text() const override; + + void update() override; + + void back() override; + +private: + tl::expected m_last_can_status_info; +}; + +#endif diff --git a/main/displays/menus/debugmenu.cpp b/main/displays/menus/debugmenu.cpp index c5f4665..b08cfca 100644 --- a/main/displays/menus/debugmenu.cpp +++ b/main/displays/menus/debugmenu.cpp @@ -1,11 +1,10 @@ #include "debugmenu.h" // 3rdparty lib includes -#include "menuitem.h" -#include "actions/switchscreenaction.h" -#include "actions/dummyaction.h" -#include "icons/back.h" -#include "accessors/settingsaccessors.h" +#include +#include +#include +#include #include // local includes @@ -17,8 +16,12 @@ #include "icons/battery.h" #include "debugcolorhelpers.h" #include "esptexthelpers.h" +#include "accessors/settingsaccessors.h" #include "displays/qrcodedebug.h" #include "displays/menus/taskmanagermenu.h" +#ifdef FEATURE_CAN +#include "displays/menus/candebugmenu.h" +#endif #include "displays/menus/commanddebugmenu.h" #include "displays/menus/motorstatedebugmenu.h" #include "displays/menus/feedbackdebugmenu.h" @@ -31,6 +34,9 @@ namespace { constexpr char TEXT_DEBUG[] = "Debug"; constexpr char TEXT_TASKMANAGER[] = "Taskmanager"; +#ifdef FEATURE_CAN +constexpr char TEXT_CANDEBUG[] = "CAN Debug"; +#endif constexpr char TEXT_QRCODE_DEBUG[] = "QR Debug"; constexpr char TEXT_BATTERYDEBUG[] = "Bat Debug Menu"; constexpr char TEXT_TOGGLECLOUDDEBUG[] = "Cloud Debug"; @@ -57,6 +63,7 @@ DebugMenu::DebugMenu() { using namespace espgui; constructMenuItem, SwitchScreenAction>>(); + constructMenuItem, SwitchScreenAction>>(); constructMenuItem, SwitchScreenAction>>(); constructMenuItem, SwitchScreenAction, StaticMenuItemIcon<&bobbyicons::battery>>>(); #ifdef FEATURE_UDPCLOUD @@ -95,5 +102,5 @@ std::string DebugMenu::text() const void DebugMenu::back() { - switchScreen(); + espgui::switchScreen(); } diff --git a/main/taskmanager.cpp b/main/taskmanager.cpp index 04ffdb8..ee1d64c 100644 --- a/main/taskmanager.cpp +++ b/main/taskmanager.cpp @@ -119,7 +119,7 @@ espcpputils::SchedulerTask schedulerTasksArr[] { #endif #endif #ifdef FEATURE_CAN - espcpputils::SchedulerTask { "can", can::initCan, can::parseCanInput, 10ms }, + espcpputils::SchedulerTask { "can", can::initCan, can::updateCan, 10ms }, #endif espcpputils::SchedulerTask { "debuginput", initDebugInput, handleDebugInput, 50ms }, #ifdef FEATURE_SERIAL