Merge pull request #129 from pimoroni/patch-gpio-int-types

Add a common header for pins and settings + common I2C class for managing I2C busses across drivers
This commit is contained in:
Philip Howard 2021-05-19 11:56:46 +01:00 committed by GitHub
commit cb958a7c8a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
121 changed files with 1197 additions and 1090 deletions

View File

@ -32,6 +32,9 @@ include_directories(
${CMAKE_CURRENT_LIST_DIR}
)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Werror")
add_subdirectory(common)
add_subdirectory(drivers)
add_subdirectory(libraries)

9
common/CMakeLists.txt Normal file
View File

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

View File

@ -0,0 +1,41 @@
#pragma once
#include <stdint.h>
#include <climits>
#define PIMORONI_I2C_DEFAULT_INSTANCE i2c0
#define PIMORONI_SPI_DEFAULT_INSTANCE spi0
namespace pimoroni {
static const unsigned int PIN_UNUSED = INT_MAX; // Intentionally INT_MAX to avoid overflowing MicroPython's int type
// I2C
static const unsigned int I2C_DEFAULT_BAUDRATE = 400000;
static const unsigned int I2C_DEFAULT_SDA = 20;
static const unsigned int I2C_DEFAULT_SCL = 21;
static const unsigned int I2C_DEFAULT_INT = 22;
static const unsigned int I2C_BG_SDA = 4;
static const unsigned int I2C_BG_SCL = 5;
static const unsigned int I2C_BG_INT = 3;
// SPI
static const unsigned int SPI_DEFAULT_MOSI = 19;
static const unsigned int SPI_DEFAULT_MISO = 16;
static const unsigned int SPI_DEFAULT_SCK = 18;
static const unsigned int SPI_BG_FRONT_PWM = 20;
static const unsigned int SPI_BG_FRONT_CS = 17;
static const unsigned int SPI_BG_BACK_PWM = 21;
static const unsigned int SPI_BG_BACK_CS = 22;
enum BG_SPI_SLOT {
BG_SPI_FRONT,
BG_SPI_BACK
};
enum BOARD {
BREAKOUT_GARDEN,
PICO_EXPLORER
};
}

91
common/pimoroni_i2c.cpp Normal file
View File

@ -0,0 +1,91 @@
#include "pimoroni_common.hpp"
#include "pimoroni_i2c.hpp"
namespace pimoroni {
void I2C::init() {
i2c = ((sda / 2) & 0b1) ? i2c1 : i2c0;
i2c_init(i2c, baudrate);
gpio_set_function(sda, GPIO_FUNC_I2C); gpio_pull_up(sda);
gpio_set_function(scl, GPIO_FUNC_I2C); gpio_pull_up(scl);
}
/* Basic wrappers for devices using i2c functions directly */
int I2C::write_blocking(uint8_t addr, const uint8_t *src, size_t len, bool nostop) {
return i2c_write_blocking(i2c, addr, src, len, nostop);
}
int I2C::read_blocking(uint8_t addr, uint8_t *dst, size_t len, bool nostop) {
return i2c_read_blocking(i2c, addr, dst, len, nostop);
}
/* Convenience functions for various common i2c operations */
void I2C::reg_write_uint8(uint8_t address, uint8_t reg, uint8_t value) {
uint8_t buffer[2] = {reg, value};
i2c_write_blocking(i2c, address, buffer, 2, false);
}
uint8_t I2C::reg_read_uint8(uint8_t address, uint8_t reg) {
uint8_t value;
i2c_write_blocking(i2c, address, &reg, 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, &reg, 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, &reg, 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, &reg, 1, true);
i2c_read_blocking(i2c, address, (uint8_t *)&value, sizeof(int16_t), false);
return value;
}
int I2C::write_bytes(uint8_t address, uint8_t reg, uint8_t *buf, int len) {
uint8_t buffer[len + 1];
buffer[0] = reg;
for(int x = 0; x < len; x++) {
buffer[x + 1] = buf[x];
}
return i2c_write_blocking(i2c, address, buffer, len + 1, false);
};
int I2C::read_bytes(uint8_t address, uint8_t reg, uint8_t *buf, int len) {
i2c_write_blocking(i2c, address, &reg, 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);
}
}

72
common/pimoroni_i2c.hpp Normal file
View File

@ -0,0 +1,72 @@
#pragma once
#include <stdint.h>
#include <climits>
#include "hardware/i2c.h"
#include "hardware/gpio.h"
#include "pimoroni_common.hpp"
#include "pimoroni_i2c.hpp"
namespace pimoroni {
class I2C {
private:
i2c_inst_t *i2c = PIMORONI_I2C_DEFAULT_INSTANCE;
uint sda = I2C_DEFAULT_SDA;
uint scl = I2C_DEFAULT_SCL;
uint interrupt = PIN_UNUSED;
uint32_t baudrate = I2C_DEFAULT_BAUDRATE;
public:
I2C(BOARD board, uint32_t baudrate = I2C_DEFAULT_BAUDRATE) : baudrate(baudrate) {
switch(board) {
case BREAKOUT_GARDEN:
sda = I2C_BG_SDA;
scl = I2C_BG_SCL;
interrupt = I2C_BG_INT;
break;
case PICO_EXPLORER:
default:
sda = I2C_DEFAULT_SDA;
scl = I2C_DEFAULT_SCL;
interrupt = I2C_DEFAULT_INT;
break;
}
init();
}
I2C(uint sda, uint scl, uint32_t baudrate = I2C_DEFAULT_BAUDRATE) : sda(sda), scl(scl), baudrate(baudrate) {
init();
}
I2C() : I2C(I2C_DEFAULT_SDA, I2C_DEFAULT_SCL) {}
~I2C() {
i2c_deinit(i2c);
gpio_disable_pulls(sda);
gpio_set_function(sda, GPIO_FUNC_NULL);
gpio_disable_pulls(scl);
gpio_set_function(scl, GPIO_FUNC_NULL);
}
void reg_write_uint8(uint8_t address, uint8_t reg, uint8_t value);
uint8_t reg_read_uint8(uint8_t address, uint8_t reg);
uint16_t reg_read_uint16(uint8_t address, uint8_t reg);
int16_t reg_read_int16(uint8_t address, uint8_t reg);
uint32_t reg_read_uint32(uint8_t address, uint8_t reg);
int write_bytes(uint8_t address, uint8_t reg, uint8_t *buf, int len);
int read_bytes(uint8_t address, uint8_t reg, uint8_t *buf, int len);
uint8_t get_bits(uint8_t address, uint8_t reg, uint8_t shift, uint8_t mask=0b1);
void set_bits(uint8_t address, uint8_t reg, uint8_t shift, uint8_t mask=0b1);
void clear_bits(uint8_t address, uint8_t reg, uint8_t shift, uint8_t mask=0b1);
int write_blocking(uint8_t addr, const uint8_t *src, size_t len, bool nostop);
int read_blocking(uint8_t addr, uint8_t *dst, size_t len, bool nostop);
i2c_inst_t* get_i2c() {return i2c;}
uint get_scl() {return scl;}
uint get_sda() {return sda;}
uint32_t get_baudrate() {return baudrate;}
private:
void init();
};
}

View File

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

View File

@ -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, &reg, 1, false);
i2c_read_blocking(i2c, address, (uint8_t *)&value, 1, false);
i2c->write_blocking(address, &reg, 1, false);
i2c->read_blocking(address, (uint8_t *)&value, 1, false);
return value;
}
}

View File

@ -4,6 +4,8 @@
#include "hardware/i2c.h"
#include "hardware/gpio.h"
#include "common/pimoroni_common.hpp"
#include "common/pimoroni_i2c.hpp"
namespace pimoroni {
@ -13,10 +15,6 @@ namespace pimoroni {
//--------------------------------------------------
public:
static const uint8_t DEFAULT_I2C_ADDRESS = 0x49;
static const uint8_t DEFAULT_SDA_PIN = 20;
static const uint8_t DEFAULT_SCL_PIN = 21;
static const uint8_t DEFAULT_INT_PIN = 22;
static const uint8_t PIN_UNUSED = UINT8_MAX;
//--------------------------------------------------
@ -70,23 +68,23 @@ namespace pimoroni {
// Variables
//--------------------------------------------------
private:
i2c_inst_t *i2c = i2c0;
I2C *i2c;
// interface pins with our standard defaults where appropriate
int8_t address = DEFAULT_I2C_ADDRESS;
int8_t sda = DEFAULT_SDA_PIN;
int8_t scl = DEFAULT_SCL_PIN;
int8_t interrupt = DEFAULT_INT_PIN;
uint interrupt = PIN_UNUSED;
//--------------------------------------------------
// Constructors/Destructor
//--------------------------------------------------
public:
AS7262() {}
AS7262(uint interrupt = PIN_UNUSED) : AS7262(new I2C(), interrupt) {};
AS7262(i2c_inst_t *i2c, uint8_t sda, uint8_t scl, uint8_t interrupt = PIN_UNUSED) :
i2c(i2c), sda(sda), scl(scl), interrupt(interrupt) {}
AS7262(I2C *i2c, uint interrupt = PIN_UNUSED) : i2c(i2c), interrupt(interrupt) {}
// TODO remove MicroPython-binding compatibility constructors
AS7262(uint sda, uint scl, uint interrupt = PIN_UNUSED) : AS7262(new I2C(), interrupt) {}
//--------------------------------------------------

View File

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

View File

@ -297,16 +297,9 @@ namespace pimoroni {
this->mode = mode;
}
IOExpander::IOExpander() :
IOExpander(i2c0, DEFAULT_I2C_ADDRESS, DEFAULT_SDA_PIN, DEFAULT_SCL_PIN, DEFAULT_INT_PIN) {
}
IOExpander::IOExpander(uint8_t address, uint32_t timeout, bool debug) :
IOExpander(i2c0, address, DEFAULT_SDA_PIN, DEFAULT_SCL_PIN, DEFAULT_INT_PIN, timeout, debug) {
}
IOExpander::IOExpander(i2c_inst_t *i2c, uint8_t address, uint8_t sda, uint8_t scl, uint8_t interrupt, uint32_t timeout, bool debug) :
i2c(i2c), address(address), sda(sda), scl(scl), interrupt(interrupt),
IOExpander::IOExpander(I2C *i2c, uint8_t address, uint interrupt, uint32_t timeout, bool debug) :
i2c(i2c),
address(address), interrupt(interrupt),
timeout(timeout), debug(debug), vref(3.3f),
encoder_offset{0,0,0,0},
encoder_last{0,0,0,0},
@ -323,17 +316,12 @@ namespace pimoroni {
Pin::adc(0, 6, 3),
Pin::adc_or_pwm(0, 5, 4, 2, reg::PIOCON1),
Pin::adc(0, 7, 2),
Pin::adc(1, 7, 0)} {
}
Pin::adc(1, 7, 0)}
{}
bool IOExpander::init(bool skipChipIdCheck) {
bool succeeded = true;
i2c_init(i2c, 400000);
gpio_set_function(sda, GPIO_FUNC_I2C); gpio_pull_up(sda);
gpio_set_function(scl, GPIO_FUNC_I2C); gpio_pull_up(scl);
if(interrupt != PIN_UNUSED) {
gpio_set_function(interrupt, GPIO_FUNC_SIO);
gpio_set_dir(interrupt, GPIO_IN);
@ -356,7 +344,7 @@ namespace pimoroni {
}
i2c_inst_t* IOExpander::get_i2c() const {
return i2c;
return i2c->get_i2c();
}
int IOExpander::get_address() const {
@ -364,11 +352,11 @@ namespace pimoroni {
}
int IOExpander::get_sda() const {
return sda;
return i2c->get_sda();
}
int IOExpander::get_scl() const {
return scl;
return i2c->get_scl();
}
int IOExpander::get_int() const {
@ -376,12 +364,12 @@ namespace pimoroni {
}
uint16_t IOExpander::get_chip_id() {
return ((uint16_t)i2c_reg_read_uint8(reg::CHIP_ID_H) << 8) | (uint16_t)i2c_reg_read_uint8(reg::CHIP_ID_L);
return ((uint16_t)i2c->reg_read_uint8(address, reg::CHIP_ID_H) << 8) | (uint16_t)i2c->reg_read_uint8(address, reg::CHIP_ID_L);
}
void IOExpander::set_address(uint8_t address) {
set_bit(reg::CTRL, 4);
i2c_reg_write_uint8(reg::ADDR, address);
i2c->reg_write_uint8(address, reg::ADDR, address);
this->address = address;
sleep_ms(250); //TODO Handle addr change IOError better
//wait_for_flash()
@ -496,7 +484,7 @@ namespace pimoroni {
// PWMTYP - PWM type select: 0 edge-aligned, 1 center-aligned
// FBINEN - Fault-break input enable
i2c_reg_write_uint8(reg::PWMCON1, pwmdiv2);
i2c->reg_write_uint8(address, reg::PWMCON1, pwmdiv2);
}
return divider_good;
@ -504,8 +492,8 @@ namespace pimoroni {
void IOExpander::set_pwm_period(uint16_t value, bool load) {
value &= 0xffff;
i2c_reg_write_uint8(reg::PWMPL, (uint8_t)(value & 0xff));
i2c_reg_write_uint8(reg::PWMPH, (uint8_t)(value >> 8));
i2c->reg_write_uint8(address, reg::PWMPL, (uint8_t)(value & 0xff));
i2c->reg_write_uint8(address, reg::PWMPH, (uint8_t)(value >> 8));
if(load)
pwm_load();
@ -561,8 +549,8 @@ namespace pimoroni {
clr_bit(io_pin.reg_io_pwm, io_pin.pwm_channel);
}
uint8_t pm1 = i2c_reg_read_uint8(io_pin.reg_m1);
uint8_t pm2 = i2c_reg_read_uint8(io_pin.reg_m2);
uint8_t pm1 = i2c->reg_read_uint8(address, io_pin.reg_m1);
uint8_t pm2 = i2c->reg_read_uint8(address, io_pin.reg_m2);
// Clear the pm1 and pm2 bits
pm1 &= 255 - (1 << io_pin.pin);
@ -572,15 +560,15 @@ namespace pimoroni {
pm1 |= (gpio_mode >> 1) << io_pin.pin;
pm2 |= (gpio_mode & 0b1) << io_pin.pin;
i2c_reg_write_uint8(io_pin.reg_m1, pm1);
i2c_reg_write_uint8(io_pin.reg_m2, pm2);
i2c->reg_write_uint8(address, io_pin.reg_m1, pm1);
i2c->reg_write_uint8(address, io_pin.reg_m2, pm2);
// Set up Schmitt trigger mode on inputs
if(mode == PIN_MODE_PU || mode == PIN_MODE_IN)
change_bit(io_pin.reg_ps, io_pin.pin, schmitt_trigger);
// 5th bit of mode encodes default output pin state
i2c_reg_write_uint8(io_pin.reg_p, (initial_state << 3) | io_pin.pin);
i2c->reg_write_uint8(address, io_pin.reg_p, (initial_state << 3) | io_pin.pin);
}
int16_t IOExpander::input(uint8_t pin, uint32_t adc_timeout) {
@ -599,7 +587,7 @@ namespace pimoroni {
clr_bits(reg::ADCCON0, 0x0f);
set_bits(reg::ADCCON0, io_pin.adc_channel);
i2c_reg_write_uint8(reg::AINDIDS, 0);
i2c->reg_write_uint8(address, reg::AINDIDS, 0);
set_bit(reg::AINDIDS, io_pin.adc_channel);
set_bit(reg::ADCCON1, 0);
@ -617,8 +605,8 @@ namespace pimoroni {
}
}
uint8_t hi = i2c_reg_read_uint8(reg::ADCRH);
uint8_t lo = i2c_reg_read_uint8(reg::ADCRL);
uint8_t hi = i2c->reg_read_uint8(address, reg::ADCRH);
uint8_t lo = i2c->reg_read_uint8(address, reg::ADCRL);
return (uint16_t)(hi << 4) | (uint16_t)lo;
}
else {
@ -647,7 +635,7 @@ namespace pimoroni {
clr_bits(reg::ADCCON0, 0x0f);
set_bits(reg::ADCCON0, io_pin.adc_channel);
i2c_reg_write_uint8(reg::AINDIDS, 0);
i2c->reg_write_uint8(address, reg::AINDIDS, 0);
set_bit(reg::AINDIDS, io_pin.adc_channel);
set_bit(reg::ADCCON1, 0);
@ -666,8 +654,8 @@ namespace pimoroni {
}
}
uint8_t hi = i2c_reg_read_uint8(reg::ADCRH);
uint8_t lo = i2c_reg_read_uint8(reg::ADCRL);
uint8_t hi = i2c->reg_read_uint8(address, reg::ADCRH);
uint8_t lo = i2c->reg_read_uint8(address, reg::ADCRL);
return ((float)((uint16_t)(hi << 4) | (uint16_t)lo) / 4095.0f) * vref;
}
else {
@ -693,8 +681,8 @@ namespace pimoroni {
printf("Outputting PWM to pin: %d\n", pin);
}
i2c_reg_write_uint8(io_pin.reg_pwml, (uint8_t)(value & 0xff));
i2c_reg_write_uint8(io_pin.reg_pwmh, (uint8_t)(value >> 8));
i2c->reg_write_uint8(address, io_pin.reg_pwml, (uint8_t)(value & 0xff));
i2c->reg_write_uint8(address, io_pin.reg_pwmh, (uint8_t)(value >> 8));
if(load)
pwm_load();
}
@ -726,20 +714,20 @@ namespace pimoroni {
output(pin_c, 0);
}
i2c_reg_write_uint8(ENC_CFG[channel], pin_a | (pin_b << 4));
i2c->reg_write_uint8(address, ENC_CFG[channel], pin_a | (pin_b << 4));
change_bit(reg::ENC_EN, (channel * 2) + 1, count_microsteps);
set_bit(reg::ENC_EN, channel * 2);
// Reset internal encoder count to zero
uint8_t reg = ENC_COUNT[channel];
i2c_reg_write_uint8(reg, 0x00);
i2c->reg_write_uint8(address, reg, 0x00);
}
int16_t IOExpander::read_rotary_encoder(uint8_t channel) {
channel -= 1;
int16_t last = encoder_last[channel];
uint8_t reg = ENC_COUNT[channel];
int16_t value = (int16_t)i2c_reg_read_uint8(reg);
int16_t value = (int16_t)i2c->reg_read_uint8(address, reg);
if(value & 0b10000000)
value -= 256;
@ -754,21 +742,9 @@ namespace pimoroni {
return encoder_offset[channel] + value;
}
uint8_t IOExpander::i2c_reg_read_uint8(uint8_t reg) {
uint8_t value;
i2c_write_blocking(i2c, address, &reg, 1, true);
i2c_read_blocking(i2c, address, (uint8_t *)&value, 1, false);
return value;
}
void IOExpander::i2c_reg_write_uint8(uint8_t reg, uint8_t value) {
uint8_t buffer[2] = {reg, value};
i2c_write_blocking(i2c, address, buffer, 2, false);
}
uint8_t IOExpander::get_bit(uint8_t reg, uint8_t bit) {
// Returns the specified bit (nth position from right) from a register
return i2c_reg_read_uint8(reg) & (1 << bit);
return i2c->reg_read_uint8(address, reg) & (1 << bit);
}
void IOExpander::set_bits(uint8_t reg, uint8_t bits) {
@ -780,7 +756,7 @@ namespace pimoroni {
if(BIT_ADDRESSED_REGS[i] == reg) {
for(uint8_t bit = 0; bit < 8; bit++) {
if(bits & (1 << bit))
i2c_reg_write_uint8(reg, 0b1000 | (bit & 0b111));
i2c->reg_write_uint8(address, reg, 0b1000 | (bit & 0b111));
}
reg_in_bit_addressed_regs = true;
break;
@ -789,9 +765,9 @@ namespace pimoroni {
// Now deal with any other registers
if(!reg_in_bit_addressed_regs) {
uint8_t value = i2c_reg_read_uint8(reg);
uint8_t value = i2c->reg_read_uint8(address, reg);
sleep_us(10);
i2c_reg_write_uint8(reg, value | bits);
i2c->reg_write_uint8(address, reg, value | bits);
}
}
@ -806,7 +782,7 @@ namespace pimoroni {
if(BIT_ADDRESSED_REGS[i] == reg) {
for(uint8_t bit = 0; bit < 8; bit++) {
if(bits & (1 << bit))
i2c_reg_write_uint8(reg, 0b0000 | (bit & 0b111));
i2c->reg_write_uint8(address, reg, 0b0000 | (bit & 0b111));
}
reg_in_bit_addressed_regs = true;
break;
@ -815,9 +791,9 @@ namespace pimoroni {
// Now deal with any other registers
if(!reg_in_bit_addressed_regs) {
uint8_t value = i2c_reg_read_uint8(reg);
uint8_t value = i2c->reg_read_uint8(address, reg);
sleep_us(10);
i2c_reg_write_uint8(reg, value & ~bits);
i2c->reg_write_uint8(address, reg, value & ~bits);
}
}

View File

@ -2,6 +2,8 @@
#include "hardware/i2c.h"
#include "hardware/gpio.h"
#include "common/pimoroni_common.hpp"
#include "common/pimoroni_i2c.hpp"
namespace pimoroni {
@ -26,10 +28,6 @@ namespace pimoroni {
public:
static const uint8_t DEFAULT_I2C_ADDRESS = 0x18;
static const uint8_t DEFAULT_SDA_PIN = 20;
static const uint8_t DEFAULT_SCL_PIN = 21;
static const uint8_t DEFAULT_INT_PIN = 22;
static const uint8_t PIN_UNUSED = UINT8_MAX;
static const uint16_t CHIP_ID = 0xE26A;
static const uint8_t CHIP_VERSION = 2;
@ -142,13 +140,11 @@ namespace pimoroni {
// Variables
//--------------------------------------------------
private:
i2c_inst_t *i2c;
I2C *i2c;
// interface pins with our standard defaults where appropriate
int8_t address = DEFAULT_I2C_ADDRESS;
int8_t sda = DEFAULT_SDA_PIN;
int8_t scl = DEFAULT_SCL_PIN;
int8_t interrupt = DEFAULT_INT_PIN;
uint interrupt = PIN_UNUSED;
uint32_t timeout;
bool debug;
@ -162,9 +158,17 @@ namespace pimoroni {
// Constructors/Destructor
//--------------------------------------------------
public:
IOExpander();
IOExpander(uint8_t address, uint32_t timeout = 1, bool debug = false);
IOExpander(i2c_inst_t *i2c, uint8_t address, uint8_t sda, uint8_t scl, uint8_t interrupt = PIN_UNUSED, uint32_t timeout = 1, bool debug = false);
IOExpander() :
IOExpander(new I2C(), DEFAULT_I2C_ADDRESS, PIN_UNUSED, timeout, debug) {};
IOExpander(uint8_t address, uint32_t timeout = 1, bool debug = false) :
IOExpander(new I2C(), address, PIN_UNUSED, timeout, debug) {};
IOExpander(uint8_t address, uint sda, uint scl, uint interrupt = PIN_UNUSED, uint32_t timeout = 1, bool debug = false) :
IOExpander(new I2C(sda, scl), address, interrupt, timeout, debug) {};
// TODO remove MicroPython-binding compatibility constructors
IOExpander(I2C *i2c, uint8_t address=DEFAULT_I2C_ADDRESS, uint interrupt = PIN_UNUSED, uint32_t timeout = 1, bool debug = false);
//--------------------------------------------------

View File

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

View File

@ -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, &reg, 1, true);
i2c_read_blocking(i2c, address, (uint8_t *)&value, 2, false);
return value;
}
void IS31FL3731::enable(std::initializer_list<uint8_t> 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
}
}

View File

@ -2,6 +2,8 @@
#include "hardware/i2c.h"
#include "hardware/gpio.h"
#include "common/pimoroni_common.hpp"
#include "common/pimoroni_i2c.hpp"
#include <initializer_list>
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);
}
//--------------------------------------------------

View File

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

View File

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

View File

@ -2,6 +2,7 @@
#include "hardware/i2c.h"
#include "hardware/gpio.h"
#include "common/pimoroni_i2c.hpp"
namespace pimoroni {
@ -16,8 +17,6 @@ namespace pimoroni {
static const uint8_t DEFAULT_I2C_ADDRESS = 0x61;
static const uint8_t I2C_ADDRESS_ALTERNATE1 = 0x62;
static const uint8_t I2C_ADDRESS_ALTERNATE2 = 0x63;
static const uint8_t DEFAULT_SDA_PIN = 20;
static const uint8_t DEFAULT_SCL_PIN = 21;
static const uint8_t DEFAULT_BRIGHTNESS = 64;
static const uint8_t MAX_BRIGHTNESS = 127;
@ -43,12 +42,10 @@ namespace pimoroni {
// Variables
//--------------------------------------------------
private:
i2c_inst_t *i2c = i2c0;
I2C *i2c;
// interface pins with our standard defaults where appropriate
int8_t address = DEFAULT_I2C_ADDRESS;
int8_t sda = DEFAULT_SDA_PIN;
int8_t scl = DEFAULT_SCL_PIN;
uint8_t brightness = DEFAULT_BRIGHTNESS;
@ -91,8 +88,10 @@ namespace pimoroni {
LTP305(uint8_t address) :
address(address) {}
LTP305(i2c_inst_t *i2c, uint8_t address, uint8_t sda, uint8_t scl) :
i2c(i2c), address(address), sda(sda), scl(scl) {}
LTP305(I2C *i2c, uint8_t address = DEFAULT_I2C_ADDRESS) :
i2c(i2c), address(address) {}
LTP305(uint8_t address, uint sda, uint scl) : LTP305(new I2C(sda, scl), address) {}
//--------------------------------------------------
@ -114,9 +113,6 @@ namespace pimoroni {
uint16_t offset_x, uint16_t offset_y, bool wrap = false, bool bg = false, uint8_t on_level = DEFAULT_ON_LEVEL, uint8_t padding = 0);
void clear();
void show();
private:
void i2c_reg_write_uint8(uint8_t reg, uint8_t value);
};
}

View File

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

View File

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

View File

@ -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 <vector>
#include <initializer_list>
@ -85,6 +86,7 @@
namespace pimoroni {
typedef struct {
uint16_t proximity;
uint16_t als0;
@ -110,10 +112,6 @@ namespace pimoroni {
//--------------------------------------------------
public:
static const uint8_t DEFAULT_I2C_ADDRESS = 0x23;
static const uint8_t DEFAULT_SDA_PIN = 20;
static const uint8_t DEFAULT_SCL_PIN = 21;
static const uint8_t DEFAULT_INT_PIN = 22;
static const uint8_t PIN_UNUSED = UINT8_MAX;
private:
const int ch0_c[4] = {17743, 42785, 5926, 0};
@ -127,13 +125,11 @@ namespace pimoroni {
ltr559_reading data;
private:
i2c_inst_t *i2c = i2c0;
I2C *i2c;
// interface pins with our standard defaults where appropriate
int8_t address = DEFAULT_I2C_ADDRESS;
int8_t sda = DEFAULT_SDA_PIN;
int8_t scl = DEFAULT_SCL_PIN;
int8_t interrupt = DEFAULT_INT_PIN;
const uint8_t address = DEFAULT_I2C_ADDRESS;
uint interrupt = PIN_UNUSED;
static pimoroni::lookup lookup_led_current;
static pimoroni::lookup lookup_led_duty_cycle;
@ -148,14 +144,12 @@ namespace pimoroni {
// Constructors/Destructor
//--------------------------------------------------
public:
LTR559() {}
LTR559() : LTR559(new I2C()) {};
LTR559(uint8_t address) :
address(address) {}
LTR559(i2c_inst_t *i2c, uint8_t address, uint8_t sda, uint8_t scl, uint8_t interrupt = PIN_UNUSED) :
i2c(i2c), address(address), sda(sda), scl(scl), interrupt(interrupt) {}
LTR559(I2C *i2c, uint interrupt = PIN_UNUSED) : i2c(i2c), interrupt(interrupt) {}
// TODO remove MicroPython-binding compatibility constructors
LTR559(uint sda, uint scl, uint interrupt = PIN_UNUSED) : LTR559(new I2C(), interrupt) {}
//--------------------------------------------------
// Methods
@ -188,13 +182,6 @@ namespace pimoroni {
private:
uint16_t bit12_to_uint16(uint16_t value);
uint16_t uint16_to_bit12(uint16_t value);
// From i2cdevice
int write_bytes(uint8_t reg, uint8_t *buf, int len);
int read_bytes(uint8_t reg, uint8_t *buf, int len);
uint8_t get_bits(uint8_t reg, uint8_t shift, uint8_t mask=0b1);
void set_bits(uint8_t reg, uint8_t shift, uint8_t mask=0b1);
void clear_bits(uint8_t reg, uint8_t shift, uint8_t mask=0b1);
};
}

View File

@ -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)
include(msa301.cmake)

View File

@ -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)
target_link_libraries(msa301 INTERFACE pico_stdlib hardware_i2c pimoroni_i2c)

View File

@ -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, &reg, 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, &reg, 1, true);
i2c_read_blocking(i2c, address, (uint8_t *)&value, 2, false);
return value;
return i2c->reg_read_uint8(address, MOTION_INTERRUPT) & (1U << bit);
}
}

View File

@ -2,6 +2,8 @@
#include "hardware/i2c.h"
#include "hardware/gpio.h"
#include "common/pimoroni_common.hpp"
#include "common/pimoroni_i2c.hpp"
namespace pimoroni {
@ -11,10 +13,6 @@ namespace pimoroni {
//--------------------------------------------------
public:
static const uint8_t DEFAULT_I2C_ADDRESS = 0x26;
static const uint8_t DEFAULT_SDA_PIN = 20;
static const uint8_t DEFAULT_SCL_PIN = 21;
static const uint8_t DEFAULT_INT_PIN = 22;
static const uint8_t PIN_UNUSED = UINT8_MAX;
static const uint8_t SOFT_RESET = 0x00;
static const uint8_t PART_ID = 0x01;
@ -106,23 +104,20 @@ namespace pimoroni {
// Variables
//--------------------------------------------------
private:
i2c_inst_t *i2c = i2c0;
// interface pins with our standard defaults where appropriate
int8_t address = DEFAULT_I2C_ADDRESS;
int8_t sda = DEFAULT_SDA_PIN;
int8_t scl = DEFAULT_SCL_PIN;
int8_t interrupt = DEFAULT_INT_PIN;
I2C *i2c;
const uint8_t address = DEFAULT_I2C_ADDRESS;
uint interrupt = PIN_UNUSED;
//--------------------------------------------------
// Constructors/Destructor
//--------------------------------------------------
public:
MSA301() {}
MSA301() : MSA301(new I2C()) {};
MSA301(i2c_inst_t *i2c, uint8_t sda, uint8_t scl, uint8_t interrupt) :
i2c(i2c), sda(sda), scl(scl), interrupt(interrupt) {}
MSA301(I2C *i2c, uint interrupt = PIN_UNUSED) : i2c(i2c), interrupt(interrupt) {}
// TODO remove MicroPython-binding compatibility constructors
MSA301(i2c_inst_t *i2c_inst, uint sda, uint scl, uint interrupt = PIN_UNUSED) : MSA301(new I2C(sda, scl), interrupt) {}
//--------------------------------------------------
@ -152,11 +147,6 @@ namespace pimoroni {
void enable_interrupts(uint16_t interrupts);
void set_interrupt_latch(InterruptLatchPeriod latch_period, bool reset_latched);
bool read_interrupt(Interrupt interrupt);
private:
void i2c_reg_write_uint8(uint8_t reg, uint8_t value);
uint8_t i2c_reg_read_uint8(uint8_t reg);
int16_t i2c_reg_read_int16(uint8_t reg);
};
}

View File

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

View File

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

View File

@ -12,6 +12,8 @@ Distributed as-is; no warranty is given.
#include "hardware/i2c.h"
#include "hardware/gpio.h"
#include "common/pimoroni_common.hpp"
#include "common/pimoroni_i2c.hpp"
#include <stdio.h>
#include <stdlib.h>
@ -196,8 +198,6 @@ namespace pimoroni {
//--------------------------------------------------
public:
static const uint8_t DEFAULT_I2C_ADDRESS = RV3028_ADDR;
static const uint8_t DEFAULT_SDA_PIN = 20;
static const uint8_t DEFAULT_SCL_PIN = 21;
static const uint8_t DEFAULT_INT_PIN = 22;
static const uint8_t PIN_UNUSED = UINT8_MAX;
@ -206,13 +206,11 @@ namespace pimoroni {
// Variables
//--------------------------------------------------
private:
i2c_inst_t *i2c = i2c0;
I2C *i2c;
// interface pins with our standard defaults where appropriate
int8_t address = DEFAULT_I2C_ADDRESS;
int8_t sda = DEFAULT_SDA_PIN;
int8_t scl = DEFAULT_SCL_PIN;
int8_t interrupt = DEFAULT_INT_PIN;
const int8_t address = DEFAULT_I2C_ADDRESS;
uint interrupt = DEFAULT_INT_PIN;
uint8_t times[TIME_ARRAY_LENGTH];
@ -221,10 +219,13 @@ namespace pimoroni {
// Constructors/Destructor
//--------------------------------------------------
public:
RV3028() {}
RV3028() : RV3028(new I2C()) {}
RV3028(i2c_inst_t *i2c, uint8_t sda, uint8_t scl, uint8_t interrupt = PIN_UNUSED) :
i2c(i2c), sda(sda), scl(scl), interrupt(interrupt) {}
RV3028(I2C *i2c, uint interrupt = DEFAULT_INT_PIN) :
i2c(i2c), interrupt(interrupt) {}
// TODO remove MicroPython-binding compatibility constructors
RV3028(i2c_inst_t *i2c, uint sda, uint scl, uint interrupt = DEFAULT_INT_PIN) : RV3028(new I2C(sda, scl), interrupt) {}
//--------------------------------------------------
@ -324,13 +325,6 @@ private:
void set_bit(uint8_t reg_addr, uint8_t bit_num);
void clear_bit(uint8_t reg_addr, uint8_t bit_num);
bool read_bit(uint8_t reg_addr, uint8_t bit_num);
// From i2cdevice
int write_bytes(uint8_t reg, uint8_t *buf, int len);
int read_bytes(uint8_t reg, uint8_t *buf, int len);
uint8_t get_bits(uint8_t reg, uint8_t shift, uint8_t mask = 0b1);
void set_bits(uint8_t reg, uint8_t shift, uint8_t mask = 0b1);
void clear_bits(uint8_t reg, uint8_t shift, uint8_t mask = 0b1);
};
// POSSIBLE ENHANCEMENTS :

View File

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

View File

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

View File

@ -2,6 +2,8 @@
#include "hardware/i2c.h"
#include "hardware/gpio.h"
#include "common/pimoroni_common.hpp"
#include "common/pimoroni_i2c.hpp"
// commands and constants
#define SGP30_REQ_FEATURES 0x0020 // The required feature set
@ -16,8 +18,6 @@ namespace pimoroni {
//--------------------------------------------------
public:
static const uint8_t DEFAULT_I2C_ADDRESS = 0x58;
static const uint8_t DEFAULT_SDA_PIN = 20;
static const uint8_t DEFAULT_SCL_PIN = 21;
private:
/***** Private constants here *****/
@ -37,22 +37,21 @@ namespace pimoroni {
// Variables
//--------------------------------------------------
private:
i2c_inst_t *i2c = i2c0;
I2C *i2c;
int8_t address = DEFAULT_I2C_ADDRESS;
int8_t sda = DEFAULT_SDA_PIN;
int8_t scl = DEFAULT_SCL_PIN;
const int8_t address = DEFAULT_I2C_ADDRESS;
//--------------------------------------------------
// Constructors/Destructor
//--------------------------------------------------
public:
SGP30() {}
SGP30() : SGP30(new I2C()) {};
SGP30(i2c_inst_t *i2c, uint8_t sda, uint8_t scl) :
i2c(i2c), sda(sda), scl(scl) {}
SGP30(I2C *i2c) : i2c(i2c) {}
// TODO remove MicroPython-binding compatibility constructors
SGP30(i2c_inst_t *i2c_inst, uint sda, uint scl) : i2c(new I2C(sda, scl)) { }
//--------------------------------------------------
// Methods

View File

@ -2,6 +2,7 @@
#include "hardware/spi.h"
#include "hardware/gpio.h"
#include "../../common/pimoroni_common.hpp"
namespace pimoroni {
@ -20,17 +21,6 @@ namespace pimoroni {
static const uint8_t ROWS = 162;
static const uint8_t COLS = 132;
//--------------------------------------------------
// Enums
//--------------------------------------------------
public:
enum BG_SPI_SLOT {
BG_SPI_FRONT,
BG_SPI_BACK
};
//--------------------------------------------------
// Variables
//--------------------------------------------------

View File

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

View File

@ -2,29 +2,12 @@
#include "hardware/spi.h"
#include "hardware/gpio.h"
#include "../../common/pimoroni_common.hpp"
namespace pimoroni {
class ST7789 {
//--------------------------------------------------
// Constants
//--------------------------------------------------
public:
static const uint8_t DEFAULT_CS_PIN = 17;
static const uint8_t DEFAULT_DC_PIN = 16;
static const uint8_t DEFAULT_SCK_PIN = 18;
static const uint8_t DEFAULT_MOSI_PIN = 19;
static const uint8_t DEFAULT_BL_PIN = 20;
//--------------------------------------------------
// Enums
//--------------------------------------------------
public:
enum BG_SPI_SLOT {
BG_SPI_FRONT,
BG_SPI_BACK
};
spi_inst_t *spi = PIMORONI_SPI_DEFAULT_INSTANCE;
//--------------------------------------------------
@ -35,42 +18,33 @@ namespace pimoroni {
uint16_t width;
uint16_t height;
uint16_t row_stride;
uint32_t dma_channel;
// interface pins with our standard defaults where appropriate
uint cs = SPI_BG_FRONT_CS;
uint dc = SPI_DEFAULT_MISO;
uint sck = SPI_DEFAULT_SCK;
uint mosi = SPI_DEFAULT_MOSI;
uint miso = PIN_UNUSED; // used as data/command
uint bl = SPI_BG_FRONT_PWM;
uint vsync = PIN_UNUSED; // only available on some products
uint32_t spi_baud = 16 * 1000 * 1000;
public:
// frame buffer where pixel data is stored
uint16_t *frame_buffer;
private:
spi_inst_t *spi = spi0;
uint32_t dma_channel;
// interface pins with our standard defaults where appropriate
int8_t cs = DEFAULT_CS_PIN;
int8_t dc = DEFAULT_DC_PIN;
int8_t sck = DEFAULT_SCK_PIN;
int8_t mosi = DEFAULT_MOSI_PIN;
int8_t miso = -1; // we generally don't use this pin
int8_t bl = DEFAULT_BL_PIN;
int8_t vsync = -1; // only available on some products
uint32_t spi_baud = 16 * 1000 * 1000;
//--------------------------------------------------
// Constructors/Destructor
//--------------------------------------------------
public:
ST7789(uint16_t width, uint16_t height, uint16_t *frame_buffer, BG_SPI_SLOT slot) :
width(width), height(height), frame_buffer(frame_buffer) {
switch(slot) {
case BG_SPI_FRONT:
cs = 17;
bl = 20;
cs = SPI_BG_FRONT_CS;
bl = SPI_BG_FRONT_PWM;
break;
case BG_SPI_BACK:
cs = 22;
bl = 21;
cs = SPI_BG_BACK_CS;
bl = SPI_BG_BACK_PWM;
break;
}
}
@ -80,9 +54,10 @@ namespace pimoroni {
ST7789(uint16_t width, uint16_t height, uint16_t *frame_buffer,
spi_inst_t *spi,
uint8_t cs, uint8_t dc, uint8_t sck, uint8_t mosi, uint8_t miso = -1, uint8_t bl = -1) :
width(width), height(height), frame_buffer(frame_buffer),
spi(spi), cs(cs), dc(dc), sck(sck), mosi(mosi), miso(miso), bl(bl) {}
uint cs, uint dc, uint sck, uint mosi, uint miso = PIN_UNUSED, uint bl = PIN_UNUSED) :
spi(spi),
width(width), height(height),
cs(cs), dc(dc), sck(sck), mosi(mosi), miso(miso), bl(bl), frame_buffer(frame_buffer) {}
//--------------------------------------------------
@ -92,11 +67,11 @@ namespace pimoroni {
void init(bool auto_init_sequence = true, bool round = false);
spi_inst_t* get_spi() const;
int get_cs() const;
int get_dc() const;
int get_sck() const;
int get_mosi() const;
int get_bl() const;
uint get_cs() const;
uint get_dc() const;
uint get_sck() const;
uint get_mosi() const;
uint get_bl() const;
void command(uint8_t command, size_t len = 0, const char *data = NULL);
void vsync_callback(gpio_irq_callback_t callback);

View File

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

View File

@ -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, &reg, 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()) {

View File

@ -2,6 +2,7 @@
#include "hardware/i2c.h"
#include "hardware/gpio.h"
#include "common/pimoroni_i2c.hpp"
namespace pimoroni {
@ -12,11 +13,7 @@ namespace pimoroni {
public:
static const uint8_t DEFAULT_I2C_ADDRESS = 0x0A;
static const uint8_t I2C_ADDRESS_ALTERNATIVE = 0x0B;
static const uint8_t DEFAULT_SDA_PIN = 20;
static const uint8_t DEFAULT_SCL_PIN = 21;
static const uint8_t DEFAULT_INT_PIN = 22;
static const uint32_t DEFAULT_TIMEOUT = 5;
static const uint8_t PIN_UNUSED = UINT8_MAX;
private:
static const uint16_t CHIP_ID = 0xBA11;
@ -41,13 +38,9 @@ namespace pimoroni {
// Variables
//--------------------------------------------------
private:
i2c_inst_t *i2c = i2c0;
// interface pins with our standard defaults where appropriate
I2C *i2c;
int8_t address = DEFAULT_I2C_ADDRESS;
int8_t sda = DEFAULT_SDA_PIN;
int8_t scl = DEFAULT_SCL_PIN;
int8_t interrupt = DEFAULT_INT_PIN;
uint interrupt = PIN_UNUSED;
uint32_t timeout = DEFAULT_TIMEOUT;
@ -55,14 +48,12 @@ namespace pimoroni {
// Constructors/Destructor
//--------------------------------------------------
public:
Trackball() {};
Trackball(uint8_t address = DEFAULT_I2C_ADDRESS) : i2c(new I2C()), address(address) {};
Trackball(uint8_t address) :
address(address) {}
Trackball(i2c_inst_t *i2c, uint8_t address, uint8_t sda, uint8_t scl, uint8_t interrupt = PIN_UNUSED, uint32_t timeout = DEFAULT_TIMEOUT) :
i2c(i2c), address(address), sda(sda), scl(scl), interrupt(interrupt), timeout(timeout) {}
Trackball(I2C *i2c, uint8_t address = DEFAULT_I2C_ADDRESS, uint interrupt = PIN_UNUSED, uint32_t timeout = DEFAULT_TIMEOUT) : i2c(i2c), address(address), interrupt(interrupt) {}
// TODO remove MicroPython-binding compatibility constructors
Trackball(i2c_inst_t *i2c_inst, uint8_t address, uint sda, uint scl, uint interrupt = PIN_UNUSED, uint32_t timeout = DEFAULT_TIMEOUT) : Trackball(new I2C(sda, scl), address, interrupt) {}
//--------------------------------------------------
// Methods
@ -88,9 +79,6 @@ namespace pimoroni {
State read();
private:
uint8_t i2c_reg_read_uint8(uint8_t reg);
void i2c_reg_write_uint8(uint8_t reg, uint8_t value);
void wait_for_flash();
uint32_t millis();

View File

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

View File

@ -37,12 +37,6 @@ namespace pimoroni {
saved_vhv_timeout = 0;
// distance_mode = 1;
// Initialise I2C connection
i2c_init(i2c, 400000);
gpio_set_function(sda, GPIO_FUNC_I2C); gpio_pull_up(sda);
gpio_set_function(scl, GPIO_FUNC_I2C); gpio_pull_up(scl);
last_status = 0;
// check model ID and module type registers (values specified in datasheet)
@ -168,61 +162,62 @@ namespace pimoroni {
// Write an 8-bit register
void VL53L1X::writeReg(uint16_t reg, uint8_t value)
{
uint8_t buffer[3] = {(reg >> 8) & 0xFF, reg & 0xFF, value};
i2c_write_blocking(i2c, address, buffer, 3, false);
alignas(2) struct u16_u32_buffer {
uint16_t reg;
uint8_t value;
} buffer{reg, value};
i2c->write_blocking(address, (uint8_t *)&buffer, 3, false);
}
// Write a 16-bit register
void VL53L1X::writeReg16Bit(uint16_t reg, uint16_t value)
{
uint8_t buffer[4] = {(reg >> 8) & 0xFF, reg & 0xFF, (value >> 8) & 0xFF, value & 0xFF};
i2c_write_blocking(i2c, address, buffer, 4, false);
uint16_t buffer[2] = {reg, value};
i2c->write_blocking(address, (uint8_t *)buffer, 4, false);
}
// Write a 32-bit register
void VL53L1X::writeReg32Bit(uint16_t reg, uint32_t value)
{
uint8_t buffer[6] = {(reg >> 8) & 0xFF, reg & 0xFF,
(value >> 24) & 0xFF, (value >> 16) & 0xFF, (value >> 8) & 0xFF, value & 0xFF};
i2c_write_blocking(i2c, address, buffer, 6, false);
alignas(2) struct u16_u32_buffer {
uint16_t reg;
uint32_t value;
} buffer{reg, value};
i2c->write_blocking(address, (uint8_t *)&buffer, 6, false);
}
// Read an 8-bit register
uint8_t VL53L1X::readReg(regAddr reg)
{
uint8_t regbuf[2] = {((uint8_t)reg >> 8) & 0xFF, (uint8_t)reg & 0xFF};
uint8_t buffer[1];
uint8_t value;
i2c_write_blocking(i2c, address, regbuf, 2, true);
i2c_read_blocking(i2c, address, buffer, 1, false);
value = buffer[0];
// TODO do we need to bswap reg?
i2c->write_blocking(address, (uint8_t *)&reg, 2, true);
i2c->read_blocking(address, &value, 1, false);
return value;
}
// Read a 16-bit register
uint16_t VL53L1X::readReg16Bit(uint16_t reg)
{
uint8_t regbuf[2] = {(reg >> 8) & 0xFF, reg & 0xFF};
uint8_t buffer[2];
uint16_t value;
reg= (reg << 8) + (reg >> 8);
i2c_write_blocking(i2c, address, regbuf, 2, true);
i2c_read_blocking(i2c, address, buffer, 2, false);
value= (buffer[0] << 8) + buffer[1];
return value;
// TODO do we need to bswap reg?
i2c->write_blocking(address, (uint8_t *)&reg, 2, true);
i2c->read_blocking(address, (uint8_t *)&value, 2, false);
// TODO do we need to bswap this return value?
return __bswap16(value);
}
// Read a 32-bit register
uint32_t VL53L1X::readReg32Bit(uint16_t reg)
{
uint8_t regbuf[2] = {(reg >> 8) & 0xFF, reg & 0xFF};
uint8_t buffer[4];
uint32_t value;
reg= (reg << 8) + (reg >> 8);
i2c_write_blocking(i2c, address, regbuf, 2, true);
i2c_read_blocking(i2c, address, buffer, 4, false);
value= (buffer[0] << 24) + (buffer[1] << 16) + (buffer[2] << 8) + buffer[3];
return value;
i2c->write_blocking(address, (uint8_t *)&reg, 2, true);
i2c->read_blocking(address, (uint8_t *)&value, 4, false);
// TODO do we need to bswap this return value?
return __bswap32(value);
}
// set distance mode to Short, Medium, or Long
@ -578,10 +573,10 @@ namespace pimoroni {
void VL53L1X::readResults()
{
uint16_t reg = RESULT__RANGE_STATUS;
uint8_t regbuf[2] = {(reg >> 8) & 0xFF, reg & 0xFF};
// TODO do we need to bswap reg?
uint8_t buffer[17];
i2c_write_blocking(i2c, address, regbuf, 2, true);
i2c_read_blocking(i2c, address, buffer, 17, false);
i2c->write_blocking(address, (uint8_t *)&reg, 2, true);
i2c->read_blocking(address, buffer, 17, false);
results.range_status = buffer[0];

View File

@ -15,17 +15,17 @@ Distributed as-is; no warranty is given.
#include <stdio.h>
#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();

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -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() {

View File

@ -1,6 +1,7 @@
#include "pico/stdlib.h"
#include <stdio.h>
#include <math.h>
#include "common/pimoroni_common.hpp"
#include "breakout_encoder.hpp"
@ -8,7 +9,8 @@ using namespace pimoroni;
static const uint8_t STEPS_PER_REV = 24;
BreakoutEncoder enc;
I2C i2c(BOARD::BREAKOUT_GARDEN);
BreakoutEncoder enc(&i2c);
bool toggle = false;
// HSV Conversion expects float inputs in the range of 0.00-1.00 for each channel
@ -34,7 +36,7 @@ void from_hsv(float h, float s, float v, uint8_t &r, uint8_t &g, uint8_t &b) {
void count_changed(int16_t count) {
printf("Count: %d\n", count);
float h = (count % STEPS_PER_REV) / (float)STEPS_PER_REV;
uint8_t r, g, b;
uint8_t r = 0, g = 0, b = 0;
from_hsv(h, 1.0f, 1.0f, r, g, b);
enc.set_led(r, g, b);
}

View File

@ -5,7 +5,8 @@
using namespace pimoroni;
BreakoutLTR559 ltr559;
I2C i2c(BOARD::BREAKOUT_GARDEN);
BreakoutLTR559 ltr559(&i2c);
int main() {
stdio_init_all();
@ -13,7 +14,13 @@ int main() {
ltr559.init();
uint8_t part_id = ltr559.part_id();
printf("Found LTR559. Part ID: 0x%02x\n", part_id);
if(part_id == LTR559_VALID_PART_ID) {
printf("Found LTR559. Part ID: 0x%02x\n", part_id);
}
else
{
printf("Could not find LTR559. Got Part ID: 0x%02x, expected 0x%02x\n", part_id, LTR559_VALID_PART_ID);
}
while(true){
bool new_data = ltr559.get_reading();

View File

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

View File

@ -1,11 +1,13 @@
#include <stdio.h>
#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();

View File

@ -1,12 +1,14 @@
#include "pico/stdlib.h"
#include <stdio.h>
#include <math.h>
#include "common/pimoroni_common.hpp"
#include "breakout_potentiometer.hpp"
using namespace pimoroni;
BreakoutPotentiometer pot;
I2C i2c(BOARD::BREAKOUT_GARDEN);
BreakoutPotentiometer pot(&i2c);
bool toggle = false;
// HSV Conversion expects float inputs in the range of 0.00-1.00 for each channel
@ -35,7 +37,6 @@ int main() {
stdio_init_all();
int16_t count = 0;
if(pot.init()) {
printf("Potentiometer found...\n");
@ -48,7 +49,7 @@ int main() {
float percent = pot.read();
printf("Percent: %d\n", (int)(percent * 100));
uint8_t r, g, b;
uint8_t r = 0, g = 0, b = 0;
from_hsv(percent, 1.0f, 1.0f, r, g, b);
pot.set_led(r, g, b);

View File

@ -7,7 +7,8 @@
using namespace pimoroni;
BreakoutRGBMatrix5x5 rgbmatrix5x5;
I2C i2c(BOARD::BREAKOUT_GARDEN);
BreakoutRGBMatrix5x5 rgbmatrix5x5(&i2c);
int main() {
rgbmatrix5x5.init();

View File

@ -12,12 +12,12 @@ using namespace pimoroni;
uint16_t buffer[BreakoutRoundLCD::WIDTH * BreakoutRoundLCD::HEIGHT];
BreakoutRoundLCD display(buffer, ST7789::BG_SPI_FRONT);
BreakoutRoundLCD display(buffer, BG_SPI_FRONT);
constexpr float RADIUS = BreakoutRoundLCD::WIDTH / 2;
Pen from_hsv(float h, float s, float v) {
uint8_t r, g, b;
uint8_t r = 0, g = 0, b = 0;
float i = floor(h * 6.0f);
float f = h * 6.0f - i;

View File

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

View File

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

View File

@ -13,13 +13,13 @@
using namespace pimoroni;
BreakoutSGP30 sgp30;
I2C i2c(BOARD::BREAKOUT_GARDEN);
BreakoutSGP30 sgp30(&i2c);
int main() {
uint8_t prd;
uint16_t eCO2, TVOC;
uint16_t raweCO2, rawTVOC;
uint16_t baseCO2, baseTVOC;
uint16_t rawCO2, rawTVOC;
gpio_init(PICO_DEFAULT_LED_PIN);
gpio_set_dir(PICO_DEFAULT_LED_PIN, GPIO_OUT);
@ -56,8 +56,8 @@ int main() {
sleep_ms(1000 - (100 * prd));
if(prd == 1) {
sgp30.get_air_quality(&eCO2, &TVOC);
sgp30.get_air_quality_raw(&raweCO2, &rawTVOC);
printf("%3d: CO2 %d TVOC %d, raw %d %d\n", j, eCO2, TVOC, raweCO2, rawTVOC);
sgp30.get_air_quality_raw(&rawCO2, &rawTVOC);
printf("%3d: CO2 %d TVOC %d, raw %d %d\n", j, eCO2, TVOC, rawCO2, rawTVOC);
if(j == 30) {
printf("Resetting device\n");
sgp30.soft_reset();

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -8,12 +8,12 @@ namespace pimoroni {
}
BreakoutColourLCD160x80::BreakoutColourLCD160x80(uint16_t *buf, spi_inst_t *spi,
uint8_t cs, uint8_t dc, uint8_t sck, uint8_t mosi, uint8_t miso, uint8_t bl)
uint cs, uint dc, uint sck, uint mosi, uint miso, uint bl)
: PicoGraphics(WIDTH, HEIGHT, buf), screen(WIDTH, HEIGHT, buf, spi, cs, dc, sck, mosi, miso, bl) {
__fb = buf;
}
BreakoutColourLCD160x80::BreakoutColourLCD160x80(uint16_t *buf, ST7735::BG_SPI_SLOT slot)
BreakoutColourLCD160x80::BreakoutColourLCD160x80(uint16_t *buf, BG_SPI_SLOT slot)
: PicoGraphics(WIDTH, HEIGHT, buf), screen(WIDTH, HEIGHT, buf, slot) {
__fb = buf;
}

View File

@ -2,6 +2,7 @@
#include "drivers/st7735/st7735.hpp"
#include "libraries/pico_graphics/pico_graphics.hpp"
#include "common/pimoroni_common.hpp"
namespace pimoroni {
@ -12,8 +13,6 @@ namespace pimoroni {
public:
static const int WIDTH = 160;
static const int HEIGHT = 80;
static const uint8_t PIN_UNUSED = UINT8_MAX;
//--------------------------------------------------
// Variables
@ -30,8 +29,8 @@ namespace pimoroni {
public:
BreakoutColourLCD160x80(uint16_t *buf);
BreakoutColourLCD160x80(uint16_t *buf, spi_inst_t *spi,
uint8_t cs, uint8_t dc, uint8_t sck, uint8_t mosi, uint8_t miso = PIN_UNUSED, uint8_t bl = PIN_UNUSED);
BreakoutColourLCD160x80(uint16_t *buf, ST7735::BG_SPI_SLOT slot);
uint cs, uint dc, uint sck, uint mosi, uint miso = PIN_UNUSED, uint bl = PIN_UNUSED);
BreakoutColourLCD160x80(uint16_t *buf, BG_SPI_SLOT slot);
//--------------------------------------------------

View File

@ -8,12 +8,12 @@ namespace pimoroni {
}
BreakoutColourLCD240x240::BreakoutColourLCD240x240(uint16_t *buf, spi_inst_t *spi,
uint8_t cs, uint8_t dc, uint8_t sck, uint8_t mosi, uint8_t miso, uint8_t bl)
uint cs, uint dc, uint sck, uint mosi, uint miso, uint bl)
: PicoGraphics(WIDTH, HEIGHT, buf), screen(WIDTH, HEIGHT, buf, spi, cs, dc, sck, mosi, miso, bl) {
__fb = buf;
}
BreakoutColourLCD240x240::BreakoutColourLCD240x240(uint16_t *buf, ST7789::BG_SPI_SLOT slot)
BreakoutColourLCD240x240::BreakoutColourLCD240x240(uint16_t *buf, BG_SPI_SLOT slot)
: PicoGraphics(WIDTH, HEIGHT, buf), screen(WIDTH, HEIGHT, buf, slot) {
__fb = buf;
}

View File

@ -2,6 +2,7 @@
#include "drivers/st7789/st7789.hpp"
#include "libraries/pico_graphics/pico_graphics.hpp"
#include "common/pimoroni_common.hpp"
namespace pimoroni {
@ -12,8 +13,6 @@ namespace pimoroni {
public:
static const int WIDTH = 240;
static const int HEIGHT = 240;
static const uint8_t PIN_UNUSED = UINT8_MAX;
//--------------------------------------------------
// Variables
@ -30,8 +29,8 @@ namespace pimoroni {
public:
BreakoutColourLCD240x240(uint16_t *buf);
BreakoutColourLCD240x240(uint16_t *buf, spi_inst_t *spi,
uint8_t cs, uint8_t dc, uint8_t sck, uint8_t mosi, uint8_t miso = PIN_UNUSED, uint8_t bl = PIN_UNUSED);
BreakoutColourLCD240x240(uint16_t *buf, ST7789::BG_SPI_SLOT slot);
uint cs, uint dc, uint sck, uint mosi, uint miso = PIN_UNUSED, uint bl = PIN_UNUSED);
BreakoutColourLCD240x240(uint16_t *buf, BG_SPI_SLOT slot);
//--------------------------------------------------

View File

@ -1,6 +1,7 @@
#pragma once
#include "drivers/ioexpander/ioexpander.hpp"
#include "common/pimoroni_common.hpp"
namespace pimoroni {
@ -46,22 +47,20 @@ namespace pimoroni {
IOExpander ioe;
Direction direction = DEFAULT_DIRECTION;
float brightness = DEFAULT_BRIGHTNESS;
uint8_t interrupt_pin = PIN_UNUSED; // A local copy of the value passed to the IOExpander, used in initialisation
uint interrupt_pin = PIN_UNUSED; // A local copy of the value passed to the IOExpander, used in initialisation
//--------------------------------------------------
// Constructors/Destructor
//--------------------------------------------------
public:
BreakoutEncoder() :
ioe(DEFAULT_I2C_ADDRESS) {}
BreakoutEncoder(uint8_t address = DEFAULT_I2C_ADDRESS) : BreakoutEncoder(new I2C(), address) {};
BreakoutEncoder(uint8_t address) :
ioe(address) {}
BreakoutEncoder(I2C *i2c, uint8_t address = DEFAULT_I2C_ADDRESS, uint interrupt = PIN_UNUSED, uint32_t timeout = DEFAULT_TIMEOUT, bool debug = false) :
ioe(i2c, address, interrupt, timeout, debug) {}
BreakoutEncoder(i2c_inst_t *i2c, uint8_t address, uint8_t sda, uint8_t scl, uint8_t interrupt = PIN_UNUSED, uint32_t timeout = DEFAULT_TIMEOUT) :
ioe(i2c, address, sda, scl, interrupt, timeout),
interrupt_pin(interrupt) {}
// TODO remove MicroPython-binding compatibility constructors
BreakoutEncoder(uint8_t address, uint sda, uint scl, uint interrupt = PIN_UNUSED, uint32_t timeout = DEFAULT_TIMEOUT) : BreakoutEncoder(new I2C(sda, scl), address, interrupt, timeout) {};
//--------------------------------------------------

View File

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

View File

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

View File

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

View File

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

View File

@ -22,7 +22,6 @@ namespace pimoroni {
static const uint8_t DEFAULT_I2C_ADDRESS = 0x0E;
static constexpr float DEFAULT_BRIGHTNESS = 1.0f; //Effectively the maximum fraction of the period that the LED will be on
static const Direction DEFAULT_DIRECTION = DIRECTION_CW;
static const uint8_t PIN_UNUSED = UINT8_MAX;
static const uint32_t DEFAULT_TIMEOUT = 1;
static const uint32_t DEFAULT_ADC_TIMEOUT = 1;
@ -51,14 +50,13 @@ namespace pimoroni {
// Constructors/Destructor
//--------------------------------------------------
public:
BreakoutPotentiometer() :
ioe(DEFAULT_I2C_ADDRESS) {}
BreakoutPotentiometer(uint8_t address = DEFAULT_I2C_ADDRESS) : BreakoutPotentiometer(new I2C(), address) {};
BreakoutPotentiometer(uint8_t address) :
ioe(address) {}
BreakoutPotentiometer(I2C *i2c, uint8_t address = DEFAULT_I2C_ADDRESS, uint interrupt = PIN_UNUSED, uint32_t timeout = DEFAULT_TIMEOUT, bool debug = false) :
ioe(i2c, address, interrupt, timeout, debug) {}
BreakoutPotentiometer(i2c_inst_t *i2c, uint8_t address, uint8_t sda, uint8_t scl, uint8_t interrupt = PIN_UNUSED, uint32_t timeout = DEFAULT_TIMEOUT) :
ioe(i2c, address, sda, scl, interrupt, timeout) {}
// TODO remove MicroPython-binding compatibility constructors
BreakoutPotentiometer(uint8_t address, uint sda, uint scl, uint interrupt = PIN_UNUSED, uint32_t timeout = DEFAULT_TIMEOUT) : BreakoutPotentiometer(new I2C(sda, scl), address, interrupt, timeout) {};
//--------------------------------------------------

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -1,3 +1,4 @@
from pimoroni_i2c import PimoroniI2C
from breakout_as7262 import BreakoutAS7262
import picoexplorer as display
import time
@ -11,7 +12,8 @@ bar_height = height
display_buffer = bytearray(width * height * 2) # 2-bytes per pixel (RGB565)
display.init(display_buffer)
as7 = BreakoutAS7262()
i2c = PimoroniI2C(20, 21)
as7 = BreakoutAS7262(i2c)
integration_time = 10 # integration time in milliseconds, max ~90ms

View File

@ -2,9 +2,14 @@ import time
import math
import random
from pimoroni_i2c import PimoroniI2C
from breakout_dotmatrix import BreakoutDotMatrix
display = BreakoutDotMatrix()
PINS_BREAKOUT_GARDEN = {"sda": 4, "scl": 5}
PINS_PICO_EXPLORER = {"sda": 20, "scl": 21}
i2c = PimoroniI2C(**PINS_BREAKOUT_GARDEN)
display = BreakoutDotMatrix(i2c)
width = display.WIDTH
height = display.HEIGHT

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -1,7 +1,11 @@
import time
import math
from pimoroni_i2c import PimoroniI2C
from breakout_ioexpander import BreakoutIOExpander
PINS_BREAKOUT_GARDEN = {"sda": 4, "scl": 5}
PINS_PICO_EXPLORER = {"sda": 20, "scl": 21}
ioe_servo_pin = 1
# Settings to produce a 50Hz output from the 24MHz clock.
@ -12,7 +16,8 @@ period = 60000
cycle_time = 5.0
servo_range = 1000.0 # Between 1000 and 2000us (1-2ms)
ioe = BreakoutIOExpander(0x18)
i2c = PimoroniI2C(**PINS_BREAKOUT_GARDEN)
ioe = BreakoutIOExpander(i2c, address=0x18)
ioe.set_pwm_period(period)
ioe.set_pwm_control(divider)

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -1,6 +1,12 @@
from pimoroni_i2c import PimoroniI2C
from breakout_rtc import BreakoutRTC
import time
rtc = BreakoutRTC()
PINS_BREAKOUT_GARDEN = {"sda": 4, "scl": 5} # i2c pins 4, 5 for Breakout Garden
PINS_PICO_EXPLORER = {"sda": 20, "scl": 21} # Default i2c pins for Pico Explorer
i2c = PimoroniI2C(**PINS_BREAKOUT_GARDEN)
rtc = BreakoutRTC(i2c)
if rtc.is_12_hour():
rtc.set_24_hour()
@ -12,6 +18,8 @@ while True:
rtc.clear_periodic_update_interrupt_flag()
if rtc.update_time():
date = rtc.string_date()
time = rtc.string_time()
print("Date: ", date, ", Time: ", time, sep="")
rtc_date = rtc.string_date()
rtc_time = rtc.string_time()
print("Date: ", rtc_date, ", Time: ", rtc_time, sep="")
time.sleep(0.1)

View File

@ -1,7 +1,13 @@
import time
from pimoroni_i2c import PimoroniI2C
from breakout_sgp30 import BreakoutSGP30
sgp30 = BreakoutSGP30()
PINS_BREAKOUT_GARDEN = {"sda": 4, "scl": 5} # i2c pins 4, 5 for Breakout Garden
PINS_PICO_EXPLORER = {"sda": 20, "scl": 21} # Default i2c pins for Pico Explorer
i2c = PimoroniI2C(**PINS_BREAKOUT_GARDEN)
sgp30 = BreakoutSGP30(i2c)
print("SGP30 initialised - about to start measuring without waiting")
sgp30.start_measurement(False)

View File

@ -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]:

Some files were not shown because too many files have changed in this diff Show More