Jean LE QUELLEC 3 лет назад
Родитель
Сommit
f7c04a6466
12 измененных файлов с 348 добавлено и 330 удалено
  1. 2 0
      i2csender.h
  2. 2 0
      i2csniffer.h
  3. 36 316
      i2ctools.c
  4. 5 14
      i2ctools_i.h
  5. 63 0
      views/main_view.c
  6. 38 0
      views/main_view.h
  7. 55 0
      views/scanner_view.c
  8. 11 0
      views/scanner_view.h
  9. 52 0
      views/sender_view.c
  10. 11 0
      views/sender_view.h
  11. 62 0
      views/sniffer_view.c
  12. 11 0
      views/sniffer_view.h

+ 2 - 0
i2csender.h

@@ -1,3 +1,5 @@
+#pragma once
+
 #include <furi.h>
 #include <furi_hal.h>
 #include "i2cscanner.h"

+ 2 - 0
i2csniffer.h

@@ -1,3 +1,5 @@
+#pragma once
+
 #include <furi.h>
 #include <furi_hal.h>
 

+ 36 - 316
i2ctools.c

@@ -1,303 +1,29 @@
 #include "i2ctools_i.h"
 
-#define APP_NAME "I2C Tools"
-
-#define SCAN_MENU_TEXT "Scan"
-#define SCAN_MENU_X 75
-#define SCAN_MENU_Y 6
-
-#define SNIFF_MENU_TEXT "Sniff"
-#define SNIFF_MENU_X 75
-#define SNIFF_MENU_Y 20
-
-#define SEND_MENU_TEXT "Send"
-#define SEND_MENU_X 75
-#define SEND_MENU_Y 34
-
-#define PLAY_MENU_TEXT "Play"
-#define PLAY_MENU_X 75
-#define PLAY_MENU_Y 48
-
-void i2ctools_draw_main_menu(Canvas* canvas, i2cTools* i2ctools) {
-    canvas_clear(canvas);
-    canvas_set_color(canvas, ColorBlack);
-    canvas_draw_rframe(canvas, 0, 0, 128, 64, 3);
-    canvas_draw_icon(canvas, 2, 13, &I_passport_bad3_46x49);
-    canvas_set_font(canvas, FontPrimary);
-    canvas_draw_str_aligned(canvas, 3, 3, AlignLeft, AlignTop, APP_NAME);
-
-    switch(i2ctools->main_menu_index) {
-    case 0:
-        canvas_set_color(canvas, ColorBlack);
-        canvas_draw_str_aligned(
-            canvas, SNIFF_MENU_X, SNIFF_MENU_Y, AlignLeft, AlignTop, SNIFF_MENU_TEXT);
-        canvas_draw_str_aligned(
-            canvas, SEND_MENU_X, SEND_MENU_Y, AlignLeft, AlignTop, SEND_MENU_TEXT);
-        canvas_draw_str_aligned(
-            canvas, PLAY_MENU_X, PLAY_MENU_Y, AlignLeft, AlignTop, PLAY_MENU_TEXT);
-
-        canvas_draw_rbox(canvas, 60, SCAN_MENU_Y - 2, 60, 13, 3);
-        canvas_set_color(canvas, ColorWhite);
-        canvas_draw_str_aligned(
-            canvas, SCAN_MENU_X, SCAN_MENU_Y, AlignLeft, AlignTop, SCAN_MENU_TEXT);
-        break;
-
-    case 1:
-        canvas_set_color(canvas, ColorBlack);
-        canvas_draw_str_aligned(
-            canvas, SCAN_MENU_X, SCAN_MENU_Y, AlignLeft, AlignTop, SCAN_MENU_TEXT);
-        canvas_draw_str_aligned(
-            canvas, SEND_MENU_X, SEND_MENU_Y, AlignLeft, AlignTop, SEND_MENU_TEXT);
-        canvas_draw_str_aligned(
-            canvas, PLAY_MENU_X, PLAY_MENU_Y, AlignLeft, AlignTop, PLAY_MENU_TEXT);
-
-        canvas_draw_rbox(canvas, 60, SNIFF_MENU_Y - 2, 60, 13, 3);
-        canvas_set_color(canvas, ColorWhite);
-        canvas_draw_str_aligned(
-            canvas, SNIFF_MENU_X, SNIFF_MENU_Y, AlignLeft, AlignTop, SNIFF_MENU_TEXT);
-        break;
-
-    case 2:
-        canvas_set_color(canvas, ColorBlack);
-        canvas_draw_str_aligned(
-            canvas, SCAN_MENU_X, SCAN_MENU_Y, AlignLeft, AlignTop, SCAN_MENU_TEXT);
-        canvas_draw_str_aligned(
-            canvas, SNIFF_MENU_X, SNIFF_MENU_Y, AlignLeft, AlignTop, SNIFF_MENU_TEXT);
-        canvas_draw_str_aligned(
-            canvas, PLAY_MENU_X, PLAY_MENU_Y, AlignLeft, AlignTop, PLAY_MENU_TEXT);
-
-        canvas_draw_rbox(canvas, 60, SEND_MENU_Y - 2, 60, 13, 3);
-        canvas_set_color(canvas, ColorWhite);
-        canvas_draw_str_aligned(
-            canvas, SEND_MENU_X, SEND_MENU_Y, AlignLeft, AlignTop, SEND_MENU_TEXT);
-        break;
-
-    case 3:
-        canvas_set_color(canvas, ColorBlack);
-        canvas_draw_str_aligned(
-            canvas, SCAN_MENU_X, SCAN_MENU_Y, AlignLeft, AlignTop, SCAN_MENU_TEXT);
-        canvas_draw_str_aligned(
-            canvas, SNIFF_MENU_X, SNIFF_MENU_Y, AlignLeft, AlignTop, SNIFF_MENU_TEXT);
-        canvas_draw_str_aligned(
-            canvas, SEND_MENU_X, SEND_MENU_Y, AlignLeft, AlignTop, SEND_MENU_TEXT);
-
-        canvas_draw_rbox(canvas, 60, PLAY_MENU_Y - 2, 60, 13, 3);
-        canvas_set_color(canvas, ColorWhite);
-        canvas_draw_str_aligned(
-            canvas, PLAY_MENU_X, PLAY_MENU_Y, AlignLeft, AlignTop, PLAY_MENU_TEXT);
-        break;
-
-    default:
-        break;
-    }
-}
-
-void i2ctools_draw_sniff_view(Canvas* canvas, i2cTools* i2ctools) {
-    canvas_clear(canvas);
-    canvas_set_color(canvas, ColorBlack);
-    canvas_draw_rframe(canvas, 0, 0, 128, 64, 3);
-    canvas_draw_icon(canvas, 2, 13, &I_passport_happy2_46x49);
-
-    canvas_set_font(canvas, FontPrimary);
-    canvas_draw_str_aligned(canvas, 3, 3, AlignLeft, AlignTop, SNIFF_MENU_TEXT);
-    canvas_set_font(canvas, FontSecondary);
-
-    // Button
-    canvas_draw_rbox(canvas, 70, 48, 45, 13, 3);
-    canvas_set_color(canvas, ColorWhite);
-    canvas_draw_icon(canvas, 75, 50, &I_Ok_btn_9x9);
-    if(!i2ctools->sniffer->started) {
-        canvas_draw_str_aligned(canvas, 85, 51, AlignLeft, AlignTop, "Start");
-    } else {
-        canvas_draw_str_aligned(canvas, 85, 51, AlignLeft, AlignTop, "Stop");
-    }
-    canvas_set_color(canvas, ColorBlack);
-    // Address text
-    char addr_text[8];
-    snprintf(
-        addr_text,
-        sizeof(addr_text),
-        "0x%02x",
-        (int)(i2ctools->sniffer->frames[i2ctools->sniffer->menu_index].data[0] >> 1));
-    canvas_draw_str_aligned(canvas, 50, 3, AlignLeft, AlignTop, "Addr: ");
-    canvas_draw_str_aligned(canvas, 75, 3, AlignLeft, AlignTop, addr_text);
-    // R/W
-    if((int)(i2ctools->sniffer->frames[i2ctools->sniffer->menu_index].data[0]) % 2 == 0) {
-        canvas_draw_str_aligned(canvas, 105, 3, AlignLeft, AlignTop, "W");
-    } else {
-        canvas_draw_str_aligned(canvas, 105, 3, AlignLeft, AlignTop, "R");
-    }
-    // nbFrame text
-    canvas_draw_str_aligned(canvas, 50, 13, AlignLeft, AlignTop, "Frames: ");
-    snprintf(addr_text, sizeof(addr_text), "%d", (int)i2ctools->sniffer->menu_index + 1);
-    canvas_draw_str_aligned(canvas, 90, 13, AlignLeft, AlignTop, addr_text);
-    canvas_draw_str_aligned(canvas, 100, 13, AlignLeft, AlignTop, "/");
-    snprintf(addr_text, sizeof(addr_text), "%d", (int)i2ctools->sniffer->frame_index + 1);
-    canvas_draw_str_aligned(canvas, 110, 13, AlignLeft, AlignTop, addr_text);
-    // Frames content
-    uint8_t x_pos = 0;
-    uint8_t y_pos = 23;
-    for(uint8_t i = 1; i < i2ctools->sniffer->frames[i2ctools->sniffer->menu_index].data_index;
-        i++) {
-        snprintf(
-            addr_text,
-            sizeof(addr_text),
-            "0x%02x",
-            (int)i2ctools->sniffer->frames[i2ctools->sniffer->menu_index].data[i]);
-        x_pos = 50 + (i - 1) * 35;
-        canvas_draw_str_aligned(canvas, x_pos, y_pos, AlignLeft, AlignTop, addr_text);
-        if(i2ctools->sniffer->frames[i2ctools->sniffer->menu_index].ack[i]) {
-            canvas_draw_str_aligned(canvas, x_pos + 24, y_pos, AlignLeft, AlignTop, "A");
-        } else {
-            canvas_draw_str_aligned(canvas, x_pos + 24, y_pos, AlignLeft, AlignTop, "N");
-        }
-    }
-}
-
-void i2ctools_draw_record_view(Canvas* canvas, i2cTools* i2ctools) {
-    UNUSED(i2ctools);
-    canvas_clear(canvas);
-    canvas_set_color(canvas, ColorBlack);
-    canvas_draw_rframe(canvas, 0, 0, 128, 64, 3);
-    canvas_draw_icon(canvas, 2, 13, &I_passport_happy2_46x49);
-
-    canvas_set_font(canvas, FontPrimary);
-    canvas_draw_str_aligned(canvas, 3, 3, AlignLeft, AlignTop, PLAY_MENU_TEXT);
-}
-
-void i2ctools_draw_send_view(Canvas* canvas, i2cTools* i2ctools) {
-    canvas_clear(canvas);
-    canvas_set_color(canvas, ColorBlack);
-    canvas_draw_rframe(canvas, 0, 0, 128, 64, 3);
-    canvas_draw_icon(canvas, 2, 13, &I_passport_happy2_46x49);
-    canvas_set_font(canvas, FontPrimary);
-    canvas_draw_str_aligned(canvas, 3, 3, AlignLeft, AlignTop, SEND_MENU_TEXT);
-
-    if(!i2ctools->scanner->scanned) {
-        scan_i2c_bus(i2ctools->scanner);
-    }
-
-    canvas_set_font(canvas, FontSecondary);
-    if(i2ctools->scanner->nb_found <= 0) {
-        canvas_draw_str_aligned(canvas, 60, 5, AlignLeft, AlignTop, "No peripherals");
-        canvas_draw_str_aligned(canvas, 60, 15, AlignLeft, AlignTop, "Found");
-        return;
-    }
-    canvas_draw_rbox(canvas, 70, 48, 45, 13, 3);
-    canvas_set_color(canvas, ColorWhite);
-    canvas_draw_icon(canvas, 75, 50, &I_Ok_btn_9x9);
-    canvas_draw_str_aligned(canvas, 85, 51, AlignLeft, AlignTop, "Send");
-    canvas_set_color(canvas, ColorBlack);
-    canvas_draw_str_aligned(canvas, 50, 5, AlignLeft, AlignTop, "Addr: ");
-    canvas_draw_icon(canvas, 80, 5, &I_ButtonLeft_4x7);
-    canvas_draw_icon(canvas, 115, 5, &I_ButtonRight_4x7);
-    char addr_text[8];
-    snprintf(
-        addr_text,
-        sizeof(addr_text),
-        "0x%02x",
-        (int)i2ctools->scanner->addresses[i2ctools->sender->address_idx]);
-    canvas_draw_str_aligned(canvas, 90, 5, AlignLeft, AlignTop, addr_text);
-    canvas_draw_str_aligned(canvas, 50, 15, AlignLeft, AlignTop, "Value: ");
-
-    canvas_draw_icon(canvas, 80, 17, &I_ButtonUp_7x4);
-    canvas_draw_icon(canvas, 115, 17, &I_ButtonDown_7x4);
-    snprintf(addr_text, sizeof(addr_text), "0x%02x", (int)i2ctools->sender->value);
-    canvas_draw_str_aligned(canvas, 90, 15, AlignLeft, AlignTop, addr_text);
-    if(i2ctools->sender->must_send) {
-        i2c_send(i2ctools->sender);
-    }
-    canvas_draw_str_aligned(canvas, 50, 25, AlignLeft, AlignTop, "Result: ");
-    if(i2ctools->sender->sended) {
-        for(uint8_t i = 0; i < sizeof(i2ctools->sender->recv); i++) {
-            snprintf(addr_text, sizeof(addr_text), "0x%02x", (int)i2ctools->sender->recv[i]);
-            canvas_draw_str_aligned(canvas, 90, 25 + (i * 10), AlignLeft, AlignTop, addr_text);
-        }
-    }
-}
-
-void i2ctools_draw_scan_view(Canvas* canvas, i2cTools* i2ctools) {
-    canvas_clear(canvas);
-    canvas_set_color(canvas, ColorBlack);
-    canvas_draw_rframe(canvas, 0, 0, 128, 64, 3);
-    canvas_draw_icon(canvas, 2, 13, &I_passport_happy3_46x49);
-    canvas_set_font(canvas, FontPrimary);
-    canvas_draw_str_aligned(canvas, 3, 3, AlignLeft, AlignTop, SCAN_MENU_TEXT);
-
-    char count_text[46];
-    char count_text_fmt[] = "Found: %d";
-    canvas_set_font(canvas, FontSecondary);
-    snprintf(count_text, sizeof(count_text), count_text_fmt, (int)i2ctools->scanner->nb_found);
-    canvas_draw_str_aligned(canvas, 50, 3, AlignLeft, AlignTop, count_text);
-    uint8_t x_pos = 0;
-    uint8_t y_pos = 0;
-    uint8_t idx_to_print = 0;
-    for(uint8_t i = 0; i < (int)i2ctools->scanner->nb_found; i++) {
-        idx_to_print = i + i2ctools->scanner->menu_index * 3;
-        if(idx_to_print >= MAX_I2C_ADDR) {
-            break;
-        }
-        snprintf(
-            count_text,
-            sizeof(count_text),
-            "0x%02x ",
-            (int)i2ctools->scanner->addresses[idx_to_print]);
-        if(i < 3) {
-            x_pos = 50 + (i * 26);
-            y_pos = 15;
-        } else if(i < 6) {
-            x_pos = 50 + ((i - 3) * 26);
-            y_pos = 25;
-        } else if(i < 9) {
-            x_pos = 50 + ((i - 6) * 26);
-            y_pos = 35;
-        } else if(i < 12) {
-            x_pos = 50 + ((i - 9) * 26);
-            y_pos = 45;
-        } else if(i < 15) {
-            x_pos = 50 + ((i - 12) * 26);
-            y_pos = 55;
-        } else {
-            break;
-        }
-        canvas_draw_str_aligned(canvas, x_pos, y_pos, AlignLeft, AlignTop, count_text);
-    }
-    // Right cursor
-    y_pos = 14 + i2ctools->scanner->menu_index;
-    canvas_draw_rbox(canvas, 125, y_pos, 3, 10, 1);
-
-    // Button
-    canvas_draw_rbox(canvas, 70, 48, 45, 13, 3);
-    canvas_set_color(canvas, ColorWhite);
-    canvas_draw_icon(canvas, 75, 50, &I_Ok_btn_9x9);
-    canvas_draw_str_aligned(canvas, 85, 51, AlignLeft, AlignTop, "Scan");
-}
-
 void i2ctools_draw_callback(Canvas* canvas, void* ctx) {
-    i2cTools* i2c_addr = acquire_mutex((ValueMutex*)ctx, 25);
+    i2cTools* i2ctools = acquire_mutex((ValueMutex*)ctx, 25);
 
-    switch(i2c_addr->current_menu) {
+    switch(i2ctools->main_view->current_view) {
     case MAIN_VIEW:
-        i2ctools_draw_main_menu(canvas, i2c_addr);
+        draw_main_view(canvas, i2ctools->main_view);
         break;
 
     case SCAN_VIEW:
-        i2ctools_draw_scan_view(canvas, i2c_addr);
+        draw_scanner_view(canvas, i2ctools->scanner);
         break;
 
     case SNIFF_VIEW:
-        i2ctools_draw_sniff_view(canvas, i2c_addr);
+        draw_sniffer_view(canvas, i2ctools->sniffer);
         break;
+
     case SEND_VIEW:
-        i2ctools_draw_send_view(canvas, i2c_addr);
-        break;
-    case PLAY_VIEW:
-        i2ctools_draw_record_view(canvas, i2c_addr);
+        draw_sender_view(canvas, i2ctools->sender);
         break;
+
     default:
         break;
     }
-    release_mutex((ValueMutex*)ctx, i2c_addr);
+    release_mutex((ValueMutex*)ctx, i2ctools);
 }
 
 void i2ctools_input_callback(InputEvent* input_event, void* ctx) {
@@ -330,6 +56,8 @@ int32_t i2ctools_app(void* p) {
 
     InputEvent event;
 
+    i2ctools->main_view = i2c_main_view_alloc();
+
     i2ctools->sniffer = i2c_sniffer_alloc();
     i2ctools->sniffer->menu_index = 0;
 
@@ -341,26 +69,26 @@ int32_t i2ctools_app(void* p) {
 
     while(furi_message_queue_get(event_queue, &event, FuriWaitForever) == FuriStatusOk) {
         if(event.key == InputKeyBack && event.type == InputTypeRelease) {
-            if(i2ctools->current_menu == MAIN_VIEW) {
+            if(i2ctools->main_view->current_view == MAIN_VIEW) {
                 break;
             } else {
-                if(i2ctools->current_menu == SNIFF_VIEW) {
+                if(i2ctools->main_view->current_view == SNIFF_VIEW) {
                     stop_interrupts();
                     i2ctools->sniffer->started = false;
                     i2ctools->sniffer->state = I2C_BUS_FREE;
                 }
-                i2ctools->current_menu = MAIN_VIEW;
+                i2ctools->main_view->current_view = MAIN_VIEW;
             }
         } else if(event.key == InputKeyUp && event.type == InputTypeRelease) {
-            if(i2ctools->current_menu == MAIN_VIEW) {
-                if(i2ctools->main_menu_index > 0) {
-                    i2ctools->main_menu_index--;
+            if(i2ctools->main_view->current_view == MAIN_VIEW) {
+                if((i2ctools->main_view->menu_index > SCAN_VIEW)) {
+                    i2ctools->main_view->menu_index--;
                 }
-            } else if(i2ctools->current_menu == SCAN_VIEW) {
+            } else if(i2ctools->main_view->current_view == SCAN_VIEW) {
                 if(i2ctools->scanner->menu_index > 0) {
                     i2ctools->scanner->menu_index--;
                 }
-            } else if(i2ctools->current_menu == SEND_VIEW) {
+            } else if(i2ctools->main_view->current_view == SEND_VIEW) {
                 if(i2ctools->sender->value < 0xFF) {
                     i2ctools->sender->value++;
                     i2ctools->sender->sended = false;
@@ -369,29 +97,29 @@ int32_t i2ctools_app(void* p) {
         } else if(
             event.key == InputKeyUp &&
             (event.type == InputTypeLong || event.type == InputTypeRepeat)) {
-            if(i2ctools->current_menu == SEND_VIEW) {
+            if(i2ctools->main_view->current_view == SEND_VIEW) {
                 if(i2ctools->sender->value < 0xF9) {
                     i2ctools->sender->value += 5;
                     i2ctools->sender->sended = false;
                 }
             }
         } else if(event.key == InputKeyDown && event.type == InputTypeRelease) {
-            if(i2ctools->current_menu == MAIN_VIEW) {
-                if(i2ctools->main_menu_index < 3) {
-                    i2ctools->main_menu_index++;
+            if(i2ctools->main_view->current_view == MAIN_VIEW) {
+                if(i2ctools->main_view->menu_index < MENU_SIZE) {
+                    i2ctools->main_view->menu_index++;
                 }
-            } else if(i2ctools->current_menu == SCAN_VIEW) {
+            } else if(i2ctools->main_view->current_view == SCAN_VIEW) {
                 if(i2ctools->scanner->menu_index < ((int)i2ctools->scanner->nb_found / 3)) {
                     i2ctools->scanner->menu_index++;
                 }
-            } else if(i2ctools->current_menu == SEND_VIEW) {
+            } else if(i2ctools->main_view->current_view == SEND_VIEW) {
                 if(i2ctools->sender->value > 0x00) {
                     i2ctools->sender->value--;
                     i2ctools->sender->sended = false;
                 }
             }
         } else if(event.key == InputKeyDown && event.type == InputTypeLong) {
-            if(i2ctools->current_menu == SEND_VIEW) {
+            if(i2ctools->main_view->current_view == SEND_VIEW) {
                 if(i2ctools->sender->value > 0x05) {
                     i2ctools->sender->value -= 5;
                     i2ctools->sender->sended = false;
@@ -399,22 +127,13 @@ int32_t i2ctools_app(void* p) {
             }
 
         } else if(event.key == InputKeyOk && event.type == InputTypeRelease) {
-            if(i2ctools->current_menu == MAIN_VIEW) {
-                if(i2ctools->main_menu_index == 0) {
-                    scan_i2c_bus(i2ctools->scanner);
-                    i2ctools->current_menu = SCAN_VIEW;
-                } else if(i2ctools->main_menu_index == 1) {
-                    i2ctools->current_menu = SNIFF_VIEW;
-                } else if(i2ctools->main_menu_index == 2) {
-                    i2ctools->current_menu = SEND_VIEW;
-                } else if(i2ctools->main_menu_index == 3) {
-                    i2ctools->current_menu = PLAY_VIEW;
-                }
-            } else if(i2ctools->current_menu == SCAN_VIEW) {
+            if(i2ctools->main_view->current_view == MAIN_VIEW) {
+                i2ctools->main_view->current_view = i2ctools->main_view->menu_index;
+            } else if(i2ctools->main_view->current_view == SCAN_VIEW) {
                 scan_i2c_bus(i2ctools->scanner);
-            } else if(i2ctools->current_menu == SEND_VIEW) {
+            } else if(i2ctools->main_view->current_view == SEND_VIEW) {
                 i2ctools->sender->must_send = true;
-            } else if(i2ctools->current_menu == SNIFF_VIEW) {
+            } else if(i2ctools->main_view->current_view == SNIFF_VIEW) {
                 if(i2ctools->sniffer->started) {
                     stop_interrupts();
                     i2ctools->sniffer->started = false;
@@ -426,23 +145,23 @@ int32_t i2ctools_app(void* p) {
                 }
             }
         } else if(event.key == InputKeyRight && event.type == InputTypeRelease) {
-            if(i2ctools->current_menu == SEND_VIEW) {
+            if(i2ctools->main_view->current_view == SEND_VIEW) {
                 if(i2ctools->sender->address_idx < (i2ctools->scanner->nb_found - 1)) {
                     i2ctools->sender->address_idx++;
                     i2ctools->sender->sended = false;
                 }
-            } else if(i2ctools->current_menu == SNIFF_VIEW) {
+            } else if(i2ctools->main_view->current_view == SNIFF_VIEW) {
                 if(i2ctools->sniffer->menu_index < i2ctools->sniffer->frame_index) {
                     i2ctools->sniffer->menu_index++;
                 }
             }
         } else if(event.key == InputKeyLeft && event.type == InputTypeRelease) {
-            if(i2ctools->current_menu == SEND_VIEW) {
+            if(i2ctools->main_view->current_view == SEND_VIEW) {
                 if(i2ctools->sender->address_idx > 0) {
                     i2ctools->sender->address_idx--;
                     i2ctools->sender->sended = false;
                 }
-            } else if(i2ctools->current_menu == SNIFF_VIEW) {
+            } else if(i2ctools->main_view->current_view == SNIFF_VIEW) {
                 if(i2ctools->sniffer->menu_index > 0) {
                     i2ctools->sniffer->menu_index--;
                 }
@@ -456,6 +175,7 @@ int32_t i2ctools_app(void* p) {
     i2c_sniffer_free(i2ctools->sniffer);
     i2c_scanner_free(i2ctools->scanner);
     i2c_sender_free(i2ctools->sender);
+    i2c_main_view_free(i2ctools->main_view);
     free(i2ctools);
     furi_record_close(RECORD_GUI);
     return 0;

+ 5 - 14
i2ctools_i.h

@@ -6,24 +6,15 @@
 #include "i2csniffer.h"
 #include "i2cscanner.h"
 #include "i2csender.h"
-
-// Menu
-typedef enum {
-    MAIN_VIEW,
-    SCAN_VIEW,
-    SNIFF_VIEW,
-    SEND_VIEW,
-    PLAY_VIEW,
-
-    /* Know menu Size*/
-    MENU_SIZE
-} i2cToolsMainMenu;
+#include "views/main_view.h"
+#include "views/sniffer_view.h"
+#include "views/scanner_view.h"
+#include "views/sender_view.h"
 
 // App datas
 typedef struct {
     ViewPort* view_port;
-    i2cToolsMainMenu current_menu;
-    uint8_t main_menu_index;
+    i2cMainView* main_view;
 
     i2cScanner* scanner;
     i2cSniffer* sniffer;

+ 63 - 0
views/main_view.c

@@ -0,0 +1,63 @@
+#include "main_view.h"
+
+void draw_main_view(Canvas* canvas, i2cMainView* main_view) {
+    canvas_clear(canvas);
+    canvas_set_color(canvas, ColorBlack);
+    canvas_draw_rframe(canvas, 0, 0, 128, 64, 3);
+    canvas_draw_icon(canvas, 2, 13, &I_passport_bad3_46x49);
+    canvas_set_font(canvas, FontPrimary);
+    canvas_draw_str_aligned(canvas, 3, 3, AlignLeft, AlignTop, APP_NAME);
+
+    switch(main_view->menu_index) {
+    case SCAN_VIEW:
+        canvas_set_color(canvas, ColorBlack);
+        canvas_draw_str_aligned(
+            canvas, SNIFF_MENU_X, SNIFF_MENU_Y, AlignLeft, AlignTop, SNIFF_MENU_TEXT);
+        canvas_draw_str_aligned(
+            canvas, SEND_MENU_X, SEND_MENU_Y, AlignLeft, AlignTop, SEND_MENU_TEXT);
+        canvas_draw_rbox(canvas, 60, SCAN_MENU_Y - 2, 60, 13, 3);
+        canvas_set_color(canvas, ColorWhite);
+        canvas_draw_str_aligned(
+            canvas, SCAN_MENU_X, SCAN_MENU_Y, AlignLeft, AlignTop, SCAN_MENU_TEXT);
+        break;
+
+    case SNIFF_VIEW:
+        canvas_set_color(canvas, ColorBlack);
+        canvas_draw_str_aligned(
+            canvas, SCAN_MENU_X, SCAN_MENU_Y, AlignLeft, AlignTop, SCAN_MENU_TEXT);
+        canvas_draw_str_aligned(
+            canvas, SEND_MENU_X, SEND_MENU_Y, AlignLeft, AlignTop, SEND_MENU_TEXT);
+        canvas_draw_rbox(canvas, 60, SNIFF_MENU_Y - 2, 60, 13, 3);
+        canvas_set_color(canvas, ColorWhite);
+        canvas_draw_str_aligned(
+            canvas, SNIFF_MENU_X, SNIFF_MENU_Y, AlignLeft, AlignTop, SNIFF_MENU_TEXT);
+        break;
+
+    case SEND_VIEW:
+        canvas_set_color(canvas, ColorBlack);
+        canvas_draw_str_aligned(
+            canvas, SCAN_MENU_X, SCAN_MENU_Y, AlignLeft, AlignTop, SCAN_MENU_TEXT);
+        canvas_draw_str_aligned(
+            canvas, SNIFF_MENU_X, SNIFF_MENU_Y, AlignLeft, AlignTop, SNIFF_MENU_TEXT);
+        canvas_draw_rbox(canvas, 60, SEND_MENU_Y - 2, 60, 13, 3);
+        canvas_set_color(canvas, ColorWhite);
+        canvas_draw_str_aligned(
+            canvas, SEND_MENU_X, SEND_MENU_Y, AlignLeft, AlignTop, SEND_MENU_TEXT);
+        break;
+
+    default:
+        break;
+    }
+}
+
+i2cMainView* i2c_main_view_alloc() {
+    i2cMainView* main_view = malloc(sizeof(i2cMainView));
+    main_view->menu_index = SCAN_VIEW;
+    main_view->current_view = MAIN_VIEW;
+    return main_view;
+}
+
+void i2c_main_view_free(i2cMainView* main_view) {
+    furi_assert(main_view);
+    free(main_view);
+}

+ 38 - 0
views/main_view.h

@@ -0,0 +1,38 @@
+#include <furi.h>
+#include <furi_hal.h>
+#include <gui/gui.h>
+
+#define APP_NAME "I2C Tools"
+
+#define SCAN_MENU_TEXT "Scan"
+#define SCAN_MENU_X 75
+#define SCAN_MENU_Y 6
+
+#define SNIFF_MENU_TEXT "Sniff"
+#define SNIFF_MENU_X 75
+#define SNIFF_MENU_Y 20
+
+#define SEND_MENU_TEXT "Send"
+#define SEND_MENU_X 75
+#define SEND_MENU_Y 34
+
+// Menu
+typedef enum {
+    MAIN_VIEW,
+    SCAN_VIEW,
+    SNIFF_VIEW,
+    SEND_VIEW,
+
+    /* Know menu Size*/
+    MENU_SIZE
+} i2cToolsViews;
+
+typedef struct {
+    i2cToolsViews current_view;
+    i2cToolsViews menu_index;
+} i2cMainView;
+
+void draw_main_view(Canvas* canvas, i2cMainView* main_view);
+
+i2cMainView* i2c_main_view_alloc();
+void i2c_main_view_free(i2cMainView* main_view);

+ 55 - 0
views/scanner_view.c

@@ -0,0 +1,55 @@
+#include "scanner_view.h"
+
+void draw_scanner_view(Canvas* canvas, i2cScanner* i2c_scanner) {
+    canvas_clear(canvas);
+    canvas_set_color(canvas, ColorBlack);
+    canvas_draw_rframe(canvas, 0, 0, 128, 64, 3);
+    canvas_draw_icon(canvas, 2, 13, &I_passport_happy3_46x49);
+    canvas_set_font(canvas, FontPrimary);
+    canvas_draw_str_aligned(canvas, 3, 3, AlignLeft, AlignTop, SCAN_MENU_TEXT);
+
+    char count_text[46];
+    char count_text_fmt[] = "Found: %d";
+    canvas_set_font(canvas, FontSecondary);
+    snprintf(count_text, sizeof(count_text), count_text_fmt, (int)i2c_scanner->nb_found);
+    canvas_draw_str_aligned(canvas, 50, 3, AlignLeft, AlignTop, count_text);
+    uint8_t x_pos = 0;
+    uint8_t y_pos = 0;
+    uint8_t idx_to_print = 0;
+    for(uint8_t i = 0; i < (int)i2c_scanner->nb_found; i++) {
+        idx_to_print = i + i2c_scanner->menu_index * 3;
+        if(idx_to_print >= MAX_I2C_ADDR) {
+            break;
+        }
+        snprintf(
+            count_text, sizeof(count_text), "0x%02x ", (int)i2c_scanner->addresses[idx_to_print]);
+        if(i < 3) {
+            x_pos = 50 + (i * 26);
+            y_pos = 15;
+        } else if(i < 6) {
+            x_pos = 50 + ((i - 3) * 26);
+            y_pos = 25;
+        } else if(i < 9) {
+            x_pos = 50 + ((i - 6) * 26);
+            y_pos = 35;
+        } else if(i < 12) {
+            x_pos = 50 + ((i - 9) * 26);
+            y_pos = 45;
+        } else if(i < 15) {
+            x_pos = 50 + ((i - 12) * 26);
+            y_pos = 55;
+        } else {
+            break;
+        }
+        canvas_draw_str_aligned(canvas, x_pos, y_pos, AlignLeft, AlignTop, count_text);
+    }
+    // Right cursor
+    y_pos = 14 + i2c_scanner->menu_index;
+    canvas_draw_rbox(canvas, 125, y_pos, 3, 10, 1);
+
+    // Button
+    canvas_draw_rbox(canvas, 70, 48, 45, 13, 3);
+    canvas_set_color(canvas, ColorWhite);
+    canvas_draw_icon(canvas, 75, 50, &I_Ok_btn_9x9);
+    canvas_draw_str_aligned(canvas, 85, 51, AlignLeft, AlignTop, "Scan");
+}

+ 11 - 0
views/scanner_view.h

@@ -0,0 +1,11 @@
+#include <furi.h>
+#include <furi_hal.h>
+#include <gui/gui.h>
+
+#include "../i2cscanner.h"
+
+#define SCAN_MENU_TEXT "Scan"
+#define SCAN_MENU_X 75
+#define SCAN_MENU_Y 6
+
+void draw_scanner_view(Canvas* canvas, i2cScanner* i2c_scanner);

+ 52 - 0
views/sender_view.c

@@ -0,0 +1,52 @@
+#include "sender_view.h"
+
+void draw_sender_view(Canvas* canvas, i2cSender* i2c_sender) {
+    canvas_clear(canvas);
+    canvas_set_color(canvas, ColorBlack);
+    canvas_draw_rframe(canvas, 0, 0, 128, 64, 3);
+    canvas_draw_icon(canvas, 2, 13, &I_passport_happy2_46x49);
+    canvas_set_font(canvas, FontPrimary);
+    canvas_draw_str_aligned(canvas, 3, 3, AlignLeft, AlignTop, SEND_MENU_TEXT);
+
+    if(!i2c_sender->scanner->scanned) {
+        scan_i2c_bus(i2c_sender->scanner);
+    }
+
+    canvas_set_font(canvas, FontSecondary);
+    if(i2c_sender->scanner->nb_found <= 0) {
+        canvas_draw_str_aligned(canvas, 60, 5, AlignLeft, AlignTop, "No peripherals");
+        canvas_draw_str_aligned(canvas, 60, 15, AlignLeft, AlignTop, "Found");
+        return;
+    }
+    canvas_draw_rbox(canvas, 70, 48, 45, 13, 3);
+    canvas_set_color(canvas, ColorWhite);
+    canvas_draw_icon(canvas, 75, 50, &I_Ok_btn_9x9);
+    canvas_draw_str_aligned(canvas, 85, 51, AlignLeft, AlignTop, "Send");
+    canvas_set_color(canvas, ColorBlack);
+    canvas_draw_str_aligned(canvas, 50, 5, AlignLeft, AlignTop, "Addr: ");
+    canvas_draw_icon(canvas, 80, 5, &I_ButtonLeft_4x7);
+    canvas_draw_icon(canvas, 115, 5, &I_ButtonRight_4x7);
+    char addr_text[8];
+    snprintf(
+        addr_text,
+        sizeof(addr_text),
+        "0x%02x",
+        (int)i2c_sender->scanner->addresses[i2c_sender->address_idx]);
+    canvas_draw_str_aligned(canvas, 90, 5, AlignLeft, AlignTop, addr_text);
+    canvas_draw_str_aligned(canvas, 50, 15, AlignLeft, AlignTop, "Value: ");
+
+    canvas_draw_icon(canvas, 80, 17, &I_ButtonUp_7x4);
+    canvas_draw_icon(canvas, 115, 17, &I_ButtonDown_7x4);
+    snprintf(addr_text, sizeof(addr_text), "0x%02x", (int)i2c_sender->value);
+    canvas_draw_str_aligned(canvas, 90, 15, AlignLeft, AlignTop, addr_text);
+    if(i2c_sender->must_send) {
+        i2c_send(i2c_sender);
+    }
+    canvas_draw_str_aligned(canvas, 50, 25, AlignLeft, AlignTop, "Result: ");
+    if(i2c_sender->sended) {
+        for(uint8_t i = 0; i < sizeof(i2c_sender->recv); i++) {
+            snprintf(addr_text, sizeof(addr_text), "0x%02x", (int)i2c_sender->recv[i]);
+            canvas_draw_str_aligned(canvas, 90, 25 + (i * 10), AlignLeft, AlignTop, addr_text);
+        }
+    }
+}

+ 11 - 0
views/sender_view.h

@@ -0,0 +1,11 @@
+#include <furi.h>
+#include <furi_hal.h>
+#include <gui/gui.h>
+
+#include "../i2csender.h"
+
+#define SEND_MENU_TEXT "Send"
+#define SEND_MENU_X 75
+#define SEND_MENU_Y 34
+
+void draw_sender_view(Canvas* canvas, i2cSender* i2c_sender);

+ 62 - 0
views/sniffer_view.c

@@ -0,0 +1,62 @@
+#include "sniffer_view.h"
+
+void draw_sniffer_view(Canvas* canvas, i2cSniffer* i2c_sniffer) {
+    canvas_clear(canvas);
+    canvas_set_color(canvas, ColorBlack);
+    canvas_draw_rframe(canvas, 0, 0, 128, 64, 3);
+    canvas_draw_icon(canvas, 2, 13, &I_passport_happy2_46x49);
+
+    canvas_set_font(canvas, FontPrimary);
+    canvas_draw_str_aligned(canvas, 3, 3, AlignLeft, AlignTop, SNIFF_MENU_TEXT);
+    canvas_set_font(canvas, FontSecondary);
+
+    // Button
+    canvas_draw_rbox(canvas, 70, 48, 45, 13, 3);
+    canvas_set_color(canvas, ColorWhite);
+    canvas_draw_icon(canvas, 75, 50, &I_Ok_btn_9x9);
+    if(!i2c_sniffer->started) {
+        canvas_draw_str_aligned(canvas, 85, 51, AlignLeft, AlignTop, "Start");
+    } else {
+        canvas_draw_str_aligned(canvas, 85, 51, AlignLeft, AlignTop, "Stop");
+    }
+    canvas_set_color(canvas, ColorBlack);
+    // Address text
+    char addr_text[8];
+    snprintf(
+        addr_text,
+        sizeof(addr_text),
+        "0x%02x",
+        (int)(i2c_sniffer->frames[i2c_sniffer->menu_index].data[0] >> 1));
+    canvas_draw_str_aligned(canvas, 50, 3, AlignLeft, AlignTop, "Addr: ");
+    canvas_draw_str_aligned(canvas, 75, 3, AlignLeft, AlignTop, addr_text);
+    // R/W
+    if((int)(i2c_sniffer->frames[i2c_sniffer->menu_index].data[0]) % 2 == 0) {
+        canvas_draw_str_aligned(canvas, 105, 3, AlignLeft, AlignTop, "W");
+    } else {
+        canvas_draw_str_aligned(canvas, 105, 3, AlignLeft, AlignTop, "R");
+    }
+    // nbFrame text
+    canvas_draw_str_aligned(canvas, 50, 13, AlignLeft, AlignTop, "Frames: ");
+    snprintf(addr_text, sizeof(addr_text), "%d", (int)i2c_sniffer->menu_index + 1);
+    canvas_draw_str_aligned(canvas, 90, 13, AlignLeft, AlignTop, addr_text);
+    canvas_draw_str_aligned(canvas, 100, 13, AlignLeft, AlignTop, "/");
+    snprintf(addr_text, sizeof(addr_text), "%d", (int)i2c_sniffer->frame_index + 1);
+    canvas_draw_str_aligned(canvas, 110, 13, AlignLeft, AlignTop, addr_text);
+    // Frames content
+    uint8_t x_pos = 0;
+    uint8_t y_pos = 23;
+    for(uint8_t i = 1; i < i2c_sniffer->frames[i2c_sniffer->menu_index].data_index; i++) {
+        snprintf(
+            addr_text,
+            sizeof(addr_text),
+            "0x%02x",
+            (int)i2c_sniffer->frames[i2c_sniffer->menu_index].data[i]);
+        x_pos = 50 + (i - 1) * 35;
+        canvas_draw_str_aligned(canvas, x_pos, y_pos, AlignLeft, AlignTop, addr_text);
+        if(i2c_sniffer->frames[i2c_sniffer->menu_index].ack[i]) {
+            canvas_draw_str_aligned(canvas, x_pos + 24, y_pos, AlignLeft, AlignTop, "A");
+        } else {
+            canvas_draw_str_aligned(canvas, x_pos + 24, y_pos, AlignLeft, AlignTop, "N");
+        }
+    }
+}

+ 11 - 0
views/sniffer_view.h

@@ -0,0 +1,11 @@
+#include <furi.h>
+#include <furi_hal.h>
+#include <gui/gui.h>
+
+#include "../i2csniffer.h"
+
+#define SNIFF_MENU_TEXT "Sniff"
+#define SNIFF_MENU_X 75
+#define SNIFF_MENU_Y 20
+
+void draw_sniffer_view(Canvas* canvas, i2cSniffer* i2c_sniffer);