avr_isp_view_chip_detect.c 6.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213
  1. #include "avr_isp_view_chip_detect.h"
  2. #include <avr_isp_icons.h>
  3. #include <gui/elements.h>
  4. #include "../helpers/avr_isp_worker_rw.h"
  5. struct AvrIspChipDetectView {
  6. View* view;
  7. AvrIspWorkerRW* avr_isp_worker_rw;
  8. AvrIspChipDetectViewCallback callback;
  9. void* context;
  10. };
  11. typedef struct {
  12. uint16_t idx;
  13. const char* name_chip;
  14. uint32_t flash_size;
  15. AvrIspChipDetectViewState state;
  16. } AvrIspChipDetectViewModel;
  17. void avr_isp_chip_detect_view_set_callback(
  18. AvrIspChipDetectView* instance,
  19. AvrIspChipDetectViewCallback callback,
  20. void* context) {
  21. furi_assert(instance);
  22. furi_assert(callback);
  23. instance->callback = callback;
  24. instance->context = context;
  25. }
  26. void avr_isp_chip_detect_set_state(AvrIspChipDetectView* instance, AvrIspChipDetectViewState state) {
  27. furi_assert(instance);
  28. with_view_model(
  29. instance->view, AvrIspChipDetectViewModel * model, { model->state = state; }, true);
  30. }
  31. void avr_isp_chip_detect_view_draw(Canvas* canvas, AvrIspChipDetectViewModel* model) {
  32. canvas_clear(canvas);
  33. char str_buf[64] = {0};
  34. canvas_set_font(canvas, FontPrimary);
  35. switch(model->state) {
  36. case AvrIspChipDetectViewStateDetected:
  37. canvas_draw_str_aligned(canvas, 64, 5, AlignCenter, AlignCenter, "AVR chip detected!");
  38. canvas_draw_icon(canvas, 29, 14, &I_chip_long_70x22);
  39. canvas_set_font(canvas, FontSecondary);
  40. snprintf(str_buf, sizeof(str_buf), "%ld Kb", model->flash_size / 1024);
  41. canvas_draw_str_aligned(canvas, 64, 25, AlignCenter, AlignCenter, str_buf);
  42. canvas_draw_str_aligned(canvas, 64, 45, AlignCenter, AlignCenter, model->name_chip);
  43. elements_button_right(canvas, "Next");
  44. break;
  45. case AvrIspChipDetectViewStateErrorOccured:
  46. canvas_draw_str_aligned(
  47. canvas, 64, 5, AlignCenter, AlignCenter, "Error occured, try again!");
  48. canvas_draw_icon(canvas, 29, 14, &I_chip_error_70x22);
  49. canvas_set_font(canvas, FontSecondary);
  50. canvas_draw_str_aligned(
  51. canvas, 64, 45, AlignCenter, AlignCenter, "Check the wiring and retry");
  52. break;
  53. case AvrIspChipDetectViewStateErrorVerification:
  54. canvas_draw_str_aligned(
  55. canvas, 64, 5, AlignCenter, AlignCenter, "Data verification failed");
  56. canvas_draw_icon(canvas, 29, 14, &I_chip_error_70x22);
  57. canvas_set_font(canvas, FontSecondary);
  58. canvas_draw_str_aligned(
  59. canvas, 64, 45, AlignCenter, AlignCenter, "Try to restart the process");
  60. break;
  61. default:
  62. //AvrIspChipDetectViewStateNoDetect
  63. canvas_draw_str_aligned(canvas, 64, 5, AlignCenter, AlignCenter, "AVR chip not found!");
  64. canvas_draw_icon(canvas, 29, 12, &I_chif_not_found_83x37);
  65. break;
  66. }
  67. canvas_set_font(canvas, FontSecondary);
  68. elements_button_left(canvas, "Retry");
  69. }
  70. bool avr_isp_chip_detect_view_input(InputEvent* event, void* context) {
  71. furi_assert(context);
  72. AvrIspChipDetectView* instance = context;
  73. if(event->type == InputTypeShort) {
  74. if(event->key == InputKeyBack) {
  75. return false;
  76. } else if(event->key == InputKeyRight) {
  77. with_view_model(
  78. instance->view,
  79. AvrIspChipDetectViewModel * model,
  80. {
  81. if(model->state == AvrIspChipDetectViewStateDetected) {
  82. if(instance->callback)
  83. instance->callback(
  84. AvrIspCustomEventSceneChipDetectOk, instance->context);
  85. }
  86. },
  87. false);
  88. } else if(event->key == InputKeyLeft) {
  89. bool detect_chip = false;
  90. with_view_model(
  91. instance->view,
  92. AvrIspChipDetectViewModel * model,
  93. {
  94. if(model->state != AvrIspChipDetectViewStateDetecting) {
  95. model->state = AvrIspChipDetectViewStateDetecting;
  96. detect_chip = true;
  97. }
  98. },
  99. false);
  100. if(detect_chip) avr_isp_worker_rw_detect_chip(instance->avr_isp_worker_rw);
  101. }
  102. } else {
  103. return false;
  104. }
  105. return true;
  106. }
  107. static void avr_isp_chip_detect_detect_chip_callback(
  108. void* context,
  109. const char* name,
  110. bool detect_chip,
  111. uint32_t flash_size) {
  112. furi_assert(context);
  113. AvrIspChipDetectView* instance = context;
  114. with_view_model(
  115. instance->view,
  116. AvrIspChipDetectViewModel * model,
  117. {
  118. model->name_chip = name;
  119. model->flash_size = flash_size;
  120. if(detect_chip) {
  121. model->state = AvrIspChipDetectViewStateDetected;
  122. } else {
  123. model->state = AvrIspChipDetectViewStateNoDetect;
  124. }
  125. },
  126. true);
  127. }
  128. void avr_isp_chip_detect_view_enter(void* context) {
  129. furi_assert(context);
  130. AvrIspChipDetectView* instance = context;
  131. bool detect_chip = false;
  132. with_view_model(
  133. instance->view,
  134. AvrIspChipDetectViewModel * model,
  135. {
  136. if(model->state == AvrIspChipDetectViewStateNoDetect ||
  137. model->state == AvrIspChipDetectViewStateDetected) {
  138. detect_chip = true;
  139. }
  140. },
  141. false);
  142. //Start avr_isp_worker_rw
  143. instance->avr_isp_worker_rw = avr_isp_worker_rw_alloc(instance->context);
  144. avr_isp_worker_rw_set_callback(
  145. instance->avr_isp_worker_rw, avr_isp_chip_detect_detect_chip_callback, instance);
  146. if(detect_chip) avr_isp_worker_rw_detect_chip(instance->avr_isp_worker_rw);
  147. }
  148. void avr_isp_chip_detect_view_exit(void* context) {
  149. furi_assert(context);
  150. AvrIspChipDetectView* instance = context;
  151. avr_isp_worker_rw_set_callback(instance->avr_isp_worker_rw, NULL, NULL);
  152. avr_isp_worker_rw_free(instance->avr_isp_worker_rw);
  153. }
  154. AvrIspChipDetectView* avr_isp_chip_detect_view_alloc() {
  155. AvrIspChipDetectView* instance = malloc(sizeof(AvrIspChipDetectView));
  156. // View allocation and configuration
  157. instance->view = view_alloc();
  158. view_allocate_model(instance->view, ViewModelTypeLocking, sizeof(AvrIspChipDetectViewModel));
  159. view_set_context(instance->view, instance);
  160. view_set_draw_callback(instance->view, (ViewDrawCallback)avr_isp_chip_detect_view_draw);
  161. view_set_input_callback(instance->view, avr_isp_chip_detect_view_input);
  162. view_set_enter_callback(instance->view, avr_isp_chip_detect_view_enter);
  163. view_set_exit_callback(instance->view, avr_isp_chip_detect_view_exit);
  164. with_view_model(
  165. instance->view,
  166. AvrIspChipDetectViewModel * model,
  167. { model->state = AvrIspChipDetectViewStateNoDetect; },
  168. false);
  169. return instance;
  170. }
  171. void avr_isp_chip_detect_view_free(AvrIspChipDetectView* instance) {
  172. furi_assert(instance);
  173. view_free(instance->view);
  174. free(instance);
  175. }
  176. View* avr_isp_chip_detect_view_get_view(AvrIspChipDetectView* instance) {
  177. furi_assert(instance);
  178. return instance->view;
  179. }