forked from flipperdevices/flipperzero-firmware
-
-
Notifications
You must be signed in to change notification settings - Fork 547
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #139 from GitChris3004/gpio_i2c_scanner
Gpio i2c scanner
- Loading branch information
Showing
10 changed files
with
253 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
#include "gpio_i2c_scanner_control.h" | ||
#include <furi_hal_delay.h> | ||
|
||
|
||
void gpio_i2c_scanner_run_once(I2CScannerState* i2c_scanner_state) { | ||
//Reset the number of items for rewriting the array | ||
i2c_scanner_state->items = 0; | ||
furi_hal_i2c_acquire(&furi_hal_i2c_handle_external); | ||
|
||
uint32_t response_timeout_ticks = furi_hal_ms_to_ticks(5.f); | ||
|
||
//Addresses 0 to 7 are reserved and won't be scanned | ||
for(int i = FIRST_NON_RESERVED_I2C_ADDRESS; i<=HIGHEST_I2C_ADDRESS; i++) { | ||
if(furi_hal_i2c_is_device_ready(&furi_hal_i2c_handle_external, i<<1, response_timeout_ticks)) {//Bitshift of 1 bit to convert 7-Bit Address into 8-Bit Address | ||
i2c_scanner_state->responding_address[i2c_scanner_state->items] = i; | ||
i2c_scanner_state->items++; | ||
} | ||
} | ||
|
||
furi_hal_i2c_release(&furi_hal_i2c_handle_external); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
#pragma once | ||
|
||
#include <stdint.h> | ||
#include <stdbool.h> | ||
|
||
#include <furi_hal_i2c.h> | ||
|
||
#define FIRST_NON_RESERVED_I2C_ADDRESS 8 | ||
#define HIGHEST_I2C_ADDRESS 127 | ||
#define AVAILABLE_NONRESVERED_I2C_ADDRESSES 120 | ||
|
||
typedef struct { | ||
uint8_t items; | ||
uint8_t responding_address[AVAILABLE_NONRESVERED_I2C_ADDRESSES]; | ||
} I2CScannerState; | ||
|
||
/** Scans the I2C-Bus (SDA: Pin 15, SCL: Pin 16) for available 7-Bit slave addresses. Saves the number of detected slaves and their addresses. | ||
* | ||
* @param i2c_scanner_state State including the detected addresses and the number of addresses saved. | ||
*/ | ||
void gpio_i2c_scanner_run_once(I2CScannerState* st); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
#include "../gpio_app_i.h" | ||
#include <furi_hal_gpio.h> | ||
|
||
static I2CScannerState* i2c_scanner_state; | ||
|
||
|
||
void gpio_scene_i2c_scanner_ok_callback(InputType type, void* context) { | ||
furi_assert(context); | ||
GpioApp* app = context; | ||
|
||
if(type == InputTypeRelease) { | ||
notification_message(app->notifications, &sequence_set_green_255); | ||
gpio_i2c_scanner_run_once(i2c_scanner_state); | ||
notification_message(app->notifications, &sequence_reset_green); | ||
gpio_i2c_scanner_update_state(app->gpio_i2c_scanner, i2c_scanner_state); | ||
} | ||
} | ||
|
||
void gpio_scene_i2c_scanner_on_enter(void* context) { | ||
GpioApp* app = context; | ||
i2c_scanner_state = malloc(sizeof(I2CScannerState)); | ||
|
||
gpio_i2c_scanner_set_ok_callback(app->gpio_i2c_scanner, gpio_scene_i2c_scanner_ok_callback, app); | ||
view_dispatcher_switch_to_view(app->view_dispatcher, GpioAppViewI2CScanner); | ||
} | ||
|
||
bool gpio_scene_i2c_scanner_on_event(void* context, SceneManagerEvent event) { | ||
UNUSED(context); | ||
UNUSED(event); | ||
return false; | ||
} | ||
|
||
void gpio_scene_i2c_scanner_on_exit(void* context) { | ||
UNUSED(context); | ||
free(i2c_scanner_state); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,136 @@ | ||
#include <gui/elements.h> | ||
#include "gpio_i2c_scanner.h" | ||
#include "../gpio_item.h" | ||
|
||
#include <string.h> | ||
|
||
|
||
struct GpioI2CScanner { | ||
View* view; | ||
GpioI2CScannerOkCallback callback; | ||
void* context; | ||
}; | ||
|
||
typedef struct { | ||
uint8_t items; | ||
uint8_t responding_address[AVAILABLE_NONRESVERED_I2C_ADDRESSES]; | ||
} GpioI2CScannerModel; | ||
|
||
static bool gpio_i2c_scanner_process_ok(GpioI2CScanner* gpio_i2c_scanner, InputEvent* event); | ||
|
||
static void gpio_i2c_scanner_draw_callback(Canvas* canvas, void* _model) { | ||
GpioI2CScannerModel* model = _model; | ||
|
||
char temp_str[25]; | ||
elements_button_center(canvas, "Start scan"); | ||
canvas_draw_line(canvas, 2, 10, 125, 10); | ||
canvas_draw_line(canvas, 2, 52, 125, 52); | ||
|
||
canvas_set_font(canvas, FontPrimary); | ||
canvas_draw_str(canvas, 2, 9, "I2C-Scanner"); | ||
canvas_draw_str(canvas, 3, 25, "SDA:"); | ||
canvas_draw_str(canvas, 3, 42, "SCL:"); | ||
|
||
canvas_set_font(canvas, FontSecondary); | ||
snprintf(temp_str, 25, "Slaves: %u", model->items); | ||
canvas_draw_str_aligned(canvas, 126, 8, AlignRight, AlignBottom, temp_str); | ||
|
||
canvas_draw_str(canvas, 29, 25, "Pin 15"); | ||
canvas_draw_str(canvas, 29, 42, "Pin 16"); | ||
|
||
canvas_set_font(canvas, FontSecondary); | ||
|
||
char temp_str2[6]; | ||
if(model->items > 0) { | ||
snprintf(temp_str, 25, "Addr: " ); | ||
for(int i = 0; i< model->items; i++){ | ||
snprintf(temp_str2, 6, "0x%x ", model->responding_address[i]); | ||
strcat (temp_str, temp_str2); | ||
|
||
if(i == 1 || model->items == 1) { //Draw a maximum of two addresses in the first line | ||
canvas_draw_str_aligned(canvas, 127, 24, AlignRight, AlignBottom, temp_str); | ||
temp_str[0] = '\0'; | ||
} | ||
else if(i == 4 || (model->items-1 == i && i<6 )) { //Draw a maximum of three addresses in the second line | ||
canvas_draw_str_aligned(canvas, 127, 36, AlignRight, AlignBottom, temp_str); | ||
temp_str[0] = '\0'; | ||
} | ||
else if(i == 7 || model->items-1 == i) { //Draw a maximum of three addresses in the third line | ||
canvas_draw_str_aligned(canvas, 127, 48, AlignRight, AlignBottom, temp_str); | ||
break; | ||
} | ||
} | ||
} | ||
} | ||
|
||
static bool gpio_i2c_scanner_input_callback(InputEvent* event, void* context) { | ||
furi_assert(context); | ||
GpioI2CScanner* gpio_i2c_scanner = context; | ||
bool consumed = false; | ||
|
||
if(event->key == InputKeyOk) { | ||
consumed = gpio_i2c_scanner_process_ok(gpio_i2c_scanner, event); | ||
} | ||
|
||
return consumed; | ||
} | ||
|
||
static bool gpio_i2c_scanner_process_ok(GpioI2CScanner* gpio_i2c_scanner, InputEvent* event) { | ||
bool consumed = false; | ||
gpio_i2c_scanner->callback(event->type, gpio_i2c_scanner->context); | ||
|
||
return consumed; | ||
} | ||
|
||
GpioI2CScanner* gpio_i2c_scanner_alloc() { | ||
GpioI2CScanner* gpio_i2c_scanner = malloc(sizeof(GpioI2CScanner)); | ||
|
||
gpio_i2c_scanner->view = view_alloc(); | ||
view_allocate_model(gpio_i2c_scanner->view, ViewModelTypeLocking, sizeof(GpioI2CScannerModel)); | ||
view_set_context(gpio_i2c_scanner->view, gpio_i2c_scanner); | ||
view_set_draw_callback(gpio_i2c_scanner->view, gpio_i2c_scanner_draw_callback); | ||
view_set_input_callback(gpio_i2c_scanner->view, gpio_i2c_scanner_input_callback); | ||
|
||
return gpio_i2c_scanner; | ||
} | ||
|
||
void gpio_i2c_scanner_free(GpioI2CScanner* gpio_i2c_scanner) { | ||
furi_assert(gpio_i2c_scanner); | ||
view_free(gpio_i2c_scanner->view); | ||
free(gpio_i2c_scanner); | ||
} | ||
|
||
View* gpio_i2c_scanner_get_view(GpioI2CScanner* gpio_i2c_scanner) { | ||
furi_assert(gpio_i2c_scanner); | ||
return gpio_i2c_scanner->view; | ||
} | ||
|
||
void gpio_i2c_scanner_set_ok_callback(GpioI2CScanner* gpio_i2c_scanner, GpioI2CScannerOkCallback callback, void* context) { | ||
furi_assert(gpio_i2c_scanner); | ||
furi_assert(callback); | ||
with_view_model( | ||
gpio_i2c_scanner->view, (GpioI2CScannerModel * model) { | ||
UNUSED(model); | ||
gpio_i2c_scanner->callback = callback; | ||
gpio_i2c_scanner->context = context; | ||
return false; | ||
}); | ||
} | ||
|
||
void gpio_i2c_scanner_update_state(GpioI2CScanner* instance, I2CScannerState* st) { | ||
furi_assert(instance); | ||
furi_assert(st); | ||
|
||
with_view_model( | ||
instance->view, (GpioI2CScannerModel * model) { | ||
model->items = st->items; | ||
|
||
for(int i =0; i<model->items; i++) { | ||
model->responding_address[i] = st->responding_address[i]; | ||
} | ||
|
||
return true; | ||
}); | ||
} | ||
|
||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
#pragma once | ||
|
||
#include <gui/view.h> | ||
#include "../gpio_i2c_scanner_control.h" | ||
|
||
|
||
typedef struct GpioI2CScanner GpioI2CScanner; | ||
typedef void (*GpioI2CScannerOkCallback)(InputType type, void* context); | ||
|
||
GpioI2CScanner* gpio_i2c_scanner_alloc(); | ||
|
||
void gpio_i2c_scanner_free(GpioI2CScanner* gpio_i2c_scanner); | ||
|
||
View* gpio_i2c_scanner_get_view(GpioI2CScanner* gpio_i2c_scanner); | ||
|
||
void gpio_i2c_scanner_set_ok_callback(GpioI2CScanner* gpio_i2c_scanner, GpioI2CScannerOkCallback callback, void* context); | ||
|
||
void gpio_i2c_scanner_update_state(GpioI2CScanner* instance, I2CScannerState* st); | ||
|