diff --git a/micropython/modules/breakout_as7262/breakout_as7262.cpp b/micropython/modules/breakout_as7262/breakout_as7262.cpp index 7942a0b1..ddd45732 100644 --- a/micropython/modules/breakout_as7262/breakout_as7262.cpp +++ b/micropython/modules/breakout_as7262/breakout_as7262.cpp @@ -1,4 +1,5 @@ #include "libraries/breakout_as7262/breakout_as7262.hpp" +#include "common/pimoroni_i2c.hpp" #define MP_OBJ_TO_PTR2(o, t) ((t *)(uintptr_t)(o)) @@ -13,18 +14,14 @@ extern "C" { #include "breakout_as7262.h" #include "pimoroni_i2c.h" -/***** I2C Struct *****/ -typedef struct _PimoroniI2C_obj_t { - mp_obj_base_t base; - I2C *i2c; -} _PimoroniI2C_obj_t; - /***** Variables Struct *****/ typedef struct _breakout_as7262_BreakoutAS7262_obj_t { mp_obj_base_t base; BreakoutAS7262 *breakout; + _PimoroniI2C_obj_t *i2c; } breakout_as7262_BreakoutAS7262_obj_t; + /***** Print *****/ void BreakoutAS7262_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind) { (void)kind; //Unused input parameter @@ -61,18 +58,12 @@ mp_obj_t BreakoutAS7262_make_new(const mp_obj_type_t *type, size_t n_args, size_ mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; mp_arg_parse_all_kw_array(n_args, n_kw, all_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); - - if(!MP_OBJ_IS_TYPE(args[ARG_i2c].u_obj, &PimoroniI2C_type)) { - mp_raise_ValueError(MP_ERROR_TEXT("BreakoutAS7262: Bad i2C object")); - return mp_const_none; - } - - _PimoroniI2C_obj_t *i2c = (_PimoroniI2C_obj_t *)MP_OBJ_TO_PTR(args[ARG_i2c].u_obj); - self = m_new_obj(breakout_as7262_BreakoutAS7262_obj_t); self->base.type = &breakout_as7262_BreakoutAS7262_type; - self->breakout = new BreakoutAS7262(i2c->i2c, args[ARG_int].u_int); + self->i2c = PimoroniI2C_from_machine_i2c_or_native(args[ARG_i2c].u_obj); + + self->breakout = new BreakoutAS7262((pimoroni::I2C *)(self->i2c->i2c), args[ARG_int].u_int); if(!self->breakout->init()) { mp_raise_msg(&mp_type_RuntimeError, "BreakoutAS7262: breakout not found when initialising"); diff --git a/micropython/modules/breakout_bh1745/breakout_bh1745.cpp b/micropython/modules/breakout_bh1745/breakout_bh1745.cpp index de3c60b5..93aa88a6 100644 --- a/micropython/modules/breakout_bh1745/breakout_bh1745.cpp +++ b/micropython/modules/breakout_bh1745/breakout_bh1745.cpp @@ -14,16 +14,11 @@ extern "C" { #include "breakout_bh1745.h" #include "pimoroni_i2c.h" -/***** I2C Struct *****/ -typedef struct _PimoroniI2C_obj_t { - mp_obj_base_t base; - I2C *i2c; -} _PimoroniI2C_obj_t; - /***** Variables Struct *****/ typedef struct _breakout_bh1745_BreakoutBH1745_obj_t { mp_obj_base_t base; BreakoutBH1745 *breakout; + _PimoroniI2C_obj_t *i2c; } breakout_bh1745_BreakoutBH1745_obj_t; /***** Print *****/ @@ -64,17 +59,12 @@ mp_obj_t BreakoutBH1745_make_new(const mp_obj_type_t *type, size_t n_args, size_ mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; mp_arg_parse_all_kw_array(n_args, n_kw, all_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); - if(!MP_OBJ_IS_TYPE(args[ARG_i2c].u_obj, &PimoroniI2C_type)) { - mp_raise_ValueError(MP_ERROR_TEXT("BreakoutBH1745: Bad i2C object")); - return mp_const_none; - } - - _PimoroniI2C_obj_t *i2c = (_PimoroniI2C_obj_t *)MP_OBJ_TO_PTR(args[ARG_i2c].u_obj); - self = m_new_obj(breakout_bh1745_BreakoutBH1745_obj_t); self->base.type = &breakout_bh1745_BreakoutBH1745_type; - self->breakout = new BreakoutBH1745(i2c->i2c, args[ARG_address].u_int); + self->i2c = PimoroniI2C_from_machine_i2c_or_native(args[ARG_i2c].u_obj); + + self->breakout = new BreakoutBH1745((pimoroni::I2C *)(self->i2c->i2c), args[ARG_address].u_int); if(!self->breakout->init()) { mp_raise_msg(&mp_type_RuntimeError, "BreakoutBH1745: breakout not found when initialising"); diff --git a/micropython/modules/breakout_bme280/breakout_bme280.cpp b/micropython/modules/breakout_bme280/breakout_bme280.cpp index 8a00e0a8..cae9930f 100644 --- a/micropython/modules/breakout_bme280/breakout_bme280.cpp +++ b/micropython/modules/breakout_bme280/breakout_bme280.cpp @@ -13,16 +13,11 @@ extern "C" { #include "breakout_bme280.h" #include "pimoroni_i2c.h" -/***** I2C Struct *****/ -typedef struct _PimoroniI2C_obj_t { - mp_obj_base_t base; - I2C *i2c; -} _PimoroniI2C_obj_t; - /***** Variables Struct *****/ typedef struct _breakout_bme280_BreakoutBME280_obj_t { mp_obj_base_t base; BME280 *breakout; + _PimoroniI2C_obj_t *i2c; } breakout_bme280_BreakoutBME280_obj_t; /***** Print *****/ @@ -62,18 +57,12 @@ mp_obj_t BreakoutBME280_make_new(const mp_obj_type_t *type, size_t n_args, size_ mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; mp_arg_parse_all_kw_array(n_args, n_kw, all_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); - - if(!MP_OBJ_IS_TYPE(args[ARG_i2c].u_obj, &PimoroniI2C_type)) { - mp_raise_ValueError(MP_ERROR_TEXT("BreakoutBME280: Bad i2C object")); - return mp_const_none; - } - - _PimoroniI2C_obj_t *i2c = (_PimoroniI2C_obj_t *)MP_OBJ_TO_PTR(args[ARG_i2c].u_obj); - self = m_new_obj(breakout_bme280_BreakoutBME280_obj_t); self->base.type = &breakout_bme280_BreakoutBME280_type; - self->breakout = new BME280(i2c->i2c, args[ARG_address].u_int, args[ARG_int].u_int); + self->i2c = PimoroniI2C_from_machine_i2c_or_native(args[ARG_i2c].u_obj); + + self->breakout = new BME280((pimoroni::I2C *)(self->i2c->i2c), args[ARG_address].u_int, args[ARG_int].u_int); if(!self->breakout->init()) { mp_raise_msg(&mp_type_RuntimeError, "BreakoutBME280: breakout not found when initialising"); diff --git a/micropython/modules/breakout_bme68x/breakout_bme68x.cpp b/micropython/modules/breakout_bme68x/breakout_bme68x.cpp index 663c8b06..70d92b66 100644 --- a/micropython/modules/breakout_bme68x/breakout_bme68x.cpp +++ b/micropython/modules/breakout_bme68x/breakout_bme68x.cpp @@ -13,16 +13,12 @@ extern "C" { #include "breakout_bme68x.h" #include "pimoroni_i2c.h" -/***** I2C Struct *****/ -typedef struct _PimoroniI2C_obj_t { - mp_obj_base_t base; - I2C *i2c; -} _PimoroniI2C_obj_t; /***** Variables Struct *****/ typedef struct _breakout_bme68x_BreakoutBME68X_obj_t { mp_obj_base_t base; BME68X *breakout; + _PimoroniI2C_obj_t *i2c; } breakout_bme68x_BreakoutBME68X_obj_t; /***** Print *****/ @@ -62,18 +58,12 @@ mp_obj_t BreakoutBME68X_make_new(const mp_obj_type_t *type, size_t n_args, size_ mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; mp_arg_parse_all_kw_array(n_args, n_kw, all_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); - - if(!MP_OBJ_IS_TYPE(args[ARG_i2c].u_obj, &PimoroniI2C_type)) { - mp_raise_ValueError(MP_ERROR_TEXT("BreakoutBME68X: Bad i2C object")); - return mp_const_none; - } - - _PimoroniI2C_obj_t *i2c = (_PimoroniI2C_obj_t *)MP_OBJ_TO_PTR(args[ARG_i2c].u_obj); - self = m_new_obj(breakout_bme68x_BreakoutBME68X_obj_t); self->base.type = &breakout_bme68x_BreakoutBME68X_type; - self->breakout = new BME68X(i2c->i2c, args[ARG_address].u_int, args[ARG_int].u_int); + self->i2c = PimoroniI2C_from_machine_i2c_or_native(args[ARG_i2c].u_obj); + + self->breakout = new BME68X((pimoroni::I2C *)(self->i2c->i2c), args[ARG_address].u_int, args[ARG_int].u_int); if(!self->breakout->init()) { mp_raise_msg(&mp_type_RuntimeError, "BreakoutBME68X: breakout not found when initialising"); diff --git a/micropython/modules/breakout_bmp280/breakout_bmp280.cpp b/micropython/modules/breakout_bmp280/breakout_bmp280.cpp index 91532096..83052ec3 100644 --- a/micropython/modules/breakout_bmp280/breakout_bmp280.cpp +++ b/micropython/modules/breakout_bmp280/breakout_bmp280.cpp @@ -13,16 +13,11 @@ extern "C" { #include "breakout_bmp280.h" #include "pimoroni_i2c.h" -/***** I2C Struct *****/ -typedef struct _PimoroniI2C_obj_t { - mp_obj_base_t base; - I2C *i2c; -} _PimoroniI2C_obj_t; - /***** Variables Struct *****/ typedef struct _breakout_bmp280_BreakoutBMP280_obj_t { mp_obj_base_t base; BMP280 *breakout; + _PimoroniI2C_obj_t *i2c; } breakout_bmp280_BreakoutBMP280_obj_t; /***** Print *****/ @@ -62,18 +57,12 @@ mp_obj_t BreakoutBMP280_make_new(const mp_obj_type_t *type, size_t n_args, size_ mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; mp_arg_parse_all_kw_array(n_args, n_kw, all_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); - - if(!MP_OBJ_IS_TYPE(args[ARG_i2c].u_obj, &PimoroniI2C_type)) { - mp_raise_ValueError(MP_ERROR_TEXT("BreakoutBMP280: Bad i2C object")); - return mp_const_none; - } - - _PimoroniI2C_obj_t *i2c = (_PimoroniI2C_obj_t *)MP_OBJ_TO_PTR(args[ARG_i2c].u_obj); - self = m_new_obj(breakout_bmp280_BreakoutBMP280_obj_t); self->base.type = &breakout_bmp280_BreakoutBMP280_type; - self->breakout = new BMP280(i2c->i2c, args[ARG_address].u_int, args[ARG_int].u_int); + self->i2c = PimoroniI2C_from_machine_i2c_or_native(args[ARG_i2c].u_obj); + + self->breakout = new BMP280((pimoroni::I2C *)(self->i2c->i2c), args[ARG_address].u_int, args[ARG_int].u_int); if(!self->breakout->init()) { mp_raise_msg(&mp_type_RuntimeError, "BreakoutBMP280: breakout not found when initialising"); diff --git a/micropython/modules/breakout_dotmatrix/breakout_dotmatrix.cpp b/micropython/modules/breakout_dotmatrix/breakout_dotmatrix.cpp index de9fca75..b15a1edb 100644 --- a/micropython/modules/breakout_dotmatrix/breakout_dotmatrix.cpp +++ b/micropython/modules/breakout_dotmatrix/breakout_dotmatrix.cpp @@ -14,16 +14,11 @@ extern "C" { #include "breakout_dotmatrix.h" #include "pimoroni_i2c.h" -/***** I2C Struct *****/ -typedef struct _PimoroniI2C_obj_t { - mp_obj_base_t base; - I2C *i2c; -} _PimoroniI2C_obj_t; - /***** Variables Struct *****/ typedef struct _breakout_dotmatrix_BreakoutDotMatrix_obj_t { mp_obj_base_t base; BreakoutDotMatrix *breakout; + _PimoroniI2C_obj_t *i2c; } breakout_dotmatrix_BreakoutDotMatrix_obj_t; /***** Print *****/ @@ -64,17 +59,12 @@ mp_obj_t BreakoutDotMatrix_make_new(const mp_obj_type_t *type, size_t n_args, si mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; mp_arg_parse_all_kw_array(n_args, n_kw, all_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); - if(!MP_OBJ_IS_TYPE(args[ARG_i2c].u_obj, &PimoroniI2C_type)) { - mp_raise_ValueError(MP_ERROR_TEXT("BreakoutDotMatrix: Bad i2C object")); - return mp_const_none; - } - - _PimoroniI2C_obj_t *i2c = (_PimoroniI2C_obj_t *)MP_OBJ_TO_PTR(args[ARG_i2c].u_obj); - self = m_new_obj(breakout_dotmatrix_BreakoutDotMatrix_obj_t); self->base.type = &breakout_dotmatrix_BreakoutDotMatrix_type; - - self->breakout = new BreakoutDotMatrix(i2c->i2c, args[ARG_address].u_int); + + self->i2c = PimoroniI2C_from_machine_i2c_or_native(args[ARG_i2c].u_obj); + + self->breakout = new BreakoutDotMatrix((pimoroni::I2C *)(self->i2c->i2c), args[ARG_address].u_int); if(!self->breakout->init()) { mp_raise_msg(&mp_type_RuntimeError, "DotMatrix breakout not found when initialising"); diff --git a/micropython/modules/breakout_encoder/breakout_encoder.cpp b/micropython/modules/breakout_encoder/breakout_encoder.cpp index c9525501..8dbaf21e 100644 --- a/micropython/modules/breakout_encoder/breakout_encoder.cpp +++ b/micropython/modules/breakout_encoder/breakout_encoder.cpp @@ -14,16 +14,11 @@ extern "C" { #include "breakout_encoder.h" #include "pimoroni_i2c.h" -/***** I2C Struct *****/ -typedef struct _PimoroniI2C_obj_t { - mp_obj_base_t base; - I2C *i2c; -} _PimoroniI2C_obj_t; - /***** Variables Struct *****/ typedef struct _breakout_encoder_BreakoutEncoder_obj_t { mp_obj_base_t base; BreakoutEncoder *breakout; + _PimoroniI2C_obj_t *i2c; } breakout_encoder_BreakoutEncoder_obj_t; /***** Print *****/ @@ -68,17 +63,12 @@ mp_obj_t BreakoutEncoder_make_new(const mp_obj_type_t *type, size_t n_args, size mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; mp_arg_parse_all_kw_array(n_args, n_kw, all_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); - if(!MP_OBJ_IS_TYPE(args[ARG_i2c].u_obj, &PimoroniI2C_type)) { - mp_raise_ValueError(MP_ERROR_TEXT("BreakoutEncoder: Bad i2C object")); - return mp_const_none; - } - - _PimoroniI2C_obj_t *i2c = (_PimoroniI2C_obj_t *)MP_OBJ_TO_PTR(args[ARG_i2c].u_obj); - self = m_new_obj(breakout_encoder_BreakoutEncoder_obj_t); self->base.type = &breakout_encoder_BreakoutEncoder_type; - self->breakout = new BreakoutEncoder(i2c->i2c, args[ARG_address].u_int, args[ARG_interrupt].u_int); + self->i2c = PimoroniI2C_from_machine_i2c_or_native(args[ARG_i2c].u_obj); + + self->breakout = new BreakoutEncoder((pimoroni::I2C *)(self->i2c->i2c), args[ARG_address].u_int, args[ARG_interrupt].u_int); if(!self->breakout->init()) { mp_raise_msg(&mp_type_RuntimeError, "BreakoutEncoder: breakout not found when initialising"); diff --git a/micropython/modules/breakout_icp10125/breakout_icp10125.cpp b/micropython/modules/breakout_icp10125/breakout_icp10125.cpp index c02ad8ab..83c84c72 100644 --- a/micropython/modules/breakout_icp10125/breakout_icp10125.cpp +++ b/micropython/modules/breakout_icp10125/breakout_icp10125.cpp @@ -8,16 +8,11 @@ extern "C" { #include "breakout_icp10125.h" #include "pimoroni_i2c.h" -/***** I2C Struct *****/ -typedef struct _PimoroniI2C_obj_t { - mp_obj_base_t base; - I2C *i2c; -} _PimoroniI2C_obj_t; - /***** Variables Struct *****/ typedef struct _breakout_icp10125_BreakoutICP10125_obj_t { mp_obj_base_t base; ICP10125 *breakout; + _PimoroniI2C_obj_t *i2c; } breakout_icp10125_BreakoutICP10125_obj_t; /***** Print *****/ @@ -43,18 +38,12 @@ mp_obj_t BreakoutICP10125_make_new(const mp_obj_type_t *type, size_t n_args, siz mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; mp_arg_parse_all_kw_array(n_args, n_kw, all_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); - // Get I2C bus. - if(!MP_OBJ_IS_TYPE(args[ARG_i2c].u_obj, &PimoroniI2C_type)) { - mp_raise_ValueError(MP_ERROR_TEXT("BreakoutICP10125: Bad i2C object")); - return mp_const_none; - } - - _PimoroniI2C_obj_t *i2c = (_PimoroniI2C_obj_t *)MP_OBJ_TO_PTR(args[ARG_i2c].u_obj); - self = m_new_obj(breakout_icp10125_BreakoutICP10125_obj_t); self->base.type = &breakout_icp10125_BreakoutICP10125_type; - self->breakout = new ICP10125(i2c->i2c); + self->i2c = PimoroniI2C_from_machine_i2c_or_native(args[ARG_i2c].u_obj); + + self->breakout = new ICP10125((pimoroni::I2C *)(self->i2c->i2c)); if(!self->breakout->init()) { mp_raise_msg(&mp_type_RuntimeError, "BreakoutICP10125: breakout not found when initialising"); diff --git a/micropython/modules/breakout_ioexpander/breakout_ioexpander.cpp b/micropython/modules/breakout_ioexpander/breakout_ioexpander.cpp index d1d8d356..2e44ea82 100644 --- a/micropython/modules/breakout_ioexpander/breakout_ioexpander.cpp +++ b/micropython/modules/breakout_ioexpander/breakout_ioexpander.cpp @@ -14,16 +14,11 @@ extern "C" { #include "breakout_ioexpander.h" #include "pimoroni_i2c.h" -/***** I2C Struct *****/ -typedef struct _PimoroniI2C_obj_t { - mp_obj_base_t base; - I2C *i2c; -} _PimoroniI2C_obj_t; - /***** Variables Struct *****/ typedef struct _breakout_ioexpander_BreakoutIOExpander_obj_t { mp_obj_base_t base; BreakoutIOExpander *breakout; + _PimoroniI2C_obj_t *i2c; } breakout_ioexpander_BreakoutIOExpander_obj_t; /***** Print *****/ @@ -68,18 +63,12 @@ mp_obj_t BreakoutIOExpander_make_new(const mp_obj_type_t *type, size_t n_args, s mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; mp_arg_parse_all_kw_array(n_args, n_kw, all_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); - // Get I2C bus. - if(!MP_OBJ_IS_TYPE(args[ARG_i2c].u_obj, &PimoroniI2C_type)) { - mp_raise_ValueError(MP_ERROR_TEXT("BreakoutIOExpander: Bad i2C object")); - return mp_const_none; - } - - _PimoroniI2C_obj_t *i2c = (_PimoroniI2C_obj_t *)MP_OBJ_TO_PTR(args[ARG_i2c].u_obj); - self = m_new_obj(breakout_ioexpander_BreakoutIOExpander_obj_t); self->base.type = &breakout_ioexpander_BreakoutIOExpander_type; - self->breakout = new BreakoutIOExpander(i2c->i2c, args[ARG_address].u_int, args[ARG_interrupt].u_int); + self->i2c = PimoroniI2C_from_machine_i2c_or_native(args[ARG_i2c].u_obj); + + self->breakout = new BreakoutIOExpander((pimoroni::I2C *)(self->i2c->i2c), args[ARG_address].u_int, args[ARG_interrupt].u_int); if(!self->breakout->init()) { mp_raise_msg(&mp_type_RuntimeError, "BreakoutIOExpander: breakout not found when initialising"); diff --git a/micropython/modules/breakout_ltr559/breakout_ltr559.cpp b/micropython/modules/breakout_ltr559/breakout_ltr559.cpp index 735a5845..53d04645 100644 --- a/micropython/modules/breakout_ltr559/breakout_ltr559.cpp +++ b/micropython/modules/breakout_ltr559/breakout_ltr559.cpp @@ -14,16 +14,11 @@ extern "C" { #include "breakout_ltr559.h" #include "pimoroni_i2c.h" -/***** I2C Struct *****/ -typedef struct _PimoroniI2C_obj_t { - mp_obj_base_t base; - I2C *i2c; -} _PimoroniI2C_obj_t; - /***** Variables Struct *****/ typedef struct _breakout_ltr559_BreakoutLTR559_obj_t { mp_obj_base_t base; BreakoutLTR559 *breakout; + _PimoroniI2C_obj_t *i2c; } breakout_ltr559_BreakoutLTR559_obj_t; /***** Print *****/ @@ -67,17 +62,12 @@ mp_obj_t BreakoutLTR559_make_new(const mp_obj_type_t *type, size_t n_args, size_ mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; mp_arg_parse_all_kw_array(n_args, n_kw, all_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); - if(!MP_OBJ_IS_TYPE(args[ARG_i2c].u_obj, &PimoroniI2C_type)) { - mp_raise_ValueError(MP_ERROR_TEXT("BreakoutLTR559: Bad i2C object")); - return mp_const_none; - } - - _PimoroniI2C_obj_t *i2c = (_PimoroniI2C_obj_t *)MP_OBJ_TO_PTR(args[ARG_i2c].u_obj); - self = m_new_obj(breakout_ltr559_BreakoutLTR559_obj_t); self->base.type = &breakout_ltr559_BreakoutLTR559_type; - self->breakout = new BreakoutLTR559(i2c->i2c, args[ARG_interrupt].u_int); + self->i2c = PimoroniI2C_from_machine_i2c_or_native(args[ARG_i2c].u_obj); + + self->breakout = new BreakoutLTR559((pimoroni::I2C *)(self->i2c->i2c), args[ARG_interrupt].u_int); if(!self->breakout->init()) { mp_raise_msg(&mp_type_RuntimeError, "BreakoutLTR559: breakout not found when initialising"); diff --git a/micropython/modules/breakout_matrix11x7/breakout_matrix11x7.cpp b/micropython/modules/breakout_matrix11x7/breakout_matrix11x7.cpp index 06d89c90..072e91b7 100644 --- a/micropython/modules/breakout_matrix11x7/breakout_matrix11x7.cpp +++ b/micropython/modules/breakout_matrix11x7/breakout_matrix11x7.cpp @@ -14,16 +14,11 @@ extern "C" { #include "breakout_matrix11x7.h" #include "pimoroni_i2c.h" -/***** I2C Struct *****/ -typedef struct _PimoroniI2C_obj_t { - mp_obj_base_t base; - I2C *i2c; -} _PimoroniI2C_obj_t; - /***** Variables Struct *****/ typedef struct _breakout_matrix11x7_BreakoutMatrix11x7_obj_t { mp_obj_base_t base; BreakoutMatrix11x7 *breakout; + _PimoroniI2C_obj_t *i2c; } breakout_matrix11x7_BreakoutMatrix11x7_obj_t; /***** Print *****/ @@ -64,18 +59,12 @@ mp_obj_t BreakoutMatrix11x7_make_new(const mp_obj_type_t *type, size_t n_args, s mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; mp_arg_parse_all_kw_array(n_args, n_kw, all_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); - // Get I2C bus. - if(!MP_OBJ_IS_TYPE(args[ARG_i2c].u_obj, &PimoroniI2C_type)) { - mp_raise_ValueError(MP_ERROR_TEXT("BreakoutMatrix11x7: Bad i2C object")); - return mp_const_none; - } - - _PimoroniI2C_obj_t *i2c = (_PimoroniI2C_obj_t *)MP_OBJ_TO_PTR(args[ARG_i2c].u_obj); - self = m_new_obj(breakout_matrix11x7_BreakoutMatrix11x7_obj_t); self->base.type = &breakout_matrix11x7_BreakoutMatrix11x7_type; - self->breakout = new BreakoutMatrix11x7(i2c->i2c, args[ARG_address].u_int); + self->i2c = PimoroniI2C_from_machine_i2c_or_native(args[ARG_i2c].u_obj); + + self->breakout = new BreakoutMatrix11x7((pimoroni::I2C *)(self->i2c->i2c), args[ARG_address].u_int); if(!self->breakout->init()) { mp_raise_msg(&mp_type_RuntimeError, "BreakoutMatrix11x7: breakout not found when initialising"); diff --git a/micropython/modules/breakout_mics6814/breakout_mics6814.cpp b/micropython/modules/breakout_mics6814/breakout_mics6814.cpp index 3994faac..b7802c18 100644 --- a/micropython/modules/breakout_mics6814/breakout_mics6814.cpp +++ b/micropython/modules/breakout_mics6814/breakout_mics6814.cpp @@ -14,16 +14,11 @@ extern "C" { #include "breakout_mics6814.h" #include "pimoroni_i2c.h" -/***** I2C Struct *****/ -typedef struct _PimoroniI2C_obj_t { - mp_obj_base_t base; - I2C *i2c; -} _PimoroniI2C_obj_t; - /***** Variables Struct *****/ typedef struct _breakout_mics6814_BreakoutMICS6814_obj_t { mp_obj_base_t base; BreakoutMICS6814 *breakout; + _PimoroniI2C_obj_t *i2c; } breakout_mics6814_BreakoutMICS6814_obj_t; /***** Print *****/ @@ -68,18 +63,12 @@ mp_obj_t BreakoutMICS6814_make_new(const mp_obj_type_t *type, size_t n_args, siz mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; mp_arg_parse_all_kw_array(n_args, n_kw, all_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); - // Get I2C bus. - if(!MP_OBJ_IS_TYPE(args[ARG_i2c].u_obj, &PimoroniI2C_type)) { - mp_raise_ValueError(MP_ERROR_TEXT("BreakoutMICS6814: Bad i2C object")); - return mp_const_none; - } - - _PimoroniI2C_obj_t *i2c = (_PimoroniI2C_obj_t *)MP_OBJ_TO_PTR(args[ARG_i2c].u_obj); - self = m_new_obj(breakout_mics6814_BreakoutMICS6814_obj_t); self->base.type = &breakout_mics6814_BreakoutMICS6814_type; - self->breakout = new BreakoutMICS6814(i2c->i2c, args[ARG_address].u_int, args[ARG_interrupt].u_int); + self->i2c = PimoroniI2C_from_machine_i2c_or_native(args[ARG_i2c].u_obj); + + self->breakout = new BreakoutMICS6814((pimoroni::I2C *)(self->i2c->i2c), args[ARG_address].u_int, args[ARG_interrupt].u_int); if(!self->breakout->init()) { mp_raise_msg(&mp_type_RuntimeError, "BreakoutMICS6814: breakout not found when initialising"); diff --git a/micropython/modules/breakout_msa301/breakout_msa301.cpp b/micropython/modules/breakout_msa301/breakout_msa301.cpp index bb21fed3..46c9eb57 100644 --- a/micropython/modules/breakout_msa301/breakout_msa301.cpp +++ b/micropython/modules/breakout_msa301/breakout_msa301.cpp @@ -13,16 +13,11 @@ extern "C" { #include "breakout_msa301.h" #include "pimoroni_i2c.h" -/***** I2C Struct *****/ -typedef struct _PimoroniI2C_obj_t { - mp_obj_base_t base; - I2C *i2c; -} _PimoroniI2C_obj_t; - /***** Variables Struct *****/ typedef struct _breakout_msa301_BreakoutMSA301_obj_t { mp_obj_base_t base; BreakoutMSA301 *breakout; + _PimoroniI2C_obj_t *i2c; } breakout_msa301_BreakoutMSA301_obj_t; /***** Print *****/ @@ -61,17 +56,12 @@ mp_obj_t BreakoutMSA301_make_new(const mp_obj_type_t *type, size_t n_args, size_ mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; mp_arg_parse_all_kw_array(n_args, n_kw, all_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); - if(!MP_OBJ_IS_TYPE(args[ARG_i2c].u_obj, &PimoroniI2C_type)) { - mp_raise_ValueError(MP_ERROR_TEXT("BreakoutMSA301: Bad i2C object")); - return mp_const_none; - } - - _PimoroniI2C_obj_t *i2c = (_PimoroniI2C_obj_t *)MP_OBJ_TO_PTR(args[ARG_i2c].u_obj); - self = m_new_obj(breakout_msa301_BreakoutMSA301_obj_t); self->base.type = &breakout_msa301_BreakoutMSA301_type; - self->breakout = new BreakoutMSA301(i2c->i2c, args[ARG_interrupt].u_int); + self->i2c = PimoroniI2C_from_machine_i2c_or_native(args[ARG_i2c].u_obj); + + self->breakout = new BreakoutMSA301((pimoroni::I2C *)(self->i2c->i2c), args[ARG_interrupt].u_int); if(!self->breakout->init()) { mp_raise_msg(&mp_type_RuntimeError, "BreakoutMSA301: breakout not found when initialising"); diff --git a/micropython/modules/breakout_potentiometer/breakout_potentiometer.cpp b/micropython/modules/breakout_potentiometer/breakout_potentiometer.cpp index 90fc24d3..a838e330 100644 --- a/micropython/modules/breakout_potentiometer/breakout_potentiometer.cpp +++ b/micropython/modules/breakout_potentiometer/breakout_potentiometer.cpp @@ -14,16 +14,11 @@ extern "C" { #include "breakout_potentiometer.h" #include "pimoroni_i2c.h" -/***** I2C Struct *****/ -typedef struct _PimoroniI2C_obj_t { - mp_obj_base_t base; - I2C *i2c; -} _PimoroniI2C_obj_t; - /***** Variables Struct *****/ typedef struct _breakout_potentiometer_BreakoutPotentiometer_obj_t { mp_obj_base_t base; BreakoutPotentiometer *breakout; + _PimoroniI2C_obj_t *i2c; } breakout_potentiometer_BreakoutPotentiometer_obj_t; /***** Print *****/ @@ -68,17 +63,12 @@ mp_obj_t BreakoutPotentiometer_make_new(const mp_obj_type_t *type, size_t n_args mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; mp_arg_parse_all_kw_array(n_args, n_kw, all_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); - if(!MP_OBJ_IS_TYPE(args[ARG_i2c].u_obj, &PimoroniI2C_type)) { - mp_raise_ValueError(MP_ERROR_TEXT("BreakoutPotentiometer: Bad i2C object")); - return mp_const_none; - } - - _PimoroniI2C_obj_t *i2c = (_PimoroniI2C_obj_t *)MP_OBJ_TO_PTR(args[ARG_i2c].u_obj); - self = m_new_obj(breakout_potentiometer_BreakoutPotentiometer_obj_t); self->base.type = &breakout_potentiometer_BreakoutPotentiometer_type; - self->breakout = new BreakoutPotentiometer(i2c->i2c, args[ARG_interrupt].u_int); + self->i2c = PimoroniI2C_from_machine_i2c_or_native(args[ARG_i2c].u_obj); + + self->breakout = new BreakoutPotentiometer((pimoroni::I2C *)(self->i2c->i2c), args[ARG_interrupt].u_int); if(!self->breakout->init()) { mp_raise_msg(&mp_type_RuntimeError, "BreakoutPotentiometer: breakout not found when initialising"); diff --git a/micropython/modules/breakout_rgbmatrix5x5/breakout_rgbmatrix5x5.cpp b/micropython/modules/breakout_rgbmatrix5x5/breakout_rgbmatrix5x5.cpp index c1c80676..b7d763be 100644 --- a/micropython/modules/breakout_rgbmatrix5x5/breakout_rgbmatrix5x5.cpp +++ b/micropython/modules/breakout_rgbmatrix5x5/breakout_rgbmatrix5x5.cpp @@ -14,16 +14,11 @@ extern "C" { #include "breakout_rgbmatrix5x5.h" #include "pimoroni_i2c.h" -/***** I2C Struct *****/ -typedef struct _PimoroniI2C_obj_t { - mp_obj_base_t base; - I2C *i2c; -} _PimoroniI2C_obj_t; - /***** Variables Struct *****/ typedef struct _breakout_rgbmatrix5x5_BreakoutRGBMatrix5x5_obj_t { mp_obj_base_t base; BreakoutRGBMatrix5x5 *breakout; + _PimoroniI2C_obj_t *i2c; } breakout_rgbmatrix5x5_BreakoutRGBMatrix5x5_obj_t; /***** Print *****/ @@ -64,18 +59,12 @@ mp_obj_t BreakoutRGBMatrix5x5_make_new(const mp_obj_type_t *type, size_t n_args, mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; mp_arg_parse_all_kw_array(n_args, n_kw, all_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); - // Get I2C bus. - if(!MP_OBJ_IS_TYPE(args[ARG_i2c].u_obj, &PimoroniI2C_type)) { - mp_raise_ValueError(MP_ERROR_TEXT("BreakoutRGBMatrix5x5: Bad i2C object")); - return mp_const_none; - } - - _PimoroniI2C_obj_t *i2c = (_PimoroniI2C_obj_t *)MP_OBJ_TO_PTR(args[ARG_i2c].u_obj); - self = m_new_obj(breakout_rgbmatrix5x5_BreakoutRGBMatrix5x5_obj_t); self->base.type = &breakout_rgbmatrix5x5_BreakoutRGBMatrix5x5_type; - self->breakout = new BreakoutRGBMatrix5x5(i2c->i2c, args[ARG_address].u_int); + self->i2c = PimoroniI2C_from_machine_i2c_or_native(args[ARG_i2c].u_obj); + + self->breakout = new BreakoutRGBMatrix5x5((pimoroni::I2C *)(self->i2c->i2c), args[ARG_address].u_int); if(!self->breakout->init()) { mp_raise_msg(&mp_type_RuntimeError, "BreakoutRGBMatrix5x5: breakout not found when initialising"); diff --git a/micropython/modules/breakout_rtc/breakout_rtc.cpp b/micropython/modules/breakout_rtc/breakout_rtc.cpp index a391258c..e91bdf69 100644 --- a/micropython/modules/breakout_rtc/breakout_rtc.cpp +++ b/micropython/modules/breakout_rtc/breakout_rtc.cpp @@ -16,16 +16,11 @@ extern "C" { #include "breakout_rtc.h" #include "pimoroni_i2c.h" -/***** I2C Struct *****/ -typedef struct _PimoroniI2C_obj_t { - mp_obj_base_t base; - I2C *i2c; -} _PimoroniI2C_obj_t; - /***** Variables Struct *****/ typedef struct _breakout_rtc_BreakoutRTC_obj_t { mp_obj_base_t base; BreakoutRTC *breakout; + _PimoroniI2C_obj_t *i2c; } breakout_rtc_BreakoutRTC_obj_t; /***** Print *****/ @@ -64,18 +59,12 @@ mp_obj_t BreakoutRTC_make_new(const mp_obj_type_t *type, size_t n_args, size_t n mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; mp_arg_parse_all_kw_array(n_args, n_kw, all_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); - // Get I2C bus. - if(!MP_OBJ_IS_TYPE(args[ARG_i2c].u_obj, &PimoroniI2C_type)) { - mp_raise_ValueError(MP_ERROR_TEXT("BreakoutRTC: Bad i2C object")); - return mp_const_none; - } - - _PimoroniI2C_obj_t *i2c = (_PimoroniI2C_obj_t *)MP_OBJ_TO_PTR(args[ARG_i2c].u_obj); - self = m_new_obj(breakout_rtc_BreakoutRTC_obj_t); self->base.type = &breakout_rtc_BreakoutRTC_type; - self->breakout = new BreakoutRTC(i2c->i2c, args[ARG_interrupt].u_int); + self->i2c = PimoroniI2C_from_machine_i2c_or_native(args[ARG_i2c].u_obj); + + self->breakout = new BreakoutRTC((pimoroni::I2C *)(self->i2c->i2c), args[ARG_interrupt].u_int); if(!self->breakout->init()) { mp_raise_msg(&mp_type_RuntimeError, "BreakoutRTC: breakout not found when initialising"); diff --git a/micropython/modules/breakout_scd41/breakout_scd41.cpp b/micropython/modules/breakout_scd41/breakout_scd41.cpp index e797b796..efc7bfc2 100644 --- a/micropython/modules/breakout_scd41/breakout_scd41.cpp +++ b/micropython/modules/breakout_scd41/breakout_scd41.cpp @@ -16,12 +16,6 @@ extern "C" { #include "breakout_scd41.h" #include "pimoroni_i2c.h" -/***** I2C Struct *****/ -typedef struct _PimoroniI2C_obj_t { - mp_obj_base_t base; - I2C *i2c; -} _PimoroniI2C_obj_t; - #define NOT_INITIALISED_MSG "SCD41: Not initialised. Call scd41.init() first." #define READ_FAIL_MSG "SCD41: Reading failed." #define FAIL_MSG "SCD41: Error." @@ -38,15 +32,9 @@ mp_obj_t scd41_init(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; mp_arg_parse_all(n_args, pos_args, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); - // Perform the I2C type checking incantations - if(!MP_OBJ_IS_TYPE(args[ARG_i2c].u_obj, &PimoroniI2C_type)) { - mp_raise_ValueError(MP_ERROR_TEXT("SCD41: Bad i2C object")); - return mp_const_none; - } + _PimoroniI2C_obj_t *i2c = PimoroniI2C_from_machine_i2c_or_native(args[ARG_i2c].u_obj); - _PimoroniI2C_obj_t *i2c = (_PimoroniI2C_obj_t *)MP_OBJ_TO_PTR(args[ARG_i2c].u_obj); - - sensirion_i2c_hal_init(i2c->i2c); + sensirion_i2c_hal_init((pimoroni::I2C*)i2c->i2c); scd4x_stop_periodic_measurement(); scd4x_reinit(); scd41_initialised = true; diff --git a/micropython/modules/breakout_sgp30/breakout_sgp30.cpp b/micropython/modules/breakout_sgp30/breakout_sgp30.cpp index 41ff3029..21f59739 100644 --- a/micropython/modules/breakout_sgp30/breakout_sgp30.cpp +++ b/micropython/modules/breakout_sgp30/breakout_sgp30.cpp @@ -13,16 +13,11 @@ extern "C" { #include "breakout_sgp30.h" #include "pimoroni_i2c.h" -/***** I2C Struct *****/ -typedef struct _PimoroniI2C_obj_t { - mp_obj_base_t base; - I2C *i2c; -} _PimoroniI2C_obj_t; - /***** Variables Struct *****/ typedef struct _breakout_sgp30_BreakoutSGP30_obj_t { mp_obj_base_t base; BreakoutSGP30 *breakout; + _PimoroniI2C_obj_t *i2c; } breakout_sgp30_BreakoutSGP30_obj_t; /***** Print *****/ @@ -57,18 +52,12 @@ mp_obj_t BreakoutSGP30_make_new(const mp_obj_type_t *type, size_t n_args, size_t mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; mp_arg_parse_all_kw_array(n_args, n_kw, all_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); - // Get I2C bus. - if(!MP_OBJ_IS_TYPE(args[ARG_i2c].u_obj, &PimoroniI2C_type)) { - mp_raise_ValueError(MP_ERROR_TEXT("BreakoutSGP30: Bad i2C object")); - return mp_const_none; - } - - _PimoroniI2C_obj_t *i2c = (_PimoroniI2C_obj_t *)MP_OBJ_TO_PTR(args[ARG_i2c].u_obj); - self = m_new_obj(breakout_sgp30_BreakoutSGP30_obj_t); self->base.type = &breakout_sgp30_BreakoutSGP30_type; - self->breakout = new BreakoutSGP30(i2c->i2c); + self->i2c = PimoroniI2C_from_machine_i2c_or_native(args[ARG_i2c].u_obj); + + self->breakout = new BreakoutSGP30((pimoroni::I2C *)(self->i2c->i2c)); if(!self->breakout->init()) { mp_raise_msg(&mp_type_RuntimeError, "BreakoutSGP30: breakout not found when initialising"); diff --git a/micropython/modules/breakout_trackball/breakout_trackball.cpp b/micropython/modules/breakout_trackball/breakout_trackball.cpp index eb62513e..54f3da82 100644 --- a/micropython/modules/breakout_trackball/breakout_trackball.cpp +++ b/micropython/modules/breakout_trackball/breakout_trackball.cpp @@ -14,16 +14,11 @@ extern "C" { #include "breakout_trackball.h" #include "pimoroni_i2c.h" -/***** I2C Struct *****/ -typedef struct _PimoroniI2C_obj_t { - mp_obj_base_t base; - I2C *i2c; -} _PimoroniI2C_obj_t; - /***** Variables Struct *****/ typedef struct _breakout_trackball_BreakoutTrackball_obj_t { mp_obj_base_t base; BreakoutTrackball *breakout; + _PimoroniI2C_obj_t *i2c; } breakout_trackball_BreakoutTrackball_obj_t; /***** Print *****/ @@ -68,18 +63,12 @@ mp_obj_t BreakoutTrackball_make_new(const mp_obj_type_t *type, size_t n_args, si mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; mp_arg_parse_all_kw_array(n_args, n_kw, all_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); - // Get I2C bus. - if(!MP_OBJ_IS_TYPE(args[ARG_i2c].u_obj, &PimoroniI2C_type)) { - mp_raise_ValueError(MP_ERROR_TEXT("BreakoutSGP30: Bad i2C object")); - return mp_const_none; - } - - _PimoroniI2C_obj_t *i2c = (_PimoroniI2C_obj_t *)MP_OBJ_TO_PTR(args[ARG_i2c].u_obj); - self = m_new_obj(breakout_trackball_BreakoutTrackball_obj_t); self->base.type = &breakout_trackball_BreakoutTrackball_type; - self->breakout = new BreakoutTrackball(i2c->i2c, args[ARG_address].u_int, args[ARG_interrupt].u_int); + self->i2c = PimoroniI2C_from_machine_i2c_or_native(args[ARG_i2c].u_obj); + + self->breakout = new BreakoutTrackball((pimoroni::I2C *)(self->i2c->i2c), args[ARG_address].u_int, args[ARG_interrupt].u_int); if(!self->breakout->init()) { mp_raise_msg(&mp_type_RuntimeError, "Trackball breakout not found when initialising"); diff --git a/micropython/modules/breakout_vl53l5cx/vl53l5cx.cpp b/micropython/modules/breakout_vl53l5cx/vl53l5cx.cpp index 335d2aba..67b3a1f8 100644 --- a/micropython/modules/breakout_vl53l5cx/vl53l5cx.cpp +++ b/micropython/modules/breakout_vl53l5cx/vl53l5cx.cpp @@ -19,13 +19,6 @@ typedef struct _mp_obj_float_t { const mp_obj_float_t const_float_1 = {{&mp_type_float}, 1.0f}; -/***** I2C Struct *****/ -typedef struct _PimoroniI2C_obj_t { - mp_obj_base_t base; - pimoroni::I2C *i2c; -} _PimoroniI2C_obj_t; - - /***** Variables Struct *****/ typedef struct _VL53L5CX_obj_t { mp_obj_base_t base; @@ -77,17 +70,12 @@ mp_obj_t VL53L5CX_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; mp_arg_parse_all_kw_array(n_args, n_kw, all_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); - if(!MP_OBJ_IS_TYPE(args[ARG_i2c].u_obj, &PimoroniI2C_type)) { - mp_raise_ValueError(MP_ERROR_TEXT("VL53L5CX: Bad i2C object")); - return mp_const_none; - } - - _PimoroniI2C_obj_t *i2c = (_PimoroniI2C_obj_t *)MP_OBJ_TO_PTR(args[ARG_i2c].u_obj); int addr = args[ARG_addr].u_int; self = m_new_obj_with_finaliser(_VL53L5CX_obj_t); self->base.type = &VL53L5CX_type; - self->i2c = i2c; + + self->i2c = PimoroniI2C_from_machine_i2c_or_native(args[ARG_i2c].u_obj); mp_buffer_info_t bufinfo; const size_t firmware_size = 84 * 1024; @@ -112,7 +100,7 @@ mp_obj_t VL53L5CX_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw mp_raise_ValueError("Firmware must be 84k bytes!"); } - self->breakout = new pimoroni::VL53L5CX(i2c->i2c, (uint8_t *)bufinfo.buf, addr); + self->breakout = new pimoroni::VL53L5CX((pimoroni::I2C*)self->i2c->i2c, (uint8_t *)bufinfo.buf, addr); if(!self->breakout->init()) { mp_raise_msg(&mp_type_RuntimeError, "VL53L5CX: init error"); diff --git a/micropython/modules/pimoroni_i2c/pimoroni_i2c.c b/micropython/modules/pimoroni_i2c/pimoroni_i2c.c index e91b53b3..6070e51f 100644 --- a/micropython/modules/pimoroni_i2c/pimoroni_i2c.c +++ b/micropython/modules/pimoroni_i2c/pimoroni_i2c.c @@ -5,15 +5,20 @@ //////////////////////////////////////////////////////////////////////////////////////////////////// -/***** Methods *****/ +/* MP_DEFINE_CONST_FUN_OBJ_1(PimoroniI2C___del___obj, PimoroniI2C___del__); -/***** Binding of Methods *****/ STATIC const mp_rom_map_elem_t PimoroniI2C_locals_dict_table[] = { { MP_ROM_QSTR(MP_QSTR___del__), MP_ROM_PTR(&PimoroniI2C___del___obj) }, }; STATIC MP_DEFINE_CONST_DICT(PimoroniI2C_locals_dict, PimoroniI2C_locals_dict_table); +*/ + +STATIC const mp_machine_i2c_p_t machine_i2c_p = { + .transfer = mp_machine_i2c_transfer_adaptor, + .transfer_single = machine_i2c_transfer_single, +}; /***** Class Definition *****/ const mp_obj_type_t PimoroniI2C_type = { @@ -21,7 +26,8 @@ const mp_obj_type_t PimoroniI2C_type = { .name = MP_QSTR_pimoroni_i2c, .print = PimoroniI2C_print, .make_new = PimoroniI2C_make_new, - .locals_dict = (mp_obj_dict_t*)&PimoroniI2C_locals_dict, + .protocol = &machine_i2c_p, + .locals_dict = (mp_obj_dict_t*)&mp_machine_i2c_locals_dict, }; diff --git a/micropython/modules/pimoroni_i2c/pimoroni_i2c.cpp b/micropython/modules/pimoroni_i2c/pimoroni_i2c.cpp index f8924fd2..6167cdc3 100644 --- a/micropython/modules/pimoroni_i2c/pimoroni_i2c.cpp +++ b/micropython/modules/pimoroni_i2c/pimoroni_i2c.cpp @@ -12,19 +12,30 @@ using namespace pimoroni; extern "C" { #include "pimoroni_i2c.h" - -/***** Variables Struct *****/ -typedef struct _PimoroniI2C_obj_t { - mp_obj_base_t base; - I2C *i2c; -} _PimoroniI2C_obj_t; +#include "py/mperrno.h" +#include "extmod/machine_i2c.h" -/***** Print *****/ +_PimoroniI2C_obj_t* PimoroniI2C_from_machine_i2c_or_native(mp_obj_t i2c_obj) { + if(MP_OBJ_IS_TYPE(i2c_obj, &PimoroniI2C_type)) { + return (_PimoroniI2C_obj_t *)MP_OBJ_TO_PTR(i2c_obj); + } else if(MP_OBJ_IS_TYPE(i2c_obj, &machine_hw_i2c_type)) { + _PimoroniI2C_obj_t *pimoroni_i2c = m_new_obj(_PimoroniI2C_obj_t); + machine_i2c_obj_t *machine_i2c = (machine_i2c_obj_t *)MP_OBJ_TO_PTR(i2c_obj); + pimoroni_i2c = m_new_obj(_PimoroniI2C_obj_t); + pimoroni_i2c->base.type = &PimoroniI2C_type; + pimoroni_i2c->i2c = new I2C(machine_i2c->sda, machine_i2c->scl, machine_i2c->freq); + return pimoroni_i2c; + } else { + mp_raise_ValueError(MP_ERROR_TEXT("Bad I2C object")); + return nullptr; + } +} + void PimoroniI2C_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind) { (void)kind; //Unused input parameter _PimoroniI2C_obj_t *self = MP_OBJ_TO_PTR2(self_in, _PimoroniI2C_obj_t); - I2C* i2c = self->i2c; + I2C* i2c = (I2C*)self->i2c; mp_print_str(print, "PimoroniI2C("); mp_print_str(print, "i2c = "); @@ -39,14 +50,6 @@ void PimoroniI2C_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_ mp_print_str(print, ")"); } -/***** Destructor ******/ -mp_obj_t PimoroniI2C___del__(mp_obj_t self_in) { - _PimoroniI2C_obj_t *self = MP_OBJ_TO_PTR2(self_in, _PimoroniI2C_obj_t); - delete self->i2c; - return mp_const_none; -} - -/***** Constructor *****/ mp_obj_t PimoroniI2C_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *all_args) { _PimoroniI2C_obj_t *self = nullptr; @@ -75,7 +78,7 @@ mp_obj_t PimoroniI2C_make_new(const mp_obj_type_t *type, size_t n_args, size_t n mp_raise_ValueError(MP_ERROR_TEXT("bad SCL pin")); } - self = m_new_obj_with_finaliser(_PimoroniI2C_obj_t); + self = m_new_obj(_PimoroniI2C_obj_t); self->base.type = &PimoroniI2C_type; self->i2c = new I2C(sda, scl, baud); @@ -83,4 +86,48 @@ mp_obj_t PimoroniI2C_make_new(const mp_obj_type_t *type, size_t n_args, size_t n return MP_OBJ_FROM_PTR(self); } +// Reimplementation of the RP2 port's machine_i2c_transfer_single in terms of Pimoroni I2C +// https://github.com/micropython/micropython/blob/1fb01bd6c5dc350f3c617ca8edae8dea9e5516ae/ports/rp2/machine_i2c.c#L123 +int machine_i2c_transfer_single(mp_obj_base_t *self_in, uint16_t addr, size_t len, uint8_t *buf, unsigned int flags) { + _PimoroniI2C_obj_t *self = (_PimoroniI2C_obj_t *)self_in; + I2C *i2c = (I2C*)self->i2c; + int ret; + bool nostop = !(flags & MP_MACHINE_I2C_FLAG_STOP); + if (flags & MP_MACHINE_I2C_FLAG_READ) { + ret = i2c_read_blocking(i2c->get_i2c(), addr, buf, len, nostop); + } else { + if (len == 0) { + // Workaround issue with hardware I2C not accepting zero-length writes. + mp_machine_soft_i2c_obj_t soft_i2c = { + .base = { &mp_machine_soft_i2c_type }, + .us_delay = 500000 / i2c->get_baudrate() + 1, + .us_timeout = 50000, + .scl = i2c->get_scl(), + .sda = i2c->get_sda(), + }; + mp_machine_i2c_buf_t bufs = { + .len = len, + .buf = buf, + }; + mp_hal_pin_open_drain(i2c->get_scl()); + mp_hal_pin_open_drain(i2c->get_sda()); + ret = mp_machine_soft_i2c_transfer(&soft_i2c.base, addr, 1, &bufs, flags); + gpio_set_function(i2c->get_scl(), GPIO_FUNC_I2C); + gpio_set_function(i2c->get_sda(), GPIO_FUNC_I2C); + return ret; + } else { + ret = i2c_write_blocking(i2c->get_i2c(), addr, buf, len, nostop); + } + } + if (ret < 0) { + if (ret == PICO_ERROR_TIMEOUT) { + return -MP_ETIMEDOUT; + } else { + return -MP_EIO; + } + } else { + return ret; + } +} + } \ No newline at end of file diff --git a/micropython/modules/pimoroni_i2c/pimoroni_i2c.h b/micropython/modules/pimoroni_i2c/pimoroni_i2c.h index 3351a8af..af7dbc97 100644 --- a/micropython/modules/pimoroni_i2c/pimoroni_i2c.h +++ b/micropython/modules/pimoroni_i2c/pimoroni_i2c.h @@ -1,12 +1,34 @@ // Include MicroPython API. #include "py/runtime.h" +#include "extmod/machine_i2c.h" +#include "hardware/i2c.h" /***** Extern of Class Definition *****/ extern const mp_obj_type_t PimoroniI2C_type; +typedef struct _PimoroniI2C_obj_t { + mp_obj_base_t base; + void *i2c; +} _PimoroniI2C_obj_t; + /***** Extern of Class Methods *****/ extern void PimoroniI2C_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind); extern mp_obj_t PimoroniI2C_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *all_args); extern mp_obj_t PimoroniI2C___del__(mp_obj_t self_in); -extern bool Pimoroni_mp_obj_to_i2c(mp_obj_t in, void *out); \ No newline at end of file +extern bool Pimoroni_mp_obj_to_i2c(mp_obj_t in, void *out); + +extern const mp_obj_type_t machine_hw_i2c_type; + +typedef struct _machine_i2c_obj_t { + mp_obj_base_t base; + i2c_inst_t *const i2c_inst; + uint8_t i2c_id; + uint8_t scl; + uint8_t sda; + uint32_t freq; +} machine_i2c_obj_t; + +extern int machine_i2c_transfer_single(mp_obj_base_t *self_in, uint16_t addr, size_t len, uint8_t *buf, unsigned int flags); + +_PimoroniI2C_obj_t* PimoroniI2C_from_machine_i2c_or_native(mp_obj_t i2c_obj); \ No newline at end of file