Merge pull request #361 from pimoroni/patch-micropython-i2c-compat

MicroPython: Make Pimoroni I2C compatible with machine.I2C
This commit is contained in:
Philip Howard 2022-05-18 13:34:55 +01:00 committed by GitHub
commit b41b52e262
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
23 changed files with 176 additions and 314 deletions

View File

@ -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");

View File

@ -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");

View File

@ -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");

View File

@ -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");

View File

@ -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");

View File

@ -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");

View File

@ -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");

View File

@ -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");

View File

@ -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");

View File

@ -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");

View File

@ -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");

View File

@ -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");

View File

@ -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");

View File

@ -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");

View File

@ -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");

View File

@ -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");

View File

@ -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(<i2c instance>) 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;

View File

@ -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");

View File

@ -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");

View File

@ -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");

View File

@ -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,
};

View File

@ -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;
}
}
}

View File

@ -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);
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);