Skip to content

Commit 17e24b8

Browse files
committed
i2ctarget: Add deinit() to I2CTargetRequest; remove close()
1 parent 2959f0a commit 17e24b8

File tree

1 file changed

+50
-15
lines changed

1 file changed

+50
-15
lines changed

shared-bindings/i2ctarget/I2CTarget.c

Lines changed: 50 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@
2121

2222
static mp_obj_t mp_obj_new_i2ctarget_i2c_target_request(i2ctarget_i2c_target_obj_t *target, uint8_t address, bool is_read, bool is_restart) {
2323
i2ctarget_i2c_target_request_obj_t *self =
24-
mp_obj_malloc(i2ctarget_i2c_target_request_obj_t, &i2ctarget_i2c_target_request_type);
24+
mp_obj_malloc_with_finaliser(i2ctarget_i2c_target_request_obj_t, &i2ctarget_i2c_target_request_type);
2525
self->target = target;
2626
self->address = address;
2727
self->is_read = is_read;
@@ -200,7 +200,7 @@ static MP_DEFINE_CONST_DICT(i2ctarget_i2c_target_locals_dict, i2ctarget_i2c_targ
200200
MP_DEFINE_CONST_OBJ_TYPE(
201201
i2ctarget_i2c_target_type,
202202
MP_QSTR_I2CTarget,
203-
MP_TYPE_FLAG_NONE,
203+
MP_TYPE_FLAG_HAS_SPECIAL_ACCESSORS,
204204
make_new, i2ctarget_i2c_target_make_new,
205205
locals_dict, &i2ctarget_i2c_target_locals_dict
206206
);
@@ -222,6 +222,26 @@ static mp_obj_t i2ctarget_i2c_target_request_make_new(const mp_obj_type_t *type,
222222
return mp_obj_new_i2ctarget_i2c_target_request(args[0], mp_obj_get_int(args[1]), mp_obj_is_true(args[2]), mp_obj_is_true(args[3]));
223223
}
224224

225+
//| def deinit(self) -> None:
226+
//| """Disconnects from parent `I2CTarget`.
227+
//| Called by `__exit__()` to indicate the `I2CTargetRequest` is no longer useful."""
228+
//| ...
229+
//|
230+
static mp_obj_t i2ctarget_i2c_target_request_deinit(mp_obj_t self_in) {
231+
i2ctarget_i2c_target_request_obj_t *self = MP_OBJ_TO_PTR(self_in);
232+
self->target = NULL;
233+
234+
return mp_const_none;
235+
}
236+
MP_DEFINE_CONST_FUN_OBJ_1(i2ctarget_i2c_target_request_deinit_obj, i2ctarget_i2c_target_request_deinit);
237+
238+
static void target_request_check_for_deinit(i2ctarget_i2c_target_request_obj_t *self) {
239+
if (self->target == NULL) {
240+
raise_deinited_error();
241+
}
242+
check_for_deinit(self->target);
243+
}
244+
225245
//| def __enter__(self) -> I2CTargetRequest:
226246
//| """No-op used in Context Managers."""
227247
//| ...
@@ -238,7 +258,7 @@ static mp_obj_t i2ctarget_i2c_target_request_make_new(const mp_obj_type_t *type,
238258
//| """The I2C address of the request."""
239259
static mp_obj_t i2ctarget_i2c_target_request_get_address(mp_obj_t self_in) {
240260
i2ctarget_i2c_target_request_obj_t *self = MP_OBJ_TO_PTR(self_in);
241-
check_for_deinit(self->target);
261+
target_request_check_for_deinit(self);
242262

243263
return mp_obj_new_int(self->address);
244264
}
@@ -248,7 +268,7 @@ MP_DEFINE_CONST_PROP_GET(i2ctarget_i2c_target_request_address_obj, i2ctarget_i2c
248268
//| """The I2C main controller is reading from this target."""
249269
static mp_obj_t i2ctarget_i2c_target_request_get_is_read(mp_obj_t self_in) {
250270
i2ctarget_i2c_target_request_obj_t *self = MP_OBJ_TO_PTR(self_in);
251-
check_for_deinit(self->target);
271+
target_request_check_for_deinit(self);
252272

253273
return mp_obj_new_bool(self->is_read);
254274
}
@@ -259,7 +279,7 @@ MP_DEFINE_CONST_PROP_GET(i2ctarget_i2c_target_request_is_read_obj, i2ctarget_i2c
259279
//|
260280
static mp_obj_t i2ctarget_i2c_target_request_get_is_restart(mp_obj_t self_in) {
261281
i2ctarget_i2c_target_request_obj_t *self = MP_OBJ_TO_PTR(self_in);
262-
check_for_deinit(self->target);
282+
target_request_check_for_deinit(self);
263283

264284
return mp_obj_new_bool(self->is_restart);
265285
}
@@ -276,7 +296,7 @@ MP_DEFINE_CONST_PROP_GET(i2ctarget_i2c_target_request_is_restart_obj, i2ctarget_
276296
//|
277297
static mp_obj_t i2ctarget_i2c_target_request_read(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
278298
i2ctarget_i2c_target_request_obj_t *self = MP_OBJ_TO_PTR(pos_args[0]);
279-
check_for_deinit(self->target);
299+
target_request_check_for_deinit(self);
280300

281301
enum { ARG_n, ARG_ack };
282302
static const mp_arg_t allowed_args[] = {
@@ -335,7 +355,7 @@ MP_DEFINE_CONST_FUN_OBJ_KW(i2ctarget_i2c_target_request_read_obj, 1, i2ctarget_i
335355
//|
336356
static mp_obj_t i2ctarget_i2c_target_request_write(mp_obj_t self_in, mp_obj_t buf_in) {
337357
i2ctarget_i2c_target_request_obj_t *self = MP_OBJ_TO_PTR(self_in);
338-
check_for_deinit(self->target);
358+
target_request_check_for_deinit(self);
339359

340360
if (!self->is_read) {
341361
mp_raise_OSError(MP_EACCES);
@@ -370,7 +390,7 @@ static MP_DEFINE_CONST_FUN_OBJ_2(i2ctarget_i2c_target_request_write_obj, i2ctarg
370390
//|
371391
static mp_obj_t i2ctarget_i2c_target_request_ack(uint n_args, const mp_obj_t *args) {
372392
i2ctarget_i2c_target_request_obj_t *self = MP_OBJ_TO_PTR(args[0]);
373-
check_for_deinit(self->target);
393+
target_request_check_for_deinit(self);
374394

375395
bool ack = (n_args == 1) ? true : mp_obj_is_true(args[1]);
376396

@@ -383,25 +403,40 @@ static mp_obj_t i2ctarget_i2c_target_request_ack(uint n_args, const mp_obj_t *ar
383403
}
384404
MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(i2ctarget_i2c_target_request_ack_obj, 1, 2, i2ctarget_i2c_target_request_ack);
385405

386-
static mp_obj_t i2ctarget_i2c_target_request_close(mp_obj_t self_in) {
387-
i2ctarget_i2c_target_request_obj_t *self = MP_OBJ_TO_PTR(self_in);
388-
check_for_deinit(self->target);
406+
//| def __enter__(self) -> I2CTargetRequest:
407+
//| """No-op used in Context Managers."""
408+
//| ...
409+
//|
410+
// Provided by context manager helper.
411+
412+
//| def __exit__(self) -> None:
413+
//| """Close and deinit the request."""
414+
//| ...
415+
//|
416+
static mp_obj_t i2ctarget_i2c_target_request__exit__(size_t n_args, const mp_obj_t *args) {
417+
i2ctarget_i2c_target_request_obj_t *self = MP_OBJ_TO_PTR(args[0]);
418+
target_request_check_for_deinit(self);
389419

390-
common_hal_i2ctarget_i2c_target_close(self->target);
420+
i2ctarget_i2c_target_obj_t *target = self->target;
421+
// Deinit target request first in case _close() fails.
422+
i2ctarget_i2c_target_request_deinit(args[0]);
423+
424+
common_hal_i2ctarget_i2c_target_close(target);
391425
return mp_const_none;
392426
}
393-
static MP_DEFINE_CONST_FUN_OBJ_1(i2ctarget_i2c_target_request_close_obj, i2ctarget_i2c_target_request_close);
427+
static MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(i2ctarget_i2c_target_request___exit___obj, 4, 4, i2ctarget_i2c_target_request__exit__);
394428

395429
static const mp_rom_map_elem_t i2ctarget_i2c_target_request_locals_dict_table[] = {
396430
{ MP_ROM_QSTR(MP_QSTR___enter__), MP_ROM_PTR(&default___enter___obj) },
397-
{ MP_ROM_QSTR(MP_QSTR___exit__), MP_ROM_PTR(&default___exit___obj) },
431+
{ MP_ROM_QSTR(MP_QSTR___exit__), MP_ROM_PTR(&i2ctarget_i2c_target_request___exit___obj) },
432+
{ MP_ROM_QSTR(MP_QSTR_deinit), MP_ROM_PTR(&i2ctarget_i2c_target_request_deinit_obj) },
433+
{ MP_ROM_QSTR(MP_QSTR__del__), MP_ROM_PTR(&i2ctarget_i2c_target_request_deinit_obj) },
398434
{ MP_ROM_QSTR(MP_QSTR_address), MP_ROM_PTR(&i2ctarget_i2c_target_request_address_obj) },
399435
{ MP_ROM_QSTR(MP_QSTR_is_read), MP_ROM_PTR(&i2ctarget_i2c_target_request_is_read_obj) },
400436
{ MP_ROM_QSTR(MP_QSTR_is_restart), MP_ROM_PTR(&i2ctarget_i2c_target_request_is_restart_obj) },
401437
{ MP_ROM_QSTR(MP_QSTR_read), MP_ROM_PTR(&i2ctarget_i2c_target_request_read_obj) },
402438
{ MP_ROM_QSTR(MP_QSTR_write), MP_ROM_PTR(&i2ctarget_i2c_target_request_write_obj) },
403439
{ MP_ROM_QSTR(MP_QSTR_ack), MP_ROM_PTR(&i2ctarget_i2c_target_request_ack_obj) },
404-
{ MP_ROM_QSTR(MP_QSTR_close), MP_ROM_PTR(&i2ctarget_i2c_target_request_close_obj) },
405440
};
406441

407442
static MP_DEFINE_CONST_DICT(i2ctarget_i2c_target_request_locals_dict, i2ctarget_i2c_target_request_locals_dict_table);

0 commit comments

Comments
 (0)