avr_isp_view_writer.c 9.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268
  1. #include "avr_isp_view_writer.h"
  2. #include <gui/elements.h>
  3. #include "../helpers/avr_isp_worker_rw.h"
  4. #include <float_tools.h>
  5. struct AvrIspWriterView {
  6. View* view;
  7. AvrIspWorkerRW* avr_isp_worker_rw;
  8. const char* file_path;
  9. const char* file_name;
  10. AvrIspWriterViewCallback callback;
  11. void* context;
  12. };
  13. typedef struct {
  14. AvrIspWriterViewStatus status;
  15. float progress_flash;
  16. float progress_eeprom;
  17. } AvrIspWriterViewModel;
  18. void avr_isp_writer_update_progress(AvrIspWriterView* instance) {
  19. with_view_model(
  20. instance->view,
  21. AvrIspWriterViewModel * model,
  22. {
  23. model->progress_flash =
  24. avr_isp_worker_rw_get_progress_flash(instance->avr_isp_worker_rw);
  25. model->progress_eeprom =
  26. avr_isp_worker_rw_get_progress_eeprom(instance->avr_isp_worker_rw);
  27. },
  28. true);
  29. }
  30. void avr_isp_writer_view_set_callback(
  31. AvrIspWriterView* instance,
  32. AvrIspWriterViewCallback callback,
  33. void* context) {
  34. furi_assert(instance);
  35. furi_assert(callback);
  36. instance->callback = callback;
  37. instance->context = context;
  38. }
  39. void avr_isp_writer_set_file_path(
  40. AvrIspWriterView* instance,
  41. const char* file_path,
  42. const char* file_name) {
  43. furi_assert(instance);
  44. instance->file_path = file_path;
  45. instance->file_name = file_name;
  46. }
  47. void avr_isp_writer_view_draw(Canvas* canvas, AvrIspWriterViewModel* model) {
  48. canvas_clear(canvas);
  49. char str_flash[32] = {0};
  50. char str_eeprom[32] = {0};
  51. canvas_set_font(canvas, FontPrimary);
  52. switch(model->status) {
  53. case AvrIspWriterViewStatusIDLE:
  54. canvas_draw_str_aligned(canvas, 64, 5, AlignCenter, AlignCenter, "Press start to write");
  55. canvas_set_font(canvas, FontSecondary);
  56. elements_button_center(canvas, "Start");
  57. snprintf(str_flash, sizeof(str_flash), "%d%%", (uint8_t)(model->progress_flash * 100));
  58. snprintf(str_eeprom, sizeof(str_eeprom), "%d%%", (uint8_t)(model->progress_eeprom * 100));
  59. break;
  60. case AvrIspWriterViewStatusWriting:
  61. if(float_is_equal(model->progress_flash, 0.f)) {
  62. canvas_draw_str_aligned(canvas, 64, 5, AlignCenter, AlignCenter, "Verifying firmware");
  63. snprintf(str_flash, sizeof(str_flash), "***");
  64. snprintf(str_eeprom, sizeof(str_eeprom), "***");
  65. } else {
  66. canvas_draw_str_aligned(canvas, 64, 5, AlignCenter, AlignCenter, "Writing dump");
  67. snprintf(str_flash, sizeof(str_flash), "%d%%", (uint8_t)(model->progress_flash * 100));
  68. snprintf(
  69. str_eeprom, sizeof(str_eeprom), "%d%%", (uint8_t)(model->progress_eeprom * 100));
  70. }
  71. break;
  72. case AvrIspWriterViewStatusVerification:
  73. canvas_draw_str_aligned(canvas, 64, 5, AlignCenter, AlignCenter, "Verifying dump");
  74. snprintf(str_flash, sizeof(str_flash), "%d%%", (uint8_t)(model->progress_flash * 100));
  75. snprintf(str_eeprom, sizeof(str_eeprom), "%d%%", (uint8_t)(model->progress_eeprom * 100));
  76. break;
  77. case AvrIspWriterViewStatusWritingFuse:
  78. canvas_draw_str_aligned(canvas, 64, 5, AlignCenter, AlignCenter, "Writing fuse");
  79. snprintf(str_flash, sizeof(str_flash), "%d%%", (uint8_t)(model->progress_flash * 100));
  80. snprintf(str_eeprom, sizeof(str_eeprom), "%d%%", (uint8_t)(model->progress_eeprom * 100));
  81. break;
  82. case AvrIspWriterViewStatusWritingFuseOk:
  83. canvas_draw_str_aligned(canvas, 64, 5, AlignCenter, AlignCenter, "Done!");
  84. snprintf(str_flash, sizeof(str_flash), "%d%%", (uint8_t)(model->progress_flash * 100));
  85. snprintf(str_eeprom, sizeof(str_eeprom), "%d%%", (uint8_t)(model->progress_eeprom * 100));
  86. canvas_set_font(canvas, FontSecondary);
  87. elements_button_center(canvas, "Reflash");
  88. elements_button_right(canvas, "Exit");
  89. break;
  90. default:
  91. break;
  92. }
  93. canvas_set_font(canvas, FontSecondary);
  94. canvas_draw_str(canvas, 0, 27, "Flash");
  95. // snprintf(str_buf, sizeof(str_buf), "%d%%", (uint8_t)(model->progress_flash * 100));
  96. elements_progress_bar_with_text(canvas, 44, 17, 84, model->progress_flash, str_flash);
  97. canvas_draw_str(canvas, 0, 43, "EEPROM");
  98. // snprintf(str_buf, sizeof(str_buf), "%d%%", (uint8_t)(model->progress_eeprom * 100));
  99. elements_progress_bar_with_text(canvas, 44, 34, 84, model->progress_eeprom, str_eeprom);
  100. }
  101. bool avr_isp_writer_view_input(InputEvent* event, void* context) {
  102. furi_assert(context);
  103. AvrIspWriterView* instance = context;
  104. bool ret = true;
  105. if(event->key == InputKeyBack && event->type == InputTypeShort) {
  106. with_view_model(
  107. instance->view,
  108. AvrIspWriterViewModel * model,
  109. {
  110. if((model->status == AvrIspWriterViewStatusIDLE) ||
  111. (model->status == AvrIspWriterViewStatusWritingFuseOk)) {
  112. if(instance->callback)
  113. instance->callback(AvrIspCustomEventSceneExit, instance->context);
  114. ret = false;
  115. }
  116. },
  117. false);
  118. } else if(event->key == InputKeyOk && event->type == InputTypeShort) {
  119. with_view_model(
  120. instance->view,
  121. AvrIspWriterViewModel * model,
  122. {
  123. if((model->status == AvrIspWriterViewStatusIDLE) ||
  124. (model->status == AvrIspWriterViewStatusWritingFuseOk)) {
  125. model->status = AvrIspWriterViewStatusWriting;
  126. avr_isp_worker_rw_write_dump_start(
  127. instance->avr_isp_worker_rw, instance->file_path, instance->file_name);
  128. }
  129. },
  130. false);
  131. } else if(event->key == InputKeyRight && event->type == InputTypeShort) {
  132. with_view_model(
  133. instance->view,
  134. AvrIspWriterViewModel * model,
  135. {
  136. if((model->status == AvrIspWriterViewStatusIDLE) ||
  137. (model->status == AvrIspWriterViewStatusWritingFuseOk)) {
  138. if(instance->callback)
  139. instance->callback(AvrIspCustomEventSceneExitStartMenu, instance->context);
  140. ret = false;
  141. }
  142. },
  143. false);
  144. }
  145. return ret;
  146. }
  147. static void avr_isp_writer_callback_status(void* context, AvrIspWorkerRWStatus status) {
  148. furi_assert(context);
  149. AvrIspWriterView* instance = context;
  150. with_view_model(
  151. instance->view,
  152. AvrIspWriterViewModel * model,
  153. {
  154. switch(status) {
  155. case AvrIspWorkerRWStatusEndWriting:
  156. model->status = AvrIspWriterViewStatusVerification;
  157. avr_isp_worker_rw_verification_start(
  158. instance->avr_isp_worker_rw, instance->file_path, instance->file_name);
  159. model->status = AvrIspWriterViewStatusVerification;
  160. break;
  161. case AvrIspWorkerRWStatusErrorVerification:
  162. if(instance->callback)
  163. instance->callback(AvrIspCustomEventSceneErrorVerification, instance->context);
  164. break;
  165. case AvrIspWorkerRWStatusEndVerification:
  166. avr_isp_worker_rw_write_fuse_start(
  167. instance->avr_isp_worker_rw, instance->file_path, instance->file_name);
  168. model->status = AvrIspWriterViewStatusWritingFuse;
  169. break;
  170. case AvrIspWorkerRWStatusErrorWritingFuse:
  171. if(instance->callback)
  172. instance->callback(AvrIspCustomEventSceneErrorWritingFuse, instance->context);
  173. break;
  174. case AvrIspWorkerRWStatusEndWritingFuse:
  175. model->status = AvrIspWriterViewStatusWritingFuseOk;
  176. break;
  177. default:
  178. //AvrIspWorkerRWStatusErrorWriting;
  179. if(instance->callback)
  180. instance->callback(AvrIspCustomEventSceneErrorWriting, instance->context);
  181. break;
  182. }
  183. },
  184. true);
  185. }
  186. void avr_isp_writer_view_enter(void* context) {
  187. furi_assert(context);
  188. AvrIspWriterView* instance = context;
  189. with_view_model(
  190. instance->view,
  191. AvrIspWriterViewModel * model,
  192. {
  193. model->status = AvrIspWriterViewStatusIDLE;
  194. model->progress_flash = 0.0f;
  195. model->progress_eeprom = 0.0f;
  196. },
  197. true);
  198. //Start avr_isp_worker_rw
  199. instance->avr_isp_worker_rw = avr_isp_worker_rw_alloc(instance->context);
  200. avr_isp_worker_rw_set_callback_status(
  201. instance->avr_isp_worker_rw, avr_isp_writer_callback_status, instance);
  202. avr_isp_worker_rw_start(instance->avr_isp_worker_rw);
  203. }
  204. void avr_isp_writer_view_exit(void* context) {
  205. furi_assert(context);
  206. AvrIspWriterView* instance = context;
  207. //Stop avr_isp_worker_rw
  208. if(avr_isp_worker_rw_is_running(instance->avr_isp_worker_rw)) {
  209. avr_isp_worker_rw_stop(instance->avr_isp_worker_rw);
  210. }
  211. avr_isp_worker_rw_free(instance->avr_isp_worker_rw);
  212. }
  213. AvrIspWriterView* avr_isp_writer_view_alloc() {
  214. AvrIspWriterView* instance = malloc(sizeof(AvrIspWriterView));
  215. // View allocation and configuration
  216. instance->view = view_alloc();
  217. view_allocate_model(instance->view, ViewModelTypeLocking, sizeof(AvrIspWriterViewModel));
  218. view_set_context(instance->view, instance);
  219. view_set_draw_callback(instance->view, (ViewDrawCallback)avr_isp_writer_view_draw);
  220. view_set_input_callback(instance->view, avr_isp_writer_view_input);
  221. view_set_enter_callback(instance->view, avr_isp_writer_view_enter);
  222. view_set_exit_callback(instance->view, avr_isp_writer_view_exit);
  223. return instance;
  224. }
  225. void avr_isp_writer_view_free(AvrIspWriterView* instance) {
  226. furi_assert(instance);
  227. view_free(instance->view);
  228. free(instance);
  229. }
  230. View* avr_isp_writer_view_get_view(AvrIspWriterView* instance) {
  231. furi_assert(instance);
  232. return instance->view;
  233. }