diff --git a/components/flow3r_bsp/flow3r_bsp_i2c.c b/components/flow3r_bsp/flow3r_bsp_i2c.c index c4baae0aa17a5864e0b9fd66e00598593c3d381e..981b22ba80f178af31a598d93c299e400ecae616 100644 --- a/components/flow3r_bsp/flow3r_bsp_i2c.c +++ b/components/flow3r_bsp/flow3r_bsp_i2c.c @@ -5,6 +5,8 @@ #include "freertos/semphr.h" #include "esp_log.h" +#include <string.h> + static SemaphoreHandle_t mutex; static const char *TAG = "flow3r-bsp-i2c"; @@ -74,7 +76,7 @@ void flow3r_bsp_i2c_init(void) { assert(i2c_param_config(I2C_NUM_0, &i2c_conf) == ESP_OK); assert(i2c_driver_install(I2C_NUM_0, i2c_conf.mode, 0, 0, ESP_INTR_FLAG_LOWMED | ESP_INTR_FLAG_SHARED) == ESP_OK); - flow3r_bsp_i2c_scan(); + flow3r_bsp_i2c_scan(NULL); } // Take I2C bus lock. @@ -101,7 +103,10 @@ esp_err_t flow3r_bsp_i2c_write_read_device(uint8_t address, const uint8_t *write return res; } -void flow3r_bsp_i2c_scan(void) { +void flow3r_bsp_i2c_scan(flow3r_bsp_i2c_scan_result_t *res) { + if (res != NULL) { + memset(res, 0, sizeof(flow3r_bsp_i2c_scan_result_t)); + } ESP_LOGI(TAG, "Scan: starting..."); for (uint8_t i = 1; i < 127; i++) { i2c_cmd_handle_t cmd = i2c_cmd_link_create(); @@ -112,6 +117,11 @@ void flow3r_bsp_i2c_scan(void) { i2c_cmd_link_delete(cmd); if (ret == ESP_OK) { ESP_LOGI(TAG, "Scan: detected %02x", i); + if (res != NULL) { + size_t ix = i / 32; + size_t offs = i % 32; + res->res[ix] |= (1 << offs); + } } } ESP_LOGI(TAG, "Scan: done."); diff --git a/components/flow3r_bsp/flow3r_bsp_i2c.h b/components/flow3r_bsp/flow3r_bsp_i2c.h index 49a14fdbae4395ae7f10a671902245a2afb43663..37d0c3b8453f618b78453ebe357d1d0c923c7f42 100644 --- a/components/flow3r_bsp/flow3r_bsp_i2c.h +++ b/components/flow3r_bsp/flow3r_bsp_i2c.h @@ -37,4 +37,8 @@ esp_err_t flow3r_bsp_i2c_write_to_device(flow3r_i2c_address address, const uint8 // This can be called concurrently from different tassks. esp_err_t flow3r_bsp_i2c_write_read_device(flow3r_i2c_address address, const uint8_t *write_buffer, size_t write_size, uint8_t *read_buffer, size_t read_size, TickType_t ticks_to_wait); -void flow3r_bsp_i2c_scan(void); \ No newline at end of file +typedef struct { + uint32_t res[4]; // Bitfield of addresses from 0 to 127. +} flow3r_bsp_i2c_scan_result_t; + +void flow3r_bsp_i2c_scan(flow3r_bsp_i2c_scan_result_t *res); \ No newline at end of file diff --git a/usermodule/mp_hardware.c b/usermodule/mp_hardware.c index 0f26f937b2e182312d4f1628063a9bd54588b648..cb5418254589df2c62d4c9b477edf6c75965d305 100644 --- a/usermodule/mp_hardware.c +++ b/usermodule/mp_hardware.c @@ -197,6 +197,23 @@ STATIC mp_obj_t mp_scope_draw(mp_obj_t ctx_in) { } STATIC MP_DEFINE_CONST_FUN_OBJ_1(mp_scope_draw_obj, mp_scope_draw); +STATIC mp_obj_t mp_i2c_scan(void) { + flow3r_bsp_i2c_scan_result_t scan; + flow3r_bsp_i2c_scan(&scan); + + mp_obj_t res = mp_obj_new_list(0, NULL); + for (int i = 0; i < 127; i++) { + size_t ix = i / 32; + size_t offs = i % 32; + if (scan.res[ix] & (1 << offs)) { + mp_obj_list_append(res, mp_obj_new_int_from_uint(i)); + } + } + return res; +} + +STATIC MP_DEFINE_CONST_FUN_OBJ_0(mp_i2c_scan_obj, mp_i2c_scan); + STATIC const mp_rom_map_elem_t mp_module_hardware_globals_table[] = { { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_hardware) }, @@ -224,6 +241,7 @@ STATIC const mp_rom_map_elem_t mp_module_hardware_globals_table[] = { { MP_ROM_QSTR(MP_QSTR_display_set_backlight), MP_ROM_PTR(&mp_display_set_backlight_obj) }, { MP_ROM_QSTR(MP_QSTR_version), MP_ROM_PTR(&mp_version_obj) }, { MP_ROM_QSTR(MP_QSTR_get_ctx), MP_ROM_PTR(&mp_get_ctx_obj) }, + { MP_ROM_QSTR(MP_QSTR_i2c_scan), MP_ROM_PTR(&mp_i2c_scan_obj) }, { MP_ROM_QSTR(MP_QSTR_BUTTON_PRESSED_LEFT), MP_ROM_INT(st3m_tripos_left) }, { MP_ROM_QSTR(MP_QSTR_BUTTON_PRESSED_RIGHT), MP_ROM_INT(st3m_tripos_right) },