diff options
| author | ailurux <ailuruxx@gmail.com> | 2024-04-22 09:48:21 +1000 |
|---|---|---|
| committer | ailurux <ailuruxx@gmail.com> | 2024-04-22 09:48:21 +1000 |
| commit | 4eb1a074f7c7dc7e43789400bea5e6357e4546f5 (patch) | |
| tree | a93e29b51e5c902329d28a7b2064e0ffdcee9887 /src | |
| parent | dfccf56f34484b3e9efcb48b240abdb22c577281 (diff) | |
| parent | 5b99267cb9f0344e519956096867aea5468ecf9f (diff) | |
| download | tangara-fw-4eb1a074f7c7dc7e43789400bea5e6357e4546f5.tar.gz | |
Merge branch 'main' of codeberg.org:cool-tech-zone/tangara-fw
Diffstat (limited to 'src')
| -rw-r--r-- | src/database/track.cpp | 2 | ||||
| -rw-r--r-- | src/drivers/adc.cpp | 2 | ||||
| -rw-r--r-- | src/drivers/bluetooth.cpp | 3 | ||||
| -rw-r--r-- | src/drivers/haptics.cpp | 68 | ||||
| -rw-r--r-- | src/drivers/include/haptics.hpp | 50 | ||||
| -rw-r--r-- | src/drivers/include/nvs.hpp | 6 | ||||
| -rw-r--r-- | src/drivers/nvs.cpp | 14 | ||||
| -rw-r--r-- | src/lua/lua_version.cpp | 8 | ||||
| -rw-r--r-- | src/system_fsm/booting.cpp | 10 |
9 files changed, 123 insertions, 40 deletions
diff --git a/src/database/track.cpp b/src/database/track.cpp index 141a9b7e..a2bd05d3 100644 --- a/src/database/track.cpp +++ b/src/database/track.cpp @@ -234,7 +234,7 @@ auto TrackTags::genres(const std::string_view s) -> void { std::string src = {s.data(), s.size()}; char* token = std::strtok(src.data(), kGenreDelimiters); - auto trim_and_add = [=](std::string_view s) { + auto trim_and_add = [this](std::string_view s) { std::string copy = {s.data(), s.size()}; // Trim the left diff --git a/src/drivers/adc.cpp b/src/drivers/adc.cpp index 56d2cbb4..3379a1ae 100644 --- a/src/drivers/adc.cpp +++ b/src/drivers/adc.cpp @@ -18,7 +18,7 @@ static const adc_bitwidth_t kAdcBitWidth = ADC_BITWIDTH_12; static const adc_unit_t kAdcUnit = ADC_UNIT_1; // Max battery voltage should be a little over 2V due to our divider, so we need // the max attenuation to properly handle the full range. -static const adc_atten_t kAdcAttenuation = ADC_ATTEN_DB_11; +static const adc_atten_t kAdcAttenuation = ADC_ATTEN_DB_12; // Corresponds to SENSOR_VP. static const adc_channel_t kAdcChannel = ADC_CHANNEL_0; diff --git a/src/drivers/bluetooth.cpp b/src/drivers/bluetooth.cpp index edd5f67e..5d1b35fa 100644 --- a/src/drivers/bluetooth.cpp +++ b/src/drivers/bluetooth.cpp @@ -438,7 +438,8 @@ void Disabled::react(const events::Enable&) { return; } - if ((err = esp_bluedroid_init() != ESP_OK)) { + esp_bluedroid_config_t cfg = BT_BLUEDROID_INIT_CONFIG_DEFAULT(); + if ((err = esp_bluedroid_init_with_cfg(&cfg) != ESP_OK)) { ESP_LOGE(kTag, "initialize bluedroid failed %s", esp_err_to_name(err)); return; } diff --git a/src/drivers/haptics.cpp b/src/drivers/haptics.cpp index 46136e62..f7b18086 100644 --- a/src/drivers/haptics.cpp +++ b/src/drivers/haptics.cpp @@ -10,6 +10,7 @@ #include <cstdint> #include <initializer_list> #include <mutex> +#include <variant> #include "assert.h" #include "driver/gpio.h" @@ -27,24 +28,55 @@ namespace drivers { static constexpr char kTag[] = "haptics"; static constexpr uint8_t kHapticsAddress = 0x5A; -Haptics::Haptics() { +Haptics::Haptics(const std::variant<ErmMotor, LraMotor>& motor) { PowerUp(); - // Put into ERM Open Loop: - // (§8.5.4.1 Programming for ERM Open-Loop Operation) - // - Turn off N_ERM_LRA first - WriteRegister(Register::kControl1, - static_cast<uint8_t>(RegisterDefaults::kControl1) & - (~ControlMask::kNErmLra)); - // - Turn on ERM_OPEN_LOOP - WriteRegister(Register::kControl3, - static_cast<uint8_t>(RegisterDefaults::kControl3) | - ControlMask::kErmOpenLoop); - - // Set library - // TODO(robin): try the other libraries and test response. C is marginal, D - // too much? - WriteRegister(Register::kWaveformLibrary, static_cast<uint8_t>(kDefaultLibrary)); + // TODO: Break out into helper functions + // TODO: Use LRA closed loop instead, loading in calibration data from NVS, or + // running calibration + storing the result first if necessary. + + if (std::holds_alternative<ErmMotor>(motor)) { + ESP_LOGI(kTag, "Setting up ERM motor..."); + + // Put into ERM Open Loop: + // (§8.5.4.1 Programming for ERM Open-Loop Operation) + + // - Turn off N_ERM_LRA first + WriteRegister(Register::kFeedbackControl, + static_cast<uint8_t>(RegisterDefaults::kFeedbackControl) & + (~ControlMask::kNErmLra)); + + // - Turn on ERM_OPEN_LOOP + WriteRegister(Register::kControl3, + static_cast<uint8_t>(RegisterDefaults::kControl3) | + ControlMask::kErmOpenLoop); + + // Set library + // TODO(robin): try the other libraries and test response. C is marginal, D + // too much? + WriteRegister(Register::kWaveformLibrary, static_cast<uint8_t>(kDefaultErmLibrary)); + + } else if (std::holds_alternative<LraMotor>(motor)) { + ESP_LOGI(kTag, "Setting up LRA motor..."); + // TODO: + // auto lraInit = std::get<LraMotor>(motor); + + // Put into LRA Open Loop: + // (§8.5.4.1 Programming for LRA Open-Loop Operation) + + // - Turn on N_ERM_LRA first + WriteRegister(Register::kFeedbackControl, + static_cast<uint8_t>(RegisterDefaults::kFeedbackControl) & + (ControlMask::kNErmLra)); + + // - Turn on LRA_OPEN_LOOP + WriteRegister(Register::kControl3, + static_cast<uint8_t>(RegisterDefaults::kControl3) | + ControlMask::kLraOpenLoop); + + // Set library; only option is the LRA one for, well, LRA motors. + WriteRegister(Register::kWaveformLibrary, static_cast<uint8_t>(Library::LRA)); + } // Set mode (internal trigger, on writing 1 to Go register) WriteRegister(Register::kMode, static_cast<uint8_t>(Mode::kInternalTrigger)); @@ -93,13 +125,13 @@ auto Haptics::SetWaveformEffect(Effect effect) -> void { auto Haptics::TourEffects() -> void { - TourEffects(Effect::kFirst, Effect::kLast, kDefaultLibrary); + TourEffects(Effect::kFirst, Effect::kLast, kDefaultErmLibrary); } auto Haptics::TourEffects(Library lib) -> void { TourEffects(Effect::kFirst, Effect::kLast, lib); } auto Haptics::TourEffects(Effect from, Effect to) -> void { - TourEffects(from, to, kDefaultLibrary); + TourEffects(from, to, kDefaultErmLibrary); } auto Haptics::TourEffects(Effect from, Effect to, Library lib) -> void { ESP_LOGI(kTag, "With library #%u...", static_cast<uint8_t>(lib)); diff --git a/src/drivers/include/haptics.hpp b/src/drivers/include/haptics.hpp index 6cfcbb0d..940c3c6d 100644 --- a/src/drivers/include/haptics.hpp +++ b/src/drivers/include/haptics.hpp @@ -11,13 +11,24 @@ #include <mutex> #include <optional> #include <string> +#include <variant> namespace drivers { +typedef std::monostate ErmMotor; +struct LraMotor { + // TODO: fill out with calibration data from https://www.ti.com/lit/ds/symlink/drv2605l.pdf + bool hi; +}; + class Haptics { public: - static auto Create() -> Haptics* { return new Haptics(); } - Haptics(); + static auto Create(const std::variant<ErmMotor, LraMotor>& motor) + -> Haptics* { + return new Haptics(motor); + } + + Haptics(const std::variant<ErmMotor, LraMotor>& motor); ~Haptics(); // Not copyable or movable. @@ -169,11 +180,12 @@ class Haptics { B = 2, // 3V, Rise: 40-60ms, Brake: 5-15ms C = 3, // 3V, Rise: 60-80ms, Brake: 10-20ms D = 4, // 3V, Rise: 100-140ms, Brake: 15-25ms - E = 5 // 3V, Rise: >140ms, Brake: >30ms - // 6 is LRA-only, 7 is 4.5V+ + E = 5, // 3V, Rise: >140ms, Brake: >30ms + LRA = 6 + // 7 is 4.5V+ }; - static constexpr Library kDefaultLibrary = Library::C; + static constexpr Library kDefaultErmLibrary = Library::C; auto PowerDown() -> void; auto Reset() -> void; @@ -214,10 +226,12 @@ class Haptics { }; struct ControlMask { - // Control1 + // FeedbackControl static constexpr uint8_t kNErmLra = 0b10000000; + // Control3 static constexpr uint8_t kErmOpenLoop = 0b00100000; + static constexpr uint8_t kLraOpenLoop = 0b00000001; }; // §8.6 Register Map @@ -257,12 +271,12 @@ class Haptics { // A bunch of different options, not grouped // in any particular sensible way - kControl1 = 0x1A, - kControl2 = 0x1B, - kControl3 = 0x1C, - kControl4 = 0x1D, - kControl5 = 0x1E, - kControl6 = 0x1F, + kFeedbackControl = 0x1A, + kControl1 = 0x1B, + kControl2 = 0x1C, + kControl3 = 0x1D, + kControl4 = 0x1E, + kControl5 = 0x1F, kSupplyVoltageMonitor = 0x21, // "VBAT" kLraResonancePeriod = 0x22, @@ -295,12 +309,12 @@ class Haptics { kOverdriveClampVoltage = 0x8C, kAutoCalibrationCompensationResult = 0x0C, kAutoCalibrationBackEmfResult = 0x6C, - kControl1 = 0x36, - kControl2 = 0x93, - kControl3 = 0xF5, - kControl4 = 0xA0, - kControl5 = 0x20, - kControl6 = 0x80, + kFeedbackControl = 0x36, + kControl1 = 0x93, + kControl2 = 0xF5, + kControl3 = 0xA0, + kControl4 = 0x20, + kControl5 = 0x80, kSupplyVoltageMonitor = 0, kLraResonancePeriod = 0, }; diff --git a/src/drivers/include/nvs.hpp b/src/drivers/include/nvs.hpp index 25396622..7c74ceb0 100644 --- a/src/drivers/include/nvs.hpp +++ b/src/drivers/include/nvs.hpp @@ -68,6 +68,7 @@ class NvsStorage { auto Read() -> void; auto Write() -> bool; + // Hardware Compatibility auto LockPolarity() -> bool; auto LockPolarity(bool) -> void; @@ -76,6 +77,10 @@ class NvsStorage { auto DisplaySize(std::pair<std::optional<uint16_t>, std::optional<uint16_t>>) -> void; + auto HapticMotorIsErm() -> bool; + auto HapticMotorIsErm(bool) -> void; + // /Hardware Compatibility + auto PreferredBluetoothDevice() -> std::optional<bluetooth::MacAndName>; auto PreferredBluetoothDevice(std::optional<bluetooth::MacAndName>) -> void; @@ -130,6 +135,7 @@ class NvsStorage { Setting<uint8_t> lock_polarity_; Setting<uint16_t> display_cols_; Setting<uint16_t> display_rows_; + Setting<uint8_t> haptic_motor_type_; Setting<uint8_t> brightness_; Setting<uint8_t> sensitivity_; diff --git a/src/drivers/nvs.cpp b/src/drivers/nvs.cpp index fbdb5286..c8befe48 100644 --- a/src/drivers/nvs.cpp +++ b/src/drivers/nvs.cpp @@ -39,6 +39,7 @@ static constexpr char kKeyScrollSensitivity[] = "scroll"; static constexpr char kKeyLockPolarity[] = "lockpol"; static constexpr char kKeyDisplayCols[] = "dispcols"; static constexpr char kKeyDisplayRows[] = "disprows"; +static constexpr char kKeyHapticMotorType[] = "hapticmtype"; static constexpr char kKeyDbAutoIndex[] = "dbautoindex"; static auto nvs_get_string(nvs_handle_t nvs, const char* key) @@ -166,6 +167,7 @@ NvsStorage::NvsStorage(nvs_handle_t handle) lock_polarity_(kKeyLockPolarity), display_cols_(kKeyDisplayCols), display_rows_(kKeyDisplayRows), + haptic_motor_type_(kKeyHapticMotorType), brightness_(kKeyBrightness), sensitivity_(kKeyScrollSensitivity), amp_max_vol_(kKeyAmpMaxVolume), @@ -188,6 +190,7 @@ auto NvsStorage::Read() -> void { lock_polarity_.read(handle_); display_cols_.read(handle_); display_rows_.read(handle_); + haptic_motor_type_.read(handle_), brightness_.read(handle_); sensitivity_.read(handle_); amp_max_vol_.read(handle_); @@ -205,6 +208,7 @@ auto NvsStorage::Write() -> bool { lock_polarity_.write(handle_); display_cols_.write(handle_); display_rows_.write(handle_); + haptic_motor_type_.write(handle_), brightness_.write(handle_); sensitivity_.write(handle_); amp_max_vol_.write(handle_); @@ -243,6 +247,16 @@ auto NvsStorage::LockPolarity(bool p) -> void { lock_polarity_.set(p); } +auto NvsStorage::HapticMotorIsErm() -> bool { + std::lock_guard<std::mutex> lock{mutex_}; + return haptic_motor_type_.get().value_or(0) > 0; +} + +auto NvsStorage::HapticMotorIsErm(bool p) -> void { + std::lock_guard<std::mutex> lock{mutex_}; + haptic_motor_type_.set(p); +} + auto NvsStorage::DisplaySize() -> std::pair<std::optional<uint16_t>, std::optional<uint16_t>> { std::lock_guard<std::mutex> lock{mutex_}; diff --git a/src/lua/lua_version.cpp b/src/lua/lua_version.cpp index c1098a1b..e5f06bb5 100644 --- a/src/lua/lua_version.cpp +++ b/src/lua/lua_version.cpp @@ -34,6 +34,13 @@ static auto samd(lua_State* L) -> int { return 1; } +static auto update_samd(lua_State* L) -> int { + Bridge* instance = Bridge::Get(L); + auto& samd = instance->services().samd(); + samd.ResetToFlashSamd(); + return 0; +} + static auto collator(lua_State* L) -> int { Bridge* instance = Bridge::Get(L); auto& collator = instance->services().collator(); @@ -45,6 +52,7 @@ static auto collator(lua_State* L) -> int { static const struct luaL_Reg kVersionFuncs[] = {{"esp", esp}, {"samd", samd}, {"collator", collator}, + {"update_samd", update_samd}, {NULL, NULL}}; static auto lua_version(lua_State* L) -> int { diff --git a/src/system_fsm/booting.cpp b/src/system_fsm/booting.cpp index bd394428..a89f35d9 100644 --- a/src/system_fsm/booting.cpp +++ b/src/system_fsm/booting.cpp @@ -62,6 +62,10 @@ auto Booting::entry() -> void { sServices->nvs( std::unique_ptr<drivers::NvsStorage>(drivers::NvsStorage::OpenSync())); + // HACK: tell the unit that it has an ERM motor (we will likely default to + // LRAs in future, but all the current units in the field use ERMs.) + sServices->nvs().HapticMotorIsErm(true); + // HACK: fix up the switch polarity on newer dev units // sServices->nvs().LockPolarity(false); @@ -85,7 +89,11 @@ auto Booting::entry() -> void { sServices->samd(std::unique_ptr<drivers::Samd>(drivers::Samd::Create())); sServices->touchwheel( std::unique_ptr<drivers::TouchWheel>{drivers::TouchWheel::Create()}); - sServices->haptics(std::make_unique<drivers::Haptics>()); + sServices->haptics(std::make_unique<drivers::Haptics>( + sServices->nvs().HapticMotorIsErm() + ? std::variant<drivers::ErmMotor, drivers::LraMotor>( + drivers::ErmMotor()) + : drivers::LraMotor())); auto adc = drivers::AdcBattery::Create(); sServices->battery(std::make_unique<battery::Battery>( |
