mag_scene_settings.c 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177
  1. #include "../mag_i.h"
  2. #include "../mag_state.h"
  3. #include "../helpers/mag_helpers.h"
  4. #define TAG "MagSceneEmulateConfig"
  5. enum VarItemListIndex {
  6. VarItemListIndexPinInput,
  7. VarItemListIndexPinOutput,
  8. VarItemListIndexPinEnable,
  9. VarItemListIndexAllowUART,
  10. };
  11. static const char* gpio[] = {
  12. [MagPinA7] = "2 (A7)",
  13. [MagPinA6] = "3 (A6)",
  14. [MagPinA4] = "4 (A4)",
  15. [MagPinB3] = "5 (B3)",
  16. [MagPinB2] = "6 (B2)",
  17. [MagPinC3] = "7 (C3)",
  18. [MagPinC1] = "15 (C1)",
  19. [MagPinC0] = "16 (C0)",
  20. };
  21. const uint8_t GPIO_COUNT = COUNT_OF(gpio);
  22. // static const char* uart_pins[] = {[DapUartTypeUSART1] = "13,14", [DapUartTypeLPUART1] = "15,16"};
  23. // static const char* uart_swap[] = {[DapUartTXRXNormal] = "No", [DapUartTXRXSwap] = "Yes"};
  24. void mag_scene_settings_var_item_list_callback(void* context, uint32_t index) {
  25. Mag* mag = context;
  26. view_dispatcher_send_custom_event(mag->view_dispatcher, index);
  27. }
  28. static void mag_scene_settings_set_gpio(VariableItem* item, MagPin* pin_out) {
  29. MagPin pin = variable_item_get_current_value_index(item);
  30. variable_item_set_current_value_text(item, gpio[pin]);
  31. *pin_out = pin;
  32. }
  33. static void mag_scene_settings_set_gpio_input(VariableItem* item) {
  34. Mag* mag = variable_item_get_context(item);
  35. mag_scene_settings_set_gpio(item, &mag->state.pin_input);
  36. };
  37. static void mag_scene_settings_set_gpio_output(VariableItem* item) {
  38. Mag* mag = variable_item_get_context(item);
  39. mag_scene_settings_set_gpio(item, &mag->state.pin_output);
  40. };
  41. static void mag_scene_settings_set_gpio_enable(VariableItem* item) {
  42. Mag* mag = variable_item_get_context(item);
  43. mag_scene_settings_set_gpio(item, &mag->state.pin_enable);
  44. };
  45. static void mag_pin_variable_item_list_add(
  46. Mag* mag,
  47. const char* label,
  48. MagPin pin,
  49. VariableItemChangeCallback change_callback) {
  50. VariableItem* item =
  51. variable_item_list_add(mag->variable_item_list, label, GPIO_COUNT, change_callback, mag);
  52. variable_item_set_current_value_index(item, pin);
  53. variable_item_set_current_value_text(item, gpio[pin]);
  54. }
  55. void mag_scene_settings_on_enter(void* context) {
  56. Mag* mag = context;
  57. VariableItem* item;
  58. VariableItemList* var_item_list = mag->variable_item_list;
  59. mag_pin_variable_item_list_add(
  60. mag, "Input pin:", mag->state.pin_input, mag_scene_settings_set_gpio_input);
  61. mag_pin_variable_item_list_add(
  62. mag, "Output pin:", mag->state.pin_output, mag_scene_settings_set_gpio_output);
  63. mag_pin_variable_item_list_add(
  64. mag, "Enable pin:", mag->state.pin_enable, mag_scene_settings_set_gpio_enable);
  65. item = variable_item_list_add(var_item_list, "UART MSR: ", 1, NULL, mag);
  66. variable_item_set_current_value_text(item, mag->state.allow_uart ? "ON" : "OFF");
  67. variable_item_list_set_enter_callback(
  68. var_item_list, mag_scene_settings_var_item_list_callback, mag);
  69. variable_item_list_set_selected_item(
  70. var_item_list, scene_manager_get_scene_state(mag->scene_manager, MagSceneSettings));
  71. view_dispatcher_switch_to_view(mag->view_dispatcher, MagViewVariableItemList);
  72. }
  73. void mag_scene_settings_dialog_invalid_pins(Mag* mag) {
  74. SceneManager* scene_manager = mag->scene_manager;
  75. DialogMessage* message = dialog_message_alloc();
  76. dialog_message_set_header(message, "Invalid Pin Config!", 64, 0, AlignCenter, AlignTop);
  77. dialog_message_set_buttons(message, "Modify", NULL, "Reset");
  78. dialog_message_set_text(
  79. message,
  80. "Pins cannot overlap.\nChange, or reset to defaults.",
  81. 64,
  82. 32,
  83. AlignCenter,
  84. AlignCenter);
  85. DialogMessageButton res = dialog_message_show(furi_record_open(RECORD_DIALOGS), message);
  86. dialog_message_free(message);
  87. furi_record_close(RECORD_DIALOGS);
  88. if(res == DialogMessageButtonRight) {
  89. mag_state_gpio_reset(&mag->state);
  90. scene_manager_previous_scene(scene_manager);
  91. }
  92. }
  93. void mag_scene_settings_dialog_allow_uart(Mag* mag) {
  94. bool change = mag->state.allow_uart;
  95. if(!change) {
  96. DialogMessage* msg = dialog_message_alloc();
  97. dialog_message_set_header(msg, "UART MSR", 64, 0, AlignCenter, AlignTop);
  98. dialog_message_set_buttons(msg, "No", NULL, "Yes");
  99. dialog_message_set_text(
  100. msg,
  101. "This option requires a\nUART-compatible mag reader.\nIs it installed?\n",
  102. 64,
  103. 32,
  104. AlignCenter,
  105. AlignCenter);
  106. DialogMessageButton res = dialog_message_show(furi_record_open(RECORD_DIALOGS), msg);
  107. if(res == DialogMessageButtonRight) {
  108. change = true;
  109. }
  110. dialog_message_free(msg);
  111. furi_record_close(RECORD_DIALOGS);
  112. }
  113. if(change) {
  114. mag->state.allow_uart = !mag->state.allow_uart;
  115. variable_item_set_current_value_text(
  116. variable_item_list_get(mag->variable_item_list, VarItemListIndexAllowUART),
  117. mag->state.allow_uart ? "ON" : "OFF");
  118. }
  119. }
  120. bool mag_scene_settings_on_event(void* context, SceneManagerEvent event) {
  121. Mag* mag = context;
  122. SceneManager* scene_manager = mag->scene_manager;
  123. bool consumed = false;
  124. switch(event.type) {
  125. case SceneManagerEventTypeBack:
  126. // when attempting to exit, validate pin configuration
  127. // if invalid, prompt
  128. consumed = true;
  129. if(!mag_state_gpio_is_valid(&mag->state)) {
  130. mag_scene_settings_dialog_invalid_pins(mag);
  131. } else {
  132. scene_manager_previous_scene(scene_manager);
  133. }
  134. break;
  135. case SceneManagerEventTypeCustom:
  136. scene_manager_set_scene_state(mag->scene_manager, MagSceneSettings, event.event);
  137. consumed = true;
  138. if(event.event == VarItemListIndexAllowUART) {
  139. mag_scene_settings_dialog_allow_uart(mag);
  140. }
  141. break;
  142. default:
  143. break;
  144. }
  145. return consumed;
  146. }
  147. void mag_scene_settings_on_exit(void* context) {
  148. Mag* mag = context;
  149. variable_item_list_reset(mag->variable_item_list);
  150. mag_state_save(&mag->state);
  151. }