Skip to content

Commit

Permalink
scenes: pokemon_pins: Initial commit
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
kbembedded committed Dec 17, 2023
1 parent 3759704 commit a9f399b
Show file tree
Hide file tree
Showing 4 changed files with 189 additions and 0 deletions.
10 changes: 10 additions & 0 deletions scenes/pokemon_menu.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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,
Expand Down Expand Up @@ -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*) = {
Expand All @@ -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) = {
Expand All @@ -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 = {
Expand Down
1 change: 1 addition & 0 deletions scenes/pokemon_menu.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ typedef enum {
SelectOTIDScene,
SelectOTNameScene,
TradeScene,
SelectPinsScene,
SceneCount,
} AppScene;

Expand Down
169 changes: 169 additions & 0 deletions scenes/pokemon_pins.c
Original file line number Diff line number Diff line change
@@ -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 changes: 9 additions & 0 deletions scenes/pokemon_pins.h
Original file line number Diff line number Diff line change
@@ -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

0 comments on commit a9f399b

Please sign in to comment.