pimoroni-pico/drivers/bh1745/bh1745.cpp

136 lines
4.0 KiB
C++
Raw Normal View History

2021-01-27 11:14:25 +00:00
#include "bh1745.hpp"
#include <algorithm>
namespace pimoroni {
2021-07-12 15:26:41 +01:00
bool BH1745::init() {
2021-01-27 11:14:25 +00:00
reset();
2021-07-12 13:21:14 +01:00
if (this->get_chip_id() != BH1745_CHIP_ID || this->get_manufacturer() != BH1745_MANUFACTURER) {
2021-07-12 15:26:41 +01:00
return false;
2021-01-27 11:14:25 +00:00
}
2021-07-12 13:21:14 +01:00
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
2021-01-27 11:14:25 +00:00
sleep_ms(320);
2021-07-12 15:26:41 +01:00
return true;
2021-01-27 11:14:25 +00:00
}
2021-07-12 15:26:41 +01:00
I2C* BH1745::get_i2c() const {
return i2c;
}
int BH1745::get_address() const {
return address;
2021-07-12 13:21:14 +01:00
}
2021-01-27 11:14:25 +00:00
uint8_t BH1745::get_chip_id() {
2021-07-12 13:21:14 +01:00
uint8_t chip_id = i2c->reg_read_uint8(address, BH1745_REG_SYSTEM_CONTROL);
2021-01-27 11:14:25 +00:00
return chip_id & 0b00111111;
}
uint8_t BH1745::get_manufacturer() {
2021-07-12 13:21:14 +01:00
uint8_t manufacturer = i2c->reg_read_uint8(address, BH1745_REG_MANUFACTURER);
2021-01-27 11:14:25 +00:00
return manufacturer;
}
void BH1745::reset() {
2021-07-12 13:21:14 +01:00
i2c->set_bits(address, BH1745_REG_SYSTEM_CONTROL, 7);
2021-01-27 11:14:25 +00:00
2021-07-12 13:21:14 +01:00
while (i2c->get_bits(address, BH1745_REG_SYSTEM_CONTROL, 7)) {
2021-01-27 11:14:25 +00:00
sleep_ms(100);
}
}
void BH1745::set_measurement_time_ms(uint16_t value) {
uint8_t reg = 0;
switch(value) {
case 160:
reg = 0b000;
break;
case 320:
reg = 0b001;
break;
case 640:
reg = 0b010;
break;
case 1280:
reg = 0b011;
break;
case 2560:
reg = 0b100;
break;
case 5120:
reg = 0b101;
break;
}
2021-07-12 13:21:14 +01:00
i2c->write_bytes(address, BH1745_REG_MODE_CONTROL1, &reg, 1);
2021-01-27 11:14:25 +00:00
}
void BH1745::set_threshold_high(uint16_t value) {
2021-07-12 13:21:14 +01:00
i2c->write_bytes(address, BH1745_REG_THRESHOLD_HIGH, (uint8_t *)&value, 2);
2021-01-27 11:14:25 +00:00
}
void BH1745::set_threshold_low(uint16_t value) {
2021-07-12 13:21:14 +01:00
i2c->write_bytes(address, BH1745_REG_THRESHOLD_LOW, (uint8_t *)&value, 2);
2021-01-27 11:14:25 +00:00
}
void BH1745::set_leds(bool state) {
if(state){
2021-07-12 13:21:14 +01:00
i2c->set_bits(address, BH1745_REG_INTERRUPT, 0);
2021-01-27 11:14:25 +00:00
}
else
{
2021-07-12 13:21:14 +01:00
i2c->clear_bits(address, BH1745_REG_INTERRUPT, 0);
2021-01-27 11:14:25 +00:00
}
}
rgbc_t BH1745::get_rgb_scaled() {
rgbc_t rgbc = this->get_rgbc_raw();
if(rgbc.c > 0) {
rgbc.r = (uint16_t)((uint32_t)rgbc.r * 255 / rgbc.c) & 0xff;
rgbc.g = (uint16_t)((uint32_t)rgbc.g * 255 / rgbc.c) & 0xff;
rgbc.b = (uint16_t)((uint32_t)rgbc.b * 255 / rgbc.c) & 0xff;
} else {
rgbc.r = 0;
rgbc.g = 0;
rgbc.b = 0;
}
return rgbc;
}
rgbc_t BH1745::get_rgb_clamped() {
2021-07-12 13:21:14 +01:00
rgbc_t rgbc = get_rgbc_raw();
2021-01-27 11:14:25 +00:00
uint16_t vmax = std::max(rgbc.r, std::max(rgbc.g, rgbc.b));
rgbc.r = (uint16_t)((uint32_t)rgbc.r * 255 / vmax);
rgbc.g = (uint16_t)((uint32_t)rgbc.g * 255 / vmax);
rgbc.b = (uint16_t)((uint32_t)rgbc.b * 255 / vmax);
return rgbc;
}
rgbc_t BH1745::get_rgbc_raw() {
2021-07-12 13:21:14 +01:00
while(i2c->get_bits(address, BH1745_REG_MODE_CONTROL2, 7) == 0) {
2021-01-27 11:14:25 +00:00
sleep_ms(1);
}
rgbc_t colour_data;
2021-07-12 13:21:14 +01:00
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];
2021-01-27 11:14:25 +00:00
return colour_data;
}
}