2121
2222static 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
200200MP_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."""
239259static 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."""
249269static 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//|
260280static 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//|
277297static 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//|
336356static 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//|
371391static 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}
384404MP_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
395429static 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
407442static MP_DEFINE_CONST_DICT (i2ctarget_i2c_target_request_locals_dict , i2ctarget_i2c_target_request_locals_dict_table ) ;
0 commit comments