Micropython bindings for IOExpander breakout

pull/144/head
ZodiusInfuser 2021-05-12 00:01:35 +01:00 zatwierdzone przez Phil Howard
rodzic 31edcf8f93
commit d45a92fef3
8 zmienionych plików z 700 dodań i 59 usunięć

Wyświetl plik

@ -334,8 +334,11 @@ namespace pimoroni {
gpio_set_function(sda, GPIO_FUNC_I2C); gpio_pull_up(sda);
gpio_set_function(scl, GPIO_FUNC_I2C); gpio_pull_up(scl);
if(interrupt != -1) {
gpio_set_function(interrupt, GPIO_FUNC_SIO); gpio_set_dir(interrupt, GPIO_IN); gpio_pull_up(interrupt);
if(interrupt != PIN_UNUSED) {
gpio_set_function(interrupt, GPIO_FUNC_SIO);
gpio_set_dir(interrupt, GPIO_IN);
gpio_pull_up(interrupt);
enable_interrupt_out(true);
}
@ -398,11 +401,11 @@ namespace pimoroni {
clr_bit(reg::INT, int_bit::OUT_EN);
}
uint8_t IOExpander::get_interrupt_flag() {
if(interrupt != 0)
bool IOExpander::get_interrupt_flag() {
if(interrupt != PIN_UNUSED)
return !gpio_get(interrupt);
else
return get_bit(reg::INT, int_bit::TRIGD);
return (get_bit(reg::INT, int_bit::TRIGD) != 0);
}
void IOExpander::clear_interrupt_flag() {
@ -421,21 +424,14 @@ namespace pimoroni {
return succeeded;
}
void IOExpander::set_interrupt_callback(void (*callback)()) {
if(interrupt != 0 && callback != nullptr) {
//attachInterrupt(digitalPinToInterrupt(_interruptPin), callback, FALLING);
clear_interrupt_flag();
}
}
void IOExpander::pwm_load(bool wait_for_load) {
//Load new period and duty registers into buffer
// Load new period and duty registers into buffer
uint32_t start_time = millis();
set_bit(reg::PWMCON0, 6); //Set the "LOAD" bit of PWMCON0
set_bit(reg::PWMCON0, 6); // Set the "LOAD" bit of PWMCON0
if(wait_for_load) {
while(pwm_loading()) {
sleep_ms(1); //Wait for "LOAD" to complete
sleep_ms(1); // Wait for "LOAD" to complete
if(millis() - start_time >= timeout) {
if(debug)
printf("Timed out waiting for PWM load!");
@ -451,10 +447,10 @@ namespace pimoroni {
void IOExpander::pwm_clear(bool wait_for_clear) {
uint32_t start_time = millis();
set_bit(reg::PWMCON0, 4); //Set the "CLRPWM" bit of PWMCON0
set_bit(reg::PWMCON0, 4); // Set the "CLRPWM" bit of PWMCON0
if(wait_for_clear) {
while(pwm_clearing()) {
sleep_ms(1); //Wait for "CLRPWM" to complete
sleep_ms(1); // Wait for "CLRPWM" to complete
if(millis() - start_time >= timeout) {
if(debug)
printf("Timed out waiting for PWM clear!");
@ -491,10 +487,10 @@ namespace pimoroni {
if(divider_good) {
//TODO: This currently sets GP, PWMTYP and FBINEN to 0
//It might be desirable to make these available to the user
//GP - Group mode enable (changes first three pairs of pAM to PWM01H and PWM01L)
//PWMTYP - PWM type select: 0 edge-aligned, 1 center-aligned
//FBINEN - Fault-break input enable
// It might be desirable to make these available to the user
// GP - Group mode enable (changes first three pairs of pAM to PWM01H and PWM01L)
// PWMTYP - PWM type select: 0 edge-aligned, 1 center-aligned
// FBINEN - Fault-break input enable
i2c_reg_write_uint8(reg::PWMCON1, pwmdiv2);
}
@ -512,12 +508,16 @@ namespace pimoroni {
}
uint8_t IOExpander::get_mode(uint8_t pin) {
if(pin < 1 || pin > NUM_PINS) {
printf("ValueError: Pin should be in range 1-14.\n");
return UINT8_MAX;
}
return pins[pin - 1].get_mode();
}
void IOExpander::set_mode(uint8_t pin, uint8_t mode, bool schmitt_trigger, bool invert) {
if(pin < 1 || pin > NUM_PINS)
{
if(pin < 1 || pin > NUM_PINS) {
printf("ValueError: Pin should be in range 1-14.\n");
return;
}
@ -527,7 +527,7 @@ namespace pimoroni {
uint8_t gpio_mode = mode & 0b11;
uint8_t io_type = (mode >> 2) & 0b11;
uint8_t initial_state = mode >> 4;
if(io_pin.get_mode() == mode) {
if(debug) {
printf("Mode already is %s\n", MODE_NAMES[io_type]);
@ -550,7 +550,7 @@ namespace pimoroni {
if(mode == PIN_MODE_PWM) {
set_bit(io_pin.reg_io_pwm, io_pin.pwm_channel);
change_bit(reg::PNP, io_pin.pwm_channel, invert);
set_bit(reg::PWMCON0, 7); //Set PWMRUN bit
set_bit(reg::PWMCON0, 7); // Set PWMRUN bit
}
else {
if(io_pin.get_type() & Pin::TYPE_PWM)
@ -560,28 +560,27 @@ namespace pimoroni {
uint8_t pm1 = i2c_reg_read_uint8(io_pin.reg_m1);
uint8_t pm2 = i2c_reg_read_uint8(io_pin.reg_m2);
//Clear the pm1 and pm2 bits
// Clear the pm1 and pm2 bits
pm1 &= 255 - (1 << io_pin.pin);
pm2 &= 255 - (1 << io_pin.pin);
//Set the new pm1 and pm2 bits according to our gpio_mode
// Set the new pm1 and pm2 bits according to our gpio_mode
pm1 |= (gpio_mode >> 1) << io_pin.pin;
pm2 |= (gpio_mode & 0b1) << io_pin.pin;
i2c_reg_write_uint8(io_pin.reg_m1, pm1);
i2c_reg_write_uint8(io_pin.reg_m2, pm2);
//Set up Schmitt trigger mode on inputs
// Set up Schmitt trigger mode on inputs
if(mode == PIN_MODE_PU || mode == PIN_MODE_IN)
change_bit(io_pin.reg_ps, io_pin.pin, schmitt_trigger);
//5th bit of mode encodes default output pin state
// 5th bit of mode encodes default output pin state
i2c_reg_write_uint8(io_pin.reg_p, (initial_state << 3) | io_pin.pin);
}
int16_t IOExpander::input(uint8_t pin, uint32_t adc_timeout) {
if(pin < 1 || pin > NUM_PINS)
{
if(pin < 1 || pin > NUM_PINS) {
if(debug)
printf("ValueError: Pin should be in range 1-14.\n");
return -1;
@ -600,10 +599,10 @@ namespace pimoroni {
set_bit(reg::AINDIDS, io_pin.adc_channel);
set_bit(reg::ADCCON1, 0);
clr_bit(reg::ADCCON0, 7); //ADCF - Clear the conversion complete flag
set_bit(reg::ADCCON0, 6); //ADCS - Set the ADC conversion start flag
clr_bit(reg::ADCCON0, 7); // ADCF - Clear the conversion complete flag
set_bit(reg::ADCCON0, 6); // ADCS - Set the ADC conversion start flag
//Wait for the ADCF conversion complete flag to be set
// Wait for the ADCF conversion complete flag to be set
unsigned long start_time = millis();
while(!get_bit(reg::ADCCON0, 7)) {
sleep_ms(10);
@ -629,8 +628,7 @@ namespace pimoroni {
}
float IOExpander::input_as_voltage(uint8_t pin, uint32_t adc_timeout) {
if(pin < 1 || pin > NUM_PINS)
{
if(pin < 1 || pin > NUM_PINS) {
if(debug)
printf("ValueError: Pin should be in range 1-14.\n");
return -1;
@ -650,10 +648,10 @@ namespace pimoroni {
set_bit(reg::ADCCON1, 0);
clr_bit(reg::ADCCON0, 7); //ADCF - Clear the conversion complete flag
set_bit(reg::ADCCON0, 6); //ADCS - Set the ADC conversion start flag
clr_bit(reg::ADCCON0, 7); // ADCF - Clear the conversion complete flag
set_bit(reg::ADCCON0, 6); // ADCS - Set the ADC conversion start flag
//Wait for the ADCF conversion complete flag to be set
// Wait for the ADCF conversion complete flag to be set
unsigned long start_time = millis();
while(!get_bit(reg::ADCCON0, 7)) {
sleep_ms(1);
@ -714,21 +712,21 @@ namespace pimoroni {
}
}
void IOExpander::setup_rotary_encoder(uint8_t channel, uint8_t pinA, uint8_t pinB, uint8_t pinC, bool count_microsteps) {
void IOExpander::setup_rotary_encoder(uint8_t channel, uint8_t pin_a, uint8_t pin_b, uint8_t pin_c, bool count_microsteps) {
channel -= 1;
set_mode(pinA, PIN_MODE_PU, true);
set_mode(pinB, PIN_MODE_PU, true);
set_mode(pin_a, PIN_MODE_PU, true);
set_mode(pin_b, PIN_MODE_PU, true);
if(pinC != 0) {
set_mode(pinC, PIN_MODE_OD);
output(pinC, 0);
if(pin_c != 0) {
set_mode(pin_c, PIN_MODE_OD);
output(pin_c, 0);
}
i2c_reg_write_uint8(ENC_CFG[channel], pinA | (pinB << 4));
i2c_reg_write_uint8(ENC_CFG[channel], pin_a | (pin_b << 4));
change_bit(reg::ENC_EN, (channel * 2) + 1, count_microsteps);
set_bit(reg::ENC_EN, channel * 2);
//Reset internal encoder count to zero
// Reset internal encoder count to zero
uint8_t reg = ENC_COUNT[channel];
i2c_reg_write_uint8(reg, 0x00);
}
@ -765,14 +763,14 @@ namespace pimoroni {
}
uint8_t IOExpander::get_bit(uint8_t reg, uint8_t bit) {
//Returns the specified bit (nth position from right) from a register
// Returns the specified bit (nth position from right) from a register
return i2c_reg_read_uint8(reg) & (1 << bit);
}
void IOExpander::set_bits(uint8_t reg, uint8_t bits) {
//Set the specified bits (using a mask) in a register.
// Set the specified bits (using a mask) in a register.
//Deal with special case registers first
// Deal with special case registers first
bool reg_in_bit_addressed_regs = false;
for(uint8_t i = 0; i < NUM_BIT_ADDRESSED_REGISTERS; i++) {
if(BIT_ADDRESSED_REGS[i] == reg) {
@ -785,7 +783,7 @@ namespace pimoroni {
}
}
//Now deal with any other registers
// Now deal with any other registers
if(!reg_in_bit_addressed_regs) {
uint8_t value = i2c_reg_read_uint8(reg);
sleep_us(10);
@ -794,7 +792,7 @@ namespace pimoroni {
}
void IOExpander::set_bit(uint8_t reg, uint8_t bit) {
//Set the specified bit (nth position from right) in a register.
// Set the specified bit (nth position from right) in a register.
set_bits(reg, (1 << bit));
}
@ -811,7 +809,7 @@ namespace pimoroni {
}
}
//Now deal with any other registers
// Now deal with any other registers
if(!reg_in_bit_addressed_regs) {
uint8_t value = i2c_reg_read_uint8(reg);
sleep_us(10);
@ -820,12 +818,12 @@ namespace pimoroni {
}
void IOExpander::clr_bit(uint8_t reg, uint8_t bit) {
//Clear the specified bit (nth position from right) in a register.
// Clear the specified bit (nth position from right) in a register.
clr_bits(reg, (1 << bit));
}
void IOExpander::change_bit(uint8_t reg, uint8_t bit, bool state) {
//Toggle one register bit on/off.
// Toggle one register bit on/off.
if(state)
set_bit(reg, bit);
else
@ -833,7 +831,7 @@ namespace pimoroni {
}
void IOExpander::wait_for_flash(void) {
//Wait for the IOE to finish writing non-volatile memory.
// Wait for the IOE to finish writing non-volatile memory.
unsigned long start_time = millis();
while(get_interrupt_flag()) {
if(millis() - start_time > timeout) {

Wyświetl plik

@ -187,10 +187,9 @@ namespace pimoroni {
void enable_interrupt_out(bool pin_swap = false);
void disable_interrupt_out();
uint8_t get_interrupt_flag();
bool get_interrupt_flag();
void clear_interrupt_flag();
bool set_pin_interrupt(uint8_t pin, bool enabled);
void set_interrupt_callback(void (*callback)());
void pwm_load(bool wait_for_load = true);
bool pwm_loading();
@ -207,7 +206,7 @@ namespace pimoroni {
void output(uint8_t pin, uint16_t value, bool load = true);
void setup_rotary_encoder(uint8_t channel, uint8_t pinA, uint8_t pinB, uint8_t pinC = 0, bool count_microsteps = false);
void setup_rotary_encoder(uint8_t channel, uint8_t pin_a, uint8_t pin_b, uint8_t pin_c = 0, bool count_microsteps = false);
int16_t read_rotary_encoder(uint8_t channel);
private:

Wyświetl plik

@ -0,0 +1,90 @@
#include "breakout_ioexpander.h"
////////////////////////////////////////////////////////////////////////////////////////////////////
// BreakoutIOExpander Class
////////////////////////////////////////////////////////////////////////////////////////////////////
/***** Methods *****/
MP_DEFINE_CONST_FUN_OBJ_1(BreakoutIOExpander_get_chip_id_obj, BreakoutIOExpander_get_chip_id);
MP_DEFINE_CONST_FUN_OBJ_KW(BreakoutIOExpander_set_address_obj, 2, BreakoutIOExpander_set_address);
MP_DEFINE_CONST_FUN_OBJ_1(BreakoutIOExpander_get_adc_vref_obj, BreakoutIOExpander_get_adc_vref);
MP_DEFINE_CONST_FUN_OBJ_KW(BreakoutIOExpander_set_adc_vref_obj, 2, BreakoutIOExpander_set_adc_vref);
MP_DEFINE_CONST_FUN_OBJ_KW(BreakoutIOExpander_enable_interrupt_out_obj, 1, BreakoutIOExpander_enable_interrupt_out);
MP_DEFINE_CONST_FUN_OBJ_1(BreakoutIOExpander_disable_interrupt_out_obj, BreakoutIOExpander_disable_interrupt_out);
MP_DEFINE_CONST_FUN_OBJ_1(BreakoutIOExpander_get_interrupt_flag_obj, BreakoutIOExpander_get_interrupt_flag);
MP_DEFINE_CONST_FUN_OBJ_1(BreakoutIOExpander_clear_interrupt_flag_obj, BreakoutIOExpander_clear_interrupt_flag);
MP_DEFINE_CONST_FUN_OBJ_KW(BreakoutIOExpander_set_pin_interrupt_obj, 3, BreakoutIOExpander_set_pin_interrupt);
MP_DEFINE_CONST_FUN_OBJ_KW(BreakoutIOExpander_pwm_load_obj, 1, BreakoutIOExpander_pwm_load);
MP_DEFINE_CONST_FUN_OBJ_1(BreakoutIOExpander_pwm_loading_obj, BreakoutIOExpander_pwm_loading);
MP_DEFINE_CONST_FUN_OBJ_KW(BreakoutIOExpander_pwm_clear_obj, 1, BreakoutIOExpander_pwm_clear);
MP_DEFINE_CONST_FUN_OBJ_1(BreakoutIOExpander_pwm_clearing_obj, BreakoutIOExpander_pwm_clearing);
MP_DEFINE_CONST_FUN_OBJ_KW(BreakoutIOExpander_set_pwm_control_obj, 2, BreakoutIOExpander_set_pwm_control);
MP_DEFINE_CONST_FUN_OBJ_KW(BreakoutIOExpander_set_pwm_period_obj, 2, BreakoutIOExpander_set_pwm_period);
MP_DEFINE_CONST_FUN_OBJ_KW(BreakoutIOExpander_set_mode_obj, 3, BreakoutIOExpander_set_mode);
MP_DEFINE_CONST_FUN_OBJ_KW(BreakoutIOExpander_input_obj, 2, BreakoutIOExpander_input);
MP_DEFINE_CONST_FUN_OBJ_KW(BreakoutIOExpander_input_as_voltage_obj, 2, BreakoutIOExpander_input_as_voltage);
MP_DEFINE_CONST_FUN_OBJ_KW(BreakoutIOExpander_output_obj, 3, BreakoutIOExpander_output);
MP_DEFINE_CONST_FUN_OBJ_KW(BreakoutIOExpander_setup_rotary_encoder_obj, 4, BreakoutIOExpander_setup_rotary_encoder);
MP_DEFINE_CONST_FUN_OBJ_KW(BreakoutIOExpander_read_rotary_encoder_obj, 2, BreakoutIOExpander_read_rotary_encoder);
/***** Binding of Methods *****/
STATIC const mp_rom_map_elem_t BreakoutIOExpander_locals_dict_table[] = {
{ MP_ROM_QSTR(MP_QSTR_get_chip_id), MP_ROM_PTR(&BreakoutIOExpander_get_chip_id_obj) },
{ MP_ROM_QSTR(MP_QSTR_set_address), MP_ROM_PTR(&BreakoutIOExpander_set_address_obj) },
{ MP_ROM_QSTR(MP_QSTR_get_adc_vref), MP_ROM_PTR(&BreakoutIOExpander_get_adc_vref_obj) },
{ MP_ROM_QSTR(MP_QSTR_set_adc_vref), MP_ROM_PTR(&BreakoutIOExpander_set_adc_vref_obj) },
{ MP_ROM_QSTR(MP_QSTR_enable_interrupt_out), MP_ROM_PTR(&BreakoutIOExpander_enable_interrupt_out_obj) },
{ MP_ROM_QSTR(MP_QSTR_disable_interrupt_out), MP_ROM_PTR(&BreakoutIOExpander_disable_interrupt_out_obj) },
{ MP_ROM_QSTR(MP_QSTR_get_interrupt_flag), MP_ROM_PTR(&BreakoutIOExpander_get_interrupt_flag_obj) },
{ MP_ROM_QSTR(MP_QSTR_clear_interrupt_flag), MP_ROM_PTR(&BreakoutIOExpander_clear_interrupt_flag_obj) },
{ MP_ROM_QSTR(MP_QSTR_set_pin_interrupt), MP_ROM_PTR(&BreakoutIOExpander_set_pin_interrupt_obj) },
{ MP_ROM_QSTR(MP_QSTR_pwm_load), MP_ROM_PTR(&BreakoutIOExpander_pwm_load_obj) },
{ MP_ROM_QSTR(MP_QSTR_pwm_loading), MP_ROM_PTR(&BreakoutIOExpander_pwm_loading_obj) },
{ MP_ROM_QSTR(MP_QSTR_pwm_clear), MP_ROM_PTR(&BreakoutIOExpander_pwm_clear_obj) },
{ MP_ROM_QSTR(MP_QSTR_pwm_clearing), MP_ROM_PTR(&BreakoutIOExpander_pwm_clearing_obj) },
{ MP_ROM_QSTR(MP_QSTR_set_pwm_control), MP_ROM_PTR(&BreakoutIOExpander_set_pwm_control_obj) },
{ MP_ROM_QSTR(MP_QSTR_set_pwm_period), MP_ROM_PTR(&BreakoutIOExpander_set_pwm_period_obj) },
{ MP_ROM_QSTR(MP_QSTR_set_mode), MP_ROM_PTR(&BreakoutIOExpander_set_mode_obj) },
{ MP_ROM_QSTR(MP_QSTR_input), MP_ROM_PTR(&BreakoutIOExpander_input_obj) },
{ MP_ROM_QSTR(MP_QSTR_input_as_voltage), MP_ROM_PTR(&BreakoutIOExpander_input_as_voltage_obj) },
{ MP_ROM_QSTR(MP_QSTR_output), MP_ROM_PTR(&BreakoutIOExpander_output_obj) },
{ MP_ROM_QSTR(MP_QSTR_setup_rotary_encoder), MP_ROM_PTR(&BreakoutIOExpander_setup_rotary_encoder_obj) },
{ MP_ROM_QSTR(MP_QSTR_read_rotary_encoder), MP_ROM_PTR(&BreakoutIOExpander_read_rotary_encoder_obj) },
// { MP_ROM_QSTR(MP_QSTR_REF), MP_ROM_INT(REF) },
// { MP_ROM_QSTR(MP_QSTR_REDUCING), MP_ROM_INT(REDUCING) },
// { MP_ROM_QSTR(MP_QSTR_NH3), MP_ROM_INT(NH3) },
// { MP_ROM_QSTR(MP_QSTR_OXIDISING), MP_ROM_INT(OXIDISING) },
};
STATIC MP_DEFINE_CONST_DICT(BreakoutIOExpander_locals_dict, BreakoutIOExpander_locals_dict_table);
/***** Class Definition *****/
const mp_obj_type_t breakout_ioexpander_BreakoutIOExpander_type = {
{ &mp_type_type },
.name = MP_QSTR_breakout_ioexpander,
.print = BreakoutIOExpander_print,
.make_new = BreakoutIOExpander_make_new,
.locals_dict = (mp_obj_dict_t*)&BreakoutIOExpander_locals_dict,
};
////////////////////////////////////////////////////////////////////////////////////////////////////
// breakout_ioexpander Module
////////////////////////////////////////////////////////////////////////////////////////////////////
/***** Globals Table *****/
STATIC const mp_map_elem_t breakout_ioexpander_globals_table[] = {
{ MP_OBJ_NEW_QSTR(MP_QSTR___name__), MP_OBJ_NEW_QSTR(MP_QSTR_breakout_ioexpander) },
{ MP_OBJ_NEW_QSTR(MP_QSTR_BreakoutIOExpander), (mp_obj_t)&breakout_ioexpander_BreakoutIOExpander_type },
};
STATIC MP_DEFINE_CONST_DICT(mp_module_breakout_ioexpander_globals, breakout_ioexpander_globals_table);
/***** Module Definition *****/
const mp_obj_module_t breakout_ioexpander_user_cmodule = {
.base = { &mp_type_module },
.globals = (mp_obj_dict_t*)&mp_module_breakout_ioexpander_globals,
};
////////////////////////////////////////////////////////////////////////////////////////////////////
MP_REGISTER_MODULE(MP_QSTR_breakout_ioexpander, breakout_ioexpander_user_cmodule, MODULE_BREAKOUT_IOEXPANDER_ENABLED);
////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////

Wyświetl plik

@ -0,0 +1,482 @@
#include "../../../pimoroni-pico/libraries/breakout_ioexpander/breakout_ioexpander.hpp"
#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 "breakout_ioexpander.h"
/***** Variables Struct *****/
typedef struct _breakout_ioexpander_BreakoutIOExpander_obj_t {
mp_obj_base_t base;
BreakoutIOExpander *breakout;
} breakout_ioexpander_BreakoutIOExpander_obj_t;
/***** Print *****/
void BreakoutIOExpander_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind) {
(void)kind; //Unused input parameter
breakout_ioexpander_BreakoutIOExpander_obj_t *self = MP_OBJ_TO_PTR2(self_in, breakout_ioexpander_BreakoutIOExpander_obj_t);
BreakoutIOExpander* breakout = self->breakout;
mp_print_str(print, "BreakoutIOExpander(");
mp_print_str(print, "i2c = ");
mp_obj_print_helper(print, mp_obj_new_int((breakout->get_i2c() == i2c0) ? 0 : 1), PRINT_REPR);
mp_print_str(print, ", sda = ");
mp_obj_print_helper(print, mp_obj_new_int(breakout->get_sda()), PRINT_REPR);
mp_print_str(print, ", scl = ");
mp_obj_print_helper(print, mp_obj_new_int(breakout->get_scl()), PRINT_REPR);
mp_print_str(print, ", int = ");
mp_obj_print_helper(print, mp_obj_new_int(breakout->get_int()), PRINT_REPR);
mp_print_str(print, ")");
}
/***** Constructor *****/
mp_obj_t BreakoutIOExpander_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *all_args) {
breakout_ioexpander_BreakoutIOExpander_obj_t *self = nullptr;
if(n_args == 0) {
mp_arg_check_num(n_args, n_kw, 0, 0, true);
self = m_new_obj(breakout_ioexpander_BreakoutIOExpander_obj_t);
self->base.type = &breakout_ioexpander_BreakoutIOExpander_type;
self->breakout = new BreakoutIOExpander();
}
else if(n_args == 1) {
enum { ARG_address };
static const mp_arg_t allowed_args[] = {
{ MP_QSTR_address, MP_ARG_REQUIRED | MP_ARG_INT },
};
// 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);
self = m_new_obj(breakout_ioexpander_BreakoutIOExpander_obj_t);
self->base.type = &breakout_ioexpander_BreakoutIOExpander_type;
self->breakout = new BreakoutIOExpander(args[ARG_address].u_int);
}
else {
enum { ARG_i2c, ARG_address, ARG_sda, ARG_scl, ARG_interrupt };
static const mp_arg_t allowed_args[] = {
{ MP_QSTR_i2c, MP_ARG_REQUIRED | MP_ARG_INT },
{ MP_QSTR_address, MP_ARG_REQUIRED | MP_ARG_INT },
{ MP_QSTR_sda, MP_ARG_REQUIRED | MP_ARG_INT },
{ MP_QSTR_scl, MP_ARG_REQUIRED | MP_ARG_INT },
{ MP_QSTR_interrupt, MP_ARG_INT, {.u_int = BreakoutIOExpander::PIN_UNUSED} },
};
// 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 i2c_id = args[ARG_i2c].u_int;
if(i2c_id < 0 || i2c_id > 1) {
mp_raise_msg_varg(&mp_type_ValueError, MP_ERROR_TEXT("I2C(%d) doesn't exist"), i2c_id);
}
int sda = args[ARG_sda].u_int;
if (!IS_VALID_SDA(i2c_id, sda)) {
mp_raise_ValueError(MP_ERROR_TEXT("bad SDA pin"));
}
int scl = args[ARG_scl].u_int;
if (!IS_VALID_SCL(i2c_id, scl)) {
mp_raise_ValueError(MP_ERROR_TEXT("bad SCL pin"));
}
self = m_new_obj(breakout_ioexpander_BreakoutIOExpander_obj_t);
self->base.type = &breakout_ioexpander_BreakoutIOExpander_type;
i2c_inst_t *i2c = (i2c_id == 0) ? i2c0 : i2c1;
self->breakout = new BreakoutIOExpander(i2c, args[ARG_address].u_int, sda, scl, args[ARG_interrupt].u_int);
}
if(!self->breakout->init()) {
mp_raise_msg(&mp_type_RuntimeError, "IOExpander breakout not found when initialising");
}
return MP_OBJ_FROM_PTR(self);
}
/***** Methods *****/
mp_obj_t BreakoutIOExpander_get_chip_id(mp_obj_t self_in) {
breakout_ioexpander_BreakoutIOExpander_obj_t *self = MP_OBJ_TO_PTR2(self_in, breakout_ioexpander_BreakoutIOExpander_obj_t);
return mp_obj_new_int(self->breakout->get_chip_id());
}
mp_obj_t BreakoutIOExpander_set_address(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
enum { ARG_self, ARG_address };
static const mp_arg_t allowed_args[] = {
{ MP_QSTR_, MP_ARG_REQUIRED | MP_ARG_OBJ },
{ MP_QSTR_address, MP_ARG_REQUIRED | MP_ARG_INT },
};
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);
breakout_ioexpander_BreakoutIOExpander_obj_t *self = MP_OBJ_TO_PTR2(args[ARG_self].u_obj, breakout_ioexpander_BreakoutIOExpander_obj_t);
self->breakout->set_address(args[ARG_address].u_int);
return mp_const_none;
}
mp_obj_t BreakoutIOExpander_get_adc_vref(mp_obj_t self_in) {
breakout_ioexpander_BreakoutIOExpander_obj_t *self = MP_OBJ_TO_PTR2(self_in, breakout_ioexpander_BreakoutIOExpander_obj_t);
return mp_obj_new_float(self->breakout->get_adc_vref());
}
mp_obj_t BreakoutIOExpander_set_adc_vref(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
enum { ARG_self, ARG_vref };
static const mp_arg_t allowed_args[] = {
{ MP_QSTR_, MP_ARG_REQUIRED | MP_ARG_OBJ },
{ MP_QSTR_vref, MP_ARG_REQUIRED | MP_ARG_OBJ },
};
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);
breakout_ioexpander_BreakoutIOExpander_obj_t *self = MP_OBJ_TO_PTR2(args[ARG_self].u_obj, breakout_ioexpander_BreakoutIOExpander_obj_t);
float vref = mp_obj_get_float(args[ARG_vref].u_obj);
self->breakout->set_adc_vref(vref);
return mp_const_none;
}
mp_obj_t BreakoutIOExpander_enable_interrupt_out(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
enum { ARG_self, ARG_pin_swap };
static const mp_arg_t allowed_args[] = {
{ MP_QSTR_, MP_ARG_REQUIRED | MP_ARG_OBJ },
{ MP_QSTR_pin_swap, MP_ARG_BOOL, {.u_bool = false} },
};
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);
breakout_ioexpander_BreakoutIOExpander_obj_t *self = MP_OBJ_TO_PTR2(args[ARG_self].u_obj, breakout_ioexpander_BreakoutIOExpander_obj_t);
bool pin_swap = args[ARG_pin_swap].u_bool;
self->breakout->enable_interrupt_out(pin_swap);
return mp_const_none;
}
mp_obj_t BreakoutIOExpander_disable_interrupt_out(mp_obj_t self_in) {
breakout_ioexpander_BreakoutIOExpander_obj_t *self = MP_OBJ_TO_PTR2(self_in, breakout_ioexpander_BreakoutIOExpander_obj_t);
self->breakout->disable_interrupt_out();
return mp_const_none;
}
mp_obj_t BreakoutIOExpander_get_interrupt_flag(mp_obj_t self_in) {
breakout_ioexpander_BreakoutIOExpander_obj_t *self = MP_OBJ_TO_PTR2(self_in, breakout_ioexpander_BreakoutIOExpander_obj_t);
return mp_obj_new_bool(self->breakout->get_interrupt_flag());
}
mp_obj_t BreakoutIOExpander_clear_interrupt_flag(mp_obj_t self_in) {
breakout_ioexpander_BreakoutIOExpander_obj_t *self = MP_OBJ_TO_PTR2(self_in, breakout_ioexpander_BreakoutIOExpander_obj_t);
self->breakout->clear_interrupt_flag();
return mp_const_none;
}
mp_obj_t BreakoutIOExpander_set_pin_interrupt(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
enum { ARG_self, ARG_pin, ARG_enabled };
static const mp_arg_t allowed_args[] = {
{ MP_QSTR_, MP_ARG_REQUIRED | MP_ARG_OBJ },
{ MP_QSTR_exp_pin, MP_ARG_REQUIRED | MP_ARG_INT },
{ MP_QSTR_enabled, MP_ARG_REQUIRED | MP_ARG_BOOL },
};
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);
breakout_ioexpander_BreakoutIOExpander_obj_t *self = MP_OBJ_TO_PTR2(args[ARG_self].u_obj, breakout_ioexpander_BreakoutIOExpander_obj_t);
int pin = args[ARG_pin].u_int;
bool enabled = args[ARG_enabled].u_bool;
if(!self->breakout->set_pin_interrupt(pin, enabled)) {
mp_raise_ValueError("pin out of range. Expected 1 to 14");
}
return mp_const_none;
}
mp_obj_t BreakoutIOExpander_pwm_load(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
enum { ARG_self, ARG_wait_for_load };
static const mp_arg_t allowed_args[] = {
{ MP_QSTR_, MP_ARG_REQUIRED | MP_ARG_OBJ },
{ MP_QSTR_wait_for_load, MP_ARG_BOOL, {.u_bool = true} },
};
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);
breakout_ioexpander_BreakoutIOExpander_obj_t *self = MP_OBJ_TO_PTR2(args[ARG_self].u_obj, breakout_ioexpander_BreakoutIOExpander_obj_t);
bool wait_for_load = args[ARG_wait_for_load].u_bool;
self->breakout->pwm_load(wait_for_load);
return mp_const_none;
}
mp_obj_t BreakoutIOExpander_pwm_loading(mp_obj_t self_in) {
breakout_ioexpander_BreakoutIOExpander_obj_t *self = MP_OBJ_TO_PTR2(self_in, breakout_ioexpander_BreakoutIOExpander_obj_t);
return mp_obj_new_bool(self->breakout->pwm_loading());
}
mp_obj_t BreakoutIOExpander_pwm_clear(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
enum { ARG_self, ARG_wait_for_clear };
static const mp_arg_t allowed_args[] = {
{ MP_QSTR_, MP_ARG_REQUIRED | MP_ARG_OBJ },
{ MP_QSTR_wait_for_clear, MP_ARG_BOOL, {.u_bool = true} },
};
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);
breakout_ioexpander_BreakoutIOExpander_obj_t *self = MP_OBJ_TO_PTR2(args[ARG_self].u_obj, breakout_ioexpander_BreakoutIOExpander_obj_t);
bool wait_for_clear = args[ARG_wait_for_clear].u_bool;
self->breakout->pwm_clear(wait_for_clear);
return mp_const_none;
}
mp_obj_t BreakoutIOExpander_pwm_clearing(mp_obj_t self_in) {
breakout_ioexpander_BreakoutIOExpander_obj_t *self = MP_OBJ_TO_PTR2(self_in, breakout_ioexpander_BreakoutIOExpander_obj_t);
return mp_obj_new_bool(self->breakout->pwm_clearing());
}
mp_obj_t BreakoutIOExpander_set_pwm_control(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
enum { ARG_self, ARG_divider };
static const mp_arg_t allowed_args[] = {
{ MP_QSTR_, MP_ARG_REQUIRED | MP_ARG_OBJ },
{ MP_QSTR_divider, MP_ARG_REQUIRED | MP_ARG_INT },
};
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);
breakout_ioexpander_BreakoutIOExpander_obj_t *self = MP_OBJ_TO_PTR2(args[ARG_self].u_obj, breakout_ioexpander_BreakoutIOExpander_obj_t);
int divider = args[ARG_divider].u_int;
if(!self->breakout->set_pwm_control(divider)) {
mp_raise_ValueError("divider not valid. Available options are: 1, 2, 4, 8, 16, 32, 64, 128");
}
return mp_const_none;
}
mp_obj_t BreakoutIOExpander_set_pwm_period(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
enum { ARG_self, ARG_value, ARG_load };
static const mp_arg_t allowed_args[] = {
{ MP_QSTR_, MP_ARG_REQUIRED | MP_ARG_OBJ },
{ MP_QSTR_value, MP_ARG_REQUIRED | MP_ARG_INT },
{ MP_QSTR_load, MP_ARG_BOOL, {.u_bool = true} },
};
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);
breakout_ioexpander_BreakoutIOExpander_obj_t *self = MP_OBJ_TO_PTR2(args[ARG_self].u_obj, breakout_ioexpander_BreakoutIOExpander_obj_t);
int value = args[ARG_value].u_int;
bool load = args[ARG_load].u_bool;
if(value < 0 || value > 65535)
mp_raise_ValueError("value out of range. Expected 0 to 65535");
else
self->breakout->set_pwm_period(value, load);
return mp_const_none;
}
mp_obj_t BreakoutIOExpander_get_mode(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
enum { ARG_self, ARG_pin, ARG_enabled };
static const mp_arg_t allowed_args[] = {
{ MP_QSTR_, MP_ARG_REQUIRED | MP_ARG_OBJ },
{ MP_QSTR_exp_pin, MP_ARG_REQUIRED | MP_ARG_INT },
};
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);
breakout_ioexpander_BreakoutIOExpander_obj_t *self = MP_OBJ_TO_PTR2(args[ARG_self].u_obj, breakout_ioexpander_BreakoutIOExpander_obj_t);
int pin = args[ARG_pin].u_int;
uint8_t mode = self->breakout->get_mode(pin);
if(mode == UINT8_MAX)
mp_raise_ValueError("pin out of range. Expected 1 to 14");
return mp_obj_new_int(mode);
}
mp_obj_t BreakoutIOExpander_set_mode(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
enum { ARG_self, ARG_pin, ARG_mode, ARG_schmitt_trigger, ARG_invert };
static const mp_arg_t allowed_args[] = {
{ MP_QSTR_, MP_ARG_REQUIRED | MP_ARG_OBJ },
{ MP_QSTR_exp_pin, MP_ARG_REQUIRED | MP_ARG_INT },
{ MP_QSTR_mode, MP_ARG_REQUIRED | MP_ARG_INT },
{ MP_QSTR_schmitt_trigger, MP_ARG_BOOL, {.u_bool = false} },
{ MP_QSTR_invert, MP_ARG_BOOL, {.u_bool = false} },
};
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);
breakout_ioexpander_BreakoutIOExpander_obj_t *self = MP_OBJ_TO_PTR2(args[ARG_self].u_obj, breakout_ioexpander_BreakoutIOExpander_obj_t);
int pin = args[ARG_pin].u_int;
int mode = args[ARG_mode].u_int;
bool schmitt_trigger = args[ARG_schmitt_trigger].u_bool;
bool invert = args[ARG_invert].u_bool;
if(pin < 1 || pin > IOExpander::NUM_PINS)
mp_raise_ValueError("pin out of range. Expected 1 to 14");
else
self->breakout->set_mode(pin, mode, schmitt_trigger, invert);
return mp_const_none;
}
mp_obj_t BreakoutIOExpander_input(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
enum { ARG_self, ARG_pin };
static const mp_arg_t allowed_args[] = {
{ MP_QSTR_, MP_ARG_REQUIRED | MP_ARG_OBJ },
{ MP_QSTR_exp_pin, MP_ARG_REQUIRED | MP_ARG_INT },
};
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);
breakout_ioexpander_BreakoutIOExpander_obj_t *self = MP_OBJ_TO_PTR2(args[ARG_self].u_obj, breakout_ioexpander_BreakoutIOExpander_obj_t);
int pin = args[ARG_pin].u_int;
if(pin < 1 || pin > IOExpander::NUM_PINS)
mp_raise_ValueError("pin out of range. Expected 1 to 14");
else
return mp_obj_new_int(self->breakout->input(pin));
return mp_const_none;
}
mp_obj_t BreakoutIOExpander_input_as_voltage(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
enum { ARG_self, ARG_pin };
static const mp_arg_t allowed_args[] = {
{ MP_QSTR_, MP_ARG_REQUIRED | MP_ARG_OBJ },
{ MP_QSTR_exp_pin, MP_ARG_REQUIRED | MP_ARG_INT },
};
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);
breakout_ioexpander_BreakoutIOExpander_obj_t *self = MP_OBJ_TO_PTR2(args[ARG_self].u_obj, breakout_ioexpander_BreakoutIOExpander_obj_t);
int pin = args[ARG_pin].u_int;
if(pin < 1 || pin > IOExpander::NUM_PINS)
mp_raise_ValueError("pin out of range. Expected 1 to 14");
else
return mp_obj_new_float(self->breakout->input_as_voltage(pin));
return mp_const_none;
}
mp_obj_t BreakoutIOExpander_output(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
enum { ARG_self, ARG_pin, ARG_value, ARG_load };
static const mp_arg_t allowed_args[] = {
{ MP_QSTR_, MP_ARG_REQUIRED | MP_ARG_OBJ },
{ MP_QSTR_exp_pin, MP_ARG_REQUIRED | MP_ARG_INT },
{ MP_QSTR_value, MP_ARG_REQUIRED | MP_ARG_INT },
{ MP_QSTR_load, MP_ARG_BOOL, {.u_bool = false} },
};
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);
breakout_ioexpander_BreakoutIOExpander_obj_t *self = MP_OBJ_TO_PTR2(args[ARG_self].u_obj, breakout_ioexpander_BreakoutIOExpander_obj_t);
int pin = args[ARG_pin].u_int;
int value = args[ARG_value].u_int;
bool load = args[ARG_load].u_bool;
if(pin < 1 || pin > IOExpander::NUM_PINS)
mp_raise_ValueError("pin out of range. Expected 1 to 14");
else if(value < 0 || value > 65535)
mp_raise_ValueError("value out of range. Expected 0 to 65535");
else
self->breakout->output(pin, value, load);
return mp_const_none;
}
mp_obj_t BreakoutIOExpander_setup_rotary_encoder(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
enum { ARG_self, ARG_channel, ARG_pin_a, ARG_pin_b, ARG_pin_c, ARG_count_microsteps };
static const mp_arg_t allowed_args[] = {
{ MP_QSTR_, MP_ARG_REQUIRED | MP_ARG_OBJ },
{ MP_QSTR_channel, MP_ARG_REQUIRED | MP_ARG_INT },
{ MP_QSTR_pin_a, MP_ARG_REQUIRED | MP_ARG_INT },
{ MP_QSTR_pin_b, MP_ARG_REQUIRED | MP_ARG_INT },
{ MP_QSTR_pin_c, MP_ARG_INT, {.u_int = 0} },
{ MP_QSTR_count_microsteps, MP_ARG_BOOL, {.u_bool = false} },
};
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);
breakout_ioexpander_BreakoutIOExpander_obj_t *self = MP_OBJ_TO_PTR2(args[ARG_self].u_obj, breakout_ioexpander_BreakoutIOExpander_obj_t);
int channel = args[ARG_channel].u_int;
int pin_a = args[ARG_pin_a].u_int;
int pin_b = args[ARG_pin_b].u_int;
int pin_c = args[ARG_pin_c].u_int;
bool count_microsteps = args[ARG_count_microsteps].u_bool;
if(channel < 1 || channel > 4)
mp_raise_ValueError("channel out of range. Expected 1 to 4");
else if(pin_a < 1 || pin_a > 14)
mp_raise_ValueError("pin_a out of range. Expected 1 to 14");
else if(pin_b < 1 || pin_b > 14)
mp_raise_ValueError("pin_b out of range. Expected 1 to 14");
else if(pin_c < 1 || pin_c > 14)
mp_raise_ValueError("pin_c out of range. Expected 1 to 14");
else
self->breakout->setup_rotary_encoder(channel, pin_a, pin_b, pin_c, count_microsteps);
return mp_const_none;
}
mp_obj_t BreakoutIOExpander_read_rotary_encoder(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
enum { ARG_self, ARG_channel, ARG_value, ARG_load };
static const mp_arg_t allowed_args[] = {
{ MP_QSTR_, MP_ARG_REQUIRED | MP_ARG_OBJ },
{ MP_QSTR_channel, MP_ARG_REQUIRED | MP_ARG_INT },
};
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);
breakout_ioexpander_BreakoutIOExpander_obj_t *self = MP_OBJ_TO_PTR2(args[ARG_self].u_obj, breakout_ioexpander_BreakoutIOExpander_obj_t);
int channel = args[ARG_channel].u_int;
if(channel < 1 || channel > 4)
mp_raise_ValueError("channel out of range. Expected 1 to 4");
else
return mp_obj_new_int(self->breakout->read_rotary_encoder(channel));
return mp_const_none;
}
}

Wyświetl plik

@ -0,0 +1,38 @@
// Include MicroPython API.
#include "py/runtime.h"
// enum {
// REF = 0,
// REDUCING,
// NH3,
// OXIDISING
// };
/***** Extern of Class Definition *****/
extern const mp_obj_type_t breakout_ioexpander_BreakoutIOExpander_type;
/***** Extern of Class Methods *****/
extern void BreakoutIOExpander_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind);
extern mp_obj_t BreakoutIOExpander_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 BreakoutIOExpander_get_chip_id(mp_obj_t self_in);
extern mp_obj_t BreakoutIOExpander_set_address(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args);
extern mp_obj_t BreakoutIOExpander_get_adc_vref(mp_obj_t self_in);
extern mp_obj_t BreakoutIOExpander_set_adc_vref(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args);
extern mp_obj_t BreakoutIOExpander_enable_interrupt_out(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args);
extern mp_obj_t BreakoutIOExpander_disable_interrupt_out(mp_obj_t self_in);
extern mp_obj_t BreakoutIOExpander_get_interrupt_flag(mp_obj_t self_in);
extern mp_obj_t BreakoutIOExpander_clear_interrupt_flag(mp_obj_t self_in);
extern mp_obj_t BreakoutIOExpander_set_pin_interrupt(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args);
extern mp_obj_t BreakoutIOExpander_pwm_load(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args);
extern mp_obj_t BreakoutIOExpander_pwm_loading(mp_obj_t self_in);
extern mp_obj_t BreakoutIOExpander_pwm_clear(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args);
extern mp_obj_t BreakoutIOExpander_pwm_clearing(mp_obj_t self_in);
extern mp_obj_t BreakoutIOExpander_set_pwm_control(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args);
extern mp_obj_t BreakoutIOExpander_set_pwm_period(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args);
extern mp_obj_t BreakoutIOExpander_get_mode(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args);
extern mp_obj_t BreakoutIOExpander_set_mode(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args);
extern mp_obj_t BreakoutIOExpander_input(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args);
extern mp_obj_t BreakoutIOExpander_input_as_voltage(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args);
extern mp_obj_t BreakoutIOExpander_output(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args);
extern mp_obj_t BreakoutIOExpander_setup_rotary_encoder(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args);
extern mp_obj_t BreakoutIOExpander_read_rotary_encoder(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args);

Wyświetl plik

@ -0,0 +1,20 @@
set(MOD_NAME breakout_ioexpander)
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}/../../../libraries/${MOD_NAME}/${MOD_NAME}.cpp
${CMAKE_CURRENT_LIST_DIR}/../../../drivers/ioexpander/ioexpander.cpp
)
target_include_directories(usermod_${MOD_NAME} INTERFACE
${CMAKE_CURRENT_LIST_DIR}
)
target_compile_definitions(usermod_${MOD_NAME} INTERFACE
-DMODULE_${MOD_NAME_UPPER}_ENABLED=1
)
target_link_libraries(usermod INTERFACE usermod_${MOD_NAME})

Wyświetl plik

@ -0,0 +1,13 @@
set(MOD_NAME breakout_ioexpander)
BREAKOUT_MOD_DIR := $(USERMOD_DIR)
# Add our source files to the respective variables.
SRC_USERMOD += $(BREAKOUT_MOD_DIR)/${MOD_NAME}.c
SRC_USERMOD_CXX += $(BREAKOUT_MOD_DIR)/${MOD_NAME}.cpp
# Add our module directory to the include path.
CFLAGS_USERMOD += -I$(BREAKOUT_MOD_DIR)
CXXFLAGS_USERMOD += -I$(BREAKOUT_MOD_DIR)
# We use C++ features so have to link against the standard library.
LDFLAGS_USERMOD += -lstdc++

Wyświetl plik

@ -2,6 +2,7 @@ include_directories(${CMAKE_CURRENT_LIST_DIR}/../../)
include(${CMAKE_CURRENT_LIST_DIR}/breakout_dotmatrix/micropython.cmake)
include(${CMAKE_CURRENT_LIST_DIR}/breakout_encoder/micropython.cmake)
include(${CMAKE_CURRENT_LIST_DIR}/breakout_ioexpander/micropython.cmake)
include(${CMAKE_CURRENT_LIST_DIR}/breakout_ltr559/micropython.cmake)
include(${CMAKE_CURRENT_LIST_DIR}/breakout_colourlcd160x80/micropython.cmake)
include(${CMAKE_CURRENT_LIST_DIR}/breakout_as7262/micropython.cmake)