pokemon_pins.c 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163
  1. #include <gui/modules/variable_item_list.h>
  2. #include <furi.h>
  3. #include <src/include/pokemon_app.h>
  4. #include <src/scenes/include/pokemon_scene.h>
  5. /* This is a bit of a hack to save some space and not have to refactor this scene.
  6. * We re-use the name and pin from the global gpio pin definition, but need to
  7. * skip the two debug pins in the row of header pins.
  8. *
  9. * This is hard-coded, not really portable, but saves a couple hundred bytes :D
  10. *
  11. * In the future, the right way to do this would be to build our own table of
  12. * non-debug pins from whatever the current platforms gpio pin definition is.
  13. */
  14. #define NUM_PINS 8
  15. static const GpioPinRecord* named_pins[NUM_PINS] = {
  16. &gpio_pins[0],
  17. &gpio_pins[1],
  18. &gpio_pins[2],
  19. &gpio_pins[3],
  20. &gpio_pins[4],
  21. &gpio_pins[5],
  22. &gpio_pins[10],
  23. &gpio_pins[11]};
  24. /* This must match gblink's enum order */
  25. static const char* named_groups[] = {
  26. "Original",
  27. "MLVK2.5",
  28. "Custom",
  29. "",
  30. };
  31. struct itemlist_builder {
  32. VariableItem* named;
  33. VariableItem* serin;
  34. VariableItem* serout;
  35. VariableItem* clk;
  36. uint8_t named_index;
  37. uint8_t serin_index;
  38. uint8_t serout_index;
  39. uint8_t clk_index;
  40. };
  41. /* Just make it a global, whatever */
  42. static struct itemlist_builder builder = {0};
  43. static void select_pins_rebuild_list(PokemonFap* pokemon_fap);
  44. static void select_pins_set(PokemonFap* pokemon_fap) {
  45. pokemon_fap->pins.serin = named_pins[builder.serin_index]->pin;
  46. pokemon_fap->pins.serout = named_pins[builder.serout_index]->pin;
  47. pokemon_fap->pins.clk = named_pins[builder.clk_index]->pin;
  48. }
  49. static void select_named_group_callback(VariableItem* item) {
  50. uint8_t index = variable_item_get_current_value_index(item);
  51. PokemonFap* pokemon_fap = variable_item_get_context(item);
  52. variable_item_set_current_value_text(item, named_groups[index]);
  53. builder.named_index = index;
  54. select_pins_rebuild_list(pokemon_fap);
  55. variable_item_list_set_selected_item(pokemon_fap->variable_item_list, 0);
  56. }
  57. static void select_pins_serin_callback(VariableItem* item) {
  58. uint8_t index = variable_item_get_current_value_index(item);
  59. PokemonFap* pokemon_fap = variable_item_get_context(item);
  60. variable_item_set_current_value_text(item, named_pins[index]->name);
  61. builder.serin_index = index;
  62. select_pins_rebuild_list(pokemon_fap);
  63. variable_item_list_set_selected_item(pokemon_fap->variable_item_list, 1);
  64. }
  65. static void select_pins_serout_callback(VariableItem* item) {
  66. uint8_t index = variable_item_get_current_value_index(item);
  67. PokemonFap* pokemon_fap = variable_item_get_context(item);
  68. variable_item_set_current_value_text(item, named_pins[index]->name);
  69. builder.serout_index = index;
  70. select_pins_rebuild_list(pokemon_fap);
  71. variable_item_list_set_selected_item(pokemon_fap->variable_item_list, 2);
  72. }
  73. static void select_pins_clk_callback(VariableItem* item) {
  74. uint8_t index = variable_item_get_current_value_index(item);
  75. PokemonFap* pokemon_fap = variable_item_get_context(item);
  76. variable_item_set_current_value_text(item, named_pins[index]->name);
  77. builder.clk_index = index;
  78. select_pins_rebuild_list(pokemon_fap);
  79. variable_item_list_set_selected_item(pokemon_fap->variable_item_list, 3);
  80. }
  81. static void select_pins_rebuild_list(PokemonFap* pokemon_fap) {
  82. int num;
  83. /* HACK: TODO: It would be better to do this programmatically, but, I'm kind
  84. * of done working on this feature so its going to be hardcoded for now.
  85. */
  86. switch(builder.named_index) {
  87. case 0: // Original
  88. num = 1;
  89. builder.serin_index = 5;
  90. builder.serout_index = 3;
  91. builder.clk_index = 4;
  92. break;
  93. case 1: // MALVEKE
  94. num = 1;
  95. builder.serin_index = 1;
  96. builder.serout_index = 0;
  97. builder.clk_index = 3;
  98. break;
  99. default:
  100. num = NUM_PINS;
  101. break;
  102. }
  103. select_pins_set(pokemon_fap);
  104. variable_item_list_reset(pokemon_fap->variable_item_list);
  105. builder.named = variable_item_list_add(
  106. pokemon_fap->variable_item_list, "Mode", 3, select_named_group_callback, pokemon_fap);
  107. builder.serin = variable_item_list_add(
  108. pokemon_fap->variable_item_list, "SI:", num, select_pins_serin_callback, pokemon_fap);
  109. builder.serout = variable_item_list_add(
  110. pokemon_fap->variable_item_list, "SO:", num, select_pins_serout_callback, pokemon_fap);
  111. builder.clk = variable_item_list_add(
  112. pokemon_fap->variable_item_list, "CLK:", num, select_pins_clk_callback, pokemon_fap);
  113. variable_item_set_current_value_index(builder.named, builder.named_index);
  114. variable_item_set_current_value_text(builder.named, named_groups[builder.named_index]);
  115. variable_item_set_current_value_index(builder.serin, (num == 1 ? 0 : builder.serin_index));
  116. variable_item_set_current_value_text(builder.serin, named_pins[builder.serin_index]->name);
  117. variable_item_set_current_value_index(builder.serout, (num == 1 ? 0 : builder.serout_index));
  118. variable_item_set_current_value_text(builder.serout, named_pins[builder.serout_index]->name);
  119. variable_item_set_current_value_index(builder.clk, (num == 1 ? 0 : builder.clk_index));
  120. variable_item_set_current_value_text(builder.clk, named_pins[builder.clk_index]->name);
  121. }
  122. void pokemon_scene_select_pins_on_enter(void* context) {
  123. PokemonFap* pokemon_fap = (PokemonFap*)context;
  124. select_pins_rebuild_list(pokemon_fap);
  125. view_dispatcher_switch_to_view(pokemon_fap->view_dispatcher, AppViewVariableItem);
  126. }
  127. bool pokemon_scene_select_pins_on_event(void* context, SceneManagerEvent event) {
  128. UNUSED(context);
  129. UNUSED(event);
  130. return false;
  131. }
  132. void pokemon_scene_select_pins_on_exit(void* context) {
  133. UNUSED(context);
  134. }