From ea6acf2207cc02d71ab7cd7739449e275c56b548 Mon Sep 17 00:00:00 2001 From: Phil Howard Date: Mon, 12 Jul 2021 13:21:14 +0100 Subject: [PATCH] Porti BH1745 to Pimoroni I2C --- drivers/bh1745/bh1745.cmake | 2 +- drivers/bh1745/bh1745.cpp | 98 +++++++++---------------------- drivers/bh1745/bh1745.hpp | 58 ++++++++---------- examples/breakout_bh1745/demo.cpp | 5 +- 4 files changed, 59 insertions(+), 104 deletions(-) diff --git a/drivers/bh1745/bh1745.cmake b/drivers/bh1745/bh1745.cmake index 6d286cd3..15e02c7c 100644 --- a/drivers/bh1745/bh1745.cmake +++ b/drivers/bh1745/bh1745.cmake @@ -6,4 +6,4 @@ target_sources(bh1745 INTERFACE target_include_directories(bh1745 INTERFACE ${CMAKE_CURRENT_LIST_DIR}) # Pull in pico libraries that we need -target_link_libraries(bh1745 INTERFACE pico_stdlib hardware_i2c) +target_link_libraries(bh1745 INTERFACE pico_stdlib hardware_i2c pimoroni_i2c) diff --git a/drivers/bh1745/bh1745.cpp b/drivers/bh1745/bh1745.cpp index f40d4c7c..1600def7 100644 --- a/drivers/bh1745/bh1745.cpp +++ b/drivers/bh1745/bh1745.cpp @@ -3,47 +3,44 @@ namespace pimoroni { int BH1745::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); - reset(); - if (this->get_chip_id() != CHIP_ID || this->get_manufacturer() != MANUFACTURER) { + if (this->get_chip_id() != BH1745_CHIP_ID || this->get_manufacturer() != BH1745_MANUFACTURER) { return 1; } - this->reset(); - this->clear_bits(REG_SYSTEM_CONTROL, 6); // Clear INT reset bit - this->set_measurement_time_ms(640); - this->set_bits(REG_MODE_CONTROL2, 4); // Enable RGBC - this->set_bits(REG_MODE_CONTROL3, 0, 0xff); // Turn on sensor - this->set_threshold_high(0x0000); // Set threshold so int will always fire - this->set_threshold_low(0xFFFF); // this lets us turn on the LEDs with the int pin - this->clear_bits(REG_INTERRUPT, 4); // Enable interrupt latch + reset(); + i2c->clear_bits(address, BH1745_REG_SYSTEM_CONTROL, 6); // Clear INT reset bit + set_measurement_time_ms(640); + i2c->set_bits(address, BH1745_REG_MODE_CONTROL2, 4); // Enable RGBC + i2c->set_bits(address, BH1745_REG_MODE_CONTROL3, 0, 0xff); // Turn on sensor + set_threshold_high(0x0000); // Set threshold so int will always fire + set_threshold_low(0xFFFF); // this lets us turn on the LEDs with the int pin + i2c->clear_bits(address, BH1745_REG_INTERRUPT, 4); // Enable interrupt latch sleep_ms(320); return 0; } + i2c_inst_t* BH1745::get_i2c() const { + return i2c->get_i2c(); + } + uint8_t BH1745::get_chip_id() { - uint8_t chip_id; - this->read_bytes(REG_SYSTEM_CONTROL, &chip_id, 1); + uint8_t chip_id = i2c->reg_read_uint8(address, BH1745_REG_SYSTEM_CONTROL); return chip_id & 0b00111111; } uint8_t BH1745::get_manufacturer() { - uint8_t manufacturer; - this->read_bytes(REG_MANUFACTURER, &manufacturer, 1); + uint8_t manufacturer = i2c->reg_read_uint8(address, BH1745_REG_MANUFACTURER); return manufacturer; } void BH1745::reset() { - this->set_bits(REG_SYSTEM_CONTROL, 7); + i2c->set_bits(address, BH1745_REG_SYSTEM_CONTROL, 7); - while (this->get_bits(REG_SYSTEM_CONTROL, 7)) { + while (i2c->get_bits(address, BH1745_REG_SYSTEM_CONTROL, 7)) { sleep_ms(100); } } @@ -70,24 +67,24 @@ namespace pimoroni { reg = 0b101; break; } - this->write_bytes(REG_MODE_CONTROL1, ®, 1); + i2c->write_bytes(address, BH1745_REG_MODE_CONTROL1, ®, 1); } void BH1745::set_threshold_high(uint16_t value) { - this->write_bytes(REG_THRESHOLD_HIGH, (uint8_t *)&value, 2); + i2c->write_bytes(address, BH1745_REG_THRESHOLD_HIGH, (uint8_t *)&value, 2); } void BH1745::set_threshold_low(uint16_t value) { - this->write_bytes(REG_THRESHOLD_LOW, (uint8_t *)&value, 2); + i2c->write_bytes(address, BH1745_REG_THRESHOLD_LOW, (uint8_t *)&value, 2); } void BH1745::set_leds(bool state) { if(state){ - this->set_bits(REG_INTERRUPT, 0); + i2c->set_bits(address, BH1745_REG_INTERRUPT, 0); } else { - this->clear_bits(REG_INTERRUPT, 0); + i2c->clear_bits(address, BH1745_REG_INTERRUPT, 0); } } @@ -109,7 +106,7 @@ namespace pimoroni { } rgbc_t BH1745::get_rgb_clamped() { - rgbc_t rgbc = this->get_rgbc_raw(); + rgbc_t rgbc = get_rgbc_raw(); uint16_t vmax = std::max(rgbc.r, std::max(rgbc.g, rgbc.b)); @@ -121,52 +118,15 @@ namespace pimoroni { } rgbc_t BH1745::get_rgbc_raw() { - while(this->get_bits(REG_MODE_CONTROL2, 7) == 0) { + while(i2c->get_bits(address, BH1745_REG_MODE_CONTROL2, 7) == 0) { sleep_ms(1); } rgbc_t colour_data; - this->read_bytes(REG_COLOUR_DATA, (uint8_t *)&colour_data, 8); - colour_data.r *= this->channel_compensation[0]; - colour_data.g *= this->channel_compensation[1]; - colour_data.b *= this->channel_compensation[2]; - colour_data.c *= this->channel_compensation[3]; + i2c->read_bytes(address, BH1745_REG_COLOUR_DATA, (uint8_t *)&colour_data, 8); + colour_data.r *= channel_compensation[0]; + colour_data.g *= channel_compensation[1]; + colour_data.b *= channel_compensation[2]; + colour_data.c *= channel_compensation[3]; return colour_data; } - - // i2c functions - - int BH1745::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(this->i2c, this->address, buffer, len + 1, false); - }; - - int BH1745::read_bytes(uint8_t reg, uint8_t *buf, int len) { - i2c_write_blocking(this->i2c, this->address, ®, 1, true); - i2c_read_blocking(this->i2c, this->address, buf, len, false); - return len; - }; - - uint8_t BH1745::get_bits(uint8_t reg, uint8_t shift, uint8_t mask) { - uint8_t value; - this->read_bytes(reg, &value, 1); - return value & (mask << shift); - } - - void BH1745::set_bits(uint8_t reg, uint8_t shift, uint8_t mask) { - uint8_t value; - this->read_bytes(reg, &value, 1); - value |= mask << shift; - this->write_bytes(reg, &value, 1); - } - - void BH1745::clear_bits(uint8_t reg, uint8_t shift, uint8_t mask) { - uint8_t value; - this->read_bytes(reg, &value, 1); - value &= ~(mask << shift); - this->write_bytes(reg, &value, 1); - } } \ No newline at end of file diff --git a/drivers/bh1745/bh1745.hpp b/drivers/bh1745/bh1745.hpp index bf0a4843..3da7e792 100644 --- a/drivers/bh1745/bh1745.hpp +++ b/drivers/bh1745/bh1745.hpp @@ -2,24 +2,22 @@ #include "hardware/i2c.h" #include "hardware/gpio.h" +#include "common/pimoroni_i2c.hpp" -#define REG_SYSTEM_CONTROL 0x40 -#define REG_MODE_CONTROL1 0x41 -#define REG_MODE_CONTROL2 0x42 -#define REG_MODE_CONTROL3 0x44 -#define REG_COLOUR_DATA 0x50 -#define REG_DINT_DATA 0x58 -#define REG_INTERRUPT 0x60 -#define REG_PERSISTENCE 0x61 -#define REG_THRESHOLD_LOW 0x64 -#define REG_THRESHOLD_HIGH 0x62 -#define REG_MANUFACTURER 0x92 +#define BH1745_REG_SYSTEM_CONTROL 0x40 +#define BH1745_REG_MODE_CONTROL1 0x41 +#define BH1745_REG_MODE_CONTROL2 0x42 +#define BH1745_REG_MODE_CONTROL3 0x44 +#define BH1745_REG_COLOUR_DATA 0x50 +#define BH1745_REG_DINT_DATA 0x58 +#define BH1745_REG_INTERRUPT 0x60 +#define BH1745_REG_PERSISTENCE 0x61 +#define BH1745_REG_THRESHOLD_LOW 0x64 +#define BH1745_REG_THRESHOLD_HIGH 0x62 +#define BH1745_REG_MANUFACTURER 0x92 -#define CHIP_ID 0b001011 -#define MANUFACTURER 0xe0 - -#define I2C_ADDR 0x38 -#define I2C_ADDR_ALT 0x39 +#define BH1745_CHIP_ID 0b001011 +#define BH1745_MANUFACTURER 0xe0 namespace pimoroni { typedef struct { @@ -31,14 +29,19 @@ namespace pimoroni { class BH1745 { public: - BH1745() {}; + static const uint8_t DEFAULT_I2C_ADDRESS = 0x38; + static const uint8_t I2C_ADDRESS_ALTERNATE = 0x39; - BH1745(uint8_t addr) : address(addr) {}; + BH1745(I2C *i2c, uint8_t address = DEFAULT_I2C_ADDRESS) : + i2c(i2c), address(address) {} - BH1745(i2c_inst_t *i2c, uint8_t addr, uint8_t sda, uint8_t scl, uint8_t interrupt) : - i2c(i2c), address(addr), sda(sda), scl(scl), interrupt(interrupt) {}; + BH1745(i2c_inst_t *i2c, uint8_t addr, uint8_t sda, uint8_t scl, uint interrupt) : + BH1745(new I2C(sda, scl), address) {}; int init(); + + i2c_inst_t* get_i2c() const; + uint8_t get_chip_id(); uint8_t get_manufacturer(); void set_threshold_high(uint16_t value); @@ -51,21 +54,12 @@ namespace pimoroni { void set_leds(bool state=true); private: - i2c_inst_t *i2c = i2c0; + I2C *i2c; // interface pins with our standard defaults where appropriate - int8_t address = 0x38; - int8_t sda = 4; - int8_t scl = 5; - int8_t interrupt = 22; + int8_t address = DEFAULT_I2C_ADDRESS; + uint interrupt = 22; float channel_compensation[4] = {2.2f, 1.0f, 1.8f, 10.0f}; - - // From i2cdevice - int write_bytes(uint8_t reg, uint8_t *buf, int len); - int read_bytes(uint8_t reg, uint8_t *buf, int len); - uint8_t get_bits(uint8_t reg, uint8_t shift, uint8_t mask=0b1); - void set_bits(uint8_t reg, uint8_t shift, uint8_t mask=0b1); - void clear_bits(uint8_t reg, uint8_t shift, uint8_t mask=0b1); }; } \ No newline at end of file diff --git a/examples/breakout_bh1745/demo.cpp b/examples/breakout_bh1745/demo.cpp index 244f58b4..fbdbfcee 100644 --- a/examples/breakout_bh1745/demo.cpp +++ b/examples/breakout_bh1745/demo.cpp @@ -7,10 +7,11 @@ using namespace pimoroni; -BH1745 bh1745(0x39); +I2C i2c(BOARD::BREAKOUT_GARDEN); +BH1745 bh1745(&i2c, BH1745::DEFAULT_I2C_ADDRESS); int main() { - setup_default_uart(); + stdio_init_all(); if (bh1745.init() == 1) { printf("Failed to set up sensor\n");