Skip to content

Commit 1f3032e

Browse files
committed
pybricks.iodevices.I2CDevice: Add helper for asserting id string.
This is commonly used for LEGO-style I2C device classes. Also simplify passing in address to I2CDevice object creator.
1 parent 45e2d46 commit 1f3032e

File tree

3 files changed

+28
-5
lines changed

3 files changed

+28
-5
lines changed

pybricks/iodevices/iodevices.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,8 +26,9 @@ extern const mp_obj_type_t pb_type_i2c_device;
2626
*/
2727
typedef mp_obj_t (*pb_type_i2c_device_return_map_t)(const uint8_t *data, size_t len);
2828

29-
mp_obj_t pb_type_i2c_device_make_new(mp_obj_t port_in, mp_obj_t address_in, bool custom, bool powered, bool nxt_quirk);
29+
mp_obj_t pb_type_i2c_device_make_new(mp_obj_t port_in, uint8_t address, bool custom, bool powered, bool nxt_quirk);
3030
mp_obj_t pb_type_i2c_device_start_operation(mp_obj_t i2c_device_obj, const uint8_t *write_data, size_t write_len, size_t read_len, pb_type_i2c_device_return_map_t return_map);
31+
void pb_type_i2c_device_assert_string_at_register(mp_obj_t i2c_device_obj, uint8_t reg, const char *string);
3132

3233
#endif
3334

pybricks/iodevices/pb_type_i2c_device.c

Lines changed: 22 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ typedef struct {
4242
} device_obj_t;
4343

4444
// pybricks.iodevices.I2CDevice.__init__
45-
mp_obj_t pb_type_i2c_device_make_new(mp_obj_t port_in, mp_obj_t address_in, bool custom, bool powered, bool nxt_quirk) {
45+
mp_obj_t pb_type_i2c_device_make_new(mp_obj_t port_in, uint8_t address, bool custom, bool powered, bool nxt_quirk) {
4646

4747
pb_module_tools_assert_blocking();
4848

@@ -67,7 +67,7 @@ mp_obj_t pb_type_i2c_device_make_new(mp_obj_t port_in, mp_obj_t address_in, bool
6767

6868
device_obj_t *device = mp_obj_malloc(device_obj_t, &pb_type_i2c_device);
6969
device->i2c_dev = i2c_dev;
70-
device->address = mp_obj_get_int(address_in);
70+
device->address = address;
7171
device->nxt_quirk = nxt_quirk;
7272
if (powered) {
7373
pbio_port_p1p2_set_power(port, PBIO_PORT_POWER_REQUIREMENTS_BATTERY_VOLTAGE_P1_POS);
@@ -86,7 +86,7 @@ static mp_obj_t make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw,
8686
PB_ARG_DEFAULT_FALSE(nxt_quirk)
8787
);
8888

89-
return pb_type_i2c_device_make_new(port_in, address_in, mp_obj_is_true(custom_in), mp_obj_is_true(powered_in), mp_obj_is_true(nxt_quirk_in));
89+
return pb_type_i2c_device_make_new(port_in, mp_obj_get_int(address_in), mp_obj_is_true(custom_in), mp_obj_is_true(powered_in), mp_obj_is_true(nxt_quirk_in));
9090
}
9191

9292
// Object representing the iterable that is returned when calling an I2C
@@ -202,6 +202,25 @@ mp_obj_t pb_type_i2c_device_start_operation(mp_obj_t i2c_device_obj, const uint8
202202
return device->return_map(device->read_buf, device->read_len);
203203
}
204204

205+
/**
206+
* Helper utility to verify that expected device is attached by asserting an
207+
* expected manufacturer or id string. Raises ::PBIO_ERROR_NO_DEV if expected
208+
* string is not found.
209+
*/
210+
void pb_type_i2c_device_assert_string_at_register(mp_obj_t i2c_device_obj, uint8_t reg, const char *string) {
211+
pb_module_tools_assert_blocking();
212+
213+
const uint8_t write_data[] = { reg };
214+
mp_obj_t result = pb_type_i2c_device_start_operation(i2c_device_obj, write_data, MP_ARRAY_SIZE(write_data), strlen(string) - 1, mp_obj_new_bytes);
215+
216+
size_t result_len;
217+
const char *result_data = mp_obj_str_get_data(result, &result_len);
218+
219+
if (memcmp(string, result_data, strlen(string) - 1)) {
220+
pb_assert(PBIO_ERROR_NO_DEV);
221+
}
222+
}
223+
205224
// pybricks.iodevices.I2CDevice.write_then_read
206225
static mp_obj_t write_then_read(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
207226
PB_PARSE_ARGS_METHOD(n_args, pos_args, kw_args,

pybricks/nxtdevices/pb_type_nxtdevices_ultrasonicsensor.c

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,11 +30,14 @@ static mp_obj_t nxtdevices_UltrasonicSensor_make_new(const mp_obj_type_t *type,
3030
PB_ARG_REQUIRED(port));
3131

3232
nxtdevices_UltrasonicSensor_obj_t *self = mp_obj_malloc(nxtdevices_UltrasonicSensor_obj_t, type);
33-
self->i2c_device_obj = pb_type_i2c_device_make_new(port_in, mp_obj_new_int(0x01), false, true, true);
33+
self->i2c_device_obj = pb_type_i2c_device_make_new(port_in, 0x01, false, true, true);
3434

3535
// NXT Ultrasonic Sensor appears to need some time after initializing I2C pins before it can receive data.
3636
mp_hal_delay_ms(100);
3737

38+
pb_type_i2c_device_assert_string_at_register(self->i2c_device_obj, 0x08, "LEGO");
39+
pb_type_i2c_device_assert_string_at_register(self->i2c_device_obj, 0x10, "Sonar");
40+
3841
return MP_OBJ_FROM_PTR(self);
3942
}
4043

0 commit comments

Comments
 (0)