From 3dfae2ed5c7abece1332c20fb7a12c22c7d6ac12 Mon Sep 17 00:00:00 2001 From: Phil Howard Date: Tue, 20 Apr 2021 10:54:10 +0100 Subject: [PATCH 01/10] Add a common header for pins and settings * Add a common/pimoroni.hpp to list default pins for various add-ons * Move the BG SPI Slot enum here for safe keeping * Switch all GPIO pin references to "uint" to match Pico SDK and bring back PIN_UNUSED as UINT_MAX --- common/pimoroni.hpp | 35 +++++++++ drivers/msa301/msa301.hpp | 10 ++- drivers/rv3028/rv3028.hpp | 11 +-- drivers/st7735/st7735.hpp | 12 +-- drivers/st7789/st7789.cpp | 16 ++-- drivers/st7789/st7789.hpp | 75 +++++++------------ examples/breakout_roundlcd/demo.cpp | 2 +- .../breakout_colourlcd160x80.cpp | 2 +- .../breakout_colourlcd160x80.hpp | 3 +- .../breakout_colourlcd240x240.cpp | 2 +- .../breakout_colourlcd240x240.hpp | 3 +- .../breakout_roundlcd/breakout_roundlcd.cpp | 5 +- .../breakout_roundlcd/breakout_roundlcd.hpp | 4 +- libraries/pico_explorer/pico_explorer.cpp | 2 +- libraries/pico_explorer/pico_explorer.hpp | 26 +++---- .../breakout_colourlcd160x80.cpp | 4 +- .../breakout_colourlcd240x240.cpp | 14 ++-- .../breakout_roundlcd/breakout_roundlcd.cpp | 14 ++-- 18 files changed, 122 insertions(+), 118 deletions(-) create mode 100644 common/pimoroni.hpp diff --git a/common/pimoroni.hpp b/common/pimoroni.hpp new file mode 100644 index 000000000..5c1db512a --- /dev/null +++ b/common/pimoroni.hpp @@ -0,0 +1,35 @@ +#pragma once +#include +#include + +#define PIMORONI_I2C_DEFAULT_INSTANCE i2c0 +#define PIMORONI_SPI_DEFAULT_INSTANCE spi0 + +namespace pimoroni { + static const unsigned int PIN_UNUSED = UINT_MAX; + + // I2C + 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 + }; +} \ No newline at end of file diff --git a/drivers/msa301/msa301.hpp b/drivers/msa301/msa301.hpp index afdbc8ca7..eb03cecad 100644 --- a/drivers/msa301/msa301.hpp +++ b/drivers/msa301/msa301.hpp @@ -2,6 +2,7 @@ #include "hardware/i2c.h" #include "hardware/gpio.h" +#include "common/pimoroni.hpp" namespace pimoroni { @@ -110,9 +111,10 @@ namespace pimoroni { // 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 sda = I2C_DEFAULT_SDA; + uint scl = I2C_DEFAULT_SCL; + uint interrupt = I2C_DEFAULT_INT; + i2c_inst_t *i2c = PIMORONI_I2C_DEFAULT_INSTANCE; //-------------------------------------------------- @@ -121,7 +123,7 @@ namespace pimoroni { public: MSA301() {} - MSA301(i2c_inst_t *i2c, uint8_t sda, uint8_t scl, uint8_t interrupt) : + MSA301(i2c_inst_t *i2c, uint sda, uint scl, uint interrupt) : i2c(i2c), sda(sda), scl(scl), interrupt(interrupt) {} diff --git a/drivers/rv3028/rv3028.hpp b/drivers/rv3028/rv3028.hpp index 4ef2f1ec6..bc7c7f44e 100644 --- a/drivers/rv3028/rv3028.hpp +++ b/drivers/rv3028/rv3028.hpp @@ -12,6 +12,7 @@ Distributed as-is; no warranty is given. #include "hardware/i2c.h" #include "hardware/gpio.h" +#include "common/pimoroni.hpp" #include #include @@ -206,13 +207,13 @@ namespace pimoroni { // Variables //-------------------------------------------------- private: - i2c_inst_t *i2c = i2c0; + i2c_inst_t *i2c = PIMORONI_I2C_DEFAULT_INSTANCE; // 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; + int8_t address = DEFAULT_I2C_ADDRESS; + uint sda = DEFAULT_SDA_PIN; + uint scl = DEFAULT_SCL_PIN; + uint interrupt = DEFAULT_INT_PIN; uint8_t times[TIME_ARRAY_LENGTH]; diff --git a/drivers/st7735/st7735.hpp b/drivers/st7735/st7735.hpp index a5214ec7d..c3c7c832c 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.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 9729e53ab..af73df5de 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 8407f5757..029d739db 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.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; - - 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 + 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; - - //-------------------------------------------------- - // Constructors/Destructor - //-------------------------------------------------- public: + // frame buffer where pixel data is stored + uint16_t *frame_buffer; + 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/examples/breakout_roundlcd/demo.cpp b/examples/breakout_roundlcd/demo.cpp index 51fe8f1d6..103062e65 100644 --- a/examples/breakout_roundlcd/demo.cpp +++ b/examples/breakout_roundlcd/demo.cpp @@ -12,7 +12,7 @@ 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; diff --git a/libraries/breakout_colourlcd160x80/breakout_colourlcd160x80.cpp b/libraries/breakout_colourlcd160x80/breakout_colourlcd160x80.cpp index f64699026..c2f035d8a 100644 --- a/libraries/breakout_colourlcd160x80/breakout_colourlcd160x80.cpp +++ b/libraries/breakout_colourlcd160x80/breakout_colourlcd160x80.cpp @@ -13,7 +13,7 @@ namespace pimoroni { __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 7e628be7c..bf75a916f 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.hpp" namespace pimoroni { @@ -31,7 +32,7 @@ namespace pimoroni { 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); + 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 3cf1cad66..83427e72e 100644 --- a/libraries/breakout_colourlcd240x240/breakout_colourlcd240x240.cpp +++ b/libraries/breakout_colourlcd240x240/breakout_colourlcd240x240.cpp @@ -13,7 +13,7 @@ namespace pimoroni { __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 470b8d70b..16e5e7737 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.hpp" namespace pimoroni { @@ -31,7 +32,7 @@ namespace pimoroni { 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); + BreakoutColourLCD240x240(uint16_t *buf, BG_SPI_SLOT slot); //-------------------------------------------------- diff --git a/libraries/breakout_roundlcd/breakout_roundlcd.cpp b/libraries/breakout_roundlcd/breakout_roundlcd.cpp index 2e27134dd..49a639dae 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 9d0c07e02..24c82ed67 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/pico_explorer/pico_explorer.cpp b/libraries/pico_explorer/pico_explorer.cpp index 0d1606861..5c416a25c 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 0cee484c0..3c5217eec 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/modules/breakout_colourlcd160x80/breakout_colourlcd160x80.cpp b/micropython/modules/breakout_colourlcd160x80/breakout_colourlcd160x80.cpp index 967be3618..42bc4d6cc 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"); diff --git a/micropython/modules/breakout_colourlcd240x240/breakout_colourlcd240x240.cpp b/micropython/modules/breakout_colourlcd240x240/breakout_colourlcd240x240.cpp index 8927d5f70..642d9638f 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. diff --git a/micropython/modules/breakout_roundlcd/breakout_roundlcd.cpp b/micropython/modules/breakout_roundlcd/breakout_roundlcd.cpp index 624db96d6..901aa9dd1 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. From 42c7555c967343cc3dcfbd2566d316acc3e75a14 Mon Sep 17 00:00:00 2001 From: Phil Howard Date: Fri, 14 May 2021 18:12:37 +0100 Subject: [PATCH 02/10] Add common I2C class This change adds a common I2C class, gathering various I2C functions into a single point of responsibility. It's necessary for correctly managing the I2C bus pins and state across multiple devices. --- CMakeLists.txt | 1 + common/CMakeLists.txt | 9 ++ common/{pimoroni.hpp => pimoroni_common.hpp} | 5 + common/pimoroni_i2c.cpp | 77 +++++++++++++++ common/pimoroni_i2c.hpp | 66 +++++++++++++ drivers/as7262/as7262.cmake | 2 +- drivers/as7262/as7262.cpp | 19 ++-- drivers/as7262/as7262.hpp | 21 ++-- drivers/ioexpander/ioexpander.cmake | 2 +- drivers/ioexpander/ioexpander.cpp | 98 ++++++++----------- drivers/ioexpander/ioexpander.hpp | 8 +- drivers/is31fl3731/is31fl3731.cmake | 2 +- drivers/is31fl3731/is31fl3731.cpp | 44 +++------ drivers/is31fl3731/is31fl3731.hpp | 19 ++-- drivers/ltp305/ltp305.cmake | 2 +- drivers/ltp305/ltp305.cpp | 30 ++---- drivers/ltp305/ltp305.hpp | 16 ++- drivers/ltr559/ltr559.cmake | 2 +- drivers/ltr559/ltr559.cpp | 90 +++++------------ drivers/ltr559/ltr559.hpp | 38 ++++--- drivers/msa301/CMakeLists.txt | 11 +-- drivers/msa301/msa301.cmake | 2 +- drivers/msa301/msa301.cpp | 56 +++-------- drivers/msa301/msa301.hpp | 33 +++---- drivers/rv3028/rv3028.cmake | 2 +- drivers/rv3028/rv3028.cpp | 68 +++---------- drivers/rv3028/rv3028.hpp | 25 ++--- drivers/sgp30/sgp30.cmake | 2 +- drivers/sgp30/sgp30.cpp | 34 +++---- drivers/sgp30/sgp30.hpp | 25 +++-- drivers/st7735/st7735.hpp | 2 +- drivers/st7789/st7789.hpp | 2 +- examples/breakout_as7262/basic_demo.cpp | 4 +- .../breakout_as7262/explorer_bargraph.cpp | 4 +- .../breakout_dotmatrix/bargraph/bargraph.cpp | 3 +- examples/breakout_dotmatrix/eyes/eyes.cpp | 3 +- examples/breakout_dotmatrix/image/image.cpp | 3 +- examples/breakout_dotmatrix/timer/timer.cpp | 3 +- examples/breakout_encoder/demo.cpp | 4 +- examples/breakout_ltr559/demo.cpp | 3 +- examples/breakout_matrix11x7/demo.cpp | 3 +- examples/breakout_msa301/demo.cpp | 4 +- examples/breakout_potentiometer/demo.cpp | 4 +- examples/breakout_rgbmatrix5x5/demo.cpp | 3 +- examples/breakout_rtc/CMakeLists.txt | 2 +- examples/breakout_rtc/demo.cpp | 7 +- examples/breakout_sgp30/demo.cpp | 3 +- .../breakout_colourlcd160x80.hpp | 2 +- .../breakout_colourlcd240x240.hpp | 2 +- .../breakout_encoder/breakout_encoder.hpp | 4 + .../breakout_ltr559/breakout_ltr559.cmake | 2 +- .../breakout_matrix11x7.hpp | 10 +- .../breakout_msa301/breakout_msa301.cmake | 2 +- .../breakout_potentiometer.hpp | 3 + .../breakout_rgbmatrix5x5.hpp | 12 ++- libraries/breakout_sgp30/breakout_sgp30.cmake | 2 +- micropython/modules/micropython.cmake | 2 + .../modules/pimoroni_i2c/micropython.cmake | 17 ++++ 58 files changed, 484 insertions(+), 440 deletions(-) create mode 100644 common/CMakeLists.txt rename common/{pimoroni.hpp => pimoroni_common.hpp} (93%) create mode 100644 common/pimoroni_i2c.cpp create mode 100644 common/pimoroni_i2c.hpp create mode 100644 micropython/modules/pimoroni_i2c/micropython.cmake diff --git a/CMakeLists.txt b/CMakeLists.txt index f134b0eda..dc142c538 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -32,6 +32,7 @@ include_directories( ${CMAKE_CURRENT_LIST_DIR} ) +add_subdirectory(common) add_subdirectory(drivers) add_subdirectory(libraries) diff --git a/common/CMakeLists.txt b/common/CMakeLists.txt new file mode 100644 index 000000000..be65a2393 --- /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.hpp b/common/pimoroni_common.hpp similarity index 93% rename from common/pimoroni.hpp rename to common/pimoroni_common.hpp index 5c1db512a..30ccc2685 100644 --- a/common/pimoroni.hpp +++ b/common/pimoroni_common.hpp @@ -32,4 +32,9 @@ namespace pimoroni { 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 000000000..c4f2e724b --- /dev/null +++ b/common/pimoroni_i2c.cpp @@ -0,0 +1,77 @@ +#include "pimoroni_common.hpp" +#include "pimoroni_i2c.hpp" + +namespace pimoroni { + void I2C::init() { + i2c = ((sda / 2) & 0b1) ? i2c1 : i2c0; + + 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); + } + + /* 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, 1, 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); + } + + 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, 2, false); + return value; + } +} \ No newline at end of file diff --git a/common/pimoroni_i2c.hpp b/common/pimoroni_i2c.hpp new file mode 100644 index 000000000..28eb41576 --- /dev/null +++ b/common/pimoroni_i2c.hpp @@ -0,0 +1,66 @@ +#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; + + public: + I2C(BOARD board) { + 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) : sda(sda), scl(scl) { + init(); + } + + ~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); + int16_t reg_read_int16(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;} + private: + void init(); + }; +} \ No newline at end of file diff --git a/drivers/as7262/as7262.cmake b/drivers/as7262/as7262.cmake index 65591866a..f48a7a986 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 3309e104b..3ac188e92 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 d3151b513..d2e4a75ec 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 { @@ -70,12 +72,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; int8_t interrupt = DEFAULT_INT_PIN; @@ -83,10 +83,17 @@ namespace pimoroni { // Constructors/Destructor //-------------------------------------------------- public: - AS7262() {} - - 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 = new I2C(DEFAULT_SDA_PIN, DEFAULT_SCL_PIN); + }; + AS7262(uint8_t address) : address(address) { + i2c = new I2C(DEFAULT_SDA_PIN, DEFAULT_SCL_PIN); + }; + AS7262(i2c_inst_t *i2c_inst, uint8_t address, uint sda, uint scl, uint8_t interrupt = PIN_UNUSED) : address(address), interrupt(interrupt) { + i2c = new I2C(sda, scl); + } + AS7262(I2C *i2c, uint8_t address = DEFAULT_I2C_ADDRESS, uint8_t interrupt = PIN_UNUSED) : + i2c(i2c), address(address), interrupt(interrupt) {} //-------------------------------------------------- diff --git a/drivers/ioexpander/ioexpander.cmake b/drivers/ioexpander/ioexpander.cmake index dbd7a67cd..901290a18 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 e32d79bb1..14709f25f 100644 --- a/drivers/ioexpander/ioexpander.cpp +++ b/drivers/ioexpander/ioexpander.cpp @@ -298,15 +298,20 @@ namespace pimoroni { } IOExpander::IOExpander() : - IOExpander(i2c0, DEFAULT_I2C_ADDRESS, DEFAULT_SDA_PIN, DEFAULT_SCL_PIN, DEFAULT_INT_PIN) { - } + IOExpander(new I2C(DEFAULT_SDA_PIN, DEFAULT_SCL_PIN), DEFAULT_I2C_ADDRESS, DEFAULT_INT_PIN, timeout, debug) {}; 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(new I2C(DEFAULT_SDA_PIN, DEFAULT_SCL_PIN), address, DEFAULT_INT_PIN, timeout, debug) {}; + + IOExpander::IOExpander(uint8_t address, uint8_t sda, uint8_t scl, uint8_t interrupt, uint32_t timeout, bool debug) : + IOExpander(new I2C(sda, scl), address, interrupt, 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(new I2C(sda, scl), address, interrupt, timeout, debug) {}; + + IOExpander::IOExpander(I2C *i2c, uint8_t address, uint8_t 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 +328,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 +356,7 @@ namespace pimoroni { } i2c_inst_t* IOExpander::get_i2c() const { - return i2c; + return i2c->get_i2c(); } int IOExpander::get_address() const { @@ -364,11 +364,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 +376,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 +496,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 +504,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 +561,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 +572,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 +599,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 +617,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 +647,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 +666,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 +693,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 +726,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 +754,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 +768,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 +777,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 +794,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 +803,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 0d8d58aba..da0c790bb 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 { @@ -142,12 +144,10 @@ 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; uint32_t timeout; @@ -164,7 +164,9 @@ namespace pimoroni { public: IOExpander(); IOExpander(uint8_t address, uint32_t timeout = 1, bool debug = false); + IOExpander(uint8_t address, uint8_t sda, uint8_t scl, uint8_t interrupt = PIN_UNUSED, 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(I2C *i2c, uint8_t address=DEFAULT_I2C_ADDRESS, uint8_t interrupt = PIN_UNUSED, uint32_t timeout = 1, bool debug = false); //-------------------------------------------------- diff --git a/drivers/is31fl3731/is31fl3731.cmake b/drivers/is31fl3731/is31fl3731.cmake index c3c2b7b74..11c1b280e 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 e1c562365..be79b2615 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 ddccb94ba..34a6a2b0e 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 c8663029a..aa6779d85 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 45a03bee6..d0016daaf 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 c28082a31..f8a42eb9d 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(i2c_inst_t *i2c, uint8_t address, uint8_t sda, uint8_t 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 0debe482c..411e96af9 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 df7686f37..bc48897b3 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 4bca0e24a..7bc352b62 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; @@ -127,13 +129,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; + uint8_t address = DEFAULT_I2C_ADDRESS; + uint8_t interrupt = DEFAULT_INT_PIN; static pimoroni::lookup lookup_led_current; static pimoroni::lookup lookup_led_duty_cycle; @@ -148,14 +148,17 @@ namespace pimoroni { // Constructors/Destructor //-------------------------------------------------- public: - LTR559() {} - - 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 = new I2C(DEFAULT_SDA_PIN, DEFAULT_SCL_PIN); + }; + LTR559(uint8_t address) : address(address) { + i2c = new I2C(DEFAULT_SDA_PIN, DEFAULT_SCL_PIN); + }; + LTR559(i2c_inst_t *i2c_inst, uint8_t address, uint sda, uint scl, uint8_t interrupt = PIN_UNUSED) : address(address), interrupt(interrupt) { + i2c = new I2C(sda, scl); + } + LTR559(I2C *i2c, uint8_t address = DEFAULT_I2C_ADDRESS, uint8_t interrupt = PIN_UNUSED) : + i2c(i2c), address(address), interrupt(interrupt) {} //-------------------------------------------------- // Methods @@ -188,13 +191,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 85e325009..ff143a47e 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 f10aadc2f..8cb300f95 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 a190de515..2f30d8d13 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 eb03cecad..7200e5939 100644 --- a/drivers/msa301/msa301.hpp +++ b/drivers/msa301/msa301.hpp @@ -2,7 +2,8 @@ #include "hardware/i2c.h" #include "hardware/gpio.h" -#include "common/pimoroni.hpp" +#include "common/pimoroni_common.hpp" +#include "common/pimoroni_i2c.hpp" namespace pimoroni { @@ -107,24 +108,27 @@ 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; - uint sda = I2C_DEFAULT_SDA; - uint scl = I2C_DEFAULT_SCL; - uint interrupt = I2C_DEFAULT_INT; - i2c_inst_t *i2c = PIMORONI_I2C_DEFAULT_INSTANCE; - + uint8_t address = DEFAULT_I2C_ADDRESS; + uint interrupt = I2C_DEFAULT_INT; //-------------------------------------------------- // Constructors/Destructor //-------------------------------------------------- public: - MSA301() {} - - MSA301(i2c_inst_t *i2c, uint sda, uint scl, uint interrupt) : - i2c(i2c), sda(sda), scl(scl), interrupt(interrupt) {} + MSA301() { + i2c = new I2C(DEFAULT_SDA_PIN, DEFAULT_SCL_PIN); + }; + MSA301(uint8_t address) : address(address) { + i2c = new I2C(DEFAULT_SDA_PIN, DEFAULT_SCL_PIN); + }; + MSA301(i2c_inst_t *i2c_inst, uint8_t address, uint sda, uint scl, uint8_t interrupt = PIN_UNUSED) : address(address), interrupt(interrupt) { + i2c = new I2C(sda, scl); + } + MSA301(I2C *i2c, uint8_t address = DEFAULT_I2C_ADDRESS, uint interrupt = PIN_UNUSED) : + i2c(i2c), address(address), interrupt(interrupt) {} //-------------------------------------------------- @@ -154,11 +158,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 8a32686cb..bc3e0fad5 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 5e5e41b48..3dd1477c2 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 bc7c7f44e..2f452ae4c 100644 --- a/drivers/rv3028/rv3028.hpp +++ b/drivers/rv3028/rv3028.hpp @@ -12,7 +12,8 @@ Distributed as-is; no warranty is given. #include "hardware/i2c.h" #include "hardware/gpio.h" -#include "common/pimoroni.hpp" +#include "common/pimoroni_common.hpp" +#include "common/pimoroni_i2c.hpp" #include #include @@ -197,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; @@ -207,12 +206,10 @@ namespace pimoroni { // Variables //-------------------------------------------------- private: - i2c_inst_t *i2c = PIMORONI_I2C_DEFAULT_INSTANCE; + I2C *i2c; // interface pins with our standard defaults where appropriate int8_t address = DEFAULT_I2C_ADDRESS; - uint sda = DEFAULT_SDA_PIN; - uint scl = DEFAULT_SCL_PIN; uint interrupt = DEFAULT_INT_PIN; uint8_t times[TIME_ARRAY_LENGTH]; @@ -224,8 +221,13 @@ namespace pimoroni { public: RV3028() {} - 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(uint8_t address) : + address(address) {} + + RV3028(I2C *i2c, uint8_t address = DEFAULT_I2C_ADDRESS, uint interrupt = DEFAULT_INT_PIN) : + i2c(i2c), address(address), interrupt(interrupt) {} + + RV3028(i2c_inst_t *i2c, uint8_t address, uint8_t sda, uint8_t scl) : RV3028(new I2C(sda, scl), address) {} //-------------------------------------------------- @@ -325,13 +327,6 @@ namespace pimoroni { 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 e2d4f6b65..b7ad01af7 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 f785f8d48..3b029d69b 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 07c14addf..20c937a55 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 @@ -37,22 +39,29 @@ 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; //-------------------------------------------------- // Constructors/Destructor //-------------------------------------------------- public: - SGP30() {} - - SGP30(i2c_inst_t *i2c, uint8_t sda, uint8_t scl) : - i2c(i2c), sda(sda), scl(scl) {} - + SGP30() { + i2c = new I2C(DEFAULT_SDA_PIN, DEFAULT_SCL_PIN); + }; + SGP30(uint8_t address) : address(address) { + i2c = new I2C(DEFAULT_SDA_PIN, DEFAULT_SCL_PIN); + }; + SGP30(i2c_inst_t *i2c_inst, uint sda, uint scl) { + i2c = new I2C(sda, scl); + } + SGP30(i2c_inst_t *i2c_inst, uint8_t address, uint sda, uint scl) : address(address) { + i2c = new I2C(sda, scl); + } + SGP30(I2C *i2c, uint8_t address = DEFAULT_I2C_ADDRESS, uint interrupt = PIN_UNUSED) : + i2c(i2c), address(address) {} //-------------------------------------------------- // Methods diff --git a/drivers/st7735/st7735.hpp b/drivers/st7735/st7735.hpp index c3c7c832c..6b912eed3 100644 --- a/drivers/st7735/st7735.hpp +++ b/drivers/st7735/st7735.hpp @@ -2,7 +2,7 @@ #include "hardware/spi.h" #include "hardware/gpio.h" -#include "../../common/pimoroni.hpp" +#include "../../common/pimoroni_common.hpp" namespace pimoroni { diff --git a/drivers/st7789/st7789.hpp b/drivers/st7789/st7789.hpp index 029d739db..12019bd50 100644 --- a/drivers/st7789/st7789.hpp +++ b/drivers/st7789/st7789.hpp @@ -2,7 +2,7 @@ #include "hardware/spi.h" #include "hardware/gpio.h" -#include "../../common/pimoroni.hpp" +#include "../../common/pimoroni_common.hpp" namespace pimoroni { diff --git a/examples/breakout_as7262/basic_demo.cpp b/examples/breakout_as7262/basic_demo.cpp index 14287634c..9e777ce40 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 0df4063bc..189f624fe 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 a9c2783c1..819e3564a 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 f685ec75b..05bf455dc 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 cc6ceecd2..ed678cd8a 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 ffd8976b8..eb865de3d 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 ae57882f8..e07c44da9 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 diff --git a/examples/breakout_ltr559/demo.cpp b/examples/breakout_ltr559/demo.cpp index 5eeb9e8ac..6c6770ae8 100644 --- a/examples/breakout_ltr559/demo.cpp +++ b/examples/breakout_ltr559/demo.cpp @@ -5,7 +5,8 @@ using namespace pimoroni; -BreakoutLTR559 ltr559; +I2C i2c(4, 5); +BreakoutLTR559 ltr559(&i2c); int main() { stdio_init_all(); diff --git a/examples/breakout_matrix11x7/demo.cpp b/examples/breakout_matrix11x7/demo.cpp index ee2030631..80449bf2b 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 5af8cf243..4c14f7982 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 2892f3143..8dfebac88 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 diff --git a/examples/breakout_rgbmatrix5x5/demo.cpp b/examples/breakout_rgbmatrix5x5/demo.cpp index 0981b67f7..47c4e2e83 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_rtc/CMakeLists.txt b/examples/breakout_rtc/CMakeLists.txt index 70c13b2ed..4ec2b29a5 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 f8d8c1786..c0c3669d0 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 834daa1ee..825417dbe 100644 --- a/examples/breakout_sgp30/demo.cpp +++ b/examples/breakout_sgp30/demo.cpp @@ -13,7 +13,8 @@ using namespace pimoroni; -BreakoutSGP30 sgp30; +I2C i2c(BOARD::BREAKOUT_GARDEN); +BreakoutSGP30 sgp30(&i2c); int main() { uint8_t prd; diff --git a/libraries/breakout_colourlcd160x80/breakout_colourlcd160x80.hpp b/libraries/breakout_colourlcd160x80/breakout_colourlcd160x80.hpp index bf75a916f..f08c4e181 100644 --- a/libraries/breakout_colourlcd160x80/breakout_colourlcd160x80.hpp +++ b/libraries/breakout_colourlcd160x80/breakout_colourlcd160x80.hpp @@ -2,7 +2,7 @@ #include "drivers/st7735/st7735.hpp" #include "libraries/pico_graphics/pico_graphics.hpp" -#include "common/pimoroni.hpp" +#include "common/pimoroni_common.hpp" namespace pimoroni { diff --git a/libraries/breakout_colourlcd240x240/breakout_colourlcd240x240.hpp b/libraries/breakout_colourlcd240x240/breakout_colourlcd240x240.hpp index 16e5e7737..524db9e03 100644 --- a/libraries/breakout_colourlcd240x240/breakout_colourlcd240x240.hpp +++ b/libraries/breakout_colourlcd240x240/breakout_colourlcd240x240.hpp @@ -2,7 +2,7 @@ #include "drivers/st7789/st7789.hpp" #include "libraries/pico_graphics/pico_graphics.hpp" -#include "common/pimoroni.hpp" +#include "common/pimoroni_common.hpp" namespace pimoroni { diff --git a/libraries/breakout_encoder/breakout_encoder.hpp b/libraries/breakout_encoder/breakout_encoder.hpp index c1980f1b5..f925ba04f 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 { @@ -59,6 +60,9 @@ namespace pimoroni { BreakoutEncoder(uint8_t address) : ioe(address) {} + BreakoutEncoder(I2C *i2c, uint8_t address = DEFAULT_I2C_ADDRESS, uint8_t 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) {} diff --git a/libraries/breakout_ltr559/breakout_ltr559.cmake b/libraries/breakout_ltr559/breakout_ltr559.cmake index b21335f9e..a79c2830e 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 cef3d646d..75650ef4f 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_msa301/breakout_msa301.cmake b/libraries/breakout_msa301/breakout_msa301.cmake index 15f3acece..f7f24a6d6 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 470b3316c..0cc7eece0 100644 --- a/libraries/breakout_potentiometer/breakout_potentiometer.hpp +++ b/libraries/breakout_potentiometer/breakout_potentiometer.hpp @@ -57,6 +57,9 @@ namespace pimoroni { BreakoutPotentiometer(uint8_t address) : ioe(address) {} + BreakoutPotentiometer(I2C *i2c, uint8_t address = DEFAULT_I2C_ADDRESS, uint8_t 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) {} diff --git a/libraries/breakout_rgbmatrix5x5/breakout_rgbmatrix5x5.hpp b/libraries/breakout_rgbmatrix5x5/breakout_rgbmatrix5x5.hpp index e9b1e3be6..f7e7f816b 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_sgp30/breakout_sgp30.cmake b/libraries/breakout_sgp30/breakout_sgp30.cmake index 4f13e5f2a..874689d9c 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/micropython/modules/micropython.cmake b/micropython/modules/micropython.cmake index 9d54d435a..87705f3b6 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 000000000..761e92547 --- /dev/null +++ b/micropython/modules/pimoroni_i2c/micropython.cmake @@ -0,0 +1,17 @@ +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}/../../../common/pimoroni_i2c.cpp +) + +target_include_directories(usermod_${MOD_NAME} INTERFACE + ${CMAKE_CURRENT_LIST_DIR} +) + +target_compile_definitions(usermod_${MOD_NAME} INTERFACE + -DMODULE_${MOD_NAME_UPPER}_ENABLED=1 +) + +target_link_libraries(usermod INTERFACE usermod_${MOD_NAME}) \ No newline at end of file From 445737088f0dbb81110c901172f1dc5a0f02c91b Mon Sep 17 00:00:00 2001 From: Phil Howard Date: Mon, 17 May 2021 11:08:23 +0100 Subject: [PATCH 03/10] Switch drivers over to I2C class, tidy up common include Removes all driver-specific SDA/SCL pin definitions and defaults. Pin type is "uint" everywhere, but "PIN_UNUSED" is *int*_max for MicroPython compat. That's still a lot of pins! Adds baudrate to the I2C class, and allows a driver (like Trackball) to check the baudrate is supported --- common/pimoroni_common.hpp | 3 +- common/pimoroni_i2c.cpp | 32 +++++++--- common/pimoroni_i2c.hpp | 10 ++- drivers/as7262/as7262.hpp | 21 ++----- drivers/ioexpander/ioexpander.cpp | 10 +-- drivers/ioexpander/ioexpander.hpp | 8 +-- drivers/ltr559/ltr559.hpp | 20 ++---- drivers/msa301/msa301.hpp | 25 ++------ drivers/sgp30/sgp30.hpp | 21 ++----- drivers/trackball/trackball.cmake | 2 +- drivers/trackball/trackball.cpp | 63 +++++++------------ drivers/trackball/trackball.hpp | 27 +++----- drivers/vl53l1x/CMakeLists.txt | 2 +- drivers/vl53l1x/vl53l1x.cpp | 28 ++++----- drivers/vl53l1x/vl53l1x.hpp | 15 +++-- examples/breakout_ltr559/demo.cpp | 10 ++- examples/breakout_trackball/demo.cpp | 14 ++++- .../breakout_colourlcd160x80.cpp | 2 +- .../breakout_colourlcd160x80.hpp | 4 +- .../breakout_colourlcd240x240.cpp | 2 +- .../breakout_colourlcd240x240.hpp | 4 +- .../breakout_encoder/breakout_encoder.hpp | 6 +- .../breakout_as7262/breakout_as7262.cpp | 6 +- .../breakout_colourlcd160x80.cpp | 2 +- .../breakout_colourlcd240x240.cpp | 2 +- .../breakout_dotmatrix/breakout_dotmatrix.cpp | 4 +- .../breakout_encoder/breakout_encoder.cpp | 6 +- .../breakout_ioexpander.cpp | 6 +- .../breakout_ltr559/breakout_ltr559.cpp | 6 +- .../breakout_matrix11x7.cpp | 4 +- .../breakout_mics6814/breakout_mics6814.cpp | 6 +- .../breakout_msa301/breakout_msa301.cpp | 6 +- .../breakout_potentiometer.cpp | 6 +- .../breakout_rgbmatrix5x5.cpp | 4 +- .../breakout_roundlcd/breakout_roundlcd.cpp | 2 +- .../modules/breakout_rtc/breakout_rtc.cpp | 6 +- .../modules/breakout_sgp30/breakout_sgp30.cpp | 4 +- .../breakout_trackball/breakout_trackball.cpp | 6 +- 38 files changed, 180 insertions(+), 225 deletions(-) diff --git a/common/pimoroni_common.hpp b/common/pimoroni_common.hpp index 30ccc2685..9f372c11e 100644 --- a/common/pimoroni_common.hpp +++ b/common/pimoroni_common.hpp @@ -6,9 +6,10 @@ #define PIMORONI_SPI_DEFAULT_INSTANCE spi0 namespace pimoroni { - static const unsigned int PIN_UNUSED = UINT_MAX; + 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; diff --git a/common/pimoroni_i2c.cpp b/common/pimoroni_i2c.cpp index c4f2e724b..52fcda615 100644 --- a/common/pimoroni_i2c.cpp +++ b/common/pimoroni_i2c.cpp @@ -5,7 +5,7 @@ namespace pimoroni { void I2C::init() { i2c = ((sda / 2) & 0b1) ? i2c1 : i2c0; - i2c_init(i2c, 400000); + 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); @@ -29,7 +29,28 @@ namespace pimoroni { 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, 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; } @@ -67,11 +88,4 @@ namespace pimoroni { value &= ~(mask << shift); write_bytes(address, reg, &value, 1); } - - 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, 2, false); - return value; - } } \ No newline at end of file diff --git a/common/pimoroni_i2c.hpp b/common/pimoroni_i2c.hpp index 28eb41576..87146c8ef 100644 --- a/common/pimoroni_i2c.hpp +++ b/common/pimoroni_i2c.hpp @@ -13,9 +13,10 @@ namespace pimoroni { uint sda = I2C_DEFAULT_SDA; uint scl = I2C_DEFAULT_SCL; uint interrupt = PIN_UNUSED; + uint32_t baudrate = I2C_DEFAULT_BAUDRATE; public: - I2C(BOARD board) { + I2C(BOARD board, uint32_t baudrate = I2C_DEFAULT_BAUDRATE) : baudrate(baudrate) { switch(board) { case BREAKOUT_GARDEN: sda = I2C_BG_SDA; @@ -32,10 +33,12 @@ namespace pimoroni { init(); } - I2C(uint sda, uint scl) : sda(sda), scl(scl) { + 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); @@ -46,7 +49,9 @@ namespace pimoroni { 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); @@ -60,6 +65,7 @@ namespace pimoroni { 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(); }; diff --git a/drivers/as7262/as7262.hpp b/drivers/as7262/as7262.hpp index d2e4a75ec..5a46471e8 100644 --- a/drivers/as7262/as7262.hpp +++ b/drivers/as7262/as7262.hpp @@ -15,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; //-------------------------------------------------- @@ -76,24 +72,17 @@ namespace pimoroni { // interface pins with our standard defaults where appropriate int8_t address = DEFAULT_I2C_ADDRESS; - int8_t interrupt = DEFAULT_INT_PIN; + uint interrupt = PIN_UNUSED; //-------------------------------------------------- // Constructors/Destructor //-------------------------------------------------- public: - AS7262() { - i2c = new I2C(DEFAULT_SDA_PIN, DEFAULT_SCL_PIN); - }; - AS7262(uint8_t address) : address(address) { - i2c = new I2C(DEFAULT_SDA_PIN, DEFAULT_SCL_PIN); - }; - AS7262(i2c_inst_t *i2c_inst, uint8_t address, uint sda, uint scl, uint8_t interrupt = PIN_UNUSED) : address(address), interrupt(interrupt) { - i2c = new I2C(sda, scl); - } - AS7262(I2C *i2c, uint8_t address = DEFAULT_I2C_ADDRESS, uint8_t interrupt = PIN_UNUSED) : - i2c(i2c), address(address), interrupt(interrupt) {} + AS7262() : AS7262(DEFAULT_I2C_ADDRESS) {}; + AS7262(uint8_t address) : i2c(new I2C()), address(address) {}; + AS7262(i2c_inst_t *i2c_inst, uint8_t address, uint sda, uint scl, uint interrupt = PIN_UNUSED) : i2c(new I2C()), address(address), interrupt(interrupt) {} + AS7262(I2C *i2c, uint8_t address = DEFAULT_I2C_ADDRESS, uint interrupt = PIN_UNUSED) : i2c(i2c), address(address), interrupt(interrupt) {} //-------------------------------------------------- diff --git a/drivers/ioexpander/ioexpander.cpp b/drivers/ioexpander/ioexpander.cpp index 14709f25f..c1d7756a8 100644 --- a/drivers/ioexpander/ioexpander.cpp +++ b/drivers/ioexpander/ioexpander.cpp @@ -298,18 +298,18 @@ namespace pimoroni { } IOExpander::IOExpander() : - IOExpander(new I2C(DEFAULT_SDA_PIN, DEFAULT_SCL_PIN), DEFAULT_I2C_ADDRESS, DEFAULT_INT_PIN, timeout, debug) {}; + IOExpander(new I2C(), DEFAULT_I2C_ADDRESS, DEFAULT_INT_PIN, timeout, debug) {}; IOExpander::IOExpander(uint8_t address, uint32_t timeout, bool debug) : - IOExpander(new I2C(DEFAULT_SDA_PIN, DEFAULT_SCL_PIN), address, DEFAULT_INT_PIN, timeout, debug) {}; + IOExpander(new I2C(), address, DEFAULT_INT_PIN, timeout, debug) {}; - IOExpander::IOExpander(uint8_t address, uint8_t sda, uint8_t scl, uint8_t interrupt, uint32_t timeout, bool debug) : + IOExpander::IOExpander(uint8_t address, uint sda, uint scl, uint interrupt, uint32_t timeout, bool debug) : IOExpander(new I2C(sda, scl), address, interrupt, 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) : + IOExpander::IOExpander(i2c_inst_t *i2c, uint8_t address, uint sda, uint scl, uint interrupt, uint32_t timeout, bool debug) : IOExpander(new I2C(sda, scl), address, interrupt, timeout, debug) {}; - IOExpander::IOExpander(I2C *i2c, uint8_t address, uint8_t interrupt, uint32_t timeout, bool debug) : + 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), diff --git a/drivers/ioexpander/ioexpander.hpp b/drivers/ioexpander/ioexpander.hpp index da0c790bb..dfee4047a 100644 --- a/drivers/ioexpander/ioexpander.hpp +++ b/drivers/ioexpander/ioexpander.hpp @@ -148,7 +148,7 @@ namespace pimoroni { // interface pins with our standard defaults where appropriate int8_t address = DEFAULT_I2C_ADDRESS; - int8_t interrupt = DEFAULT_INT_PIN; + uint interrupt = DEFAULT_INT_PIN; uint32_t timeout; bool debug; @@ -164,9 +164,9 @@ namespace pimoroni { public: IOExpander(); IOExpander(uint8_t address, uint32_t timeout = 1, bool debug = false); - IOExpander(uint8_t address, uint8_t sda, uint8_t scl, uint8_t interrupt = PIN_UNUSED, 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(I2C *i2c, uint8_t address=DEFAULT_I2C_ADDRESS, uint8_t interrupt = PIN_UNUSED, uint32_t timeout = 1, bool debug = false); + IOExpander(uint8_t address, uint sda, uint scl, uint interrupt = PIN_UNUSED, uint32_t timeout = 1, bool debug = false); + IOExpander(i2c_inst_t *i2c, uint8_t address, uint sda, uint scl, uint interrupt = PIN_UNUSED, uint32_t timeout = 1, bool debug = false); + IOExpander(I2C *i2c, uint8_t address=DEFAULT_I2C_ADDRESS, uint interrupt = PIN_UNUSED, uint32_t timeout = 1, bool debug = false); //-------------------------------------------------- diff --git a/drivers/ltr559/ltr559.hpp b/drivers/ltr559/ltr559.hpp index 7bc352b62..f32fa7000 100644 --- a/drivers/ltr559/ltr559.hpp +++ b/drivers/ltr559/ltr559.hpp @@ -112,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}; @@ -133,7 +129,7 @@ namespace pimoroni { // interface pins with our standard defaults where appropriate uint8_t address = DEFAULT_I2C_ADDRESS; - uint8_t interrupt = DEFAULT_INT_PIN; + uint interrupt = PIN_UNUSED; static pimoroni::lookup lookup_led_current; static pimoroni::lookup lookup_led_duty_cycle; @@ -148,16 +144,10 @@ namespace pimoroni { // Constructors/Destructor //-------------------------------------------------- public: - LTR559() { - i2c = new I2C(DEFAULT_SDA_PIN, DEFAULT_SCL_PIN); - }; - LTR559(uint8_t address) : address(address) { - i2c = new I2C(DEFAULT_SDA_PIN, DEFAULT_SCL_PIN); - }; - LTR559(i2c_inst_t *i2c_inst, uint8_t address, uint sda, uint scl, uint8_t interrupt = PIN_UNUSED) : address(address), interrupt(interrupt) { - i2c = new I2C(sda, scl); - } - LTR559(I2C *i2c, uint8_t address = DEFAULT_I2C_ADDRESS, uint8_t interrupt = PIN_UNUSED) : + LTR559() : LTR559(DEFAULT_I2C_ADDRESS) {}; + LTR559(uint8_t address) : i2c(new I2C()), address(address) {}; + LTR559(i2c_inst_t *i2c_inst, uint8_t address, uint sda, uint scl, uint interrupt = PIN_UNUSED) : i2c(new I2C()), address(address), interrupt(interrupt) {} + LTR559(I2C *i2c, uint8_t address = DEFAULT_I2C_ADDRESS, uint interrupt = PIN_UNUSED) : i2c(i2c), address(address), interrupt(interrupt) {} //-------------------------------------------------- diff --git a/drivers/msa301/msa301.hpp b/drivers/msa301/msa301.hpp index 7200e5939..bab102e62 100644 --- a/drivers/msa301/msa301.hpp +++ b/drivers/msa301/msa301.hpp @@ -13,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; @@ -109,26 +105,17 @@ namespace pimoroni { //-------------------------------------------------- private: I2C *i2c; - - // interface pins with our standard defaults where appropriate - uint8_t address = DEFAULT_I2C_ADDRESS; - uint interrupt = I2C_DEFAULT_INT; + uint8_t address = DEFAULT_I2C_ADDRESS; + uint interrupt = PIN_UNUSED; //-------------------------------------------------- // Constructors/Destructor //-------------------------------------------------- public: - MSA301() { - i2c = new I2C(DEFAULT_SDA_PIN, DEFAULT_SCL_PIN); - }; - MSA301(uint8_t address) : address(address) { - i2c = new I2C(DEFAULT_SDA_PIN, DEFAULT_SCL_PIN); - }; - MSA301(i2c_inst_t *i2c_inst, uint8_t address, uint sda, uint scl, uint8_t interrupt = PIN_UNUSED) : address(address), interrupt(interrupt) { - i2c = new I2C(sda, scl); - } - MSA301(I2C *i2c, uint8_t address = DEFAULT_I2C_ADDRESS, uint interrupt = PIN_UNUSED) : - i2c(i2c), address(address), interrupt(interrupt) {} + MSA301() : MSA301(DEFAULT_I2C_ADDRESS) {}; + MSA301(uint8_t address) : i2c(new I2C()), address(address) {}; + MSA301(i2c_inst_t *i2c_inst, uint8_t address, uint sda, uint scl, uint interrupt = PIN_UNUSED) : i2c(new I2C(sda, scl)), address(address), interrupt(interrupt) {} + MSA301(I2C *i2c, uint8_t address = DEFAULT_I2C_ADDRESS, uint interrupt = PIN_UNUSED) : i2c(i2c), address(address), interrupt(interrupt) {} //-------------------------------------------------- diff --git a/drivers/sgp30/sgp30.hpp b/drivers/sgp30/sgp30.hpp index 20c937a55..08f9de916 100644 --- a/drivers/sgp30/sgp30.hpp +++ b/drivers/sgp30/sgp30.hpp @@ -18,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 *****/ @@ -48,20 +46,11 @@ namespace pimoroni { // Constructors/Destructor //-------------------------------------------------- public: - SGP30() { - i2c = new I2C(DEFAULT_SDA_PIN, DEFAULT_SCL_PIN); - }; - SGP30(uint8_t address) : address(address) { - i2c = new I2C(DEFAULT_SDA_PIN, DEFAULT_SCL_PIN); - }; - SGP30(i2c_inst_t *i2c_inst, uint sda, uint scl) { - i2c = new I2C(sda, scl); - } - SGP30(i2c_inst_t *i2c_inst, uint8_t address, uint sda, uint scl) : address(address) { - i2c = new I2C(sda, scl); - } - SGP30(I2C *i2c, uint8_t address = DEFAULT_I2C_ADDRESS, uint interrupt = PIN_UNUSED) : - i2c(i2c), address(address) {} + SGP30() : SGP30(DEFAULT_I2C_ADDRESS) {}; + SGP30(uint8_t address) : i2c(new I2C()), address(address) {}; + SGP30(i2c_inst_t *i2c_inst, uint sda, uint scl) : i2c(new I2C(sda, scl)) { } + SGP30(i2c_inst_t *i2c_inst, uint8_t address, uint sda, uint scl) : i2c(new I2C(sda, scl)) , address(address) {} + SGP30(I2C *i2c, uint8_t address = DEFAULT_I2C_ADDRESS, uint interrupt = PIN_UNUSED) : i2c(i2c), address(address) {} //-------------------------------------------------- // Methods diff --git a/drivers/trackball/trackball.cmake b/drivers/trackball/trackball.cmake index 97e545700..d5e13c89e 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 d806456f3..7551c3a6b 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 4e82e1c83..3defdef52 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,13 +48,10 @@ namespace pimoroni { // Constructors/Destructor //-------------------------------------------------- public: - Trackball() {}; - - 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() : Trackball(DEFAULT_I2C_ADDRESS) {}; + Trackball(uint8_t address) : i2c(new I2C()), address(address) {}; + Trackball(i2c_inst_t *i2c_inst, uint8_t address, uint sda, uint scl, uint interrupt = PIN_UNUSED, uint32_t timeout = DEFAULT_TIMEOUT) : i2c(new I2C(sda, scl)), address(address), interrupt(interrupt) {} + Trackball(I2C *i2c, uint8_t address = DEFAULT_I2C_ADDRESS, uint interrupt = PIN_UNUSED, uint32_t timeout = DEFAULT_TIMEOUT) : i2c(i2c), address(address), interrupt(interrupt) {} //-------------------------------------------------- @@ -88,9 +78,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 7d5060ad4..eff5eb253 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 a38c48334..d50be0ace 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) @@ -169,14 +163,14 @@ namespace pimoroni { 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); + i2c->write_blocking(address, 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); + i2c->write_blocking(address, buffer, 4, false); } // Write a 32-bit register @@ -184,7 +178,7 @@ namespace pimoroni { { 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); + i2c->write_blocking(address, buffer, 6, false); } // Read an 8-bit register @@ -193,8 +187,8 @@ namespace pimoroni { 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); + i2c->write_blocking(address, regbuf, 2, true); + i2c->read_blocking(address, buffer, 1, false); value = buffer[0]; return value; } @@ -206,8 +200,8 @@ namespace pimoroni { 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); + i2c->write_blocking(address, regbuf, 2, true); + i2c->read_blocking(address, buffer, 2, false); value= (buffer[0] << 8) + buffer[1]; return value; } @@ -219,8 +213,8 @@ namespace pimoroni { 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); + i2c->write_blocking(address, regbuf, 2, true); + i2c->read_blocking(address, buffer, 4, false); value= (buffer[0] << 24) + (buffer[1] << 16) + (buffer[2] << 8) + buffer[3]; return value; } @@ -580,8 +574,8 @@ namespace pimoroni { uint16_t reg = RESULT__RANGE_STATUS; uint8_t regbuf[2] = {(reg >> 8) & 0xFF, reg & 0xFF}; uint8_t buffer[17]; - i2c_write_blocking(i2c, address, regbuf, 2, true); - i2c_read_blocking(i2c, address, buffer, 17, false); + i2c->write_blocking(address, regbuf, 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 85231667e..d108bb0cb 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_ltr559/demo.cpp b/examples/breakout_ltr559/demo.cpp index 6c6770ae8..276f6690d 100644 --- a/examples/breakout_ltr559/demo.cpp +++ b/examples/breakout_ltr559/demo.cpp @@ -5,7 +5,7 @@ using namespace pimoroni; -I2C i2c(4, 5); +I2C i2c(BOARD::BREAKOUT_GARDEN); BreakoutLTR559 ltr559(&i2c); int main() { @@ -14,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_trackball/demo.cpp b/examples/breakout_trackball/demo.cpp index 2a1f7ed7b..2d08f62da 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/libraries/breakout_colourlcd160x80/breakout_colourlcd160x80.cpp b/libraries/breakout_colourlcd160x80/breakout_colourlcd160x80.cpp index c2f035d8a..bfa71ff4e 100644 --- a/libraries/breakout_colourlcd160x80/breakout_colourlcd160x80.cpp +++ b/libraries/breakout_colourlcd160x80/breakout_colourlcd160x80.cpp @@ -8,7 +8,7 @@ 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; } diff --git a/libraries/breakout_colourlcd160x80/breakout_colourlcd160x80.hpp b/libraries/breakout_colourlcd160x80/breakout_colourlcd160x80.hpp index f08c4e181..8db78425b 100644 --- a/libraries/breakout_colourlcd160x80/breakout_colourlcd160x80.hpp +++ b/libraries/breakout_colourlcd160x80/breakout_colourlcd160x80.hpp @@ -13,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 @@ -31,7 +29,7 @@ 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); + 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 83427e72e..6be2a5814 100644 --- a/libraries/breakout_colourlcd240x240/breakout_colourlcd240x240.cpp +++ b/libraries/breakout_colourlcd240x240/breakout_colourlcd240x240.cpp @@ -8,7 +8,7 @@ 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; } diff --git a/libraries/breakout_colourlcd240x240/breakout_colourlcd240x240.hpp b/libraries/breakout_colourlcd240x240/breakout_colourlcd240x240.hpp index 524db9e03..2b63e586a 100644 --- a/libraries/breakout_colourlcd240x240/breakout_colourlcd240x240.hpp +++ b/libraries/breakout_colourlcd240x240/breakout_colourlcd240x240.hpp @@ -13,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 @@ -31,7 +29,7 @@ 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); + 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 f925ba04f..f69cb676f 100644 --- a/libraries/breakout_encoder/breakout_encoder.hpp +++ b/libraries/breakout_encoder/breakout_encoder.hpp @@ -47,7 +47,7 @@ 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 //-------------------------------------------------- @@ -60,10 +60,10 @@ namespace pimoroni { BreakoutEncoder(uint8_t address) : ioe(address) {} - BreakoutEncoder(I2C *i2c, uint8_t address = DEFAULT_I2C_ADDRESS, uint8_t interrupt = PIN_UNUSED, uint32_t timeout = DEFAULT_TIMEOUT, bool debug = false) : + 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) : + BreakoutEncoder(i2c_inst_t *i2c, uint8_t address, uint8_t sda, uint8_t scl, uint interrupt = PIN_UNUSED, uint32_t timeout = DEFAULT_TIMEOUT) : ioe(i2c, address, sda, scl, interrupt, timeout), interrupt_pin(interrupt) {} diff --git a/micropython/modules/breakout_as7262/breakout_as7262.cpp b/micropython/modules/breakout_as7262/breakout_as7262.cpp index a0dd86216..c17ad413c 100644 --- a/micropython/modules/breakout_as7262/breakout_as7262.cpp +++ b/micropython/modules/breakout_as7262/breakout_as7262.cpp @@ -47,9 +47,9 @@ mp_obj_t BreakoutAS7262_make_new(const mp_obj_type_t *type, size_t n_args, size_ enum { ARG_i2c, ARG_sda, ARG_scl, 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_sda, MP_ARG_INT, {.u_int = I2C_DEFAULT_SDA} }, + { MP_QSTR_scl, MP_ARG_INT, {.u_int = I2C_DEFAULT_SCL} }, + { MP_QSTR_interrupt, MP_ARG_INT, {.u_int = PIN_UNUSED} }, }; // Parse args. diff --git a/micropython/modules/breakout_colourlcd160x80/breakout_colourlcd160x80.cpp b/micropython/modules/breakout_colourlcd160x80/breakout_colourlcd160x80.cpp index 42bc4d6cc..2d387c758 100644 --- a/micropython/modules/breakout_colourlcd160x80/breakout_colourlcd160x80.cpp +++ b/micropython/modules/breakout_colourlcd160x80/breakout_colourlcd160x80.cpp @@ -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 642d9638f..79aa909fe 100644 --- a/micropython/modules/breakout_colourlcd240x240/breakout_colourlcd240x240.cpp +++ b/micropython/modules/breakout_colourlcd240x240/breakout_colourlcd240x240.cpp @@ -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 f8205c378..09de89c39 100644 --- a/micropython/modules/breakout_dotmatrix/breakout_dotmatrix.cpp +++ b/micropython/modules/breakout_dotmatrix/breakout_dotmatrix.cpp @@ -51,8 +51,8 @@ mp_obj_t BreakoutDotMatrix_make_new(const mp_obj_type_t *type, size_t n_args, si static const mp_arg_t allowed_args[] = { { MP_QSTR_i2c, MP_ARG_INT, {.u_int = -1} }, { 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} }, + { MP_QSTR_sda, MP_ARG_INT, {.u_int = I2C_DEFAULT_SDA} }, + { MP_QSTR_scl, MP_ARG_INT, {.u_int = I2C_DEFAULT_SCL} }, }; // Parse args. diff --git a/micropython/modules/breakout_encoder/breakout_encoder.cpp b/micropython/modules/breakout_encoder/breakout_encoder.cpp index 8d30b1bc7..c111c3f6c 100644 --- a/micropython/modules/breakout_encoder/breakout_encoder.cpp +++ b/micropython/modules/breakout_encoder/breakout_encoder.cpp @@ -54,9 +54,9 @@ mp_obj_t BreakoutEncoder_make_new(const mp_obj_type_t *type, size_t n_args, size static const mp_arg_t allowed_args[] = { { MP_QSTR_i2c, MP_ARG_INT, {.u_int = -1} }, { 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_sda, MP_ARG_INT, {.u_int = I2C_DEFAULT_SDA} }, + { MP_QSTR_scl, MP_ARG_INT, {.u_int = I2C_DEFAULT_SCL} }, + { MP_QSTR_interrupt, MP_ARG_INT, {.u_int = PIN_UNUSED} }, }; // Parse args. diff --git a/micropython/modules/breakout_ioexpander/breakout_ioexpander.cpp b/micropython/modules/breakout_ioexpander/breakout_ioexpander.cpp index 272405be2..5f84e350f 100644 --- a/micropython/modules/breakout_ioexpander/breakout_ioexpander.cpp +++ b/micropython/modules/breakout_ioexpander/breakout_ioexpander.cpp @@ -54,9 +54,9 @@ mp_obj_t BreakoutIOExpander_make_new(const mp_obj_type_t *type, size_t n_args, s static const mp_arg_t allowed_args[] = { { MP_QSTR_i2c, MP_ARG_INT, {.u_int = -1} }, { 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_sda, MP_ARG_INT, {.u_int = I2C_DEFAULT_SDA} }, + { MP_QSTR_scl, MP_ARG_INT, {.u_int = I2C_DEFAULT_SCL} }, + { MP_QSTR_interrupt, MP_ARG_INT, {.u_int = PIN_UNUSED} }, }; // Parse args. diff --git a/micropython/modules/breakout_ltr559/breakout_ltr559.cpp b/micropython/modules/breakout_ltr559/breakout_ltr559.cpp index 645df5a16..1c10e0e22 100644 --- a/micropython/modules/breakout_ltr559/breakout_ltr559.cpp +++ b/micropython/modules/breakout_ltr559/breakout_ltr559.cpp @@ -54,9 +54,9 @@ mp_obj_t BreakoutLTR559_make_new(const mp_obj_type_t *type, size_t n_args, size_ 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_sda, MP_ARG_INT, {.u_int = I2C_DEFAULT_SDA} }, + { MP_QSTR_scl, MP_ARG_INT, {.u_int = I2C_DEFAULT_SCL} }, + { MP_QSTR_interrupt, MP_ARG_INT, {.u_int = -1} }, }; // Parse args. diff --git a/micropython/modules/breakout_matrix11x7/breakout_matrix11x7.cpp b/micropython/modules/breakout_matrix11x7/breakout_matrix11x7.cpp index 801f8bae0..5952fcdfd 100644 --- a/micropython/modules/breakout_matrix11x7/breakout_matrix11x7.cpp +++ b/micropython/modules/breakout_matrix11x7/breakout_matrix11x7.cpp @@ -51,8 +51,8 @@ mp_obj_t BreakoutMatrix11x7_make_new(const mp_obj_type_t *type, size_t n_args, s 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_sda, MP_ARG_INT, {.u_int = I2C_DEFAULT_SDA} }, + { MP_QSTR_scl, MP_ARG_INT, {.u_int = I2C_DEFAULT_SCL} }, }; // Parse args. diff --git a/micropython/modules/breakout_mics6814/breakout_mics6814.cpp b/micropython/modules/breakout_mics6814/breakout_mics6814.cpp index 5579c0162..0bd565f37 100644 --- a/micropython/modules/breakout_mics6814/breakout_mics6814.cpp +++ b/micropython/modules/breakout_mics6814/breakout_mics6814.cpp @@ -54,9 +54,9 @@ mp_obj_t BreakoutMICS6814_make_new(const mp_obj_type_t *type, size_t n_args, siz static const mp_arg_t allowed_args[] = { { MP_QSTR_i2c, MP_ARG_INT, {.u_int = -1} }, { 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_sda, MP_ARG_INT, {.u_int = I2C_DEFAULT_SDA} }, + { MP_QSTR_scl, MP_ARG_INT, {.u_int = I2C_DEFAULT_SCL} }, + { MP_QSTR_interrupt, MP_ARG_INT, {.u_int = PIN_UNUSED} }, }; // Parse args. diff --git a/micropython/modules/breakout_msa301/breakout_msa301.cpp b/micropython/modules/breakout_msa301/breakout_msa301.cpp index a59628ef7..bd1cea90a 100644 --- a/micropython/modules/breakout_msa301/breakout_msa301.cpp +++ b/micropython/modules/breakout_msa301/breakout_msa301.cpp @@ -47,9 +47,9 @@ mp_obj_t BreakoutMSA301_make_new(const mp_obj_type_t *type, size_t n_args, size_ enum { ARG_i2c, ARG_sda, ARG_scl, 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_sda, MP_ARG_INT, {.u_int = I2C_DEFAULT_SDA} }, + { MP_QSTR_scl, MP_ARG_INT, {.u_int = I2C_DEFAULT_SCL} }, + { MP_QSTR_interrupt, MP_ARG_INT, {.u_int = PIN_UNUSED} }, }; // Parse args. diff --git a/micropython/modules/breakout_potentiometer/breakout_potentiometer.cpp b/micropython/modules/breakout_potentiometer/breakout_potentiometer.cpp index 2812a1619..47aa71272 100644 --- a/micropython/modules/breakout_potentiometer/breakout_potentiometer.cpp +++ b/micropython/modules/breakout_potentiometer/breakout_potentiometer.cpp @@ -54,9 +54,9 @@ mp_obj_t BreakoutPotentiometer_make_new(const mp_obj_type_t *type, size_t n_args static const mp_arg_t allowed_args[] = { { MP_QSTR_i2c, MP_ARG_INT, {.u_int = -1} }, { 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_sda, MP_ARG_INT, {.u_int = I2C_DEFAULT_SDA} }, + { MP_QSTR_scl, MP_ARG_INT, {.u_int = I2C_DEFAULT_SCL} }, + { MP_QSTR_interrupt, MP_ARG_INT, {.u_int = PIN_UNUSED} }, }; // Parse args. diff --git a/micropython/modules/breakout_rgbmatrix5x5/breakout_rgbmatrix5x5.cpp b/micropython/modules/breakout_rgbmatrix5x5/breakout_rgbmatrix5x5.cpp index 3057e5071..3e4859a9f 100644 --- a/micropython/modules/breakout_rgbmatrix5x5/breakout_rgbmatrix5x5.cpp +++ b/micropython/modules/breakout_rgbmatrix5x5/breakout_rgbmatrix5x5.cpp @@ -51,8 +51,8 @@ mp_obj_t BreakoutRGBMatrix5x5_make_new(const mp_obj_type_t *type, size_t n_args, 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_sda, MP_ARG_INT, {.u_int = I2C_DEFAULT_SDA} }, + { MP_QSTR_scl, MP_ARG_INT, {.u_int = I2C_DEFAULT_SCL} }, }; // Parse args. diff --git a/micropython/modules/breakout_roundlcd/breakout_roundlcd.cpp b/micropython/modules/breakout_roundlcd/breakout_roundlcd.cpp index 901aa9dd1..3f970b375 100644 --- a/micropython/modules/breakout_roundlcd/breakout_roundlcd.cpp +++ b/micropython/modules/breakout_roundlcd/breakout_roundlcd.cpp @@ -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 d36df64d8..7ab6793db 100644 --- a/micropython/modules/breakout_rtc/breakout_rtc.cpp +++ b/micropython/modules/breakout_rtc/breakout_rtc.cpp @@ -50,9 +50,9 @@ mp_obj_t BreakoutRTC_make_new(const mp_obj_type_t *type, size_t n_args, size_t n enum { ARG_i2c, ARG_sda, ARG_scl, 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_sda, MP_ARG_INT, {.u_int = I2C_DEFAULT_SDA} }, + { MP_QSTR_scl, MP_ARG_INT, {.u_int = I2C_DEFAULT_SCL} }, + { MP_QSTR_interrupt, MP_ARG_INT, {.u_int = PIN_UNUSED} }, }; // Parse args. diff --git a/micropython/modules/breakout_sgp30/breakout_sgp30.cpp b/micropython/modules/breakout_sgp30/breakout_sgp30.cpp index 7812b4a1d..10c6a42df 100644 --- a/micropython/modules/breakout_sgp30/breakout_sgp30.cpp +++ b/micropython/modules/breakout_sgp30/breakout_sgp30.cpp @@ -44,8 +44,8 @@ mp_obj_t BreakoutSGP30_make_new(const mp_obj_type_t *type, size_t n_args, size_t enum { ARG_i2c, ARG_sda, ARG_scl }; 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_sda, MP_ARG_INT, {.u_int = I2C_DEFAULT_SDA} }, + { MP_QSTR_scl, MP_ARG_INT, {.u_int = I2C_DEFAULT_SCL} }, }; // Parse args. diff --git a/micropython/modules/breakout_trackball/breakout_trackball.cpp b/micropython/modules/breakout_trackball/breakout_trackball.cpp index 81b23f3c4..660c9630a 100644 --- a/micropython/modules/breakout_trackball/breakout_trackball.cpp +++ b/micropython/modules/breakout_trackball/breakout_trackball.cpp @@ -54,9 +54,9 @@ mp_obj_t BreakoutTrackball_make_new(const mp_obj_type_t *type, size_t n_args, si static const mp_arg_t allowed_args[] = { { MP_QSTR_i2c, MP_ARG_INT, {.u_int = -1} }, { 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_sda, MP_ARG_INT, {.u_int = I2C_DEFAULT_SDA} }, + { MP_QSTR_scl, MP_ARG_INT, {.u_int = I2C_DEFAULT_SCL} }, + { MP_QSTR_interrupt, MP_ARG_INT, {.u_int = PIN_UNUSED} }, }; // Parse args. From 77839e2a6ad59d513d84b13a9333cbcf8bc67276 Mon Sep 17 00:00:00 2001 From: Phil Howard Date: Mon, 17 May 2021 14:50:49 +0100 Subject: [PATCH 04/10] Tidy up constructors, drop unused variables, const single addr Removes i2c_inst_t from constructors since it's ignored, and updated the Python bindings not to supply this argument. Instance is inferred from the supplied pins. --- drivers/as7262/as7262.hpp | 10 ++++++---- drivers/ioexpander/ioexpander.cpp | 12 ----------- drivers/ioexpander/ioexpander.hpp | 20 ++++++++++--------- drivers/ltp305/ltp305.hpp | 2 +- drivers/ltr559/ltr559.hpp | 15 +++++++------- drivers/msa301/msa301.hpp | 14 +++++++------ drivers/rv3028/rv3028.hpp | 14 ++++++------- drivers/sgp30/sgp30.hpp | 11 +++++----- drivers/trackball/trackball.hpp | 7 ++++--- .../breakout_encoder/breakout_encoder.hpp | 11 +++------- .../breakout_mics6814/breakout_mics6814.hpp | 13 +++++------- .../breakout_potentiometer.hpp | 13 ++++-------- micropython/examples/breakout_rtc/demo.py | 12 +++++++---- micropython/examples/breakout_sgp30/demo.py | 4 +++- .../breakout_as7262/breakout_as7262.cpp | 3 +-- .../breakout_dotmatrix/breakout_dotmatrix.cpp | 3 +-- .../breakout_encoder/breakout_encoder.cpp | 3 +-- .../breakout_ioexpander.cpp | 3 +-- .../breakout_ltr559/breakout_ltr559.cpp | 8 +++----- .../breakout_mics6814/breakout_mics6814.cpp | 3 +-- .../breakout_potentiometer.cpp | 3 +-- 21 files changed, 82 insertions(+), 102 deletions(-) diff --git a/drivers/as7262/as7262.hpp b/drivers/as7262/as7262.hpp index 5a46471e8..eea68decf 100644 --- a/drivers/as7262/as7262.hpp +++ b/drivers/as7262/as7262.hpp @@ -72,18 +72,20 @@ namespace pimoroni { // interface pins with our standard defaults where appropriate int8_t address = DEFAULT_I2C_ADDRESS; - uint interrupt = PIN_UNUSED; + uint interrupt = PIN_UNUSED; //-------------------------------------------------- // Constructors/Destructor //-------------------------------------------------- public: - AS7262() : AS7262(DEFAULT_I2C_ADDRESS) {}; - AS7262(uint8_t address) : i2c(new I2C()), address(address) {}; - AS7262(i2c_inst_t *i2c_inst, uint8_t address, uint sda, uint scl, uint interrupt = PIN_UNUSED) : i2c(new I2C()), address(address), interrupt(interrupt) {} + AS7262(uint8_t address = DEFAULT_I2C_ADDRESS, uint interrupt = PIN_UNUSED) : AS7262(new I2C(), address, interrupt) {}; + AS7262(I2C *i2c, uint8_t address = DEFAULT_I2C_ADDRESS, uint interrupt = PIN_UNUSED) : i2c(i2c), address(address), interrupt(interrupt) {} + // TODO remove MicroPython-binding compatibility constructors + AS7262(uint8_t address, uint sda, uint scl, uint interrupt = PIN_UNUSED) : AS7262(new I2C(), address, interrupt) {} + //-------------------------------------------------- // Methods diff --git a/drivers/ioexpander/ioexpander.cpp b/drivers/ioexpander/ioexpander.cpp index c1d7756a8..265f4dc78 100644 --- a/drivers/ioexpander/ioexpander.cpp +++ b/drivers/ioexpander/ioexpander.cpp @@ -297,18 +297,6 @@ namespace pimoroni { this->mode = mode; } - IOExpander::IOExpander() : - IOExpander(new I2C(), DEFAULT_I2C_ADDRESS, DEFAULT_INT_PIN, timeout, debug) {}; - - IOExpander::IOExpander(uint8_t address, uint32_t timeout, bool debug) : - IOExpander(new I2C(), address, DEFAULT_INT_PIN, timeout, debug) {}; - - IOExpander::IOExpander(uint8_t address, uint sda, uint scl, uint interrupt, uint32_t timeout, bool debug) : - IOExpander(new I2C(sda, scl), address, interrupt, timeout, debug) {}; - - IOExpander::IOExpander(i2c_inst_t *i2c, uint8_t address, uint sda, uint scl, uint interrupt, uint32_t timeout, bool debug) : - IOExpander(new I2C(sda, scl), address, interrupt, timeout, debug) {}; - IOExpander::IOExpander(I2C *i2c, uint8_t address, uint interrupt, uint32_t timeout, bool debug) : i2c(i2c), address(address), interrupt(interrupt), diff --git a/drivers/ioexpander/ioexpander.hpp b/drivers/ioexpander/ioexpander.hpp index dfee4047a..66138c0ca 100644 --- a/drivers/ioexpander/ioexpander.hpp +++ b/drivers/ioexpander/ioexpander.hpp @@ -28,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; @@ -148,7 +144,7 @@ namespace pimoroni { // interface pins with our standard defaults where appropriate int8_t address = DEFAULT_I2C_ADDRESS; - uint interrupt = DEFAULT_INT_PIN; + uint interrupt = PIN_UNUSED; uint32_t timeout; bool debug; @@ -162,10 +158,16 @@ namespace pimoroni { // Constructors/Destructor //-------------------------------------------------- public: - IOExpander(); - IOExpander(uint8_t address, uint32_t timeout = 1, bool debug = false); - IOExpander(uint8_t address, uint sda, uint scl, uint interrupt = PIN_UNUSED, uint32_t timeout = 1, bool debug = false); - IOExpander(i2c_inst_t *i2c, uint8_t address, uint sda, uint scl, uint 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/ltp305/ltp305.hpp b/drivers/ltp305/ltp305.hpp index f8a42eb9d..f22197950 100644 --- a/drivers/ltp305/ltp305.hpp +++ b/drivers/ltp305/ltp305.hpp @@ -91,7 +91,7 @@ namespace pimoroni { LTP305(I2C *i2c, uint8_t address = DEFAULT_I2C_ADDRESS) : i2c(i2c), address(address) {} - LTP305(i2c_inst_t *i2c, uint8_t address, uint8_t sda, uint8_t scl) : LTP305(new I2C(sda, scl), address) {} + LTP305(uint8_t address, uint sda, uint scl) : LTP305(new I2C(sda, scl), address) {} //-------------------------------------------------- diff --git a/drivers/ltr559/ltr559.hpp b/drivers/ltr559/ltr559.hpp index f32fa7000..7c2cacc93 100644 --- a/drivers/ltr559/ltr559.hpp +++ b/drivers/ltr559/ltr559.hpp @@ -128,8 +128,8 @@ namespace pimoroni { I2C *i2c; // interface pins with our standard defaults where appropriate - uint8_t address = DEFAULT_I2C_ADDRESS; - uint interrupt = PIN_UNUSED; + const uint8_t address = DEFAULT_I2C_ADDRESS; + uint interrupt = PIN_UNUSED; static pimoroni::lookup lookup_led_current; static pimoroni::lookup lookup_led_duty_cycle; @@ -144,11 +144,12 @@ namespace pimoroni { // Constructors/Destructor //-------------------------------------------------- public: - LTR559() : LTR559(DEFAULT_I2C_ADDRESS) {}; - LTR559(uint8_t address) : i2c(new I2C()), address(address) {}; - LTR559(i2c_inst_t *i2c_inst, uint8_t address, uint sda, uint scl, uint interrupt = PIN_UNUSED) : i2c(new I2C()), address(address), interrupt(interrupt) {} - LTR559(I2C *i2c, uint8_t address = DEFAULT_I2C_ADDRESS, uint interrupt = PIN_UNUSED) : - i2c(i2c), address(address), interrupt(interrupt) {} + LTR559() : LTR559(new I2C()) {}; + + 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 diff --git a/drivers/msa301/msa301.hpp b/drivers/msa301/msa301.hpp index bab102e62..5d43088c1 100644 --- a/drivers/msa301/msa301.hpp +++ b/drivers/msa301/msa301.hpp @@ -105,17 +105,19 @@ namespace pimoroni { //-------------------------------------------------- private: I2C *i2c; - uint8_t address = DEFAULT_I2C_ADDRESS; - uint interrupt = PIN_UNUSED; + const uint8_t address = DEFAULT_I2C_ADDRESS; + uint interrupt = PIN_UNUSED; //-------------------------------------------------- // Constructors/Destructor //-------------------------------------------------- public: - MSA301() : MSA301(DEFAULT_I2C_ADDRESS) {}; - MSA301(uint8_t address) : i2c(new I2C()), address(address) {}; - MSA301(i2c_inst_t *i2c_inst, uint8_t address, uint sda, uint scl, uint interrupt = PIN_UNUSED) : i2c(new I2C(sda, scl)), address(address), interrupt(interrupt) {} - MSA301(I2C *i2c, uint8_t address = DEFAULT_I2C_ADDRESS, uint interrupt = PIN_UNUSED) : i2c(i2c), address(address), interrupt(interrupt) {} + MSA301() : MSA301(new I2C()) {}; + + 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) {} //-------------------------------------------------- diff --git a/drivers/rv3028/rv3028.hpp b/drivers/rv3028/rv3028.hpp index 2f452ae4c..ba66c2d3a 100644 --- a/drivers/rv3028/rv3028.hpp +++ b/drivers/rv3028/rv3028.hpp @@ -209,7 +209,7 @@ namespace pimoroni { I2C *i2c; // interface pins with our standard defaults where appropriate - int8_t address = DEFAULT_I2C_ADDRESS; + const int8_t address = DEFAULT_I2C_ADDRESS; uint interrupt = DEFAULT_INT_PIN; uint8_t times[TIME_ARRAY_LENGTH]; @@ -219,15 +219,13 @@ namespace pimoroni { // Constructors/Destructor //-------------------------------------------------- public: - RV3028() {} + RV3028() : RV3028(new I2C()) {} - RV3028(uint8_t address) : - address(address) {} + RV3028(I2C *i2c, uint interrupt = DEFAULT_INT_PIN) : + i2c(i2c), interrupt(interrupt) {} - RV3028(I2C *i2c, uint8_t address = DEFAULT_I2C_ADDRESS, uint interrupt = DEFAULT_INT_PIN) : - i2c(i2c), address(address), interrupt(interrupt) {} - - RV3028(i2c_inst_t *i2c, uint8_t address, uint8_t sda, uint8_t scl) : RV3028(new I2C(sda, scl), address) {} + // 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) {} //-------------------------------------------------- diff --git a/drivers/sgp30/sgp30.hpp b/drivers/sgp30/sgp30.hpp index 08f9de916..c027de5db 100644 --- a/drivers/sgp30/sgp30.hpp +++ b/drivers/sgp30/sgp30.hpp @@ -39,18 +39,19 @@ namespace pimoroni { private: I2C *i2c; - int8_t address = DEFAULT_I2C_ADDRESS; + const int8_t address = DEFAULT_I2C_ADDRESS; //-------------------------------------------------- // Constructors/Destructor //-------------------------------------------------- public: - SGP30() : SGP30(DEFAULT_I2C_ADDRESS) {}; - SGP30(uint8_t address) : i2c(new I2C()), address(address) {}; + SGP30() : SGP30(new I2C()) {}; + + 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)) { } - SGP30(i2c_inst_t *i2c_inst, uint8_t address, uint sda, uint scl) : i2c(new I2C(sda, scl)) , address(address) {} - SGP30(I2C *i2c, uint8_t address = DEFAULT_I2C_ADDRESS, uint interrupt = PIN_UNUSED) : i2c(i2c), address(address) {} //-------------------------------------------------- // Methods diff --git a/drivers/trackball/trackball.hpp b/drivers/trackball/trackball.hpp index 3defdef52..d5d6f0391 100644 --- a/drivers/trackball/trackball.hpp +++ b/drivers/trackball/trackball.hpp @@ -48,11 +48,12 @@ namespace pimoroni { // Constructors/Destructor //-------------------------------------------------- public: - Trackball() : Trackball(DEFAULT_I2C_ADDRESS) {}; - Trackball(uint8_t address) : i2c(new I2C()), address(address) {}; - Trackball(i2c_inst_t *i2c_inst, uint8_t address, uint sda, uint scl, uint interrupt = PIN_UNUSED, uint32_t timeout = DEFAULT_TIMEOUT) : i2c(new I2C(sda, scl)), address(address), interrupt(interrupt) {} + Trackball(uint8_t address = DEFAULT_I2C_ADDRESS) : i2c(new I2C()), address(address) {}; + 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 diff --git a/libraries/breakout_encoder/breakout_encoder.hpp b/libraries/breakout_encoder/breakout_encoder.hpp index f69cb676f..6eeae4f3a 100644 --- a/libraries/breakout_encoder/breakout_encoder.hpp +++ b/libraries/breakout_encoder/breakout_encoder.hpp @@ -54,18 +54,13 @@ namespace pimoroni { // Constructors/Destructor //-------------------------------------------------- public: - BreakoutEncoder() : - ioe(DEFAULT_I2C_ADDRESS) {} - - BreakoutEncoder(uint8_t address) : - ioe(address) {} + BreakoutEncoder(uint8_t address = DEFAULT_I2C_ADDRESS) : BreakoutEncoder(new I2C(), 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, uint 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_mics6814/breakout_mics6814.hpp b/libraries/breakout_mics6814/breakout_mics6814.hpp index eee7f2dd8..2b03a7de2 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_potentiometer/breakout_potentiometer.hpp b/libraries/breakout_potentiometer/breakout_potentiometer.hpp index 0cc7eece0..7d149cebb 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,17 +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, uint8_t interrupt = PIN_UNUSED, uint32_t timeout = DEFAULT_TIMEOUT, bool debug = false) : + 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/micropython/examples/breakout_rtc/demo.py b/micropython/examples/breakout_rtc/demo.py index e0bf227d4..a1c19fa3f 100644 --- a/micropython/examples/breakout_rtc/demo.py +++ b/micropython/examples/breakout_rtc/demo.py @@ -1,6 +1,8 @@ from breakout_rtc import BreakoutRTC +import time -rtc = BreakoutRTC() +# rtc = BreakoutRTC(sda=4, scl=5) # i2c pins 4, 5 for Breakout Garden +rtc = BreakoutRTC() # Default i2c pins for Pico Explorer if rtc.is_12_hour(): rtc.set_24_hour() @@ -12,6 +14,8 @@ 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 cf5300e87..4894b1674 100644 --- a/micropython/examples/breakout_sgp30/demo.py +++ b/micropython/examples/breakout_sgp30/demo.py @@ -1,7 +1,9 @@ import time from breakout_sgp30 import BreakoutSGP30 -sgp30 = BreakoutSGP30() +# sgp30 = BreakoutSGP30(sda=4, scl=5) # i2c pins 4, 5 for Breakout Garden +sgp30 = BreakoutSGP30() # Default i2c pins for Pico Explorer + print("SGP30 initialised - about to start measuring without waiting") sgp30.start_measurement(False) diff --git a/micropython/modules/breakout_as7262/breakout_as7262.cpp b/micropython/modules/breakout_as7262/breakout_as7262.cpp index c17ad413c..62dd291be 100644 --- a/micropython/modules/breakout_as7262/breakout_as7262.cpp +++ b/micropython/modules/breakout_as7262/breakout_as7262.cpp @@ -79,8 +79,7 @@ mp_obj_t BreakoutAS7262_make_new(const mp_obj_type_t *type, size_t n_args, size_ 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(sda, scl, args[ARG_int].u_int); if(!self->breakout->init()) { mp_raise_msg(&mp_type_RuntimeError, "AS7262 breakout not found when initialising"); diff --git a/micropython/modules/breakout_dotmatrix/breakout_dotmatrix.cpp b/micropython/modules/breakout_dotmatrix/breakout_dotmatrix.cpp index 09de89c39..6a66a7f61 100644 --- a/micropython/modules/breakout_dotmatrix/breakout_dotmatrix.cpp +++ b/micropython/modules/breakout_dotmatrix/breakout_dotmatrix.cpp @@ -82,8 +82,7 @@ mp_obj_t BreakoutDotMatrix_make_new(const mp_obj_type_t *type, size_t n_args, si 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(args[ARG_address].u_int, sda, scl); 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 c111c3f6c..3c01d8315 100644 --- a/micropython/modules/breakout_encoder/breakout_encoder.cpp +++ b/micropython/modules/breakout_encoder/breakout_encoder.cpp @@ -86,8 +86,7 @@ mp_obj_t BreakoutEncoder_make_new(const mp_obj_type_t *type, size_t n_args, size 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(args[ARG_address].u_int, sda, scl, args[ARG_interrupt].u_int); if(!self->breakout->init()) { mp_raise_msg(&mp_type_RuntimeError, "Encoder breakout not found when initialising"); diff --git a/micropython/modules/breakout_ioexpander/breakout_ioexpander.cpp b/micropython/modules/breakout_ioexpander/breakout_ioexpander.cpp index 5f84e350f..6ae34a679 100644 --- a/micropython/modules/breakout_ioexpander/breakout_ioexpander.cpp +++ b/micropython/modules/breakout_ioexpander/breakout_ioexpander.cpp @@ -86,8 +86,7 @@ mp_obj_t BreakoutIOExpander_make_new(const mp_obj_type_t *type, size_t n_args, s 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(args[ARG_address].u_int, sda, scl, args[ARG_interrupt].u_int); if(!self->breakout->init()) { mp_raise_msg(&mp_type_RuntimeError, "IOExpander breakout not found when initialising"); diff --git a/micropython/modules/breakout_ltr559/breakout_ltr559.cpp b/micropython/modules/breakout_ltr559/breakout_ltr559.cpp index 1c10e0e22..7d3661c47 100644 --- a/micropython/modules/breakout_ltr559/breakout_ltr559.cpp +++ b/micropython/modules/breakout_ltr559/breakout_ltr559.cpp @@ -50,10 +50,9 @@ 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_sda, ARG_scl, 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 = I2C_DEFAULT_SDA} }, { MP_QSTR_scl, MP_ARG_INT, {.u_int = I2C_DEFAULT_SCL} }, { MP_QSTR_interrupt, MP_ARG_INT, {.u_int = -1} }, @@ -85,9 +84,8 @@ mp_obj_t BreakoutLTR559_make_new(const mp_obj_type_t *type, size_t n_args, size_ 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(sda, scl, args[ARG_interrupt].u_int); if(!self->breakout->init()) { mp_raise_msg(&mp_type_RuntimeError, "LTR559 breakout not found when initialising"); diff --git a/micropython/modules/breakout_mics6814/breakout_mics6814.cpp b/micropython/modules/breakout_mics6814/breakout_mics6814.cpp index 0bd565f37..d8b471410 100644 --- a/micropython/modules/breakout_mics6814/breakout_mics6814.cpp +++ b/micropython/modules/breakout_mics6814/breakout_mics6814.cpp @@ -86,8 +86,7 @@ mp_obj_t BreakoutMICS6814_make_new(const mp_obj_type_t *type, size_t n_args, siz 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(args[ARG_address].u_int, sda, scl, args[ARG_interrupt].u_int); if(!self->breakout->init()) { mp_raise_msg(&mp_type_RuntimeError, "MICS6814 breakout not found when initialising"); diff --git a/micropython/modules/breakout_potentiometer/breakout_potentiometer.cpp b/micropython/modules/breakout_potentiometer/breakout_potentiometer.cpp index 47aa71272..f26203619 100644 --- a/micropython/modules/breakout_potentiometer/breakout_potentiometer.cpp +++ b/micropython/modules/breakout_potentiometer/breakout_potentiometer.cpp @@ -86,8 +86,7 @@ mp_obj_t BreakoutPotentiometer_make_new(const mp_obj_type_t *type, size_t n_args 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(args[ARG_address].u_int, sda, scl, args[ARG_interrupt].u_int); if(!self->breakout->init()) { mp_raise_msg(&mp_type_RuntimeError, "Potentiometer breakout not found when initialising"); From 3e56dfb14c86ee1f77dec212538703742c8cb16a Mon Sep 17 00:00:00 2001 From: Phil Howard Date: Mon, 17 May 2021 16:05:09 +0100 Subject: [PATCH 05/10] Remove unecessary manual conversion to byte arrays --- drivers/vl53l1x/vl53l1x.cpp | 55 +++++++++++++++++++------------------ 1 file changed, 28 insertions(+), 27 deletions(-) diff --git a/drivers/vl53l1x/vl53l1x.cpp b/drivers/vl53l1x/vl53l1x.cpp index d50be0ace..059b406c2 100644 --- a/drivers/vl53l1x/vl53l1x.cpp +++ b/drivers/vl53l1x/vl53l1x.cpp @@ -162,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(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(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(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(address, regbuf, 2, true); - i2c->read_blocking(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(address, regbuf, 2, true); - i2c->read_blocking(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(address, regbuf, 2, true); - i2c->read_blocking(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 @@ -572,9 +573,9 @@ 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(address, regbuf, 2, true); + i2c->write_blocking(address, (uint8_t *)®, 2, true); i2c->read_blocking(address, buffer, 17, false); results.range_status = buffer[0]; From 7fa9e5bdcadd3c6e12e276716fc08731be0e9003 Mon Sep 17 00:00:00 2001 From: Phil Howard Date: Mon, 17 May 2021 16:20:42 +0100 Subject: [PATCH 06/10] Enable -Werror -Wall and fix all the things Since MicroPython builds under stricter conditions, this change should help minimise pitfalls when writing/binding drivers. --- CMakeLists.txt | 2 ++ examples/breakout_encoder/demo.cpp | 2 +- examples/breakout_potentiometer/demo.cpp | 3 +-- examples/breakout_roundlcd/demo.cpp | 2 +- examples/breakout_sgp30/demo.cpp | 7 +++---- examples/pico_display/demo.cpp | 5 ----- examples/pico_explorer/demo.cpp | 7 +------ examples/pico_pot_explorer/demo.cpp | 3 +-- examples/pico_tof_display/demo.cpp | 2 +- examples/pico_unicorn/demo.cpp | 5 ----- examples/pico_unicorn_plasma/demo.cpp | 5 +++-- examples/pico_wireless/demo.cpp | 12 ++++++------ examples/pico_wireless/rgb_http.cpp | 2 +- examples/pico_wireless/sdcard_http.cpp | 4 ++-- 14 files changed, 23 insertions(+), 38 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index dc142c538..8322b7a62 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -32,6 +32,8 @@ 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/examples/breakout_encoder/demo.cpp b/examples/breakout_encoder/demo.cpp index e07c44da9..aeb627d7f 100644 --- a/examples/breakout_encoder/demo.cpp +++ b/examples/breakout_encoder/demo.cpp @@ -36,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_potentiometer/demo.cpp b/examples/breakout_potentiometer/demo.cpp index 8dfebac88..8de69c657 100644 --- a/examples/breakout_potentiometer/demo.cpp +++ b/examples/breakout_potentiometer/demo.cpp @@ -37,7 +37,6 @@ int main() { stdio_init_all(); - int16_t count = 0; if(pot.init()) { printf("Potentiometer found...\n"); @@ -50,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_roundlcd/demo.cpp b/examples/breakout_roundlcd/demo.cpp index 103062e65..b4bc995ff 100644 --- a/examples/breakout_roundlcd/demo.cpp +++ b/examples/breakout_roundlcd/demo.cpp @@ -17,7 +17,7 @@ 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_sgp30/demo.cpp b/examples/breakout_sgp30/demo.cpp index 825417dbe..c743712e2 100644 --- a/examples/breakout_sgp30/demo.cpp +++ b/examples/breakout_sgp30/demo.cpp @@ -19,8 +19,7 @@ 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); @@ -57,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/pico_display/demo.cpp b/examples/pico_display/demo.cpp index a29d97114..24d859eaf 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 ffa89b4cd..6e7cbbf71 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 14752a3ce..d5eed1074 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 1404f3854..cd750d816 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 51d253e69..53757347b 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 9992497d0..c45435af6 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 f220b5aba..c13417c36 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 23454b59e..39cf30e09 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 42eece660..8054e8c8a 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); From b2056040e83747aa870557641a9e66a26512d7f9 Mon Sep 17 00:00:00 2001 From: Phil Howard Date: Mon, 17 May 2021 18:09:39 +0100 Subject: [PATCH 07/10] Port Encoder and Potentiometer to Pimoroni I2C Wraps just enough of Pimoroni I2C to make it work in MicroPython. Ports Encoder and Potentiometer to use a PimorniI2C() instance in lieu of sda/scl. --- .../breakout_encoder/breakout_encoder.cpp | 36 ++++----- .../breakout_potentiometer.cpp | 36 ++++----- .../modules/pimoroni_i2c/micropython.cmake | 4 +- .../modules/pimoroni_i2c/pimoroni_i2c.c | 47 +++++++++++ .../modules/pimoroni_i2c/pimoroni_i2c.cpp | 77 +++++++++++++++++++ .../modules/pimoroni_i2c/pimoroni_i2c.h | 11 +++ 6 files changed, 166 insertions(+), 45 deletions(-) create mode 100644 micropython/modules/pimoroni_i2c/pimoroni_i2c.c create mode 100644 micropython/modules/pimoroni_i2c/pimoroni_i2c.cpp create mode 100644 micropython/modules/pimoroni_i2c/pimoroni_i2c.h diff --git a/micropython/modules/breakout_encoder/breakout_encoder.cpp b/micropython/modules/breakout_encoder/breakout_encoder.cpp index 3c01d8315..2bd3b86d1 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,12 +57,10 @@ void BreakoutEncoder_print(const mp_print_t *print, mp_obj_t self_in, mp_print_k mp_obj_t BreakoutEncoder_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *all_args) { breakout_encoder_BreakoutEncoder_obj_t *self = nullptr; - enum { ARG_i2c, ARG_address, ARG_sda, ARG_scl, ARG_interrupt }; + enum { ARG_i2c, ARG_address, ARG_interrupt }; static const mp_arg_t allowed_args[] = { - { MP_QSTR_i2c, MP_ARG_INT, {.u_int = -1} }, + { MP_QSTR_i2c, MP_ARG_OBJ, {.u_obj = nullptr} }, { MP_QSTR_address, MP_ARG_INT, {.u_int = BreakoutEncoder::DEFAULT_I2C_ADDRESS} }, - { MP_QSTR_sda, MP_ARG_INT, {.u_int = I2C_DEFAULT_SDA} }, - { MP_QSTR_scl, MP_ARG_INT, {.u_int = I2C_DEFAULT_SCL} }, { MP_QSTR_interrupt, MP_ARG_INT, {.u_int = PIN_UNUSED} }, }; @@ -63,30 +68,17 @@ mp_obj_t BreakoutEncoder_make_new(const mp_obj_type_t *type, size_t n_args, size mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; mp_arg_parse_all_kw_array(n_args, n_kw, all_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); - // Get I2C bus. - int i2c_id = args[ARG_i2c].u_int; - int sda = args[ARG_sda].u_int; - int scl = args[ARG_scl].u_int; - - if(i2c_id == -1) { - i2c_id = (sda >> 1) & 0b1; // If no i2c specified, choose the one for the given SDA pin - } - if(i2c_id < 0 || i2c_id > 1) { - mp_raise_msg_varg(&mp_type_ValueError, MP_ERROR_TEXT("I2C(%d) doesn't exist"), i2c_id); + if(!MP_OBJ_IS_TYPE(args[ARG_i2c].u_obj, &PimoroniI2C_type)) { + mp_raise_ValueError(MP_ERROR_TEXT("bad i2C object")); + return mp_const_none; } - if(!IS_VALID_SDA(i2c_id, sda)) { - mp_raise_ValueError(MP_ERROR_TEXT("bad SDA pin")); - } - - if(!IS_VALID_SCL(i2c_id, scl)) { - mp_raise_ValueError(MP_ERROR_TEXT("bad SCL pin")); - } + _PimoroniI2C_obj_t *i2c = (_PimoroniI2C_obj_t *)MP_OBJ_TO_PTR(args[ARG_i2c].u_obj); self = m_new_obj(breakout_encoder_BreakoutEncoder_obj_t); self->base.type = &breakout_encoder_BreakoutEncoder_type; - self->breakout = new BreakoutEncoder(args[ARG_address].u_int, sda, scl, args[ARG_interrupt].u_int); + self->breakout = new BreakoutEncoder(i2c->i2c, args[ARG_address].u_int, args[ARG_interrupt].u_int); if(!self->breakout->init()) { mp_raise_msg(&mp_type_RuntimeError, "Encoder breakout not found when initialising"); diff --git a/micropython/modules/breakout_potentiometer/breakout_potentiometer.cpp b/micropython/modules/breakout_potentiometer/breakout_potentiometer.cpp index f26203619..05c2820e2 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,12 +57,10 @@ void BreakoutPotentiometer_print(const mp_print_t *print, mp_obj_t self_in, mp_p mp_obj_t BreakoutPotentiometer_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *all_args) { breakout_potentiometer_BreakoutPotentiometer_obj_t *self = nullptr; - enum { ARG_i2c, ARG_address, ARG_sda, ARG_scl, ARG_interrupt }; + enum { ARG_i2c, ARG_interrupt }; static const mp_arg_t allowed_args[] = { - { MP_QSTR_i2c, MP_ARG_INT, {.u_int = -1} }, + { MP_QSTR_i2c, MP_ARG_OBJ, {.u_obj = nullptr} }, { MP_QSTR_address, MP_ARG_INT, {.u_int = BreakoutPotentiometer::DEFAULT_I2C_ADDRESS} }, - { MP_QSTR_sda, MP_ARG_INT, {.u_int = I2C_DEFAULT_SDA} }, - { MP_QSTR_scl, MP_ARG_INT, {.u_int = I2C_DEFAULT_SCL} }, { MP_QSTR_interrupt, MP_ARG_INT, {.u_int = PIN_UNUSED} }, }; @@ -63,30 +68,17 @@ mp_obj_t BreakoutPotentiometer_make_new(const mp_obj_type_t *type, size_t n_args mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; mp_arg_parse_all_kw_array(n_args, n_kw, all_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); - // Get I2C bus. - int i2c_id = args[ARG_i2c].u_int; - int sda = args[ARG_sda].u_int; - int scl = args[ARG_scl].u_int; - - if(i2c_id == -1) { - i2c_id = (sda >> 1) & 0b1; // If no i2c specified, choose the one for the given SDA pin - } - if(i2c_id < 0 || i2c_id > 1) { - mp_raise_msg_varg(&mp_type_ValueError, MP_ERROR_TEXT("I2C(%d) doesn't exist"), i2c_id); + if(!MP_OBJ_IS_TYPE(args[ARG_i2c].u_obj, &PimoroniI2C_type)) { + mp_raise_ValueError(MP_ERROR_TEXT("bad i2C object")); + return mp_const_none; } - if(!IS_VALID_SDA(i2c_id, sda)) { - mp_raise_ValueError(MP_ERROR_TEXT("bad SDA pin")); - } - - if(!IS_VALID_SCL(i2c_id, scl)) { - mp_raise_ValueError(MP_ERROR_TEXT("bad SCL pin")); - } + _PimoroniI2C_obj_t *i2c = (_PimoroniI2C_obj_t *)MP_OBJ_TO_PTR(args[ARG_i2c].u_obj); self = m_new_obj(breakout_potentiometer_BreakoutPotentiometer_obj_t); self->base.type = &breakout_potentiometer_BreakoutPotentiometer_type; - self->breakout = new BreakoutPotentiometer(args[ARG_address].u_int, sda, scl, args[ARG_interrupt].u_int); + self->breakout = new BreakoutPotentiometer(i2c->i2c, args[ARG_interrupt].u_int); if(!self->breakout->init()) { mp_raise_msg(&mp_type_RuntimeError, "Potentiometer breakout not found when initialising"); diff --git a/micropython/modules/pimoroni_i2c/micropython.cmake b/micropython/modules/pimoroni_i2c/micropython.cmake index 761e92547..0d4d9801f 100644 --- a/micropython/modules/pimoroni_i2c/micropython.cmake +++ b/micropython/modules/pimoroni_i2c/micropython.cmake @@ -3,6 +3,8 @@ string(TOUPPER ${MOD_NAME} MOD_NAME_UPPER) add_library(usermod_${MOD_NAME} INTERFACE) target_sources(usermod_${MOD_NAME} INTERFACE + ${CMAKE_CURRENT_LIST_DIR}/${MOD_NAME}.c + ${CMAKE_CURRENT_LIST_DIR}/${MOD_NAME}.cpp ${CMAKE_CURRENT_LIST_DIR}/../../../common/pimoroni_i2c.cpp ) @@ -11,7 +13,7 @@ target_include_directories(usermod_${MOD_NAME} INTERFACE ) target_compile_definitions(usermod_${MOD_NAME} INTERFACE - -DMODULE_${MOD_NAME_UPPER}_ENABLED=1 + MODULE_${MOD_NAME_UPPER}_ENABLED=1 ) target_link_libraries(usermod INTERFACE usermod_${MOD_NAME}) \ 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 000000000..9c5e021d2 --- /dev/null +++ b/micropython/modules/pimoroni_i2c/pimoroni_i2c.c @@ -0,0 +1,47 @@ +#include "pimoroni_i2c.h" + +//////////////////////////////////////////////////////////////////////////////////////////////////// +// PimoroniI2C Class +//////////////////////////////////////////////////////////////////////////////////////////////////// + + +/***** Methods *****/ +//MP_DEFINE_CONST_FUN_OBJ_KW(PimoroniI2C_read_obj, 2, PimoroniI2C_set_address); + +/***** Binding of Methods *****/ +STATIC const mp_rom_map_elem_t PimoroniI2C_locals_dict_table[] = { +}; + +STATIC MP_DEFINE_CONST_DICT(PimoroniI2C_locals_dict, PimoroniI2C_locals_dict_table); + +/***** Class Definition *****/ +const mp_obj_type_t PimoroniI2C_type = { + { &mp_type_type }, + .name = MP_QSTR_pimoroni_i2c, + .print = PimoroniI2C_print, + .make_new = PimoroniI2C_make_new, + .locals_dict = (mp_obj_dict_t*)&PimoroniI2C_locals_dict, +}; + + +//////////////////////////////////////////////////////////////////////////////////////////////////// +// breakout_potentiometer Module +//////////////////////////////////////////////////////////////////////////////////////////////////// + +/***** Globals Table *****/ +STATIC const mp_map_elem_t pimoroni_i2c_globals_table[] = { + { MP_OBJ_NEW_QSTR(MP_QSTR___name__), MP_OBJ_NEW_QSTR(MP_QSTR_pimoroni_i2c) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_PimoroniI2C), (mp_obj_t)&PimoroniI2C_type }, +}; +STATIC MP_DEFINE_CONST_DICT(mp_module_pimoroni_i2c_globals, pimoroni_i2c_globals_table); + +/***** Module Definition *****/ +const mp_obj_module_t pimoroni_i2c_user_cmodule = { + .base = { &mp_type_module }, + .globals = (mp_obj_dict_t*)&mp_module_pimoroni_i2c_globals, +}; + +//////////////////////////////////////////////////////////////////////////////////////////////////// +MP_REGISTER_MODULE(MP_QSTR_pimoroni_i2c, pimoroni_i2c_user_cmodule, MODULE_PIMORONI_I2C_ENABLED); +//////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////////////////////////// \ 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 000000000..9e071782a --- /dev/null +++ b/micropython/modules/pimoroni_i2c/pimoroni_i2c.cpp @@ -0,0 +1,77 @@ +#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, ")"); +} + +/***** Constructor *****/ +mp_obj_t PimoroniI2C_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *all_args) { + _PimoroniI2C_obj_t *self = nullptr; + + enum { ARG_sda, ARG_scl }; + static const mp_arg_t allowed_args[] = { + { MP_QSTR_sda, MP_ARG_INT, {.u_int = I2C_DEFAULT_SDA} }, + { MP_QSTR_scl, MP_ARG_INT, {.u_int = I2C_DEFAULT_SCL} }, + }; + + // Parse args. + mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; + mp_arg_parse_all_kw_array(n_args, n_kw, all_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); + + // Get I2C bus. + int sda = args[ARG_sda].u_int; + int scl = args[ARG_scl].u_int; + int i2c_id = (sda >> 1) & 0b1; // i2c bus for given SDA pin + + if(!IS_VALID_SDA(i2c_id, sda)) { + mp_raise_ValueError(MP_ERROR_TEXT("bad SDA pin")); + } + + if(!IS_VALID_SCL(i2c_id, scl)) { + mp_raise_ValueError(MP_ERROR_TEXT("bad SCL pin")); + } + + self = m_new_obj(_PimoroniI2C_obj_t); + self->base.type = &PimoroniI2C_type; + + self->i2c = new I2C(sda, scl); + + return MP_OBJ_FROM_PTR(self); +} + +} \ 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 000000000..684c9c227 --- /dev/null +++ b/micropython/modules/pimoroni_i2c/pimoroni_i2c.h @@ -0,0 +1,11 @@ +// Include MicroPython API. +#include "py/runtime.h" + +/***** Extern of Class Definition *****/ +extern const mp_obj_type_t PimoroniI2C_type; + +/***** Extern of Class Methods *****/ +extern void PimoroniI2C_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind); +extern mp_obj_t PimoroniI2C_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *all_args); + +extern bool Pimoroni_mp_obj_to_i2c(mp_obj_t in, void *out); \ No newline at end of file From edf77ddb760eae3957699e7229dcc3509eb0fb9c Mon Sep 17 00:00:00 2001 From: Phil Howard Date: Tue, 18 May 2021 09:48:41 +0100 Subject: [PATCH 08/10] Add finaliser for Pimoroni I2C This is the final piece of the puzzle. Prior to this rather considerable change, Pimoroni breakouts were not de-init'ing I2C when they failed to init() This change adds a __del__ method which cleans up the I2C instance attached to a MicroPython object. Under the hood this calls i2c_deinit() and resets the associated pins to their default state. This means that I2C is now cleaned up during a *soft* reset, so running a script with the wrong pins, seeing an error, changing the pins and running it again will not result in subsequent I2C errors. Previously a hard reset was required. To recreate on Breakout Garden run the following code: ``` from breakout_potentiometer import BreakoutPotentiometer from pimoroni_i2c import PimoroniI2C i2c = PimoroniI2C() pot = BreakoutPotentiometer(i2c) ``` This will fail correctly with "Potentiometer breakout not found when initialising." (The default pins are configured for Pico Explorer) Now change that to the following and run again without hard-resetting: ``` from breakout_potentiometer import BreakoutPotentiometer from pimoroni_i2c import PimoroniI2C i2c = PimoroniI2C(4, 5) pot = BreakoutPotentiometer(i2c) ``` This should now work, since the failed I2C instance was cleaned up. Without this change, the second attempt would result in an inexplicable failure. Since most? (many?) Pico users do not have a reset button, this trap requiring a hard-reset is pretty nasty and would likely have resulted in a support nightmare. Whew. --- micropython/modules/pimoroni_i2c/pimoroni_i2c.c | 3 ++- micropython/modules/pimoroni_i2c/pimoroni_i2c.cpp | 9 ++++++++- micropython/modules/pimoroni_i2c/pimoroni_i2c.h | 1 + 3 files changed, 11 insertions(+), 2 deletions(-) diff --git a/micropython/modules/pimoroni_i2c/pimoroni_i2c.c b/micropython/modules/pimoroni_i2c/pimoroni_i2c.c index 9c5e021d2..e91b53b33 100644 --- a/micropython/modules/pimoroni_i2c/pimoroni_i2c.c +++ b/micropython/modules/pimoroni_i2c/pimoroni_i2c.c @@ -6,10 +6,11 @@ /***** Methods *****/ -//MP_DEFINE_CONST_FUN_OBJ_KW(PimoroniI2C_read_obj, 2, PimoroniI2C_set_address); +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); diff --git a/micropython/modules/pimoroni_i2c/pimoroni_i2c.cpp b/micropython/modules/pimoroni_i2c/pimoroni_i2c.cpp index 9e071782a..1d0c2dee8 100644 --- a/micropython/modules/pimoroni_i2c/pimoroni_i2c.cpp +++ b/micropython/modules/pimoroni_i2c/pimoroni_i2c.cpp @@ -39,6 +39,13 @@ void PimoroniI2C_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_ mp_print_str(print, ")"); } +/***** Destructor ******/ +mp_obj_t PimoroniI2C___del__(mp_obj_t self_in) { + _PimoroniI2C_obj_t *self = MP_OBJ_TO_PTR2(self_in, _PimoroniI2C_obj_t); + delete self->i2c; + return mp_const_none; +} + /***** Constructor *****/ mp_obj_t PimoroniI2C_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *all_args) { _PimoroniI2C_obj_t *self = nullptr; @@ -66,7 +73,7 @@ mp_obj_t PimoroniI2C_make_new(const mp_obj_type_t *type, size_t n_args, size_t n mp_raise_ValueError(MP_ERROR_TEXT("bad SCL pin")); } - self = m_new_obj(_PimoroniI2C_obj_t); + self = m_new_obj_with_finaliser(_PimoroniI2C_obj_t); self->base.type = &PimoroniI2C_type; self->i2c = new I2C(sda, scl); diff --git a/micropython/modules/pimoroni_i2c/pimoroni_i2c.h b/micropython/modules/pimoroni_i2c/pimoroni_i2c.h index 684c9c227..3351a8af5 100644 --- a/micropython/modules/pimoroni_i2c/pimoroni_i2c.h +++ b/micropython/modules/pimoroni_i2c/pimoroni_i2c.h @@ -7,5 +7,6 @@ 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 From 66f6983290782cca6414cea79767b627b34b9e12 Mon Sep 17 00:00:00 2001 From: Phil Howard Date: Tue, 18 May 2021 11:18:41 +0100 Subject: [PATCH 09/10] Port remaining modules to PimoroniI2C, update examples --- micropython/examples/breakout_as7262/demo.py | 7 +++- .../examples/breakout_dotmatrix/bargraph.py | 7 +++- .../examples/breakout_dotmatrix/eyes.py | 9 +++- .../examples/breakout_dotmatrix/image.py | 7 +++- .../examples/breakout_dotmatrix/timer.py | 7 +++- micropython/examples/breakout_encoder/demo.py | 7 +++- .../examples/breakout_ioexpander/adc.py | 7 +++- .../examples/breakout_ioexpander/button.py | 7 +++- .../examples/breakout_ioexpander/servo.py | 7 +++- micropython/examples/breakout_ltr559/demo.py | 7 +++- .../examples/breakout_matrix11x7/demo.py | 7 +++- .../examples/breakout_mics6814/demo.py | 7 +++- micropython/examples/breakout_msa301/demo.py | 7 +++- .../examples/breakout_potentiometer/demo.py | 7 +++- .../examples/breakout_rgbmatrix5x5/demo.py | 9 +++- micropython/examples/breakout_rtc/demo.py | 8 +++- micropython/examples/breakout_sgp30/demo.py | 8 +++- .../examples/breakout_trackball/demo.py | 9 +++- .../breakout_as7262/breakout_as7262.cpp | 37 +++++++--------- .../breakout_dotmatrix/breakout_dotmatrix.cpp | 36 +++++++--------- .../breakout_encoder/breakout_encoder.cpp | 4 +- .../breakout_ioexpander.cpp | 37 +++++++--------- .../breakout_ltr559/breakout_ltr559.cpp | 40 +++++++----------- .../breakout_matrix11x7.cpp | 40 +++++++----------- .../breakout_mics6814/breakout_mics6814.cpp | 37 +++++++--------- .../breakout_msa301/breakout_msa301.cpp | 41 +++++++----------- .../breakout_potentiometer.cpp | 4 +- .../breakout_rgbmatrix5x5.cpp | 42 ++++++++----------- .../modules/breakout_rtc/breakout_rtc.cpp | 38 +++++++---------- .../modules/breakout_sgp30/breakout_sgp30.cpp | 40 +++++++----------- .../breakout_trackball/breakout_trackball.cpp | 36 +++++++--------- .../modules/pimoroni_i2c/pimoroni_i2c.cpp | 6 ++- 32 files changed, 289 insertions(+), 283 deletions(-) diff --git a/micropython/examples/breakout_as7262/demo.py b/micropython/examples/breakout_as7262/demo.py index f6fdd8d7c..da1008885 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_dotmatrix/bargraph.py b/micropython/examples/breakout_dotmatrix/bargraph.py index 665e1a6f8..e80f4aecb 100644 --- a/micropython/examples/breakout_dotmatrix/bargraph.py +++ b/micropython/examples/breakout_dotmatrix/bargraph.py @@ -2,9 +2,14 @@ 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 7d0b04840..e625f1e4f 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 f1af07ae3..31e7acfe5 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 c32db6cff..d420f4ec6 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 c83374534..848e4192e 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 290a83ba4..f66a9274d 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 624306a68..1955073bb 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 7ca012fc7..622fe0ab0 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 @@ 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 7f79f67d6..a027de45d 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 47c836776..07554c513 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 b8af41c6a..cdd8c08a7 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 703915a35..cb2c97925 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 ec354b725..81cbfb2b7 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 c5862842c..5f486b796 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 a1c19fa3f..cc24b6ca3 100644 --- a/micropython/examples/breakout_rtc/demo.py +++ b/micropython/examples/breakout_rtc/demo.py @@ -1,8 +1,12 @@ +from pimoroni_i2c import PimoroniI2C from breakout_rtc import BreakoutRTC import time -# rtc = BreakoutRTC(sda=4, scl=5) # i2c pins 4, 5 for Breakout Garden -rtc = BreakoutRTC() # Default i2c pins for Pico Explorer +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() diff --git a/micropython/examples/breakout_sgp30/demo.py b/micropython/examples/breakout_sgp30/demo.py index 4894b1674..2a316bdb0 100644 --- a/micropython/examples/breakout_sgp30/demo.py +++ b/micropython/examples/breakout_sgp30/demo.py @@ -1,8 +1,12 @@ import time +from pimoroni_i2c import PimoroniI2C from breakout_sgp30 import BreakoutSGP30 -# sgp30 = BreakoutSGP30(sda=4, scl=5) # i2c pins 4, 5 for Breakout Garden -sgp30 = BreakoutSGP30() # Default i2c pins for Pico Explorer +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") diff --git a/micropython/examples/breakout_trackball/demo.py b/micropython/examples/breakout_trackball/demo.py index e846b6c61..5d726ee11 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 62dd291be..7942a0b19 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,11 +51,9 @@ 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 = I2C_DEFAULT_SDA} }, - { MP_QSTR_scl, MP_ARG_INT, {.u_int = I2C_DEFAULT_SCL} }, + { MP_QSTR_i2c, MP_ARG_OBJ, {.u_obj = nullptr} }, { MP_QSTR_interrupt, MP_ARG_INT, {.u_int = PIN_UNUSED} }, }; @@ -56,33 +61,21 @@ mp_obj_t BreakoutAS7262_make_new(const mp_obj_type_t *type, size_t n_args, size_ mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; mp_arg_parse_all_kw_array(n_args, n_kw, all_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); - // 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(!IS_VALID_SDA(i2c_id, sda)) { - mp_raise_ValueError(MP_ERROR_TEXT("bad SDA pin")); + 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_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; - self->breakout = new BreakoutAS7262(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_dotmatrix/breakout_dotmatrix.cpp b/micropython/modules/breakout_dotmatrix/breakout_dotmatrix.cpp index 6a66a7f61..de9fca756 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,42 +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 = I2C_DEFAULT_SDA} }, - { MP_QSTR_scl, MP_ARG_INT, {.u_int = I2C_DEFAULT_SCL} }, }; // Parse args. mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; mp_arg_parse_all_kw_array(n_args, n_kw, all_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); - // Get I2C bus. - int 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; - self->breakout = new BreakoutDotMatrix(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 2bd3b86d1..314bf86b3 100644 --- a/micropython/modules/breakout_encoder/breakout_encoder.cpp +++ b/micropython/modules/breakout_encoder/breakout_encoder.cpp @@ -69,7 +69,7 @@ mp_obj_t BreakoutEncoder_make_new(const mp_obj_type_t *type, size_t n_args, size mp_arg_parse_all_kw_array(n_args, n_kw, all_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); if(!MP_OBJ_IS_TYPE(args[ARG_i2c].u_obj, &PimoroniI2C_type)) { - mp_raise_ValueError(MP_ERROR_TEXT("bad i2C object")); + mp_raise_ValueError(MP_ERROR_TEXT("BreakoutEncoder: Bad i2C object")); return mp_const_none; } @@ -81,7 +81,7 @@ mp_obj_t BreakoutEncoder_make_new(const mp_obj_type_t *type, size_t n_args, size 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 6ae34a679..d1d8d3560 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,12 +57,10 @@ 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 = I2C_DEFAULT_SDA} }, - { MP_QSTR_scl, MP_ARG_INT, {.u_int = I2C_DEFAULT_SCL} }, { MP_QSTR_interrupt, MP_ARG_INT, {.u_int = PIN_UNUSED} }, }; @@ -64,32 +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; - self->breakout = new BreakoutIOExpander(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 7d3661c47..735a5845a 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,45 +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_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 = I2C_DEFAULT_SDA} }, - { MP_QSTR_scl, MP_ARG_INT, {.u_int = I2C_DEFAULT_SCL} }, - { MP_QSTR_interrupt, MP_ARG_INT, {.u_int = -1} }, + { 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; - self->breakout = new BreakoutLTR559(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 5952fcdfd..06d89c90f 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 = I2C_DEFAULT_SDA} }, - { MP_QSTR_scl, MP_ARG_INT, {.u_int = I2C_DEFAULT_SCL} }, + { 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 d8b471410..3994faac0 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,12 +57,10 @@ 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 = I2C_DEFAULT_SDA} }, - { MP_QSTR_scl, MP_ARG_INT, {.u_int = I2C_DEFAULT_SCL} }, { MP_QSTR_interrupt, MP_ARG_INT, {.u_int = PIN_UNUSED} }, }; @@ -64,32 +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; - self->breakout = new BreakoutMICS6814(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 bd1cea90a..bb21fed33 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,11 +51,9 @@ 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 = I2C_DEFAULT_SDA} }, - { MP_QSTR_scl, MP_ARG_INT, {.u_int = I2C_DEFAULT_SCL} }, + { MP_QSTR_i2c, MP_ARG_OBJ, {.u_obj = nullptr} }, { MP_QSTR_interrupt, MP_ARG_INT, {.u_int = PIN_UNUSED} }, }; @@ -56,34 +61,20 @@ mp_obj_t BreakoutMSA301_make_new(const mp_obj_type_t *type, size_t n_args, size_ mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; mp_arg_parse_all_kw_array(n_args, n_kw, all_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); - // 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 05c2820e2..90fc24d35 100644 --- a/micropython/modules/breakout_potentiometer/breakout_potentiometer.cpp +++ b/micropython/modules/breakout_potentiometer/breakout_potentiometer.cpp @@ -69,7 +69,7 @@ mp_obj_t BreakoutPotentiometer_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); if(!MP_OBJ_IS_TYPE(args[ARG_i2c].u_obj, &PimoroniI2C_type)) { - mp_raise_ValueError(MP_ERROR_TEXT("bad i2C object")); + mp_raise_ValueError(MP_ERROR_TEXT("BreakoutPotentiometer: Bad i2C object")); return mp_const_none; } @@ -81,7 +81,7 @@ mp_obj_t BreakoutPotentiometer_make_new(const mp_obj_type_t *type, size_t n_args 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 3e4859a9f..c1c806766 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 = I2C_DEFAULT_SDA} }, - { MP_QSTR_scl, MP_ARG_INT, {.u_int = I2C_DEFAULT_SCL} }, + { 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_rtc/breakout_rtc.cpp b/micropython/modules/breakout_rtc/breakout_rtc.cpp index 7ab6793db..22afbf428 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,11 +54,9 @@ 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 = I2C_DEFAULT_SDA} }, - { MP_QSTR_scl, MP_ARG_INT, {.u_int = I2C_DEFAULT_SCL} }, + { MP_QSTR_i2c, MP_ARG_OBJ, {.u_obj = nullptr} }, { MP_QSTR_interrupt, MP_ARG_INT, {.u_int = PIN_UNUSED} }, }; @@ -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 10c6a42df..41ff30294 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 = I2C_DEFAULT_SDA} }, - { MP_QSTR_scl, MP_ARG_INT, {.u_int = I2C_DEFAULT_SCL} }, + { 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(!IS_VALID_SDA(i2c_id, sda)) { - mp_raise_ValueError(MP_ERROR_TEXT("bad SDA pin")); + 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_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 660c9630a..eb62513e1 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,12 +57,10 @@ 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 = I2C_DEFAULT_SDA} }, - { MP_QSTR_scl, MP_ARG_INT, {.u_int = I2C_DEFAULT_SCL} }, { MP_QSTR_interrupt, MP_ARG_INT, {.u_int = PIN_UNUSED} }, }; @@ -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/pimoroni_i2c/pimoroni_i2c.cpp b/micropython/modules/pimoroni_i2c/pimoroni_i2c.cpp index 1d0c2dee8..f8924fd2f 100644 --- a/micropython/modules/pimoroni_i2c/pimoroni_i2c.cpp +++ b/micropython/modules/pimoroni_i2c/pimoroni_i2c.cpp @@ -50,10 +50,11 @@ mp_obj_t PimoroniI2C___del__(mp_obj_t self_in) { 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 }; + 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. @@ -63,6 +64,7 @@ mp_obj_t PimoroniI2C_make_new(const mp_obj_type_t *type, size_t n_args, size_t n // 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)) { @@ -76,7 +78,7 @@ mp_obj_t PimoroniI2C_make_new(const mp_obj_type_t *type, size_t n_args, size_t n self = m_new_obj_with_finaliser(_PimoroniI2C_obj_t); self->base.type = &PimoroniI2C_type; - self->i2c = new I2C(sda, scl); + self->i2c = new I2C(sda, scl, baud); return MP_OBJ_FROM_PTR(self); } From 0bda2abd2acd4269725efb81ffd3f33621a8e176 Mon Sep 17 00:00:00 2001 From: Phil Howard Date: Tue, 18 May 2021 11:36:14 +0100 Subject: [PATCH 10/10] Fix AS7262 constructor and example --- drivers/as7262/as7262.hpp | 6 +++--- micropython/examples/breakout_as7262/pico_explorer_graph.py | 4 +++- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/drivers/as7262/as7262.hpp b/drivers/as7262/as7262.hpp index eea68decf..319598612 100644 --- a/drivers/as7262/as7262.hpp +++ b/drivers/as7262/as7262.hpp @@ -79,12 +79,12 @@ namespace pimoroni { // Constructors/Destructor //-------------------------------------------------- public: - AS7262(uint8_t address = DEFAULT_I2C_ADDRESS, uint interrupt = PIN_UNUSED) : AS7262(new I2C(), address, interrupt) {}; + AS7262(uint interrupt = PIN_UNUSED) : AS7262(new I2C(), interrupt) {}; - AS7262(I2C *i2c, uint8_t address = DEFAULT_I2C_ADDRESS, uint interrupt = PIN_UNUSED) : i2c(i2c), address(address), interrupt(interrupt) {} + AS7262(I2C *i2c, uint interrupt = PIN_UNUSED) : i2c(i2c), interrupt(interrupt) {} // TODO remove MicroPython-binding compatibility constructors - AS7262(uint8_t address, uint sda, uint scl, uint interrupt = PIN_UNUSED) : AS7262(new I2C(), address, interrupt) {} + AS7262(uint sda, uint scl, uint interrupt = PIN_UNUSED) : AS7262(new I2C(), interrupt) {} //-------------------------------------------------- diff --git a/micropython/examples/breakout_as7262/pico_explorer_graph.py b/micropython/examples/breakout_as7262/pico_explorer_graph.py index 24f8e6f52..432469361 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 @@ 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