gpio_controller.c 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239
  1. #include <furi.h>
  2. #include <furi_hal.h>
  3. #include <gui/gui.h>
  4. #include <input/input.h>
  5. /* Magic happens here -- this file is generated by fbt.
  6. * Just set fap_icon_assets in application.fam and #include {APPID}_icons.h */
  7. #include "gpio_controller_icons.h"
  8. #include "gpio_items.h"
  9. typedef struct {
  10. int selected;
  11. GPIOItems* gpio_items;
  12. } ViewerState;
  13. static ViewerState vstate = {.selected = 0};
  14. typedef enum {
  15. PIN_5V = 0,
  16. PIN_A7,
  17. PIN_A6,
  18. PIN_A4,
  19. PIN_B3,
  20. PIN_B2,
  21. PIN_C3,
  22. GEARIC,
  23. PIN_3V,
  24. PIN_SWC,
  25. PIN_SIO,
  26. PIN_TX,
  27. PIN_RX,
  28. PIN_C1,
  29. PIN_C0,
  30. PIN_1W,
  31. PIN_GND_08,
  32. PIN_GND_11,
  33. PIN_GND_18,
  34. NONE
  35. }ViewElement;
  36. // 5V A7 A6 A4 B3 B2 C3 GND SET
  37. //
  38. //
  39. // 3V SWC GND SIO TX RX C1 C0 1W GND
  40. // next element when pressing up or down from a given element
  41. // ground pins cannot be selected
  42. static uint8_t y_mapping[] = {
  43. PIN_3V, // <- PIN_5V
  44. PIN_SWC, // <- PIN_A7
  45. NONE, // <- PIN_A6
  46. PIN_SIO, // <- PIN_A4
  47. PIN_TX, // <- PIN_B3
  48. PIN_RX, // <- PIN_B2
  49. PIN_C1, // <- PIN_C3
  50. PIN_1W, // <- GEARIC
  51. PIN_5V, // <- PIN_3V
  52. PIN_A7, // <- PIN_SWC
  53. PIN_A4, // <- PIN_SIO
  54. PIN_B3, // <- PIN_TX
  55. PIN_B2, // <- PIN_RX
  56. PIN_C3, // <- PIN_C1
  57. NONE, // <- PIN_C0
  58. GEARIC // <- PIN_1W
  59. };
  60. static uint8_t x_pos[] = {
  61. 0, // PIN_5V
  62. 14, // PIN_A7
  63. 28, // PIN_A6
  64. 42, // PIN_A4
  65. 56, // PIN_B3
  66. 70, // PIN_B2
  67. 84, // PIN_C3
  68. 112, // GEARIC
  69. 0, // PIN_3V
  70. 14, // PIN_SWC
  71. 42, // PIN_SIO
  72. 56, // PIN_TX
  73. 70, // PIN_RX
  74. 84, // PIN_C1
  75. 98, // PIN_C0
  76. 112, // PIN_1W
  77. 98, // PIN_GND_08
  78. 28, // PIN_GND_11
  79. 126 // PIN_GND_18
  80. };
  81. static int gp_pins[] = {
  82. -1, // PIN_5V
  83. 0, // PIN_A7
  84. 1, // PIN_A6
  85. 2, // PIN_A4
  86. 3, // PIN_B3
  87. 4, // PIN_B2
  88. 5, // PIN_C3
  89. -1, // GEARIC
  90. -1, // PIN_3V
  91. -1, // PIN_SWC
  92. -1, // PIN_SIO
  93. -1, // PIN_TX
  94. -1, // PIN_RX
  95. 6, // PIN_C1
  96. 7, // PIN_C0
  97. -1, // PIN_1W
  98. };
  99. static Icon * icons[] = {
  100. (Icon*)&I_5v_pin, // PIN_5V
  101. (Icon*)&I_a7_pin, // PIN_A7
  102. (Icon*)&I_a6_pin, // PIN_A6
  103. (Icon*)&I_a4_pin, // PIN_A4
  104. (Icon*)&I_b3_pin, // PIN_B3
  105. (Icon*)&I_b2_pin, // PIN_B2
  106. (Icon*)&I_c3_pin, // PIN_C3
  107. (Icon*)&I_gear_unhighlighted, // GEARIC
  108. (Icon*)&I_3v_pin, // PIN_3V
  109. (Icon*)&I_swc_pin, // PIN_SWC
  110. (Icon*)&I_sio_pin, // PIN_SIO
  111. (Icon*)&I_tx_pin, // PIN_TX
  112. (Icon*)&I_rx_pin, // PIN_RX
  113. (Icon*)&I_c1_pin, // PIN_C1
  114. (Icon*)&I_c0_pin, // PIN_C0
  115. (Icon*)&I_1w_pin // PIN_1W
  116. };
  117. static uint8_t bot_row_y = 48;
  118. // Screen is 128x64 px
  119. static void app_draw_callback(Canvas* canvas, void* ctx) {
  120. UNUSED(ctx);
  121. canvas_clear(canvas);
  122. // draw ground pins
  123. canvas_draw_icon(canvas, x_pos[PIN_GND_08], -1, &I_gnd_pin);
  124. canvas_draw_icon(canvas, x_pos[PIN_GND_11], bot_row_y, &I_gnd_pin);
  125. canvas_draw_icon(canvas, x_pos[PIN_GND_18], bot_row_y, &I_gnd_pin);
  126. // draw gear
  127. canvas_draw_icon(canvas, x_pos[GEARIC], 0, (vstate.selected == GEARIC ? &I_gear_highlighted : &I_gear_unhighlighted));
  128. // draw top row of pins
  129. for( int i = 0; i < GEARIC; i++ )
  130. {
  131. int y = vstate.selected == i ? 0 : -3;
  132. canvas_draw_icon(canvas, x_pos[i], y, icons[i]);
  133. }
  134. // draw bottom row of pins
  135. for( int i = PIN_3V; i <= PIN_1W; i++ )
  136. {
  137. int y = bot_row_y - (vstate.selected == i ? 3 : 0);
  138. canvas_draw_icon(canvas, x_pos[i], y, icons[i]);
  139. }
  140. }
  141. static void app_input_callback(InputEvent* input_event, void* ctx) {
  142. furi_assert(ctx);
  143. FuriMessageQueue* event_queue = ctx;
  144. furi_message_queue_put(event_queue, input_event, FuriWaitForever);
  145. }
  146. int32_t gpio_controller_main(void* p) {
  147. UNUSED(p);
  148. FuriMessageQueue* event_queue = furi_message_queue_alloc(8, sizeof(InputEvent));
  149. // Configure view port
  150. ViewPort* view_port = view_port_alloc();
  151. view_port_draw_callback_set(view_port, app_draw_callback, view_port);
  152. view_port_input_callback_set(view_port, app_input_callback, event_queue);
  153. // Register view port in GUI
  154. Gui* gui = furi_record_open(RECORD_GUI);
  155. gui_add_view_port(gui, view_port, GuiLayerFullscreen);
  156. InputEvent event;
  157. vstate.gpio_items = gpio_items_alloc();
  158. gpio_items_configure_all_pins(vstate.gpio_items, GpioModeOutputPushPull);
  159. bool running = true;
  160. while(running) {
  161. if(furi_message_queue_get(event_queue, &event, 100) == FuriStatusOk) {
  162. if((event.type == InputTypePress) || (event.type == InputTypeRepeat)) {
  163. switch(event.key) {
  164. case InputKeyLeft:
  165. vstate.selected--;
  166. if(vstate.selected == GEARIC) vstate.selected = PIN_1W;
  167. else if(vstate.selected < 0) vstate.selected = GEARIC;
  168. break;
  169. case InputKeyRight:
  170. if(vstate.selected <= GEARIC)
  171. {
  172. vstate.selected++;
  173. vstate.selected = vstate.selected > GEARIC ? PIN_5V : vstate.selected;
  174. }
  175. else
  176. {
  177. vstate.selected++;
  178. vstate.selected = vstate.selected > PIN_1W ? PIN_3V : vstate.selected;
  179. }
  180. break;
  181. case InputKeyUp:
  182. case InputKeyDown:
  183. if (y_mapping[vstate.selected] != NONE) vstate.selected = y_mapping[vstate.selected];
  184. break;
  185. case InputKeyBack:
  186. running = false;
  187. break;
  188. default:
  189. break;
  190. }
  191. }
  192. }
  193. else if(event.key == InputKeyOk)
  194. {
  195. if( gp_pins[vstate.selected] >= 0 && (event.type == InputTypePress || event.type == InputTypeRelease) )
  196. {
  197. gpio_items_set_pin(vstate.gpio_items, gp_pins[vstate.selected], event.type == InputTypePress);
  198. }
  199. }
  200. view_port_update(view_port);
  201. }
  202. gpio_items_free(vstate.gpio_items);
  203. view_port_enabled_set(view_port, false);
  204. gui_remove_view_port(gui, view_port);
  205. view_port_free(view_port);
  206. furi_message_queue_free(event_queue);
  207. furi_record_close(RECORD_GUI);
  208. return 0;
  209. }