Skip to content

Commit e95da5b

Browse files
committed
stmhal: Add I2C.scan method, to scan all devices on the bus.
Simple way to find the address of an attached I2C device.
1 parent f6d25ec commit e95da5b

2 files changed

Lines changed: 24 additions & 2 deletions

File tree

stmhal/i2c.c

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -98,14 +98,13 @@ STATIC mp_obj_t pyb_i2c_make_new(mp_obj_t type_in, uint n_args, uint n_kw, const
9898
return (mp_obj_t)i2c_obj;
9999
}
100100

101+
// Check if an I2C device responds to the given address.
101102
STATIC mp_obj_t pyb_i2c_is_ready(mp_obj_t self_in, mp_obj_t i2c_addr_o) {
102103
pyb_i2c_obj_t *self = self_in;
103104
machine_uint_t i2c_addr = mp_obj_get_int(i2c_addr_o) << 1;
104105

105-
//printf("IsDeviceReady\n");
106106
for (int i = 0; i < 10; i++) {
107107
HAL_StatusTypeDef status = HAL_I2C_IsDeviceReady(self->i2c_handle, i2c_addr, 10, 200);
108-
//printf(" got %d\n", status);
109108
if (status == HAL_OK) {
110109
return mp_const_true;
111110
}
@@ -116,6 +115,27 @@ STATIC mp_obj_t pyb_i2c_is_ready(mp_obj_t self_in, mp_obj_t i2c_addr_o) {
116115

117116
STATIC MP_DEFINE_CONST_FUN_OBJ_2(pyb_i2c_is_ready_obj, pyb_i2c_is_ready);
118117

118+
// Scan all I2C addresses from 0x01 to 0x7f and return a list of those that respond.
119+
STATIC mp_obj_t pyb_i2c_scan(mp_obj_t self_in) {
120+
pyb_i2c_obj_t *self = self_in;
121+
122+
mp_obj_t list = mp_obj_new_list(0, NULL);
123+
124+
for (uint addr = 1; addr <= 127; addr++) {
125+
for (int i = 0; i < 10; i++) {
126+
HAL_StatusTypeDef status = HAL_I2C_IsDeviceReady(self->i2c_handle, addr << 1, 10, 200);
127+
if (status == HAL_OK) {
128+
mp_obj_list_append(list, mp_obj_new_int(addr));
129+
break;
130+
}
131+
}
132+
}
133+
134+
return list;
135+
}
136+
137+
STATIC MP_DEFINE_CONST_FUN_OBJ_1(pyb_i2c_scan_obj, pyb_i2c_scan);
138+
119139
STATIC mp_obj_t pyb_i2c_mem_read(uint n_args, const mp_obj_t *args) {
120140
pyb_i2c_obj_t *self = args[0];
121141
machine_uint_t i2c_addr = mp_obj_get_int(args[1]) << 1;
@@ -166,6 +186,7 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(pyb_i2c_mem_write_obj, 4, 4, pyb_i2c_
166186

167187
STATIC const mp_map_elem_t pyb_i2c_locals_dict_table[] = {
168188
{ MP_OBJ_NEW_QSTR(MP_QSTR_is_ready), (mp_obj_t)&pyb_i2c_is_ready_obj },
189+
{ MP_OBJ_NEW_QSTR(MP_QSTR_scan), (mp_obj_t)&pyb_i2c_scan_obj },
169190
{ MP_OBJ_NEW_QSTR(MP_QSTR_mem_read), (mp_obj_t)&pyb_i2c_mem_read_obj },
170191
{ MP_OBJ_NEW_QSTR(MP_QSTR_mem_write), (mp_obj_t)&pyb_i2c_mem_write_obj },
171192
};

stmhal/qstrdefsport.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,7 @@ Q(MODE_EVT_RISING_FALLING)
8282
// for I2C object
8383
Q(I2C)
8484
Q(is_ready)
85+
Q(scan)
8586
Q(mem_read)
8687
Q(mem_write)
8788

0 commit comments

Comments
 (0)