Merge pull request #75 from bobbycar-graz/74-multiple-profiles
Merge "#74 Implement multiple config profiles"
This commit is contained in:
@ -16,6 +16,7 @@ framework = arduino
|
||||
lib_deps =
|
||||
TFT_eSPI
|
||||
https://github.com/Ferdi265/cxx-ring-buffer
|
||||
https://github.com/TartanLlama/optional
|
||||
|
||||
lib_compat_mode = strict
|
||||
build_unflags =
|
||||
@ -42,6 +43,13 @@ build_flags =
|
||||
-DDEFAULT_FIELDWEAKMAX=5
|
||||
-DDEFAULT_FIELDADVMAX=40
|
||||
|
||||
[default_wheels_inverted]
|
||||
build_flags =
|
||||
-DDEFAULT_INVERTFRONTLEFT=false
|
||||
-DDEFAULT_INVERTFRONTRIGHT=true
|
||||
-DDEFAULT_INVERTBACKLEFT=false
|
||||
-DDEFAULT_INVERTBACKRIGHT=true
|
||||
|
||||
[peters_platine_common]
|
||||
build_flags =
|
||||
-DILI9341_DRIVER=1
|
||||
@ -107,6 +115,10 @@ build_flags =
|
||||
-DPINS_TX1=5
|
||||
-DPINS_RX2=22
|
||||
-DPINS_TX2=23
|
||||
-DDEFAULT_INVERTFRONTLEFT=false
|
||||
-DDEFAULT_INVERTFRONTRIGHT=true
|
||||
-DDEFAULT_INVERTBACKLEFT=true
|
||||
-DDEFAULT_INVERTBACKRIGHT=false
|
||||
; -DFEATURE_MOSFETS
|
||||
; -DPINS_MOSFET0=18
|
||||
; -DPINS_MOSFET1=19
|
||||
@ -116,10 +128,21 @@ build_flags =
|
||||
-DDEVICE_PREFIX=bobbyquad
|
||||
-DAP_PASSWORD=Passwort_123
|
||||
-DFEATURE_WEBSERVER
|
||||
; -DFEATURE_DPAD_3WIRESW
|
||||
; -DPINS_DPAD_3WIRESW_OUT=0
|
||||
; -DPINS_DPAD_3WIRESW_IN1=16
|
||||
; -DPINS_DPAD_3WIRESW_IN2=27
|
||||
-DFEATURE_DPAD_5WIRESW
|
||||
-DPINS_DPAD_5WIRESW_OUT=32
|
||||
-DPINS_DPAD_5WIRESW_IN1=25
|
||||
-DPINS_DPAD_5WIRESW_IN2=26
|
||||
-DPINS_DPAD_5WIRESW_IN3=27
|
||||
-DPINS_DPAD_5WIRESW_IN4=21
|
||||
-DDPAD_5WIRESW_UP=4
|
||||
-DDPAD_5WIRESW_DOWN=3
|
||||
-DDPAD_5WIRESW_CONFIRM=7
|
||||
-DDPAD_5WIRESW_BACK=0
|
||||
-DDPAD_5WIRESW_PROFILE0=1
|
||||
-DDPAD_5WIRESW_PROFILE1=5
|
||||
-DDPAD_5WIRESW_PROFILE2=2
|
||||
-DDPAD_5WIRESW_PROFILE3=6
|
||||
; -DDPAD_5WIRESW_DEBUG
|
||||
-DDEFAULT_GASMIN=850
|
||||
-DDEFAULT_GASMAX=3700
|
||||
-DDEFAULT_BREMSMIN=1300
|
||||
@ -177,6 +200,7 @@ build_flags =
|
||||
${peters_platine.build_flags}
|
||||
${ota_common.build_flags}
|
||||
${default_limits.build_flags}
|
||||
${default_wheels_inverted.build_flags}
|
||||
-DDEVICE_PREFIX=bobbycar
|
||||
-DAP_PASSWORD=Passwort_123
|
||||
-DFEATURE_WEBSERVER
|
||||
@ -235,6 +259,7 @@ build_flags =
|
||||
${peters_platine.build_flags}
|
||||
${ota_common.build_flags}
|
||||
${default_limits.build_flags}
|
||||
${default_wheels_inverted.build_flags}
|
||||
-DDEVICE_PREFIX=bobbyquad
|
||||
-DAP_PASSWORD=Passwort_123
|
||||
-DFEATURE_WEBSERVER
|
||||
@ -283,6 +308,7 @@ build_flags =
|
||||
-DSPI_FREQUENCY=20000000
|
||||
-DSPI_TOUCH_FREQUENCY=2500000
|
||||
-DDEFAULT_SWAPSCREENBYTES=false
|
||||
${default_wheels_inverted.build_flags}
|
||||
; TODO: actually assign pins
|
||||
-DPINS_RX1=22
|
||||
-DPINS_TX1=25
|
||||
@ -310,6 +336,7 @@ build_flags =
|
||||
${peters_platine_reversed.build_flags}
|
||||
${ota_common.build_flags}
|
||||
${default_limits.build_flags}
|
||||
${default_wheels_inverted.build_flags}
|
||||
-DDEVICE_PREFIX=bobbycar
|
||||
-DAP_PASSWORD=Passwort_123
|
||||
-DFEATURE_WEBSERVER
|
||||
|
41
src/actions/erasenvsaction.h
Normal file
41
src/actions/erasenvsaction.h
Normal file
@ -0,0 +1,41 @@
|
||||
#pragma once
|
||||
|
||||
#include <HardwareSerial.h>
|
||||
|
||||
#include "actioninterface.h"
|
||||
#include "globals.h"
|
||||
#include "presets.h"
|
||||
|
||||
namespace {
|
||||
class EraseNvsAction : public virtual ActionInterface
|
||||
{
|
||||
public:
|
||||
void triggered() override
|
||||
{
|
||||
const auto profile = settingsPersister.currentlyOpenProfileIndex();
|
||||
|
||||
if (!settingsPersister.erase())
|
||||
{
|
||||
Serial.println("EraseNvsAction::triggered() erase failed");
|
||||
return;
|
||||
}
|
||||
|
||||
settings = presets::defaultSettings;
|
||||
|
||||
if (!profile)
|
||||
return;
|
||||
|
||||
if (!settingsPersister.openProfile(*profile))
|
||||
{
|
||||
Serial.println("EraseNvsAction::triggered() openProfile failed");
|
||||
return;
|
||||
}
|
||||
|
||||
if (!settingsPersister.load(settings))
|
||||
{
|
||||
Serial.println("EraseNvsAction::triggered() load failed");
|
||||
return;
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
27
src/actions/switchprofileaction.h
Normal file
27
src/actions/switchprofileaction.h
Normal file
@ -0,0 +1,27 @@
|
||||
#pragma once
|
||||
|
||||
#include <HardwareSerial.h>
|
||||
|
||||
#include "actioninterface.h"
|
||||
#include "globals.h"
|
||||
#include "presets.h"
|
||||
|
||||
namespace {
|
||||
template<uint8_t profile>
|
||||
class SwitchProfileAction : public virtual ActionInterface
|
||||
{
|
||||
public:
|
||||
void triggered() override
|
||||
{
|
||||
settings = presets::defaultSettings;
|
||||
|
||||
if (settingsPersister.openProfile(profile))
|
||||
{
|
||||
if (!settingsPersister.load(settings))
|
||||
Serial.println("SwitchProfileAction::triggered() load failed");
|
||||
}
|
||||
else
|
||||
Serial.println("SwitchProfileAction::triggered() openProfile failed");
|
||||
}
|
||||
};
|
||||
}
|
54
src/displays/dpad5wiredebugdisplay.h
Normal file
54
src/displays/dpad5wiredebugdisplay.h
Normal file
@ -0,0 +1,54 @@
|
||||
#pragma once
|
||||
|
||||
#include "display.h"
|
||||
#include "globals.h"
|
||||
#include "widgets/label.h"
|
||||
#include "dpad5wire.h"
|
||||
|
||||
namespace {
|
||||
#ifdef FEATURE_DPAD_5WIRESW
|
||||
class DPad5WireDebugDisplay : public Display, public virtual DummyConfirm, public virtual DummyBack
|
||||
{
|
||||
public:
|
||||
void initScreen() override;
|
||||
void redraw() override;
|
||||
|
||||
private:
|
||||
Label m_label0{30, 100};
|
||||
Label m_label1{30, 125};
|
||||
Label m_label2{30, 150};
|
||||
};
|
||||
|
||||
void DPad5WireDebugDisplay::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);
|
||||
|
||||
m_label0.start();
|
||||
m_label1.start();
|
||||
m_label2.start();
|
||||
}
|
||||
|
||||
void DPad5WireDebugDisplay::redraw()
|
||||
{
|
||||
m_label0.redraw(String{} +
|
||||
(std::get<0>(dpad5wire::lastState) ? '1' : '0') + ' ' +
|
||||
(std::get<1>(dpad5wire::lastState) ? '1' : '0') + ' ' +
|
||||
(std::get<2>(dpad5wire::lastState) ? '1' : '0') + ' ' +
|
||||
(std::get<3>(dpad5wire::lastState) ? '1' : '0') + ' ' +
|
||||
(std::get<4>(dpad5wire::lastState) ? '1' : '0') + ' ' +
|
||||
(std::get<5>(dpad5wire::lastState) ? '1' : '0') + ' ' +
|
||||
(std::get<6>(dpad5wire::lastState) ? '1' : '0') + ' ' +
|
||||
(std::get<7>(dpad5wire::lastState) ? '1' : '0'));
|
||||
m_label1.redraw(String{raw_gas});
|
||||
m_label2.redraw(String{raw_brems});
|
||||
}
|
||||
#endif
|
||||
}
|
@ -66,7 +66,7 @@ using BremsMaxChangeScreen = makeComponent<
|
||||
SwitchScreenAction<BoardcomputerHardwareSettingsMenu>
|
||||
>;
|
||||
|
||||
#if defined(FEATURE_DPAD) || defined(FEATURE_DPAD_3WIRESW)
|
||||
#if defined(FEATURE_DPAD) || defined(FEATURE_DPAD_3WIRESW) || defined(FEATURE_DPAD_5WIRESW)
|
||||
using DPadDebounceChangeScreen = makeComponent<
|
||||
ChangeValueDisplay<uint8_t>,
|
||||
StaticText<TEXT_SETDPADDEBOUNCE>,
|
||||
@ -147,7 +147,7 @@ class BoardcomputerHardwareSettingsMenu :
|
||||
makeComponent<MenuItem, StaticText<TEXT_SETGASMAX>, SwitchScreenAction<GasMaxChangeScreen>>,
|
||||
makeComponent<MenuItem, StaticText<TEXT_SETBREMSMIN>, SwitchScreenAction<BremsMinChangeScreen>>,
|
||||
makeComponent<MenuItem, StaticText<TEXT_SETBREMSMAX>, SwitchScreenAction<BremsMaxChangeScreen>>,
|
||||
#if defined(FEATURE_DPAD) || defined(FEATURE_DPAD_3WIRESW)
|
||||
#if defined(FEATURE_DPAD) || defined(FEATURE_DPAD_3WIRESW) || defined(FEATURE_DPAD_5WIRESW)
|
||||
makeComponent<MenuItem, StaticText<TEXT_SETDPADDEBOUNCE>, SwitchScreenAction<DPadDebounceChangeScreen>>,
|
||||
#endif
|
||||
#ifdef FEATURE_GAMETRAK
|
||||
|
@ -6,6 +6,7 @@
|
||||
#include "menuitem.h"
|
||||
#include "actions/loadsettingsaction.h"
|
||||
#include "actions/savesettingsaction.h"
|
||||
#include "actions/erasenvsaction.h"
|
||||
#include "actions/switchscreenaction.h"
|
||||
#include "actions/dummyaction.h"
|
||||
#include "actions/toggleboolaction.h"
|
||||
@ -40,6 +41,7 @@ class DebugMenu :
|
||||
public StaticMenuDefinition<
|
||||
makeComponent<MenuItem, StaticText<TEXT_LOADSETTINGS>, LoadSettingsAction>,
|
||||
makeComponent<MenuItem, StaticText<TEXT_SAVESETTINGS>, SaveSettingsAction>,
|
||||
makeComponent<MenuItem, StaticText<TEXT_ERASENVS>, EraseNvsAction>,
|
||||
makeComponent<MenuItem, StaticText<nullptr>, DummyAction>,
|
||||
makeComponent<MenuItem, StaticText<TEXT_FRONTCOMMAND>, SwitchScreenAction<FrontCommandDebugMenu>>,
|
||||
makeComponent<MenuItem, StaticText<TEXT_BACKCOMMAND>, SwitchScreenAction<BackCommandDebugMenu>>,
|
||||
|
@ -21,6 +21,7 @@
|
||||
namespace {
|
||||
class StatusDisplay;
|
||||
class SelectModeMenu;
|
||||
class ProfilesMenu;
|
||||
class PresetsMenu;
|
||||
class GraphsMenu;
|
||||
class BmsMenu;
|
||||
@ -42,6 +43,7 @@ class MainMenu :
|
||||
makeComponent<MenuItem, StaticText<TEXT_SELECTMODE>, SwitchScreenAction<SelectModeMenu>, StaticMenuItemIcon<&icons::modes>>,
|
||||
makeComponent<MenuItem, StaticText<TEXT_MODESETTINGS>, ModeSettingsAction>,
|
||||
makeComponent<MenuItem, StaticText<TEXT_PRESETS>, SwitchScreenAction<PresetsMenu>, StaticMenuItemIcon<&icons::presets>>,
|
||||
makeComponent<MenuItem, StaticText<TEXT_PROFILES>, SwitchScreenAction<ProfilesMenu>>,
|
||||
makeComponent<MenuItem, StaticText<TEXT_GRAPHS>, SwitchScreenAction<GraphsMenu>, StaticMenuItemIcon<&icons::graph>>,
|
||||
#ifdef FEATURE_BMS
|
||||
makeComponent<MenuItem, StaticText<TEXT_BMS>, SwitchScreenAction<BmsMenu>, StaticMenuItemIcon<&icons::bms>>,
|
||||
|
@ -4,7 +4,7 @@
|
||||
#include "menudisplay.h"
|
||||
#include "staticmenudefinition.h"
|
||||
#include "utils.h"
|
||||
#include "actions/dummyaction.h"
|
||||
#include "actions/multiaction.h"
|
||||
#include "actions/switchscreenaction.h"
|
||||
#include "icons/back.h"
|
||||
#include "texts.h"
|
||||
@ -77,17 +77,17 @@ class PresetsMenu :
|
||||
public StaticText<TEXT_PRESETS>,
|
||||
public BackActionInterface<SwitchScreenAction<MainMenu>>,
|
||||
public StaticMenuDefinition<
|
||||
makeComponent<MenuItem, StaticText<TEXT_DEFAULTEVERYTHING>, ApplySettingsPresetAction<&presets::defaultSettings>>,
|
||||
makeComponent<MenuItem, StaticText<TEXT_DEFAULTLIMITS>, ApplyLimitsPresetAction<&presets::defaultLimits>>,
|
||||
makeComponent<MenuItem, StaticText<TEXT_KIDSLIMITS>, ApplyLimitsPresetAction<&presets::kidsLimits>>,
|
||||
makeComponent<MenuItem, StaticText<TEXT_DEFAULTCONTROLLERHARDWARE>, ApplyControllerHardwarePresetAction<&presets::defaultControllerHardware>>,
|
||||
makeComponent<MenuItem, StaticText<TEXT_MOSFETSOFFCONTROLLERHARDWARE>, ApplyControllerHardwarePresetAction<&presets::mosfetsOffControllerHardware>>,
|
||||
makeComponent<MenuItem, StaticText<TEXT_SPINNERCONTROLLERHARDWARE>, ApplyControllerHardwarePresetAction<&presets::spinnerControllerHardware>>,
|
||||
makeComponent<MenuItem, StaticText<TEXT_DEFAULTBOARDCOMPUTERHARDWARE>, ApplyBoardcomputerHardwarePresetAction<&presets::defaultBoardcomputerHardware>>,
|
||||
makeComponent<MenuItem, StaticText<TEXT_DEFAULTDEFAULTMODE>, ApplyDefaultModePresetAction<&presets::defaultDefaultMode>>,
|
||||
makeComponent<MenuItem, StaticText<TEXT_SINUSOIDALDEFAULTMODE>, ApplyDefaultModePresetAction<&presets::sinusoidalDefaultMode>>,
|
||||
makeComponent<MenuItem, StaticText<TEXT_DEFAULTTEMPOMATMODE>, ApplyTempomatModePresetAction<&presets::defaultTempomatMode>>,
|
||||
makeComponent<MenuItem, StaticText<TEXT_DEFAULTLARSMMODE>, ApplyLarsmModePresetAction<&presets::defaultLarsmMode>>,
|
||||
makeComponent<MenuItem, StaticText<TEXT_DEFAULTEVERYTHING>, MultiAction<ApplySettingsPresetAction<&presets::defaultSettings>, SwitchScreenAction<MainMenu>>>,
|
||||
makeComponent<MenuItem, StaticText<TEXT_DEFAULTLIMITS>, MultiAction<ApplyLimitsPresetAction<&presets::defaultLimits>, SwitchScreenAction<MainMenu>>>,
|
||||
makeComponent<MenuItem, StaticText<TEXT_KIDSLIMITS>, MultiAction<ApplyLimitsPresetAction<&presets::kidsLimits>, SwitchScreenAction<MainMenu>>>,
|
||||
makeComponent<MenuItem, StaticText<TEXT_DEFAULTCONTROLLERHARDWARE>, MultiAction<ApplyControllerHardwarePresetAction<&presets::defaultControllerHardware>, SwitchScreenAction<MainMenu>>>,
|
||||
makeComponent<MenuItem, StaticText<TEXT_MOSFETSOFFCONTROLLERHARDWARE>, MultiAction<ApplyControllerHardwarePresetAction<&presets::mosfetsOffControllerHardware>, SwitchScreenAction<MainMenu>>>,
|
||||
makeComponent<MenuItem, StaticText<TEXT_SPINNERCONTROLLERHARDWARE>, MultiAction<ApplyControllerHardwarePresetAction<&presets::spinnerControllerHardware>, SwitchScreenAction<MainMenu>>>,
|
||||
makeComponent<MenuItem, StaticText<TEXT_DEFAULTBOARDCOMPUTERHARDWARE>, MultiAction<ApplyBoardcomputerHardwarePresetAction<&presets::defaultBoardcomputerHardware>, SwitchScreenAction<MainMenu>>>,
|
||||
makeComponent<MenuItem, StaticText<TEXT_DEFAULTDEFAULTMODE>, MultiAction<ApplyDefaultModePresetAction<&presets::defaultDefaultMode>, SwitchScreenAction<MainMenu>>>,
|
||||
makeComponent<MenuItem, StaticText<TEXT_SINUSOIDALDEFAULTMODE>, MultiAction<ApplyDefaultModePresetAction<&presets::sinusoidalDefaultMode>, SwitchScreenAction<MainMenu>>>,
|
||||
makeComponent<MenuItem, StaticText<TEXT_DEFAULTTEMPOMATMODE>, MultiAction<ApplyTempomatModePresetAction<&presets::defaultTempomatMode>, SwitchScreenAction<MainMenu>>>,
|
||||
makeComponent<MenuItem, StaticText<TEXT_DEFAULTLARSMMODE>, MultiAction<ApplyLarsmModePresetAction<&presets::defaultLarsmMode>, SwitchScreenAction<MainMenu>>>,
|
||||
makeComponent<MenuItem, StaticText<TEXT_BACK>, SwitchScreenAction<MainMenu>, StaticMenuItemIcon<&icons::back>>
|
||||
>
|
||||
{};
|
||||
|
27
src/displays/menus/profilesmenu.h
Normal file
27
src/displays/menus/profilesmenu.h
Normal file
@ -0,0 +1,27 @@
|
||||
#pragma once
|
||||
|
||||
#include "menudisplay.h"
|
||||
#include "staticmenudefinition.h"
|
||||
#include "actions/switchprofileaction.h"
|
||||
#include "actions/switchscreenaction.h"
|
||||
#include "icons/back.h"
|
||||
#include "texts.h"
|
||||
|
||||
namespace {
|
||||
class MainMenu;
|
||||
}
|
||||
|
||||
namespace {
|
||||
class ProfilesMenu :
|
||||
public MenuDisplay,
|
||||
public StaticText<TEXT_PROFILES>,
|
||||
public BackActionInterface<SwitchScreenAction<MainMenu>>,
|
||||
public StaticMenuDefinition<
|
||||
makeComponent<MenuItem, StaticText<TEXT_PROFILE0>, SwitchProfileAction<0>>,
|
||||
makeComponent<MenuItem, StaticText<TEXT_PROFILE1>, SwitchProfileAction<1>>,
|
||||
makeComponent<MenuItem, StaticText<TEXT_PROFILE2>, SwitchProfileAction<2>>,
|
||||
makeComponent<MenuItem, StaticText<TEXT_PROFILE3>, SwitchProfileAction<3>>,
|
||||
makeComponent<MenuItem, StaticText<TEXT_BACK>, SwitchScreenAction<MainMenu>, StaticMenuItemIcon<&icons::back>>
|
||||
>
|
||||
{};
|
||||
}
|
@ -99,6 +99,7 @@ private:
|
||||
Label m_labelPerformance{85, bottomLines[2]}; // 40, 15
|
||||
Label m_labelMode{165, bottomLines[2]}; // 75, 15
|
||||
Label m_labelName{40, bottomLines[3]}; // 40, 15
|
||||
Label m_labelProfile{205, bottomLines[3]}; // 35, 15
|
||||
|
||||
static const constexpr int bottomLines[4] { 251, 266, 281, 296 };
|
||||
};
|
||||
@ -136,6 +137,7 @@ void StatusDisplay::initScreen()
|
||||
m_labelMode.start();
|
||||
tft.drawString("Name:", 0, bottomLines[3]);
|
||||
m_labelName.start();
|
||||
m_labelProfile.start();
|
||||
|
||||
tft.setTextColor(TFT_WHITE, TFT_BLACK);
|
||||
}
|
||||
@ -161,6 +163,8 @@ void StatusDisplay::redraw()
|
||||
m_labelPerformance.redraw(String{performance.last});
|
||||
m_labelMode.redraw(currentMode->displayName());
|
||||
m_labelName.redraw(&deviceName[0]);
|
||||
const auto profile = settingsPersister.currentlyOpenProfileIndex();
|
||||
m_labelProfile.redraw(profile?String{*profile}:"-");
|
||||
}
|
||||
|
||||
void StatusDisplay::rotate(int offset)
|
||||
|
158
src/dpad5wire.h
Normal file
158
src/dpad5wire.h
Normal file
@ -0,0 +1,158 @@
|
||||
#pragma once
|
||||
|
||||
#include <tuple>
|
||||
|
||||
#include <Arduino.h>
|
||||
|
||||
#include "globals.h"
|
||||
#include "types.h"
|
||||
#include "actions/switchprofileaction.h"
|
||||
|
||||
namespace {
|
||||
namespace dpad5wire
|
||||
{
|
||||
using State = std::tuple<bool, bool, bool, bool, bool, bool, bool, bool>;
|
||||
|
||||
template<pin_t OUT, pin_t IN1, pin_t IN2, pin_t IN3, pin_t IN4>
|
||||
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;
|
||||
|
||||
void begin();
|
||||
|
||||
State read();
|
||||
};
|
||||
|
||||
template<pin_t OUT, pin_t IN1, pin_t IN2, pin_t IN3, pin_t IN4>
|
||||
void Helper<OUT, IN1, IN2, IN3, IN4>::begin()
|
||||
{
|
||||
pinMode(OUT, OUTPUT);
|
||||
}
|
||||
|
||||
template<pin_t OUT, pin_t IN1, pin_t IN2, pin_t IN3, pin_t IN4>
|
||||
State Helper<OUT, IN1, IN2, IN3, IN4>::read()
|
||||
{
|
||||
digitalWrite(OUT, LOW);
|
||||
|
||||
pinMode(IN1, INPUT_PULLUP);
|
||||
pinMode(IN2, INPUT_PULLUP);
|
||||
pinMode(IN3, INPUT_PULLUP);
|
||||
pinMode(IN4, INPUT_PULLUP);
|
||||
|
||||
delay(1);
|
||||
|
||||
const bool result0 = digitalRead(IN1)==LOW;
|
||||
const bool result1 = digitalRead(IN2)==LOW;
|
||||
const bool result2 = digitalRead(IN3)==LOW;
|
||||
const bool result3 = digitalRead(IN4)==LOW;
|
||||
|
||||
digitalWrite(OUT, HIGH);
|
||||
|
||||
pinMode(IN1, INPUT_PULLDOWN);
|
||||
pinMode(IN2, INPUT_PULLDOWN);
|
||||
pinMode(IN3, INPUT_PULLDOWN);
|
||||
pinMode(IN4, INPUT_PULLDOWN);
|
||||
|
||||
delay(1);
|
||||
|
||||
const bool result4 = digitalRead(IN1);
|
||||
const bool result5 = digitalRead(IN2);
|
||||
const bool result6 = digitalRead(IN3);
|
||||
const bool result7 = digitalRead(IN4);
|
||||
|
||||
return std::make_tuple(result0, result1, result2, result3, result4, result5, result6, result7);
|
||||
}
|
||||
|
||||
#ifdef FEATURE_DPAD_5WIRESW
|
||||
Helper<PINS_DPAD_5WIRESW_OUT, PINS_DPAD_5WIRESW_IN1, PINS_DPAD_5WIRESW_IN2, PINS_DPAD_5WIRESW_IN3, PINS_DPAD_5WIRESW_IN4> helper;
|
||||
State lastState;
|
||||
millis_t debounceUp, debounceDown, debounceConfirm, debounceBack, debounceProfile0, debounceProfile1, debounceProfile2, debounceProfile3;
|
||||
|
||||
void init()
|
||||
{
|
||||
helper.begin();
|
||||
debounceUp = debounceDown = debounceConfirm = debounceBack = debounceProfile0 = debounceProfile1 = debounceProfile2 = debounceProfile3 = millis();
|
||||
}
|
||||
|
||||
void update()
|
||||
{
|
||||
const auto state = helper.read();
|
||||
|
||||
#ifdef DPAD_5WIRESW_DEBUG
|
||||
lastState = state;
|
||||
return;
|
||||
#endif
|
||||
|
||||
const auto now = millis();
|
||||
|
||||
if (std::get<DPAD_5WIRESW_UP>(lastState) != std::get<DPAD_5WIRESW_UP>(state) && now-debounceUp > settings.boardcomputerHardware.dpadDebounce)
|
||||
{
|
||||
if (std::get<DPAD_5WIRESW_UP>(state))
|
||||
InputDispatcher::rotate(-1);
|
||||
std::get<DPAD_5WIRESW_UP>(lastState) = std::get<DPAD_5WIRESW_UP>(state);
|
||||
debounceUp = now;
|
||||
}
|
||||
if (std::get<DPAD_5WIRESW_DOWN>(lastState) != std::get<DPAD_5WIRESW_DOWN>(state) && now-debounceDown > settings.boardcomputerHardware.dpadDebounce)
|
||||
{
|
||||
if (std::get<DPAD_5WIRESW_DOWN>(state))
|
||||
InputDispatcher::rotate(1);
|
||||
std::get<DPAD_5WIRESW_DOWN>(lastState) = std::get<DPAD_5WIRESW_DOWN>(state);
|
||||
debounceDown = now;
|
||||
}
|
||||
if (std::get<DPAD_5WIRESW_CONFIRM>(lastState) != std::get<DPAD_5WIRESW_CONFIRM>(state) && now-debounceConfirm > settings.boardcomputerHardware.dpadDebounce)
|
||||
{
|
||||
InputDispatcher::confirmButton(std::get<DPAD_5WIRESW_CONFIRM>(state));
|
||||
std::get<DPAD_5WIRESW_CONFIRM>(lastState) = std::get<DPAD_5WIRESW_CONFIRM>(state);
|
||||
debounceConfirm = now;
|
||||
}
|
||||
if (std::get<DPAD_5WIRESW_BACK>(lastState) != std::get<DPAD_5WIRESW_BACK>(state) && now-debounceBack > settings.boardcomputerHardware.dpadDebounce)
|
||||
{
|
||||
InputDispatcher::backButton(std::get<DPAD_5WIRESW_BACK>(state));
|
||||
std::get<DPAD_5WIRESW_BACK>(lastState) = std::get<DPAD_5WIRESW_BACK>(state);
|
||||
debounceBack = now;
|
||||
}
|
||||
if (std::get<DPAD_5WIRESW_PROFILE0>(lastState) != std::get<DPAD_5WIRESW_PROFILE0>(state) && now-debounceProfile0 > settings.boardcomputerHardware.dpadDebounce)
|
||||
{
|
||||
if (std::get<DPAD_5WIRESW_PROFILE0>(state))
|
||||
{
|
||||
SwitchProfileAction<0>{}.triggered();
|
||||
}
|
||||
std::get<DPAD_5WIRESW_PROFILE0>(lastState) = std::get<DPAD_5WIRESW_PROFILE0>(state);
|
||||
debounceProfile0 = now;
|
||||
}
|
||||
if (std::get<DPAD_5WIRESW_PROFILE1>(lastState) != std::get<DPAD_5WIRESW_PROFILE1>(state) && now-debounceProfile1 > settings.boardcomputerHardware.dpadDebounce)
|
||||
{
|
||||
if (std::get<DPAD_5WIRESW_PROFILE1>(state))
|
||||
{
|
||||
SwitchProfileAction<1>{}.triggered();
|
||||
}
|
||||
std::get<DPAD_5WIRESW_PROFILE1>(lastState) = std::get<DPAD_5WIRESW_PROFILE1>(state);
|
||||
debounceProfile1 = now;
|
||||
}
|
||||
if (std::get<DPAD_5WIRESW_PROFILE2>(lastState) != std::get<DPAD_5WIRESW_PROFILE2>(state) && now-debounceProfile2 > settings.boardcomputerHardware.dpadDebounce)
|
||||
{
|
||||
if (std::get<DPAD_5WIRESW_PROFILE2>(state))
|
||||
{
|
||||
SwitchProfileAction<2>{}.triggered();
|
||||
}
|
||||
std::get<DPAD_5WIRESW_PROFILE2>(lastState) = std::get<DPAD_5WIRESW_PROFILE2>(state);
|
||||
debounceProfile2 = now;
|
||||
}
|
||||
if (std::get<DPAD_5WIRESW_PROFILE3>(lastState) != std::get<DPAD_5WIRESW_PROFILE3>(state) && now-debounceProfile3 > settings.boardcomputerHardware.dpadDebounce)
|
||||
{
|
||||
if (std::get<DPAD_5WIRESW_PROFILE3>(state))
|
||||
{
|
||||
SwitchProfileAction<3>{}.triggered();
|
||||
}
|
||||
std::get<DPAD_5WIRESW_PROFILE3>(lastState) = std::get<DPAD_5WIRESW_PROFILE3>(state);
|
||||
debounceProfile3 = now;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
@ -11,7 +11,7 @@
|
||||
#include "display.h"
|
||||
#include "modeinterface.h"
|
||||
#include "settings.h"
|
||||
#include "settingssaver.h"
|
||||
#include "settingspersister.h"
|
||||
#include "types.h"
|
||||
|
||||
namespace {
|
||||
@ -26,7 +26,7 @@ float avgSpeed, avgSpeedKmh, sumCurrent;
|
||||
char deviceName[32];
|
||||
|
||||
Settings settings;
|
||||
SettingsSaver settingsSaver;
|
||||
SettingsPersister settingsPersister;
|
||||
|
||||
constexpr auto TFT_GREY = 0x5AEB;
|
||||
|
||||
|
55
src/main.cpp
55
src/main.cpp
@ -12,9 +12,11 @@
|
||||
#include "globals.h"
|
||||
#include "modes/defaultmode.h"
|
||||
#include "modes/tempomatmode.h"
|
||||
#include "displays/dpad5wiredebugdisplay.h"
|
||||
#include "screens.h"
|
||||
#include "dpad.h"
|
||||
#include "dpad3wire.h"
|
||||
#include "dpad5wire.h"
|
||||
#include "rotary.h"
|
||||
#include "serialhandler.h"
|
||||
#include "ota.h"
|
||||
@ -48,18 +50,27 @@ void setup()
|
||||
initScreen();
|
||||
|
||||
#ifdef FEATURE_DPAD
|
||||
bootLabel.redraw("dpad");
|
||||
dpad::init();
|
||||
#endif
|
||||
|
||||
#ifdef FEATURE_DPAD_3WIRESW
|
||||
bootLabel.redraw("dpad3wire");
|
||||
dpad3wire::init();
|
||||
#endif
|
||||
|
||||
#ifdef FEATURE_DPAD_5WIRESW
|
||||
bootLabel.redraw("dpad5wire");
|
||||
dpad5wire::init();
|
||||
#endif
|
||||
|
||||
#ifdef FEATURE_ROTARY
|
||||
bootLabel.redraw("rotary");
|
||||
initRotary();
|
||||
#endif
|
||||
|
||||
#ifdef FEATURE_MOSFETS
|
||||
bootLabel.redraw("mosfets");
|
||||
pinMode(PINS_MOSFET0, OUTPUT);
|
||||
pinMode(PINS_MOSFET1, OUTPUT);
|
||||
pinMode(PINS_MOSFET2, OUTPUT);
|
||||
@ -69,45 +80,71 @@ void setup()
|
||||
digitalWrite(PINS_MOSFET2, LOW);
|
||||
#endif
|
||||
|
||||
bootLabel.redraw("settings");
|
||||
settings = presets::defaultSettings;
|
||||
|
||||
if (settingsSaver.init())
|
||||
loadSettings();
|
||||
if (settingsPersister.init())
|
||||
{
|
||||
if (settingsPersister.openProfile(0))
|
||||
{
|
||||
loadSettings();
|
||||
}
|
||||
}
|
||||
|
||||
bootLabel.redraw("swap front back");
|
||||
updateSwapFrontBack();
|
||||
|
||||
bootLabel.redraw("deviceName");
|
||||
{
|
||||
uint8_t macAddress[6];
|
||||
WiFi.macAddress(&macAddress[0]);
|
||||
std::sprintf(deviceName, STRING(DEVICE_PREFIX) "_%02hhx%02hhx%02hhx", macAddress[3], macAddress[4], macAddress[5]);
|
||||
}
|
||||
|
||||
bootLabel.redraw("setHostname");
|
||||
if (!WiFi.setHostname(deviceName))
|
||||
Serial.println("Could not setHostname");
|
||||
|
||||
bootLabel.redraw("softAPsetHostname");
|
||||
if (!WiFi.softAPsetHostname(deviceName))
|
||||
Serial.println("Could not softAPsetHostname");
|
||||
|
||||
bootLabel.redraw("WiFi mode");
|
||||
if (!WiFi.mode(settings.wifiSettings.autoWifiMode))
|
||||
Serial.println("Could not set mode to WIFI_AP_STA");
|
||||
|
||||
if (settings.wifiSettings.autoEnableAp)
|
||||
{
|
||||
bootLabel.redraw("WiFi softAp");
|
||||
WifiSoftApAction{}.triggered();
|
||||
}
|
||||
|
||||
bootLabel.redraw("WiFi begin");
|
||||
if (!WiFi.begin("realraum", "r3alraum"))
|
||||
Serial.println("Could not begin WiFi");
|
||||
|
||||
if (settings.bluetoothSettings.autoBluetoothMode == BluetoothMode::Master)
|
||||
{
|
||||
bootLabel.redraw("bluetooth begin master");
|
||||
BluetoothBeginMasterAction{}.triggered();
|
||||
#ifdef FEATURE_BMS
|
||||
if (settings.autoConnectBms)
|
||||
{
|
||||
bootLabel.redraw("connect BMS");
|
||||
BluetoothConnectBmsAction{}.triggered();
|
||||
}
|
||||
#endif
|
||||
} else if (settings.bluetoothSettings.autoBluetoothMode == BluetoothMode::Slave)
|
||||
}
|
||||
else if (settings.bluetoothSettings.autoBluetoothMode == BluetoothMode::Slave)
|
||||
{
|
||||
bootLabel.redraw("bluetooth begin");
|
||||
BluetoothBeginAction{}.triggered();
|
||||
}
|
||||
|
||||
bootLabel.redraw("front Serial begin");
|
||||
controllers.front.serial.get().begin(38400, SERIAL_8N1, PINS_RX1, PINS_TX1);
|
||||
|
||||
bootLabel.redraw("back Serial begin");
|
||||
controllers.back.serial.get().begin(38400, SERIAL_8N1, PINS_RX2, PINS_TX2);
|
||||
|
||||
raw_gas = 0;
|
||||
@ -121,13 +158,21 @@ void setup()
|
||||
currentMode = &modes::defaultMode;
|
||||
|
||||
#ifdef FEATURE_OTA
|
||||
bootLabel.redraw("ota");
|
||||
initOta();
|
||||
#endif
|
||||
|
||||
bootLabel.redraw("webserver");
|
||||
initWebserver();
|
||||
|
||||
bootLabel.redraw("potis");
|
||||
readPotis();
|
||||
|
||||
#if defined(FEATURE_DPAD_5WIRESW) && defined(DPAD_5WIRESW_DEBUG)
|
||||
switchScreen<DPad5WireDebugDisplay>();
|
||||
return;
|
||||
#endif
|
||||
|
||||
if (gas > 200.f || brems > 200.f)
|
||||
switchScreen<CalibrateDisplay>(true);
|
||||
else
|
||||
@ -146,6 +191,10 @@ void loop()
|
||||
dpad3wire::update();
|
||||
#endif
|
||||
|
||||
#ifdef FEATURE_DPAD_5WIRESW
|
||||
dpad5wire::update();
|
||||
#endif
|
||||
|
||||
if (!lastPotiRead || now - lastPotiRead >= 1000/settings.boardcomputerHardware.timersSettings.potiReadRate)
|
||||
{
|
||||
readPotis();
|
||||
|
@ -25,10 +25,10 @@ constexpr Settings::ControllerHardware defaultControllerHardware {
|
||||
.enableBackLeft = true,
|
||||
.enableBackRight = true,
|
||||
|
||||
.invertFrontLeft = false,
|
||||
.invertFrontRight = true,
|
||||
.invertBackLeft = false,
|
||||
.invertBackRight = true,
|
||||
.invertFrontLeft = DEFAULT_INVERTFRONTLEFT,
|
||||
.invertFrontRight = DEFAULT_INVERTFRONTRIGHT,
|
||||
.invertBackLeft = DEFAULT_INVERTBACKLEFT,
|
||||
.invertBackRight = DEFAULT_INVERTBACKRIGHT,
|
||||
|
||||
.wheelDiameter = 165,
|
||||
.numMagnetPoles = 15,
|
||||
@ -41,10 +41,10 @@ constexpr Settings::ControllerHardware mosfetsOffControllerHardware {
|
||||
.enableBackLeft = false,
|
||||
.enableBackRight = false,
|
||||
|
||||
.invertFrontLeft = false,
|
||||
.invertFrontRight = true,
|
||||
.invertBackLeft = false,
|
||||
.invertBackRight = true,
|
||||
.invertFrontLeft = DEFAULT_INVERTFRONTLEFT,
|
||||
.invertFrontRight = DEFAULT_INVERTFRONTRIGHT,
|
||||
.invertBackLeft = DEFAULT_INVERTBACKLEFT,
|
||||
.invertBackRight = DEFAULT_INVERTBACKRIGHT,
|
||||
|
||||
.wheelDiameter = 165,
|
||||
.numMagnetPoles = 15,
|
||||
@ -57,7 +57,7 @@ constexpr Settings::WifiSettings defaultWifiSettings {
|
||||
};
|
||||
|
||||
constexpr Settings::BluetoothSettings defaultBluetoothSettings {
|
||||
.autoBluetoothMode = BluetoothMode::Off
|
||||
.autoBluetoothMode = BluetoothMode::Master
|
||||
};
|
||||
|
||||
constexpr Settings::ControllerHardware spinnerControllerHardware {
|
||||
@ -66,10 +66,10 @@ constexpr Settings::ControllerHardware spinnerControllerHardware {
|
||||
.enableBackLeft = true,
|
||||
.enableBackRight = true,
|
||||
|
||||
.invertFrontLeft = false,
|
||||
.invertFrontRight = false,
|
||||
.invertBackLeft = false,
|
||||
.invertBackRight = false,
|
||||
.invertFrontLeft = DEFAULT_INVERTFRONTLEFT,
|
||||
.invertFrontRight = !DEFAULT_INVERTFRONTRIGHT,
|
||||
.invertBackLeft = DEFAULT_INVERTBACKLEFT,
|
||||
.invertBackRight = !DEFAULT_INVERTBACKRIGHT,
|
||||
|
||||
.wheelDiameter = 165,
|
||||
.numMagnetPoles = 15,
|
||||
@ -90,7 +90,7 @@ constexpr Settings::BoardcomputerHardware defaultBoardcomputerHardware {
|
||||
.gasMax = DEFAULT_GASMAX,
|
||||
.bremsMin = DEFAULT_BREMSMIN,
|
||||
.bremsMax = DEFAULT_BREMSMAX,
|
||||
#if defined(FEATURE_DPAD) || defined(FEATURE_DPAD_3WIRESW)
|
||||
#if defined(FEATURE_DPAD) || defined(FEATURE_DPAD_3WIRESW) || defined(FEATURE_DPAD_5WIRESW)
|
||||
.dpadDebounce = 25,
|
||||
#endif
|
||||
#ifdef FEATURE_GAMETRAK
|
||||
|
@ -1,5 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
#include <include/tl/optional.hpp>
|
||||
|
||||
#include "displays/menus/aboutmenu.h"
|
||||
#include "displays/menus/accesspointwifisettingsmenu.h"
|
||||
#include "displays/menus/bluetoothsettingsmenu.h"
|
||||
@ -25,6 +27,7 @@
|
||||
#include "displays/menus/mosfetsmenu.h"
|
||||
#include "displays/menus/motorfeedbackdebugmenu.h"
|
||||
#include "displays/menus/motorstatedebugmenu.h"
|
||||
#include "displays/menus/profilesmenu.h"
|
||||
#include "displays/menus/presetsmenu.h"
|
||||
#include "displays/menus/boardcomputerhardwaresettingsmenu.h"
|
||||
#include "displays/menus/selectmodemenu.h"
|
||||
@ -35,6 +38,7 @@
|
||||
#include "displays/menus/wifisettingsmenu.h"
|
||||
#include "displays/bmsdisplay.h"
|
||||
#include "displays/calibratedisplay.h"
|
||||
#include "displays/dpad5wiredebugdisplay.h"
|
||||
#include "displays/gameoflifedisplay.h"
|
||||
#include "displays/gametrakcalibratedisplay.h"
|
||||
#include "displays/lockscreen.h"
|
||||
@ -48,9 +52,12 @@
|
||||
|
||||
#include "globals.h"
|
||||
#include "utils.h"
|
||||
#include "widgets/label.h"
|
||||
#include "icons/logo.h"
|
||||
|
||||
namespace {
|
||||
Label bootLabel{32, 250};
|
||||
|
||||
union X {
|
||||
X() {}
|
||||
~X() { ((Display&)statusDisplay).~Display(); }
|
||||
@ -95,6 +102,7 @@ union X {
|
||||
BackLeftMotorFeedbackDebugMenu backLeftMotorFeedbackDebugMenu;
|
||||
BackRightMotorFeedbackDebugMenu backRightMotorFeedbackDebugMenu;
|
||||
BoardcomputerHardwareSettingsMenu boardcomputerHardwareSettingsMenu;
|
||||
ProfilesMenu profilesMenu;
|
||||
PresetsMenu presetsMenu;
|
||||
SelectModeMenu selectModeMenu;
|
||||
SettingsMenu settingsMenu;
|
||||
@ -107,6 +115,9 @@ union X {
|
||||
BmsDisplay bmsDisplay;
|
||||
#endif
|
||||
CalibrateDisplay calibrateDisplay;
|
||||
#if defined(FEATURE_DPAD_5WIRESW) && defined(DPAD_5WIRESW_DEBUG)
|
||||
DPad5WireDebugDisplay dPad5WireDebugDisplay;
|
||||
#endif
|
||||
GameOfLifeDisplay gameOfLifeDisplay;
|
||||
#ifdef FEATURE_GAMETRAK
|
||||
GametrakCalibrateDisplay gametrakCalibrateDisplay;
|
||||
@ -167,7 +178,7 @@ union X {
|
||||
GasMaxChangeScreen changeGasMax;
|
||||
BremsMinChangeScreen changeBremsMin;
|
||||
BremsMaxChangeScreen changeBremsMax;
|
||||
#if defined(FEATURE_DPAD) || defined(FEATURE_DPAD_3WIRESW)
|
||||
#if defined(FEATURE_DPAD) || defined(FEATURE_DPAD_3WIRESW) || defined(FEATURE_DPAD_5WIRESW)
|
||||
DPadDebounceChangeScreen dPadDebounceChangeScreen;
|
||||
#endif
|
||||
#ifdef FEATURE_GAMETRAK
|
||||
@ -249,6 +260,7 @@ template<> decltype(displays.frontLeftMotorFeedbackDebugMenu) &
|
||||
template<> decltype(displays.frontRightMotorFeedbackDebugMenu) &getRefByType<decltype(displays.frontRightMotorFeedbackDebugMenu)>() { return displays.frontRightMotorFeedbackDebugMenu; }
|
||||
template<> decltype(displays.backLeftMotorFeedbackDebugMenu) &getRefByType<decltype(displays.backLeftMotorFeedbackDebugMenu)>() { return displays.backLeftMotorFeedbackDebugMenu; }
|
||||
template<> decltype(displays.backRightMotorFeedbackDebugMenu) &getRefByType<decltype(displays.backRightMotorFeedbackDebugMenu)>() { return displays.backRightMotorFeedbackDebugMenu; }
|
||||
template<> decltype(displays.profilesMenu) &getRefByType<decltype(displays.profilesMenu)>() { return displays.profilesMenu; }
|
||||
template<> decltype(displays.presetsMenu) &getRefByType<decltype(displays.presetsMenu)>() { return displays.presetsMenu; }
|
||||
template<> decltype(displays.selectModeMenu) &getRefByType<decltype(displays.selectModeMenu)>() { return displays.selectModeMenu; }
|
||||
template<> decltype(displays.settingsMenu) &getRefByType<decltype(displays.settingsMenu)>() { return displays.settingsMenu; }
|
||||
@ -262,6 +274,9 @@ template<> decltype(displays.wifiSettingsMenu) &
|
||||
template<> decltype(displays.bmsDisplay) &getRefByType<decltype(displays.bmsDisplay)>() { return displays.bmsDisplay; }
|
||||
#endif
|
||||
template<> decltype(displays.calibrateDisplay) &getRefByType<decltype(displays.calibrateDisplay)>() { return displays.calibrateDisplay; }
|
||||
#if defined(FEATURE_DPAD_5WIRESW) && defined(DPAD_5WIRESW_DEBUG)
|
||||
template<> decltype(displays.dPad5WireDebugDisplay) &getRefByType<decltype(displays.dPad5WireDebugDisplay)>() { return displays.dPad5WireDebugDisplay; }
|
||||
#endif
|
||||
template<> decltype(displays.gameOfLifeDisplay) &getRefByType<decltype(displays.gameOfLifeDisplay)>() { return displays.gameOfLifeDisplay; }
|
||||
#ifdef FEATURE_GAMETRAK
|
||||
template<> decltype(displays.gametrakCalibrateDisplay) &getRefByType<decltype(displays.gametrakCalibrateDisplay)>() { return displays.gametrakCalibrateDisplay; }
|
||||
@ -322,7 +337,7 @@ template<> decltype(displays.changeGasMin) &
|
||||
template<> decltype(displays.changeGasMax) &getRefByType<decltype(displays.changeGasMax)>() { return displays.changeGasMax; }
|
||||
template<> decltype(displays.changeBremsMin) &getRefByType<decltype(displays.changeBremsMin)>() { return displays.changeBremsMin; }
|
||||
template<> decltype(displays.changeBremsMax) &getRefByType<decltype(displays.changeBremsMax)>() { return displays.changeBremsMax; }
|
||||
#if defined(FEATURE_DPAD) || defined(FEATURE_DPAD_3WIRESW)
|
||||
#if defined(FEATURE_DPAD) || defined(FEATURE_DPAD_3WIRESW) || defined(FEATURE_DPAD_5WIRESW)
|
||||
template<> decltype(displays.dPadDebounceChangeScreen) &getRefByType<decltype(displays.dPadDebounceChangeScreen)>() { return displays.dPadDebounceChangeScreen; }
|
||||
#endif
|
||||
#ifdef FEATURE_GAMETRAK
|
||||
@ -402,10 +417,12 @@ void initScreen()
|
||||
{
|
||||
tft.init();
|
||||
tft.fillScreen(TFT_WHITE);
|
||||
tft.setTextColor(TFT_BLACK);
|
||||
tft.setTextColor(TFT_BLACK, TFT_WHITE);
|
||||
tft.setTextFont(4);
|
||||
tft.pushImage(0, 40, icons::logo.WIDTH, icons::logo.HEIGHT, icons::logo.buffer);
|
||||
tft.drawString("Bobbycar-OS", 32, 200, 4);
|
||||
tft.drawString("booting...", 32, 225, 4);
|
||||
tft.drawString("Bobbycar-OS", 32, 200);
|
||||
tft.drawString("booting...", 32, 225);
|
||||
bootLabel.start();
|
||||
}
|
||||
|
||||
void updateDisplay()
|
||||
|
@ -53,7 +53,7 @@ struct Settings
|
||||
struct BoardcomputerHardware {
|
||||
int16_t sampleCount;
|
||||
int16_t gasMin, gasMax, bremsMin, bremsMax;
|
||||
#if defined(FEATURE_DPAD) || defined(FEATURE_DPAD_3WIRESW)
|
||||
#if defined(FEATURE_DPAD) || defined(FEATURE_DPAD_3WIRESW) || defined(FEATURE_DPAD_5WIRESW)
|
||||
uint8_t dpadDebounce;
|
||||
#endif
|
||||
#ifdef FEATURE_GAMETRAK
|
||||
@ -141,7 +141,7 @@ void Settings::executeForEverySetting(T &&callable)
|
||||
callable("gasMax", boardcomputerHardware.gasMax);
|
||||
callable("bremsMin", boardcomputerHardware.bremsMin);
|
||||
callable("bremsMax", boardcomputerHardware.bremsMax);
|
||||
#if defined(FEATURE_DPAD) || defined(FEATURE_DPAD_3WIRESW)
|
||||
#if defined(FEATURE_DPAD) || defined(FEATURE_DPAD_3WIRESW) || defined(FEATURE_DPAD_5WIRESW)
|
||||
callable("dpadDebounce", boardcomputerHardware.dpadDebounce);
|
||||
#endif
|
||||
#ifdef FEATURE_GAMETRAK
|
||||
|
@ -64,7 +64,7 @@ struct GasMinAccessor : public RefAccessorSaveSettings<int16_t> { int16_t &getRe
|
||||
struct GasMaxAccessor : public RefAccessorSaveSettings<int16_t> { int16_t &getRef() const override { return settings.boardcomputerHardware.gasMax; } };
|
||||
struct BremsMinAccessor : public RefAccessorSaveSettings<int16_t> { int16_t &getRef() const override { return settings.boardcomputerHardware.bremsMin; } };
|
||||
struct BremsMaxAccessor : public RefAccessorSaveSettings<int16_t> { int16_t &getRef() const override { return settings.boardcomputerHardware.bremsMax; } };
|
||||
#if defined(FEATURE_DPAD) || defined(FEATURE_DPAD_3WIRESW)
|
||||
#if defined(FEATURE_DPAD) || defined(FEATURE_DPAD_3WIRESW) || defined(FEATURE_DPAD_5WIRESW)
|
||||
struct DPadDebounceAccessor : public RefAccessorSaveSettings<uint8_t> { uint8_t &getRef() const override { return settings.boardcomputerHardware.dpadDebounce; } };
|
||||
#endif
|
||||
#ifdef FEATURE_GAMETRAK
|
||||
|
@ -6,36 +6,41 @@
|
||||
#include <nvs_flash.h>
|
||||
#include <nvs.h>
|
||||
|
||||
#include <include/tl/optional.hpp>
|
||||
|
||||
#include "settings.h"
|
||||
#include "bluetoothmode.h"
|
||||
#include "unifiedmodelmode.h"
|
||||
|
||||
namespace {
|
||||
class SettingsSaver
|
||||
class SettingsPersister
|
||||
{
|
||||
public:
|
||||
bool init();
|
||||
bool erase();
|
||||
bool openProfile(uint8_t index);
|
||||
void closeProfile();
|
||||
bool load(Settings &settings);
|
||||
bool save(Settings &settings);
|
||||
|
||||
tl::optional<uint8_t> currentlyOpenProfileIndex() const;
|
||||
|
||||
private:
|
||||
nvs_handle my_handle;
|
||||
struct CurrentlyOpenProfile {
|
||||
nvs_handle handle;
|
||||
uint8_t profileIndex;
|
||||
};
|
||||
tl::optional<CurrentlyOpenProfile> m_profile;
|
||||
};
|
||||
|
||||
bool SettingsSaver::init()
|
||||
bool SettingsPersister::init()
|
||||
{
|
||||
esp_err_t err = nvs_flash_init();
|
||||
if (err == ESP_ERR_NVS_NO_FREE_PAGES || err == ESP_ERR_NVS_NEW_VERSION_FOUND)
|
||||
{
|
||||
Serial.printf("nvs_flash_init() returned: %s, trying to erase\r\n", esp_err_to_name(err));
|
||||
err = nvs_flash_erase();
|
||||
if (err != ESP_OK)
|
||||
{
|
||||
Serial.printf("nvs_flash_erase() returned: %s, aborting\r\n", esp_err_to_name(err));
|
||||
return false;
|
||||
}
|
||||
|
||||
err = nvs_flash_init();
|
||||
return erase();
|
||||
}
|
||||
|
||||
if (err != ESP_OK)
|
||||
@ -44,16 +49,55 @@ bool SettingsSaver::init()
|
||||
return false;
|
||||
}
|
||||
|
||||
err = nvs_open("bobbycar", NVS_READWRITE, &my_handle);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool SettingsPersister::erase()
|
||||
{
|
||||
esp_err_t err = nvs_flash_erase();
|
||||
if (err != ESP_OK)
|
||||
{
|
||||
Serial.printf("nvs_flash_erase() returned: %s, aborting\r\n", esp_err_to_name(err));
|
||||
return false;
|
||||
}
|
||||
|
||||
err = nvs_flash_init();
|
||||
if (err != ESP_OK)
|
||||
{
|
||||
Serial.printf("nvs_flash_init() returned: %s\r\n", esp_err_to_name(err));
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool SettingsPersister::openProfile(uint8_t index)
|
||||
{
|
||||
closeProfile();
|
||||
|
||||
nvs_handle handle;
|
||||
esp_err_t err = nvs_open((String{"bobbycar"}+index).c_str(), NVS_READWRITE, &handle);
|
||||
if (err != ESP_OK)
|
||||
{
|
||||
Serial.printf("nvs_open() returned: %s\r\n", esp_err_to_name(err));
|
||||
return false;
|
||||
}
|
||||
|
||||
m_profile = {handle, index};
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void SettingsPersister::closeProfile()
|
||||
{
|
||||
if (!m_profile)
|
||||
return;
|
||||
|
||||
nvs_close(m_profile->handle);
|
||||
|
||||
m_profile = tl::nullopt;
|
||||
}
|
||||
|
||||
template<typename T> struct nvsGetterHelper;
|
||||
template<> struct nvsGetterHelper<int8_t> { static constexpr auto nvs_get = &nvs_get_i8; };
|
||||
template<> struct nvsGetterHelper<uint8_t> { static constexpr auto nvs_get = &nvs_get_u8; };
|
||||
@ -118,13 +162,19 @@ template<> struct nvsGetterHelper<wifi_mode_t> { static esp_err_t nvs_get(nvs_ha
|
||||
return err;
|
||||
}};
|
||||
|
||||
bool SettingsSaver::load(Settings &settings)
|
||||
bool SettingsPersister::load(Settings &settings)
|
||||
{
|
||||
if (!m_profile)
|
||||
{
|
||||
Serial.println("SettingsPersister::load() no profile open currently!");
|
||||
return false;
|
||||
}
|
||||
|
||||
bool result{true};
|
||||
|
||||
settings.executeForEverySetting([&](const char *key, auto &value)
|
||||
{
|
||||
esp_err_t err = nvsGetterHelper<std::remove_reference_t<decltype(value)>>::nvs_get(my_handle, key, &value);
|
||||
esp_err_t err = nvsGetterHelper<std::remove_reference_t<decltype(value)>>::nvs_get(m_profile->handle, key, &value);
|
||||
if (err != ESP_OK)
|
||||
{
|
||||
Serial.printf("nvs_get_i32() for %s returned: %s\r\n", key, esp_err_to_name(err));
|
||||
@ -168,13 +218,19 @@ template<> struct nvsSetterHelper<wifi_mode_t> { static esp_err_t nvs_set(nvs_ha
|
||||
return nvs_set_u8(handle, key, uint8_t(value));
|
||||
}};
|
||||
|
||||
bool SettingsSaver::save(Settings &settings)
|
||||
bool SettingsPersister::save(Settings &settings)
|
||||
{
|
||||
if (!m_profile)
|
||||
{
|
||||
Serial.println("SettingsPersister::save() no profile open currently!");
|
||||
return false;
|
||||
}
|
||||
|
||||
bool result{true};
|
||||
|
||||
settings.executeForEverySetting([&](const char *key, auto value)
|
||||
{
|
||||
esp_err_t err = nvsSetterHelper<decltype(value)>::nvs_set(my_handle, key, value);
|
||||
esp_err_t err = nvsSetterHelper<decltype(value)>::nvs_set(m_profile->handle, key, value);
|
||||
if (err != ESP_OK)
|
||||
{
|
||||
Serial.printf("nvs_get_i32() for %s returned: %s\r\n", key, esp_err_to_name(err));
|
||||
@ -185,4 +241,12 @@ bool SettingsSaver::save(Settings &settings)
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
tl::optional<uint8_t> SettingsPersister::currentlyOpenProfileIndex() const
|
||||
{
|
||||
if (m_profile)
|
||||
return m_profile->profileIndex;
|
||||
|
||||
return tl::nullopt;
|
||||
}
|
||||
}
|
10
src/texts.h
10
src/texts.h
@ -36,6 +36,7 @@ constexpr char TEXT_TURNOFFDISCHARGE[] = "Turn off discharge";
|
||||
//DebugMenu
|
||||
constexpr char TEXT_LOADSETTINGS[] = "Load settings";
|
||||
constexpr char TEXT_SAVESETTINGS[] = "Save settings";
|
||||
constexpr char TEXT_ERASENVS[] = "Erase NVS";
|
||||
constexpr char TEXT_FRONTCOMMAND[] = "Front command";
|
||||
constexpr char TEXT_BACKCOMMAND[] = "Back command";
|
||||
constexpr char TEXT_FRONTLEFTCOMMAND[] = "Front left command";
|
||||
@ -56,6 +57,7 @@ constexpr char TEXT_STATUS[] = "Status";
|
||||
constexpr char TEXT_SELECTMODE[] = "Select mode";
|
||||
constexpr char TEXT_MODESETTINGS[] = "Mode settings";
|
||||
constexpr char TEXT_PRESETS[] = "Presets";
|
||||
constexpr char TEXT_PROFILES[] = "Profiles";
|
||||
constexpr char TEXT_GRAPHS[] = "Graphs";
|
||||
//constexpr char TEXT_BMS[] = "BMS";
|
||||
constexpr char TEXT_SETTINGS[] = "Settings";
|
||||
@ -254,6 +256,14 @@ constexpr char TEXT_SWAPSCREENBYTES[] = "Swap screen bytes";
|
||||
constexpr char TEXT_TIMERS[] = "Timers";
|
||||
//constexpr char TEXT_BACK[] = "Back";
|
||||
|
||||
//ProfilesMenu
|
||||
//constexpr char TEXT_PROFILES[] = "Profiles";
|
||||
constexpr char TEXT_PROFILE0[] = "Profile 0";
|
||||
constexpr char TEXT_PROFILE1[] = "Profile 1";
|
||||
constexpr char TEXT_PROFILE2[] = "Profile 2";
|
||||
constexpr char TEXT_PROFILE3[] = "Profile 3";
|
||||
//constexpr char TEXT_BACK[] = "Back";
|
||||
|
||||
//PresetsMenu
|
||||
//constexpr char TEXT_PRESETS[] = "Presets";
|
||||
constexpr char TEXT_DEFAULTEVERYTHING[] = "Default everything";
|
||||
|
@ -266,12 +266,12 @@ void updateSwapFrontBack()
|
||||
|
||||
void loadSettings()
|
||||
{
|
||||
settingsSaver.load(settings);
|
||||
settingsPersister.load(settings);
|
||||
}
|
||||
|
||||
void saveSettings()
|
||||
{
|
||||
settingsSaver.save(settings);
|
||||
settingsPersister.save(settings);
|
||||
}
|
||||
|
||||
void updateAccumulators()
|
||||
|
@ -8,7 +8,7 @@ namespace {
|
||||
class Label
|
||||
{
|
||||
public:
|
||||
Label(int x, int y) : m_x{x}, m_y{y} {}
|
||||
Label(int x, int y);
|
||||
|
||||
int x() const { return m_x; };
|
||||
int y() const { return m_y; };
|
||||
@ -29,6 +29,12 @@ private:
|
||||
int m_lastHeight;
|
||||
};
|
||||
|
||||
Label::Label(int x, int y) :
|
||||
m_x{x},
|
||||
m_y{y}
|
||||
{
|
||||
}
|
||||
|
||||
void Label::start()
|
||||
{
|
||||
m_lastStr.clear();
|
||||
@ -71,7 +77,7 @@ void Label::redraw(const String &str, bool forceRedraw)
|
||||
void Label::clear()
|
||||
{
|
||||
if (m_lastWidth || m_lastHeight)
|
||||
tft.fillRect(m_x, m_y, m_lastWidth, m_lastHeight, TFT_BLACK);
|
||||
tft.fillRect(m_x, m_y, m_lastWidth, m_lastHeight, tft.textbgcolor);
|
||||
|
||||
start();
|
||||
}
|
||||
|
Reference in New Issue
Block a user