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,31 @@ 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."""
225+ //| def deinit(self) -> None:
226+ //| """Disconnects from parent `I2CTarget`.
227+ //| Called by `__exit__()` to indicate the `I2CTargetRequest` is no longer useful."""
227228//| ...
228229//|
229- // Provided by context manager helper.
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 ;
230233
231- //| def __exit__(self) -> None:
232- //| """Close the request."""
233- //| ...
234- //|
235- // Provided by context manager helper.
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+ }
236244
237245//| address: int
238246//| """The I2C address of the request."""
239247static mp_obj_t i2ctarget_i2c_target_request_get_address (mp_obj_t self_in ) {
240248 i2ctarget_i2c_target_request_obj_t * self = MP_OBJ_TO_PTR (self_in );
241- check_for_deinit (self -> target );
249+ target_request_check_for_deinit (self );
242250
243251 return mp_obj_new_int (self -> address );
244252}
@@ -248,7 +256,7 @@ MP_DEFINE_CONST_PROP_GET(i2ctarget_i2c_target_request_address_obj, i2ctarget_i2c
248256//| """The I2C main controller is reading from this target."""
249257static mp_obj_t i2ctarget_i2c_target_request_get_is_read (mp_obj_t self_in ) {
250258 i2ctarget_i2c_target_request_obj_t * self = MP_OBJ_TO_PTR (self_in );
251- check_for_deinit (self -> target );
259+ target_request_check_for_deinit (self );
252260
253261 return mp_obj_new_bool (self -> is_read );
254262}
@@ -259,7 +267,7 @@ MP_DEFINE_CONST_PROP_GET(i2ctarget_i2c_target_request_is_read_obj, i2ctarget_i2c
259267//|
260268static mp_obj_t i2ctarget_i2c_target_request_get_is_restart (mp_obj_t self_in ) {
261269 i2ctarget_i2c_target_request_obj_t * self = MP_OBJ_TO_PTR (self_in );
262- check_for_deinit (self -> target );
270+ target_request_check_for_deinit (self );
263271
264272 return mp_obj_new_bool (self -> is_restart );
265273}
@@ -276,7 +284,7 @@ MP_DEFINE_CONST_PROP_GET(i2ctarget_i2c_target_request_is_restart_obj, i2ctarget_
276284//|
277285static mp_obj_t i2ctarget_i2c_target_request_read (size_t n_args , const mp_obj_t * pos_args , mp_map_t * kw_args ) {
278286 i2ctarget_i2c_target_request_obj_t * self = MP_OBJ_TO_PTR (pos_args [0 ]);
279- check_for_deinit (self -> target );
287+ target_request_check_for_deinit (self );
280288
281289 enum { ARG_n , ARG_ack };
282290 static const mp_arg_t allowed_args [] = {
@@ -335,7 +343,7 @@ MP_DEFINE_CONST_FUN_OBJ_KW(i2ctarget_i2c_target_request_read_obj, 1, i2ctarget_i
335343//|
336344static mp_obj_t i2ctarget_i2c_target_request_write (mp_obj_t self_in , mp_obj_t buf_in ) {
337345 i2ctarget_i2c_target_request_obj_t * self = MP_OBJ_TO_PTR (self_in );
338- check_for_deinit (self -> target );
346+ target_request_check_for_deinit (self );
339347
340348 if (!self -> is_read ) {
341349 mp_raise_OSError (MP_EACCES );
@@ -370,7 +378,7 @@ static MP_DEFINE_CONST_FUN_OBJ_2(i2ctarget_i2c_target_request_write_obj, i2ctarg
370378//|
371379static mp_obj_t i2ctarget_i2c_target_request_ack (uint n_args , const mp_obj_t * args ) {
372380 i2ctarget_i2c_target_request_obj_t * self = MP_OBJ_TO_PTR (args [0 ]);
373- check_for_deinit (self -> target );
381+ target_request_check_for_deinit (self );
374382
375383 bool ack = (n_args == 1 ) ? true : mp_obj_is_true (args [1 ]);
376384
@@ -383,25 +391,40 @@ static mp_obj_t i2ctarget_i2c_target_request_ack(uint n_args, const mp_obj_t *ar
383391}
384392MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN (i2ctarget_i2c_target_request_ack_obj , 1 , 2 , i2ctarget_i2c_target_request_ack );
385393
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 );
394+ //| def __enter__(self) -> I2CTargetRequest:
395+ //| """No-op used in Context Managers."""
396+ //| ...
397+ //|
398+ // Provided by context manager helper.
389399
390- common_hal_i2ctarget_i2c_target_close (self -> target );
400+ //| def __exit__(self) -> None:
401+ //| """Close and deinit the request."""
402+ //| ...
403+ //|
404+ static mp_obj_t i2ctarget_i2c_target_request__exit__ (size_t n_args , const mp_obj_t * args ) {
405+ i2ctarget_i2c_target_request_obj_t * self = MP_OBJ_TO_PTR (args [0 ]);
406+ target_request_check_for_deinit (self );
407+
408+ i2ctarget_i2c_target_obj_t * target = self -> target ;
409+ // Deinit target request first in case _close() fails.
410+ i2ctarget_i2c_target_request_deinit (args [0 ]);
411+
412+ common_hal_i2ctarget_i2c_target_close (target );
391413 return mp_const_none ;
392414}
393- static MP_DEFINE_CONST_FUN_OBJ_1 ( i2ctarget_i2c_target_request_close_obj , i2ctarget_i2c_target_request_close ) ;
415+ static MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN ( i2ctarget_i2c_target_request___exit___obj , 4 , 4 , i2ctarget_i2c_target_request__exit__ ) ;
394416
395417static const mp_rom_map_elem_t i2ctarget_i2c_target_request_locals_dict_table [] = {
396418 { 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 ) },
419+ { MP_ROM_QSTR (MP_QSTR___exit__ ), MP_ROM_PTR (& i2ctarget_i2c_target_request___exit___obj ) },
420+ { MP_ROM_QSTR (MP_QSTR_deinit ), MP_ROM_PTR (& i2ctarget_i2c_target_request_deinit_obj ) },
421+ { MP_ROM_QSTR (MP_QSTR__del__ ), MP_ROM_PTR (& i2ctarget_i2c_target_request_deinit_obj ) },
398422 { MP_ROM_QSTR (MP_QSTR_address ), MP_ROM_PTR (& i2ctarget_i2c_target_request_address_obj ) },
399423 { MP_ROM_QSTR (MP_QSTR_is_read ), MP_ROM_PTR (& i2ctarget_i2c_target_request_is_read_obj ) },
400424 { MP_ROM_QSTR (MP_QSTR_is_restart ), MP_ROM_PTR (& i2ctarget_i2c_target_request_is_restart_obj ) },
401425 { MP_ROM_QSTR (MP_QSTR_read ), MP_ROM_PTR (& i2ctarget_i2c_target_request_read_obj ) },
402426 { MP_ROM_QSTR (MP_QSTR_write ), MP_ROM_PTR (& i2ctarget_i2c_target_request_write_obj ) },
403427 { 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 ) },
405428};
406429
407430static MP_DEFINE_CONST_DICT (i2ctarget_i2c_target_request_locals_dict , i2ctarget_i2c_target_request_locals_dict_table ) ;
0 commit comments