diff options
| author | jacqueline <me@jacqueline.id.au> | 2023-06-07 09:50:25 +1000 |
|---|---|---|
| committer | jacqueline <me@jacqueline.id.au> | 2023-06-07 09:50:25 +1000 |
| commit | 610991455d335663de1dd6c0c6a3e0247ffd46df (patch) | |
| tree | 8022526de2d30ca39386cf72d6fb5752d0c22803 /src/drivers/digital_pot.cpp | |
| parent | d2e5d2ab3cff0723cd995b0fca62aeb2a681d32d (diff) | |
| download | tangara-fw-610991455d335663de1dd6c0c6a3e0247ffd46df.tar.gz | |
R4 pre-emptive bringup
Includes stripping out the IC-specific I2S stuff, and doing more manual
volume control using pots
Diffstat (limited to 'src/drivers/digital_pot.cpp')
| -rw-r--r-- | src/drivers/digital_pot.cpp | 85 |
1 files changed, 85 insertions, 0 deletions
diff --git a/src/drivers/digital_pot.cpp b/src/drivers/digital_pot.cpp new file mode 100644 index 00000000..b20d982d --- /dev/null +++ b/src/drivers/digital_pot.cpp @@ -0,0 +1,85 @@ +/* + * Copyright 2023 jacqueline <me@jacqueline.id.au> + * + * SPDX-License-Identifier: GPL-3.0-only + */ + +#include "digital_pot.hpp" + +#include <cstdint> + +namespace drivers { + +using GpioExpander::VOL_LEFT; +using GpioExpander::VOL_RIGHT; +using GpioExpander::VOL_UP_DOWN; +using GpioExpander::VOL_Z_CROSS; + +DigitalPot::DigitalPot(GpioExpander* gpios) : gpios_(gpios) { + gpios_->set_pin(VOL_Z_CROSS, true); // Active-low + gpios_->set_pin(VOL_UP_DOWN, true); + gpios_->set_pin(VOL_LEFT, false); + gpios_->set_pin(VOL_RIGHT, false); + gpios_->Write(); + + // Power-on reset sets attenuation to maximum anyway, but we want to be safe + // and not blow anyone's ears out. + for (int i = 0; i < 32; i++) { + gpios_->set_pin(VOL_LEFT, true); + gpios_->set_pin(VOL_RIGHT, true); + gpios_->Write(); + gpios_->set_pin(VOL_LEFT, false); + gpios_->set_pin(VOL_RIGHT, false); + gpios_->Write(); + } +} + +auto DigitalPot::SetRelative(int_fast8_t change) -> void { + if (change == 0) { + return; + } + + gpios_->set_pin(VOL_UP_DOWN, change > 0); + gpios_->Write(); + + for (int i = 0; i < std::abs(change); i++) { + gpios_->set_pin(VOL_LEFT, true); + gpios_->set_pin(VOL_RIGHT, true); + gpios_->Write(); + gpios_->set_pin(VOL_LEFT, false); + gpios_->set_pin(VOL_RIGHT, false); + gpios_->Write(); + } +} + +auto DigitalPot::SetRelative(Channel ch, int_fast8_t change) -> void { + if (change == 0) { + return; + } + + GpioExpander::Pin pin = (ch == Channel::kLeft) ? VOL_LEFT : VOL_RIGHT; + gpios_->set_pin(VOL_UP_DOWN, change > 0); + gpios_->Write(); + + for (int i = 0; i < std::abs(change); i++) { + gpios_->set_pin(pin, true); + gpios_->Write(); + gpios_->set_pin(pin, false); + gpios_->Write(); + } +} + +auto DigitalPot::SetZeroCrossDetect(bool enabled) -> void { + gpios_->set_pin(VOL_Z_CROSS, !enabled); // Active-low + gpios_->Write(); +} + +auto DigitalPot::GetMaxAttenuation() -> int_fast8_t { + return 31; +} + +auto DigitalPot::GetMinAttenuation() -> int_fast8_t { + return 0; +} + +} // namespace drivers |
