diff --git a/CMakeLists.txt b/CMakeLists.txt index f134b0ed..8322b7a6 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -32,6 +32,9 @@ include_directories( ${CMAKE_CURRENT_LIST_DIR} ) +set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Werror") + +add_subdirectory(common) add_subdirectory(drivers) add_subdirectory(libraries) diff --git a/common/CMakeLists.txt b/common/CMakeLists.txt new file mode 100644 index 00000000..be65a239 --- /dev/null +++ b/common/CMakeLists.txt @@ -0,0 +1,9 @@ +add_library(pimoroni_i2c INTERFACE) + +target_sources(pimoroni_i2c INTERFACE + ${CMAKE_CURRENT_LIST_DIR}/pimoroni_i2c.cpp) + +target_include_directories(pimoroni_i2c INTERFACE ${CMAKE_CURRENT_LIST_DIR}) + +# Pull in pico libraries that we need +target_link_libraries(pimoroni_i2c INTERFACE pico_stdlib) diff --git a/common/pimoroni_common.hpp b/common/pimoroni_common.hpp new file mode 100644 index 00000000..9f372c11 --- /dev/null +++ b/common/pimoroni_common.hpp @@ -0,0 +1,41 @@ +#pragma once +#include +#include + +#define PIMORONI_I2C_DEFAULT_INSTANCE i2c0 +#define PIMORONI_SPI_DEFAULT_INSTANCE spi0 + +namespace pimoroni { + static const unsigned int PIN_UNUSED = INT_MAX; // Intentionally INT_MAX to avoid overflowing MicroPython's int type + + // I2C + static const unsigned int I2C_DEFAULT_BAUDRATE = 400000; + static const unsigned int I2C_DEFAULT_SDA = 20; + static const unsigned int I2C_DEFAULT_SCL = 21; + static const unsigned int I2C_DEFAULT_INT = 22; + + static const unsigned int I2C_BG_SDA = 4; + static const unsigned int I2C_BG_SCL = 5; + static const unsigned int I2C_BG_INT = 3; + + // SPI + static const unsigned int SPI_DEFAULT_MOSI = 19; + static const unsigned int SPI_DEFAULT_MISO = 16; + static const unsigned int SPI_DEFAULT_SCK = 18; + + static const unsigned int SPI_BG_FRONT_PWM = 20; + static const unsigned int SPI_BG_FRONT_CS = 17; + + static const unsigned int SPI_BG_BACK_PWM = 21; + static const unsigned int SPI_BG_BACK_CS = 22; + + enum BG_SPI_SLOT { + BG_SPI_FRONT, + BG_SPI_BACK + }; + + enum BOARD { + BREAKOUT_GARDEN, + PICO_EXPLORER + }; +} \ No newline at end of file diff --git a/common/pimoroni_i2c.cpp b/common/pimoroni_i2c.cpp new file mode 100644 index 00000000..52fcda61 --- /dev/null +++ b/common/pimoroni_i2c.cpp @@ -0,0 +1,91 @@ +#include "pimoroni_common.hpp" +#include "pimoroni_i2c.hpp" + +namespace pimoroni { + void I2C::init() { + i2c = ((sda / 2) & 0b1) ? i2c1 : i2c0; + + i2c_init(i2c, baudrate); + + gpio_set_function(sda, GPIO_FUNC_I2C); gpio_pull_up(sda); + gpio_set_function(scl, GPIO_FUNC_I2C); gpio_pull_up(scl); + } + + /* Basic wrappers for devices using i2c functions directly */ + int I2C::write_blocking(uint8_t addr, const uint8_t *src, size_t len, bool nostop) { + return i2c_write_blocking(i2c, addr, src, len, nostop); + } + + int I2C::read_blocking(uint8_t addr, uint8_t *dst, size_t len, bool nostop) { + return i2c_read_blocking(i2c, addr, dst, len, nostop); + } + + /* Convenience functions for various common i2c operations */ + void I2C::reg_write_uint8(uint8_t address, uint8_t reg, uint8_t value) { + uint8_t buffer[2] = {reg, value}; + i2c_write_blocking(i2c, address, buffer, 2, false); + } + + uint8_t I2C::reg_read_uint8(uint8_t address, uint8_t reg) { + uint8_t value; + i2c_write_blocking(i2c, address, ®, 1, false); + i2c_read_blocking(i2c, address, (uint8_t *)&value, sizeof(uint8_t), false); + return value; + } + + uint16_t I2C::reg_read_uint16(uint8_t address, uint8_t reg) { + uint16_t value; + i2c_write_blocking(i2c, address, ®, 1, true); + i2c_read_blocking(i2c, address, (uint8_t *)&value, sizeof(uint16_t), false); + return value; + } + + uint32_t I2C::reg_read_uint32(uint8_t address, uint8_t reg) { + uint32_t value; + i2c_write_blocking(i2c, address, ®, 1, true); + i2c_read_blocking(i2c, address, (uint8_t *)&value, sizeof(uint32_t), false); + return value; + } + + int16_t I2C::reg_read_int16(uint8_t address, uint8_t reg) { + int16_t value; + i2c_write_blocking(i2c, address, ®, 1, true); + i2c_read_blocking(i2c, address, (uint8_t *)&value, sizeof(int16_t), false); + return value; + } + + int I2C::write_bytes(uint8_t address, uint8_t reg, uint8_t *buf, int len) { + uint8_t buffer[len + 1]; + buffer[0] = reg; + for(int x = 0; x < len; x++) { + buffer[x + 1] = buf[x]; + } + return i2c_write_blocking(i2c, address, buffer, len + 1, false); + }; + + int I2C::read_bytes(uint8_t address, uint8_t reg, uint8_t *buf, int len) { + i2c_write_blocking(i2c, address, ®, 1, true); + i2c_read_blocking(i2c, address, buf, len, false); + return len; + }; + + uint8_t I2C::get_bits(uint8_t address, uint8_t reg, uint8_t shift, uint8_t mask) { + uint8_t value; + read_bytes(address, reg, &value, 1); + return value & (mask << shift); + } + + void I2C::set_bits(uint8_t address, uint8_t reg, uint8_t shift, uint8_t mask) { + uint8_t value; + read_bytes(address, reg, &value, 1); + value |= mask << shift; + write_bytes(address, reg, &value, 1); + } + + void I2C::clear_bits(uint8_t address, uint8_t reg, uint8_t shift, uint8_t mask) { + uint8_t value; + read_bytes(address, reg, &value, 1); + value &= ~(mask << shift); + write_bytes(address, reg, &value, 1); + } +} \ No newline at end of file diff --git a/common/pimoroni_i2c.hpp b/common/pimoroni_i2c.hpp new file mode 100644 index 00000000..87146c8e --- /dev/null +++ b/common/pimoroni_i2c.hpp @@ -0,0 +1,72 @@ +#pragma once +#include +#include +#include "hardware/i2c.h" +#include "hardware/gpio.h" +#include "pimoroni_common.hpp" +#include "pimoroni_i2c.hpp" + +namespace pimoroni { + class I2C { + private: + i2c_inst_t *i2c = PIMORONI_I2C_DEFAULT_INSTANCE; + uint sda = I2C_DEFAULT_SDA; + uint scl = I2C_DEFAULT_SCL; + uint interrupt = PIN_UNUSED; + uint32_t baudrate = I2C_DEFAULT_BAUDRATE; + + public: + I2C(BOARD board, uint32_t baudrate = I2C_DEFAULT_BAUDRATE) : baudrate(baudrate) { + switch(board) { + case BREAKOUT_GARDEN: + sda = I2C_BG_SDA; + scl = I2C_BG_SCL; + interrupt = I2C_BG_INT; + break; + case PICO_EXPLORER: + default: + sda = I2C_DEFAULT_SDA; + scl = I2C_DEFAULT_SCL; + interrupt = I2C_DEFAULT_INT; + break; + } + init(); + } + + I2C(uint sda, uint scl, uint32_t baudrate = I2C_DEFAULT_BAUDRATE) : sda(sda), scl(scl), baudrate(baudrate) { + init(); + } + + I2C() : I2C(I2C_DEFAULT_SDA, I2C_DEFAULT_SCL) {} + + ~I2C() { + i2c_deinit(i2c); + gpio_disable_pulls(sda); + gpio_set_function(sda, GPIO_FUNC_NULL); + gpio_disable_pulls(scl); + gpio_set_function(scl, GPIO_FUNC_NULL); + } + + void reg_write_uint8(uint8_t address, uint8_t reg, uint8_t value); + uint8_t reg_read_uint8(uint8_t address, uint8_t reg); + uint16_t reg_read_uint16(uint8_t address, uint8_t reg); + int16_t reg_read_int16(uint8_t address, uint8_t reg); + uint32_t reg_read_uint32(uint8_t address, uint8_t reg); + + int write_bytes(uint8_t address, uint8_t reg, uint8_t *buf, int len); + int read_bytes(uint8_t address, uint8_t reg, uint8_t *buf, int len); + uint8_t get_bits(uint8_t address, uint8_t reg, uint8_t shift, uint8_t mask=0b1); + void set_bits(uint8_t address, uint8_t reg, uint8_t shift, uint8_t mask=0b1); + void clear_bits(uint8_t address, uint8_t reg, uint8_t shift, uint8_t mask=0b1); + + int write_blocking(uint8_t addr, const uint8_t *src, size_t len, bool nostop); + int read_blocking(uint8_t addr, uint8_t *dst, size_t len, bool nostop); + + i2c_inst_t* get_i2c() {return i2c;} + uint get_scl() {return scl;} + uint get_sda() {return sda;} + uint32_t get_baudrate() {return baudrate;} + private: + void init(); + }; +} \ No newline at end of file diff --git a/drivers/as7262/as7262.cmake b/drivers/as7262/as7262.cmake index 65591866..f48a7a98 100644 --- a/drivers/as7262/as7262.cmake +++ b/drivers/as7262/as7262.cmake @@ -7,4 +7,4 @@ target_sources(${DRIVER_NAME} INTERFACE target_include_directories(${DRIVER_NAME} INTERFACE ${CMAKE_CURRENT_LIST_DIR}) # Pull in pico libraries that we need -target_link_libraries(${DRIVER_NAME} INTERFACE pico_stdlib hardware_i2c) +target_link_libraries(${DRIVER_NAME} INTERFACE pico_stdlib hardware_i2c pimoroni_i2c) diff --git a/drivers/as7262/as7262.cpp b/drivers/as7262/as7262.cpp index 3309e104..3ac188e9 100644 --- a/drivers/as7262/as7262.cpp +++ b/drivers/as7262/as7262.cpp @@ -42,13 +42,6 @@ namespace pimoroni { bool AS7262::init() { bool succeeded = false; - i2c_init(i2c, 400000); - - gpio_set_function(sda, GPIO_FUNC_I2C); - gpio_pull_up(sda); - gpio_set_function(scl, GPIO_FUNC_I2C); - gpio_pull_up(scl); - if(interrupt != PIN_UNUSED) { gpio_set_function(interrupt, GPIO_FUNC_SIO); gpio_set_dir(interrupt, GPIO_IN); @@ -71,15 +64,15 @@ namespace pimoroni { } i2c_inst_t* AS7262::get_i2c() const { - return i2c; + return i2c->get_i2c(); } int AS7262::get_sda() const { - return sda; + return i2c->get_sda(); } int AS7262::get_scl() const { - return scl; + return i2c->get_scl(); } int AS7262::get_int() const { @@ -216,13 +209,13 @@ namespace pimoroni { // Plumbing for virtual i2c void AS7262::_i2c_reg_write_uint8(uint8_t reg, uint8_t value) { uint8_t buffer[2] = {reg, value}; - i2c_write_blocking(i2c, address, buffer, 2, false); + i2c->write_blocking(address, buffer, 2, false); } uint8_t AS7262::_i2c_reg_read_uint8(uint8_t reg) { uint8_t value; - i2c_write_blocking(i2c, address, ®, 1, false); - i2c_read_blocking(i2c, address, (uint8_t *)&value, 1, false); + i2c->write_blocking(address, ®, 1, false); + i2c->read_blocking(address, (uint8_t *)&value, 1, false); return value; } } \ No newline at end of file diff --git a/drivers/as7262/as7262.hpp b/drivers/as7262/as7262.hpp index d3151b51..31959861 100644 --- a/drivers/as7262/as7262.hpp +++ b/drivers/as7262/as7262.hpp @@ -4,6 +4,8 @@ #include "hardware/i2c.h" #include "hardware/gpio.h" +#include "common/pimoroni_common.hpp" +#include "common/pimoroni_i2c.hpp" namespace pimoroni { @@ -13,10 +15,6 @@ namespace pimoroni { //-------------------------------------------------- public: static const uint8_t DEFAULT_I2C_ADDRESS = 0x49; - static const uint8_t DEFAULT_SDA_PIN = 20; - static const uint8_t DEFAULT_SCL_PIN = 21; - static const uint8_t DEFAULT_INT_PIN = 22; - static const uint8_t PIN_UNUSED = UINT8_MAX; //-------------------------------------------------- @@ -70,23 +68,23 @@ namespace pimoroni { // Variables //-------------------------------------------------- private: - i2c_inst_t *i2c = i2c0; + I2C *i2c; // interface pins with our standard defaults where appropriate int8_t address = DEFAULT_I2C_ADDRESS; - int8_t sda = DEFAULT_SDA_PIN; - int8_t scl = DEFAULT_SCL_PIN; - int8_t interrupt = DEFAULT_INT_PIN; + uint interrupt = PIN_UNUSED; //-------------------------------------------------- // Constructors/Destructor //-------------------------------------------------- public: - AS7262() {} + AS7262(uint interrupt = PIN_UNUSED) : AS7262(new I2C(), interrupt) {}; - AS7262(i2c_inst_t *i2c, uint8_t sda, uint8_t scl, uint8_t interrupt = PIN_UNUSED) : - i2c(i2c), sda(sda), scl(scl), interrupt(interrupt) {} + AS7262(I2C *i2c, uint interrupt = PIN_UNUSED) : i2c(i2c), interrupt(interrupt) {} + + // TODO remove MicroPython-binding compatibility constructors + AS7262(uint sda, uint scl, uint interrupt = PIN_UNUSED) : AS7262(new I2C(), interrupt) {} //-------------------------------------------------- diff --git a/drivers/ioexpander/ioexpander.cmake b/drivers/ioexpander/ioexpander.cmake index dbd7a67c..901290a1 100644 --- a/drivers/ioexpander/ioexpander.cmake +++ b/drivers/ioexpander/ioexpander.cmake @@ -7,4 +7,4 @@ target_sources(${DRIVER_NAME} INTERFACE target_include_directories(${DRIVER_NAME} INTERFACE ${CMAKE_CURRENT_LIST_DIR}) # Pull in pico libraries that we need -target_link_libraries(${DRIVER_NAME} INTERFACE pico_stdlib hardware_i2c) +target_link_libraries(${DRIVER_NAME} INTERFACE pico_stdlib hardware_i2c pimoroni_i2c) diff --git a/drivers/ioexpander/ioexpander.cpp b/drivers/ioexpander/ioexpander.cpp index e32d79bb..265f4dc7 100644 --- a/drivers/ioexpander/ioexpander.cpp +++ b/drivers/ioexpander/ioexpander.cpp @@ -297,16 +297,9 @@ namespace pimoroni { this->mode = mode; } - IOExpander::IOExpander() : - IOExpander(i2c0, DEFAULT_I2C_ADDRESS, DEFAULT_SDA_PIN, DEFAULT_SCL_PIN, DEFAULT_INT_PIN) { - } - - IOExpander::IOExpander(uint8_t address, uint32_t timeout, bool debug) : - IOExpander(i2c0, address, DEFAULT_SDA_PIN, DEFAULT_SCL_PIN, DEFAULT_INT_PIN, timeout, debug) { - } - - IOExpander::IOExpander(i2c_inst_t *i2c, uint8_t address, uint8_t sda, uint8_t scl, uint8_t interrupt, uint32_t timeout, bool debug) : - i2c(i2c), address(address), sda(sda), scl(scl), interrupt(interrupt), + IOExpander::IOExpander(I2C *i2c, uint8_t address, uint interrupt, uint32_t timeout, bool debug) : + i2c(i2c), + address(address), interrupt(interrupt), timeout(timeout), debug(debug), vref(3.3f), encoder_offset{0,0,0,0}, encoder_last{0,0,0,0}, @@ -323,17 +316,12 @@ namespace pimoroni { Pin::adc(0, 6, 3), Pin::adc_or_pwm(0, 5, 4, 2, reg::PIOCON1), Pin::adc(0, 7, 2), - Pin::adc(1, 7, 0)} { - } + Pin::adc(1, 7, 0)} + {} bool IOExpander::init(bool skipChipIdCheck) { bool succeeded = true; - i2c_init(i2c, 400000); - - gpio_set_function(sda, GPIO_FUNC_I2C); gpio_pull_up(sda); - gpio_set_function(scl, GPIO_FUNC_I2C); gpio_pull_up(scl); - if(interrupt != PIN_UNUSED) { gpio_set_function(interrupt, GPIO_FUNC_SIO); gpio_set_dir(interrupt, GPIO_IN); @@ -356,7 +344,7 @@ namespace pimoroni { } i2c_inst_t* IOExpander::get_i2c() const { - return i2c; + return i2c->get_i2c(); } int IOExpander::get_address() const { @@ -364,11 +352,11 @@ namespace pimoroni { } int IOExpander::get_sda() const { - return sda; + return i2c->get_sda(); } int IOExpander::get_scl() const { - return scl; + return i2c->get_scl(); } int IOExpander::get_int() const { @@ -376,12 +364,12 @@ namespace pimoroni { } uint16_t IOExpander::get_chip_id() { - return ((uint16_t)i2c_reg_read_uint8(reg::CHIP_ID_H) << 8) | (uint16_t)i2c_reg_read_uint8(reg::CHIP_ID_L); + return ((uint16_t)i2c->reg_read_uint8(address, reg::CHIP_ID_H) << 8) | (uint16_t)i2c->reg_read_uint8(address, reg::CHIP_ID_L); } void IOExpander::set_address(uint8_t address) { set_bit(reg::CTRL, 4); - i2c_reg_write_uint8(reg::ADDR, address); + i2c->reg_write_uint8(address, reg::ADDR, address); this->address = address; sleep_ms(250); //TODO Handle addr change IOError better //wait_for_flash() @@ -496,7 +484,7 @@ namespace pimoroni { // PWMTYP - PWM type select: 0 edge-aligned, 1 center-aligned // FBINEN - Fault-break input enable - i2c_reg_write_uint8(reg::PWMCON1, pwmdiv2); + i2c->reg_write_uint8(address, reg::PWMCON1, pwmdiv2); } return divider_good; @@ -504,8 +492,8 @@ namespace pimoroni { void IOExpander::set_pwm_period(uint16_t value, bool load) { value &= 0xffff; - i2c_reg_write_uint8(reg::PWMPL, (uint8_t)(value & 0xff)); - i2c_reg_write_uint8(reg::PWMPH, (uint8_t)(value >> 8)); + i2c->reg_write_uint8(address, reg::PWMPL, (uint8_t)(value & 0xff)); + i2c->reg_write_uint8(address, reg::PWMPH, (uint8_t)(value >> 8)); if(load) pwm_load(); @@ -561,8 +549,8 @@ namespace pimoroni { clr_bit(io_pin.reg_io_pwm, io_pin.pwm_channel); } - uint8_t pm1 = i2c_reg_read_uint8(io_pin.reg_m1); - uint8_t pm2 = i2c_reg_read_uint8(io_pin.reg_m2); + uint8_t pm1 = i2c->reg_read_uint8(address, io_pin.reg_m1); + uint8_t pm2 = i2c->reg_read_uint8(address, io_pin.reg_m2); // Clear the pm1 and pm2 bits pm1 &= 255 - (1 << io_pin.pin); @@ -572,15 +560,15 @@ namespace pimoroni { 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); + i2c->reg_write_uint8(address, io_pin.reg_m1, pm1); + i2c->reg_write_uint8(address, io_pin.reg_m2, pm2); // 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 - i2c_reg_write_uint8(io_pin.reg_p, (initial_state << 3) | io_pin.pin); + i2c->reg_write_uint8(address, io_pin.reg_p, (initial_state << 3) | io_pin.pin); } int16_t IOExpander::input(uint8_t pin, uint32_t adc_timeout) { @@ -599,7 +587,7 @@ namespace pimoroni { clr_bits(reg::ADCCON0, 0x0f); set_bits(reg::ADCCON0, io_pin.adc_channel); - i2c_reg_write_uint8(reg::AINDIDS, 0); + i2c->reg_write_uint8(address, reg::AINDIDS, 0); set_bit(reg::AINDIDS, io_pin.adc_channel); set_bit(reg::ADCCON1, 0); @@ -617,8 +605,8 @@ namespace pimoroni { } } - uint8_t hi = i2c_reg_read_uint8(reg::ADCRH); - uint8_t lo = i2c_reg_read_uint8(reg::ADCRL); + uint8_t hi = i2c->reg_read_uint8(address, reg::ADCRH); + uint8_t lo = i2c->reg_read_uint8(address, reg::ADCRL); return (uint16_t)(hi << 4) | (uint16_t)lo; } else { @@ -647,7 +635,7 @@ namespace pimoroni { clr_bits(reg::ADCCON0, 0x0f); set_bits(reg::ADCCON0, io_pin.adc_channel); - i2c_reg_write_uint8(reg::AINDIDS, 0); + i2c->reg_write_uint8(address, reg::AINDIDS, 0); set_bit(reg::AINDIDS, io_pin.adc_channel); set_bit(reg::ADCCON1, 0); @@ -666,8 +654,8 @@ namespace pimoroni { } } - uint8_t hi = i2c_reg_read_uint8(reg::ADCRH); - uint8_t lo = i2c_reg_read_uint8(reg::ADCRL); + uint8_t hi = i2c->reg_read_uint8(address, reg::ADCRH); + uint8_t lo = i2c->reg_read_uint8(address, reg::ADCRL); return ((float)((uint16_t)(hi << 4) | (uint16_t)lo) / 4095.0f) * vref; } else { @@ -693,8 +681,8 @@ namespace pimoroni { printf("Outputting PWM to pin: %d\n", pin); } - i2c_reg_write_uint8(io_pin.reg_pwml, (uint8_t)(value & 0xff)); - i2c_reg_write_uint8(io_pin.reg_pwmh, (uint8_t)(value >> 8)); + i2c->reg_write_uint8(address, io_pin.reg_pwml, (uint8_t)(value & 0xff)); + i2c->reg_write_uint8(address, io_pin.reg_pwmh, (uint8_t)(value >> 8)); if(load) pwm_load(); } @@ -726,20 +714,20 @@ namespace pimoroni { output(pin_c, 0); } - i2c_reg_write_uint8(ENC_CFG[channel], pin_a | (pin_b << 4)); + i2c->reg_write_uint8(address, 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 uint8_t reg = ENC_COUNT[channel]; - i2c_reg_write_uint8(reg, 0x00); + i2c->reg_write_uint8(address, reg, 0x00); } int16_t IOExpander::read_rotary_encoder(uint8_t channel) { channel -= 1; int16_t last = encoder_last[channel]; uint8_t reg = ENC_COUNT[channel]; - int16_t value = (int16_t)i2c_reg_read_uint8(reg); + int16_t value = (int16_t)i2c->reg_read_uint8(address, reg); if(value & 0b10000000) value -= 256; @@ -754,21 +742,9 @@ namespace pimoroni { return encoder_offset[channel] + value; } - uint8_t IOExpander::i2c_reg_read_uint8(uint8_t reg) { - uint8_t value; - i2c_write_blocking(i2c, address, ®, 1, true); - i2c_read_blocking(i2c, address, (uint8_t *)&value, 1, false); - return value; - } - - void IOExpander::i2c_reg_write_uint8(uint8_t reg, uint8_t value) { - uint8_t buffer[2] = {reg, value}; - i2c_write_blocking(i2c, address, buffer, 2, false); - } - uint8_t IOExpander::get_bit(uint8_t reg, uint8_t bit) { // Returns the specified bit (nth position from right) from a register - return i2c_reg_read_uint8(reg) & (1 << bit); + return i2c->reg_read_uint8(address, reg) & (1 << bit); } void IOExpander::set_bits(uint8_t reg, uint8_t bits) { @@ -780,7 +756,7 @@ namespace pimoroni { if(BIT_ADDRESSED_REGS[i] == reg) { for(uint8_t bit = 0; bit < 8; bit++) { if(bits & (1 << bit)) - i2c_reg_write_uint8(reg, 0b1000 | (bit & 0b111)); + i2c->reg_write_uint8(address, reg, 0b1000 | (bit & 0b111)); } reg_in_bit_addressed_regs = true; break; @@ -789,9 +765,9 @@ namespace pimoroni { // Now deal with any other registers if(!reg_in_bit_addressed_regs) { - uint8_t value = i2c_reg_read_uint8(reg); + uint8_t value = i2c->reg_read_uint8(address, reg); sleep_us(10); - i2c_reg_write_uint8(reg, value | bits); + i2c->reg_write_uint8(address, reg, value | bits); } } @@ -806,7 +782,7 @@ namespace pimoroni { if(BIT_ADDRESSED_REGS[i] == reg) { for(uint8_t bit = 0; bit < 8; bit++) { if(bits & (1 << bit)) - i2c_reg_write_uint8(reg, 0b0000 | (bit & 0b111)); + i2c->reg_write_uint8(address, reg, 0b0000 | (bit & 0b111)); } reg_in_bit_addressed_regs = true; break; @@ -815,9 +791,9 @@ namespace pimoroni { // Now deal with any other registers if(!reg_in_bit_addressed_regs) { - uint8_t value = i2c_reg_read_uint8(reg); + uint8_t value = i2c->reg_read_uint8(address, reg); sleep_us(10); - i2c_reg_write_uint8(reg, value & ~bits); + i2c->reg_write_uint8(address, reg, value & ~bits); } } diff --git a/drivers/ioexpander/ioexpander.hpp b/drivers/ioexpander/ioexpander.hpp index 0d8d58ab..66138c0c 100644 --- a/drivers/ioexpander/ioexpander.hpp +++ b/drivers/ioexpander/ioexpander.hpp @@ -2,6 +2,8 @@ #include "hardware/i2c.h" #include "hardware/gpio.h" +#include "common/pimoroni_common.hpp" +#include "common/pimoroni_i2c.hpp" namespace pimoroni { @@ -26,10 +28,6 @@ namespace pimoroni { public: static const uint8_t DEFAULT_I2C_ADDRESS = 0x18; - static const uint8_t DEFAULT_SDA_PIN = 20; - static const uint8_t DEFAULT_SCL_PIN = 21; - static const uint8_t DEFAULT_INT_PIN = 22; - static const uint8_t PIN_UNUSED = UINT8_MAX; static const uint16_t CHIP_ID = 0xE26A; static const uint8_t CHIP_VERSION = 2; @@ -142,13 +140,11 @@ namespace pimoroni { // Variables //-------------------------------------------------- private: - i2c_inst_t *i2c; + I2C *i2c; // interface pins with our standard defaults where appropriate int8_t address = DEFAULT_I2C_ADDRESS; - int8_t sda = DEFAULT_SDA_PIN; - int8_t scl = DEFAULT_SCL_PIN; - int8_t interrupt = DEFAULT_INT_PIN; + uint interrupt = PIN_UNUSED; uint32_t timeout; bool debug; @@ -162,9 +158,17 @@ namespace pimoroni { // Constructors/Destructor //-------------------------------------------------- public: - IOExpander(); - IOExpander(uint8_t address, uint32_t timeout = 1, bool debug = false); - IOExpander(i2c_inst_t *i2c, uint8_t address, uint8_t sda, uint8_t scl, uint8_t interrupt = PIN_UNUSED, uint32_t timeout = 1, bool debug = false); + IOExpander() : + IOExpander(new I2C(), DEFAULT_I2C_ADDRESS, PIN_UNUSED, timeout, debug) {}; + + IOExpander(uint8_t address, uint32_t timeout = 1, bool debug = false) : + IOExpander(new I2C(), address, PIN_UNUSED, timeout, debug) {}; + + IOExpander(uint8_t address, uint sda, uint scl, uint interrupt = PIN_UNUSED, uint32_t timeout = 1, bool debug = false) : + IOExpander(new I2C(sda, scl), address, interrupt, timeout, debug) {}; + + // TODO remove MicroPython-binding compatibility constructors + IOExpander(I2C *i2c, uint8_t address=DEFAULT_I2C_ADDRESS, uint interrupt = PIN_UNUSED, uint32_t timeout = 1, bool debug = false); //-------------------------------------------------- diff --git a/drivers/is31fl3731/is31fl3731.cmake b/drivers/is31fl3731/is31fl3731.cmake index c3c2b7b7..11c1b280 100644 --- a/drivers/is31fl3731/is31fl3731.cmake +++ b/drivers/is31fl3731/is31fl3731.cmake @@ -7,4 +7,4 @@ target_sources(${DRIVER_NAME} INTERFACE target_include_directories(${DRIVER_NAME} INTERFACE ${CMAKE_CURRENT_LIST_DIR}) # Pull in pico libraries that we need -target_link_libraries(${DRIVER_NAME} INTERFACE pico_stdlib hardware_i2c) +target_link_libraries(${DRIVER_NAME} INTERFACE pico_stdlib hardware_i2c pimoroni_i2c) diff --git a/drivers/is31fl3731/is31fl3731.cpp b/drivers/is31fl3731/is31fl3731.cpp index e1c56236..be79b261 100644 --- a/drivers/is31fl3731/is31fl3731.cpp +++ b/drivers/is31fl3731/is31fl3731.cpp @@ -54,28 +54,24 @@ namespace pimoroni { }; bool IS31FL3731::init() { - i2c_init(i2c, 100000); - gpio_set_function(sda, GPIO_FUNC_I2C); gpio_pull_up(sda); - gpio_set_function(scl, GPIO_FUNC_I2C); gpio_pull_up(scl); - - i2c_reg_write_uint8(reg::BANK, CONFIG_BANK); - i2c_reg_write_uint8(reg::SHUTDOWN, 0b00000000); + i2c->reg_write_uint8(address, reg::BANK, CONFIG_BANK); + i2c->reg_write_uint8(address, reg::SHUTDOWN, 0b00000000); clear(); update(0); - i2c_reg_write_uint8(reg::SHUTDOWN, 0b00000001); + i2c->reg_write_uint8(address, reg::SHUTDOWN, 0b00000001); - i2c_reg_write_uint8(reg::MODE, mode::PICTURE); + i2c->reg_write_uint8(address, reg::MODE, mode::PICTURE); - i2c_reg_write_uint8(reg::AUDIOSYNC, 0); + i2c->reg_write_uint8(address, reg::AUDIOSYNC, 0); return true; } i2c_inst_t* IS31FL3731::get_i2c() const { - return i2c; + return i2c->get_i2c(); } int IS31FL3731::get_address() const { @@ -83,11 +79,11 @@ namespace pimoroni { } int IS31FL3731::get_sda() const { - return sda; + return i2c->get_sda(); } int IS31FL3731::get_scl() const { - return scl; + return i2c->get_scl(); } void IS31FL3731::clear() { @@ -96,20 +92,8 @@ namespace pimoroni { } } - void IS31FL3731::i2c_reg_write_uint8(uint8_t reg, uint8_t value) { - uint8_t buffer[2] = {reg, value}; - i2c_write_blocking(i2c, address, buffer, 2, false); - } - - int16_t IS31FL3731::i2c_reg_read_int16(uint8_t reg) { - int16_t value; - i2c_write_blocking(i2c, address, ®, 1, true); - i2c_read_blocking(i2c, address, (uint8_t *)&value, 2, false); - return value; - } - void IS31FL3731::enable(std::initializer_list pattern, uint8_t frame) { - i2c_reg_write_uint8(reg::BANK, frame); + i2c->reg_write_uint8(address, reg::BANK, frame); uint8_t enable_buf[19]; enable_buf[0] = ENABLE_OFFSET; uint8_t offset = 1; @@ -117,7 +101,7 @@ namespace pimoroni { enable_buf[offset] = byte; offset++; } - i2c_write_blocking(i2c, address, enable_buf, sizeof(enable_buf), false); + i2c->write_blocking(address, enable_buf, sizeof(enable_buf), false); } void IS31FL3731::set(uint8_t index, uint8_t brightness) { @@ -125,10 +109,10 @@ namespace pimoroni { } void IS31FL3731::update(uint8_t frame) { - i2c_reg_write_uint8(reg::BANK, frame); + i2c->reg_write_uint8(address, reg::BANK, frame); buf[0] = COLOR_OFFSET; - i2c_write_blocking(i2c, address, buf, sizeof(buf), false); - i2c_reg_write_uint8(reg::BANK, CONFIG_BANK); // Switch back to config bank - i2c_reg_write_uint8(reg::FRAME, frame); // Set the desired frame as active + i2c->write_blocking(address, buf, sizeof(buf), false); + i2c->reg_write_uint8(address, reg::BANK, CONFIG_BANK); // Switch back to config bank + i2c->reg_write_uint8(address, reg::FRAME, frame); // Set the desired frame as active } } \ No newline at end of file diff --git a/drivers/is31fl3731/is31fl3731.hpp b/drivers/is31fl3731/is31fl3731.hpp index ddccb94b..34a6a2b0 100644 --- a/drivers/is31fl3731/is31fl3731.hpp +++ b/drivers/is31fl3731/is31fl3731.hpp @@ -2,6 +2,8 @@ #include "hardware/i2c.h" #include "hardware/gpio.h" +#include "common/pimoroni_common.hpp" +#include "common/pimoroni_i2c.hpp" #include namespace pimoroni { @@ -15,20 +17,16 @@ namespace pimoroni { static const uint8_t I2C_ADDRESS_ALTERNATE1 = 0x75; static const uint8_t I2C_ADDRESS_ALTERNATE2 = 0x76; static const uint8_t I2C_ADDRESS_ALTERNATE3 = 0x77; - static const uint8_t DEFAULT_SDA_PIN = 20; - static const uint8_t DEFAULT_SCL_PIN = 21; //-------------------------------------------------- // Variables //-------------------------------------------------- private: - i2c_inst_t *i2c = i2c0; + I2C *i2c; // interface pins with our standard defaults where appropriate int8_t address = DEFAULT_I2C_ADDRESS; - int8_t sda = DEFAULT_SDA_PIN; - int8_t scl = DEFAULT_SCL_PIN; uint8_t buf[145]; @@ -39,11 +37,14 @@ namespace pimoroni { public: IS31FL3731() {} - IS31FL3731(uint8_t address) : - address(address) {} + IS31FL3731(uint8_t address) : IS31FL3731(new I2C(I2C_DEFAULT_SDA, I2C_DEFAULT_SCL), address) {} + + IS31FL3731(I2C *i2c, uint8_t address = DEFAULT_I2C_ADDRESS) : i2c(i2c), address(address) {} - IS31FL3731(i2c_inst_t *i2c, uint8_t address, uint8_t sda, uint8_t scl) : - i2c(i2c), address(address), sda(sda), scl(scl) {} + IS31FL3731(i2c_inst_t *i2c_inst, uint8_t address, uint8_t sda, uint8_t scl) : + address(address) { + i2c = new I2C(sda, scl); + } //-------------------------------------------------- diff --git a/drivers/ltp305/ltp305.cmake b/drivers/ltp305/ltp305.cmake index c8663029..aa6779d8 100644 --- a/drivers/ltp305/ltp305.cmake +++ b/drivers/ltp305/ltp305.cmake @@ -7,4 +7,4 @@ target_sources(${DRIVER_NAME} INTERFACE target_include_directories(${DRIVER_NAME} INTERFACE ${CMAKE_CURRENT_LIST_DIR}) # Pull in pico libraries that we need -target_link_libraries(${DRIVER_NAME} INTERFACE pico_stdlib hardware_i2c) +target_link_libraries(${DRIVER_NAME} INTERFACE pico_stdlib hardware_i2c pimoroni_i2c) diff --git a/drivers/ltp305/ltp305.cpp b/drivers/ltp305/ltp305.cpp index 45a03bee..d0016daa 100644 --- a/drivers/ltp305/ltp305.cpp +++ b/drivers/ltp305/ltp305.cpp @@ -5,11 +5,6 @@ namespace pimoroni { bool LTP305::init() { - i2c_init(i2c, 400000); - - gpio_set_function(sda, GPIO_FUNC_I2C); gpio_pull_up(sda); - gpio_set_function(scl, GPIO_FUNC_I2C); gpio_pull_up(scl); - set_brightness(DEFAULT_BRIGHTNESS); clear(); @@ -17,7 +12,7 @@ namespace pimoroni { } i2c_inst_t* LTP305::get_i2c() const { - return i2c; + return i2c->get_i2c(); } int LTP305::get_address() const { @@ -25,17 +20,17 @@ namespace pimoroni { } int LTP305::get_sda() const { - return sda; + return i2c->get_sda(); } int LTP305::get_scl() const { - return scl; + return i2c->get_scl(); } void LTP305::set_brightness(uint8_t brightness, bool update) { brightness = std::min((uint8_t)MAX_BRIGHTNESS, brightness); if(update) - i2c_reg_write_uint8(CMD_BRIGHTNESS, brightness); + i2c->reg_write_uint8(address, CMD_BRIGHTNESS, brightness); } void LTP305::set_decimal(bool left, bool right) { @@ -120,17 +115,12 @@ namespace pimoroni { } void LTP305::show() { - i2c_write_blocking(i2c, address, buf_matrix_left, BUFFER_CMD + BUFFER_LENGTH, false); - i2c_write_blocking(i2c, address, buf_matrix_right, BUFFER_CMD + BUFFER_LENGTH, false); + i2c->write_blocking(address, buf_matrix_left, BUFFER_CMD + BUFFER_LENGTH, false); + i2c->write_blocking(address, buf_matrix_right, BUFFER_CMD + BUFFER_LENGTH, false); - i2c_reg_write_uint8(CMD_MODE, MODE); - i2c_reg_write_uint8(CMD_OPTIONS, OPTS); - i2c_reg_write_uint8(CMD_BRIGHTNESS, brightness); - i2c_reg_write_uint8(CMD_UPDATE, 0x01); - } - - void LTP305::i2c_reg_write_uint8(uint8_t reg, uint8_t value) { - uint8_t buffer[2] = {reg, value}; - i2c_write_blocking(i2c, address, buffer, 2, false); + i2c->reg_write_uint8(address, CMD_MODE, MODE); + i2c->reg_write_uint8(address, CMD_OPTIONS, OPTS); + i2c->reg_write_uint8(address, CMD_BRIGHTNESS, brightness); + i2c->reg_write_uint8(address, CMD_UPDATE, 0x01); } } \ No newline at end of file diff --git a/drivers/ltp305/ltp305.hpp b/drivers/ltp305/ltp305.hpp index c28082a3..f2219795 100644 --- a/drivers/ltp305/ltp305.hpp +++ b/drivers/ltp305/ltp305.hpp @@ -2,6 +2,7 @@ #include "hardware/i2c.h" #include "hardware/gpio.h" +#include "common/pimoroni_i2c.hpp" namespace pimoroni { @@ -16,8 +17,6 @@ namespace pimoroni { static const uint8_t DEFAULT_I2C_ADDRESS = 0x61; static const uint8_t I2C_ADDRESS_ALTERNATE1 = 0x62; static const uint8_t I2C_ADDRESS_ALTERNATE2 = 0x63; - static const uint8_t DEFAULT_SDA_PIN = 20; - static const uint8_t DEFAULT_SCL_PIN = 21; static const uint8_t DEFAULT_BRIGHTNESS = 64; static const uint8_t MAX_BRIGHTNESS = 127; @@ -43,12 +42,10 @@ namespace pimoroni { // Variables //-------------------------------------------------- private: - i2c_inst_t *i2c = i2c0; + I2C *i2c; // interface pins with our standard defaults where appropriate int8_t address = DEFAULT_I2C_ADDRESS; - int8_t sda = DEFAULT_SDA_PIN; - int8_t scl = DEFAULT_SCL_PIN; uint8_t brightness = DEFAULT_BRIGHTNESS; @@ -91,8 +88,10 @@ namespace pimoroni { LTP305(uint8_t address) : address(address) {} - LTP305(i2c_inst_t *i2c, uint8_t address, uint8_t sda, uint8_t scl) : - i2c(i2c), address(address), sda(sda), scl(scl) {} + LTP305(I2C *i2c, uint8_t address = DEFAULT_I2C_ADDRESS) : + i2c(i2c), address(address) {} + + LTP305(uint8_t address, uint sda, uint scl) : LTP305(new I2C(sda, scl), address) {} //-------------------------------------------------- @@ -114,9 +113,6 @@ namespace pimoroni { uint16_t offset_x, uint16_t offset_y, bool wrap = false, bool bg = false, uint8_t on_level = DEFAULT_ON_LEVEL, uint8_t padding = 0); void clear(); void show(); - - private: - void i2c_reg_write_uint8(uint8_t reg, uint8_t value); }; } diff --git a/drivers/ltr559/ltr559.cmake b/drivers/ltr559/ltr559.cmake index 0debe482..411e96af 100644 --- a/drivers/ltr559/ltr559.cmake +++ b/drivers/ltr559/ltr559.cmake @@ -7,4 +7,4 @@ target_sources(${DRIVER_NAME} INTERFACE target_include_directories(${DRIVER_NAME} INTERFACE ${CMAKE_CURRENT_LIST_DIR}) # Pull in pico libraries that we need -target_link_libraries(${DRIVER_NAME} INTERFACE pico_stdlib hardware_i2c) +target_link_libraries(${DRIVER_NAME} INTERFACE pico_stdlib hardware_i2c pimoroni_i2c) diff --git a/drivers/ltr559/ltr559.cpp b/drivers/ltr559/ltr559.cpp index df7686f3..bc48897b 100644 --- a/drivers/ltr559/ltr559.cpp +++ b/drivers/ltr559/ltr559.cpp @@ -27,11 +27,6 @@ namespace pimoroni { pimoroni::lookup LTR559::lookup_light_gain({1, 2, 4, 8, 0, 0, 48, 96}); bool LTR559::init() { - i2c_init(i2c, 400000); - - gpio_set_function(sda, GPIO_FUNC_I2C); gpio_pull_up(sda); - gpio_set_function(scl, GPIO_FUNC_I2C); gpio_pull_up(scl); - if(interrupt != PIN_UNUSED) { gpio_set_function(interrupt, GPIO_FUNC_SIO); gpio_set_dir(interrupt, GPIO_IN); @@ -64,15 +59,15 @@ namespace pimoroni { } void LTR559::reset() { - set_bits(LTR559_ALS_CONTROL, LTR559_ALS_CONTROL_SW_RESET_BIT); + i2c->set_bits(address, LTR559_ALS_CONTROL, LTR559_ALS_CONTROL_SW_RESET_BIT); - while(get_bits(LTR559_ALS_CONTROL, LTR559_ALS_CONTROL_SW_RESET_BIT)) { + while(i2c->get_bits(address, LTR559_ALS_CONTROL, LTR559_ALS_CONTROL_SW_RESET_BIT)) { sleep_ms(100); } } i2c_inst_t* LTR559::get_i2c() const { - return i2c; + return i2c->get_i2c(); } int LTR559::get_address() const { @@ -80,11 +75,11 @@ namespace pimoroni { } int LTR559::get_sda() const { - return sda; + return i2c->get_sda(); } int LTR559::get_scl() const { - return scl; + return i2c->get_sda(); } int LTR559::get_int() const { @@ -94,26 +89,26 @@ namespace pimoroni { uint8_t LTR559::part_id() { uint8_t part_id; - read_bytes(LTR559_PART_ID, &part_id, 1); + i2c->read_bytes(address, LTR559_PART_ID, &part_id, 1); return (part_id >> LTR559_PART_ID_PART_NUMBER_SHIFT) & LTR559_PART_ID_PART_NUMBER_MASK; } uint8_t LTR559::revision_id() { uint8_t revision_id; - read_bytes(LTR559_PART_ID, &revision_id, 1); + i2c->read_bytes(address, LTR559_PART_ID, &revision_id, 1); return revision_id & LTR559_PART_ID_REVISION_MASK; } uint8_t LTR559::manufacturer_id() { uint8_t manufacturer; - read_bytes(LTR559_MANUFACTURER_ID, &manufacturer, 1); + i2c->read_bytes(address, LTR559_MANUFACTURER_ID, &manufacturer, 1); return manufacturer; } bool LTR559::get_reading() { bool has_updated = false; uint8_t status; - this->read_bytes(LTR559_ALS_PS_STATUS, &status, 1); + i2c->read_bytes(address, LTR559_ALS_PS_STATUS, &status, 1); bool als_int = (status >> LTR559_ALS_PS_STATUS_ALS_INTERRUPT_BIT) & 0b1; bool ps_int = (status >> LTR559_ALS_PS_STATUS_PS_INTERRUPT_BIT) & 0b1; bool als_data = (status >> LTR559_ALS_PS_STATUS_ALS_DATA_BIT) & 0b1; @@ -122,7 +117,7 @@ namespace pimoroni { if(ps_int || ps_data) { has_updated = true; uint16_t ps0; - read_bytes(LTR559_PS_DATA, (uint8_t *)&ps0, 2); + i2c->read_bytes(address, LTR559_PS_DATA, (uint8_t *)&ps0, 2); ps0 &= LTR559_PS_DATA_MASK; data.proximity = ps0; @@ -131,7 +126,7 @@ namespace pimoroni { if(als_int || als_data) { has_updated = true; uint16_t als[2]; - read_bytes(LTR559_ALS_DATA_CH1, (uint8_t *)&als, 4); + i2c->read_bytes(address, LTR559_ALS_DATA_CH1, (uint8_t *)&als, 4); data.als0 = als[1]; data.als1 = als[0]; data.gain = this->lookup_light_gain.value((status >> LTR559_ALS_PS_STATUS_ALS_GAIN_SHIFT) & LTR559_ALS_PS_STATUS_ALS_GAIN_MASK); @@ -164,7 +159,7 @@ namespace pimoroni { buf |= 0b1 << LTR559_INTERRUPT_POLARITY_BIT; buf |= (uint8_t)light << LTR559_INTERRUPT_ALS_BIT; buf |= (uint8_t)proximity << LTR559_INTERRUPT_PS_BIT; - write_bytes(LTR559_INTERRUPT, &buf, 1); + i2c->write_bytes(address, LTR559_INTERRUPT, &buf, 1); } void LTR559::proximity_led(uint8_t current, uint8_t duty_cycle, uint8_t pulse_freq, uint8_t num_pulses) { @@ -177,10 +172,10 @@ namespace pimoroni { pulse_freq <<= LTR559_PS_LED_PULSE_FREQ_SHIFT; uint8_t buf = current | duty_cycle | pulse_freq; - write_bytes(LTR559_PS_LED, &buf, 1); + i2c->write_bytes(address, LTR559_PS_LED, &buf, 1); buf = num_pulses & LTR559_PS_N_PULSES_MASK; - write_bytes(LTR559_PS_N_PULSES, &buf, 1); + i2c->write_bytes(address, LTR559_PS_N_PULSES, &buf, 1); } void LTR559::light_control(bool active, uint8_t gain) { @@ -193,12 +188,12 @@ namespace pimoroni { else buf &= ~(0b1 << LTR559_ALS_CONTROL_MODE_BIT); - write_bytes(LTR559_ALS_CONTROL, &buf, 1); + i2c->write_bytes(address, LTR559_ALS_CONTROL, &buf, 1); } void LTR559::proximity_control(bool active, bool saturation_indicator) { uint8_t buf = 0; - read_bytes(LTR559_PS_CONTROL, &buf, 1); + i2c->read_bytes(address, LTR559_PS_CONTROL, &buf, 1); if(active) buf |= LTR559_PS_CONTROL_ACTIVE_MASK; else @@ -209,21 +204,21 @@ namespace pimoroni { else buf &= ~(0b1 << LTR559_PS_CONTROL_SATURATION_INDICATOR_ENABLE_BIT); - write_bytes(LTR559_PS_CONTROL, &buf, 1); + i2c->write_bytes(address, LTR559_PS_CONTROL, &buf, 1); } void LTR559::light_threshold(uint16_t lower, uint16_t upper) { lower = __builtin_bswap16(lower); upper = __builtin_bswap16(upper); - write_bytes(LTR559_ALS_THRESHOLD_LOWER, (uint8_t *)&lower, 2); - write_bytes(LTR559_ALS_THRESHOLD_UPPER, (uint8_t *)&upper, 2); + i2c->write_bytes(address, LTR559_ALS_THRESHOLD_LOWER, (uint8_t *)&lower, 2); + i2c->write_bytes(address, LTR559_ALS_THRESHOLD_UPPER, (uint8_t *)&upper, 2); } void LTR559::proximity_threshold(uint16_t lower, uint16_t upper) { lower = uint16_to_bit12(lower); upper = uint16_to_bit12(upper); - write_bytes(LTR559_PS_THRESHOLD_LOWER, (uint8_t *)&lower, 2); - write_bytes(LTR559_PS_THRESHOLD_UPPER, (uint8_t *)&upper, 2); + i2c->write_bytes(address, LTR559_PS_THRESHOLD_LOWER, (uint8_t *)&lower, 2); + i2c->write_bytes(address, LTR559_PS_THRESHOLD_UPPER, (uint8_t *)&upper, 2); } void LTR559::light_measurement_rate(uint16_t integration_time, uint16_t rate) { @@ -233,17 +228,17 @@ namespace pimoroni { uint8_t buf = 0; buf |= rate; buf |= integration_time << LTR559_ALS_MEAS_RATE_INTEGRATION_TIME_SHIFT; - write_bytes(LTR559_ALS_MEAS_RATE, &buf, 1); + i2c->write_bytes(address, LTR559_ALS_MEAS_RATE, &buf, 1); } void LTR559::proximity_measurement_rate(uint16_t rate) { uint8_t buf = lookup_proximity_meas_rate.index(rate); - write_bytes(LTR559_PS_MEAS_RATE, &buf, 1); + i2c->write_bytes(address, LTR559_PS_MEAS_RATE, &buf, 1); } void LTR559::proximity_offset(uint16_t offset) { offset &= LTR559_PS_OFFSET_MASK; - write_bytes(LTR559_PS_OFFSET, (uint8_t *)&offset, 1); + i2c->write_bytes(address, LTR559_PS_OFFSET, (uint8_t *)&offset, 1); } uint16_t LTR559::bit12_to_uint16(uint16_t value) { @@ -253,41 +248,4 @@ namespace pimoroni { uint16_t LTR559::uint16_to_bit12(uint16_t value) { return ((value & 0xFF) << 8) | ((value & 0xF00) >> 8); } - - // i2c functions - - int LTR559::write_bytes(uint8_t reg, uint8_t *buf, int len) { - uint8_t buffer[len + 1]; - buffer[0] = reg; - for(int x = 0; x < len; x++) { - buffer[x + 1] = buf[x]; - } - return i2c_write_blocking(i2c, address, buffer, len + 1, false); - }; - - int LTR559::read_bytes(uint8_t reg, uint8_t *buf, int len) { - i2c_write_blocking(i2c, address, ®, 1, true); - i2c_read_blocking(i2c, address, buf, len, false); - return len; - }; - - uint8_t LTR559::get_bits(uint8_t reg, uint8_t shift, uint8_t mask) { - uint8_t value; - read_bytes(reg, &value, 1); - return value & (mask << shift); - } - - void LTR559::set_bits(uint8_t reg, uint8_t shift, uint8_t mask) { - uint8_t value; - read_bytes(reg, &value, 1); - value |= mask << shift; - write_bytes(reg, &value, 1); - } - - void LTR559::clear_bits(uint8_t reg, uint8_t shift, uint8_t mask) { - uint8_t value; - read_bytes(reg, &value, 1); - value &= ~(mask << shift); - write_bytes(reg, &value, 1); - } } \ No newline at end of file diff --git a/drivers/ltr559/ltr559.hpp b/drivers/ltr559/ltr559.hpp index 4bca0e24..7c2cacc9 100644 --- a/drivers/ltr559/ltr559.hpp +++ b/drivers/ltr559/ltr559.hpp @@ -1,7 +1,8 @@ #pragma once -#include "hardware/i2c.h" #include "hardware/gpio.h" +#include "common/pimoroni_common.hpp" +#include "common/pimoroni_i2c.hpp" #include #include @@ -85,6 +86,7 @@ namespace pimoroni { + typedef struct { uint16_t proximity; uint16_t als0; @@ -110,10 +112,6 @@ namespace pimoroni { //-------------------------------------------------- public: static const uint8_t DEFAULT_I2C_ADDRESS = 0x23; - static const uint8_t DEFAULT_SDA_PIN = 20; - static const uint8_t DEFAULT_SCL_PIN = 21; - static const uint8_t DEFAULT_INT_PIN = 22; - static const uint8_t PIN_UNUSED = UINT8_MAX; private: const int ch0_c[4] = {17743, 42785, 5926, 0}; @@ -127,13 +125,11 @@ namespace pimoroni { ltr559_reading data; private: - i2c_inst_t *i2c = i2c0; + I2C *i2c; // interface pins with our standard defaults where appropriate - int8_t address = DEFAULT_I2C_ADDRESS; - int8_t sda = DEFAULT_SDA_PIN; - int8_t scl = DEFAULT_SCL_PIN; - int8_t interrupt = DEFAULT_INT_PIN; + const uint8_t address = DEFAULT_I2C_ADDRESS; + uint interrupt = PIN_UNUSED; static pimoroni::lookup lookup_led_current; static pimoroni::lookup lookup_led_duty_cycle; @@ -148,14 +144,12 @@ namespace pimoroni { // Constructors/Destructor //-------------------------------------------------- public: - LTR559() {} + LTR559() : LTR559(new I2C()) {}; - LTR559(uint8_t address) : - address(address) {} - - LTR559(i2c_inst_t *i2c, uint8_t address, uint8_t sda, uint8_t scl, uint8_t interrupt = PIN_UNUSED) : - i2c(i2c), address(address), sda(sda), scl(scl), interrupt(interrupt) {} + LTR559(I2C *i2c, uint interrupt = PIN_UNUSED) : i2c(i2c), interrupt(interrupt) {} + // TODO remove MicroPython-binding compatibility constructors + LTR559(uint sda, uint scl, uint interrupt = PIN_UNUSED) : LTR559(new I2C(), interrupt) {} //-------------------------------------------------- // Methods @@ -188,13 +182,6 @@ namespace pimoroni { private: uint16_t bit12_to_uint16(uint16_t value); uint16_t uint16_to_bit12(uint16_t value); - - // From i2cdevice - int write_bytes(uint8_t reg, uint8_t *buf, int len); - int read_bytes(uint8_t reg, uint8_t *buf, int len); - uint8_t get_bits(uint8_t reg, uint8_t shift, uint8_t mask=0b1); - void set_bits(uint8_t reg, uint8_t shift, uint8_t mask=0b1); - void clear_bits(uint8_t reg, uint8_t shift, uint8_t mask=0b1); }; } \ No newline at end of file diff --git a/drivers/msa301/CMakeLists.txt b/drivers/msa301/CMakeLists.txt index 85e32500..ff143a47 100644 --- a/drivers/msa301/CMakeLists.txt +++ b/drivers/msa301/CMakeLists.txt @@ -1,10 +1 @@ -add_library(msa301 INTERFACE) - -target_sources(msa301 INTERFACE - ${CMAKE_CURRENT_LIST_DIR}/msa301.cpp -) - -target_include_directories(msa301 INTERFACE ${CMAKE_CURRENT_LIST_DIR}) - -# Pull in pico libraries that we need -target_link_libraries(msa301 INTERFACE pico_stdlib hardware_i2c) \ No newline at end of file +include(msa301.cmake) \ No newline at end of file diff --git a/drivers/msa301/msa301.cmake b/drivers/msa301/msa301.cmake index f10aadc2..8cb300f9 100644 --- a/drivers/msa301/msa301.cmake +++ b/drivers/msa301/msa301.cmake @@ -7,4 +7,4 @@ target_sources(msa301 INTERFACE target_include_directories(msa301 INTERFACE ${CMAKE_CURRENT_LIST_DIR}) # Pull in pico libraries that we need -target_link_libraries(msa301 INTERFACE pico_stdlib hardware_i2c) \ No newline at end of file +target_link_libraries(msa301 INTERFACE pico_stdlib hardware_i2c pimoroni_i2c) \ No newline at end of file diff --git a/drivers/msa301/msa301.cpp b/drivers/msa301/msa301.cpp index a190de51..2f30d8d1 100644 --- a/drivers/msa301/msa301.cpp +++ b/drivers/msa301/msa301.cpp @@ -8,11 +8,6 @@ namespace pimoroni { bool MSA301::init() { - i2c_init(i2c, 400000); - - gpio_set_function(sda, GPIO_FUNC_I2C); gpio_pull_up(sda); - gpio_set_function(scl, GPIO_FUNC_I2C); gpio_pull_up(scl); - if(interrupt != PIN_UNUSED) { gpio_set_function(interrupt, GPIO_FUNC_SIO); gpio_set_dir(interrupt, GPIO_IN); @@ -28,20 +23,20 @@ namespace pimoroni { } void MSA301::reset() { - i2c_reg_write_uint8(SOFT_RESET, 0b00100100); + i2c->reg_write_uint8(address, SOFT_RESET, 0b00100100); sleep_ms(1); } i2c_inst_t* MSA301::get_i2c() const { - return i2c; + return i2c->get_i2c(); } int MSA301::get_sda() const { - return sda; + return i2c->get_sda(); } int MSA301::get_scl() const { - return scl; + return i2c->get_scl(); } int MSA301::get_int() const { @@ -49,20 +44,20 @@ namespace pimoroni { } uint8_t MSA301::part_id() { - return i2c_reg_read_uint8(PART_ID); + return i2c->reg_read_uint8(address, PART_ID); } float MSA301::get_axis(Axis axis, uint8_t sample_count) { if(sample_count > 1) { int32_t total = 0; for(uint8_t i = 0; i < sample_count; i++) { - total += i2c_reg_read_int16((int)axis); + total += i2c->reg_read_int16(address, (int)axis); } total /= sample_count; return total / 16384.0f; } - return i2c_reg_read_int16(axis) / 16384.0f; + return i2c->reg_read_int16(address, axis) / 16384.0f; } float MSA301::get_x_axis(uint8_t sample_count) { @@ -78,19 +73,19 @@ namespace pimoroni { } MSA301::Orientation MSA301::get_orientation() { - return (Orientation)((i2c_reg_read_uint8(ORIENTATION_STATUS) >> 4) & 0b11); + return (Orientation)((i2c->reg_read_uint8(address, ORIENTATION_STATUS) >> 4) & 0b11); } void MSA301::set_power_mode(MSA301::PowerMode power_mode) { - i2c_reg_write_uint8(POWER_MODE_BANDWIDTH, power_mode); + i2c->reg_write_uint8(address, POWER_MODE_BANDWIDTH, power_mode); } void MSA301::set_range_and_resolution(Range range, MSA301::Resolution resolution) { - i2c_reg_write_uint8(RESOLUTION_RANGE, range | resolution); + i2c->reg_write_uint8(address, RESOLUTION_RANGE, range | resolution); } void MSA301::set_axis_polarity(uint8_t polarity) { - i2c_reg_write_uint8(SET_AXIS_POLARITY, polarity); + i2c->reg_write_uint8(address, SET_AXIS_POLARITY, polarity); } void MSA301::disable_all_interrupts() { @@ -98,17 +93,17 @@ namespace pimoroni { } void MSA301::enable_interrupts(uint16_t interrupts) { - i2c_reg_write_uint8(INTERRUPT_ENABLE_0, interrupts & 0xff); - i2c_reg_write_uint8(INTERRUPT_ENABLE_1, (interrupts & 0xff00) >> 8); + i2c->reg_write_uint8(address, INTERRUPT_ENABLE_0, interrupts & 0xff); + i2c->reg_write_uint8(address, INTERRUPT_ENABLE_1, (interrupts & 0xff00) >> 8); } void MSA301::set_interrupt_latch(MSA301::InterruptLatchPeriod latch_period, bool reset_latched = false) { - i2c_reg_write_uint8(INTERRUPT_LATCH_PERIOD, latch_period | (reset_latched ? 0b10000000: 0b0)); + i2c->reg_write_uint8(address, INTERRUPT_LATCH_PERIOD, latch_period | (reset_latched ? 0b10000000: 0b0)); } bool MSA301::read_interrupt(Interrupt interrupt) { if(interrupt == NEW_DATA) { - return i2c_reg_read_uint8(DATA_INTERRUPT) & 0b1; + return i2c->reg_read_uint8(address, DATA_INTERRUPT) & 0b1; } // determine which bit indicates the status of this interrupt @@ -119,26 +114,7 @@ namespace pimoroni { if(interrupt == SINGLE_TAP) bit = 5; if(interrupt == ORIENTATION) bit = 6; - return i2c_reg_read_uint8(MOTION_INTERRUPT) & (1U << bit); - } - - void MSA301::i2c_reg_write_uint8(uint8_t reg, uint8_t value) { - uint8_t buffer[2] = {reg, value}; - i2c_write_blocking(i2c, address, buffer, 2, false); - } - - uint8_t MSA301::i2c_reg_read_uint8(uint8_t reg) { - uint8_t value; - i2c_write_blocking(i2c, address, ®, 1, true); - i2c_read_blocking(i2c, address, (uint8_t *)&value, 1, false); - return value; - } - - int16_t MSA301::i2c_reg_read_int16(uint8_t reg) { - int16_t value; - i2c_write_blocking(i2c, address, ®, 1, true); - i2c_read_blocking(i2c, address, (uint8_t *)&value, 2, false); - return value; + return i2c->reg_read_uint8(address, MOTION_INTERRUPT) & (1U << bit); } } \ No newline at end of file diff --git a/drivers/msa301/msa301.hpp b/drivers/msa301/msa301.hpp index afdbc8ca..5d43088c 100644 --- a/drivers/msa301/msa301.hpp +++ b/drivers/msa301/msa301.hpp @@ -2,6 +2,8 @@ #include "hardware/i2c.h" #include "hardware/gpio.h" +#include "common/pimoroni_common.hpp" +#include "common/pimoroni_i2c.hpp" namespace pimoroni { @@ -11,10 +13,6 @@ namespace pimoroni { //-------------------------------------------------- public: static const uint8_t DEFAULT_I2C_ADDRESS = 0x26; - static const uint8_t DEFAULT_SDA_PIN = 20; - static const uint8_t DEFAULT_SCL_PIN = 21; - static const uint8_t DEFAULT_INT_PIN = 22; - static const uint8_t PIN_UNUSED = UINT8_MAX; static const uint8_t SOFT_RESET = 0x00; static const uint8_t PART_ID = 0x01; @@ -106,23 +104,20 @@ namespace pimoroni { // Variables //-------------------------------------------------- private: - i2c_inst_t *i2c = i2c0; - - // interface pins with our standard defaults where appropriate - int8_t address = DEFAULT_I2C_ADDRESS; - int8_t sda = DEFAULT_SDA_PIN; - int8_t scl = DEFAULT_SCL_PIN; - int8_t interrupt = DEFAULT_INT_PIN; - + I2C *i2c; + const uint8_t address = DEFAULT_I2C_ADDRESS; + uint interrupt = PIN_UNUSED; //-------------------------------------------------- // Constructors/Destructor //-------------------------------------------------- public: - MSA301() {} + MSA301() : MSA301(new I2C()) {}; - MSA301(i2c_inst_t *i2c, uint8_t sda, uint8_t scl, uint8_t interrupt) : - i2c(i2c), sda(sda), scl(scl), interrupt(interrupt) {} + MSA301(I2C *i2c, uint interrupt = PIN_UNUSED) : i2c(i2c), interrupt(interrupt) {} + + // TODO remove MicroPython-binding compatibility constructors + MSA301(i2c_inst_t *i2c_inst, uint sda, uint scl, uint interrupt = PIN_UNUSED) : MSA301(new I2C(sda, scl), interrupt) {} //-------------------------------------------------- @@ -152,11 +147,6 @@ namespace pimoroni { void enable_interrupts(uint16_t interrupts); void set_interrupt_latch(InterruptLatchPeriod latch_period, bool reset_latched); bool read_interrupt(Interrupt interrupt); - - private: - void i2c_reg_write_uint8(uint8_t reg, uint8_t value); - uint8_t i2c_reg_read_uint8(uint8_t reg); - int16_t i2c_reg_read_int16(uint8_t reg); }; } diff --git a/drivers/rv3028/rv3028.cmake b/drivers/rv3028/rv3028.cmake index 8a32686c..bc3e0fad 100644 --- a/drivers/rv3028/rv3028.cmake +++ b/drivers/rv3028/rv3028.cmake @@ -7,4 +7,4 @@ target_sources(${DRIVER_NAME} INTERFACE target_include_directories(${DRIVER_NAME} INTERFACE ${CMAKE_CURRENT_LIST_DIR}) # Pull in pico libraries that we need -target_link_libraries(${DRIVER_NAME} INTERFACE pico_stdlib hardware_i2c) +target_link_libraries(${DRIVER_NAME} INTERFACE pico_stdlib hardware_i2c pimoroni_i2c) diff --git a/drivers/rv3028/rv3028.cpp b/drivers/rv3028/rv3028.cpp index 5e5e41b4..3dd1477c 100644 --- a/drivers/rv3028/rv3028.cpp +++ b/drivers/rv3028/rv3028.cpp @@ -61,13 +61,6 @@ BUILD_MONTH_OCT | BUILD_MONTH_NOV | BUILD_MONTH_DEC namespace pimoroni { bool RV3028::init() { - i2c_init(i2c, 400000); - - gpio_set_function(sda, GPIO_FUNC_I2C); - gpio_pull_up(sda); - gpio_set_function(scl, GPIO_FUNC_I2C); - gpio_pull_up(scl); - if(interrupt != PIN_UNUSED) { gpio_set_function(interrupt, GPIO_FUNC_SIO); gpio_set_dir(interrupt, GPIO_IN); @@ -75,7 +68,7 @@ namespace pimoroni { } uint8_t chip_id = 0; - read_bytes(RV3028_ID, &chip_id, 1); + i2c->read_bytes(address, RV3028_ID, &chip_id, 1); if(chip_id != (RV3028_CHIP_ID | RV3028_VERSION)) { return false; } @@ -88,15 +81,15 @@ namespace pimoroni { } i2c_inst_t* RV3028::get_i2c() const { - return i2c; + return i2c->get_i2c(); } int RV3028::get_sda() const { - return sda; + return i2c->get_sda(); } int RV3028::get_scl() const { - return scl; + return i2c->get_scl(); } int RV3028::get_int() const { @@ -712,7 +705,7 @@ namespace pimoroni { // Returns the status byte uint8_t RV3028::status(void) { - return(read_register(RV3028_STATUS)); + return read_register(RV3028_STATUS); } void RV3028::clear_interrupts() { // Read the status register to clear the current interrupt flags @@ -733,7 +726,7 @@ namespace pimoroni { uint8_t RV3028::read_register(uint8_t addr) { uint8_t b1[2]; - if(1 == RV3028::read_bytes(addr, b1, 1)) + if(1 == i2c->read_bytes(address, addr, b1, 1)) return b1[0]; else return 0xFF; //Error @@ -743,15 +736,15 @@ namespace pimoroni { uint8_t b1[2]; b1[0] = val; b1[1] = 0; - return(RV3028::write_bytes(addr, b1, 1)); + return i2c->write_bytes(address, addr, b1, 1); } bool RV3028::read_multiple_registers(uint8_t addr, uint8_t *dest, uint8_t len) { - return(RV3028::read_bytes(addr, dest, len)); + return i2c->read_bytes(address, addr, dest, len); } bool RV3028::write_multiple_registers(uint8_t addr, uint8_t *values, uint8_t len) { - return(RV3028::write_bytes(addr, values, len)); + return i2c->write_bytes(address, addr, values, len); } bool RV3028::write_config_eeprom_ram_mirror(uint8_t eeprom_addr, uint8_t val) { @@ -833,52 +826,15 @@ namespace pimoroni { } void RV3028::set_bit(uint8_t reg_addr, uint8_t bit_num) { - RV3028::set_bits(reg_addr, bit_num, 0x01); + i2c->set_bits(address, reg_addr, bit_num, 0x01); } void RV3028::clear_bit(uint8_t reg_addr, uint8_t bit_num) { - RV3028::clear_bits(reg_addr, bit_num, 0x01); + i2c->clear_bits(address, reg_addr, bit_num, 0x01); } bool RV3028::read_bit(uint8_t reg_addr, uint8_t bit_num) { - uint8_t value = RV3028::get_bits(reg_addr, bit_num, 0x01); + uint8_t value = i2c->get_bits(address, reg_addr, bit_num, 0x01); return value; } - - // i2c functions - int RV3028::write_bytes(uint8_t reg, uint8_t *buf, int len) { - uint8_t buffer[len + 1]; - buffer[0] = reg; - for(int x = 0; x < len; x++) { - buffer[x + 1] = buf[x]; - } - return i2c_write_blocking(i2c, address, buffer, len + 1, false); - }; - - int RV3028::read_bytes(uint8_t reg, uint8_t *buf, int len) { - i2c_write_blocking(i2c, address, ®, 1, true); - i2c_read_blocking(i2c, address, buf, len, false); - return len; - }; - - uint8_t RV3028::get_bits(uint8_t reg, uint8_t shift, uint8_t mask) { - uint8_t value; - read_bytes(reg, &value, 1); - return value & (mask << shift); - } - - void RV3028::set_bits(uint8_t reg, uint8_t shift, uint8_t mask) { - uint8_t value; - read_bytes(reg, &value, 1); - value |= mask << shift; - write_bytes(reg, &value, 1); - } - - void RV3028::clear_bits(uint8_t reg, uint8_t shift, uint8_t mask) { - uint8_t value; - read_bytes(reg, &value, 1); - value &= ~(mask << shift); - write_bytes(reg, &value, 1); - } - } \ No newline at end of file diff --git a/drivers/rv3028/rv3028.hpp b/drivers/rv3028/rv3028.hpp index 4ef2f1ec..ba66c2d3 100644 --- a/drivers/rv3028/rv3028.hpp +++ b/drivers/rv3028/rv3028.hpp @@ -12,6 +12,8 @@ Distributed as-is; no warranty is given. #include "hardware/i2c.h" #include "hardware/gpio.h" +#include "common/pimoroni_common.hpp" +#include "common/pimoroni_i2c.hpp" #include #include @@ -196,8 +198,6 @@ namespace pimoroni { //-------------------------------------------------- public: static const uint8_t DEFAULT_I2C_ADDRESS = RV3028_ADDR; - static const uint8_t DEFAULT_SDA_PIN = 20; - static const uint8_t DEFAULT_SCL_PIN = 21; static const uint8_t DEFAULT_INT_PIN = 22; static const uint8_t PIN_UNUSED = UINT8_MAX; @@ -206,13 +206,11 @@ namespace pimoroni { // Variables //-------------------------------------------------- private: - i2c_inst_t *i2c = i2c0; + I2C *i2c; // interface pins with our standard defaults where appropriate - int8_t address = DEFAULT_I2C_ADDRESS; - int8_t sda = DEFAULT_SDA_PIN; - int8_t scl = DEFAULT_SCL_PIN; - int8_t interrupt = DEFAULT_INT_PIN; + const int8_t address = DEFAULT_I2C_ADDRESS; + uint interrupt = DEFAULT_INT_PIN; uint8_t times[TIME_ARRAY_LENGTH]; @@ -221,10 +219,13 @@ namespace pimoroni { // Constructors/Destructor //-------------------------------------------------- public: - RV3028() {} + RV3028() : RV3028(new I2C()) {} - RV3028(i2c_inst_t *i2c, uint8_t sda, uint8_t scl, uint8_t interrupt = PIN_UNUSED) : - i2c(i2c), sda(sda), scl(scl), interrupt(interrupt) {} + RV3028(I2C *i2c, uint interrupt = DEFAULT_INT_PIN) : + i2c(i2c), interrupt(interrupt) {} + + // TODO remove MicroPython-binding compatibility constructors + RV3028(i2c_inst_t *i2c, uint sda, uint scl, uint interrupt = DEFAULT_INT_PIN) : RV3028(new I2C(sda, scl), interrupt) {} //-------------------------------------------------- @@ -324,13 +325,6 @@ private: void set_bit(uint8_t reg_addr, uint8_t bit_num); void clear_bit(uint8_t reg_addr, uint8_t bit_num); bool read_bit(uint8_t reg_addr, uint8_t bit_num); - - // From i2cdevice - int write_bytes(uint8_t reg, uint8_t *buf, int len); - int read_bytes(uint8_t reg, uint8_t *buf, int len); - uint8_t get_bits(uint8_t reg, uint8_t shift, uint8_t mask = 0b1); - void set_bits(uint8_t reg, uint8_t shift, uint8_t mask = 0b1); - void clear_bits(uint8_t reg, uint8_t shift, uint8_t mask = 0b1); }; // POSSIBLE ENHANCEMENTS : diff --git a/drivers/sgp30/sgp30.cmake b/drivers/sgp30/sgp30.cmake index e2d4f6b6..b7ad01af 100644 --- a/drivers/sgp30/sgp30.cmake +++ b/drivers/sgp30/sgp30.cmake @@ -7,4 +7,4 @@ target_sources(${DRIVER_NAME} INTERFACE target_include_directories(${DRIVER_NAME} INTERFACE ${CMAKE_CURRENT_LIST_DIR}) # Pull in pico libraries that we need -target_link_libraries(${DRIVER_NAME} INTERFACE pico_stdlib hardware_i2c) \ No newline at end of file +target_link_libraries(${DRIVER_NAME} INTERFACE pico_stdlib hardware_i2c pimoroni_i2c) \ No newline at end of file diff --git a/drivers/sgp30/sgp30.cpp b/drivers/sgp30/sgp30.cpp index f785f8d4..3b029d69 100644 --- a/drivers/sgp30/sgp30.cpp +++ b/drivers/sgp30/sgp30.cpp @@ -14,14 +14,6 @@ Distributed as-is; no warranty is given. namespace pimoroni { bool SGP30::init() { - - i2c_init(i2c, 400000); - - gpio_set_function(sda, GPIO_FUNC_I2C); - gpio_pull_up(sda); - gpio_set_function(scl, GPIO_FUNC_I2C); - gpio_pull_up(scl); - soft_reset(); if(!retrieve_unique_id()) { @@ -46,15 +38,15 @@ namespace pimoroni { } i2c_inst_t* SGP30::get_i2c() const { - return i2c; + return i2c->get_i2c(); } int SGP30::get_sda() const { - return sda; + return i2c->get_sda(); } int SGP30::get_scl() const { - return scl; + return i2c->get_scl(); } // Get the unique ID from the Chip. Will fail if no chip attached @@ -137,7 +129,7 @@ namespace pimoroni { // Write a single byte globally (not to a specifc I2c address) bool SGP30::write_global(uint16_t reg, uint16_t delay_ms) { uint8_t buffer[1] = { (uint8_t)(reg & 0xFF)}; - i2c_write_blocking(i2c, 0, buffer, 1, false); + i2c->write_blocking(0, buffer, 1, false); sleep_ms(delay_ms); return true; } @@ -145,7 +137,7 @@ namespace pimoroni { // Write just the register to the i2c address, no parameter bool SGP30::write_reg(uint16_t reg, uint16_t delay_ms) { uint8_t buffer[2] = { (uint8_t)((reg >> 8) & 0xFF), (uint8_t)(reg & 0xFF)}; - i2c_write_blocking(i2c, address, buffer, 2, false); + i2c->write_blocking(address, buffer, 2, false); sleep_ms(delay_ms); return true; } @@ -154,7 +146,7 @@ namespace pimoroni { bool SGP30::write_reg_1_word(uint16_t reg, uint16_t delay_ms, uint16_t value) { uint8_t buffer[5] = { (uint8_t)((reg >> 8) & 0xFF), (uint8_t)(reg & 0xFF), (uint8_t)((value >> 8) & 0xFF), (uint8_t)(value & 0xFF), calculate_crc(value)}; - i2c_write_blocking(i2c, address, buffer, 5, false); + i2c->write_blocking(address, buffer, 5, false); sleep_ms(delay_ms); return true; } @@ -164,7 +156,7 @@ namespace pimoroni { uint8_t buffer[8] = { (uint8_t)((reg >> 8) & 0xFF), (uint8_t)(reg & 0xFF), (uint8_t)((value1 >> 8) & 0xFF), (uint8_t)(value1 & 0xFF), calculate_crc(value1), (uint8_t)((value2 >> 8) & 0xFF), (uint8_t)(value2 & 0xFF), calculate_crc(value2)}; - i2c_write_blocking(i2c, address, buffer, 8, false); + i2c->write_blocking(address, buffer, 8, false); sleep_ms(delay_ms); return true; } @@ -173,9 +165,9 @@ namespace pimoroni { bool SGP30::read_reg_1_word(uint16_t reg, uint16_t delay_ms, uint16_t *value) { uint8_t regbuf[2] = { (uint8_t)((reg >> 8) & 0xFF), (uint8_t)(reg & 0xFF) }; uint8_t buffer[3]; - i2c_write_blocking(i2c, address, regbuf, 2, true); + i2c->write_blocking(address, regbuf, 2, true); sleep_ms(delay_ms); - i2c_read_blocking(i2c, address, buffer, 3, false); + i2c->read_blocking(address, buffer, 3, false); if(buffer[2] != calculate_crc(buffer[0], buffer[1])) return false; *value = (buffer[0] << 8) + buffer[1]; @@ -186,9 +178,9 @@ namespace pimoroni { bool SGP30::read_reg_2_words(uint16_t reg, uint16_t delay_ms, uint16_t *value1, uint16_t *value2) { uint8_t regbuf[2] = { (uint8_t)((reg >> 8) & 0xFF), (uint8_t)(reg & 0xFF) }; uint8_t buffer[6]; - i2c_write_blocking(i2c, address, regbuf, 2, true); + i2c->write_blocking(address, regbuf, 2, true); sleep_ms(delay_ms); - i2c_read_blocking(i2c, address, buffer, 6, false); + i2c->read_blocking(address, buffer, 6, false); if((buffer[2] != calculate_crc(buffer[0], buffer[1])) || (buffer[5] != calculate_crc(buffer[3], buffer[4]))) { return false; } @@ -201,9 +193,9 @@ namespace pimoroni { bool SGP30::read_reg_3_words(uint16_t reg, uint16_t delay_ms, uint16_t *value1, uint16_t *value2, uint16_t *value3) { uint8_t regbuf[2] = { (uint8_t)((reg >> 8) & 0xFF), (uint8_t)(reg & 0xFF) }; uint8_t buffer[9]; - i2c_write_blocking(i2c, address, regbuf, 2, true); + i2c->write_blocking(address, regbuf, 2, true); sleep_ms(delay_ms); - i2c_read_blocking(i2c, address, buffer, 9, false); + i2c->read_blocking(address, buffer, 9, false); if(buffer[2] != calculate_crc(buffer[0], buffer[1])) { return false; } diff --git a/drivers/sgp30/sgp30.hpp b/drivers/sgp30/sgp30.hpp index 07c14add..c027de5d 100644 --- a/drivers/sgp30/sgp30.hpp +++ b/drivers/sgp30/sgp30.hpp @@ -2,6 +2,8 @@ #include "hardware/i2c.h" #include "hardware/gpio.h" +#include "common/pimoroni_common.hpp" +#include "common/pimoroni_i2c.hpp" // commands and constants #define SGP30_REQ_FEATURES 0x0020 // The required feature set @@ -16,8 +18,6 @@ namespace pimoroni { //-------------------------------------------------- public: static const uint8_t DEFAULT_I2C_ADDRESS = 0x58; - static const uint8_t DEFAULT_SDA_PIN = 20; - static const uint8_t DEFAULT_SCL_PIN = 21; private: /***** Private constants here *****/ @@ -37,22 +37,21 @@ namespace pimoroni { // Variables //-------------------------------------------------- private: - i2c_inst_t *i2c = i2c0; + I2C *i2c; - int8_t address = DEFAULT_I2C_ADDRESS; - int8_t sda = DEFAULT_SDA_PIN; - int8_t scl = DEFAULT_SCL_PIN; + const int8_t address = DEFAULT_I2C_ADDRESS; //-------------------------------------------------- // Constructors/Destructor //-------------------------------------------------- public: - SGP30() {} + SGP30() : SGP30(new I2C()) {}; - SGP30(i2c_inst_t *i2c, uint8_t sda, uint8_t scl) : - i2c(i2c), sda(sda), scl(scl) {} + SGP30(I2C *i2c) : i2c(i2c) {} + // TODO remove MicroPython-binding compatibility constructors + SGP30(i2c_inst_t *i2c_inst, uint sda, uint scl) : i2c(new I2C(sda, scl)) { } //-------------------------------------------------- // Methods diff --git a/drivers/st7735/st7735.hpp b/drivers/st7735/st7735.hpp index a5214ec7..6b912eed 100644 --- a/drivers/st7735/st7735.hpp +++ b/drivers/st7735/st7735.hpp @@ -2,6 +2,7 @@ #include "hardware/spi.h" #include "hardware/gpio.h" +#include "../../common/pimoroni_common.hpp" namespace pimoroni { @@ -20,17 +21,6 @@ namespace pimoroni { static const uint8_t ROWS = 162; static const uint8_t COLS = 132; - - //-------------------------------------------------- - // Enums - //-------------------------------------------------- - public: - enum BG_SPI_SLOT { - BG_SPI_FRONT, - BG_SPI_BACK - }; - - //-------------------------------------------------- // Variables //-------------------------------------------------- diff --git a/drivers/st7789/st7789.cpp b/drivers/st7789/st7789.cpp index 9729e53a..af73df5d 100644 --- a/drivers/st7789/st7789.cpp +++ b/drivers/st7789/st7789.cpp @@ -67,13 +67,13 @@ namespace pimoroni { gpio_set_function(sck, GPIO_FUNC_SPI); gpio_set_function(mosi, GPIO_FUNC_SPI); - if(miso != -1) { + if(miso != PIN_UNUSED) { gpio_set_function(miso, GPIO_FUNC_SPI); } // if supported by the display then the vsync pin is // toggled high during vertical blanking period - if(vsync != -1) { + if(vsync != PIN_UNUSED) { gpio_set_function(vsync, GPIO_FUNC_SIO); gpio_set_dir(vsync, GPIO_IN); gpio_set_pulls(vsync, false, true); @@ -81,7 +81,7 @@ namespace pimoroni { // if a backlight pin is provided then set it up for // pwm control - if(bl != -1) { + if(bl != PIN_UNUSED) { pwm_config cfg = pwm_get_default_config(); pwm_set_wrap(pwm_gpio_to_slice_num(bl), 65535); pwm_init(pwm_gpio_to_slice_num(bl), &cfg, true); @@ -180,23 +180,23 @@ namespace pimoroni { return spi; } - int ST7789::get_cs() const { + uint ST7789::get_cs() const { return cs; } - int ST7789::get_dc() const { + uint ST7789::get_dc() const { return dc; } - int ST7789::get_sck() const { + uint ST7789::get_sck() const { return sck; } - int ST7789::get_mosi() const { + uint ST7789::get_mosi() const { return mosi; } - int ST7789::get_bl() const { + uint ST7789::get_bl() const { return bl; } diff --git a/drivers/st7789/st7789.hpp b/drivers/st7789/st7789.hpp index 8407f575..12019bd5 100644 --- a/drivers/st7789/st7789.hpp +++ b/drivers/st7789/st7789.hpp @@ -2,29 +2,12 @@ #include "hardware/spi.h" #include "hardware/gpio.h" +#include "../../common/pimoroni_common.hpp" namespace pimoroni { class ST7789 { - //-------------------------------------------------- - // Constants - //-------------------------------------------------- - public: - static const uint8_t DEFAULT_CS_PIN = 17; - static const uint8_t DEFAULT_DC_PIN = 16; - static const uint8_t DEFAULT_SCK_PIN = 18; - static const uint8_t DEFAULT_MOSI_PIN = 19; - static const uint8_t DEFAULT_BL_PIN = 20; - - - //-------------------------------------------------- - // Enums - //-------------------------------------------------- - public: - enum BG_SPI_SLOT { - BG_SPI_FRONT, - BG_SPI_BACK - }; + spi_inst_t *spi = PIMORONI_SPI_DEFAULT_INSTANCE; //-------------------------------------------------- @@ -35,42 +18,33 @@ namespace pimoroni { uint16_t width; uint16_t height; uint16_t row_stride; + uint32_t dma_channel; + + // interface pins with our standard defaults where appropriate + uint cs = SPI_BG_FRONT_CS; + uint dc = SPI_DEFAULT_MISO; + uint sck = SPI_DEFAULT_SCK; + uint mosi = SPI_DEFAULT_MOSI; + uint miso = PIN_UNUSED; // used as data/command + uint bl = SPI_BG_FRONT_PWM; + uint vsync = PIN_UNUSED; // only available on some products + + uint32_t spi_baud = 16 * 1000 * 1000; public: // frame buffer where pixel data is stored uint16_t *frame_buffer; - private: - spi_inst_t *spi = spi0; - - uint32_t dma_channel; - - // interface pins with our standard defaults where appropriate - int8_t cs = DEFAULT_CS_PIN; - int8_t dc = DEFAULT_DC_PIN; - int8_t sck = DEFAULT_SCK_PIN; - int8_t mosi = DEFAULT_MOSI_PIN; - int8_t miso = -1; // we generally don't use this pin - int8_t bl = DEFAULT_BL_PIN; - int8_t vsync = -1; // only available on some products - - uint32_t spi_baud = 16 * 1000 * 1000; - - - //-------------------------------------------------- - // Constructors/Destructor - //-------------------------------------------------- - public: ST7789(uint16_t width, uint16_t height, uint16_t *frame_buffer, BG_SPI_SLOT slot) : width(width), height(height), frame_buffer(frame_buffer) { switch(slot) { case BG_SPI_FRONT: - cs = 17; - bl = 20; + cs = SPI_BG_FRONT_CS; + bl = SPI_BG_FRONT_PWM; break; case BG_SPI_BACK: - cs = 22; - bl = 21; + cs = SPI_BG_BACK_CS; + bl = SPI_BG_BACK_PWM; break; } } @@ -80,9 +54,10 @@ namespace pimoroni { ST7789(uint16_t width, uint16_t height, uint16_t *frame_buffer, spi_inst_t *spi, - uint8_t cs, uint8_t dc, uint8_t sck, uint8_t mosi, uint8_t miso = -1, uint8_t bl = -1) : - width(width), height(height), frame_buffer(frame_buffer), - spi(spi), cs(cs), dc(dc), sck(sck), mosi(mosi), miso(miso), bl(bl) {} + uint cs, uint dc, uint sck, uint mosi, uint miso = PIN_UNUSED, uint bl = PIN_UNUSED) : + spi(spi), + width(width), height(height), + cs(cs), dc(dc), sck(sck), mosi(mosi), miso(miso), bl(bl), frame_buffer(frame_buffer) {} //-------------------------------------------------- @@ -92,11 +67,11 @@ namespace pimoroni { void init(bool auto_init_sequence = true, bool round = false); spi_inst_t* get_spi() const; - int get_cs() const; - int get_dc() const; - int get_sck() const; - int get_mosi() const; - int get_bl() const; + uint get_cs() const; + uint get_dc() const; + uint get_sck() const; + uint get_mosi() const; + uint get_bl() const; void command(uint8_t command, size_t len = 0, const char *data = NULL); void vsync_callback(gpio_irq_callback_t callback); diff --git a/drivers/trackball/trackball.cmake b/drivers/trackball/trackball.cmake index 97e54570..d5e13c89 100644 --- a/drivers/trackball/trackball.cmake +++ b/drivers/trackball/trackball.cmake @@ -7,4 +7,4 @@ target_sources(${DRIVER_NAME} INTERFACE target_include_directories(${DRIVER_NAME} INTERFACE ${CMAKE_CURRENT_LIST_DIR}) # Pull in pico libraries that we need -target_link_libraries(${DRIVER_NAME} INTERFACE pico_stdlib hardware_i2c) +target_link_libraries(${DRIVER_NAME} INTERFACE pico_stdlib hardware_i2c pimoroni_i2c) diff --git a/drivers/trackball/trackball.cpp b/drivers/trackball/trackball.cpp index d806456f..7551c3a6 100644 --- a/drivers/trackball/trackball.cpp +++ b/drivers/trackball/trackball.cpp @@ -42,12 +42,9 @@ namespace pimoroni { bool Trackball::init() { bool succeeded = false; - i2c_init(i2c, 100000); - - gpio_set_function(sda, GPIO_FUNC_I2C); - gpio_pull_up(sda); - gpio_set_function(scl, GPIO_FUNC_I2C); - gpio_pull_up(scl); + if(i2c->get_baudrate() > 100000) { + return false; + } if(interrupt != PIN_UNUSED) { gpio_set_function(interrupt, GPIO_FUNC_SIO); @@ -55,7 +52,7 @@ namespace pimoroni { gpio_pull_up(interrupt); } - uint16_t chip_id = ((uint16_t)i2c_reg_read_uint8(reg::CHIP_ID_H) << 8) | (uint16_t)i2c_reg_read_uint8(reg::CHIP_ID_L); + uint16_t chip_id = ((uint16_t)i2c->reg_read_uint8(address, reg::CHIP_ID_H) << 8) | (uint16_t)i2c->reg_read_uint8(address, reg::CHIP_ID_L); if(chip_id == CHIP_ID) { enable_interrupt(); succeeded = true; @@ -65,7 +62,7 @@ namespace pimoroni { } i2c_inst_t* Trackball::get_i2c() const { - return i2c; + return i2c->get_i2c(); } int Trackball::get_address() const { @@ -73,11 +70,11 @@ namespace pimoroni { } int Trackball::get_sda() const { - return sda; + return i2c->get_sda(); } int Trackball::get_scl() const { - return scl; + return i2c->get_scl(); } int Trackball::get_int() const { @@ -85,17 +82,17 @@ namespace pimoroni { } void Trackball::change_address(uint8_t new_address) { - i2c_reg_write_uint8(reg::I2C_ADDR, new_address); + i2c->reg_write_uint8(address, reg::I2C_ADDR, new_address); wait_for_flash(); } void Trackball::enable_interrupt(bool use_interrupt) { - uint8_t value = i2c_reg_read_uint8(reg::INT); + uint8_t value = i2c->reg_read_uint8(address, reg::INT); value &= ~MSK_INT_OUT_EN; if(use_interrupt) value |= MSK_INT_OUT_EN; - i2c_reg_write_uint8(reg::INT, value); + i2c->reg_write_uint8(address, reg::INT, value); } bool Trackball::get_interrupt() { @@ -105,61 +102,49 @@ namespace pimoroni { value = !gpio_get(interrupt); } else { - value = i2c_reg_read_uint8(reg::INT); + value = i2c->reg_read_uint8(address, reg::INT); value &= MSK_INT_TRIGGERED; } return false; } void Trackball::set_rgbw(uint8_t r, uint8_t g, uint8_t b, uint8_t w) { - i2c_reg_write_uint8(reg::LED_RED, r); - i2c_reg_write_uint8(reg::LED_GRN, g); - i2c_reg_write_uint8(reg::LED_BLU, b); - i2c_reg_write_uint8(reg::LED_WHT, w); + i2c->reg_write_uint8(address, reg::LED_RED, r); + i2c->reg_write_uint8(address, reg::LED_GRN, g); + i2c->reg_write_uint8(address, reg::LED_BLU, b); + i2c->reg_write_uint8(address, reg::LED_WHT, w); } void Trackball::set_red(uint8_t value) { - i2c_reg_write_uint8(reg::LED_RED, value); + i2c->reg_write_uint8(address, reg::LED_RED, value); } void Trackball::set_green(uint8_t value) { - i2c_reg_write_uint8(reg::LED_GRN, value); + i2c->reg_write_uint8(address, reg::LED_GRN, value); } void Trackball::set_blue(uint8_t value) { - i2c_reg_write_uint8(reg::LED_BLU, value); + i2c->reg_write_uint8(address, reg::LED_BLU, value); } void Trackball::set_white(uint8_t value) { - i2c_reg_write_uint8(reg::LED_WHT, value); + i2c->reg_write_uint8(address, reg::LED_WHT, value); } Trackball::State Trackball::read() { State state; uint8_t sw_state; - state.left = i2c_reg_read_uint8(reg::LEFT); - state.right = i2c_reg_read_uint8(reg::RIGHT); - state.up = i2c_reg_read_uint8(reg::UP); - state.down = i2c_reg_read_uint8(reg::DOWN); - sw_state = i2c_reg_read_uint8(reg::SWITCH); + state.left = i2c->reg_read_uint8(address, reg::LEFT); + state.right = i2c->reg_read_uint8(address, reg::RIGHT); + state.up = i2c->reg_read_uint8(address, reg::UP); + state.down = i2c->reg_read_uint8(address, reg::DOWN); + sw_state = i2c->reg_read_uint8(address, reg::SWITCH); state.sw_changed = sw_state & ~MSK_SWITCH_STATE; state.sw_pressed = (sw_state & MSK_SWITCH_STATE) > 0; return state; } - uint8_t Trackball::i2c_reg_read_uint8(uint8_t reg) { - uint8_t value; - i2c_write_blocking(i2c, address, ®, 1, true); - i2c_read_blocking(i2c, address, (uint8_t *)&value, 1, false); - return value; - } - - void Trackball::i2c_reg_write_uint8(uint8_t reg, uint8_t value) { - uint8_t buffer[2] = {reg, value}; - i2c_write_blocking(i2c, address, buffer, 2, false); - } - void Trackball::wait_for_flash(void) { unsigned long start_time = millis(); while(get_interrupt()) { diff --git a/drivers/trackball/trackball.hpp b/drivers/trackball/trackball.hpp index 4e82e1c8..d5d6f039 100644 --- a/drivers/trackball/trackball.hpp +++ b/drivers/trackball/trackball.hpp @@ -2,6 +2,7 @@ #include "hardware/i2c.h" #include "hardware/gpio.h" +#include "common/pimoroni_i2c.hpp" namespace pimoroni { @@ -12,11 +13,7 @@ namespace pimoroni { public: static const uint8_t DEFAULT_I2C_ADDRESS = 0x0A; static const uint8_t I2C_ADDRESS_ALTERNATIVE = 0x0B; - static const uint8_t DEFAULT_SDA_PIN = 20; - static const uint8_t DEFAULT_SCL_PIN = 21; - static const uint8_t DEFAULT_INT_PIN = 22; static const uint32_t DEFAULT_TIMEOUT = 5; - static const uint8_t PIN_UNUSED = UINT8_MAX; private: static const uint16_t CHIP_ID = 0xBA11; @@ -41,13 +38,9 @@ namespace pimoroni { // Variables //-------------------------------------------------- private: - i2c_inst_t *i2c = i2c0; - - // interface pins with our standard defaults where appropriate + I2C *i2c; int8_t address = DEFAULT_I2C_ADDRESS; - int8_t sda = DEFAULT_SDA_PIN; - int8_t scl = DEFAULT_SCL_PIN; - int8_t interrupt = DEFAULT_INT_PIN; + uint interrupt = PIN_UNUSED; uint32_t timeout = DEFAULT_TIMEOUT; @@ -55,14 +48,12 @@ namespace pimoroni { // Constructors/Destructor //-------------------------------------------------- public: - Trackball() {}; + Trackball(uint8_t address = DEFAULT_I2C_ADDRESS) : i2c(new I2C()), address(address) {}; - Trackball(uint8_t address) : - address(address) {} - - Trackball(i2c_inst_t *i2c, uint8_t address, uint8_t sda, uint8_t scl, uint8_t interrupt = PIN_UNUSED, uint32_t timeout = DEFAULT_TIMEOUT) : - i2c(i2c), address(address), sda(sda), scl(scl), interrupt(interrupt), timeout(timeout) {} + Trackball(I2C *i2c, uint8_t address = DEFAULT_I2C_ADDRESS, uint interrupt = PIN_UNUSED, uint32_t timeout = DEFAULT_TIMEOUT) : i2c(i2c), address(address), interrupt(interrupt) {} + // TODO remove MicroPython-binding compatibility constructors + Trackball(i2c_inst_t *i2c_inst, uint8_t address, uint sda, uint scl, uint interrupt = PIN_UNUSED, uint32_t timeout = DEFAULT_TIMEOUT) : Trackball(new I2C(sda, scl), address, interrupt) {} //-------------------------------------------------- // Methods @@ -88,9 +79,6 @@ namespace pimoroni { State read(); private: - uint8_t i2c_reg_read_uint8(uint8_t reg); - void i2c_reg_write_uint8(uint8_t reg, uint8_t value); - void wait_for_flash(); uint32_t millis(); diff --git a/drivers/vl53l1x/CMakeLists.txt b/drivers/vl53l1x/CMakeLists.txt index 7d5060ad..eff5eb25 100644 --- a/drivers/vl53l1x/CMakeLists.txt +++ b/drivers/vl53l1x/CMakeLists.txt @@ -7,4 +7,4 @@ target_sources(vl53l1x INTERFACE target_include_directories(vl53l1x INTERFACE ${CMAKE_CURRENT_LIST_DIR}) # Pull in pico libraries that we need -target_link_libraries(vl53l1x INTERFACE pico_stdlib hardware_i2c) +target_link_libraries(vl53l1x INTERFACE pico_stdlib hardware_i2c pimoroni_i2c) diff --git a/drivers/vl53l1x/vl53l1x.cpp b/drivers/vl53l1x/vl53l1x.cpp index a38c4833..059b406c 100644 --- a/drivers/vl53l1x/vl53l1x.cpp +++ b/drivers/vl53l1x/vl53l1x.cpp @@ -37,12 +37,6 @@ namespace pimoroni { saved_vhv_timeout = 0; // distance_mode = 1; - // Initialise I2C connection - i2c_init(i2c, 400000); - - gpio_set_function(sda, GPIO_FUNC_I2C); gpio_pull_up(sda); - gpio_set_function(scl, GPIO_FUNC_I2C); gpio_pull_up(scl); - last_status = 0; // check model ID and module type registers (values specified in datasheet) @@ -168,61 +162,62 @@ namespace pimoroni { // Write an 8-bit register void VL53L1X::writeReg(uint16_t reg, uint8_t value) { - uint8_t buffer[3] = {(reg >> 8) & 0xFF, reg & 0xFF, value}; - i2c_write_blocking(i2c, address, buffer, 3, false); + alignas(2) struct u16_u32_buffer { + uint16_t reg; + uint8_t value; + } buffer{reg, value}; + i2c->write_blocking(address, (uint8_t *)&buffer, 3, false); } // Write a 16-bit register void VL53L1X::writeReg16Bit(uint16_t reg, uint16_t value) { - uint8_t buffer[4] = {(reg >> 8) & 0xFF, reg & 0xFF, (value >> 8) & 0xFF, value & 0xFF}; - i2c_write_blocking(i2c, address, buffer, 4, false); + uint16_t buffer[2] = {reg, value}; + i2c->write_blocking(address, (uint8_t *)buffer, 4, false); } // Write a 32-bit register void VL53L1X::writeReg32Bit(uint16_t reg, uint32_t value) { - uint8_t buffer[6] = {(reg >> 8) & 0xFF, reg & 0xFF, - (value >> 24) & 0xFF, (value >> 16) & 0xFF, (value >> 8) & 0xFF, value & 0xFF}; - i2c_write_blocking(i2c, address, buffer, 6, false); + alignas(2) struct u16_u32_buffer { + uint16_t reg; + uint32_t value; + } buffer{reg, value}; + i2c->write_blocking(address, (uint8_t *)&buffer, 6, false); } // Read an 8-bit register uint8_t VL53L1X::readReg(regAddr reg) { - uint8_t regbuf[2] = {((uint8_t)reg >> 8) & 0xFF, (uint8_t)reg & 0xFF}; - uint8_t buffer[1]; uint8_t value; - i2c_write_blocking(i2c, address, regbuf, 2, true); - i2c_read_blocking(i2c, address, buffer, 1, false); - value = buffer[0]; + // TODO do we need to bswap reg? + i2c->write_blocking(address, (uint8_t *)®, 2, true); + i2c->read_blocking(address, &value, 1, false); return value; } // Read a 16-bit register uint16_t VL53L1X::readReg16Bit(uint16_t reg) { - uint8_t regbuf[2] = {(reg >> 8) & 0xFF, reg & 0xFF}; - uint8_t buffer[2]; uint16_t value; - reg= (reg << 8) + (reg >> 8); - i2c_write_blocking(i2c, address, regbuf, 2, true); - i2c_read_blocking(i2c, address, buffer, 2, false); - value= (buffer[0] << 8) + buffer[1]; - return value; + // TODO do we need to bswap reg? + i2c->write_blocking(address, (uint8_t *)®, 2, true); + i2c->read_blocking(address, (uint8_t *)&value, 2, false); + + // TODO do we need to bswap this return value? + return __bswap16(value); } // Read a 32-bit register uint32_t VL53L1X::readReg32Bit(uint16_t reg) { - uint8_t regbuf[2] = {(reg >> 8) & 0xFF, reg & 0xFF}; - uint8_t buffer[4]; uint32_t value; reg= (reg << 8) + (reg >> 8); - i2c_write_blocking(i2c, address, regbuf, 2, true); - i2c_read_blocking(i2c, address, buffer, 4, false); - value= (buffer[0] << 24) + (buffer[1] << 16) + (buffer[2] << 8) + buffer[3]; - return value; + i2c->write_blocking(address, (uint8_t *)®, 2, true); + i2c->read_blocking(address, (uint8_t *)&value, 4, false); + + // TODO do we need to bswap this return value? + return __bswap32(value); } // set distance mode to Short, Medium, or Long @@ -578,10 +573,10 @@ namespace pimoroni { void VL53L1X::readResults() { uint16_t reg = RESULT__RANGE_STATUS; - uint8_t regbuf[2] = {(reg >> 8) & 0xFF, reg & 0xFF}; + // TODO do we need to bswap reg? uint8_t buffer[17]; - i2c_write_blocking(i2c, address, regbuf, 2, true); - i2c_read_blocking(i2c, address, buffer, 17, false); + i2c->write_blocking(address, (uint8_t *)®, 2, true); + i2c->read_blocking(address, buffer, 17, false); results.range_status = buffer[0]; diff --git a/drivers/vl53l1x/vl53l1x.hpp b/drivers/vl53l1x/vl53l1x.hpp index 85231667..d108bb0c 100644 --- a/drivers/vl53l1x/vl53l1x.hpp +++ b/drivers/vl53l1x/vl53l1x.hpp @@ -15,17 +15,17 @@ Distributed as-is; no warranty is given. #include #include "pico/stdlib.h" +#include "common/pimoroni_i2c.hpp" namespace pimoroni { class VL53L1X { + static const uint8_t DEFAULT_I2C_ADDRESS = 0x29; - i2c_inst_t *i2c = i2c0; + I2C *i2c; - int8_t address = 0x29; - int8_t sda = 20; - int8_t scl = 21; - int8_t interrupt = 22; + int8_t address = DEFAULT_I2C_ADDRESS; + uint interrupt = 22; // register addresses from API vl53l1x_register_map.h enum regAddr : uint16_t @@ -1291,7 +1291,10 @@ namespace pimoroni { uint8_t last_status; // status of last I2C transmission public: - VL53L1X() {} + VL53L1X() : VL53L1X(DEFAULT_I2C_ADDRESS) {}; + VL53L1X(uint8_t address) : i2c(new I2C()), address(address) {}; + VL53L1X(i2c_inst_t *i2c_inst, uint8_t address, uint sda, uint scl, uint interrupt = PIN_UNUSED) : i2c(new I2C()), address(address), interrupt(interrupt) {} + VL53L1X(I2C *i2c, uint8_t address = DEFAULT_I2C_ADDRESS, uint interrupt = PIN_UNUSED) : i2c(i2c), address(address), interrupt(interrupt) {} uint16_t getid(); uint16_t getosc(); diff --git a/examples/breakout_as7262/basic_demo.cpp b/examples/breakout_as7262/basic_demo.cpp index 14287634..9e777ce4 100644 --- a/examples/breakout_as7262/basic_demo.cpp +++ b/examples/breakout_as7262/basic_demo.cpp @@ -1,10 +1,12 @@ #include "pico/stdlib.h" +#include "common/pimoroni_common.hpp" #include "breakout_as7262.hpp" using namespace pimoroni; -BreakoutAS7262 as7262; +I2C i2c(BOARD::BREAKOUT_GARDEN); +BreakoutAS7262 as7262(&i2c); int main() { stdio_init_all(); diff --git a/examples/breakout_as7262/explorer_bargraph.cpp b/examples/breakout_as7262/explorer_bargraph.cpp index 0df4063b..189f624f 100644 --- a/examples/breakout_as7262/explorer_bargraph.cpp +++ b/examples/breakout_as7262/explorer_bargraph.cpp @@ -1,4 +1,5 @@ #include "pico/stdlib.h" +#include "common/pimoroni_common.hpp" #include "breakout_as7262.hpp" #include "pico_explorer.hpp" @@ -7,7 +8,8 @@ using namespace pimoroni; constexpr float INTEGRATION_TIME = 10.0f; -BreakoutAS7262 as7262; +I2C i2c(BOARD::PICO_EXPLORER); +BreakoutAS7262 as7262(&i2c); uint16_t buffer[PicoExplorer::WIDTH * PicoExplorer::HEIGHT]; PicoExplorer pico_explorer(buffer); diff --git a/examples/breakout_dotmatrix/bargraph/bargraph.cpp b/examples/breakout_dotmatrix/bargraph/bargraph.cpp index a9c2783c..819e3564 100644 --- a/examples/breakout_dotmatrix/bargraph/bargraph.cpp +++ b/examples/breakout_dotmatrix/bargraph/bargraph.cpp @@ -5,7 +5,8 @@ using namespace pimoroni; -BreakoutDotMatrix display; +I2C i2c(BOARD::BREAKOUT_GARDEN); +BreakoutDotMatrix display(&i2c); static const uint8_t WIDTH = display.WIDTH; static const uint8_t HEIGHT = display.HEIGHT; static const uint8_t HALF_WIDTH = (WIDTH / 2); diff --git a/examples/breakout_dotmatrix/eyes/eyes.cpp b/examples/breakout_dotmatrix/eyes/eyes.cpp index f685ec75..05bf455d 100644 --- a/examples/breakout_dotmatrix/eyes/eyes.cpp +++ b/examples/breakout_dotmatrix/eyes/eyes.cpp @@ -5,7 +5,8 @@ using namespace pimoroni; -BreakoutDotMatrix display; +I2C i2c(BOARD::BREAKOUT_GARDEN); +BreakoutDotMatrix display(&i2c); bool led_toggle = false; void eye(uint8_t x, uint8_t y) { diff --git a/examples/breakout_dotmatrix/image/image.cpp b/examples/breakout_dotmatrix/image/image.cpp index cc6ceecd..ed678cd8 100644 --- a/examples/breakout_dotmatrix/image/image.cpp +++ b/examples/breakout_dotmatrix/image/image.cpp @@ -4,7 +4,8 @@ using namespace pimoroni; -BreakoutDotMatrix display; +I2C i2c(BOARD::BREAKOUT_GARDEN); +BreakoutDotMatrix display(&i2c); bool led_toggle = false; // Left Image Padding Right Image Padding diff --git a/examples/breakout_dotmatrix/timer/timer.cpp b/examples/breakout_dotmatrix/timer/timer.cpp index ffd8976b..eb865de3 100644 --- a/examples/breakout_dotmatrix/timer/timer.cpp +++ b/examples/breakout_dotmatrix/timer/timer.cpp @@ -6,7 +6,8 @@ using namespace pimoroni; -BreakoutDotMatrix display(BreakoutDotMatrix::DEFAULT_I2C_ADDRESS); +I2C i2c(BOARD::BREAKOUT_GARDEN); +BreakoutDotMatrix display(&i2c); bool led_toggle = false; int main() { diff --git a/examples/breakout_encoder/demo.cpp b/examples/breakout_encoder/demo.cpp index ae57882f..aeb627d7 100644 --- a/examples/breakout_encoder/demo.cpp +++ b/examples/breakout_encoder/demo.cpp @@ -1,6 +1,7 @@ #include "pico/stdlib.h" #include #include +#include "common/pimoroni_common.hpp" #include "breakout_encoder.hpp" @@ -8,7 +9,8 @@ using namespace pimoroni; static const uint8_t STEPS_PER_REV = 24; -BreakoutEncoder enc; +I2C i2c(BOARD::BREAKOUT_GARDEN); +BreakoutEncoder enc(&i2c); bool toggle = false; // HSV Conversion expects float inputs in the range of 0.00-1.00 for each channel @@ -34,7 +36,7 @@ void from_hsv(float h, float s, float v, uint8_t &r, uint8_t &g, uint8_t &b) { void count_changed(int16_t count) { printf("Count: %d\n", count); float h = (count % STEPS_PER_REV) / (float)STEPS_PER_REV; - uint8_t r, g, b; + uint8_t r = 0, g = 0, b = 0; from_hsv(h, 1.0f, 1.0f, r, g, b); enc.set_led(r, g, b); } diff --git a/examples/breakout_ltr559/demo.cpp b/examples/breakout_ltr559/demo.cpp index 5eeb9e8a..276f6690 100644 --- a/examples/breakout_ltr559/demo.cpp +++ b/examples/breakout_ltr559/demo.cpp @@ -5,7 +5,8 @@ using namespace pimoroni; -BreakoutLTR559 ltr559; +I2C i2c(BOARD::BREAKOUT_GARDEN); +BreakoutLTR559 ltr559(&i2c); int main() { stdio_init_all(); @@ -13,7 +14,13 @@ int main() { ltr559.init(); uint8_t part_id = ltr559.part_id(); - printf("Found LTR559. Part ID: 0x%02x\n", part_id); + if(part_id == LTR559_VALID_PART_ID) { + printf("Found LTR559. Part ID: 0x%02x\n", part_id); + } + else + { + printf("Could not find LTR559. Got Part ID: 0x%02x, expected 0x%02x\n", part_id, LTR559_VALID_PART_ID); + } while(true){ bool new_data = ltr559.get_reading(); diff --git a/examples/breakout_matrix11x7/demo.cpp b/examples/breakout_matrix11x7/demo.cpp index ee203063..80449bf2 100644 --- a/examples/breakout_matrix11x7/demo.cpp +++ b/examples/breakout_matrix11x7/demo.cpp @@ -4,7 +4,8 @@ using namespace pimoroni; -BreakoutMatrix11x7 matrix11x7(0x75); +I2C i2c(BOARD::BREAKOUT_GARDEN); +BreakoutMatrix11x7 matrix11x7(&i2c, 0x75); int main() { gpio_init(PICO_DEFAULT_LED_PIN); diff --git a/examples/breakout_msa301/demo.cpp b/examples/breakout_msa301/demo.cpp index 5af8cf24..4c14f798 100644 --- a/examples/breakout_msa301/demo.cpp +++ b/examples/breakout_msa301/demo.cpp @@ -1,11 +1,13 @@ #include #include "pico/stdlib.h" +#include "common/pimoroni_common.hpp" #include "breakout_msa301.hpp" using namespace pimoroni; -BreakoutMSA301 msa301; +I2C i2c(BOARD::BREAKOUT_GARDEN); +BreakoutMSA301 msa301(&i2c); int main() { stdio_init_all(); diff --git a/examples/breakout_potentiometer/demo.cpp b/examples/breakout_potentiometer/demo.cpp index 2892f314..8de69c65 100644 --- a/examples/breakout_potentiometer/demo.cpp +++ b/examples/breakout_potentiometer/demo.cpp @@ -1,12 +1,14 @@ #include "pico/stdlib.h" #include #include +#include "common/pimoroni_common.hpp" #include "breakout_potentiometer.hpp" using namespace pimoroni; -BreakoutPotentiometer pot; +I2C i2c(BOARD::BREAKOUT_GARDEN); +BreakoutPotentiometer pot(&i2c); bool toggle = false; // HSV Conversion expects float inputs in the range of 0.00-1.00 for each channel @@ -35,7 +37,6 @@ int main() { stdio_init_all(); - int16_t count = 0; if(pot.init()) { printf("Potentiometer found...\n"); @@ -48,7 +49,7 @@ int main() { float percent = pot.read(); printf("Percent: %d\n", (int)(percent * 100)); - uint8_t r, g, b; + uint8_t r = 0, g = 0, b = 0; from_hsv(percent, 1.0f, 1.0f, r, g, b); pot.set_led(r, g, b); diff --git a/examples/breakout_rgbmatrix5x5/demo.cpp b/examples/breakout_rgbmatrix5x5/demo.cpp index 0981b67f..47c4e2e8 100644 --- a/examples/breakout_rgbmatrix5x5/demo.cpp +++ b/examples/breakout_rgbmatrix5x5/demo.cpp @@ -7,7 +7,8 @@ using namespace pimoroni; -BreakoutRGBMatrix5x5 rgbmatrix5x5; +I2C i2c(BOARD::BREAKOUT_GARDEN); +BreakoutRGBMatrix5x5 rgbmatrix5x5(&i2c); int main() { rgbmatrix5x5.init(); diff --git a/examples/breakout_roundlcd/demo.cpp b/examples/breakout_roundlcd/demo.cpp index 51fe8f1d..b4bc995f 100644 --- a/examples/breakout_roundlcd/demo.cpp +++ b/examples/breakout_roundlcd/demo.cpp @@ -12,12 +12,12 @@ using namespace pimoroni; uint16_t buffer[BreakoutRoundLCD::WIDTH * BreakoutRoundLCD::HEIGHT]; -BreakoutRoundLCD display(buffer, ST7789::BG_SPI_FRONT); +BreakoutRoundLCD display(buffer, BG_SPI_FRONT); constexpr float RADIUS = BreakoutRoundLCD::WIDTH / 2; Pen from_hsv(float h, float s, float v) { - uint8_t r, g, b; + uint8_t r = 0, g = 0, b = 0; float i = floor(h * 6.0f); float f = h * 6.0f - i; diff --git a/examples/breakout_rtc/CMakeLists.txt b/examples/breakout_rtc/CMakeLists.txt index 70c13b2e..4ec2b29a 100644 --- a/examples/breakout_rtc/CMakeLists.txt +++ b/examples/breakout_rtc/CMakeLists.txt @@ -7,7 +7,7 @@ add_executable( # enable usb output, disable uart output pico_enable_stdio_usb(${OUTPUT_NAME} 1) -pico_enable_stdio_uart(${OUTPUT_NAME} 0) +pico_enable_stdio_uart(${OUTPUT_NAME} 1) # Pull in pico libraries that we need target_link_libraries(${OUTPUT_NAME} pico_stdlib breakout_rtc) diff --git a/examples/breakout_rtc/demo.cpp b/examples/breakout_rtc/demo.cpp index f8d8c178..c0c3669d 100644 --- a/examples/breakout_rtc/demo.cpp +++ b/examples/breakout_rtc/demo.cpp @@ -4,7 +4,8 @@ using namespace pimoroni; -BreakoutRTC rtc; +I2C i2c(BOARD::BREAKOUT_GARDEN); +BreakoutRTC rtc(&i2c); int main() { stdio_init_all(); @@ -15,10 +16,10 @@ int main() { if(!rtc.init()) { printf("Init failed! Check your connections and i2c pin choices.\n"); } - // rtc.setup(false); + //rtc.setup(false); // Uncomment the below line on first run to set the RTC date and time to the program's compiler time - // rtc.set_to_compiler_time(); + //rtc.set_to_compiler_time(); // Make sure we have 24-hour time if(rtc.is_12_hour()) diff --git a/examples/breakout_sgp30/demo.cpp b/examples/breakout_sgp30/demo.cpp index 834daa1e..c743712e 100644 --- a/examples/breakout_sgp30/demo.cpp +++ b/examples/breakout_sgp30/demo.cpp @@ -13,13 +13,13 @@ using namespace pimoroni; -BreakoutSGP30 sgp30; +I2C i2c(BOARD::BREAKOUT_GARDEN); +BreakoutSGP30 sgp30(&i2c); int main() { uint8_t prd; uint16_t eCO2, TVOC; - uint16_t raweCO2, rawTVOC; - uint16_t baseCO2, baseTVOC; + uint16_t rawCO2, rawTVOC; gpio_init(PICO_DEFAULT_LED_PIN); gpio_set_dir(PICO_DEFAULT_LED_PIN, GPIO_OUT); @@ -56,8 +56,8 @@ int main() { sleep_ms(1000 - (100 * prd)); if(prd == 1) { sgp30.get_air_quality(&eCO2, &TVOC); - sgp30.get_air_quality_raw(&raweCO2, &rawTVOC); - printf("%3d: CO2 %d TVOC %d, raw %d %d\n", j, eCO2, TVOC, raweCO2, rawTVOC); + sgp30.get_air_quality_raw(&rawCO2, &rawTVOC); + printf("%3d: CO2 %d TVOC %d, raw %d %d\n", j, eCO2, TVOC, rawCO2, rawTVOC); if(j == 30) { printf("Resetting device\n"); sgp30.soft_reset(); diff --git a/examples/breakout_trackball/demo.cpp b/examples/breakout_trackball/demo.cpp index 2a1f7ed7..2d08f62d 100644 --- a/examples/breakout_trackball/demo.cpp +++ b/examples/breakout_trackball/demo.cpp @@ -7,11 +7,19 @@ using namespace pimoroni; static const uint8_t SENSITIVITY = 2; - -BreakoutTrackball trackball; +// Trackball requires I2C at 100kHz or less. +I2C i2c(BOARD::BREAKOUT_GARDEN, 100000); +BreakoutTrackball trackball(&i2c); int main() { - trackball.init(); + stdio_init_all(); + + if(!trackball.init()) { + printf("Trackball failed to init!\n"); + return 1; + } + + printf("Roll the Trackball to change colour!\n"); trackball.set_rgbw(0, 0, 0, 64); diff --git a/examples/pico_display/demo.cpp b/examples/pico_display/demo.cpp index a29d9711..24d859ea 100644 --- a/examples/pico_display/demo.cpp +++ b/examples/pico_display/demo.cpp @@ -82,11 +82,6 @@ int main() { // uint16_t dark_green = pico_display.create_pen(10, 100, 10); // uint16_t blue = pico_display.create_pen(0, 0, 255); - bool a_pressed = false; - bool b_pressed = false; - bool x_pressed = false; - bool y_pressed = false; - struct pt { float x; float y; diff --git a/examples/pico_explorer/demo.cpp b/examples/pico_explorer/demo.cpp index ffa89b4c..6e7cbbf7 100644 --- a/examples/pico_explorer/demo.cpp +++ b/examples/pico_explorer/demo.cpp @@ -58,11 +58,6 @@ int main() { pico_explorer.init(); msa301.init(); - bool a_pressed = false; - bool b_pressed = false; - bool x_pressed = false; - bool y_pressed = false; - struct pt { float x; float y; @@ -160,7 +155,7 @@ int main() { float yoff = cos(i / 20.0f) * 50.0f; yoff += 120 - (68 / 2); for(int y = 0; y < 68; y++) { - uint16_t *dest = pico_explorer.frame_buffer + (y * 240); + // uint16_t *dest = pico_explorer.frame_buffer + (y * 240); uint8_t *src = _binary_fox_tga_start + 18 + (y * 81 * 3); for(int x = 0; x < 81; x++) { uint8_t b = *src++; diff --git a/examples/pico_pot_explorer/demo.cpp b/examples/pico_pot_explorer/demo.cpp index 14752a3c..d5eed107 100644 --- a/examples/pico_pot_explorer/demo.cpp +++ b/examples/pico_pot_explorer/demo.cpp @@ -44,7 +44,6 @@ int main() { pico_explorer.init(); pico_explorer.update(); - int16_t count = 0; if(pot.init()) { printf("Potentiometer found...\n"); @@ -55,7 +54,7 @@ int main() { float percent = pot.read(); printf("Percent: %d\n", (int)(percent * 100)); - uint8_t r, g, b; + uint8_t r = 0, g = 0, b = 0; from_hsv(percent, 1.0f, 1.0f, r, g, b); pot.set_led(r, g, b); diff --git a/examples/pico_tof_display/demo.cpp b/examples/pico_tof_display/demo.cpp index 1404f385..cd750d81 100644 --- a/examples/pico_tof_display/demo.cpp +++ b/examples/pico_tof_display/demo.cpp @@ -170,7 +170,7 @@ int main() { bool dist_held = false; while(true) { - bool a_pressed = ar_button_a.next(i, pico_display.is_pressed(pico_display.A)); + // bool a_pressed = ar_button_a.next(i, pico_display.is_pressed(pico_display.A)); bool b_pressed = ar_button_b.next(i, pico_display.is_pressed(pico_display.B)); bool x_pressed = ar_button_x.next(i, pico_display.is_pressed(pico_display.X)); bool y_pressed = ar_button_y.next(i, pico_display.is_pressed(pico_display.Y)); diff --git a/examples/pico_unicorn/demo.cpp b/examples/pico_unicorn/demo.cpp index 51d253e6..53757347 100644 --- a/examples/pico_unicorn/demo.cpp +++ b/examples/pico_unicorn/demo.cpp @@ -40,11 +40,6 @@ int main() { uint32_t i = 0; while(true) { i = i + 1; - uint8_t j = 0; - - - - if(pico_unicorn.is_pressed(pico_unicorn.A)) { a_pressed = true; } if(pico_unicorn.is_pressed(pico_unicorn.B)) { b_pressed = true; } diff --git a/examples/pico_unicorn_plasma/demo.cpp b/examples/pico_unicorn_plasma/demo.cpp index 9992497d..c45435af 100644 --- a/examples/pico_unicorn_plasma/demo.cpp +++ b/examples/pico_unicorn_plasma/demo.cpp @@ -102,8 +102,9 @@ int main() { while(true) { int x1, x2, x3, x4, y1, y2, y3, y4, sx1, sx2, sx3, sx4; unsigned char x, y; - int8_t value; - uint8_t r, g, b,j,k,l,m; + int8_t value; + uint8_t r = 0, g = 0, b = 0; + uint8_t j, k, l, m; // Setup a delay to slow the framerate. // Would be better to read from a timer as some math operations take variable time diff --git a/examples/pico_wireless/demo.cpp b/examples/pico_wireless/demo.cpp index f220b5ab..c13417c3 100644 --- a/examples/pico_wireless/demo.cpp +++ b/examples/pico_wireless/demo.cpp @@ -66,7 +66,7 @@ int main() { sleep_ms(1000); - uint8_t r, g, b; + uint8_t r = 0, g = 0, b = 0; uint8_t a = 0; while(!wireless.is_pressed(PicoWireless::A)) { from_hsv((float)a/256.0f, 1, 1, r, g, b); @@ -79,15 +79,15 @@ int main() { printf("firmware version Nina %s\n", wireless.get_fw_version()); uint8_t* mac = wireless.get_mac_address(); - printf("mac address ", wireless.get_mac_address()[0]); - for(uint i =0; i < WL_MAC_ADDR_LENGTH; i++) { + printf("mac address "); + for(uint i = 0; i < WL_MAC_ADDR_LENGTH; i++) { printf("%d:", mac[i]); } printf("\n"); printf("starting connection\n"); - bool connected = wireless.wifi_set_passphrase(NETWORK, PASSWORD); + wireless.wifi_set_passphrase(NETWORK, PASSWORD); printf("waiting to establish connection status\n"); while(wireless.get_connection_status() != WL_CONNECTED) { @@ -103,8 +103,8 @@ int main() { wireless.get_gateway_ip(gateway); printf("gateway address: %d.%d.%d.%d\n", gateway[0], gateway[1], gateway[2], gateway[3]); - printf("SSID = %s\n", wireless.get_current_ssid()); - printf("RSSI = %d\n", wireless.get_current_rssi()); + printf("SSID = %s\n", wireless.get_current_ssid().c_str()); + printf("RSSI = %ld\n", wireless.get_current_rssi()); uint8_t t = 0; while (true) { diff --git a/examples/pico_wireless/rgb_http.cpp b/examples/pico_wireless/rgb_http.cpp index 23454b59..39cf30e0 100644 --- a/examples/pico_wireless/rgb_http.cpp +++ b/examples/pico_wireless/rgb_http.cpp @@ -79,7 +79,7 @@ int socket_accept(int8_t server_sock) { } uint8_t start_server(uint16_t http_port) { - printf("Starting server...\n", NETWORK); + printf("Starting server...\n"); // Get a socket for our server uint8_t server_sock = wireless.get_socket(); wireless.start_server(http_port, server_sock); diff --git a/examples/pico_wireless/sdcard_http.cpp b/examples/pico_wireless/sdcard_http.cpp index 42eece66..8054e8c8 100644 --- a/examples/pico_wireless/sdcard_http.cpp +++ b/examples/pico_wireless/sdcard_http.cpp @@ -103,7 +103,7 @@ bool has_suffix(std::string_view path, std::string_view suffix) { } uint8_t start_server(uint16_t http_port) { - printf("Starting server...\n", NETWORK); + printf("Starting server...\n"); // Get a socket for our server uint8_t server_sock = wireless.get_socket(); wireless.start_server(http_port, server_sock); @@ -237,7 +237,7 @@ int main() { printf("Listing /\n"); f_opendir(dir, "/"); while(f_readdir(dir, &file) == FR_OK && file.fname[0]) { - printf("%s %d\n", file.fname, file.fsize); + printf("%s %lld\n", file.fname, file.fsize); } f_closedir(dir); diff --git a/libraries/breakout_colourlcd160x80/breakout_colourlcd160x80.cpp b/libraries/breakout_colourlcd160x80/breakout_colourlcd160x80.cpp index f6469902..bfa71ff4 100644 --- a/libraries/breakout_colourlcd160x80/breakout_colourlcd160x80.cpp +++ b/libraries/breakout_colourlcd160x80/breakout_colourlcd160x80.cpp @@ -8,12 +8,12 @@ namespace pimoroni { } BreakoutColourLCD160x80::BreakoutColourLCD160x80(uint16_t *buf, spi_inst_t *spi, - uint8_t cs, uint8_t dc, uint8_t sck, uint8_t mosi, uint8_t miso, uint8_t bl) + uint cs, uint dc, uint sck, uint mosi, uint miso, uint bl) : PicoGraphics(WIDTH, HEIGHT, buf), screen(WIDTH, HEIGHT, buf, spi, cs, dc, sck, mosi, miso, bl) { __fb = buf; } - BreakoutColourLCD160x80::BreakoutColourLCD160x80(uint16_t *buf, ST7735::BG_SPI_SLOT slot) + BreakoutColourLCD160x80::BreakoutColourLCD160x80(uint16_t *buf, BG_SPI_SLOT slot) : PicoGraphics(WIDTH, HEIGHT, buf), screen(WIDTH, HEIGHT, buf, slot) { __fb = buf; } diff --git a/libraries/breakout_colourlcd160x80/breakout_colourlcd160x80.hpp b/libraries/breakout_colourlcd160x80/breakout_colourlcd160x80.hpp index 7e628be7..8db78425 100644 --- a/libraries/breakout_colourlcd160x80/breakout_colourlcd160x80.hpp +++ b/libraries/breakout_colourlcd160x80/breakout_colourlcd160x80.hpp @@ -2,6 +2,7 @@ #include "drivers/st7735/st7735.hpp" #include "libraries/pico_graphics/pico_graphics.hpp" +#include "common/pimoroni_common.hpp" namespace pimoroni { @@ -12,8 +13,6 @@ namespace pimoroni { public: static const int WIDTH = 160; static const int HEIGHT = 80; - static const uint8_t PIN_UNUSED = UINT8_MAX; - //-------------------------------------------------- // Variables @@ -30,8 +29,8 @@ namespace pimoroni { public: BreakoutColourLCD160x80(uint16_t *buf); BreakoutColourLCD160x80(uint16_t *buf, spi_inst_t *spi, - uint8_t cs, uint8_t dc, uint8_t sck, uint8_t mosi, uint8_t miso = PIN_UNUSED, uint8_t bl = PIN_UNUSED); - BreakoutColourLCD160x80(uint16_t *buf, ST7735::BG_SPI_SLOT slot); + uint cs, uint dc, uint sck, uint mosi, uint miso = PIN_UNUSED, uint bl = PIN_UNUSED); + BreakoutColourLCD160x80(uint16_t *buf, BG_SPI_SLOT slot); //-------------------------------------------------- diff --git a/libraries/breakout_colourlcd240x240/breakout_colourlcd240x240.cpp b/libraries/breakout_colourlcd240x240/breakout_colourlcd240x240.cpp index 3cf1cad6..6be2a581 100644 --- a/libraries/breakout_colourlcd240x240/breakout_colourlcd240x240.cpp +++ b/libraries/breakout_colourlcd240x240/breakout_colourlcd240x240.cpp @@ -8,12 +8,12 @@ namespace pimoroni { } BreakoutColourLCD240x240::BreakoutColourLCD240x240(uint16_t *buf, spi_inst_t *spi, - uint8_t cs, uint8_t dc, uint8_t sck, uint8_t mosi, uint8_t miso, uint8_t bl) + uint cs, uint dc, uint sck, uint mosi, uint miso, uint bl) : PicoGraphics(WIDTH, HEIGHT, buf), screen(WIDTH, HEIGHT, buf, spi, cs, dc, sck, mosi, miso, bl) { __fb = buf; } - BreakoutColourLCD240x240::BreakoutColourLCD240x240(uint16_t *buf, ST7789::BG_SPI_SLOT slot) + BreakoutColourLCD240x240::BreakoutColourLCD240x240(uint16_t *buf, BG_SPI_SLOT slot) : PicoGraphics(WIDTH, HEIGHT, buf), screen(WIDTH, HEIGHT, buf, slot) { __fb = buf; } diff --git a/libraries/breakout_colourlcd240x240/breakout_colourlcd240x240.hpp b/libraries/breakout_colourlcd240x240/breakout_colourlcd240x240.hpp index 470b8d70..2b63e586 100644 --- a/libraries/breakout_colourlcd240x240/breakout_colourlcd240x240.hpp +++ b/libraries/breakout_colourlcd240x240/breakout_colourlcd240x240.hpp @@ -2,6 +2,7 @@ #include "drivers/st7789/st7789.hpp" #include "libraries/pico_graphics/pico_graphics.hpp" +#include "common/pimoroni_common.hpp" namespace pimoroni { @@ -12,8 +13,6 @@ namespace pimoroni { public: static const int WIDTH = 240; static const int HEIGHT = 240; - static const uint8_t PIN_UNUSED = UINT8_MAX; - //-------------------------------------------------- // Variables @@ -30,8 +29,8 @@ namespace pimoroni { public: BreakoutColourLCD240x240(uint16_t *buf); BreakoutColourLCD240x240(uint16_t *buf, spi_inst_t *spi, - uint8_t cs, uint8_t dc, uint8_t sck, uint8_t mosi, uint8_t miso = PIN_UNUSED, uint8_t bl = PIN_UNUSED); - BreakoutColourLCD240x240(uint16_t *buf, ST7789::BG_SPI_SLOT slot); + uint cs, uint dc, uint sck, uint mosi, uint miso = PIN_UNUSED, uint bl = PIN_UNUSED); + BreakoutColourLCD240x240(uint16_t *buf, BG_SPI_SLOT slot); //-------------------------------------------------- diff --git a/libraries/breakout_encoder/breakout_encoder.hpp b/libraries/breakout_encoder/breakout_encoder.hpp index c1980f1b..6eeae4f3 100644 --- a/libraries/breakout_encoder/breakout_encoder.hpp +++ b/libraries/breakout_encoder/breakout_encoder.hpp @@ -1,6 +1,7 @@ #pragma once #include "drivers/ioexpander/ioexpander.hpp" +#include "common/pimoroni_common.hpp" namespace pimoroni { @@ -46,22 +47,20 @@ namespace pimoroni { IOExpander ioe; Direction direction = DEFAULT_DIRECTION; float brightness = DEFAULT_BRIGHTNESS; - uint8_t interrupt_pin = PIN_UNUSED; // A local copy of the value passed to the IOExpander, used in initialisation + uint interrupt_pin = PIN_UNUSED; // A local copy of the value passed to the IOExpander, used in initialisation //-------------------------------------------------- // Constructors/Destructor //-------------------------------------------------- public: - BreakoutEncoder() : - ioe(DEFAULT_I2C_ADDRESS) {} + BreakoutEncoder(uint8_t address = DEFAULT_I2C_ADDRESS) : BreakoutEncoder(new I2C(), address) {}; - BreakoutEncoder(uint8_t address) : - ioe(address) {} + BreakoutEncoder(I2C *i2c, uint8_t address = DEFAULT_I2C_ADDRESS, uint interrupt = PIN_UNUSED, uint32_t timeout = DEFAULT_TIMEOUT, bool debug = false) : + ioe(i2c, address, interrupt, timeout, debug) {} - BreakoutEncoder(i2c_inst_t *i2c, uint8_t address, uint8_t sda, uint8_t scl, uint8_t interrupt = PIN_UNUSED, uint32_t timeout = DEFAULT_TIMEOUT) : - ioe(i2c, address, sda, scl, interrupt, timeout), - interrupt_pin(interrupt) {} + // TODO remove MicroPython-binding compatibility constructors + BreakoutEncoder(uint8_t address, uint sda, uint scl, uint interrupt = PIN_UNUSED, uint32_t timeout = DEFAULT_TIMEOUT) : BreakoutEncoder(new I2C(sda, scl), address, interrupt, timeout) {}; //-------------------------------------------------- diff --git a/libraries/breakout_ltr559/breakout_ltr559.cmake b/libraries/breakout_ltr559/breakout_ltr559.cmake index b21335f9..a79c2830 100644 --- a/libraries/breakout_ltr559/breakout_ltr559.cmake +++ b/libraries/breakout_ltr559/breakout_ltr559.cmake @@ -8,4 +8,4 @@ target_sources(${LIB_NAME} INTERFACE target_include_directories(${LIB_NAME} INTERFACE ${CMAKE_CURRENT_LIST_DIR}) # Pull in pico libraries that we need -target_link_libraries(${LIB_NAME} INTERFACE pico_stdlib ltr559) +target_link_libraries(${LIB_NAME} INTERFACE pico_stdlib ltr559 pimoroni_i2c) diff --git a/libraries/breakout_matrix11x7/breakout_matrix11x7.hpp b/libraries/breakout_matrix11x7/breakout_matrix11x7.hpp index cef3d646..75650ef4 100644 --- a/libraries/breakout_matrix11x7/breakout_matrix11x7.hpp +++ b/libraries/breakout_matrix11x7/breakout_matrix11x7.hpp @@ -12,9 +12,13 @@ namespace pimoroni { bool init(); - BreakoutMatrix11x7() : IS31FL3731(DEFAULT_I2C_ADDRESS) {}; - BreakoutMatrix11x7(uint8_t address) : IS31FL3731(address) {}; - BreakoutMatrix11x7(i2c_inst_t *i2c, uint8_t address, uint8_t sda, uint8_t scl) : IS31FL3731(i2c, address, sda, scl) {}; + BreakoutMatrix11x7() : IS31FL3731(new I2C(I2C_BG_SDA, I2C_BG_SCL), DEFAULT_I2C_ADDRESS) {} + + BreakoutMatrix11x7(uint8_t address) : IS31FL3731(new I2C(I2C_DEFAULT_SDA, I2C_DEFAULT_SCL), address) {} + + BreakoutMatrix11x7(I2C *i2c, uint8_t address = DEFAULT_I2C_ADDRESS) : IS31FL3731(i2c, address) {} + + BreakoutMatrix11x7(i2c_inst_t *i2c_inst, uint8_t address, uint8_t sda, uint8_t scl) : IS31FL3731(i2c_inst, address, sda, scl) {} void set_pixel(uint8_t x, uint8_t y, uint8_t c); diff --git a/libraries/breakout_mics6814/breakout_mics6814.hpp b/libraries/breakout_mics6814/breakout_mics6814.hpp index eee7f2dd..2b03a7de 100644 --- a/libraries/breakout_mics6814/breakout_mics6814.hpp +++ b/libraries/breakout_mics6814/breakout_mics6814.hpp @@ -11,7 +11,6 @@ namespace pimoroni { public: static const uint8_t DEFAULT_I2C_ADDRESS = 0x19; static constexpr float DEFAULT_BRIGHTNESS = 1.0f; //Effectively the maximum fraction of the period that the LED will be on - static const uint8_t PIN_UNUSED = UINT8_MAX; static const uint32_t DEFAULT_TIMEOUT = 1; static const uint32_t DEFAULT_ADC_TIMEOUT = 1; @@ -53,15 +52,13 @@ namespace pimoroni { // Constructors/Destructor //-------------------------------------------------- public: - BreakoutMICS6814() : - ioe(DEFAULT_I2C_ADDRESS) {} + BreakoutMICS6814(uint8_t address = DEFAULT_I2C_ADDRESS) : BreakoutMICS6814(new I2C(), address) {}; - BreakoutMICS6814(uint8_t address) : - ioe(address) {} - - BreakoutMICS6814(i2c_inst_t *i2c, uint8_t address, uint8_t sda, uint8_t scl, uint8_t interrupt = PIN_UNUSED, uint32_t timeout = DEFAULT_TIMEOUT) : - ioe(i2c, address, sda, scl, interrupt, timeout) {} + BreakoutMICS6814(I2C *i2c, uint8_t address = DEFAULT_I2C_ADDRESS, uint interrupt = PIN_UNUSED, uint32_t timeout = DEFAULT_TIMEOUT, bool debug = false) : + ioe(i2c, address, interrupt, timeout, debug) {} + // TODO remove MicroPython-binding compatibility constructors + BreakoutMICS6814(uint8_t address, uint sda, uint scl, uint interrupt = PIN_UNUSED, uint32_t timeout = DEFAULT_TIMEOUT) : BreakoutMICS6814(new I2C(sda, scl), address, interrupt, timeout) {}; //-------------------------------------------------- // Methods diff --git a/libraries/breakout_msa301/breakout_msa301.cmake b/libraries/breakout_msa301/breakout_msa301.cmake index 15f3acec..f7f24a6d 100644 --- a/libraries/breakout_msa301/breakout_msa301.cmake +++ b/libraries/breakout_msa301/breakout_msa301.cmake @@ -8,4 +8,4 @@ target_sources(${LIB_NAME} INTERFACE target_include_directories(${LIB_NAME} INTERFACE ${CMAKE_CURRENT_LIST_DIR}) # Pull in pico libraries that we need -target_link_libraries(${LIB_NAME} INTERFACE pico_stdlib msa301) +target_link_libraries(${LIB_NAME} INTERFACE pico_stdlib msa301 pimoroni_i2c) diff --git a/libraries/breakout_potentiometer/breakout_potentiometer.hpp b/libraries/breakout_potentiometer/breakout_potentiometer.hpp index 470b3316..7d149ceb 100644 --- a/libraries/breakout_potentiometer/breakout_potentiometer.hpp +++ b/libraries/breakout_potentiometer/breakout_potentiometer.hpp @@ -22,7 +22,6 @@ namespace pimoroni { static const uint8_t DEFAULT_I2C_ADDRESS = 0x0E; static constexpr float DEFAULT_BRIGHTNESS = 1.0f; //Effectively the maximum fraction of the period that the LED will be on static const Direction DEFAULT_DIRECTION = DIRECTION_CW; - static const uint8_t PIN_UNUSED = UINT8_MAX; static const uint32_t DEFAULT_TIMEOUT = 1; static const uint32_t DEFAULT_ADC_TIMEOUT = 1; @@ -51,14 +50,13 @@ namespace pimoroni { // Constructors/Destructor //-------------------------------------------------- public: - BreakoutPotentiometer() : - ioe(DEFAULT_I2C_ADDRESS) {} + BreakoutPotentiometer(uint8_t address = DEFAULT_I2C_ADDRESS) : BreakoutPotentiometer(new I2C(), address) {}; - BreakoutPotentiometer(uint8_t address) : - ioe(address) {} + BreakoutPotentiometer(I2C *i2c, uint8_t address = DEFAULT_I2C_ADDRESS, uint interrupt = PIN_UNUSED, uint32_t timeout = DEFAULT_TIMEOUT, bool debug = false) : + ioe(i2c, address, interrupt, timeout, debug) {} - BreakoutPotentiometer(i2c_inst_t *i2c, uint8_t address, uint8_t sda, uint8_t scl, uint8_t interrupt = PIN_UNUSED, uint32_t timeout = DEFAULT_TIMEOUT) : - ioe(i2c, address, sda, scl, interrupt, timeout) {} + // TODO remove MicroPython-binding compatibility constructors + BreakoutPotentiometer(uint8_t address, uint sda, uint scl, uint interrupt = PIN_UNUSED, uint32_t timeout = DEFAULT_TIMEOUT) : BreakoutPotentiometer(new I2C(sda, scl), address, interrupt, timeout) {}; //-------------------------------------------------- diff --git a/libraries/breakout_rgbmatrix5x5/breakout_rgbmatrix5x5.hpp b/libraries/breakout_rgbmatrix5x5/breakout_rgbmatrix5x5.hpp index e9b1e3be..f7e7f816 100644 --- a/libraries/breakout_rgbmatrix5x5/breakout_rgbmatrix5x5.hpp +++ b/libraries/breakout_rgbmatrix5x5/breakout_rgbmatrix5x5.hpp @@ -18,10 +18,14 @@ namespace pimoroni { bool init(); void set_pixel(uint8_t x, uint8_t y, uint8_t r, uint8_t g, uint8_t b); - - BreakoutRGBMatrix5x5() : IS31FL3731(DEFAULT_I2C_ADDRESS) {}; - BreakoutRGBMatrix5x5(uint8_t address) : IS31FL3731(address) {}; - BreakoutRGBMatrix5x5(i2c_inst_t *i2c, uint8_t address, uint8_t sda, uint8_t scl) : IS31FL3731(i2c, address, sda, scl) {}; + + BreakoutRGBMatrix5x5() : IS31FL3731(new I2C(I2C_BG_SDA, I2C_BG_SCL), DEFAULT_I2C_ADDRESS) {} + + BreakoutRGBMatrix5x5(uint8_t address) : IS31FL3731(new I2C(I2C_DEFAULT_SDA, I2C_DEFAULT_SCL), address) {} + + BreakoutRGBMatrix5x5(I2C *i2c, uint8_t address = DEFAULT_I2C_ADDRESS) : IS31FL3731(i2c, address) {} + + BreakoutRGBMatrix5x5(i2c_inst_t *i2c_inst, uint8_t address, uint8_t sda, uint8_t scl) : IS31FL3731(i2c_inst, address, sda, scl) {} private: RGBLookup lookup_pixel(uint8_t index); diff --git a/libraries/breakout_roundlcd/breakout_roundlcd.cpp b/libraries/breakout_roundlcd/breakout_roundlcd.cpp index 2e27134d..49a639da 100644 --- a/libraries/breakout_roundlcd/breakout_roundlcd.cpp +++ b/libraries/breakout_roundlcd/breakout_roundlcd.cpp @@ -8,13 +8,12 @@ namespace pimoroni { } BreakoutRoundLCD::BreakoutRoundLCD(uint16_t *buf, spi_inst_t *spi, - uint8_t cs, uint8_t dc, uint8_t sck, uint8_t mosi, uint8_t miso, uint8_t bl) + uint cs, uint dc, uint sck, uint mosi, uint miso, uint bl) : PicoGraphics(WIDTH, HEIGHT, buf), screen(WIDTH, HEIGHT, buf, spi, cs, dc, sck, mosi, miso, bl) { __fb = buf; } - BreakoutRoundLCD::BreakoutRoundLCD(uint16_t *buf, ST7789::BG_SPI_SLOT slot) - : PicoGraphics(WIDTH, HEIGHT, buf), screen(WIDTH, HEIGHT, buf, slot) { + BreakoutRoundLCD::BreakoutRoundLCD(uint16_t *buf, BG_SPI_SLOT slot) : PicoGraphics(WIDTH, HEIGHT, buf), screen(WIDTH, HEIGHT, buf, slot) { __fb = buf; } diff --git a/libraries/breakout_roundlcd/breakout_roundlcd.hpp b/libraries/breakout_roundlcd/breakout_roundlcd.hpp index 9d0c07e0..24c82ed6 100644 --- a/libraries/breakout_roundlcd/breakout_roundlcd.hpp +++ b/libraries/breakout_roundlcd/breakout_roundlcd.hpp @@ -31,8 +31,8 @@ namespace pimoroni { public: BreakoutRoundLCD(uint16_t *buf); BreakoutRoundLCD(uint16_t *buf, spi_inst_t *spi, - uint8_t cs, uint8_t dc, uint8_t sck, uint8_t mosi, uint8_t miso = PIN_UNUSED, uint8_t bl = PIN_UNUSED); - BreakoutRoundLCD(uint16_t *buf, ST7789::BG_SPI_SLOT slot); + uint cs, uint dc, uint sck, uint mosi, uint miso = PIN_UNUSED, uint bl = PIN_UNUSED); + BreakoutRoundLCD(uint16_t *buf, BG_SPI_SLOT slot); //-------------------------------------------------- diff --git a/libraries/breakout_sgp30/breakout_sgp30.cmake b/libraries/breakout_sgp30/breakout_sgp30.cmake index 4f13e5f2..874689d9 100644 --- a/libraries/breakout_sgp30/breakout_sgp30.cmake +++ b/libraries/breakout_sgp30/breakout_sgp30.cmake @@ -8,4 +8,4 @@ target_sources(${LIB_NAME} INTERFACE target_include_directories(${LIB_NAME} INTERFACE ${CMAKE_CURRENT_LIST_DIR}) # Pull in pico libraries that we need -target_link_libraries(${LIB_NAME} INTERFACE pico_stdlib hardware_i2c sgp30) +target_link_libraries(${LIB_NAME} INTERFACE pico_stdlib hardware_i2c sgp30 pimoroni_i2c) diff --git a/libraries/pico_explorer/pico_explorer.cpp b/libraries/pico_explorer/pico_explorer.cpp index 0d160686..5c416a25 100644 --- a/libraries/pico_explorer/pico_explorer.cpp +++ b/libraries/pico_explorer/pico_explorer.cpp @@ -95,7 +95,7 @@ namespace pimoroni { } } - void PicoExplorer::set_audio_pin(uint8_t pin) { + void PicoExplorer::set_audio_pin(uint pin) { pwm_config tone_pwm_cfg = pwm_get_default_config(); // calculate the pwm wrap value for this frequency diff --git a/libraries/pico_explorer/pico_explorer.hpp b/libraries/pico_explorer/pico_explorer.hpp index 0cee484c..3c5217ee 100644 --- a/libraries/pico_explorer/pico_explorer.hpp +++ b/libraries/pico_explorer/pico_explorer.hpp @@ -9,10 +9,10 @@ namespace pimoroni { public: static const int WIDTH = 240; static const int HEIGHT = 240; - static const uint8_t A = 12; - static const uint8_t B = 13; - static const uint8_t X = 14; - static const uint8_t Y = 15; + static const uint A = 12; + static const uint B = 13; + static const uint X = 14; + static const uint Y = 15; static const uint8_t ADC0 = 0; static const uint8_t ADC1 = 1; @@ -25,14 +25,14 @@ namespace pimoroni { static const uint8_t REVERSE = 1; static const uint8_t STOP = 2; - static const uint8_t GP0 = 0; - static const uint8_t GP1 = 1; - static const uint8_t GP2 = 2; - static const uint8_t GP3 = 3; - static const uint8_t GP4 = 4; - static const uint8_t GP5 = 5; - static const uint8_t GP6 = 6; - static const uint8_t GP7 = 7; + static const uint GP0 = 0; + static const uint GP1 = 1; + static const uint GP2 = 2; + static const uint GP3 = 3; + static const uint GP4 = 4; + static const uint GP5 = 5; + static const uint GP6 = 6; + static const uint GP7 = 7; uint16_t *__fb; private: @@ -50,7 +50,7 @@ namespace pimoroni { void set_motor(uint8_t channel, uint8_t action, float speed = 0.0f); - void set_audio_pin(uint8_t pin); + void set_audio_pin(uint pin); void set_tone(uint16_t frequency, float duty = 0.2f); }; diff --git a/micropython/examples/breakout_as7262/demo.py b/micropython/examples/breakout_as7262/demo.py index f6fdd8d7..da100888 100644 --- a/micropython/examples/breakout_as7262/demo.py +++ b/micropython/examples/breakout_as7262/demo.py @@ -1,7 +1,12 @@ import time +from pimoroni_i2c import PimoroniI2C from breakout_as7262 import BreakoutAS7262 -as7262 = BreakoutAS7262() +PINS_BREAKOUT_GARDEN = {"sda": 4, "scl": 5} +PINS_PICO_EXPLORER = {"sda": 20, "scl": 21} + +i2c = PimoroniI2C(**PINS_BREAKOUT_GARDEN) +as7262 = BreakoutAS7262(i2c) dev_type = as7262.device_type() hw_version = as7262.hardware_version() diff --git a/micropython/examples/breakout_as7262/pico_explorer_graph.py b/micropython/examples/breakout_as7262/pico_explorer_graph.py index 24f8e6f5..43246936 100644 --- a/micropython/examples/breakout_as7262/pico_explorer_graph.py +++ b/micropython/examples/breakout_as7262/pico_explorer_graph.py @@ -1,3 +1,4 @@ +from pimoroni_i2c import PimoroniI2C from breakout_as7262 import BreakoutAS7262 import picoexplorer as display import time @@ -11,7 +12,8 @@ bar_height = height display_buffer = bytearray(width * height * 2) # 2-bytes per pixel (RGB565) display.init(display_buffer) -as7 = BreakoutAS7262() +i2c = PimoroniI2C(20, 21) +as7 = BreakoutAS7262(i2c) integration_time = 10 # integration time in milliseconds, max ~90ms diff --git a/micropython/examples/breakout_dotmatrix/bargraph.py b/micropython/examples/breakout_dotmatrix/bargraph.py index 665e1a6f..e80f4aec 100644 --- a/micropython/examples/breakout_dotmatrix/bargraph.py +++ b/micropython/examples/breakout_dotmatrix/bargraph.py @@ -2,9 +2,14 @@ import time import math import random +from pimoroni_i2c import PimoroniI2C from breakout_dotmatrix import BreakoutDotMatrix -display = BreakoutDotMatrix() +PINS_BREAKOUT_GARDEN = {"sda": 4, "scl": 5} +PINS_PICO_EXPLORER = {"sda": 20, "scl": 21} + +i2c = PimoroniI2C(**PINS_BREAKOUT_GARDEN) +display = BreakoutDotMatrix(i2c) width = display.WIDTH height = display.HEIGHT diff --git a/micropython/examples/breakout_dotmatrix/eyes.py b/micropython/examples/breakout_dotmatrix/eyes.py index 7d0b0484..e625f1e4 100644 --- a/micropython/examples/breakout_dotmatrix/eyes.py +++ b/micropython/examples/breakout_dotmatrix/eyes.py @@ -1,10 +1,15 @@ -import math import time +import math import random +from pimoroni_i2c import PimoroniI2C from breakout_dotmatrix import BreakoutDotMatrix -display = BreakoutDotMatrix() +PINS_BREAKOUT_GARDEN = {"sda": 4, "scl": 5} +PINS_PICO_EXPLORER = {"sda": 20, "scl": 21} + +i2c = PimoroniI2C(**PINS_BREAKOUT_GARDEN) +display = BreakoutDotMatrix(i2c) start_time = time.time() diff --git a/micropython/examples/breakout_dotmatrix/image.py b/micropython/examples/breakout_dotmatrix/image.py index f1af07ae..31e7acfe 100644 --- a/micropython/examples/breakout_dotmatrix/image.py +++ b/micropython/examples/breakout_dotmatrix/image.py @@ -1,9 +1,14 @@ import time import math +from pimoroni_i2c import PimoroniI2C from breakout_dotmatrix import BreakoutDotMatrix -display = BreakoutDotMatrix() +PINS_BREAKOUT_GARDEN = {"sda": 4, "scl": 5} +PINS_PICO_EXPLORER = {"sda": 20, "scl": 21} + +i2c = PimoroniI2C(**PINS_BREAKOUT_GARDEN) +display = BreakoutDotMatrix(i2c) # Left Image Padding Right Image Padding image = [0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, diff --git a/micropython/examples/breakout_dotmatrix/timer.py b/micropython/examples/breakout_dotmatrix/timer.py index c32db6cf..d420f4ec 100644 --- a/micropython/examples/breakout_dotmatrix/timer.py +++ b/micropython/examples/breakout_dotmatrix/timer.py @@ -1,11 +1,16 @@ import time +from pimoroni_i2c import PimoroniI2C from breakout_dotmatrix import BreakoutDotMatrix +PINS_BREAKOUT_GARDEN = {"sda": 4, "scl": 5} +PINS_PICO_EXPLORER = {"sda": 20, "scl": 21} + address = 0x61 start_time = time.time() -display = BreakoutDotMatrix(address=address) +i2c = PimoroniI2C(**PINS_BREAKOUT_GARDEN) +display = BreakoutDotMatrix(i2c, address=address) display.clear() display.show() diff --git a/micropython/examples/breakout_encoder/demo.py b/micropython/examples/breakout_encoder/demo.py index c8337453..848e4192 100644 --- a/micropython/examples/breakout_encoder/demo.py +++ b/micropython/examples/breakout_encoder/demo.py @@ -1,8 +1,13 @@ +from pimoroni_i2c import PimoroniI2C from breakout_encoder import BreakoutEncoder +PINS_BREAKOUT_GARDEN = {"sda": 4, "scl": 5} +PINS_PICO_EXPLORER = {"sda": 20, "scl": 21} + steps_per_rev = 24 -enc = BreakoutEncoder() +i2c = PimoroniI2C(**PINS_BREAKOUT_GARDEN) +enc = BreakoutEncoder(i2c) enc.set_brightness(1.0) # enc.set_direction(BreakoutEncoder.DIRECTION_CCW) # Uncomment this to flip the direction diff --git a/micropython/examples/breakout_ioexpander/adc.py b/micropython/examples/breakout_ioexpander/adc.py index 290a83ba..f66a9274 100644 --- a/micropython/examples/breakout_ioexpander/adc.py +++ b/micropython/examples/breakout_ioexpander/adc.py @@ -1,9 +1,14 @@ import time +from pimoroni_i2c import PimoroniI2C from breakout_ioexpander import BreakoutIOExpander +PINS_BREAKOUT_GARDEN = {"sda": 4, "scl": 5} +PINS_PICO_EXPLORER = {"sda": 20, "scl": 21} + ioe_adc_pin = 10 -ioe = BreakoutIOExpander(0x18) +i2c = PimoroniI2C(**PINS_BREAKOUT_GARDEN) +ioe = BreakoutIOExpander(i2c, address=0x18) ioe.set_mode(ioe_adc_pin, BreakoutIOExpander.PIN_ADC) diff --git a/micropython/examples/breakout_ioexpander/button.py b/micropython/examples/breakout_ioexpander/button.py index 624306a6..1955073b 100644 --- a/micropython/examples/breakout_ioexpander/button.py +++ b/micropython/examples/breakout_ioexpander/button.py @@ -1,9 +1,14 @@ import time +from pimoroni_i2c import PimoroniI2C from breakout_ioexpander import BreakoutIOExpander +PINS_BREAKOUT_GARDEN = {"sda": 4, "scl": 5} +PINS_PICO_EXPLORER = {"sda": 20, "scl": 21} + ioe_button_pin = 14 -ioe = BreakoutIOExpander(0x18) +i2c = PimoroniI2C(**PINS_BREAKOUT_GARDEN) +ioe = BreakoutIOExpander(i2c, address=0x18) ioe.set_mode(ioe_button_pin, BreakoutIOExpander.PIN_IN_PU) diff --git a/micropython/examples/breakout_ioexpander/servo.py b/micropython/examples/breakout_ioexpander/servo.py index 7ca012fc..622fe0ab 100644 --- a/micropython/examples/breakout_ioexpander/servo.py +++ b/micropython/examples/breakout_ioexpander/servo.py @@ -1,7 +1,11 @@ import time import math +from pimoroni_i2c import PimoroniI2C from breakout_ioexpander import BreakoutIOExpander +PINS_BREAKOUT_GARDEN = {"sda": 4, "scl": 5} +PINS_PICO_EXPLORER = {"sda": 20, "scl": 21} + ioe_servo_pin = 1 # Settings to produce a 50Hz output from the 24MHz clock. @@ -12,7 +16,8 @@ period = 60000 cycle_time = 5.0 servo_range = 1000.0 # Between 1000 and 2000us (1-2ms) -ioe = BreakoutIOExpander(0x18) +i2c = PimoroniI2C(**PINS_BREAKOUT_GARDEN) +ioe = BreakoutIOExpander(i2c, address=0x18) ioe.set_pwm_period(period) ioe.set_pwm_control(divider) diff --git a/micropython/examples/breakout_ltr559/demo.py b/micropython/examples/breakout_ltr559/demo.py index 7f79f67d..a027de45 100644 --- a/micropython/examples/breakout_ltr559/demo.py +++ b/micropython/examples/breakout_ltr559/demo.py @@ -1,7 +1,12 @@ import time +from pimoroni_i2c import PimoroniI2C from breakout_ltr559 import BreakoutLTR559 -ltr = BreakoutLTR559() +PINS_BREAKOUT_GARDEN = {"sda": 4, "scl": 5} +PINS_PICO_EXPLORER = {"sda": 20, "scl": 21} + +i2c = PimoroniI2C(**PINS_BREAKOUT_GARDEN) +ltr = BreakoutLTR559(i2c) part_id = ltr.part_id() print("Found LTR559. Part ID: 0x", '{:02x}'.format(part_id), sep="") diff --git a/micropython/examples/breakout_matrix11x7/demo.py b/micropython/examples/breakout_matrix11x7/demo.py index 47c83677..07554c51 100644 --- a/micropython/examples/breakout_matrix11x7/demo.py +++ b/micropython/examples/breakout_matrix11x7/demo.py @@ -1,9 +1,14 @@ import time +from pimoroni_i2c import PimoroniI2C from breakout_matrix11x7 import BreakoutMatrix11x7 on_brightness = 64 -matrix = BreakoutMatrix11x7() +PINS_BREAKOUT_GARDEN = {"sda": 4, "scl": 5} +PINS_PICO_EXPLORER = {"sda": 20, "scl": 21} + +i2c = PimoroniI2C(**PINS_BREAKOUT_GARDEN) +matrix = BreakoutMatrix11x7(i2c) x = 0 y = 0 diff --git a/micropython/examples/breakout_mics6814/demo.py b/micropython/examples/breakout_mics6814/demo.py index b8af41c6..cdd8c08a 100644 --- a/micropython/examples/breakout_mics6814/demo.py +++ b/micropython/examples/breakout_mics6814/demo.py @@ -1,9 +1,14 @@ import time +from pimoroni_i2c import PimoroniI2C from breakout_mics6814 import BreakoutMICS6814 OUTPUT_FREQUENCY = 0.5 -gas = BreakoutMICS6814() +PINS_BREAKOUT_GARDEN = {"sda": 4, "scl": 5} +PINS_PICO_EXPLORER = {"sda": 20, "scl": 21} + +i2c = PimoroniI2C(**PINS_BREAKOUT_GARDEN) +gas = BreakoutMICS6814(i2c) gas.set_brightness(1.0) diff --git a/micropython/examples/breakout_msa301/demo.py b/micropython/examples/breakout_msa301/demo.py index 703915a3..cb2c9792 100644 --- a/micropython/examples/breakout_msa301/demo.py +++ b/micropython/examples/breakout_msa301/demo.py @@ -1,7 +1,12 @@ import time +from pimoroni_i2c import PimoroniI2C from breakout_msa301 import BreakoutMSA301 -msa = BreakoutMSA301() +PINS_BREAKOUT_GARDEN = {"sda": 4, "scl": 5} +PINS_PICO_EXPLORER = {"sda": 20, "scl": 21} + +i2c = PimoroniI2C(**PINS_BREAKOUT_GARDEN) +msa = BreakoutMSA301(i2c) part_id = msa.part_id() print("Found MSA301. Part ID: 0x", '{:02x}'.format(part_id), sep="") diff --git a/micropython/examples/breakout_potentiometer/demo.py b/micropython/examples/breakout_potentiometer/demo.py index ec354b72..81cbfb2b 100644 --- a/micropython/examples/breakout_potentiometer/demo.py +++ b/micropython/examples/breakout_potentiometer/demo.py @@ -1,7 +1,12 @@ import time +from pimoroni_i2c import PimoroniI2C from breakout_potentiometer import BreakoutPotentiometer -pot = BreakoutPotentiometer() +PINS_BREAKOUT_GARDEN = {"sda": 4, "scl": 5} +PINS_PICO_EXPLORER = {"sda": 20, "scl": 21} + +i2c = PimoroniI2C(**PINS_BREAKOUT_GARDEN) +pot = BreakoutPotentiometer(i2c) pot.set_brightness(1.0) # pot.set_direction(BreakoutPotentiometer.DIRECTION_CCW) # Uncomment this to flip the direction diff --git a/micropython/examples/breakout_rgbmatrix5x5/demo.py b/micropython/examples/breakout_rgbmatrix5x5/demo.py index c5862842..5f486b79 100644 --- a/micropython/examples/breakout_rgbmatrix5x5/demo.py +++ b/micropython/examples/breakout_rgbmatrix5x5/demo.py @@ -1,14 +1,19 @@ import time +from pimoroni_i2c import PimoroniI2C from breakout_rgbmatrix5x5 import BreakoutRGBMatrix5x5 +PINS_BREAKOUT_GARDEN = {"sda": 4, "scl": 5} +PINS_PICO_EXPLORER = {"sda": 20, "scl": 21} + +i2c = PimoroniI2C(**PINS_BREAKOUT_GARDEN) +matrix = BreakoutRGBMatrix5x5(i2c) + colors = [] colors.append((255, 0, 0)) colors.append((0, 255, 0)) colors.append((0, 0, 255)) colors.append((128, 128, 128)) -matrix = BreakoutRGBMatrix5x5() - x = 0 y = 0 col = 0 diff --git a/micropython/examples/breakout_rtc/demo.py b/micropython/examples/breakout_rtc/demo.py index e0bf227d..cc24b6ca 100644 --- a/micropython/examples/breakout_rtc/demo.py +++ b/micropython/examples/breakout_rtc/demo.py @@ -1,6 +1,12 @@ +from pimoroni_i2c import PimoroniI2C from breakout_rtc import BreakoutRTC +import time -rtc = BreakoutRTC() +PINS_BREAKOUT_GARDEN = {"sda": 4, "scl": 5} # i2c pins 4, 5 for Breakout Garden +PINS_PICO_EXPLORER = {"sda": 20, "scl": 21} # Default i2c pins for Pico Explorer + +i2c = PimoroniI2C(**PINS_BREAKOUT_GARDEN) +rtc = BreakoutRTC(i2c) if rtc.is_12_hour(): rtc.set_24_hour() @@ -12,6 +18,8 @@ while True: rtc.clear_periodic_update_interrupt_flag() if rtc.update_time(): - date = rtc.string_date() - time = rtc.string_time() - print("Date: ", date, ", Time: ", time, sep="") + rtc_date = rtc.string_date() + rtc_time = rtc.string_time() + print("Date: ", rtc_date, ", Time: ", rtc_time, sep="") + + time.sleep(0.1) diff --git a/micropython/examples/breakout_sgp30/demo.py b/micropython/examples/breakout_sgp30/demo.py index cf5300e8..2a316bdb 100644 --- a/micropython/examples/breakout_sgp30/demo.py +++ b/micropython/examples/breakout_sgp30/demo.py @@ -1,7 +1,13 @@ import time +from pimoroni_i2c import PimoroniI2C from breakout_sgp30 import BreakoutSGP30 -sgp30 = BreakoutSGP30() +PINS_BREAKOUT_GARDEN = {"sda": 4, "scl": 5} # i2c pins 4, 5 for Breakout Garden +PINS_PICO_EXPLORER = {"sda": 20, "scl": 21} # Default i2c pins for Pico Explorer + +i2c = PimoroniI2C(**PINS_BREAKOUT_GARDEN) +sgp30 = BreakoutSGP30(i2c) + print("SGP30 initialised - about to start measuring without waiting") sgp30.start_measurement(False) diff --git a/micropython/examples/breakout_trackball/demo.py b/micropython/examples/breakout_trackball/demo.py index e846b6c6..5d726ee1 100644 --- a/micropython/examples/breakout_trackball/demo.py +++ b/micropython/examples/breakout_trackball/demo.py @@ -1,12 +1,19 @@ import time +from pimoroni_i2c import PimoroniI2C from breakout_trackball import BreakoutTrackball +PINS_BREAKOUT_GARDEN = {"sda": 4, "scl": 5, "baudrate": 100000} +PINS_PICO_EXPLORER = {"sda": 20, "scl": 21, "baudrate": 100000} + sensitivity = 2 -trackball = BreakoutTrackball() +i2c = PimoroniI2C(**PINS_BREAKOUT_GARDEN) +trackball = BreakoutTrackball(i2c) trackball.set_rgbw(0, 0, 0, 64) +print("Roll the trackball to change colour!") + while True: state = trackball.read() if state[BreakoutTrackball.SW_PRESSED]: diff --git a/micropython/modules/breakout_as7262/breakout_as7262.cpp b/micropython/modules/breakout_as7262/breakout_as7262.cpp index a0dd8621..7942a0b1 100644 --- a/micropython/modules/breakout_as7262/breakout_as7262.cpp +++ b/micropython/modules/breakout_as7262/breakout_as7262.cpp @@ -11,6 +11,13 @@ using namespace pimoroni; 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 { @@ -44,46 +51,31 @@ void BreakoutAS7262_print(const mp_print_t *print, mp_obj_t self_in, mp_print_ki mp_obj_t BreakoutAS7262_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *all_args) { breakout_as7262_BreakoutAS7262_obj_t *self = nullptr; - enum { ARG_i2c, ARG_sda, ARG_scl, ARG_int }; + enum { ARG_i2c, ARG_int }; static const mp_arg_t allowed_args[] = { - { MP_QSTR_i2c, MP_ARG_INT, {.u_int = -1} }, - { MP_QSTR_sda, MP_ARG_INT, {.u_int = 20} }, - { MP_QSTR_scl, MP_ARG_INT, {.u_int = 21} }, - { MP_QSTR_interrupt, MP_ARG_INT, {.u_int = BreakoutAS7262::PIN_UNUSED} }, + { MP_QSTR_i2c, MP_ARG_OBJ, {.u_obj = nullptr} }, + { MP_QSTR_interrupt, MP_ARG_INT, {.u_int = 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; - 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("BreakoutAS7262: 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_as7262_BreakoutAS7262_obj_t); self->base.type = &breakout_as7262_BreakoutAS7262_type; - i2c_inst_t *i2c = (i2c_id == 0) ? i2c0 : i2c1; - self->breakout = new BreakoutAS7262(i2c, sda, scl, args[ARG_int].u_int); + self->breakout = new BreakoutAS7262(i2c->i2c, args[ARG_int].u_int); if(!self->breakout->init()) { - mp_raise_msg(&mp_type_RuntimeError, "AS7262 breakout not found when initialising"); + mp_raise_msg(&mp_type_RuntimeError, "BreakoutAS7262: breakout not found when initialising"); } return MP_OBJ_FROM_PTR(self); diff --git a/micropython/modules/breakout_colourlcd160x80/breakout_colourlcd160x80.cpp b/micropython/modules/breakout_colourlcd160x80/breakout_colourlcd160x80.cpp index 967be361..2d387c75 100644 --- a/micropython/modules/breakout_colourlcd160x80/breakout_colourlcd160x80.cpp +++ b/micropython/modules/breakout_colourlcd160x80/breakout_colourlcd160x80.cpp @@ -63,14 +63,14 @@ mp_obj_t BreakoutColourLCD160x80_make_new(const mp_obj_type_t *type, size_t n_ar mp_arg_parse_all_kw_array(n_args, n_kw, all_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); int slot = args[ARG_slot].u_int; - if(slot == ST7735::BG_SPI_FRONT || slot == ST7735::BG_SPI_BACK) { + if(slot == BG_SPI_FRONT || slot == BG_SPI_BACK) { self = m_new_obj(breakout_colourlcd160x80_BreakoutColourLCD160x80_obj_t); self->base.type = &breakout_colourlcd160x80_BreakoutColourLCD160x80_type; mp_buffer_info_t bufinfo; mp_get_buffer_raise(args[ARG_buffer].u_obj, &bufinfo, MP_BUFFER_RW); - self->breakout = new BreakoutColourLCD160x80((uint16_t *)bufinfo.buf, (ST7735::BG_SPI_SLOT)slot); + self->breakout = new BreakoutColourLCD160x80((uint16_t *)bufinfo.buf, (BG_SPI_SLOT)slot); } else { mp_raise_ValueError("slot not a valid value. Expected 0 to 1"); @@ -120,7 +120,7 @@ mp_obj_t BreakoutColourLCD160x80_make_new(const mp_obj_type_t *type, size_t n_ar spi_inst_t *spi = (spi_id == 0) ? spi0 : spi1; self->breakout = new BreakoutColourLCD160x80((uint16_t *)bufinfo.buf, spi, - args[ARG_cs].u_int, args[ARG_dc].u_int, sck, mosi, BreakoutColourLCD160x80::PIN_UNUSED, args[ARG_bl].u_int); + args[ARG_cs].u_int, args[ARG_dc].u_int, sck, mosi, PIN_UNUSED, args[ARG_bl].u_int); } self->breakout->init(); diff --git a/micropython/modules/breakout_colourlcd240x240/breakout_colourlcd240x240.cpp b/micropython/modules/breakout_colourlcd240x240/breakout_colourlcd240x240.cpp index 8927d5f7..79aa909f 100644 --- a/micropython/modules/breakout_colourlcd240x240/breakout_colourlcd240x240.cpp +++ b/micropython/modules/breakout_colourlcd240x240/breakout_colourlcd240x240.cpp @@ -63,14 +63,14 @@ mp_obj_t BreakoutColourLCD240x240_make_new(const mp_obj_type_t *type, size_t n_a mp_arg_parse_all_kw_array(n_args, n_kw, all_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); int slot = args[ARG_slot].u_int; - if(slot == ST7789::BG_SPI_FRONT || slot == ST7789::BG_SPI_BACK) { + if(slot == BG_SPI_FRONT || slot == BG_SPI_BACK) { self = m_new_obj(breakout_colourlcd240x240_BreakoutColourLCD240x240_obj_t); self->base.type = &breakout_colourlcd240x240_BreakoutColourLCD240x240_type; mp_buffer_info_t bufinfo; mp_get_buffer_raise(args[ARG_buffer].u_obj, &bufinfo, MP_BUFFER_RW); - self->breakout = new BreakoutColourLCD240x240((uint16_t *)bufinfo.buf, (ST7789::BG_SPI_SLOT)slot); + self->breakout = new BreakoutColourLCD240x240((uint16_t *)bufinfo.buf, (BG_SPI_SLOT)slot); } else { mp_raise_ValueError("slot not a valid value. Expected 0 to 1"); @@ -81,11 +81,11 @@ mp_obj_t BreakoutColourLCD240x240_make_new(const mp_obj_type_t *type, size_t n_a static const mp_arg_t allowed_args[] = { { MP_QSTR_buffer, MP_ARG_REQUIRED | MP_ARG_OBJ }, { MP_QSTR_spi, MP_ARG_INT, {.u_int = -1} }, - { MP_QSTR_cs, MP_ARG_INT, {.u_int = ST7789::DEFAULT_CS_PIN} }, - { MP_QSTR_dc, MP_ARG_INT, {.u_int = ST7789::DEFAULT_DC_PIN} }, - { MP_QSTR_sck, MP_ARG_INT, {.u_int = ST7789::DEFAULT_SCK_PIN} }, - { MP_QSTR_mosi, MP_ARG_INT, {.u_int = ST7789::DEFAULT_MOSI_PIN} }, - { MP_QSTR_bl, MP_ARG_INT, {.u_int = ST7789::DEFAULT_BL_PIN} }, + { MP_QSTR_cs, MP_ARG_INT, {.u_int = pimoroni::SPI_BG_FRONT_CS} }, + { MP_QSTR_dc, MP_ARG_INT, {.u_int = pimoroni::SPI_DEFAULT_MISO} }, + { MP_QSTR_sck, MP_ARG_INT, {.u_int = pimoroni::SPI_DEFAULT_SCK} }, + { MP_QSTR_mosi, MP_ARG_INT, {.u_int = pimoroni::SPI_DEFAULT_MOSI} }, + { MP_QSTR_bl, MP_ARG_INT, {.u_int = pimoroni::SPI_BG_FRONT_PWM} }, }; // Parse args. @@ -120,7 +120,7 @@ mp_obj_t BreakoutColourLCD240x240_make_new(const mp_obj_type_t *type, size_t n_a spi_inst_t *spi = (spi_id == 0) ? spi0 : spi1; self->breakout = new BreakoutColourLCD240x240((uint16_t *)bufinfo.buf, spi, - args[ARG_cs].u_int, args[ARG_dc].u_int, sck, mosi, BreakoutColourLCD240x240::PIN_UNUSED, args[ARG_bl].u_int); + args[ARG_cs].u_int, args[ARG_dc].u_int, sck, mosi, PIN_UNUSED, args[ARG_bl].u_int); } self->breakout->init(); diff --git a/micropython/modules/breakout_dotmatrix/breakout_dotmatrix.cpp b/micropython/modules/breakout_dotmatrix/breakout_dotmatrix.cpp index f8205c37..de9fca75 100644 --- a/micropython/modules/breakout_dotmatrix/breakout_dotmatrix.cpp +++ b/micropython/modules/breakout_dotmatrix/breakout_dotmatrix.cpp @@ -12,6 +12,13 @@ using namespace pimoroni; 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 { @@ -47,43 +54,27 @@ void BreakoutDotMatrix_print(const mp_print_t *print, mp_obj_t self_in, mp_print mp_obj_t BreakoutDotMatrix_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *all_args) { breakout_dotmatrix_BreakoutDotMatrix_obj_t *self = nullptr; - enum { ARG_i2c, ARG_address, ARG_sda, ARG_scl }; + enum { ARG_i2c, ARG_address }; 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 = BreakoutDotMatrix::DEFAULT_I2C_ADDRESS} }, - { MP_QSTR_sda, MP_ARG_INT, {.u_int = 20} }, - { MP_QSTR_scl, MP_ARG_INT, {.u_int = 21} }, }; // 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; - 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("BreakoutDotMatrix: 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_dotmatrix_BreakoutDotMatrix_obj_t); self->base.type = &breakout_dotmatrix_BreakoutDotMatrix_type; - i2c_inst_t *i2c = (i2c_id == 0) ? i2c0 : i2c1; - self->breakout = new BreakoutDotMatrix(i2c, args[ARG_address].u_int, sda, scl); + self->breakout = new BreakoutDotMatrix(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 8d30b1bc..314bf86b 100644 --- a/micropython/modules/breakout_encoder/breakout_encoder.cpp +++ b/micropython/modules/breakout_encoder/breakout_encoder.cpp @@ -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,47 +57,31 @@ 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 = 20} }, - { MP_QSTR_scl, MP_ARG_INT, {.u_int = 21} }, - { MP_QSTR_interrupt, MP_ARG_INT, {.u_int = BreakoutEncoder::PIN_UNUSED} }, + { MP_QSTR_interrupt, MP_ARG_INT, {.u_int = 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; - 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("BreakoutEncoder: 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; - i2c_inst_t *i2c = (i2c_id == 0) ? i2c0 : i2c1; - self->breakout = new BreakoutEncoder(i2c, 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"); + mp_raise_msg(&mp_type_RuntimeError, "BreakoutEncoder: breakout not found when initialising"); } return MP_OBJ_FROM_PTR(self); diff --git a/micropython/modules/breakout_ioexpander/breakout_ioexpander.cpp b/micropython/modules/breakout_ioexpander/breakout_ioexpander.cpp index 272405be..d1d8d356 100644 --- a/micropython/modules/breakout_ioexpander/breakout_ioexpander.cpp +++ b/micropython/modules/breakout_ioexpander/breakout_ioexpander.cpp @@ -12,6 +12,13 @@ using namespace pimoroni; 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 { @@ -50,13 +57,11 @@ void BreakoutIOExpander_print(const mp_print_t *print, mp_obj_t self_in, mp_prin 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; - 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 = BreakoutIOExpander::DEFAULT_I2C_ADDRESS} }, - { MP_QSTR_sda, MP_ARG_INT, {.u_int = 20} }, - { MP_QSTR_scl, MP_ARG_INT, {.u_int = 21} }, - { MP_QSTR_interrupt, MP_ARG_INT, {.u_int = BreakoutIOExpander::PIN_UNUSED} }, + { MP_QSTR_interrupt, MP_ARG_INT, {.u_int = PIN_UNUSED} }, }; // Parse args. @@ -64,33 +69,20 @@ mp_obj_t BreakoutIOExpander_make_new(const mp_obj_type_t *type, size_t n_args, s 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("BreakoutIOExpander: 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_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); + self->breakout = new BreakoutIOExpander(i2c->i2c, args[ARG_address].u_int, args[ARG_interrupt].u_int); if(!self->breakout->init()) { - mp_raise_msg(&mp_type_RuntimeError, "IOExpander breakout not found when initialising"); + mp_raise_msg(&mp_type_RuntimeError, "BreakoutIOExpander: breakout not found when initialising"); } return MP_OBJ_FROM_PTR(self); diff --git a/micropython/modules/breakout_ltr559/breakout_ltr559.cpp b/micropython/modules/breakout_ltr559/breakout_ltr559.cpp index 645df5a1..735a5845 100644 --- a/micropython/modules/breakout_ltr559/breakout_ltr559.cpp +++ b/micropython/modules/breakout_ltr559/breakout_ltr559.cpp @@ -12,6 +12,13 @@ using namespace pimoroni; 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 { @@ -50,47 +57,30 @@ void BreakoutLTR559_print(const mp_print_t *print, mp_obj_t self_in, mp_print_ki mp_obj_t BreakoutLTR559_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *all_args) { breakout_ltr559_BreakoutLTR559_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_address, MP_ARG_INT, {.u_int = BreakoutLTR559::DEFAULT_I2C_ADDRESS} }, - { MP_QSTR_sda, MP_ARG_INT, {.u_int = 20} }, - { MP_QSTR_scl, MP_ARG_INT, {.u_int = 21} }, - { MP_QSTR_interrupt, MP_ARG_INT, {.u_int = BreakoutLTR559::PIN_UNUSED} }, + { MP_QSTR_i2c, MP_ARG_OBJ, {.u_obj = nullptr} }, + { MP_QSTR_interrupt, MP_ARG_INT, {.u_int = 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; - 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("BreakoutLTR559: 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_ltr559_BreakoutLTR559_obj_t); self->base.type = &breakout_ltr559_BreakoutLTR559_type; - - i2c_inst_t *i2c = (i2c_id == 0) ? i2c0 : i2c1; - self->breakout = new BreakoutLTR559(i2c, args[ARG_address].u_int, sda, scl, args[ARG_interrupt].u_int); + + self->breakout = new BreakoutLTR559(i2c->i2c, args[ARG_interrupt].u_int); if(!self->breakout->init()) { - mp_raise_msg(&mp_type_RuntimeError, "LTR559 breakout not found when initialising"); + mp_raise_msg(&mp_type_RuntimeError, "BreakoutLTR559: breakout not found when initialising"); } return MP_OBJ_FROM_PTR(self); diff --git a/micropython/modules/breakout_matrix11x7/breakout_matrix11x7.cpp b/micropython/modules/breakout_matrix11x7/breakout_matrix11x7.cpp index 801f8bae..06d89c90 100644 --- a/micropython/modules/breakout_matrix11x7/breakout_matrix11x7.cpp +++ b/micropython/modules/breakout_matrix11x7/breakout_matrix11x7.cpp @@ -12,6 +12,13 @@ using namespace pimoroni; 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 { @@ -47,12 +54,10 @@ void BreakoutMatrix11x7_print(const mp_print_t *print, mp_obj_t self_in, mp_prin mp_obj_t BreakoutMatrix11x7_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *all_args) { breakout_matrix11x7_BreakoutMatrix11x7_obj_t *self = nullptr; - enum { ARG_i2c, ARG_address, ARG_sda, ARG_scl }; + enum { ARG_i2c, ARG_address }; static const mp_arg_t allowed_args[] = { - { MP_QSTR_i2c, MP_ARG_INT, {.u_int = -1} }, - { MP_QSTR_address, MP_ARG_INT, {.u_int = BreakoutMatrix11x7::DEFAULT_I2C_ADDRESS} }, - { MP_QSTR_sda, MP_ARG_INT, {.u_int = 20} }, - { MP_QSTR_scl, MP_ARG_INT, {.u_int = 21} }, + { MP_QSTR_i2c, MP_ARG_OBJ, {.u_obj = nullptr} }, + { MP_QSTR_address, MP_ARG_INT, {.u_int = BreakoutMatrix11x7::DEFAULT_I2C_ADDRESS} } }; // Parse args. @@ -60,33 +65,20 @@ mp_obj_t BreakoutMatrix11x7_make_new(const mp_obj_type_t *type, size_t n_args, s 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("BreakoutMatrix11x7: 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_matrix11x7_BreakoutMatrix11x7_obj_t); self->base.type = &breakout_matrix11x7_BreakoutMatrix11x7_type; - i2c_inst_t *i2c = (i2c_id == 0) ? i2c0 : i2c1; - self->breakout = new BreakoutMatrix11x7(i2c, args[ARG_address].u_int, sda, scl); + self->breakout = new BreakoutMatrix11x7(i2c->i2c, args[ARG_address].u_int); if(!self->breakout->init()) { - mp_raise_msg(&mp_type_RuntimeError, "Matrix11x7 breakout not found when initialising"); + mp_raise_msg(&mp_type_RuntimeError, "BreakoutMatrix11x7: breakout not found when initialising"); } return MP_OBJ_FROM_PTR(self); diff --git a/micropython/modules/breakout_mics6814/breakout_mics6814.cpp b/micropython/modules/breakout_mics6814/breakout_mics6814.cpp index 5579c016..3994faac 100644 --- a/micropython/modules/breakout_mics6814/breakout_mics6814.cpp +++ b/micropython/modules/breakout_mics6814/breakout_mics6814.cpp @@ -12,6 +12,13 @@ using namespace pimoroni; 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 { @@ -50,13 +57,11 @@ void BreakoutMICS6814_print(const mp_print_t *print, mp_obj_t self_in, mp_print_ mp_obj_t BreakoutMICS6814_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *all_args) { breakout_mics6814_BreakoutMICS6814_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 = BreakoutMICS6814::DEFAULT_I2C_ADDRESS} }, - { MP_QSTR_sda, MP_ARG_INT, {.u_int = 20} }, - { MP_QSTR_scl, MP_ARG_INT, {.u_int = 21} }, - { MP_QSTR_interrupt, MP_ARG_INT, {.u_int = BreakoutMICS6814::PIN_UNUSED} }, + { MP_QSTR_interrupt, MP_ARG_INT, {.u_int = PIN_UNUSED} }, }; // Parse args. @@ -64,33 +69,20 @@ mp_obj_t BreakoutMICS6814_make_new(const mp_obj_type_t *type, size_t n_args, siz 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("BreakoutMICS6814: 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_mics6814_BreakoutMICS6814_obj_t); self->base.type = &breakout_mics6814_BreakoutMICS6814_type; - i2c_inst_t *i2c = (i2c_id == 0) ? i2c0 : i2c1; - self->breakout = new BreakoutMICS6814(i2c, args[ARG_address].u_int, sda, scl, args[ARG_interrupt].u_int); + self->breakout = new BreakoutMICS6814(i2c->i2c, args[ARG_address].u_int, args[ARG_interrupt].u_int); if(!self->breakout->init()) { - mp_raise_msg(&mp_type_RuntimeError, "MICS6814 breakout not found when initialising"); + mp_raise_msg(&mp_type_RuntimeError, "BreakoutMICS6814: breakout not found when initialising"); } return MP_OBJ_FROM_PTR(self); diff --git a/micropython/modules/breakout_msa301/breakout_msa301.cpp b/micropython/modules/breakout_msa301/breakout_msa301.cpp index a59628ef..bb21fed3 100644 --- a/micropython/modules/breakout_msa301/breakout_msa301.cpp +++ b/micropython/modules/breakout_msa301/breakout_msa301.cpp @@ -11,6 +11,13 @@ using namespace pimoroni; 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 { @@ -44,46 +51,30 @@ void BreakoutMSA301_print(const mp_print_t *print, mp_obj_t self_in, mp_print_ki mp_obj_t BreakoutMSA301_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *all_args) { breakout_msa301_BreakoutMSA301_obj_t *self = nullptr; - enum { ARG_i2c, 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_sda, MP_ARG_INT, {.u_int = 20} }, - { MP_QSTR_scl, MP_ARG_INT, {.u_int = 21} }, - { MP_QSTR_interrupt, MP_ARG_INT, {.u_int = BreakoutMSA301::PIN_UNUSED} }, + { MP_QSTR_i2c, MP_ARG_OBJ, {.u_obj = nullptr} }, + { MP_QSTR_interrupt, MP_ARG_INT, {.u_int = 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; - 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("BreakoutMSA301: 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_msa301_BreakoutMSA301_obj_t); self->base.type = &breakout_msa301_BreakoutMSA301_type; - - i2c_inst_t *i2c = (i2c_id == 0) ? i2c0 : i2c1; - self->breakout = new BreakoutMSA301(i2c, sda, scl, args[ARG_interrupt].u_int); + + self->breakout = new BreakoutMSA301(i2c->i2c, args[ARG_interrupt].u_int); if(!self->breakout->init()) { - mp_raise_msg(&mp_type_RuntimeError, "MSA301 breakout not found when initialising"); + mp_raise_msg(&mp_type_RuntimeError, "BreakoutMSA301: breakout not found when initialising"); } return MP_OBJ_FROM_PTR(self); diff --git a/micropython/modules/breakout_potentiometer/breakout_potentiometer.cpp b/micropython/modules/breakout_potentiometer/breakout_potentiometer.cpp index 2812a161..90fc24d3 100644 --- a/micropython/modules/breakout_potentiometer/breakout_potentiometer.cpp +++ b/micropython/modules/breakout_potentiometer/breakout_potentiometer.cpp @@ -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,47 +57,31 @@ 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 = 20} }, - { MP_QSTR_scl, MP_ARG_INT, {.u_int = 21} }, - { MP_QSTR_interrupt, MP_ARG_INT, {.u_int = BreakoutPotentiometer::PIN_UNUSED} }, + { MP_QSTR_interrupt, MP_ARG_INT, {.u_int = 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; - 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("BreakoutPotentiometer: 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; - i2c_inst_t *i2c = (i2c_id == 0) ? i2c0 : i2c1; - self->breakout = new BreakoutPotentiometer(i2c, 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"); + mp_raise_msg(&mp_type_RuntimeError, "BreakoutPotentiometer: breakout not found when initialising"); } return MP_OBJ_FROM_PTR(self); diff --git a/micropython/modules/breakout_rgbmatrix5x5/breakout_rgbmatrix5x5.cpp b/micropython/modules/breakout_rgbmatrix5x5/breakout_rgbmatrix5x5.cpp index 3057e507..c1c80676 100644 --- a/micropython/modules/breakout_rgbmatrix5x5/breakout_rgbmatrix5x5.cpp +++ b/micropython/modules/breakout_rgbmatrix5x5/breakout_rgbmatrix5x5.cpp @@ -12,6 +12,13 @@ using namespace pimoroni; 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 { @@ -47,12 +54,10 @@ void BreakoutRGBMatrix5x5_print(const mp_print_t *print, mp_obj_t self_in, mp_pr mp_obj_t BreakoutRGBMatrix5x5_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *all_args) { breakout_rgbmatrix5x5_BreakoutRGBMatrix5x5_obj_t *self = nullptr; - enum { ARG_i2c, ARG_address, ARG_sda, ARG_scl }; + enum { ARG_i2c, ARG_address }; static const mp_arg_t allowed_args[] = { - { MP_QSTR_i2c, MP_ARG_INT, {.u_int = -1} }, - { MP_QSTR_address, MP_ARG_INT, {.u_int = BreakoutRGBMatrix5x5::DEFAULT_I2C_ADDRESS} }, - { MP_QSTR_sda, MP_ARG_INT, {.u_int = 20} }, - { MP_QSTR_scl, MP_ARG_INT, {.u_int = 21} }, + { MP_QSTR_i2c, MP_ARG_OBJ, {.u_obj = nullptr} }, + { MP_QSTR_address, MP_ARG_INT, {.u_int = BreakoutRGBMatrix5x5::DEFAULT_I2C_ADDRESS} } }; // Parse args. @@ -60,33 +65,20 @@ mp_obj_t BreakoutRGBMatrix5x5_make_new(const mp_obj_type_t *type, size_t n_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("BreakoutRGBMatrix5x5: 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_rgbmatrix5x5_BreakoutRGBMatrix5x5_obj_t); self->base.type = &breakout_rgbmatrix5x5_BreakoutRGBMatrix5x5_type; - - i2c_inst_t *i2c = (i2c_id == 0) ? i2c0 : i2c1; - self->breakout = new BreakoutRGBMatrix5x5(i2c, args[ARG_address].u_int, sda, scl); + + self->breakout = new BreakoutRGBMatrix5x5(i2c->i2c, args[ARG_address].u_int); if(!self->breakout->init()) { - mp_raise_msg(&mp_type_RuntimeError, "RGBMatrix5x5 breakout not found when initialising"); + mp_raise_msg(&mp_type_RuntimeError, "BreakoutRGBMatrix5x5: breakout not found when initialising"); } return MP_OBJ_FROM_PTR(self); diff --git a/micropython/modules/breakout_roundlcd/breakout_roundlcd.cpp b/micropython/modules/breakout_roundlcd/breakout_roundlcd.cpp index 624db96d..3f970b37 100644 --- a/micropython/modules/breakout_roundlcd/breakout_roundlcd.cpp +++ b/micropython/modules/breakout_roundlcd/breakout_roundlcd.cpp @@ -63,14 +63,14 @@ mp_obj_t BreakoutRoundLCD_make_new(const mp_obj_type_t *type, size_t n_args, siz mp_arg_parse_all_kw_array(n_args, n_kw, all_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); int slot = args[ARG_slot].u_int; - if(slot == ST7789::BG_SPI_FRONT || slot == ST7789::BG_SPI_BACK) { + if(slot == BG_SPI_FRONT || slot == BG_SPI_BACK) { self = m_new_obj(breakout_roundlcd_BreakoutRoundLCD_obj_t); self->base.type = &breakout_roundlcd_BreakoutRoundLCD_type; mp_buffer_info_t bufinfo; mp_get_buffer_raise(args[ARG_buffer].u_obj, &bufinfo, MP_BUFFER_RW); - self->breakout = new BreakoutRoundLCD((uint16_t *)bufinfo.buf, (ST7789::BG_SPI_SLOT)slot); + self->breakout = new BreakoutRoundLCD((uint16_t *)bufinfo.buf, (BG_SPI_SLOT)slot); } else { mp_raise_ValueError("slot not a valid value. Expected 0 to 1"); @@ -81,11 +81,11 @@ mp_obj_t BreakoutRoundLCD_make_new(const mp_obj_type_t *type, size_t n_args, siz static const mp_arg_t allowed_args[] = { { MP_QSTR_buffer, MP_ARG_REQUIRED | MP_ARG_OBJ }, { MP_QSTR_spi, MP_ARG_INT, {.u_int = -1} }, - { MP_QSTR_cs, MP_ARG_INT, {.u_int = ST7789::DEFAULT_CS_PIN} }, - { MP_QSTR_dc, MP_ARG_INT, {.u_int = ST7789::DEFAULT_DC_PIN} }, - { MP_QSTR_sck, MP_ARG_INT, {.u_int = ST7789::DEFAULT_SCK_PIN} }, - { MP_QSTR_mosi, MP_ARG_INT, {.u_int = ST7789::DEFAULT_MOSI_PIN} }, - { MP_QSTR_bl, MP_ARG_INT, {.u_int = ST7789::DEFAULT_BL_PIN} }, + { MP_QSTR_cs, MP_ARG_INT, {.u_int = pimoroni::SPI_BG_FRONT_CS} }, + { MP_QSTR_dc, MP_ARG_INT, {.u_int = pimoroni::SPI_DEFAULT_MISO} }, + { MP_QSTR_sck, MP_ARG_INT, {.u_int = pimoroni::SPI_DEFAULT_SCK} }, + { MP_QSTR_mosi, MP_ARG_INT, {.u_int = pimoroni::SPI_DEFAULT_MOSI} }, + { MP_QSTR_bl, MP_ARG_INT, {.u_int = pimoroni::SPI_BG_FRONT_PWM} }, }; // Parse args. @@ -120,7 +120,7 @@ mp_obj_t BreakoutRoundLCD_make_new(const mp_obj_type_t *type, size_t n_args, siz spi_inst_t *spi = (spi_id == 0) ? spi0 : spi1; self->breakout = new BreakoutRoundLCD((uint16_t *)bufinfo.buf, spi, - args[ARG_cs].u_int, args[ARG_dc].u_int, sck, mosi, BreakoutRoundLCD::PIN_UNUSED, args[ARG_bl].u_int); + args[ARG_cs].u_int, args[ARG_dc].u_int, sck, mosi, PIN_UNUSED, args[ARG_bl].u_int); } self->breakout->init(); diff --git a/micropython/modules/breakout_rtc/breakout_rtc.cpp b/micropython/modules/breakout_rtc/breakout_rtc.cpp index d36df64d..22afbf42 100644 --- a/micropython/modules/breakout_rtc/breakout_rtc.cpp +++ b/micropython/modules/breakout_rtc/breakout_rtc.cpp @@ -14,6 +14,13 @@ using namespace pimoroni; 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 { @@ -47,12 +54,10 @@ void BreakoutRTC_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_ mp_obj_t BreakoutRTC_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *all_args) { breakout_rtc_BreakoutRTC_obj_t *self = nullptr; - enum { ARG_i2c, 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_sda, MP_ARG_INT, {.u_int = 20} }, - { MP_QSTR_scl, MP_ARG_INT, {.u_int = 21} }, - { MP_QSTR_interrupt, MP_ARG_INT, {.u_int = BreakoutRTC::PIN_UNUSED} }, + { MP_QSTR_i2c, MP_ARG_OBJ, {.u_obj = nullptr} }, + { MP_QSTR_interrupt, MP_ARG_INT, {.u_int = PIN_UNUSED} }, }; // Parse args. @@ -60,33 +65,20 @@ mp_obj_t BreakoutRTC_make_new(const mp_obj_type_t *type, size_t n_args, size_t n 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("BreakoutRTC: 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_rtc_BreakoutRTC_obj_t); self->base.type = &breakout_rtc_BreakoutRTC_type; - i2c_inst_t *i2c = (i2c_id == 0) ? i2c0 : i2c1; - self->breakout = new BreakoutRTC(i2c, sda, scl, args[ARG_interrupt].u_int); + self->breakout = new BreakoutRTC(i2c->i2c, args[ARG_interrupt].u_int); if(!self->breakout->init()) { - mp_raise_msg(&mp_type_RuntimeError, "RTC breakout not found when initialising"); + mp_raise_msg(&mp_type_RuntimeError, "BreakoutRTC: breakout not found when initialising"); } return MP_OBJ_FROM_PTR(self); diff --git a/micropython/modules/breakout_sgp30/breakout_sgp30.cpp b/micropython/modules/breakout_sgp30/breakout_sgp30.cpp index 7812b4a1..41ff3029 100644 --- a/micropython/modules/breakout_sgp30/breakout_sgp30.cpp +++ b/micropython/modules/breakout_sgp30/breakout_sgp30.cpp @@ -11,6 +11,13 @@ using namespace pimoroni; 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 { @@ -41,11 +48,9 @@ void BreakoutSGP30_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kin mp_obj_t BreakoutSGP30_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *all_args) { breakout_sgp30_BreakoutSGP30_obj_t *self = nullptr; - enum { ARG_i2c, ARG_sda, ARG_scl }; + enum { ARG_i2c }; static const mp_arg_t allowed_args[] = { - { MP_QSTR_i2c, MP_ARG_INT, {.u_int = -1} }, - { MP_QSTR_sda, MP_ARG_INT, {.u_int = 20} }, - { MP_QSTR_scl, MP_ARG_INT, {.u_int = 21} }, + { MP_QSTR_i2c, MP_ARG_OBJ, {.u_obj = nullptr} } }; // Parse args. @@ -53,33 +58,20 @@ mp_obj_t BreakoutSGP30_make_new(const mp_obj_type_t *type, size_t n_args, size_t 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("BreakoutSGP30: 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_sgp30_BreakoutSGP30_obj_t); self->base.type = &breakout_sgp30_BreakoutSGP30_type; - - i2c_inst_t *i2c = (i2c_id == 0) ? i2c0 : i2c1; - self->breakout = new BreakoutSGP30(i2c, sda, scl); + + self->breakout = new BreakoutSGP30(i2c->i2c); if(!self->breakout->init()) { - mp_raise_msg(&mp_type_RuntimeError, "SGP30 breakout not found when initialising"); + mp_raise_msg(&mp_type_RuntimeError, "BreakoutSGP30: breakout not found when initialising"); } return MP_OBJ_FROM_PTR(self); diff --git a/micropython/modules/breakout_trackball/breakout_trackball.cpp b/micropython/modules/breakout_trackball/breakout_trackball.cpp index 81b23f3c..eb62513e 100644 --- a/micropython/modules/breakout_trackball/breakout_trackball.cpp +++ b/micropython/modules/breakout_trackball/breakout_trackball.cpp @@ -12,6 +12,13 @@ using namespace pimoroni; 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 { @@ -50,13 +57,11 @@ void BreakoutTrackball_print(const mp_print_t *print, mp_obj_t self_in, mp_print mp_obj_t BreakoutTrackball_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *all_args) { breakout_trackball_BreakoutTrackball_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 = BreakoutTrackball::DEFAULT_I2C_ADDRESS} }, - { MP_QSTR_sda, MP_ARG_INT, {.u_int = 20} }, - { MP_QSTR_scl, MP_ARG_INT, {.u_int = 21} }, - { MP_QSTR_interrupt, MP_ARG_INT, {.u_int = BreakoutTrackball::PIN_UNUSED} }, + { MP_QSTR_interrupt, MP_ARG_INT, {.u_int = PIN_UNUSED} }, }; // Parse args. @@ -64,30 +69,17 @@ mp_obj_t BreakoutTrackball_make_new(const mp_obj_type_t *type, size_t n_args, si 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("BreakoutSGP30: 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_trackball_BreakoutTrackball_obj_t); self->base.type = &breakout_trackball_BreakoutTrackball_type; - i2c_inst_t *i2c = (i2c_id == 0) ? i2c0 : i2c1; - self->breakout = new BreakoutTrackball(i2c, args[ARG_address].u_int, sda, scl, args[ARG_interrupt].u_int); + self->breakout = new BreakoutTrackball(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/micropython.cmake b/micropython/modules/micropython.cmake index 9d54d435..87705f3b 100644 --- a/micropython/modules/micropython.cmake +++ b/micropython/modules/micropython.cmake @@ -1,5 +1,7 @@ include_directories(${CMAKE_CURRENT_LIST_DIR}/../../) +include(${CMAKE_CURRENT_LIST_DIR}/pimoroni_i2c/micropython.cmake) + 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) diff --git a/micropython/modules/pimoroni_i2c/micropython.cmake b/micropython/modules/pimoroni_i2c/micropython.cmake new file mode 100644 index 00000000..0d4d9801 --- /dev/null +++ b/micropython/modules/pimoroni_i2c/micropython.cmake @@ -0,0 +1,19 @@ +set(MOD_NAME pimoroni_i2c) +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 +) + +target_include_directories(usermod_${MOD_NAME} INTERFACE + ${CMAKE_CURRENT_LIST_DIR} +) + +target_compile_definitions(usermod_${MOD_NAME} INTERFACE + MODULE_${MOD_NAME_UPPER}_ENABLED=1 +) + +target_link_libraries(usermod INTERFACE usermod_${MOD_NAME}) \ No newline at end of file diff --git a/micropython/modules/pimoroni_i2c/pimoroni_i2c.c b/micropython/modules/pimoroni_i2c/pimoroni_i2c.c new file mode 100644 index 00000000..e91b53b3 --- /dev/null +++ b/micropython/modules/pimoroni_i2c/pimoroni_i2c.c @@ -0,0 +1,48 @@ +#include "pimoroni_i2c.h" + +//////////////////////////////////////////////////////////////////////////////////////////////////// +// PimoroniI2C Class +//////////////////////////////////////////////////////////////////////////////////////////////////// + + +/***** 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); + +/***** 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); +//////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////////////////////////// \ No newline at end of file diff --git a/micropython/modules/pimoroni_i2c/pimoroni_i2c.cpp b/micropython/modules/pimoroni_i2c/pimoroni_i2c.cpp new file mode 100644 index 00000000..f8924fd2 --- /dev/null +++ b/micropython/modules/pimoroni_i2c/pimoroni_i2c.cpp @@ -0,0 +1,86 @@ +#include "common/pimoroni_i2c.hpp" +#include + +#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, ")"); +} + +/***** 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; + + enum { ARG_sda, ARG_scl, ARG_baudrate }; + 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} }, + { MP_QSTR_baudrate, MP_ARG_INT, {.u_int = I2C_DEFAULT_BAUDRATE} }, + }; + + // 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 baud = args[ARG_baudrate].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_with_finaliser(_PimoroniI2C_obj_t); + self->base.type = &PimoroniI2C_type; + + self->i2c = new I2C(sda, scl, baud); + + return MP_OBJ_FROM_PTR(self); +} + +} \ No newline at end of file diff --git a/micropython/modules/pimoroni_i2c/pimoroni_i2c.h b/micropython/modules/pimoroni_i2c/pimoroni_i2c.h new file mode 100644 index 00000000..3351a8af --- /dev/null +++ b/micropython/modules/pimoroni_i2c/pimoroni_i2c.h @@ -0,0 +1,12 @@ +// 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 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