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,23 +222,38 @@ 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 __enter__(self) -> I2CTargetRequest:
226- //| """No-op used in Context Managers."""
227- //| ...
228- //|
229- // Provided by context manager helper.
225+ static void target_request_check_for_deinit (i2ctarget_i2c_target_request_obj_t * self ) {
226+ if (self -> target == NULL ) {
227+ raise_deinited_error ();
228+ }
229+ check_for_deinit (self -> target );
230+ }
230231
231- //| def __exit__(self) -> None:
232- //| """Close the request."""
232+ //| def deinit(self) -> None:
233+ //| """Disconnects from parent `I2CTarget`.
234+ //| Called by `__exit__()` to indicate the `I2CTargetRequest` is no longer useful."""
233235//| ...
234236//|
235- // Provided by context manager helper.
237+ static mp_obj_t i2ctarget_i2c_target_request_deinit (mp_obj_t self_in ) {
238+ i2ctarget_i2c_target_request_obj_t * self = MP_OBJ_TO_PTR (self_in );
239+ target_request_check_for_deinit (self );
240+
241+ i2ctarget_i2c_target_obj_t * target = self -> target ;
242+
243+ // Deinit I2CTargetRequest first in case _close() fails.
244+ self -> target = NULL ;
245+
246+ common_hal_i2ctarget_i2c_target_close (target );
247+
248+ return mp_const_none ;
249+ }
250+ MP_DEFINE_CONST_FUN_OBJ_1 (i2ctarget_i2c_target_request_deinit_obj , i2ctarget_i2c_target_request_deinit );
236251
237252//| address: int
238253//| """The I2C address of the request."""
239254static mp_obj_t i2ctarget_i2c_target_request_get_address (mp_obj_t self_in ) {
240255 i2ctarget_i2c_target_request_obj_t * self = MP_OBJ_TO_PTR (self_in );
241- check_for_deinit (self -> target );
256+ target_request_check_for_deinit (self );
242257
243258 return mp_obj_new_int (self -> address );
244259}
@@ -248,7 +263,7 @@ MP_DEFINE_CONST_PROP_GET(i2ctarget_i2c_target_request_address_obj, i2ctarget_i2c
248263//| """The I2C main controller is reading from this target."""
249264static mp_obj_t i2ctarget_i2c_target_request_get_is_read (mp_obj_t self_in ) {
250265 i2ctarget_i2c_target_request_obj_t * self = MP_OBJ_TO_PTR (self_in );
251- check_for_deinit (self -> target );
266+ target_request_check_for_deinit (self );
252267
253268 return mp_obj_new_bool (self -> is_read );
254269}
@@ -259,7 +274,7 @@ MP_DEFINE_CONST_PROP_GET(i2ctarget_i2c_target_request_is_read_obj, i2ctarget_i2c
259274//|
260275static mp_obj_t i2ctarget_i2c_target_request_get_is_restart (mp_obj_t self_in ) {
261276 i2ctarget_i2c_target_request_obj_t * self = MP_OBJ_TO_PTR (self_in );
262- check_for_deinit (self -> target );
277+ target_request_check_for_deinit (self );
263278
264279 return mp_obj_new_bool (self -> is_restart );
265280}
@@ -276,7 +291,7 @@ MP_DEFINE_CONST_PROP_GET(i2ctarget_i2c_target_request_is_restart_obj, i2ctarget_
276291//|
277292static mp_obj_t i2ctarget_i2c_target_request_read (size_t n_args , const mp_obj_t * pos_args , mp_map_t * kw_args ) {
278293 i2ctarget_i2c_target_request_obj_t * self = MP_OBJ_TO_PTR (pos_args [0 ]);
279- check_for_deinit (self -> target );
294+ target_request_check_for_deinit (self );
280295
281296 enum { ARG_n , ARG_ack };
282297 static const mp_arg_t allowed_args [] = {
@@ -335,7 +350,7 @@ MP_DEFINE_CONST_FUN_OBJ_KW(i2ctarget_i2c_target_request_read_obj, 1, i2ctarget_i
335350//|
336351static mp_obj_t i2ctarget_i2c_target_request_write (mp_obj_t self_in , mp_obj_t buf_in ) {
337352 i2ctarget_i2c_target_request_obj_t * self = MP_OBJ_TO_PTR (self_in );
338- check_for_deinit (self -> target );
353+ target_request_check_for_deinit (self );
339354
340355 if (!self -> is_read ) {
341356 mp_raise_OSError (MP_EACCES );
@@ -370,7 +385,7 @@ static MP_DEFINE_CONST_FUN_OBJ_2(i2ctarget_i2c_target_request_write_obj, i2ctarg
370385//|
371386static mp_obj_t i2ctarget_i2c_target_request_ack (uint n_args , const mp_obj_t * args ) {
372387 i2ctarget_i2c_target_request_obj_t * self = MP_OBJ_TO_PTR (args [0 ]);
373- check_for_deinit (self -> target );
388+ target_request_check_for_deinit (self );
374389
375390 bool ack = (n_args == 1 ) ? true : mp_obj_is_true (args [1 ]);
376391
@@ -383,25 +398,29 @@ static mp_obj_t i2ctarget_i2c_target_request_ack(uint n_args, const mp_obj_t *ar
383398}
384399MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN (i2ctarget_i2c_target_request_ack_obj , 1 , 2 , i2ctarget_i2c_target_request_ack );
385400
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 );
401+ //| def __enter__(self) -> I2CTargetRequest:
402+ //| """No-op used in Context Managers."""
403+ //| ...
404+ //|
405+ // Provided by context manager helper.
389406
390- common_hal_i2ctarget_i2c_target_close (self -> target );
391- return mp_const_none ;
392- }
393- static MP_DEFINE_CONST_FUN_OBJ_1 (i2ctarget_i2c_target_request_close_obj , i2ctarget_i2c_target_request_close ) ;
407+ //| def __exit__(self) -> None:
408+ //| """Close and deinit the request."""
409+ //| ...
410+ //|
411+ // Provided by context manager helper.
394412
395413static const mp_rom_map_elem_t i2ctarget_i2c_target_request_locals_dict_table [] = {
396414 { MP_ROM_QSTR (MP_QSTR___enter__ ), MP_ROM_PTR (& default___enter___obj ) },
397415 { MP_ROM_QSTR (MP_QSTR___exit__ ), MP_ROM_PTR (& default___exit___obj ) },
416+ { MP_ROM_QSTR (MP_QSTR_deinit ), MP_ROM_PTR (& i2ctarget_i2c_target_request_deinit_obj ) },
417+ { MP_ROM_QSTR (MP_QSTR__del__ ), MP_ROM_PTR (& i2ctarget_i2c_target_request_deinit_obj ) },
398418 { MP_ROM_QSTR (MP_QSTR_address ), MP_ROM_PTR (& i2ctarget_i2c_target_request_address_obj ) },
399419 { MP_ROM_QSTR (MP_QSTR_is_read ), MP_ROM_PTR (& i2ctarget_i2c_target_request_is_read_obj ) },
400420 { MP_ROM_QSTR (MP_QSTR_is_restart ), MP_ROM_PTR (& i2ctarget_i2c_target_request_is_restart_obj ) },
401421 { MP_ROM_QSTR (MP_QSTR_read ), MP_ROM_PTR (& i2ctarget_i2c_target_request_read_obj ) },
402422 { MP_ROM_QSTR (MP_QSTR_write ), MP_ROM_PTR (& i2ctarget_i2c_target_request_write_obj ) },
403423 { 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 ) },
405424};
406425
407426static MP_DEFINE_CONST_DICT (i2ctarget_i2c_target_request_locals_dict , i2ctarget_i2c_target_request_locals_dict_table ) ;
0 commit comments