You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

534 lines
16KB

  1. // Copyright 2015 Olivier Gillet.
  2. //
  3. // Author: Olivier Gillet (ol.gillet@gmail.com)
  4. //
  5. // Permission is hereby granted, free of charge, to any person obtaining a copy
  6. // of this software and associated documentation files (the "Software"), to deal
  7. // in the Software without restriction, including without limitation the rights
  8. // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  9. // copies of the Software, and to permit persons to whom the Software is
  10. // furnished to do so, subject to the following conditions:
  11. //
  12. // The above copyright notice and this permission notice shall be included in
  13. // all copies or substantial portions of the Software.
  14. //
  15. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  16. // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  17. // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  18. // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  19. // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  20. // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  21. // THE SOFTWARE.
  22. //
  23. // See http://creativecommons.org/licenses/MIT/ for more information.
  24. //
  25. // -----------------------------------------------------------------------------
  26. //
  27. // User interface.
  28. #include "marbles/ui.h"
  29. #include <algorithm>
  30. #include "stmlib/system/system_clock.h"
  31. #include "marbles/drivers/clock_inputs.h"
  32. #include "marbles/cv_reader.h"
  33. #include "marbles/scale_recorder.h"
  34. #include "marbles/settings.h"
  35. namespace marbles {
  36. const int32_t kLongPressDuration = 2000;
  37. using namespace std;
  38. using namespace stmlib;
  39. /* static */
  40. const LedColor Ui::palette_[4] = {
  41. LED_COLOR_GREEN,
  42. LED_COLOR_YELLOW,
  43. LED_COLOR_RED,
  44. LED_COLOR_OFF
  45. };
  46. /* static */
  47. AlternateKnobMapping Ui::alternate_knob_mappings_[ADC_CHANNEL_LAST];
  48. void Ui::Init(
  49. Settings* settings,
  50. CvReader* cv_reader,
  51. ScaleRecorder* scale_recorder,
  52. ClockInputs* clock_inputs) {
  53. settings_ = settings;
  54. cv_reader_ = cv_reader;
  55. scale_recorder_ = scale_recorder;
  56. clock_inputs_ = clock_inputs;
  57. leds_.Init();
  58. switches_.Init();
  59. queue_.Init();
  60. // Initialize generator from settings_->state();
  61. fill(&pot_value_[0], &pot_value_[ADC_CHANNEL_LAST], 0.0f);
  62. State* state = settings_->mutable_state();
  63. alternate_knob_mappings_[ADC_CHANNEL_T_BIAS].unlock_switch = SWITCH_T_MODEL;
  64. alternate_knob_mappings_[ADC_CHANNEL_T_BIAS].destination = &state->t_pulse_width_mean;
  65. alternate_knob_mappings_[ADC_CHANNEL_T_JITTER].unlock_switch = SWITCH_T_MODEL;
  66. alternate_knob_mappings_[ADC_CHANNEL_T_JITTER].destination = &state->t_pulse_width_std;
  67. alternate_knob_mappings_[ADC_CHANNEL_T_RATE].unlock_switch = SWITCH_X_MODE;
  68. alternate_knob_mappings_[ADC_CHANNEL_T_RATE].destination = &state->y_divider;
  69. alternate_knob_mappings_[ADC_CHANNEL_X_SPREAD].unlock_switch = SWITCH_X_MODE;
  70. alternate_knob_mappings_[ADC_CHANNEL_X_SPREAD].destination = &state->y_spread;
  71. alternate_knob_mappings_[ADC_CHANNEL_X_BIAS].unlock_switch = SWITCH_X_MODE;
  72. alternate_knob_mappings_[ADC_CHANNEL_X_BIAS].destination = &state->y_bias;
  73. alternate_knob_mappings_[ADC_CHANNEL_X_STEPS].unlock_switch = SWITCH_X_MODE;
  74. alternate_knob_mappings_[ADC_CHANNEL_X_STEPS].destination = &state->y_steps;
  75. setting_modification_flag_ = false;
  76. output_test_mode_ = false;
  77. if (switches_.pressed_immediate(SWITCH_X_MODE)) {
  78. if (state->color_blind == 1) {
  79. state->color_blind = 0;
  80. } else {
  81. state->color_blind = 1;
  82. }
  83. settings_->SaveState();
  84. }
  85. deja_vu_lock_ = false;
  86. }
  87. void Ui::SaveState() {
  88. settings_->SaveState();
  89. }
  90. void Ui::Poll() {
  91. // 1kHz.
  92. system_clock.Tick();
  93. switches_.Debounce();
  94. for (int i = 0; i < SWITCH_LAST; ++i) {
  95. if (switches_.just_pressed(Switch(i))) {
  96. queue_.AddEvent(CONTROL_SWITCH, i, 0);
  97. press_time_[i] = system_clock.milliseconds();
  98. ignore_release_[i] = false;
  99. }
  100. if (switches_.pressed(Switch(i)) && !ignore_release_[i]) {
  101. int32_t pressed_time = system_clock.milliseconds() - press_time_[i];
  102. if (pressed_time > kLongPressDuration && !setting_modification_flag_) {
  103. queue_.AddEvent(CONTROL_SWITCH, i, pressed_time);
  104. ignore_release_[i] = true;
  105. }
  106. }
  107. if (switches_.released(Switch(i)) && !ignore_release_[i]) {
  108. queue_.AddEvent(
  109. CONTROL_SWITCH,
  110. i,
  111. system_clock.milliseconds() - press_time_[i] + 1);
  112. ignore_release_[i] = true;
  113. }
  114. }
  115. UpdateLEDs();
  116. }
  117. /* static */
  118. LedColor Ui::MakeColor(uint8_t value, bool color_blind) {
  119. bool slow_blink = (system_clock.milliseconds() & 255) > 128;
  120. uint8_t bank = value >= 3 ? 1 : 0;
  121. value -= bank * 3;
  122. LedColor color = palette_[value];
  123. if (color_blind) {
  124. uint8_t pwm_counter = system_clock.milliseconds() & 15;
  125. uint8_t triangle = (system_clock.milliseconds() >> 5) & 31;
  126. triangle = triangle < 16 ? triangle : 31 - triangle;
  127. if (value == 0) {
  128. color = pwm_counter < (4 + (triangle >> 2))
  129. ? LED_COLOR_GREEN
  130. : LED_COLOR_OFF;
  131. } else if (value == 1) {
  132. color = LED_COLOR_YELLOW;
  133. } else {
  134. color = pwm_counter == 0 ? LED_COLOR_RED : LED_COLOR_OFF;
  135. }
  136. }
  137. return slow_blink || !bank ? color : LED_COLOR_OFF;
  138. }
  139. void Ui::UpdateLEDs() {
  140. bool blink = (system_clock.milliseconds() & 127) > 64;
  141. bool slow_blink = (system_clock.milliseconds() & 255) > 128;
  142. bool fast_blink = (system_clock.milliseconds() & 63) > 32;
  143. const State& state = settings_->state();
  144. bool cb = state.color_blind == 1;
  145. LedColor scale_color = state.x_scale < 3
  146. ? (slow_blink ? palette_[state.x_scale] : LED_COLOR_OFF)
  147. : (fast_blink ? palette_[state.x_scale - 3] : LED_COLOR_OFF);
  148. if (cb) {
  149. int poly_counter = (system_clock.milliseconds() >> 6) % 12;
  150. if ((poly_counter >> 1) < (state.x_scale + 1) && (poly_counter & 1)) {
  151. scale_color = LED_COLOR_YELLOW;
  152. } else {
  153. scale_color = LED_COLOR_OFF;
  154. }
  155. }
  156. leds_.Clear();
  157. int slow_triangle = (system_clock.milliseconds() & 1023) >> 5;
  158. slow_triangle = slow_triangle >= 16 ? 31 - slow_triangle : slow_triangle;
  159. int pw = system_clock.milliseconds() & 15;
  160. bool deja_vu_glow = !deja_vu_lock_ || (slow_triangle >= pw);
  161. switch (mode_) {
  162. case UI_MODE_NORMAL:
  163. case UI_MODE_RECORD_SCALE:
  164. {
  165. leds_.set(LED_T_MODEL, MakeColor(state.t_model, cb));
  166. leds_.set(LED_T_RANGE, MakeColor(state.t_range, cb));
  167. leds_.set(LED_T_DEJA_VU,
  168. state.t_deja_vu && deja_vu_glow ?
  169. LED_COLOR_GREEN : LED_COLOR_OFF);
  170. leds_.set(LED_X_CONTROL_MODE, MakeColor(state.x_control_mode, cb));
  171. leds_.set(LED_X_DEJA_VU,
  172. state.x_deja_vu && deja_vu_glow ?
  173. LED_COLOR_GREEN : LED_COLOR_OFF);
  174. if (mode_ == UI_MODE_NORMAL) {
  175. leds_.set(LED_X_RANGE,
  176. state.x_register_mode
  177. ? LED_COLOR_OFF
  178. : MakeColor(state.x_range, cb));
  179. leds_.set(LED_X_EXT,
  180. state.x_register_mode ? LED_COLOR_GREEN : LED_COLOR_OFF);
  181. } else {
  182. leds_.set(LED_X_RANGE, scale_color);
  183. leds_.set(LED_X_EXT, LED_COLOR_GREEN);
  184. }
  185. }
  186. break;
  187. case UI_MODE_SELECT_SCALE:
  188. leds_.set(LED_X_RANGE, scale_color);
  189. break;
  190. case UI_MODE_CALIBRATION_1:
  191. leds_.set(LED_T_RANGE, blink ? MakeColor(0, cb) : LED_COLOR_OFF);
  192. break;
  193. case UI_MODE_CALIBRATION_2:
  194. leds_.set(LED_T_RANGE, blink ? MakeColor(1, cb) : LED_COLOR_OFF);
  195. break;
  196. case UI_MODE_CALIBRATION_3:
  197. leds_.set(LED_X_RANGE, blink ? MakeColor(0, cb) : LED_COLOR_OFF);
  198. break;
  199. case UI_MODE_CALIBRATION_4:
  200. leds_.set(LED_X_RANGE, blink ? MakeColor(1, cb) : LED_COLOR_OFF);
  201. break;
  202. case UI_MODE_PANIC:
  203. leds_.set(LED_T_MODEL, blink ? LED_COLOR_RED : LED_COLOR_OFF);
  204. leds_.set(LED_T_RANGE, !blink ? LED_COLOR_RED : LED_COLOR_OFF);
  205. leds_.set(LED_X_CONTROL_MODE, !blink ? LED_COLOR_RED : LED_COLOR_OFF);
  206. leds_.set(LED_X_RANGE, blink ? LED_COLOR_RED : LED_COLOR_OFF);
  207. break;
  208. }
  209. leds_.Write();
  210. }
  211. void Ui::FlushEvents() {
  212. queue_.Flush();
  213. }
  214. void Ui::OnSwitchPressed(const Event& e) {
  215. }
  216. void Ui::OnSwitchReleased(const Event& e) {
  217. if (setting_modification_flag_) {
  218. for (int i = 0; i < ADC_CHANNEL_LAST; ++i) {
  219. cv_reader_->mutable_channel(i)->UnlockPot();
  220. }
  221. setting_modification_flag_ = false;
  222. return;
  223. }
  224. // Check if the other switch is still pressed.
  225. if (e.control_id == SWITCH_T_RANGE && switches_.pressed(SWITCH_X_RANGE)) {
  226. mode_ = UI_MODE_CALIBRATION_1;
  227. ignore_release_[SWITCH_T_RANGE] = ignore_release_[SWITCH_X_RANGE] = true;
  228. return;
  229. }
  230. State* state = settings_->mutable_state();
  231. switch (e.control_id) {
  232. case SWITCH_T_DEJA_VU:
  233. state->t_deja_vu = !state->t_deja_vu;
  234. break;
  235. case SWITCH_X_DEJA_VU:
  236. state->x_deja_vu = !state->x_deja_vu;
  237. break;
  238. case SWITCH_T_MODEL:
  239. {
  240. uint8_t bank = state->t_model / 3;
  241. if (e.data >= kLongPressDuration) {
  242. if (!bank) {
  243. state->t_model += 3;
  244. }
  245. } else {
  246. if (bank) {
  247. state->t_model -= 3;
  248. } else {
  249. state->t_model = (state->t_model + 1) % 3;
  250. }
  251. }
  252. SaveState();
  253. }
  254. break;
  255. case SWITCH_T_RANGE:
  256. {
  257. if (mode_ >= UI_MODE_CALIBRATION_1 && mode_ <= UI_MODE_CALIBRATION_4) {
  258. NextCalibrationStep();
  259. } else {
  260. state->t_range = (state->t_range + 1) % 3;
  261. }
  262. SaveState();
  263. }
  264. break;
  265. case SWITCH_X_MODE:
  266. state->x_control_mode = (state->x_control_mode + 1) % 3;
  267. SaveState();
  268. break;
  269. case SWITCH_X_EXT:
  270. if (mode_ == UI_MODE_RECORD_SCALE) {
  271. int scale_index = settings_->state().x_scale;
  272. bool success = true;
  273. if (e.data >= kLongPressDuration) {
  274. settings_->ResetScale(scale_index);
  275. } else {
  276. success = scale_recorder_->ExtractScale(
  277. settings_->mutable_scale(scale_index));
  278. }
  279. if (success) {
  280. settings_->SavePersistentData();
  281. settings_->set_dirty_scale_index(scale_index);
  282. }
  283. mode_ = UI_MODE_NORMAL;
  284. } else if (e.data >= kLongPressDuration) {
  285. mode_ = UI_MODE_RECORD_SCALE;
  286. scale_recorder_->Clear();
  287. } else {
  288. state->x_register_mode = !state->x_register_mode;
  289. SaveState();
  290. }
  291. break;
  292. case SWITCH_X_RANGE:
  293. if (mode_ >= UI_MODE_CALIBRATION_1 && mode_ <= UI_MODE_CALIBRATION_4) {
  294. NextCalibrationStep();
  295. } else if (e.data >= kLongPressDuration) {
  296. if (mode_ == UI_MODE_NORMAL) {
  297. mode_ = UI_MODE_SELECT_SCALE;
  298. }
  299. } else if (mode_ == UI_MODE_SELECT_SCALE) {
  300. state->x_scale = (state->x_scale + 1) % kNumScales;
  301. } else {
  302. if (!state->x_register_mode) {
  303. state->x_range = (state->x_range + 1) % 3;
  304. }
  305. }
  306. SaveState();
  307. break;
  308. }
  309. }
  310. void Ui::TerminateScaleRecording() {
  311. for (int i = 0; i < ADC_CHANNEL_LAST; ++i) {
  312. cv_reader_->mutable_channel(i)->UnlockPot();
  313. }
  314. mode_ = UI_MODE_NORMAL;
  315. }
  316. void Ui::NextCalibrationStep() {
  317. switch (mode_) {
  318. case UI_MODE_CALIBRATION_1:
  319. cv_reader_->CalibrateOffsets();
  320. cv_reader_->CalibrateRateC1();
  321. mode_ = UI_MODE_CALIBRATION_2;
  322. break;
  323. case UI_MODE_CALIBRATION_2:
  324. cv_reader_->CalibrateRateC3();
  325. mode_ = UI_MODE_CALIBRATION_3;
  326. break;
  327. case UI_MODE_CALIBRATION_3:
  328. cv_reader_->CalibrateSpreadC1();
  329. mode_ = UI_MODE_CALIBRATION_4;
  330. break;
  331. case UI_MODE_CALIBRATION_4:
  332. if (cv_reader_->CalibrateSpreadC3()) {
  333. settings_->SavePersistentData();
  334. mode_ = UI_MODE_NORMAL;
  335. } else {
  336. mode_ = UI_MODE_PANIC;
  337. }
  338. break;
  339. default:
  340. break;
  341. }
  342. }
  343. void Ui::UpdateHiddenParameters() {
  344. // Check if some pots have been moved.
  345. for (int i = 0; i < ADC_CHANNEL_LAST; ++i) {
  346. float new_value = cv_reader_->channel(i).unscaled_pot();
  347. float old_value = pot_value_[i];
  348. bool changed = fabs(new_value - old_value) >= 0.008f;
  349. if (changed) {
  350. pot_value_[i] = new_value;
  351. AlternateKnobMapping mapping = alternate_knob_mappings_[i];
  352. if (switches_.pressed(mapping.unlock_switch)) {
  353. if (mapping.unlock_switch == SWITCH_T_RANGE && new_value < 0.1f) {
  354. new_value = 0.0f;
  355. }
  356. *mapping.destination = static_cast<uint8_t>(new_value * 255.0f);
  357. cv_reader_->mutable_channel(i)->LockPot();
  358. // The next time a switch is released, we unlock the pots.
  359. setting_modification_flag_ = true;
  360. }
  361. }
  362. }
  363. }
  364. void Ui::DoEvents() {
  365. while (queue_.available()) {
  366. Event e = queue_.PullEvent();
  367. if (e.control_type == CONTROL_SWITCH) {
  368. if (e.data == 0) {
  369. OnSwitchPressed(e);
  370. } else {
  371. OnSwitchReleased(e);
  372. }
  373. }
  374. }
  375. UpdateHiddenParameters();
  376. if (queue_.idle_time() > 800 && mode_ == UI_MODE_PANIC) {
  377. mode_ = UI_MODE_NORMAL;
  378. }
  379. if (mode_ == UI_MODE_SELECT_SCALE) {
  380. if (queue_.idle_time() > 4000) {
  381. mode_ = UI_MODE_NORMAL;
  382. queue_.Touch();
  383. }
  384. } else if (queue_.idle_time() > 1000) {
  385. queue_.Touch();
  386. }
  387. }
  388. uint8_t Ui::HandleFactoryTestingRequest(uint8_t command) {
  389. uint8_t argument = command & 0x1f;
  390. command = command >> 5;
  391. uint8_t reply = 0;
  392. switch (command) {
  393. case FACTORY_TESTING_READ_POT:
  394. case FACTORY_TESTING_READ_CV:
  395. reply = cv_reader_->adc_value(argument);
  396. break;
  397. case FACTORY_TESTING_READ_NORMALIZATION:
  398. reply = clock_inputs_->is_normalized(ClockInput(argument)) ? 255 : 0;
  399. break;
  400. case FACTORY_TESTING_READ_GATE:
  401. reply = argument >= SWITCH_LAST
  402. ? clock_inputs_->value(ClockInput(argument - SWITCH_LAST))
  403. : switches_.pressed(Switch(argument));
  404. break;
  405. case FACTORY_TESTING_GENERATE_TEST_SIGNALS:
  406. output_test_mode_ = static_cast<bool>(argument);
  407. fill(
  408. &output_test_forced_dac_code_[0],
  409. &output_test_forced_dac_code_[4],
  410. 0);
  411. break;
  412. case FACTORY_TESTING_CALIBRATE:
  413. if (argument == 0) {
  414. // Revert all settings before getting into calibration mode.
  415. settings_->mutable_state()->t_deja_vu = 0;
  416. settings_->mutable_state()->x_deja_vu = 0;
  417. settings_->mutable_state()->t_model = 0;
  418. settings_->mutable_state()->t_range = 1;
  419. settings_->mutable_state()->x_control_mode = 0;
  420. settings_->mutable_state()->x_range = 2;
  421. settings_->mutable_state()->x_register_mode = 0;
  422. settings_->SavePersistentData();
  423. mode_ = UI_MODE_CALIBRATION_1;
  424. } else {
  425. NextCalibrationStep();
  426. }
  427. {
  428. const CalibrationData& cal = settings_->calibration_data();
  429. float voltage = (argument & 1) == 0 ? 1.0f : 3.0f;
  430. for (int i = 0; i < 4; ++i) {
  431. output_test_forced_dac_code_[i] = static_cast<uint16_t>(
  432. voltage * cal.dac_scale[i] + cal.dac_offset[i]);
  433. }
  434. }
  435. queue_.Touch();
  436. break;
  437. case FACTORY_TESTING_FORCE_DAC_CODE:
  438. {
  439. int channel = argument >> 2;
  440. int step = argument & 0x3;
  441. if (step == 0) {
  442. output_test_forced_dac_code_[channel] = 0xaf35;
  443. } else if (step == 1) {
  444. output_test_forced_dac_code_[channel] = 0x1d98;
  445. } else {
  446. CalibrationData* cal = settings_->mutable_calibration_data();
  447. cal->dac_offset[channel] = static_cast<float>(
  448. calibration_data_ & 0xffff);
  449. cal->dac_scale[channel] = static_cast<float>(
  450. calibration_data_ >> 16) * -0.125f;
  451. output_test_forced_dac_code_[channel] = static_cast<uint16_t>(cal->dac_scale[channel] + cal->dac_offset[channel]);
  452. settings_->SavePersistentData();
  453. }
  454. }
  455. break;
  456. case FACTORY_TESTING_WRITE_CALIBRATION_DATA_NIBBLE:
  457. calibration_data_ <<= 4;
  458. calibration_data_ |= argument & 0xf;
  459. break;
  460. }
  461. return reply;
  462. }
  463. } // namespace marbles