mag_state.c 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147
  1. #include "mag_state.h"
  2. #define TAG "MagState"
  3. const GpioPin* mag_state_enum_to_pin(MagPin pin) {
  4. switch(pin) {
  5. case MagPinA7:
  6. return &gpio_ext_pa7;
  7. case MagPinA6:
  8. return &gpio_ext_pa6;
  9. case MagPinA4:
  10. return &gpio_ext_pa4;
  11. case MagPinB3:
  12. return &gpio_ext_pb3;
  13. case MagPinB2:
  14. return &gpio_ext_pb2;
  15. case MagPinC3:
  16. return &gpio_ext_pc3;
  17. case MagPinC1:
  18. return &gpio_ext_pc1;
  19. case MagPinC0:
  20. return &gpio_ext_pc0;
  21. default:
  22. return NULL;
  23. }
  24. }
  25. bool mag_state_gpio_is_valid(MagState* state) {
  26. return (state->pin_input != state->pin_output) && (state->pin_input != state->pin_enable) &&
  27. (state->pin_enable != state->pin_output);
  28. }
  29. void mag_state_gpio_reset(MagState* state) {
  30. state->pin_input = MAG_STATE_DEFAULT_PIN_INPUT;
  31. state->pin_output = MAG_STATE_DEFAULT_PIN_OUTPUT;
  32. state->pin_enable = MAG_STATE_DEFAULT_PIN_ENABLE;
  33. }
  34. bool mag_state_load(MagState* out_state) {
  35. MagState state;
  36. // Try to load from file
  37. bool loaded_from_file = false;
  38. Storage* storage = furi_record_open(RECORD_STORAGE);
  39. if(storage_file_exists(storage, MAG_STATE_PATH)) {
  40. FlipperFormat* file = flipper_format_file_alloc(storage);
  41. do {
  42. uint32_t tmp;
  43. FuriString* str = furi_string_alloc();
  44. if(!flipper_format_file_open_existing(file, MAG_STATE_PATH)) break;
  45. if(!flipper_format_read_header(file, str, &tmp)) break;
  46. if(furi_string_cmp_str(str, MAG_STATE_HEADER)) break;
  47. // if(tmp != MAG_STATE_VER) break;
  48. if(!flipper_format_read_uint32(file, "pin_input", &tmp, 1)) {
  49. flipper_format_rewind(file);
  50. tmp = MAG_STATE_DEFAULT_PIN_INPUT;
  51. }
  52. state.pin_input = (MagPin)tmp;
  53. if(!flipper_format_read_uint32(file, "pin_output", &tmp, 1)) {
  54. flipper_format_rewind(file);
  55. tmp = MAG_STATE_DEFAULT_PIN_OUTPUT;
  56. }
  57. state.pin_output = (MagPin)tmp;
  58. if(!flipper_format_read_uint32(file, "pin_enable", &tmp, 1)) {
  59. flipper_format_rewind(file);
  60. tmp = MAG_STATE_DEFAULT_PIN_ENABLE;
  61. }
  62. state.pin_enable = (MagPin)tmp;
  63. if(!flipper_format_read_bool(file, "allow_uart", &state.allow_uart, 1)) {
  64. flipper_format_rewind(file);
  65. state.allow_uart = MAG_STATE_DEFAULT_ALLOW_UART;
  66. }
  67. if(!flipper_format_read_uint32(file, "n_repeats", &tmp, 1)) {
  68. flipper_format_rewind(file);
  69. tmp = MAG_STATE_DEFAULT_N_REPEATS;
  70. }
  71. state.n_repeats = (uint8_t)tmp;
  72. if(!flipper_format_read_bool(file, "repeat_mode", &state.repeat_mode, 1)) {
  73. flipper_format_rewind(file);
  74. state.repeat_mode = MAG_STATE_DEFAULT_REPEAT_MODE;
  75. }
  76. loaded_from_file = true;
  77. } while(0);
  78. flipper_format_free(file);
  79. }
  80. furi_record_close(RECORD_STORAGE);
  81. // If file's GPIO config is invalid (pins overlap)
  82. // Reset to defaults
  83. // Additionally raise message to user?
  84. if(!mag_state_gpio_is_valid(&state)) {
  85. mag_state_gpio_reset(&state);
  86. }
  87. if(!loaded_from_file) {
  88. mag_state_gpio_reset(&state);
  89. state.allow_uart = MAG_STATE_DEFAULT_ALLOW_UART;
  90. state.n_repeats = MAG_STATE_DEFAULT_N_REPEATS;
  91. state.repeat_mode = MAG_STATE_DEFAULT_REPEAT_MODE;
  92. }
  93. // set defaults we don't save
  94. state.tx = MAG_STATE_DEFAULT_TX;
  95. state.track = MAG_STATE_DEFAULT_TRACK;
  96. state.reverse = MAG_STATE_DEFAULT_REVERSE;
  97. state.us_clock = MAG_STATE_DEFAULT_US_CLOCK;
  98. state.us_interpacket = MAG_STATE_DEFAULT_US_INTERPACKET;
  99. state.is_debug = furi_hal_rtc_is_flag_set(FuriHalRtcFlagDebug);
  100. // Copy to caller state before popping stack
  101. memcpy(out_state, &state, sizeof(state));
  102. return loaded_from_file;
  103. }
  104. void mag_state_save(MagState* state) {
  105. Storage* storage = furi_record_open(RECORD_STORAGE);
  106. storage_simply_mkdir(storage, MAG_STATE_DIR);
  107. FlipperFormat* file = flipper_format_file_alloc(storage);
  108. do {
  109. uint32_t tmp;
  110. if(!flipper_format_file_open_always(file, MAG_STATE_PATH)) break;
  111. if(!flipper_format_write_header_cstr(file, MAG_STATE_HEADER, MAG_STATE_VER)) break;
  112. tmp = (uint32_t)state->pin_input;
  113. if(!flipper_format_write_uint32(file, "pin_input", &tmp, 1)) break;
  114. tmp = (uint32_t)state->pin_output;
  115. if(!flipper_format_write_uint32(file, "pin_output", &tmp, 1)) break;
  116. tmp = (uint32_t)state->pin_enable;
  117. if(!flipper_format_write_uint32(file, "pin_enable", &tmp, 1)) break;
  118. if(!flipper_format_write_bool(file, "allow_uart", &state->allow_uart, 1)) break;
  119. tmp = (uint32_t)state->n_repeats;
  120. if(!flipper_format_write_uint32(file, "n_repeats", &tmp, 1)) break;
  121. if(!flipper_format_write_bool(file, "repeat_mode", &state->repeat_mode, 1)) break;
  122. } while(0);
  123. flipper_format_free(file);
  124. furi_record_close(RECORD_STORAGE);
  125. }