mag_scene_settings.c 6.1 KB

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