diff --git a/config_comred.cmake b/config_comred.cmake index 2026453..251df02 100644 --- a/config_comred.cmake +++ b/config_comred.cmake @@ -44,21 +44,44 @@ set(BOBBYCAR_BUILDFLAGS -DAP_PASSWORD=Passwort_123 -DFEATURE_WEBSERVER -DFEATURE_OTA - -DFEATURE_DPAD_5WIRESW - -DPINS_DPAD_5WIRESW_OUT=4 - -DPINS_DPAD_5WIRESW_IN1=5 - -DPINS_DPAD_5WIRESW_IN2=27 - -DPINS_DPAD_5WIRESW_IN3=18 - -DPINS_DPAD_5WIRESW_IN4=19 - -DDPAD_5WIRESW_UP=1 - -DDPAD_5WIRESW_DOWN=5 - -DDPAD_5WIRESW_CONFIRM=2 - -DDPAD_5WIRESW_BACK=6 - -DDPAD_5WIRESW_PROFILE0=4 - -DDPAD_5WIRESW_PROFILE1=0 - -DDPAD_5WIRESW_PROFILE2=7 - -DDPAD_5WIRESW_PROFILE3=3 +# -DFEATURE_DPAD_5WIRESW +# -DPINS_DPAD_5WIRESW_OUT=4 +# -DPINS_DPAD_5WIRESW_IN1=5 +# -DPINS_DPAD_5WIRESW_IN2=27 +# -DPINS_DPAD_5WIRESW_IN3=18 +# -DPINS_DPAD_5WIRESW_IN4=19 +# -DPINS_DPAD_EXTRASW_IN5=25 + -DFEATURE_DPAD_6WIRESW + -DPINS_DPAD_6WIRESW_OUT=4 + -DPINS_DPAD_6WIRESW_IN1=5 + -DPINS_DPAD_6WIRESW_IN2=27 + -DPINS_DPAD_6WIRESW_IN3=18 + -DPINS_DPAD_6WIRESW_IN4=19 + -DPINS_DPAD_6WIRESW_IN5=26 + +# -DDPAD_5WIRESW_UP=1 +# -DDPAD_5WIRESW_DOWN=5 +# -DDPAD_5WIRESW_CONFIRM=2 +# -DDPAD_5WIRESW_BACK=6 +# -DDPAD_5WIRESW_PROFILE0=4 +# -DDPAD_5WIRESW_PROFILE1=0 +# -DDPAD_5WIRESW_PROFILE2=7 +# -DDPAD_5WIRESW_PROFILE3=3 # -DDPAD_5WIRESW_DEBUG + + -DDPAD_6WIRESW_UP=1 + -DDPAD_6WIRESW_DOWN=5 + -DDPAD_6WIRESW_CONFIRM=2 + -DDPAD_6WIRESW_BACK=6 + -DDPAD_6WIRESW_PROFILE0=4 + -DDPAD_6WIRESW_PROFILE1=0 + -DDPAD_6WIRESW_PROFILE2=7 + -DDPAD_6WIRESW_PROFILE3=3 + -DDPAD_6WIRESW_BLINK_LEFT=9 + -DDPAD_6WIRESW_BLINK_RIGHT=8 +# -DDPAD_6WIRESW_DEBUG + -DFEATURE_GSCHISSENE_DIODE + -DDEFAULT_GASMIN=842 -DDEFAULT_GASMAX=2480 -DDEFAULT_BREMSMIN=826 diff --git a/main/CMakeLists.txt b/main/CMakeLists.txt index cdbff58..1431cc9 100644 --- a/main/CMakeLists.txt +++ b/main/CMakeLists.txt @@ -85,6 +85,8 @@ set(headers displays/bmsdisplay.h displays/calibratedisplay.h displays/dpad5wiredebugdisplay.h + displays/dpad5wire2outdebugdisplay.h + displays/dpad6wiredebugdisplay.h displays/gametrakcalibratedisplay.h displays/garagedisplay.h displays/lockscreen.h @@ -133,6 +135,8 @@ set(headers dpad.h dpad3wire.h dpad5wire.h + dpad5wire_2out.h + dpad6wire.h feedbackparser.h globals.h macros_bobbycar.h diff --git a/main/accessors/settingsaccessors.h b/main/accessors/settingsaccessors.h index 2f5f49b..a81e7fa 100644 --- a/main/accessors/settingsaccessors.h +++ b/main/accessors/settingsaccessors.h @@ -101,7 +101,7 @@ struct GasMinAccessor : public RefAccessorSaveSettings { int16_t &getRe struct GasMaxAccessor : public RefAccessorSaveSettings { int16_t &getRef() const override { return settings.boardcomputerHardware.gasMax; } }; struct BremsMinAccessor : public RefAccessorSaveSettings { int16_t &getRef() const override { return settings.boardcomputerHardware.bremsMin; } }; struct BremsMaxAccessor : public RefAccessorSaveSettings { int16_t &getRef() const override { return settings.boardcomputerHardware.bremsMax; } }; -#if defined(FEATURE_DPAD) || defined(FEATURE_DPAD_3WIRESW) || defined(FEATURE_DPAD_5WIRESW) || defined(FEATURE_DPAD_5WIRESW_2OUT) +#if defined(FEATURE_DPAD) || defined(FEATURE_DPAD_3WIRESW) || defined(FEATURE_DPAD_5WIRESW) || defined(FEATURE_DPAD_5WIRESW_2OUT) || defined (FEATURE_DPAD_6WIRESW) struct DPadDebounceAccessor : public RefAccessorSaveSettings { uint8_t &getRef() const override { return settings.boardcomputerHardware.dpadDebounce; } }; #endif #ifdef FEATURE_GAMETRAK diff --git a/main/displays/dpad6wiredebugdisplay.h b/main/displays/dpad6wiredebugdisplay.h new file mode 100644 index 0000000..783651c --- /dev/null +++ b/main/displays/dpad6wiredebugdisplay.h @@ -0,0 +1,92 @@ +#pragma once + +#include "display.h" +#include "globals.h" +#include "widgets/label.h" +#include "dpad6wire.h" + +namespace { +#ifdef FEATURE_DPAD_6WIRESW +class DPad6WireDebugDisplay : public Display, public virtual DummyConfirm, public virtual DummyBack +{ +public: + void initScreen() override; + void redraw() override; + +private: + Label m_labelRaw{0, 50}; + Label m_labelUp{175, 75}; + Label m_labelDown{175, 100}; + Label m_labelBack{175, 125}; + Label m_labelConfirm{175, 150}; + Label m_labelProfile0{175, 175}; + Label m_labelProfile1{175, 200}; + Label m_labelProfile2{175, 225}; + Label m_labelProfile3{175, 250}; + Label m_labelGas{175, 275}; + Label m_labelBrems{175, 300}; +}; + +void DPad6WireDebugDisplay::initScreen() +{ + tft.fillScreen(TFT_BLACK); + tft.setTextFont(4); + tft.setTextColor(TFT_YELLOW); + + tft.drawString("DPad 5wire debug", 5, 5); + + tft.fillRect(0, 34, tft.width(), 3, TFT_WHITE); + + tft.setTextColor(TFT_WHITE, TFT_BLACK); + + tft.drawString("UP:", 30, 75); + tft.drawString("DOWN:", 30, 100); + tft.drawString("CONFIRM:", 30, 125); + tft.drawString("BACK:", 30, 150); + tft.drawString("PROFILE0:", 30, 175); + tft.drawString("PROFILE1:", 30, 200); + tft.drawString("PROFILE2:", 30, 225); + tft.drawString("PROFILE3:", 30, 250); + tft.drawString("GAS:", 30, 275); + tft.drawString("BREMS:", 30, 300); + + m_labelRaw.start(); + m_labelUp.start(); + m_labelDown.start(); + m_labelBack.start(); + m_labelConfirm.start(); + m_labelProfile0.start(); + m_labelProfile1.start(); + m_labelProfile2.start(); + m_labelProfile3.start(); + m_labelGas.start(); + m_labelBrems.start(); +} + +void DPad6WireDebugDisplay::redraw() +{ + m_labelRaw.redraw(std::string{} + + (std::get<0>(dpad6wire::lastState) ? 'Z' : '0') + ' ' + + (std::get<1>(dpad6wire::lastState) ? '1' : '0') + ' ' + + (std::get<2>(dpad6wire::lastState) ? '2' : '0') + ' ' + + (std::get<3>(dpad6wire::lastState) ? '3' : '0') + ' ' + + (std::get<4>(dpad6wire::lastState) ? '4' : '0') + ' ' + + (std::get<5>(dpad6wire::lastState) ? '5' : '0') + ' ' + + (std::get<6>(dpad6wire::lastState) ? '6' : '0') + ' ' + + (std::get<7>(dpad6wire::lastState) ? '7' : '0') + ' ' + + (std::get<8>(dpad6wire::lastState) ? '8' : '0') + ' ' + + (std::get<9>(dpad6wire::lastState) ? '9' : '0')); + + m_labelUp.redraw(std::get(dpad6wire::lastState) ? "1" : "0"); + m_labelDown.redraw(std::get(dpad6wire::lastState) ? "1" : "0"); + m_labelBack.redraw(std::get(dpad6wire::lastState) ? "1" : "0"); + m_labelConfirm.redraw(std::get(dpad6wire::lastState) ? "1" : "0"); + m_labelProfile0.redraw(std::get(dpad6wire::lastState) ? "1" : "0"); + m_labelProfile1.redraw(std::get(dpad6wire::lastState) ? "1" : "0"); + m_labelProfile2.redraw(std::get(dpad6wire::lastState) ? "1" : "0"); + m_labelProfile3.redraw(std::get(dpad6wire::lastState) ? "1" : "0"); + m_labelGas.redraw(raw_gas ? std::to_string(*raw_gas) : "?"); + m_labelBrems.redraw(raw_brems ? std::to_string(*raw_brems) : "?"); +} +#endif +} diff --git a/main/displays/menus/boardcomputerhardwaresettingsmenu.h b/main/displays/menus/boardcomputerhardwaresettingsmenu.h index 29d0e85..182f54e 100644 --- a/main/displays/menus/boardcomputerhardwaresettingsmenu.h +++ b/main/displays/menus/boardcomputerhardwaresettingsmenu.h @@ -86,7 +86,7 @@ using BremsMaxChangeScreen = makeComponent< SwitchScreenAction >; -#if defined(FEATURE_DPAD) || defined(FEATURE_DPAD_3WIRESW) || defined(FEATURE_DPAD_5WIRESW) || defined(FEATURE_DPAD_5WIRESW_2OUT) +#if defined(FEATURE_DPAD) || defined(FEATURE_DPAD_3WIRESW) || defined(FEATURE_DPAD_5WIRESW) || defined(FEATURE_DPAD_5WIRESW_2OUT) || defined (FEATURE_DPAD_6WIRESW) using DPadDebounceChangeScreen = makeComponent< ChangeValueDisplay, StaticText, @@ -171,7 +171,7 @@ public: constructMenuItem, SwitchScreenAction>>(); constructMenuItem, SwitchScreenAction>>(); constructMenuItem, SwitchScreenAction>>(); -#if defined(FEATURE_DPAD) || defined(FEATURE_DPAD_3WIRESW) || defined(FEATURE_DPAD_5WIRESW) || defined(FEATURE_DPAD_5WIRESW_2OUT) +#if defined(FEATURE_DPAD) || defined(FEATURE_DPAD_3WIRESW) || defined(FEATURE_DPAD_5WIRESW) || defined(FEATURE_DPAD_5WIRESW_2OUT) || defined (FEATURE_DPAD_6WIRESW) constructMenuItem, SwitchScreenAction>>(); #endif #ifdef FEATURE_GAMETRAK diff --git a/main/dpad6wire.h b/main/dpad6wire.h new file mode 100644 index 0000000..b9b86f7 --- /dev/null +++ b/main/dpad6wire.h @@ -0,0 +1,213 @@ +#pragma once +#define FEATURE_DPAD_6WIRESW +// system includes +#include + +// Arduino includes +#include + +// 3rdparty lib includes +#include +#include + +// local includes +#include "buttons.h" +#include "types.h" + +namespace { +namespace dpad6wire { +#ifdef FEATURE_DPAD_6WIRESW +class State : public std::array +{ +public: + State() : std::array{false, false, false, false, false, false, false, false, false, false} {} + State(const std::array &other) : std::array{} {} + + State &operator=(const std::array &other) + { + std::array::operator=(other); + return *this; + } + + State &operator=(const State &other) + { + std::array::operator=(other); + return *this; + } + + bool &up{this->at(DPAD_6WIRESW_UP)}; + bool &down{this->at(DPAD_6WIRESW_DOWN)}; + bool &confirm{this->at(DPAD_6WIRESW_CONFIRM)}; + bool &back{this->at(DPAD_6WIRESW_BACK)}; + bool &profile0{this->at(DPAD_6WIRESW_PROFILE0)}; + bool &profile1{this->at(DPAD_6WIRESW_PROFILE1)}; + bool &profile2{this->at(DPAD_6WIRESW_PROFILE2)}; + bool &profile3{this->at(DPAD_6WIRESW_PROFILE3)}; + + bool &blink_left{this->at(DPAD_6WIRESW_BLINK_LEFT)}; + bool &blink_right{this->at(DPAD_6WIRESW_BLINK_RIGHT)}; +}; + +template +class Helper +{ +public: + static constexpr auto OutPin = OUT; + static constexpr auto In1Pin = IN1; + static constexpr auto In2Pin = IN2; + static constexpr auto In3Pin = IN3; + static constexpr auto In4Pin = IN4; + static constexpr auto In5Pin = IN5; + + void begin(); + + State read(); +}; + +template +void Helper::begin() +{ + pinMode(OUT, OUTPUT); +} + +template +State Helper::read() +{ + State result; + + digitalWrite(OUT, LOW); + + pinMode(IN1, INPUT_PULLUP); + pinMode(IN2, INPUT_PULLUP); + pinMode(IN3, INPUT_PULLUP); + pinMode(IN4, INPUT_PULLUP); + pinMode(IN5, INPUT_PULLUP); + + vPortYield(); + + result[0] = digitalRead(IN1)==LOW; + result[1] = digitalRead(IN2)==LOW; + result[2] = digitalRead(IN3)==LOW; + result[3] = digitalRead(IN4)==LOW; + result[8] = digitalRead(IN5)==LOW; + + digitalWrite(OUT, HIGH); + + pinMode(IN1, INPUT_PULLDOWN); + pinMode(IN2, INPUT_PULLDOWN); + pinMode(IN3, INPUT_PULLDOWN); + pinMode(IN4, INPUT_PULLDOWN); + pinMode(IN5, INPUT_PULLDOWN); + + vPortYield(); + + result[4] = digitalRead(IN1); + result[5] = digitalRead(IN2); + result[6] = digitalRead(IN3); + result[7] = digitalRead(IN4); + result[9] = digitalRead(IN5); + +#ifdef FEATURE_GSCHISSENE_DIODE + if (result[8] && result[9]) result[9] = 0; +#endif + + return result; +} + +Helper helper; +State lastState; +espchrono::millis_clock::time_point debounceUp, debounceDown, debounceConfirm, debounceBack, debounceProfile0, debounceProfile1, debounceProfile2, debounceProfile3, debounceBlinkLeft, debounceBlinkRight; + +void init() +{ + helper.begin(); + debounceUp = debounceDown = debounceConfirm = debounceBack = debounceProfile0 = debounceProfile1 = debounceProfile2 = debounceProfile3 = debounceBlinkLeft = debounceBlinkRight = espchrono::millis_clock::now(); +} + +void update() +{ + const auto newState = helper.read(); + +#ifdef DPAD_6WIRESW_DEBUG + lastState = newState; + return; +#endif + + const auto now = espchrono::millis_clock::now(); + + const std::chrono::milliseconds dpadDebounce{settings.boardcomputerHardware.dpadDebounce}; + + if (lastState.up != newState.up && now - debounceUp > dpadDebounce) + { + lastState.up = newState.up; + InputDispatcher::upButton(newState.up); + debounceUp = now; + } + + if (lastState.down != newState.down && now - debounceDown > dpadDebounce) + { + lastState.down = newState.down; + InputDispatcher::downButton(newState.down); + debounceDown = now; + } + + if (lastState.confirm != newState.confirm && now - debounceConfirm > dpadDebounce) + { + lastState.confirm = newState.confirm; + InputDispatcher::confirmButton(newState.confirm); + debounceConfirm = now; + } + + if (lastState.back != newState.back && now - debounceBack > dpadDebounce) + { + lastState.back = newState.back; + InputDispatcher::backButton(newState.back); + debounceBack = now; + } + + if (lastState.profile0 != newState.profile0 && now - debounceProfile0 > dpadDebounce) + { + lastState.profile0 = newState.profile0; + InputDispatcher::profileButton(0, newState.profile0); + debounceProfile0 = now; + } + + if (lastState.profile1 != newState.profile1 && now - debounceProfile1 > dpadDebounce) + { + lastState.profile1 = newState.profile1; + InputDispatcher::profileButton(1, newState.profile1); + debounceProfile1 = now; + } + + if (lastState.profile2 != newState.profile2 && now - debounceProfile2 > dpadDebounce) + { + lastState.profile2 = newState.profile2; + InputDispatcher::profileButton(2, newState.profile2); + debounceProfile2 = now; + } + + if (lastState.profile3 != newState.profile3 && now - debounceProfile3 > dpadDebounce) + { + lastState.profile3 = newState.profile3; + InputDispatcher::profileButton(3, newState.profile3); + debounceProfile3 = now; + } + + if (lastState.blink_left != newState.blink_left && now - debounceBlinkLeft > dpadDebounce) + { + lastState.blink_left = newState.blink_left; + InputDispatcher::blinkLeftButton(newState.blink_left); + debounceBlinkLeft = now; + } + + if (lastState.blink_right != newState.blink_right && now - debounceBlinkRight > dpadDebounce) + { + lastState.blink_right = newState.blink_right; + InputDispatcher::blinkRightButton(newState.blink_right); + debounceBlinkRight = now; + } +} +#endif + +} // namespace dpad6wire +} // namespace diff --git a/main/main.cpp b/main/main.cpp index ce6c348..534b9f3 100644 --- a/main/main.cpp +++ b/main/main.cpp @@ -85,6 +85,9 @@ using namespace std::chrono_literals; #ifdef FEATURE_DPAD_5WIRESW_2OUT #include "displays/dpad5wire2outdebugdisplay.h" #endif +#ifdef FEATURE_DPAD_6WIRESW +#include "displays/dpad6wiredebugdisplay.h" +#endif #include "displays/gameoflifedisplay.h" #ifdef FEATURE_GARAGE #include "displays/garagedisplay.h" @@ -114,6 +117,9 @@ using namespace std::chrono_literals; #ifdef FEATURE_DPAD_5WIRESW_2OUT #include "dpad5wire_2out.h" #endif +#ifdef FEATURE_DPAD_6WIRESW +#include "dpad6wire.h" +#endif #ifdef FEATURE_ROTARY #include "rotary.h" #endif @@ -236,6 +242,11 @@ extern "C" void app_main() dpad5wire_2out::init(); #endif +#ifdef FEATURE_DPAD_6WIRESW + bootLabel.redraw("dpad6wire"); + dpad6wire::init(); +#endif + #ifdef FEATURE_ROTARY bootLabel.redraw("rotary"); initRotary(); @@ -339,6 +350,8 @@ extern "C" void app_main() switchScreen(); #elif defined(FEATURE_DPAD_5WIRESW_2OUT) && defined(DPAD_5WIRESW_DEBUG) switchScreen(); +#elif defined(FEATURE_DPAD_6WIRESW) && defined(DPAD_6WIRESW_DEBUG) + switchScreen(); #else if (!gas || !brems || *gas > 200.f || *brems > 200.f) @@ -374,6 +387,9 @@ extern "C" void app_main() #ifdef FEATURE_DPAD_5WIRESW_2OUT dpad5wire_2out::update(); #endif +#ifdef FEATURE_DPAD_6WIRESW + dpad6wire::update(); +#endif if (!lastPotiRead || now - *lastPotiRead >= 1000ms/settings.boardcomputerHardware.timersSettings.potiReadRate) { diff --git a/main/presets.h b/main/presets.h index 5518604..23c19b3 100644 --- a/main/presets.h +++ b/main/presets.h @@ -154,7 +154,7 @@ constexpr Settings::BoardcomputerHardware defaultBoardcomputerHardware { .gasMax = DEFAULT_GASMAX, .bremsMin = DEFAULT_BREMSMIN, .bremsMax = DEFAULT_BREMSMAX, -#if defined(FEATURE_DPAD) || defined(FEATURE_DPAD_3WIRESW) || defined(FEATURE_DPAD_5WIRESW) || defined(FEATURE_DPAD_5WIRESW_2OUT) +#if defined(FEATURE_DPAD) || defined(FEATURE_DPAD_3WIRESW) || defined(FEATURE_DPAD_5WIRESW) || defined(FEATURE_DPAD_5WIRESW_2OUT) || defined (FEATURE_DPAD_6WIRESW) .dpadDebounce = 25, #endif #ifdef FEATURE_GAMETRAK diff --git a/main/settings.h b/main/settings.h index edc5b3f..287f236 100644 --- a/main/settings.h +++ b/main/settings.h @@ -93,7 +93,7 @@ struct Settings struct BoardcomputerHardware { int16_t sampleCount; int16_t gasMin, gasMax, bremsMin, bremsMax; -#if defined(FEATURE_DPAD) || defined(FEATURE_DPAD_3WIRESW) || defined(FEATURE_DPAD_5WIRESW) || defined(FEATURE_DPAD_5WIRESW_2OUT) +#if defined(FEATURE_DPAD) || defined(FEATURE_DPAD_3WIRESW) || defined(FEATURE_DPAD_5WIRESW) || defined(FEATURE_DPAD_5WIRESW_2OUT) || defined (FEATURE_DPAD_6WIRESW) uint8_t dpadDebounce; #endif #ifdef FEATURE_GAMETRAK