Просмотр исходного кода

scenes: pokemon_pins: Initial commit

Ability to select the pinout used to communicate over the link cable.

Be aware this contains a few points of really hacky and sloppy code
simply because I wanted to get this pushed out ASAP for supporting
the MALVEKE board.
Kris Bahnsen 2 лет назад
Родитель
Сommit
a9f399b3f1
4 измененных файлов с 189 добавлено и 0 удалено
  1. 10 0
      scenes/pokemon_menu.c
  2. 1 0
      scenes/pokemon_menu.h
  3. 169 0
      scenes/pokemon_pins.c
  4. 9 0
      scenes/pokemon_pins.h

+ 10 - 0
scenes/pokemon_menu.c

@@ -11,6 +11,7 @@
 #include "pokemon_ot_id.h"
 #include "pokemon_ot_name.h"
 #include "pokemon_trade.h"
+#include "pokemon_pins.h"
 
 static void scene_change_from_main_cb(void* context, uint32_t index) {
     PokemonFap* pokemon_fap = (PokemonFap*)context;
@@ -95,6 +96,12 @@ void main_menu_scene_on_enter(void* context) {
         pokemon_fap->submenu, buf, SelectOTNameScene, scene_change_from_main_cb, pokemon_fap);
     submenu_add_item(
         pokemon_fap->submenu, "Trade PKMN", TradeScene, scene_change_from_main_cb, pokemon_fap);
+    submenu_add_item(
+        pokemon_fap->submenu,
+        "Select Pinout",
+        SelectPinsScene,
+        scene_change_from_main_cb,
+        pokemon_fap);
 
     submenu_set_selected_item(
         pokemon_fap->submenu,
@@ -128,6 +135,7 @@ void (*const pokemon_scene_on_enter_handlers[])(void*) = {
     select_ot_id_scene_on_enter,
     select_ot_name_scene_on_enter,
     trade_scene_on_enter,
+    select_pins_scene_on_enter,
 };
 
 void (*const pokemon_scene_on_exit_handlers[])(void*) = {
@@ -143,6 +151,7 @@ void (*const pokemon_scene_on_exit_handlers[])(void*) = {
     select_ot_id_scene_on_exit,
     select_ot_name_scene_on_exit,
     null_scene_on_exit,
+    select_pins_scene_on_exit,
 };
 
 bool (*const pokemon_scene_on_event_handlers[])(void*, SceneManagerEvent) = {
@@ -158,6 +167,7 @@ bool (*const pokemon_scene_on_event_handlers[])(void*, SceneManagerEvent) = {
     null_scene_on_event,
     null_scene_on_event,
     null_scene_on_event,
+    null_scene_on_event,
 };
 
 const SceneManagerHandlers pokemon_scene_manager_handlers = {

+ 1 - 0
scenes/pokemon_menu.h

@@ -18,6 +18,7 @@ typedef enum {
     SelectOTIDScene,
     SelectOTNameScene,
     TradeScene,
+    SelectPinsScene,
     SceneCount,
 } AppScene;
 

+ 169 - 0
scenes/pokemon_pins.c

@@ -0,0 +1,169 @@
+#include <gui/modules/variable_item_list.h>
+#include <furi.h>
+
+#include "../pokemon_app.h"
+#include "pokemon_menu.h"
+
+struct named_pins {
+    const char* text;
+    const GpioPin* pin;
+};
+
+static const struct named_pins named_pins[] = {
+    {"PA7", &gpio_ext_pa7},
+    {"PA6", &gpio_ext_pa6},
+    {"PA4", &gpio_ext_pa4},
+    {"PB3", &gpio_ext_pb3},
+    {"PB2", &gpio_ext_pb2},
+    {"PC3", &gpio_ext_pc3},
+    {"PC1", &gpio_ext_pc1},
+    {"PC0", &gpio_ext_pc0},
+    {},
+};
+
+#define NUM_PINS 8
+
+/* This must match gblink's enum order */
+static const char* named_groups[] = {
+    "Original",
+    "Malveke",
+    "Custom",
+    "",
+};
+
+struct itemlist_builder {
+    VariableItem* named;
+    VariableItem* serin;
+    VariableItem* serout;
+    VariableItem* clk;
+    uint8_t named_index;
+    uint8_t serin_index;
+    uint8_t serout_index;
+    uint8_t clk_index;
+};
+
+/* Just make it a global, whatever */
+static struct itemlist_builder builder = {0};
+static void select_pins_rebuild_list(PokemonFap* pokemon_fap);
+
+static void select_pins_set(PokemonFap* pokemon_fap) {
+    pokemon_fap->pins.serin = named_pins[builder.serin_index].pin;
+    pokemon_fap->pins.serout = named_pins[builder.serout_index].pin;
+    pokemon_fap->pins.clk = named_pins[builder.clk_index].pin;
+}
+
+static void select_named_group_callback(VariableItem* item) {
+    uint8_t index = variable_item_get_current_value_index(item);
+    PokemonFap* pokemon_fap = variable_item_get_context(item);
+
+    variable_item_set_current_value_text(item, named_groups[index]);
+    builder.named_index = index;
+    select_pins_rebuild_list(pokemon_fap);
+    variable_item_list_set_selected_item(pokemon_fap->variable_item_list, 0);
+}
+
+static void select_pins_serin_callback(VariableItem* item) {
+    uint8_t index = variable_item_get_current_value_index(item);
+    PokemonFap* pokemon_fap = variable_item_get_context(item);
+
+    variable_item_set_current_value_text(item, named_pins[index].text);
+    builder.serin_index = index;
+    select_pins_rebuild_list(pokemon_fap);
+    variable_item_list_set_selected_item(pokemon_fap->variable_item_list, 1);
+}
+
+static void select_pins_serout_callback(VariableItem* item) {
+    uint8_t index = variable_item_get_current_value_index(item);
+    PokemonFap* pokemon_fap = variable_item_get_context(item);
+
+    variable_item_set_current_value_text(item, named_pins[index].text);
+    builder.serout_index = index;
+    select_pins_rebuild_list(pokemon_fap);
+    variable_item_list_set_selected_item(pokemon_fap->variable_item_list, 2);
+}
+
+static void select_pins_clk_callback(VariableItem* item) {
+    uint8_t index = variable_item_get_current_value_index(item);
+    PokemonFap* pokemon_fap = variable_item_get_context(item);
+
+    variable_item_set_current_value_text(item, named_pins[index].text);
+    builder.clk_index = index;
+    select_pins_rebuild_list(pokemon_fap);
+    variable_item_list_set_selected_item(pokemon_fap->variable_item_list, 3);
+}
+
+static void select_pins_rebuild_list(PokemonFap* pokemon_fap) {
+    int num;
+
+    /* HACK: TODO: It would be better to do this programmatically, but, I'm kind
+     * of done working on this feature so its going to be hardcoded for now.
+     */
+    switch(builder.named_index) {
+    case 0: // Original
+        num = 1;
+        builder.serin_index = 5;
+        builder.serout_index = 3;
+        builder.clk_index = 4;
+        break;
+    case 1: // MALVEKE
+        num = 1;
+        builder.serin_index = 1;
+        builder.serout_index = 0;
+        builder.clk_index = 3;
+        break;
+    default:
+        num = NUM_PINS;
+        break;
+    }
+
+    /* HACK: */
+    pokemon_fap->malveke_detected = builder.named_index;
+
+    select_pins_set(pokemon_fap);
+
+    variable_item_list_reset(pokemon_fap->variable_item_list);
+
+    builder.named = variable_item_list_add(
+        pokemon_fap->variable_item_list, "Mode", 3, select_named_group_callback, pokemon_fap);
+    builder.serin = variable_item_list_add(
+        pokemon_fap->variable_item_list, "SI:", num, select_pins_serin_callback, pokemon_fap);
+    builder.serout = variable_item_list_add(
+        pokemon_fap->variable_item_list, "SO:", num, select_pins_serout_callback, pokemon_fap);
+    builder.clk = variable_item_list_add(
+        pokemon_fap->variable_item_list, "CLK:", num, select_pins_clk_callback, pokemon_fap);
+
+    variable_item_set_current_value_index(builder.named, builder.named_index);
+    variable_item_set_current_value_text(builder.named, named_groups[builder.named_index]);
+
+    variable_item_set_current_value_index(builder.serin, (num == 1 ? 0 : builder.serin_index));
+    variable_item_set_current_value_text(builder.serin, named_pins[builder.serin_index].text);
+
+    variable_item_set_current_value_index(builder.serout, (num == 1 ? 0 : builder.serout_index));
+    variable_item_set_current_value_text(builder.serout, named_pins[builder.serout_index].text);
+
+    variable_item_set_current_value_index(builder.clk, (num == 1 ? 0 : builder.clk_index));
+    variable_item_set_current_value_text(builder.clk, named_pins[builder.clk_index].text);
+}
+
+void select_pins_scene_on_exit(void* context) {
+    PokemonFap* pokemon_fap = (PokemonFap*)context;
+
+    view_dispatcher_switch_to_view(pokemon_fap->view_dispatcher, AppViewMainMenu);
+    view_dispatcher_remove_view(pokemon_fap->view_dispatcher, AppViewOpts);
+}
+
+void select_pins_scene_on_enter(void* context) {
+    PokemonFap* pokemon_fap = (PokemonFap*)context;
+
+    /* TODO: Figure out what defaults we should use for pins based on attached board! */
+    /* HACK: */
+    if(builder.named_index < 2) builder.named_index = pokemon_fap->malveke_detected;
+
+    select_pins_rebuild_list(pokemon_fap);
+
+    view_dispatcher_add_view(
+        pokemon_fap->view_dispatcher,
+        AppViewOpts,
+        variable_item_list_get_view(pokemon_fap->variable_item_list));
+    view_dispatcher_switch_to_view(pokemon_fap->view_dispatcher, AppViewOpts);
+}

+ 9 - 0
scenes/pokemon_pins.h

@@ -0,0 +1,9 @@
+#ifndef POKEMON_PINS_H
+#define POKEMON_PINS_H
+
+#pragma once
+
+void select_pins_scene_on_enter(void* context);
+void select_pins_scene_on_exit(void* context);
+
+#endif // POKEMON_PINS_H