|
| 1 | +#include <gui/elements.h> |
| 2 | +#include "gpio_i2c_scanner.h" |
| 3 | +#include "../gpio_item.h" |
| 4 | + |
| 5 | +#include <string.h> |
| 6 | + |
| 7 | + |
| 8 | +struct GpioI2CScanner { |
| 9 | + View* view; |
| 10 | + GpioI2CScannerOkCallback callback; |
| 11 | + void* context; |
| 12 | +}; |
| 13 | + |
| 14 | +typedef struct { |
| 15 | + uint8_t items; |
| 16 | + uint8_t responding_address[AVAILABLE_NONRESVERED_I2C_ADDRESSES]; |
| 17 | +} GpioI2CScannerModel; |
| 18 | + |
| 19 | +static bool gpio_i2c_scanner_process_ok(GpioI2CScanner* gpio_i2c_scanner, InputEvent* event); |
| 20 | + |
| 21 | +static void gpio_i2c_scanner_draw_callback(Canvas* canvas, void* _model) { |
| 22 | + GpioI2CScannerModel* model = _model; |
| 23 | + |
| 24 | + char temp_str[25]; |
| 25 | + elements_button_center(canvas, "Start scan"); |
| 26 | + canvas_draw_line(canvas, 2, 10, 125, 10); |
| 27 | + canvas_draw_line(canvas, 2, 52, 125, 52); |
| 28 | + |
| 29 | + canvas_set_font(canvas, FontPrimary); |
| 30 | + canvas_draw_str(canvas, 2, 9, "I2C-Scanner"); |
| 31 | + canvas_draw_str(canvas, 3, 25, "SDA:"); |
| 32 | + canvas_draw_str(canvas, 3, 42, "SCL:"); |
| 33 | + |
| 34 | + canvas_set_font(canvas, FontSecondary); |
| 35 | + snprintf(temp_str, 25, "Slaves: %u", model->items); |
| 36 | + canvas_draw_str_aligned(canvas, 126, 8, AlignRight, AlignBottom, temp_str); |
| 37 | + |
| 38 | + canvas_draw_str(canvas, 29, 25, "Pin 15"); |
| 39 | + canvas_draw_str(canvas, 29, 42, "Pin 16"); |
| 40 | + |
| 41 | + canvas_set_font(canvas, FontSecondary); |
| 42 | + |
| 43 | + char temp_str2[6]; |
| 44 | + if(model->items > 0) { |
| 45 | + snprintf(temp_str, 25, "Addr: " ); |
| 46 | + for(int i = 0; i< model->items; i++){ |
| 47 | + snprintf(temp_str2, 6, "0x%x ", model->responding_address[i]); |
| 48 | + strcat (temp_str, temp_str2); |
| 49 | + |
| 50 | + if(i == 1 || model->items == 1) { //Draw a maximum of two addresses in the first line |
| 51 | + canvas_draw_str_aligned(canvas, 127, 24, AlignRight, AlignBottom, temp_str); |
| 52 | + temp_str[0] = '\0'; |
| 53 | + } |
| 54 | + else if(i == 4 || (model->items-1 == i && i<6 )) { //Draw a maximum of three addresses in the second line |
| 55 | + canvas_draw_str_aligned(canvas, 127, 36, AlignRight, AlignBottom, temp_str); |
| 56 | + temp_str[0] = '\0'; |
| 57 | + } |
| 58 | + else if(i == 7 || model->items-1 == i) { //Draw a maximum of three addresses in the third line |
| 59 | + canvas_draw_str_aligned(canvas, 127, 48, AlignRight, AlignBottom, temp_str); |
| 60 | + break; |
| 61 | + } |
| 62 | + } |
| 63 | + } |
| 64 | +} |
| 65 | + |
| 66 | +static bool gpio_i2c_scanner_input_callback(InputEvent* event, void* context) { |
| 67 | + furi_assert(context); |
| 68 | + GpioI2CScanner* gpio_i2c_scanner = context; |
| 69 | + bool consumed = false; |
| 70 | + |
| 71 | + if(event->key == InputKeyOk) { |
| 72 | + consumed = gpio_i2c_scanner_process_ok(gpio_i2c_scanner, event); |
| 73 | + } |
| 74 | + |
| 75 | + return consumed; |
| 76 | +} |
| 77 | + |
| 78 | +static bool gpio_i2c_scanner_process_ok(GpioI2CScanner* gpio_i2c_scanner, InputEvent* event) { |
| 79 | + bool consumed = false; |
| 80 | + gpio_i2c_scanner->callback(event->type, gpio_i2c_scanner->context); |
| 81 | + |
| 82 | + return consumed; |
| 83 | +} |
| 84 | + |
| 85 | +GpioI2CScanner* gpio_i2c_scanner_alloc() { |
| 86 | + GpioI2CScanner* gpio_i2c_scanner = malloc(sizeof(GpioI2CScanner)); |
| 87 | + |
| 88 | + gpio_i2c_scanner->view = view_alloc(); |
| 89 | + view_allocate_model(gpio_i2c_scanner->view, ViewModelTypeLocking, sizeof(GpioI2CScannerModel)); |
| 90 | + view_set_context(gpio_i2c_scanner->view, gpio_i2c_scanner); |
| 91 | + view_set_draw_callback(gpio_i2c_scanner->view, gpio_i2c_scanner_draw_callback); |
| 92 | + view_set_input_callback(gpio_i2c_scanner->view, gpio_i2c_scanner_input_callback); |
| 93 | + |
| 94 | + return gpio_i2c_scanner; |
| 95 | +} |
| 96 | + |
| 97 | +void gpio_i2c_scanner_free(GpioI2CScanner* gpio_i2c_scanner) { |
| 98 | + furi_assert(gpio_i2c_scanner); |
| 99 | + view_free(gpio_i2c_scanner->view); |
| 100 | + free(gpio_i2c_scanner); |
| 101 | +} |
| 102 | + |
| 103 | +View* gpio_i2c_scanner_get_view(GpioI2CScanner* gpio_i2c_scanner) { |
| 104 | + furi_assert(gpio_i2c_scanner); |
| 105 | + return gpio_i2c_scanner->view; |
| 106 | +} |
| 107 | + |
| 108 | +void gpio_i2c_scanner_set_ok_callback(GpioI2CScanner* gpio_i2c_scanner, GpioI2CScannerOkCallback callback, void* context) { |
| 109 | + furi_assert(gpio_i2c_scanner); |
| 110 | + furi_assert(callback); |
| 111 | + with_view_model( |
| 112 | + gpio_i2c_scanner->view, (GpioI2CScannerModel * model) { |
| 113 | + UNUSED(model); |
| 114 | + gpio_i2c_scanner->callback = callback; |
| 115 | + gpio_i2c_scanner->context = context; |
| 116 | + return false; |
| 117 | + }); |
| 118 | +} |
| 119 | + |
| 120 | +void gpio_i2c_scanner_update_state(GpioI2CScanner* instance, I2CScannerState* st) { |
| 121 | + furi_assert(instance); |
| 122 | + furi_assert(st); |
| 123 | + |
| 124 | + with_view_model( |
| 125 | + instance->view, (GpioI2CScannerModel * model) { |
| 126 | + model->items = st->items; |
| 127 | + |
| 128 | + for(int i =0; i<model->items; i++) { |
| 129 | + model->responding_address[i] = st->responding_address[i]; |
| 130 | + } |
| 131 | + |
| 132 | + return true; |
| 133 | + }); |
| 134 | +} |
| 135 | + |
| 136 | + |
0 commit comments