Add on-screen configuration for thresholds

This commit is contained in:
Frederik Walk 2023-07-16 23:34:47 +02:00
parent 9e003bb03d
commit b278f76ba0
8 changed files with 189 additions and 43 deletions

View File

@ -64,6 +64,9 @@ class Drum {
Drum(const Config &config);
void updateInputState(Utils::InputState &input_state);
void setThresholds(const Config::Thresholds& thresholds);
void setThresholdScaleLevel(const uint8_t threshold_scale_level);
};
} // namespace Doncon::Peripherals

View File

@ -18,6 +18,12 @@ class Menu {
None,
Main,
DeviceMode,
TriggerThreshold,
TriggerThresholdKaLeft,
TriggerThresholdDonLeft,
TriggerThresholdDonRight,
TriggerThresholdKaRight,
TriggerThresholdScaleLevel,
LedBrightness,
Bootsel,
BootselMsg,
@ -25,7 +31,7 @@ class Menu {
struct State {
Page page;
uint8_t selection;
uint16_t selection;
};
struct Descriptor {
@ -40,6 +46,12 @@ class Menu {
None,
GotoPageDeviceMode,
GotoPageTriggerThreshold,
GotoPageTriggerThresholdKaLeft,
GotoPageTriggerThresholdDonLeft,
GotoPageTriggerThresholdDonRight,
GotoPageTriggerThresholdKaRight,
GotoPageTriggerThresholdScaleLevel,
GotoPageLedBrightness,
GotoPageBootsel,
@ -51,6 +63,11 @@ class Menu {
ChangeUsbModeXbox360,
ChangeUsbModeDebug,
SetTriggerThresholdKaLeft,
SetTriggerThresholdDonLeft,
SetTriggerThresholdDonRight,
SetTriggerThresholdKaRight,
SetTriggerThresholdScaleLevel,
SetLedBrightness,
DoRebootToBootsel,
@ -59,6 +76,7 @@ class Menu {
Type type;
std::string name;
std::vector<std::pair<std::string, Action>> items;
uint16_t max_value;
Page parent;
};
@ -69,10 +87,10 @@ class Menu {
bool m_active;
State m_state;
uint8_t getCurrentSelection(Page page);
uint16_t getCurrentSelection(Page page);
void gotoPage(Page page);
void performSelectionAction(Descriptor::Action action);
void performValueAction(Descriptor::Action action, uint8_t value);
void performValueAction(Descriptor::Action action, uint16_t value);
public:
Menu(std::shared_ptr<SettingsStore> settings_store);

View File

@ -45,19 +45,19 @@ class SettingsStore {
public:
SettingsStore();
void setUsbMode(usb_mode_t mode);
void setUsbMode(const usb_mode_t mode);
usb_mode_t getUsbMode();
void setTriggerThresholds(Peripherals::Drum::Config::Thresholds thresholds);
void setTriggerThresholds(const Peripherals::Drum::Config::Thresholds &thresholds);
Peripherals::Drum::Config::Thresholds getTriggerThresholds();
void setTriggerThresholdScaleLevel(uint8_t threshold_scale_level);
void setTriggerThresholdScaleLevel(const uint8_t threshold_scale_level);
uint8_t getTriggerThresholdScaleLevel();
void setLedBrightness(uint8_t brightness);
void setLedBrightness(const uint8_t brightness);
uint8_t getLedBrightness();
void scheduleReboot(bool bootsel = false);
void scheduleReboot(const bool bootsel = false);
void store();
};

View File

@ -128,6 +128,9 @@ int main() {
ctrl_message = {ControlCommand::SetLedBrightness, {.brightness = settings_store->getLedBrightness()}};
queue_add_blocking(&control_queue, &ctrl_message);
drum.setThresholds(settings_store->getTriggerThresholds());
drum.setThresholdScaleLevel(settings_store->getTriggerThresholdScaleLevel());
};
readSettings();

View File

@ -35,6 +35,25 @@ Drum::Drum(const Config &config) : m_config(config) {
}
}
std::map<Drum::Id, uint16_t> Drum::sampleInputs() {
std::map<Id, uint32_t> values;
for (uint8_t sample_number = 0; sample_number < m_config.sample_count; ++sample_number) {
for (const auto &pad : m_pads) {
adc_select_input(pad.second.getPin());
values[pad.first] += adc_read();
}
}
// Take average of all samples
std::map<Id, uint16_t> result;
for (auto &value : values) {
result[value.first] = value.second / m_config.sample_count;
}
return result;
}
void Drum::updateInputState(Utils::InputState &input_state) {
// Oversample ADC inputs to get rid of ADC noise
const auto raw_values = sampleInputs();
@ -73,23 +92,10 @@ void Drum::updateInputState(Utils::InputState &input_state) {
input_state.drum.ka_right.triggered = m_pads.at(Id::KA_RIGHT).getState();
}
std::map<Drum::Id, uint16_t> Drum::sampleInputs() {
std::map<Id, uint32_t> values;
void Drum::setThresholds(const Config::Thresholds &thresholds) { m_config.trigger_thresholds = thresholds; }
for (uint8_t sample_number = 0; sample_number < m_config.sample_count; ++sample_number) {
for (const auto &pad : m_pads) {
adc_select_input(pad.second.getPin());
values[pad.first] += adc_read();
}
}
// Take average of all samples
std::map<Id, uint16_t> result;
for (auto &value : values) {
result[value.first] = value.second / m_config.sample_count;
}
return result;
void Drum::setThresholdScaleLevel(const uint8_t threshold_scale_level) {
m_config.trigger_threshold_scale_level = threshold_scale_level;
}
} // namespace Doncon::Peripherals

View File

@ -13,7 +13,7 @@ uint16_t tud_hid_get_report_cb(uint8_t itf, uint8_t report_id, hid_report_type_t
return hid_switch_get_report_cb(itf, report_id, report_type, buffer, reqlen);
case USB_MODE_DUALSHOCK3:
return hid_ps3_get_report_cb(itf, report_id, report_type, buffer, reqlen);
// case USB_MODE_PS4_TATACON:
case USB_MODE_PS4_TATACON:
case USB_MODE_DUALSHOCK4:
return hid_ps4_get_report_cb(itf, report_id, report_type, buffer, reqlen);
default:
@ -32,7 +32,7 @@ void tud_hid_set_report_cb(uint8_t itf, uint8_t report_id, hid_report_type_t rep
case USB_MODE_DUALSHOCK3:
hid_ps3_set_report_cb(itf, report_id, report_type, buffer, bufsize);
break;
// case USB_MODE_PS4_TATACON:
case USB_MODE_PS4_TATACON:
case USB_MODE_DUALSHOCK4:
hid_ps4_set_report_cb(itf, report_id, report_type, buffer, bufsize);
break;

View File

@ -3,13 +3,15 @@
namespace Doncon::Utils {
const std::map<Menu::Page, const Menu::Descriptor> Menu::descriptors = {
{Menu::Page::Main, //
{Menu::Descriptor::Type::Root, //
"Settings", //
{{"Mode", Menu::Descriptor::Action::GotoPageDeviceMode}, //
{"Brightness", Menu::Descriptor::Action::GotoPageLedBrightness}, //
{"BOOTSEL", Menu::Descriptor::Action::GotoPageBootsel}}, //
Menu::Page::None}}, //
{Menu::Page::Main, //
{Menu::Descriptor::Type::Root, //
"Settings", //
{{"Mode", Menu::Descriptor::Action::GotoPageDeviceMode}, //
{"Brightness", Menu::Descriptor::Action::GotoPageLedBrightness}, //
{"Sensitvty", Menu::Descriptor::Action::GotoPageTriggerThreshold}, //
{"BOOTSEL", Menu::Descriptor::Action::GotoPageBootsel}}, //
0, //
Menu::Page::None}}, //
{Menu::Page::DeviceMode, //
{Menu::Descriptor::Type::Selection, //
@ -21,24 +23,74 @@ const std::map<Menu::Page, const Menu::Descriptor> Menu::descriptors = {
{"Dualshock4", Menu::Descriptor::Action::ChangeUsbModeDS4}, //
{"Xbox 360", Menu::Descriptor::Action::ChangeUsbModeXbox360}, //
{"Debug", Menu::Descriptor::Action::ChangeUsbModeDebug}}, //
0, //
Menu::Page::Main}}, //
{Menu::Page::TriggerThreshold, //
{Menu::Descriptor::Type::Selection, //
"Sensitivity", //
{{"Ka Left", Menu::Descriptor::Action::GotoPageTriggerThresholdKaLeft}, //
{"Don Left", Menu::Descriptor::Action::GotoPageTriggerThresholdDonLeft}, //
{"Don Right", Menu::Descriptor::Action::GotoPageTriggerThresholdDonRight}, //
{"Ka Right", Menu::Descriptor::Action::GotoPageTriggerThresholdKaRight}, //
{"Scale Lvl", Menu::Descriptor::Action::GotoPageTriggerThresholdScaleLevel}}, //
0, //
Menu::Page::Main}}, //
{Menu::Page::TriggerThresholdKaLeft, //
{Menu::Descriptor::Type::Value, //
"Trg Level Ka Left", //
{{"", Menu::Descriptor::Action::SetTriggerThresholdKaLeft}}, //
4095, //
Menu::Page::TriggerThreshold}},
{Menu::Page::TriggerThresholdDonLeft, //
{Menu::Descriptor::Type::Value, //
"Trg Level Don Left", //
{{"", Menu::Descriptor::Action::SetTriggerThresholdDonLeft}}, //
4095, //
Menu::Page::TriggerThreshold}},
{Menu::Page::TriggerThresholdDonRight, //
{Menu::Descriptor::Type::Value, //
"Trg Level Don Right", //
{{"", Menu::Descriptor::Action::SetTriggerThresholdDonRight}}, //
4095, //
Menu::Page::TriggerThreshold}},
{Menu::Page::TriggerThresholdKaRight, //
{Menu::Descriptor::Type::Value, //
"Trg Level Ka Right", //
{{"", Menu::Descriptor::Action::SetTriggerThresholdKaRight}}, //
4095, //
Menu::Page::TriggerThreshold}},
{Menu::Page::TriggerThresholdScaleLevel, //
{Menu::Descriptor::Type::Value, //
"Sensitivity Scale Lvl", //
{{"", Menu::Descriptor::Action::SetTriggerThresholdScaleLevel}}, //
UINT8_MAX, //
Menu::Page::TriggerThreshold}},
{Menu::Page::LedBrightness, //
{Menu::Descriptor::Type::Value, //
"LED Brightness", //
{{"", Menu::Descriptor::Action::SetLedBrightness}}, //
UINT8_MAX, //
Menu::Page::Main}}, //
{Menu::Page::Bootsel, //
{Menu::Descriptor::Type::Selection, //
"Reboot to BOOTSEL", //
{{"Reboot?", Menu::Descriptor::Action::DoRebootToBootsel}}, //
0, //
Menu::Page::Main}}, //
{Menu::Page::BootselMsg, //
{Menu::Descriptor::Type::RebootInfo, //
"Ready to Flash...", //
{{"BOOTSEL", Menu::Descriptor::Action::None}}, //
0, //
Menu::Page::Main}}, //
};
@ -127,15 +179,31 @@ static InputState::Controller checkPressed(const InputState::Controller &control
return result;
}
uint8_t Menu::getCurrentSelection(Menu::Page page) {
uint16_t Menu::getCurrentSelection(Menu::Page page) {
switch (page) {
case Page::DeviceMode:
return static_cast<uint8_t>(m_store->getUsbMode());
return static_cast<uint16_t>(m_store->getUsbMode());
break;
case Page::TriggerThresholdKaLeft:
return m_store->getTriggerThresholds().ka_left;
break;
case Page::TriggerThresholdDonLeft:
return m_store->getTriggerThresholds().don_left;
break;
case Page::TriggerThresholdDonRight:
return m_store->getTriggerThresholds().don_right;
break;
case Page::TriggerThresholdKaRight:
return m_store->getTriggerThresholds().ka_right;
break;
case Page::TriggerThresholdScaleLevel:
return m_store->getTriggerThresholdScaleLevel();
break;
case Page::LedBrightness:
return m_store->getLedBrightness();
break;
case Page::Main:
case Page::TriggerThreshold:
case Page::Bootsel:
case Page::BootselMsg:
case Page::None:
@ -161,6 +229,24 @@ void Menu::performSelectionAction(Menu::Descriptor::Action action) {
case Descriptor::Action::GotoPageDeviceMode:
gotoPage(Page::DeviceMode);
break;
case Descriptor::Action::GotoPageTriggerThreshold:
gotoPage(Page::TriggerThreshold);
break;
case Descriptor::Action::GotoPageTriggerThresholdKaLeft:
gotoPage(Page::TriggerThresholdKaLeft);
break;
case Descriptor::Action::GotoPageTriggerThresholdDonLeft:
gotoPage(Page::TriggerThresholdDonLeft);
break;
case Descriptor::Action::GotoPageTriggerThresholdDonRight:
gotoPage(Page::TriggerThresholdDonRight);
break;
case Descriptor::Action::GotoPageTriggerThresholdKaRight:
gotoPage(Page::TriggerThresholdKaRight);
break;
case Descriptor::Action::GotoPageTriggerThresholdScaleLevel:
gotoPage(Page::TriggerThresholdScaleLevel);
break;
case Descriptor::Action::GotoPageLedBrightness:
gotoPage(Page::LedBrightness);
break;
@ -195,6 +281,13 @@ void Menu::performSelectionAction(Menu::Descriptor::Action action) {
m_store->setUsbMode(USB_MODE_DEBUG);
gotoPage(descriptor_it->second.parent);
break;
case Descriptor::Action::SetTriggerThresholdKaLeft:
case Descriptor::Action::SetTriggerThresholdDonLeft:
case Descriptor::Action::SetTriggerThresholdDonRight:
case Descriptor::Action::SetTriggerThresholdKaRight:
case Descriptor::Action::SetTriggerThresholdScaleLevel:
gotoPage(descriptor_it->second.parent);
break;
case Descriptor::Action::SetLedBrightness:
gotoPage(descriptor_it->second.parent);
break;
@ -202,12 +295,12 @@ void Menu::performSelectionAction(Menu::Descriptor::Action action) {
m_store->scheduleReboot(true);
gotoPage(Page::BootselMsg);
break;
default:
case Descriptor::Action::None:
break;
}
}
void Menu::performValueAction(Menu::Descriptor::Action action, uint8_t value) {
void Menu::performValueAction(Menu::Descriptor::Action action, uint16_t value) {
auto descriptor_it = descriptors.find(m_state.page);
if (descriptor_it == descriptors.end()) {
assert(false);
@ -215,6 +308,29 @@ void Menu::performValueAction(Menu::Descriptor::Action action, uint8_t value) {
}
switch (action) {
case Descriptor::Action::SetTriggerThresholdKaLeft: {
auto thresholds = m_store->getTriggerThresholds();
thresholds.ka_left = value;
m_store->setTriggerThresholds(thresholds);
} break;
case Descriptor::Action::SetTriggerThresholdDonLeft: {
auto thresholds = m_store->getTriggerThresholds();
thresholds.don_left = value;
m_store->setTriggerThresholds(thresholds);
} break;
case Descriptor::Action::SetTriggerThresholdDonRight: {
auto thresholds = m_store->getTriggerThresholds();
thresholds.don_right = value;
m_store->setTriggerThresholds(thresholds);
} break;
case Descriptor::Action::SetTriggerThresholdKaRight: {
auto thresholds = m_store->getTriggerThresholds();
thresholds.don_right = value;
m_store->setTriggerThresholds(thresholds);
} break;
case Descriptor::Action::SetTriggerThresholdScaleLevel:
m_store->setTriggerThresholdScaleLevel(value);
break;
case Descriptor::Action::SetLedBrightness:
m_store->setLedBrightness(value);
break;
@ -267,7 +383,7 @@ void Menu::update(const InputState::Controller &controller_state) {
} else if (pressed.dpad.up) {
switch (descriptor_it->second.type) {
case Descriptor::Type::Value:
if (m_state.selection < UINT8_MAX) {
if (m_state.selection < descriptor_it->second.max_value) {
m_state.selection++;
performValueAction(descriptor_it->second.items.at(0).second, m_state.selection);
}

View File

@ -35,7 +35,7 @@ SettingsStore::SettingsStore()
}
}
void SettingsStore::setUsbMode(usb_mode_t mode) {
void SettingsStore::setUsbMode(const usb_mode_t mode) {
if (mode != m_store_cache.usb_mode) {
m_store_cache.usb_mode = mode;
m_dirty = true;
@ -46,7 +46,7 @@ void SettingsStore::setUsbMode(usb_mode_t mode) {
usb_mode_t SettingsStore::getUsbMode() { return m_store_cache.usb_mode; }
void SettingsStore::setTriggerThresholds(Peripherals::Drum::Config::Thresholds thresholds) {
void SettingsStore::setTriggerThresholds(const Peripherals::Drum::Config::Thresholds &thresholds) {
if (m_store_cache.trigger_thresholds.don_left != thresholds.don_left ||
m_store_cache.trigger_thresholds.don_right != thresholds.don_right ||
m_store_cache.trigger_thresholds.ka_left != thresholds.ka_left ||
@ -58,7 +58,7 @@ void SettingsStore::setTriggerThresholds(Peripherals::Drum::Config::Thresholds t
}
Peripherals::Drum::Config::Thresholds SettingsStore::getTriggerThresholds() { return m_store_cache.trigger_thresholds; }
void SettingsStore::setTriggerThresholdScaleLevel(uint8_t threshold_scale_level) {
void SettingsStore::setTriggerThresholdScaleLevel(const uint8_t threshold_scale_level) {
if (threshold_scale_level != m_store_cache.trigger_threshold_scale_level) {
m_store_cache.trigger_threshold_scale_level = threshold_scale_level;
m_dirty = true;
@ -66,7 +66,7 @@ void SettingsStore::setTriggerThresholdScaleLevel(uint8_t threshold_scale_level)
}
uint8_t SettingsStore::getTriggerThresholdScaleLevel() { return m_store_cache.trigger_threshold_scale_level; }
void SettingsStore::setLedBrightness(uint8_t brightness) {
void SettingsStore::setLedBrightness(const uint8_t brightness) {
if (m_store_cache.led_brightness != brightness) {
m_store_cache.led_brightness = brightness;
m_dirty = true;
@ -118,7 +118,7 @@ void SettingsStore::store() {
}
}
void SettingsStore::scheduleReboot(bool bootsel) {
void SettingsStore::scheduleReboot(const bool bootsel) {
if (m_scheduled_reboot != RebootType::Bootsel) {
m_scheduled_reboot = (bootsel ? RebootType::Bootsel : RebootType::Normal);
}