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.

375 lines
10KB

  1. // Copyright 2013 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 "tides/ui.h"
  29. #include "stmlib/system/storage.h"
  30. #include "stmlib/system/system_clock.h"
  31. #include "tides/cv_scaler.h"
  32. #include "tides/generator.h"
  33. namespace tides {
  34. const int32_t kLongPressDuration = 1000;
  35. const uint8_t kMagicNumber = 42;
  36. using namespace stmlib;
  37. Storage<0x801fc00, 4> mode_storage;
  38. void Ui::Init(Generator* generator, CvScaler* cv_scaler) {
  39. factory_testing_switch_.Init();
  40. leds_.Init();
  41. switches_.Init();
  42. mode_ = factory_testing_switch_.Read()
  43. ? UI_MODE_NORMAL
  44. : UI_MODE_FACTORY_TESTING;
  45. ignore_releases_ = 0;
  46. if (switches_.pressed_immediate(1)) {
  47. mode_ = UI_MODE_CALIBRATION_C2;
  48. ignore_releases_ = 1;
  49. }
  50. generator->feature_mode_ = Generator::FEAT_MODE_FUNCTION;
  51. generator_ = generator;
  52. cv_scaler_ = cv_scaler;
  53. if (!mode_storage.ParsimoniousLoad(&settings_, &version_token_) ||
  54. settings_.magic_number != kMagicNumber) {
  55. settings_.magic_number = kMagicNumber;
  56. mode_counter_ = 1;
  57. range_counter_ = 2;
  58. cv_scaler_->quantize_ = 0;
  59. generator->set_sync(false);
  60. } else {
  61. mode_counter_ = settings_.mode;
  62. range_counter_ = 2 - settings_.range;
  63. cv_scaler_->quantize_ = settings_.quantize;
  64. generator->feature_mode_ = static_cast<Generator::FeatureMode>(settings_.feature_mode);
  65. generator->set_sync(settings_.sync);
  66. }
  67. UpdateMode();
  68. UpdateRange();
  69. leds_.set_value(32768, 32768);
  70. }
  71. void Ui::SaveState() {
  72. settings_.mode = generator_->mode();
  73. settings_.range = generator_->range();
  74. settings_.sync = generator_->sync();
  75. settings_.feature_mode = generator_->feature_mode_;
  76. settings_.quantize = cv_scaler_->quantize_;
  77. mode_storage.ParsimoniousSave(settings_, &version_token_);
  78. }
  79. const uint16_t thresholds[ADC_CHANNEL_LAST][2] = {
  80. { 0, 64000 },
  81. { 16384, 49152 },
  82. { 16384, 49152 },
  83. { 4096, 61440 },
  84. { 4096, 61440 },
  85. { 4096, 61440 },
  86. { 4096, 61440 },
  87. };
  88. void Ui::UpdateFactoryTestingFlags(
  89. uint8_t gate_input_flags,
  90. const uint16_t* adc_values) {
  91. red_ = switches_.pressed(1);
  92. green_ = switches_.pressed(0);
  93. orange_ = gate_input_flags & CONTROL_GATE;
  94. orange_ |= gate_input_flags & CONTROL_FREEZE;
  95. orange_ |= gate_input_flags & CONTROL_CLOCK;
  96. for (uint16_t i = 0; i < ADC_CHANNEL_LAST; ++i) {
  97. uint16_t value = adc_values[i];
  98. if (i == ADC_CHANNEL_FM_ATTENUVERTER) {
  99. value = ~value;
  100. }
  101. green_ |= value < thresholds[i][0];
  102. if (i == 0) {
  103. orange_ |= value > thresholds[i][1];
  104. } else {
  105. red_ |= value > thresholds[i][1];
  106. }
  107. }
  108. }
  109. void Ui::Poll() {
  110. system_clock.Tick();
  111. switches_.Debounce();
  112. for (uint8_t i = 0; i < kNumSwitches; ++i) {
  113. if (switches_.just_pressed(i)) {
  114. queue_.AddEvent(CONTROL_SWITCH, i, 0);
  115. press_time_[i] = system_clock.milliseconds();
  116. }
  117. if (switches_.pressed(i) && press_time_[i] != 0) {
  118. int32_t pressed_time = system_clock.milliseconds() - press_time_[i];
  119. if (pressed_time > kLongPressDuration) {
  120. queue_.AddEvent(CONTROL_SWITCH, i, pressed_time);
  121. press_time_[i] = 0;
  122. }
  123. }
  124. if (switches_.released(i) && press_time_[i] != 0) {
  125. queue_.AddEvent(
  126. CONTROL_SWITCH,
  127. i,
  128. system_clock.milliseconds() - press_time_[i] + 1);
  129. press_time_[i] = 0;
  130. }
  131. }
  132. switch (mode_) {
  133. case UI_MODE_FEATURE_SWITCH:
  134. {
  135. bool blink = system_clock.milliseconds() & 32;
  136. switch (generator_->feature_mode_) {
  137. case Generator::FEAT_MODE_FUNCTION:
  138. leds_.set_mode(blink);
  139. leds_.set_value(0);
  140. leds_.set_rate(0);
  141. break;
  142. case Generator::FEAT_MODE_HARMONIC:
  143. leds_.set_mode(0);
  144. leds_.set_value(blink ? 65535 : 0);
  145. leds_.set_rate(0);
  146. break;
  147. case Generator::FEAT_MODE_RANDOM:
  148. leds_.set_mode(0);
  149. leds_.set_value(0);
  150. leds_.set_rate(blink ? 65535 : 0);
  151. break;
  152. }
  153. }
  154. break;
  155. case UI_MODE_QUANTIZE:
  156. {
  157. bool led1 = cv_scaler_->quantize_ & 1;
  158. bool led2 = cv_scaler_->quantize_ & 2;
  159. bool led3 = cv_scaler_->quantize_ & 4;
  160. uint16_t on = ((system_clock.milliseconds() & 16) &&
  161. (system_clock.milliseconds() & 8) &&
  162. (system_clock.milliseconds() & 4) &&
  163. (system_clock.milliseconds() & 2)) * 65535;
  164. uint16_t off = 0;
  165. leds_.set_mode(0, led1 ? on : off);
  166. leds_.set_value(0, led2 ? on : off);
  167. leds_.set_rate(0, led3 ? on : off);
  168. }
  169. break;
  170. case UI_MODE_NORMAL:
  171. {
  172. GeneratorMode mode = generator_->mode();
  173. leds_.set_mode(mode == GENERATOR_MODE_AR, mode == GENERATOR_MODE_AD);
  174. GeneratorRange range = generator_->range();
  175. switch (range) {
  176. case GENERATOR_RANGE_LOW:
  177. leds_.set_rate(0, 65535);
  178. break;
  179. case GENERATOR_RANGE_MEDIUM:
  180. if (generator_->sync()) {
  181. leds_.set_rate(8192, 16384);
  182. } else {
  183. leds_.set_rate(0);
  184. }
  185. break;
  186. case GENERATOR_RANGE_HIGH:
  187. leds_.set_rate(65535, 0);
  188. break;
  189. }
  190. bool blink_rate_led = generator_->sync() && \
  191. system_clock.milliseconds() & 128;
  192. if (blink_rate_led) {
  193. leds_.set_rate(0);
  194. }
  195. }
  196. break;
  197. case UI_MODE_CALIBRATION_C2:
  198. leds_.set_mode(true);
  199. leds_.set_rate(65535);
  200. leds_.set_value(65535);
  201. break;
  202. case UI_MODE_CALIBRATION_C4:
  203. leds_.set_mode(false, true);
  204. leds_.set_rate(0, 65535);
  205. leds_.set_value(0, 65535);
  206. break;
  207. case UI_MODE_FACTORY_TESTING:
  208. if (orange_) {
  209. leds_.set_mode(true, true);
  210. leds_.set_rate(65535, 65535);
  211. leds_.set_value(65535, 65535);
  212. } else if (red_) {
  213. leds_.set_mode(true, 0);
  214. leds_.set_rate(65535, 0);
  215. leds_.set_value(65535, 0);
  216. } else if (green_) {
  217. leds_.set_mode(false, true);
  218. leds_.set_rate(0, 65535);
  219. leds_.set_value(0, 65535);
  220. } else {
  221. leds_.set_mode(false, false);
  222. leds_.set_rate(0, 0);
  223. leds_.set_value(0, 0);
  224. }
  225. break;
  226. }
  227. leds_.Write();
  228. }
  229. inline void Ui::UpdateMode() {
  230. uint8_t i = mode_counter_ & 3;
  231. if (i == 3) {
  232. i = 1;
  233. }
  234. generator_->set_mode(static_cast<GeneratorMode>(i));
  235. SaveState();
  236. }
  237. inline void Ui::UpdateRange() {
  238. uint8_t i = range_counter_ & 3;
  239. if (i == 3) {
  240. i = 1;
  241. }
  242. generator_->set_range(static_cast<GeneratorRange>(2 - i));
  243. SaveState();
  244. }
  245. void Ui::FlushEvents() {
  246. queue_.Flush();
  247. }
  248. void Ui::OnSwitchPressed(const Event& e) {
  249. // double press -> feature switch mode
  250. if ((e.control_id == 0 && switches_.pressed_immediate(1)) ||
  251. (e.control_id == 1 && switches_.pressed_immediate(0))) {
  252. mode_ = UI_MODE_FEATURE_SWITCH;
  253. ignore_releases_ = 2;
  254. }
  255. }
  256. void Ui::OnSwitchReleased(const Event& e) {
  257. // hack for double presses
  258. if (ignore_releases_ > 0) {
  259. ignore_releases_--;
  260. return;
  261. }
  262. if (mode_ == UI_MODE_FACTORY_TESTING) {
  263. return;
  264. } else if (mode_ == UI_MODE_FEATURE_SWITCH) {
  265. uint8_t feat = generator_->feature_mode_;
  266. int8_t dir = e.control_id == 0 ? -1 : 1;
  267. int8_t mode = (feat + dir) % 3;
  268. if (mode == -1) mode = 2;
  269. generator_->feature_mode_ = static_cast<Generator::FeatureMode>(mode);
  270. UpdateMode();
  271. UpdateRange();
  272. } else if (mode_ == UI_MODE_QUANTIZE) {
  273. if (e.data > kLongPressDuration) {
  274. mode_ = UI_MODE_NORMAL;
  275. } else {
  276. uint8_t q = cv_scaler_->quantize_;
  277. int8_t dir = e.control_id == 0 ? -1 : 1;
  278. int8_t quant = (q + dir) % 8;
  279. if (quant == -1) quant = 7;
  280. cv_scaler_->quantize_ = quant;
  281. SaveState();
  282. }
  283. } else if (mode_ == UI_MODE_CALIBRATION_C2) {
  284. if (e.data > kLongPressDuration) {
  285. ++long_press_counter_;
  286. }
  287. if (e.control_id == 0) {
  288. cv_scaler_->CaptureCalibrationValues();
  289. mode_ = UI_MODE_CALIBRATION_C4;
  290. } else {
  291. mode_ = UI_MODE_NORMAL;
  292. }
  293. } else if (mode_ == UI_MODE_CALIBRATION_C4) {
  294. mode_ = UI_MODE_NORMAL;
  295. if (e.control_id == 0) {
  296. cv_scaler_->Calibrate();
  297. }
  298. } else {
  299. long_press_counter_ = 0;
  300. switch (e.control_id) {
  301. case 0:
  302. if (e.data > kLongPressDuration) {
  303. mode_ = UI_MODE_QUANTIZE;
  304. } else {
  305. ++mode_counter_;
  306. UpdateMode();
  307. }
  308. break;
  309. case 1:
  310. if (e.data > kLongPressDuration) {
  311. generator_->set_sync(!generator_->sync());
  312. SaveState();
  313. } else {
  314. ++range_counter_;
  315. UpdateRange();
  316. }
  317. break;
  318. }
  319. }
  320. }
  321. void Ui::DoEvents() {
  322. while (queue_.available()) {
  323. Event e = queue_.PullEvent();
  324. if (e.control_type == CONTROL_SWITCH) {
  325. if (e.data == 0) {
  326. OnSwitchPressed(e);
  327. } else {
  328. OnSwitchReleased(e);
  329. }
  330. }
  331. }
  332. if (queue_.idle_time() > 2000) {
  333. queue_.Touch();
  334. if (mode_ == UI_MODE_FEATURE_SWITCH)
  335. mode_ = UI_MODE_NORMAL;
  336. }
  337. }
  338. } // namespace tides