|
- // Copyright 2013 Olivier Gillet.
- //
- // Author: Olivier Gillet (ol.gillet@gmail.com)
- //
- // Permission is hereby granted, free of charge, to any person obtaining a copy
- // of this software and associated documentation files (the "Software"), to deal
- // in the Software without restriction, including without limitation the rights
- // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- // copies of the Software, and to permit persons to whom the Software is
- // furnished to do so, subject to the following conditions:
- //
- // The above copyright notice and this permission notice shall be included in
- // all copies or substantial portions of the Software.
- //
- // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- // THE SOFTWARE.
- //
- // See http://creativecommons.org/licenses/MIT/ for more information.
- //
- // -----------------------------------------------------------------------------
- //
- // User interface.
-
- #include "tides/ui.h"
-
- #include "stmlib/system/storage.h"
- #include "stmlib/system/system_clock.h"
-
- #include "tides/cv_scaler.h"
- #include "tides/generator.h"
-
- namespace tides {
-
- const int32_t kLongPressDuration = 1000;
-
- using namespace stmlib;
-
- Storage<0x801fc00, 4> mode_storage;
-
- void Ui::Init(Generator* generator, CvScaler* cv_scaler) {
- factory_testing_switch_.Init();
- leds_.Init();
- switches_.Init();
- mode_ = factory_testing_switch_.Read()
- ? UI_MODE_NORMAL
- : UI_MODE_FACTORY_TESTING;
-
- generator_ = generator;
- cv_scaler_ = cv_scaler;
-
- if (!mode_storage.ParsimoniousLoad(&settings_, &version_token_)) {
- mode_counter_ = 1;
- range_counter_ = 2;
- generator->set_sync(false);
- } else {
- mode_counter_ = settings_.mode;
- range_counter_ = 2 - settings_.range;
- generator->set_sync(settings_.sync);
- }
-
- UpdateMode();
- UpdateRange();
- leds_.set_value(32768, 32768);
- }
-
- void Ui::SaveState() {
- settings_.mode = generator_->mode();
- settings_.range = generator_->range();
- settings_.sync = generator_->sync();
- mode_storage.ParsimoniousSave(settings_, &version_token_);
- }
-
- const uint16_t thresholds[ADC_CHANNEL_LAST][2] = {
- { 0, 64000 },
- { 16384, 49152 },
- { 16384, 49152 },
- { 4096, 61440 },
- { 4096, 61440 },
- { 4096, 61440 },
- { 4096, 61440 },
- };
-
- void Ui::UpdateFactoryTestingFlags(
- uint8_t gate_input_flags,
- const uint16_t* adc_values) {
- red_ = switches_.pressed(1);
- green_ = switches_.pressed(0);
- orange_ = gate_input_flags & CONTROL_GATE;
- orange_ |= gate_input_flags & CONTROL_FREEZE;
- orange_ |= gate_input_flags & CONTROL_CLOCK;
-
- for (uint16_t i = 0; i < ADC_CHANNEL_LAST; ++i) {
- uint16_t value = adc_values[i];
- if (i == ADC_CHANNEL_FM_ATTENUVERTER) {
- value = ~value;
- }
- green_ |= value < thresholds[i][0];
- if (i == 0) {
- orange_ |= value > thresholds[i][1];
- } else {
- red_ |= value > thresholds[i][1];
- }
- }
- }
-
- void Ui::Poll() {
- system_clock.Tick();
- switches_.Debounce();
-
- for (uint8_t i = 0; i < kNumSwitches; ++i) {
- if (switches_.just_pressed(i)) {
- queue_.AddEvent(CONTROL_SWITCH, i, 0);
- press_time_[i] = system_clock.milliseconds();
- }
- if (switches_.pressed(i) && press_time_[i] != 0) {
- int32_t pressed_time = system_clock.milliseconds() - press_time_[i];
- if (pressed_time > kLongPressDuration) {
- queue_.AddEvent(CONTROL_SWITCH, i, pressed_time);
- press_time_[i] = 0;
- }
- }
- if (switches_.released(i) && press_time_[i] != 0) {
- queue_.AddEvent(
- CONTROL_SWITCH,
- i,
- system_clock.milliseconds() - press_time_[i] + 1);
- press_time_[i] = 0;
- }
- }
-
- switch (mode_) {
- case UI_MODE_NORMAL:
- {
- GeneratorMode mode = generator_->mode();
- leds_.set_mode(mode == GENERATOR_MODE_AR, mode == GENERATOR_MODE_AD);
-
- GeneratorRange range = generator_->range();
- switch (range) {
- case GENERATOR_RANGE_LOW:
- leds_.set_rate(0, 65535);
- break;
- case GENERATOR_RANGE_MEDIUM:
- if (generator_->sync()) {
- leds_.set_rate(8192, 16384);
- } else {
- leds_.set_rate(0);
- }
- break;
- case GENERATOR_RANGE_HIGH:
- leds_.set_rate(65535, 0);
- break;
- }
- bool blink_rate_led = generator_->sync() && \
- system_clock.milliseconds() & 128;
- if (blink_rate_led) {
- leds_.set_rate(0);
- }
- }
- break;
-
- case UI_MODE_CALIBRATION_C2:
- leds_.set_mode(true);
- leds_.set_rate(65535);
- leds_.set_value(65535);
- break;
-
- case UI_MODE_CALIBRATION_C4:
- leds_.set_mode(false, true);
- leds_.set_rate(0, 65535);
- leds_.set_value(0, 65535);
- break;
-
- case UI_MODE_PAQUES:
- leds_.set_mode(true, false);
- leds_.set_rate(65535, 0);
- leds_.set_value(65535, 0);
- break;
-
- case UI_MODE_FACTORY_TESTING:
- if (orange_) {
- leds_.set_mode(true, true);
- leds_.set_rate(65535, 65535);
- leds_.set_value(65535, 65535);
- } else if (red_) {
- leds_.set_mode(true, 0);
- leds_.set_rate(65535, 0);
- leds_.set_value(65535, 0);
- } else if (green_) {
- leds_.set_mode(false, true);
- leds_.set_rate(0, 65535);
- leds_.set_value(0, 65535);
- } else {
- leds_.set_mode(false, false);
- leds_.set_rate(0, 0);
- leds_.set_value(0, 0);
- }
- break;
- }
-
- leds_.Write();
- }
-
- inline void Ui::UpdateMode() {
- uint8_t i = mode_counter_ & 3;
- if (i == 3) {
- i = 1;
- }
- generator_->set_mode(static_cast<GeneratorMode>(i));
- SaveState();
- }
-
- inline void Ui::UpdateRange() {
- uint8_t i = range_counter_ & 3;
- if (i == 3) {
- i = 1;
- }
- generator_->set_range(static_cast<GeneratorRange>(2 - i));
- SaveState();
- }
-
- void Ui::FlushEvents() {
- queue_.Flush();
- }
-
- void Ui::OnSwitchPressed(const Event& e) {
- switch (e.control_id) {
- case 0:
- break;
-
- case 1:
- break;
- }
- }
-
- void Ui::OnSwitchReleased(const Event& e) {
- if (mode_ == UI_MODE_FACTORY_TESTING) {
- return;
- } else if (mode_ == UI_MODE_PAQUES) {
- mode_ = UI_MODE_NORMAL;
- } else if (mode_ == UI_MODE_CALIBRATION_C2) {
- if (e.data > kLongPressDuration) {
- ++long_press_counter_;
- }
- if (e.control_id == 0) {
- cv_scaler_->CaptureCalibrationValues();
- mode_ = UI_MODE_CALIBRATION_C4;
- } else {
- mode_ = UI_MODE_NORMAL;
- }
- } else if (mode_ == UI_MODE_CALIBRATION_C4) {
- mode_ = UI_MODE_NORMAL;
- if (e.control_id == 0) {
- cv_scaler_->Calibrate();
- } else if (e.control_id == 1 && long_press_counter_ == 1 &&
- e.data > kLongPressDuration) {
- mode_ = UI_MODE_PAQUES;
- }
- } else {
- long_press_counter_ = 0;
- switch (e.control_id) {
- case 0:
- if (e.data > kLongPressDuration &&
- cv_scaler_->can_enter_calibration()) {
- mode_ = UI_MODE_CALIBRATION_C2;
- } else {
- ++mode_counter_;
- UpdateMode();
- }
- break;
-
- case 1:
- if (e.data > kLongPressDuration) {
- generator_->set_sync(!generator_->sync());
- SaveState();
- } else {
- ++range_counter_;
- UpdateRange();
- }
- break;
- }
- }
- }
-
- void Ui::DoEvents() {
- while (queue_.available()) {
- Event e = queue_.PullEvent();
- if (e.control_type == CONTROL_SWITCH) {
- if (e.data == 0) {
- OnSwitchPressed(e);
- } else {
- OnSwitchReleased(e);
- }
- }
- }
- if (queue_.idle_time() > 1000) {
- queue_.Touch();
- }
- }
-
- } // namespace tides
|