diff options
-rw-r--r-- | include/driver/max44006.h | 80 | ||||
-rw-r--r-- | src/app/datalogger/main.cc | 35 | ||||
-rw-r--r-- | src/driver/Kconfig | 5 | ||||
-rw-r--r-- | src/driver/max44006.cc | 81 |
4 files changed, 199 insertions, 2 deletions
diff --git a/include/driver/max44006.h b/include/driver/max44006.h new file mode 100644 index 0000000..ae5ad12 --- /dev/null +++ b/include/driver/max44006.h @@ -0,0 +1,80 @@ +/* + * Copyright 2021 Daniel Friesel + * + * SPDX-License-Identifier: BSD-2-Clause + */ +#ifndef MAX44006_H +#define MAX44006_H + +#include <stdint.h> + +/** + * Driver for MAX44006 RGB, IR, and Temperature Sensor. + * Does not support interrupts. + */ +class MAX44006 { + public: + + enum registers { + interruptStatusReg = 0x00, + mainConfigReg = 0x01, + ambientConfigReg = 0x02, + }; + + enum interruptStatus { + AMBINTS = 0b00000001, + PWRON = 0b00000010, + SHDN = 0b00001000, + RESET = 0b00010000, + }; + + enum mainConfig { + AMBINTE = 0b00000001, + AMBSEL_00 = 0b00000000, + AMBSEL_01 = 0b00000100, + AMBSEL_10 = 0b00001000, + AMBSEL_11 = 0b00001100, + MODE_00 = 0b00000000, + MODE_01 = 0b00010000, + MODE_10 = 0b00100000, + }; + + enum ambientConfig { + AMBPGA_00 = 0b00000000, + AMBPGA_01 = 0b00000001, + AMBPGA_10 = 0b00000010, + AMBPGA_11 = 0b00000011, + AMBTIM_000 = 0b00000000, + AMBTIM_001 = 0b00000100, + AMBTIM_010 = 0b00001000, + AMBTIM_011 = 0b00001100, + AMBTIM_100 = 0b00010000, + TEMPEN = 0b00100000, + COMPPEN = 0b01000000, + TRIm = 0b10000000, + }; + + private: + MAX44006(const MAX44006 ©); + unsigned char const address; + unsigned char txbuf[2]; + unsigned char rxbuf[10]; + + unsigned char ambtim; + unsigned char ambpga; + + uint16_t clear, red, green, blue, ir; + + public: + + MAX44006(unsigned char const addr = 0x45) : address(addr) {} + + uint8_t init(); + + uint16_t getTemperature(); + bool getLight(float *red, float *green, float *blue, float *clear, float *ir); +}; + +extern MAX44006 max44006; + +#endif diff --git a/src/app/datalogger/main.cc b/src/app/datalogger/main.cc index c6252b2..6cdba9e 100644 --- a/src/app/datalogger/main.cc +++ b/src/app/datalogger/main.cc @@ -36,6 +36,9 @@ #ifdef CONFIG_driver_ds2482 #include "driver/ds2482.h" #endif +#ifdef CONFIG_driver_max44006 +#include "driver/max44006.h" +#endif #ifdef CONFIG_driver_max44009 #include "driver/max44009.h" #endif @@ -149,8 +152,31 @@ void loop(void) #endif #ifdef CONFIG_driver_max44009 + kout << "MAX44006 Temperature: " << max44006.getTemperature() << " counts" << endl; + float r, g, b, c, ir; + if (max44006.getLight(&r, &g, &b, &c, &ir)) { + kout << "MAX44006 Red: "; + kout.printf_float(r); + kout << " µW/cm²" << endl; + kout << "MAX44006 Green: "; + kout.printf_float(g); + kout << " µW/cm²" << endl; + kout << "MAX44006 Blue: "; + kout.printf_float(b); + kout << " µW/cm²" << endl; + kout << "MAX44006 Clear: "; + kout.printf_float(c); + kout << " µW/cm²" << endl; + kout << "MAX44006 IR: "; + kout.printf_float(ir); + kout << " µW/cm²" << endl; + } +#endif + +#ifdef CONFIG_driver_max44009 + kout << "MAX44009 Brightness: "; kout.printf_float(max44009.getLux()); - kout << endl; + kout << " lx" << endl; #endif #ifdef CONFIG_driver_tsl2591 @@ -253,6 +279,13 @@ int main(void) } #endif +#ifdef CONFIG_driver_max44006 + unsigned char ret; + if ((ret = max44006.init()) != 0) { + kout << "MAX44006 Initialization failed: " << ret << endl; + } +#endif + #ifdef CONFIG_driver_mpu9250 mpu9250.init(); mpu9250.nineAxis(); diff --git a/src/driver/Kconfig b/src/driver/Kconfig index 13e0dc5..4b3693c 100644 --- a/src/driver/Kconfig +++ b/src/driver/Kconfig @@ -56,7 +56,10 @@ depends on meta_driver_i2c config driver_lm75 bool "LM75 Temperature Sensor" depends on meta_driver_i2c -# depends on I2C + +config driver_max44006 +bool "MAX44006 RGB + IR Sensor" +depends on meta_driver_i2c config driver_max44009 bool "MAX44009 Ambient Light Sensor" diff --git a/src/driver/max44006.cc b/src/driver/max44006.cc new file mode 100644 index 0000000..e9b9467 --- /dev/null +++ b/src/driver/max44006.cc @@ -0,0 +1,81 @@ +/* + * Copyright 2020 Daniel Friesel + * + * SPDX-License-Identifier: BSD-2-Clause + * + * Driver for MAX44006 RGB, IR, and Temperature Sensor. + * Does not support interrupts. + */ +#include "driver/max44006.h" +#if defined(CONFIG_meta_driver_hardware_i2c) +#include "driver/i2c.h" +#elif defined(CONFIG_driver_softi2c) +#include "driver/soft_i2c.h" +#endif + +#include "arch.h" + +uint8_t MAX44006::init() +{ + txbuf[0] = interruptStatusReg; + if (i2c.xmit(address, 1, txbuf, 1, rxbuf) != 0) { + return 1; + } + + if (rxbuf[0] & ~PWRON) { + // reset sensor + txbuf[1] = 0x10; + if (i2c.xmit(address, 2, txbuf, 0, rxbuf) != 0) { + return 1; + } + arch.delay_ms(200); + if (i2c.xmit(address, 1, txbuf, 1, rxbuf) != 0) { + return 1; + } + if (rxbuf[0] & ~PWRON) { + return 2; + } + } + + txbuf[0] = ambientConfigReg; + txbuf[1] = TEMPEN; // TEMPEN = 1 + if (i2c.xmit(address, 2, txbuf, 0, rxbuf) != 0) { + return 1; + } + + txbuf[0] = mainConfigReg; + txbuf[1] = MODE_10; // MODE = 10 -> Clear + RGB + IR measurement + if (i2c.xmit(address, 2, txbuf, 0, rxbuf) != 0) { + return 1; + } + + return 0; +} + +uint16_t MAX44006::getTemperature() +{ + txbuf[0] = 0x12; + if (i2c.xmit(address, 1, txbuf, 2, rxbuf) != 0) { + return 0; + } + + return (((uint16_t)rxbuf[0] << 8) + rxbuf[1]); +} + +bool MAX44006::getLight(float *red, float *green, float *blue, float *clear, float *ir) +{ + txbuf[0] = 0x04; + if (i2c.xmit(address, 1, txbuf, 10, rxbuf) != 0) { + return false; + } + + *clear = (float)(((uint16_t)rxbuf[0] << 8) + rxbuf[1]) * 0.002; + *red = (float)(((uint16_t)rxbuf[2] << 8) + rxbuf[3]) * 0.002; + *green = (float)(((uint16_t)rxbuf[4] << 8) + rxbuf[5]) * 0.002; + *blue = (float)(((uint16_t)rxbuf[6] << 8) + rxbuf[7]) * 0.004; + *ir = (float)(((uint16_t)rxbuf[8] << 8) + rxbuf[9]) * 0.002; + + return true; +} + +MAX44006 max44006(0x45); |