kopia lustrzana https://github.com/pimoroni/pimoroni-pico
Port Encoder and Potentiometer to Pimoroni I2C
Wraps just enough of Pimoroni I2C to make it work in MicroPython. Ports Encoder and Potentiometer to use a PimorniI2C() instance in lieu of sda/scl.pull/129/head
rodzic
7fa9e5bdca
commit
b2056040e8
|
@ -12,6 +12,13 @@ using namespace pimoroni;
|
|||
|
||||
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 {
|
||||
|
@ -50,12 +57,10 @@ void BreakoutEncoder_print(const mp_print_t *print, mp_obj_t self_in, mp_print_k
|
|||
mp_obj_t BreakoutEncoder_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *all_args) {
|
||||
breakout_encoder_BreakoutEncoder_obj_t *self = nullptr;
|
||||
|
||||
enum { ARG_i2c, ARG_address, ARG_sda, ARG_scl, ARG_interrupt };
|
||||
enum { ARG_i2c, ARG_address, ARG_interrupt };
|
||||
static const mp_arg_t allowed_args[] = {
|
||||
{ MP_QSTR_i2c, MP_ARG_INT, {.u_int = -1} },
|
||||
{ MP_QSTR_i2c, MP_ARG_OBJ, {.u_obj = nullptr} },
|
||||
{ MP_QSTR_address, MP_ARG_INT, {.u_int = BreakoutEncoder::DEFAULT_I2C_ADDRESS} },
|
||||
{ MP_QSTR_sda, MP_ARG_INT, {.u_int = I2C_DEFAULT_SDA} },
|
||||
{ MP_QSTR_scl, MP_ARG_INT, {.u_int = I2C_DEFAULT_SCL} },
|
||||
{ MP_QSTR_interrupt, MP_ARG_INT, {.u_int = PIN_UNUSED} },
|
||||
};
|
||||
|
||||
|
@ -63,30 +68,17 @@ 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);
|
||||
|
||||
// Get I2C bus.
|
||||
int i2c_id = args[ARG_i2c].u_int;
|
||||
int sda = args[ARG_sda].u_int;
|
||||
int scl = args[ARG_scl].u_int;
|
||||
|
||||
if(i2c_id == -1) {
|
||||
i2c_id = (sda >> 1) & 0b1; // If no i2c specified, choose the one for the given SDA pin
|
||||
}
|
||||
if(i2c_id < 0 || i2c_id > 1) {
|
||||
mp_raise_msg_varg(&mp_type_ValueError, MP_ERROR_TEXT("I2C(%d) doesn't exist"), i2c_id);
|
||||
if(!MP_OBJ_IS_TYPE(args[ARG_i2c].u_obj, &PimoroniI2C_type)) {
|
||||
mp_raise_ValueError(MP_ERROR_TEXT("bad i2C object"));
|
||||
return mp_const_none;
|
||||
}
|
||||
|
||||
if(!IS_VALID_SDA(i2c_id, sda)) {
|
||||
mp_raise_ValueError(MP_ERROR_TEXT("bad SDA pin"));
|
||||
}
|
||||
|
||||
if(!IS_VALID_SCL(i2c_id, scl)) {
|
||||
mp_raise_ValueError(MP_ERROR_TEXT("bad SCL pin"));
|
||||
}
|
||||
_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(args[ARG_address].u_int, sda, scl, args[ARG_interrupt].u_int);
|
||||
self->breakout = new BreakoutEncoder(i2c->i2c, args[ARG_address].u_int, args[ARG_interrupt].u_int);
|
||||
|
||||
if(!self->breakout->init()) {
|
||||
mp_raise_msg(&mp_type_RuntimeError, "Encoder breakout not found when initialising");
|
||||
|
|
|
@ -12,6 +12,13 @@ using namespace pimoroni;
|
|||
|
||||
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 {
|
||||
|
@ -50,12 +57,10 @@ void BreakoutPotentiometer_print(const mp_print_t *print, mp_obj_t self_in, mp_p
|
|||
mp_obj_t BreakoutPotentiometer_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *all_args) {
|
||||
breakout_potentiometer_BreakoutPotentiometer_obj_t *self = nullptr;
|
||||
|
||||
enum { ARG_i2c, ARG_address, ARG_sda, ARG_scl, ARG_interrupt };
|
||||
enum { ARG_i2c, ARG_interrupt };
|
||||
static const mp_arg_t allowed_args[] = {
|
||||
{ MP_QSTR_i2c, MP_ARG_INT, {.u_int = -1} },
|
||||
{ MP_QSTR_i2c, MP_ARG_OBJ, {.u_obj = nullptr} },
|
||||
{ MP_QSTR_address, MP_ARG_INT, {.u_int = BreakoutPotentiometer::DEFAULT_I2C_ADDRESS} },
|
||||
{ MP_QSTR_sda, MP_ARG_INT, {.u_int = I2C_DEFAULT_SDA} },
|
||||
{ MP_QSTR_scl, MP_ARG_INT, {.u_int = I2C_DEFAULT_SCL} },
|
||||
{ MP_QSTR_interrupt, MP_ARG_INT, {.u_int = PIN_UNUSED} },
|
||||
};
|
||||
|
||||
|
@ -63,30 +68,17 @@ 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);
|
||||
|
||||
// Get I2C bus.
|
||||
int i2c_id = args[ARG_i2c].u_int;
|
||||
int sda = args[ARG_sda].u_int;
|
||||
int scl = args[ARG_scl].u_int;
|
||||
|
||||
if(i2c_id == -1) {
|
||||
i2c_id = (sda >> 1) & 0b1; // If no i2c specified, choose the one for the given SDA pin
|
||||
}
|
||||
if(i2c_id < 0 || i2c_id > 1) {
|
||||
mp_raise_msg_varg(&mp_type_ValueError, MP_ERROR_TEXT("I2C(%d) doesn't exist"), i2c_id);
|
||||
if(!MP_OBJ_IS_TYPE(args[ARG_i2c].u_obj, &PimoroniI2C_type)) {
|
||||
mp_raise_ValueError(MP_ERROR_TEXT("bad i2C object"));
|
||||
return mp_const_none;
|
||||
}
|
||||
|
||||
if(!IS_VALID_SDA(i2c_id, sda)) {
|
||||
mp_raise_ValueError(MP_ERROR_TEXT("bad SDA pin"));
|
||||
}
|
||||
|
||||
if(!IS_VALID_SCL(i2c_id, scl)) {
|
||||
mp_raise_ValueError(MP_ERROR_TEXT("bad SCL pin"));
|
||||
}
|
||||
_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(args[ARG_address].u_int, sda, scl, args[ARG_interrupt].u_int);
|
||||
self->breakout = new BreakoutPotentiometer(i2c->i2c, args[ARG_interrupt].u_int);
|
||||
|
||||
if(!self->breakout->init()) {
|
||||
mp_raise_msg(&mp_type_RuntimeError, "Potentiometer breakout not found when initialising");
|
||||
|
|
|
@ -3,6 +3,8 @@ string(TOUPPER ${MOD_NAME} MOD_NAME_UPPER)
|
|||
add_library(usermod_${MOD_NAME} INTERFACE)
|
||||
|
||||
target_sources(usermod_${MOD_NAME} INTERFACE
|
||||
${CMAKE_CURRENT_LIST_DIR}/${MOD_NAME}.c
|
||||
${CMAKE_CURRENT_LIST_DIR}/${MOD_NAME}.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/../../../common/pimoroni_i2c.cpp
|
||||
)
|
||||
|
||||
|
@ -11,7 +13,7 @@ target_include_directories(usermod_${MOD_NAME} INTERFACE
|
|||
)
|
||||
|
||||
target_compile_definitions(usermod_${MOD_NAME} INTERFACE
|
||||
-DMODULE_${MOD_NAME_UPPER}_ENABLED=1
|
||||
MODULE_${MOD_NAME_UPPER}_ENABLED=1
|
||||
)
|
||||
|
||||
target_link_libraries(usermod INTERFACE usermod_${MOD_NAME})
|
|
@ -0,0 +1,47 @@
|
|||
#include "pimoroni_i2c.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// PimoroniI2C Class
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
/***** Methods *****/
|
||||
//MP_DEFINE_CONST_FUN_OBJ_KW(PimoroniI2C_read_obj, 2, PimoroniI2C_set_address);
|
||||
|
||||
/***** Binding of Methods *****/
|
||||
STATIC const mp_rom_map_elem_t PimoroniI2C_locals_dict_table[] = {
|
||||
};
|
||||
|
||||
STATIC MP_DEFINE_CONST_DICT(PimoroniI2C_locals_dict, PimoroniI2C_locals_dict_table);
|
||||
|
||||
/***** Class Definition *****/
|
||||
const mp_obj_type_t PimoroniI2C_type = {
|
||||
{ &mp_type_type },
|
||||
.name = MP_QSTR_pimoroni_i2c,
|
||||
.print = PimoroniI2C_print,
|
||||
.make_new = PimoroniI2C_make_new,
|
||||
.locals_dict = (mp_obj_dict_t*)&PimoroniI2C_locals_dict,
|
||||
};
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// breakout_potentiometer Module
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/***** Globals Table *****/
|
||||
STATIC const mp_map_elem_t pimoroni_i2c_globals_table[] = {
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR___name__), MP_OBJ_NEW_QSTR(MP_QSTR_pimoroni_i2c) },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_PimoroniI2C), (mp_obj_t)&PimoroniI2C_type },
|
||||
};
|
||||
STATIC MP_DEFINE_CONST_DICT(mp_module_pimoroni_i2c_globals, pimoroni_i2c_globals_table);
|
||||
|
||||
/***** Module Definition *****/
|
||||
const mp_obj_module_t pimoroni_i2c_user_cmodule = {
|
||||
.base = { &mp_type_module },
|
||||
.globals = (mp_obj_dict_t*)&mp_module_pimoroni_i2c_globals,
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
MP_REGISTER_MODULE(MP_QSTR_pimoroni_i2c, pimoroni_i2c_user_cmodule, MODULE_PIMORONI_I2C_ENABLED);
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
@ -0,0 +1,77 @@
|
|||
#include "common/pimoroni_i2c.hpp"
|
||||
#include <cstdio>
|
||||
|
||||
#define MP_OBJ_TO_PTR2(o, t) ((t *)(uintptr_t)(o))
|
||||
|
||||
// SDA/SCL on even/odd pins, I2C0/I2C1 on even/odd pairs of pins.
|
||||
#define IS_VALID_SCL(i2c, pin) (((pin) & 1) == 1 && (((pin) & 2) >> 1) == (i2c))
|
||||
#define IS_VALID_SDA(i2c, pin) (((pin) & 1) == 0 && (((pin) & 2) >> 1) == (i2c))
|
||||
|
||||
|
||||
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;
|
||||
|
||||
|
||||
/***** Print *****/
|
||||
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;
|
||||
mp_print_str(print, "PimoroniI2C(");
|
||||
|
||||
mp_print_str(print, "i2c = ");
|
||||
mp_obj_print_helper(print, mp_obj_new_int((i2c->get_i2c() == i2c0) ? 0 : 1), PRINT_REPR);
|
||||
|
||||
mp_print_str(print, ", sda = ");
|
||||
mp_obj_print_helper(print, mp_obj_new_int(i2c->get_sda()), PRINT_REPR);
|
||||
|
||||
mp_print_str(print, ", scl = ");
|
||||
mp_obj_print_helper(print, mp_obj_new_int(i2c->get_scl()), PRINT_REPR);
|
||||
|
||||
mp_print_str(print, ")");
|
||||
}
|
||||
|
||||
/***** 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;
|
||||
|
||||
enum { ARG_sda, ARG_scl };
|
||||
static const mp_arg_t allowed_args[] = {
|
||||
{ MP_QSTR_sda, MP_ARG_INT, {.u_int = I2C_DEFAULT_SDA} },
|
||||
{ MP_QSTR_scl, MP_ARG_INT, {.u_int = I2C_DEFAULT_SCL} },
|
||||
};
|
||||
|
||||
// Parse 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.
|
||||
int sda = args[ARG_sda].u_int;
|
||||
int scl = args[ARG_scl].u_int;
|
||||
int i2c_id = (sda >> 1) & 0b1; // i2c bus for given SDA pin
|
||||
|
||||
if(!IS_VALID_SDA(i2c_id, sda)) {
|
||||
mp_raise_ValueError(MP_ERROR_TEXT("bad SDA pin"));
|
||||
}
|
||||
|
||||
if(!IS_VALID_SCL(i2c_id, scl)) {
|
||||
mp_raise_ValueError(MP_ERROR_TEXT("bad SCL pin"));
|
||||
}
|
||||
|
||||
self = m_new_obj(_PimoroniI2C_obj_t);
|
||||
self->base.type = &PimoroniI2C_type;
|
||||
|
||||
self->i2c = new I2C(sda, scl);
|
||||
|
||||
return MP_OBJ_FROM_PTR(self);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
// Include MicroPython API.
|
||||
#include "py/runtime.h"
|
||||
|
||||
/***** Extern of Class Definition *****/
|
||||
extern const mp_obj_type_t PimoroniI2C_type;
|
||||
|
||||
/***** 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 bool Pimoroni_mp_obj_to_i2c(mp_obj_t in, void *out);
|
Ładowanie…
Reference in New Issue