|
@@ -8,7 +8,11 @@ enum VarItemListIndex {
|
|
|
VarItemListIndexPinInput,
|
|
VarItemListIndexPinInput,
|
|
|
VarItemListIndexPinOutput,
|
|
VarItemListIndexPinOutput,
|
|
|
VarItemListIndexPinEnable,
|
|
VarItemListIndexPinEnable,
|
|
|
|
|
+ VarItemListIndexNRepeats,
|
|
|
|
|
+ VarItemListIndexRepeatModeOn,
|
|
|
|
|
+#ifndef FW_ORIGIN_Official
|
|
|
VarItemListIndexAllowUART,
|
|
VarItemListIndexAllowUART,
|
|
|
|
|
+#endif
|
|
|
};
|
|
};
|
|
|
|
|
|
|
|
static const char* gpio[] = {
|
|
static const char* gpio[] = {
|
|
@@ -25,6 +29,40 @@ const uint8_t GPIO_COUNT = COUNT_OF(gpio);
|
|
|
// static const char* uart_pins[] = {[DapUartTypeUSART1] = "13,14", [DapUartTypeLPUART1] = "15,16"};
|
|
// static const char* uart_pins[] = {[DapUartTypeUSART1] = "13,14", [DapUartTypeLPUART1] = "15,16"};
|
|
|
// static const char* uart_swap[] = {[DapUartTXRXNormal] = "No", [DapUartTXRXSwap] = "Yes"};
|
|
// static const char* uart_swap[] = {[DapUartTXRXNormal] = "No", [DapUartTXRXSwap] = "Yes"};
|
|
|
|
|
|
|
|
|
|
+#define N_REPEATS_COUNT 10
|
|
|
|
|
+const char* const n_repeats_text[N_REPEATS_COUNT] = {
|
|
|
|
|
+ "2",
|
|
|
|
|
+ "3",
|
|
|
|
|
+ "4",
|
|
|
|
|
+ "5",
|
|
|
|
|
+ "6",
|
|
|
|
|
+ "7",
|
|
|
|
|
+ "8",
|
|
|
|
|
+ "9",
|
|
|
|
|
+ "10",
|
|
|
|
|
+ "20",
|
|
|
|
|
+};
|
|
|
|
|
+const uint32_t n_repeats_value[N_REPEATS_COUNT] = {
|
|
|
|
|
+ 2,
|
|
|
|
|
+ 3,
|
|
|
|
|
+ 4,
|
|
|
|
|
+ 5,
|
|
|
|
|
+ 6,
|
|
|
|
|
+ 7,
|
|
|
|
|
+ 8,
|
|
|
|
|
+ 9,
|
|
|
|
|
+ 10,
|
|
|
|
|
+ 20,
|
|
|
|
|
+};
|
|
|
|
|
+
|
|
|
|
|
+#define OFF_ON_COUNT 2
|
|
|
|
|
+const char* const off_on_text[OFF_ON_COUNT] = {
|
|
|
|
|
+ "OFF",
|
|
|
|
|
+ "ON",
|
|
|
|
|
+};
|
|
|
|
|
+
|
|
|
|
|
+VariableItem* item_dialog_cb;
|
|
|
|
|
+
|
|
|
void mag_scene_settings_var_item_list_callback(void* context, uint32_t index) {
|
|
void mag_scene_settings_var_item_list_callback(void* context, uint32_t index) {
|
|
|
Mag* mag = context;
|
|
Mag* mag = context;
|
|
|
view_dispatcher_send_custom_event(mag->view_dispatcher, index);
|
|
view_dispatcher_send_custom_event(mag->view_dispatcher, index);
|
|
@@ -51,6 +89,39 @@ static void mag_scene_settings_set_gpio_enable(VariableItem* item) {
|
|
|
mag_scene_settings_set_gpio(item, &mag->state.pin_enable);
|
|
mag_scene_settings_set_gpio(item, &mag->state.pin_enable);
|
|
|
};
|
|
};
|
|
|
|
|
|
|
|
|
|
+static void mag_scene_settings_set_n_repeats(VariableItem* item) {
|
|
|
|
|
+ Mag* mag = variable_item_get_context(item);
|
|
|
|
|
+ uint8_t index = variable_item_get_current_value_index(item);
|
|
|
|
|
+ variable_item_set_current_value_text(item, n_repeats_text[index]);
|
|
|
|
|
+ mag->state.n_repeats = n_repeats_value[index];
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+static void mag_scene_settings_set_bool(VariableItem* item, bool* bool_out) {
|
|
|
|
|
+ uint8_t index = variable_item_get_current_value_index(item);
|
|
|
|
|
+ variable_item_set_current_value_text(item, off_on_text[index]);
|
|
|
|
|
+ *bool_out = (bool)index;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+static void mag_scene_settings_set_repeat_mode(VariableItem* item) {
|
|
|
|
|
+ Mag* mag = variable_item_get_context(item);
|
|
|
|
|
+ mag_scene_settings_set_bool(item, &mag->state.repeat_mode);
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+static void mag_scene_settings_set_allow_uart(VariableItem* item) {
|
|
|
|
|
+ Mag* mag = variable_item_get_context(item);
|
|
|
|
|
+
|
|
|
|
|
+ // rising change when value index is truth-y, and prior value false
|
|
|
|
|
+ bool rising = !mag->state.allow_uart && !!variable_item_get_current_value_index(item);
|
|
|
|
|
+ // trigger dialog only on rising change
|
|
|
|
|
+ if(rising) {
|
|
|
|
|
+ item_dialog_cb = item;
|
|
|
|
|
+ view_dispatcher_send_custom_event(mag->view_dispatcher, MagEventConfirmDialog);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // set value & text based on current varitem index
|
|
|
|
|
+ mag_scene_settings_set_bool(item, &mag->state.allow_uart);
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
static void mag_pin_variable_item_list_add(
|
|
static void mag_pin_variable_item_list_add(
|
|
|
Mag* mag,
|
|
Mag* mag,
|
|
|
const char* label,
|
|
const char* label,
|
|
@@ -62,10 +133,30 @@ static void mag_pin_variable_item_list_add(
|
|
|
variable_item_set_current_value_text(item, gpio[pin]);
|
|
variable_item_set_current_value_text(item, gpio[pin]);
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+static void mag_bool_variable_item_list_add(
|
|
|
|
|
+ Mag* mag,
|
|
|
|
|
+ const char* label,
|
|
|
|
|
+ bool value,
|
|
|
|
|
+ VariableItemChangeCallback change_callback) {
|
|
|
|
|
+ VariableItem* item =
|
|
|
|
|
+ variable_item_list_add(mag->variable_item_list, label, OFF_ON_COUNT, change_callback, mag);
|
|
|
|
|
+ uint32_t value_index = (uint32_t)value;
|
|
|
|
|
+ variable_item_set_current_value_index(item, value_index);
|
|
|
|
|
+ variable_item_set_current_value_text(item, off_on_text[value_index]);
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
void mag_scene_settings_on_enter(void* context) {
|
|
void mag_scene_settings_on_enter(void* context) {
|
|
|
Mag* mag = context;
|
|
Mag* mag = context;
|
|
|
- VariableItem* item;
|
|
|
|
|
VariableItemList* var_item_list = mag->variable_item_list;
|
|
VariableItemList* var_item_list = mag->variable_item_list;
|
|
|
|
|
+ VariableItem* item;
|
|
|
|
|
+ uint32_t value_index;
|
|
|
|
|
+
|
|
|
|
|
+ // reload state in the event temporary changes have been
|
|
|
|
|
+ // made on the emulate config screen
|
|
|
|
|
+ // only changes made in this scene should be saved, and this scene
|
|
|
|
|
+ // should always represent the saved settings, not the transient ones for
|
|
|
|
|
+ // a given emulation.
|
|
|
|
|
+ mag_state_load(&mag->state);
|
|
|
|
|
|
|
|
mag_pin_variable_item_list_add(
|
|
mag_pin_variable_item_list_add(
|
|
|
mag, "Input pin:", mag->state.pin_input, mag_scene_settings_set_gpio_input);
|
|
mag, "Input pin:", mag->state.pin_input, mag_scene_settings_set_gpio_input);
|
|
@@ -74,8 +165,17 @@ void mag_scene_settings_on_enter(void* context) {
|
|
|
mag_pin_variable_item_list_add(
|
|
mag_pin_variable_item_list_add(
|
|
|
mag, "Enable pin:", mag->state.pin_enable, mag_scene_settings_set_gpio_enable);
|
|
mag, "Enable pin:", mag->state.pin_enable, mag_scene_settings_set_gpio_enable);
|
|
|
|
|
|
|
|
- item = variable_item_list_add(var_item_list, "UART MSR: ", 1, NULL, mag);
|
|
|
|
|
- variable_item_set_current_value_text(item, mag->state.allow_uart ? "ON" : "OFF");
|
|
|
|
|
|
|
+ mag_bool_variable_item_list_add(
|
|
|
|
|
+ mag, "Repeat default:", mag->state.repeat_mode, mag_scene_settings_set_repeat_mode);
|
|
|
|
|
+
|
|
|
|
|
+ item = variable_item_list_add(
|
|
|
|
|
+ var_item_list, "# repeats: ", N_REPEATS_COUNT, mag_scene_settings_set_n_repeats, mag);
|
|
|
|
|
+ value_index = value_index_uint32(mag->state.n_repeats, n_repeats_value, N_REPEATS_COUNT);
|
|
|
|
|
+ variable_item_set_current_value_index(item, value_index);
|
|
|
|
|
+ variable_item_set_current_value_text(item, n_repeats_text[value_index]);
|
|
|
|
|
+
|
|
|
|
|
+ mag_bool_variable_item_list_add(
|
|
|
|
|
+ mag, "UART MSR:", mag->state.allow_uart, mag_scene_settings_set_allow_uart);
|
|
|
|
|
|
|
|
variable_item_list_set_enter_callback(
|
|
variable_item_list_set_enter_callback(
|
|
|
var_item_list, mag_scene_settings_var_item_list_callback, mag);
|
|
var_item_list, mag_scene_settings_var_item_list_callback, mag);
|
|
@@ -109,34 +209,6 @@ void mag_scene_settings_dialog_invalid_pins(Mag* mag) {
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
-void mag_scene_settings_dialog_allow_uart(Mag* mag) {
|
|
|
|
|
- bool change = mag->state.allow_uart;
|
|
|
|
|
- if(!change) {
|
|
|
|
|
- DialogMessage* msg = dialog_message_alloc();
|
|
|
|
|
- dialog_message_set_header(msg, "UART MSR", 64, 0, AlignCenter, AlignTop);
|
|
|
|
|
- dialog_message_set_buttons(msg, "No", NULL, "Yes");
|
|
|
|
|
- dialog_message_set_text(
|
|
|
|
|
- msg,
|
|
|
|
|
- "This option requires a\nUART-compatible mag reader.\nIs it installed?\n",
|
|
|
|
|
- 64,
|
|
|
|
|
- 32,
|
|
|
|
|
- AlignCenter,
|
|
|
|
|
- AlignCenter);
|
|
|
|
|
- DialogMessageButton res = dialog_message_show(furi_record_open(RECORD_DIALOGS), msg);
|
|
|
|
|
- if(res == DialogMessageButtonRight) {
|
|
|
|
|
- change = true;
|
|
|
|
|
- }
|
|
|
|
|
- dialog_message_free(msg);
|
|
|
|
|
- furi_record_close(RECORD_DIALOGS);
|
|
|
|
|
- }
|
|
|
|
|
- if(change) {
|
|
|
|
|
- mag->state.allow_uart = !mag->state.allow_uart;
|
|
|
|
|
- variable_item_set_current_value_text(
|
|
|
|
|
- variable_item_list_get(mag->variable_item_list, VarItemListIndexAllowUART),
|
|
|
|
|
- mag->state.allow_uart ? "ON" : "OFF");
|
|
|
|
|
- }
|
|
|
|
|
-}
|
|
|
|
|
-
|
|
|
|
|
bool mag_scene_settings_on_event(void* context, SceneManagerEvent event) {
|
|
bool mag_scene_settings_on_event(void* context, SceneManagerEvent event) {
|
|
|
Mag* mag = context;
|
|
Mag* mag = context;
|
|
|
SceneManager* scene_manager = mag->scene_manager;
|
|
SceneManager* scene_manager = mag->scene_manager;
|
|
@@ -153,12 +225,31 @@ bool mag_scene_settings_on_event(void* context, SceneManagerEvent event) {
|
|
|
} else {
|
|
} else {
|
|
|
scene_manager_previous_scene(scene_manager);
|
|
scene_manager_previous_scene(scene_manager);
|
|
|
}
|
|
}
|
|
|
|
|
+
|
|
|
break;
|
|
break;
|
|
|
case SceneManagerEventTypeCustom:
|
|
case SceneManagerEventTypeCustom:
|
|
|
scene_manager_set_scene_state(mag->scene_manager, MagSceneSettings, event.event);
|
|
scene_manager_set_scene_state(mag->scene_manager, MagSceneSettings, event.event);
|
|
|
consumed = true;
|
|
consumed = true;
|
|
|
- if(event.event == VarItemListIndexAllowUART) {
|
|
|
|
|
- mag_scene_settings_dialog_allow_uart(mag);
|
|
|
|
|
|
|
+ if(event.event == MagEventConfirmDialog) {
|
|
|
|
|
+ DialogMessage* msg = dialog_message_alloc();
|
|
|
|
|
+ dialog_message_set_header(msg, "UART MSR", 64, 0, AlignCenter, AlignTop);
|
|
|
|
|
+ dialog_message_set_buttons(msg, "No", NULL, "Yes");
|
|
|
|
|
+ dialog_message_set_text(
|
|
|
|
|
+ msg,
|
|
|
|
|
+ "This option requires a\nUART-compatible mag reader.\nIs it installed?\n",
|
|
|
|
|
+ 64,
|
|
|
|
|
+ 32,
|
|
|
|
|
+ AlignCenter,
|
|
|
|
|
+ AlignCenter);
|
|
|
|
|
+ DialogMessageButton res = dialog_message_show(furi_record_open(RECORD_DIALOGS), msg);
|
|
|
|
|
+ if(res != DialogMessageButtonRight) {
|
|
|
|
|
+ // if not "Yes", reset to "OFF" (0 / false-y)
|
|
|
|
|
+ variable_item_set_current_value_index(item_dialog_cb, 0);
|
|
|
|
|
+ mag_scene_settings_set_bool(item_dialog_cb, &mag->state.allow_uart);
|
|
|
|
|
+ }
|
|
|
|
|
+ dialog_message_free(msg);
|
|
|
|
|
+ furi_record_close(RECORD_DIALOGS);
|
|
|
|
|
+ item_dialog_cb = NULL;
|
|
|
}
|
|
}
|
|
|
break;
|
|
break;
|
|
|
default:
|
|
default:
|