Explorar o código

gblink: bump to v0.63, implement new pinconf handling

Cleans up some of the initialization process to be less messy

Signed-off-by: Kris Bahnsen <Kris@KBEmbedded.com>
Kris Bahnsen hai 1 ano
pai
achega
6a8475140f

+ 2 - 0
application.fam

@@ -16,6 +16,8 @@ App(
     fap_private_libs=[
         Lib(
             name="flipper-gblink",
+            fap_include_paths=["gblink/include", "./"],
+            sources=["gblink/*.c"],
         ),
     ],
 )

+ 1 - 1
lib/flipper-gblink

@@ -1 +1 @@
-Subproject commit 93931d71fffd0476a591dc18d3263a02e93a169a
+Subproject commit ecce5b6363adb067cef424eab09fead2f038baf5

+ 2 - 2
src/include/pokemon_app.h

@@ -35,8 +35,8 @@ struct pokemon_fap {
      */
     PokemonData* pdata;
 
-    /* Pin definition to actual Game Link Cable interface */
-    struct gblink_pins pins;
+    /* gblink interface */
+    void *gblink_handle;
 };
 
 typedef struct pokemon_fap PokemonFap;

+ 13 - 4
src/pokemon_app.c

@@ -4,11 +4,13 @@
 #include <src/include/pokemon_app.h>
 #include <src/include/pokemon_data.h>
 #include <src/views/trade.h>
-#include <src/views/select_pokemon.h>
 #include <src/include/pokemon_char_encode.h>
 
 #include <src/scenes/include/pokemon_scene.h>
 
+#include <gblink/include/gblink_pinconf.h>
+#include <gblink.h>
+
 bool pokemon_custom_event_callback(void* context, uint32_t event) {
     furi_assert(context);
     PokemonFap* pokemon_fap = context;
@@ -40,9 +42,6 @@ PokemonFap* pokemon_alloc() {
         (Gui*)furi_record_open(RECORD_GUI),
         ViewDispatcherTypeFullscreen);
 
-    // Set up pinout defaults
-    memcpy(&pokemon_fap->pins, &common_pinouts[PINOUT_ORIGINAL], sizeof(struct gblink_pins));
-
     // Text input
     pokemon_fap->text_input = text_input_alloc();
     view_dispatcher_add_view(
@@ -67,22 +66,32 @@ PokemonFap* pokemon_alloc() {
     pokemon_fap->scene_manager = scene_manager_alloc(&pokemon_scene_handlers, pokemon_fap);
     scene_manager_next_scene(pokemon_fap->scene_manager, PokemonSceneMainMenu);
 
+    // Allocate gblink before going to main menu
+    pokemon_fap->gblink_handle = gblink_alloc();
+    gblink_pinconf_load(pokemon_fap->gblink_handle);
+
     return pokemon_fap;
 }
 
 void free_app(PokemonFap* pokemon_fap) {
     furi_assert(pokemon_fap);
 
+    // gblink
+    gblink_free(pokemon_fap->gblink_handle);
+
     // Submenu
     submenu_free(pokemon_fap->submenu);
     view_dispatcher_remove_view(pokemon_fap->view_dispatcher, AppViewSubmenu);
 
+    // text input
     text_input_free(pokemon_fap->text_input);
     view_dispatcher_remove_view(pokemon_fap->view_dispatcher, AppViewTextInput);
 
+    // Vairable item list
     variable_item_list_free(pokemon_fap->variable_item_list);
     view_dispatcher_remove_view(pokemon_fap->view_dispatcher, AppViewVariableItem);
 
+    // Dialog ex
     dialog_ex_free(pokemon_fap->dialog_ex);
     view_dispatcher_remove_view(pokemon_fap->view_dispatcher, AppViewDialogEx);
 

+ 1 - 1
src/scenes/pokemon_gen.c

@@ -63,7 +63,7 @@ void pokemon_scene_gen_on_enter(void* context) {
         // Trade View
         /* Allocates its own view and adds it to the main view_dispatcher */
         pokemon_fap->trade = trade_alloc(
-            pdata, &pokemon_fap->pins, pokemon_fap->view_dispatcher, AppViewTrade);
+            pdata, pokemon_fap->gblink_handle, pokemon_fap->view_dispatcher, AppViewTrade);
     }
 
     pkmn_num = pokemon_stat_get(pdata, STAT_NUM, NONE);

+ 58 - 111
src/scenes/pokemon_pins.c

@@ -5,25 +5,8 @@
 
 #include <src/scenes/include/pokemon_scene.h>
 
-/* This is a bit of a hack to save some space and not have to refactor this scene.
- * We re-use the name and pin from the global gpio pin definition, but need to
- * skip the two debug pins in the row of header pins.
- *
- * This is hard-coded, not really portable, but saves a couple hundred bytes :D
- *
- * In the future, the right way to do this would be to build our own table of
- * non-debug pins from whatever the current platforms gpio pin definition is.
- */
-#define NUM_PINS 8
-static const GpioPinRecord* named_pins[NUM_PINS] = {
-    &gpio_pins[0],
-    &gpio_pins[1],
-    &gpio_pins[2],
-    &gpio_pins[3],
-    &gpio_pins[4],
-    &gpio_pins[5],
-    &gpio_pins[10],
-    &gpio_pins[11]};
+#include <gblink/include/gblink_pinconf.h>
+#include <gblink/include/gblink.h>
 
 /* This must match gblink's enum order */
 static const char* named_groups[] = {
@@ -33,121 +16,83 @@ static const char* named_groups[] = {
     "",
 };
 
-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_pins_rebuild_list(PokemonFap* pokemon_fap, int mode);
 
-static void select_named_group_callback(VariableItem* item) {
+static void select_pins_default_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]->name);
-    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]->name);
-    builder.serout_index = index;
-    select_pins_rebuild_list(pokemon_fap);
-    variable_item_list_set_selected_item(pokemon_fap->variable_item_list, 2);
+    gblink_pin_set_default(pokemon_fap->gblink_handle, index);
+    select_pins_rebuild_list(pokemon_fap, index);
 }
 
-static void select_pins_clk_callback(VariableItem* item) {
+static void select_pins_pin_callback(VariableItem* item) {
     uint8_t index = variable_item_get_current_value_index(item);
     PokemonFap* pokemon_fap = variable_item_get_context(item);
+    uint8_t which = variable_item_list_get_selected_item_index(pokemon_fap->variable_item_list);
+    gblink_bus_pins pin;
 
-    variable_item_set_current_value_text(item, named_pins[index]->name);
-    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;
+    switch (which) {
+    case 1: // SI
+        pin = PIN_SERIN;
+        break;
+    case 2: // SO
+        pin = PIN_SEROUT;
         break;
-    case 1: // MALVEKE
-        num = 1;
-        builder.serin_index = 1;
-        builder.serout_index = 0;
-        builder.clk_index = 3;
+    case 3: // CLK
+        pin = PIN_CLK;
         break;
     default:
-        num = NUM_PINS;
+        furi_crash();
         break;
     }
 
-    select_pins_set(pokemon_fap);
+    if (index > gblink_pin_get(pokemon_fap->gblink_handle, pin))
+        index = gblink_pin_get_next(index);
+    else
+        index = gblink_pin_get_prev(index);
+    variable_item_set_current_value_index(item, index);
+    variable_item_set_current_value_text(item, gpio_pins[index].name);
+    gblink_pin_set(pokemon_fap->gblink_handle, pin, index);
+}
 
+static void select_pins_rebuild_list(PokemonFap* pokemon_fap, int mode) {
+    int pinnum;
+    int pinmax = gblink_pin_count_max() + 1;
+    VariableItem *item;
+    
     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]->name);
-
-    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]->name);
-
-    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]->name);
+    item = variable_item_list_add(
+        pokemon_fap->variable_item_list, "Mode", PINOUT_COUNT+1, select_pins_default_callback, pokemon_fap);
+    variable_item_set_current_value_index(item, mode);
+    variable_item_set_current_value_text(item, named_groups[mode]);
+
+    item = variable_item_list_add(
+        pokemon_fap->variable_item_list, "SI:", (mode < PINOUT_COUNT) ? 1 : pinmax, select_pins_pin_callback, pokemon_fap);
+    pinnum = gblink_pin_get(pokemon_fap->gblink_handle, PIN_SERIN);
+    variable_item_set_current_value_index(item, (mode < PINOUT_COUNT) ? 0 : pinnum);
+    variable_item_set_current_value_text(item, gpio_pins[pinnum].name);
+
+    item = variable_item_list_add(
+        pokemon_fap->variable_item_list, "SO:", (mode < PINOUT_COUNT) ? 1 : pinmax, select_pins_pin_callback, pokemon_fap);
+    pinnum = gblink_pin_get(pokemon_fap->gblink_handle, PIN_SEROUT);
+    variable_item_set_current_value_index(item, (mode < PINOUT_COUNT) ? 0 : pinnum);
+    variable_item_set_current_value_text(item, gpio_pins[pinnum].name);
+
+    item = variable_item_list_add(
+        pokemon_fap->variable_item_list, "CLK:", (mode < PINOUT_COUNT) ? 1 : pinmax, select_pins_pin_callback, pokemon_fap);
+    pinnum = gblink_pin_get(pokemon_fap->gblink_handle, PIN_CLK);
+    variable_item_set_current_value_index(item, (mode < PINOUT_COUNT) ? 0 : pinnum);
+    variable_item_set_current_value_text(item, gpio_pins[pinnum].name);
 }
 
 void pokemon_scene_select_pins_on_enter(void* context) {
     PokemonFap* pokemon_fap = (PokemonFap*)context;
+    int def_mode = gblink_pin_get_default(pokemon_fap->gblink_handle);
 
-    select_pins_rebuild_list(pokemon_fap);
+    select_pins_rebuild_list(pokemon_fap, (def_mode < 0) ? PINOUT_COUNT : def_mode);
 
     view_dispatcher_switch_to_view(pokemon_fap->view_dispatcher, AppViewVariableItem);
 }
@@ -159,5 +104,7 @@ bool pokemon_scene_select_pins_on_event(void* context, SceneManagerEvent event)
 }
 
 void pokemon_scene_select_pins_on_exit(void* context) {
-    UNUSED(context);
+    PokemonFap* pokemon_fap = context;
+
+    gblink_pinconf_save(pokemon_fap->gblink_handle);
 }

+ 7 - 11
src/views/trade.c

@@ -221,7 +221,6 @@ struct trade_ctx {
     PokemonData* input_pdata;
     struct patch_list* patch_list;
     void* gblink_handle;
-    struct gblink_pins* gblink_pins;
     PokemonData* pdata;
     NotificationApp* notifications;
 };
@@ -861,7 +860,6 @@ void trade_enter_callback(void* context) {
     furi_assert(context);
     struct trade_ctx* trade = (struct trade_ctx*)context;
     struct trade_model* model;
-    struct gblink_def gblink_def = {0};
 
     model = view_get_model(trade->view);
 
@@ -876,13 +874,11 @@ void trade_enter_callback(void* context) {
 
     view_commit_model(trade->view, true);
 
-    gblink_def.pins = trade->gblink_pins;
-    gblink_def.callback = transferBit;
-    gblink_def.cb_context = trade;
-
-    trade->gblink_handle = gblink_alloc(&gblink_def);
+    gblink_callback_set(trade->gblink_handle, transferBit, trade);
     gblink_nobyte_set(trade->gblink_handle, SERIAL_NO_DATA_BYTE);
 
+    gblink_start(trade->gblink_handle);
+
     /* Every 250 ms, trigger a draw update. 250 ms was chosen so that during
      * the trade process, each update can flip the LED and screen to make the
      * trade animation.
@@ -912,8 +908,8 @@ void trade_exit_callback(void* context) {
     furi_timer_free(trade->draw_timer);
     trade->draw_timer = NULL;
 
-    /* Unset the pin settings */
-    gblink_free(trade->gblink_handle);
+    /* Stop the game boy link */
+    gblink_stop(trade->gblink_handle);
 
     /* Destroy the patch list, it is allocated on the enter callback */
     plist_free(trade->patch_list);
@@ -922,7 +918,7 @@ void trade_exit_callback(void* context) {
 
 void* trade_alloc(
     PokemonData* pdata,
-    struct gblink_pins* gblink_pins,
+    void *gblink_handle,
     ViewDispatcher* view_dispatcher,
     uint32_t view_id) {
     furi_assert(pdata);
@@ -934,8 +930,8 @@ void* trade_alloc(
     trade->pdata = pdata;
     trade->input_pdata = pokemon_data_alloc(pdata->gen);
     trade->patch_list = NULL;
-    trade->gblink_pins = gblink_pins;
     trade->notifications = furi_record_open(RECORD_NOTIFICATION);
+    trade->gblink_handle = gblink_handle;
 
     view_set_context(trade->view, trade);
     view_allocate_model(trade->view, ViewModelTypeLockFree, sizeof(struct trade_model));

+ 1 - 1
src/views/trade.h

@@ -8,7 +8,7 @@
 
 void* trade_alloc(
     PokemonData* pdata,
-    struct gblink_pins* gblink_pins,
+    void *gblink_handle,
     ViewDispatcher* view_dispatcher,
     uint32_t view_id);