MAX44008 RGB Color, Infrared, and Temperature Sensor

Dependents:   test_MAX44008 testSensor

Revision:
0:7d913e68a6d7
Child:
1:45b23a5fff8e
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/MAX44008.cpp	Tue Dec 22 05:44:07 2015 +0000
@@ -0,0 +1,510 @@
+/**
+ * MAX44008 RGB Color, Infrared,
+ * and Temperature Sensor
+ * I2C 7bit address: 0x40 (A0 = 1) 0x41 (A0 = 0)
+ */
+ #include "mbed.h"
+ #include "MAX44008.h"
+ 
+ /* STATUS */
+#define REG_INT_STATUS        0x00
+
+/* CONFIGURATION */
+#define REG_MAIN_CONFIG       0x01
+#define REG_AMB_CONFIG        0x02
+
+/* AMBIENT READING */
+#define REG_AMB_CLR_MSB       0x04
+#define REG_AMB_CLR_LSB       0x05
+#define REG_AMB_RED_MSB       0x06
+#define REG_AMB_RED_LSB       0x07
+#define REG_AMB_GRN_MSB       0x08
+#define REG_AMB_GRN_LSB       0x09
+#define REG_AMB_BLU_MSB       0x0A
+#define REG_AMB_BLU_LSB       0x0B
+#define REG_AMB_IR_MSB        0x0C
+#define REG_AMB_IR_LSB        0x0D
+#define REG_AMB_IRCMP_MSB     0x0E
+#define REG_AMB_IRCMP_LSB     0x0F
+#define REG_TMP_MSB           0x12
+#define REG_TMP_LSB           0x13
+
+/* Interrupt Thresholds */
+#define REG_AMB_UPTHR_MSB     0x14
+#define REG_AMB_UPTHR_LSB     0x15
+#define REG_AMB_LOTHR_MSB     0x16
+#define REG_AMB_LOTHR_LSB     0x17
+#define REG_AMB_PST           0x18
+
+/* Ambient ADC Gains */
+#define REG_TRIM_GAIN_CLR     0x1D
+#define REG_TRIM_GAIN_RED     0x1E
+#define REG_TRIM_GAIN_GRN     0x1F
+#define REG_TRIM_GAIN_BLU     0x20
+#define REG_TRIM_GAIN_IR      0x21
+
+/* Operation Mode */
+#define MODE_CLEAR            0x00
+#define MODE_CLEAR_IR         0x01
+#define MODE_CLEAR_RGB_IR     0x02
+
+/* Ambient Interrupt Select */
+#define AMB_INT_CLEAR         0x00
+#define AMB_INT_GREEN         0x01
+#define AMB_INT_IR            0x02
+#define AMB_INT_TEMP          0x03
+
+ MAX44008::MAX44008(PinName sda, PinName scl, int addr) : m_i2c(sda, scl), m_addr(addr<<1) {
+    // activate the peripheral
+}
+
+MAX44008::~MAX44008() { }
+
+void MAX44008::readRegs(int addr, uint8_t *data, int len)
+{
+    char t[1] = {addr} ;
+    m_i2c.write(m_addr, t, 1, true) ;
+    m_i2c.read(m_addr, (char*)data, len) ;
+}
+
+void MAX44008::writeRegs(uint8_t *data, int len)
+{
+   m_i2c.write(m_addr, (char *)data, len) ;
+}
+
+/**
+ * REGISTER: Interrupt Status
+ * Bit7: -
+ * Bit6: -
+ * Bit5: -
+ * Bit4: RESET   : Reset Control
+ *       0 : The part is in normal operation.
+ *       1 : The part undergoes a forced POR sequence.
+ *           All configuration, threshold, and data registers are
+ *           reset to a power-on state by writing a 1 to this bit,
+ *           and an internal hardware reset pulse is generated.
+ *           This bit then automatically becomes 0 after the RESET sequence is completed.
+ *           After resettign, the PWRON interrupt is triggered.
+ * Bit3: SHDN    : Shutdown Control
+ *       0 : The part is in normal operatin. 
+ *           When the part returns from shutdown, note that the value in data registers
+ *           is not current until the first conversion cycle is completed.
+ *       1 : The part can be put into a power-save mode by writing a 1 to this bit.
+ *           Supply current is reduced to approximately 0.5uA with no I2C clock activity.
+ *           While all registers remain accessible and retain data, ADC conversion data
+ *           contained in them may not be current. Writeable registers also remain
+ *           accessible in shutdown. All interrupts are cleared.
+ * Bit2: PWRON   : Power-On INTERRUPT STATUS Flag
+ *       0 : Normal operating mode.
+ *       1 : The part went through a power-up event, either because the part was turned on,
+ *           or because there was a power-supply voltage glitch.
+ *           All interrupt threshold settings in the registers have been reset to power-on
+ *           default states, and should be examined if nccessary. The /INT pin is also pulled low.
+ *           Once this bit is set, the only way to clear this bit is to read this register.
+ * Bit1: -
+ * Bit0: AMBINTS : Ambient INTERRUPT STATUS Flag
+ *       0 : No interrupt trigger ever has occurred.
+ *       1 : The ambient light has exceeded the designated window limits defined 
+ *           by the threshold registers for longer than persist timer count AMBPST[1:0]. 
+ *           It also causes the /INT pin to be pulled low. Once set, 
+ *           the only way to clear this bit is to read this register. 
+ *           This bit is always set to 0 if AMBINTE bit is set to 0.
+ */
+uint8_t MAX44008::getIntStatus(void) 
+{
+    uint8_t value = 0 ;
+    readRegs(REG_INT_STATUS, &value, 1) ;
+    return( value ) ;
+}
+
+void MAX44008::setIntStatus(uint8_t newValue) 
+{
+    uint8_t val[2] ;
+    val[0] = REG_INT_STATUS ;
+    val[1] = newValue ;
+    writeRegs(val, 2) ;
+}
+
+/**
+ * REGISTER: Main Configuration
+ * Bit7: -
+ * Bit6: -
+ * Bit5: MODE[1]
+ * Bit4: MODE[0]
+ *       00 : Clear            : CLEAR + TEMP(*) channels active
+ *       01 : Clear + IR       : CLEAR + TEMP(*) + IR channels active
+ *       10 : Clear + RGB + IR : CLEAR + TEMP(*) + RGB + IR channels active
+ *       (*) When TEMPEN set to 1.
+ * Bit3: AMBSEL[1] : Ambient Interrupt Select
+ * Bit2: AMBSEL[0] : Ambient Interrupt Select
+ *       00 : CLEAR channel data is used to compare with ambient interrupt thresholds and ambient timer settings.
+         01 : GREEN channel data is used to compare with ambinet interrupt thresholds and ambient timer settings.
+         10 : IR    channel data is used to compare with ambient interrupt thresholds and ambient timer settings.
+         11 : TEMP  channel data is used to compare with ambinet interrupt thresholds and ambinet timer settings.
+ * Bit1: -
+ * Bit0: AMBINTE : Ambient Interrupt Enable
+ *       0 : The AMBINTS bit and /INT pin remain unasserted even if an ambient interrupt event has occurred.
+ *           The AMBINTS bit is set to 0 if previously set to 1. 
+ *       1 : Detection of ambient interrupt is enabled (see the AMBINTS bit for more details).
+ *           An ambient interrupt can trigger a hardware interrupt (/INT pin pullued low)
+ *           and set AMBINTS bit (register 0x00, BIT0)
+ */
+ uint8_t MAX44008::getMainConfig(void) 
+ {
+     uint8_t value = 0 ;
+     readRegs(REG_MAIN_CONFIG, &value, 1) ;
+     return( value ) ;
+}
+
+void MAX44008::setMainConfig(uint8_t newConfig) 
+{
+    uint8_t val[2] ;
+    val[0] = REG_MAIN_CONFIG ;
+    val[1] = newConfig ;
+    writeRegs(val, 2) ;
+}
+
+/**
+ * REGISTER: Ambient Configuration
+ * Bit7: TRIM
+ *       0 : Use factory-programmed gains for all the channels. 
+ *           Ignore any bytes written to TRIM_GAIN_GREEN[6:0],
+ *           TRIM_GAIN_RED[6:0], TRIM_GAIN_BLUE[6:0], TRIM_GAIN_CLEAR[6:0], 
+ *           and TRIM_GAIN_IR[6:0] registers.
+ *       1 : Use bytes written to TRIM_GAIN_GREEN[6:0], TRIM_GAIN_RED[6:0], 
+ *           TRIM_GAIN_BLUE[6:0], TRIM_GAIN_CLEAR[6:0],
+ *           and TRIM_GAIN_IR[6:0] registers to set the gain for each channel.
+ * Bit6: COMPEN
+ *       0 : Disables IR compensation.
+ *       1 : Enables IR compensation.
+ *           Only for MODE[1:0] = 00 Mode. 
+ *           The integration time of compensation channel is controlled by the AMB mode settings. 
+ *           The compensation is enabled only when the clear channel is on. 
+ *           When COMPEN = 1, the CLEAR data is automatically compensated 
+ *           for stray IR leakeds and temperature variations. 
+ *           When COMPEN = 0, the IR compensation is disabled, 
+ *           but the output of the IR compensation data exits.
+ * Bit5: TEMPEN
+ *       0 : Disables temperature sensor.
+ *       1 : Enables temperature sensor.
+ *           The integration time of temperature sensor is controlled by the ambient mode settings.
+ *           The temperature sensor is enabled only if the clear channel is on.
+ * Bit4: AMBTIM[2]
+ * Bit3: AMBTIM[1]
+ * Bit2: AMBTIM[0]
+ *            | Integration Time | Full-scale ADC | Bit Resolution |  Relative LSB Size   |
+ *            |     (ms)         |    (counts)    |                | for fixed AMPGA[1:0] |
+ *        000 :      100         |     16,384     |        14      |     1x               |
+ *        001 :       25         |      4,096     |        12      |     4x               |
+ *        010 :      6.25        |      1,024     |        10      |    16x               |
+ *        011 :      1.5625      |        256     |         8      |    64x               |
+ *        100 :      400         |     16,384     |        14      |    1/4x              |
+ *        101 :     Reserved     | Not applicable | Not applicable |     Not applicable   |
+ *        110 :     Reserved     | Not applicable | Not applicable |     Not applicable   |
+ *        111 :     Reserved     | Not applicable | Not applicable |     Not applicable   |   
+ * Bit1: AMBPGA[1]
+ * Bit0: AMBPGA[0]
+ *       In AMBTIM[2:0] = 000 Mode (100ms integraation time)
+ *           |            CLEAR/RED/GREEN/IR           |               BLUE                      |
+ *           |  nW/cm^2 per LSB | Full-scale (nW/cm^2) |  nW/cm^2 per LSB | Full-scale (nW/cm^2) |
+ *        00 :          2       |       32.768         |          4       |       65.536         |
+ *        01 :          8       |      131.072         |         16       |      262.144         |
+ *        10 :         32       |      524.288         |         64       |     1048.573         |
+ *        11 :        512       |     8388.61          |       1024       |    16777.2           |
+ *       In AMBTIM[2:0] = 100 Mode (400ms integration time)
+ *           |            CLEAR/RED/GREEN/IR           |               BLUE                      |
+ *           |  nW/cm^2 per LSB | Full-scale (nW/cm^2) |  nW/cm^2 per LSB | Full-scale (nW/cm^2) |
+ *        00 :          0.5     |        8.192         |          1       |       16.384         |
+ *        01 :          2       |       32.768         |          4       |       65.536         |
+ *        10 :          8       |      131.072         |         16       |      262.1433        |
+ *        11 :        128       |     2097.153         |        256       |     4194.3           |         
+ */    
+uint8_t MAX44008::getAMB_Config(void) 
+{
+    uint8_t value = 0 ;
+    readRegs(REG_AMB_CONFIG, &value, 1) ;
+    return( value ) ;  
+}
+
+void MAX44008::setAMB_Config(uint8_t newConfig) 
+{
+    uint8_t val[2] ;
+    val[0] = REG_AMB_CONFIG ;
+    val[1] = newConfig ;
+    writeRegs(val, 2) ;
+}
+
+int16_t MAX44008::getAMB_CLEAR(void) {
+    int16_t value;
+    uint8_t res[2];
+    readRegs(REG_AMB_CLR_MSB, res, 2) ;
+    value = (res[0] << 8)+res[1] ;
+    return( value ) ;
+}
+
+int16_t MAX44008::getAMB_RED(void) {
+    int16_t value;
+    uint8_t res[2];
+    readRegs(REG_AMB_RED_MSB, res, 2) ;
+    value = (res[0] << 8)+res[1] ;
+    return( value ) ;
+}
+    
+int16_t MAX44008::getAMB_GREEN(void) {
+    int16_t value;
+    uint8_t res[2];
+    readRegs(REG_AMB_GRN_MSB, res, 2) ;
+    value = (res[0] << 8)+res[1] ;
+    return( value ) ;
+}
+    
+int16_t MAX44008::getAMB_BLUE(void) {
+    int16_t value;
+    uint8_t res[2];
+    readRegs(REG_AMB_BLU_MSB, res, 2) ;
+    value = (res[0] << 8)+res[1] ;
+    return( value ) ;
+}
+ 
+int16_t MAX44008::getIR(void) {
+    int16_t value;
+    uint8_t res[2];
+    readRegs(REG_AMB_IR_MSB, res, 2) ;
+    value = (res[0] << 8)+res[1] ;
+    return( value ) ;
+}
+
+int16_t MAX44008::getIRCOMP(void) {
+    int16_t value;
+    uint8_t res[2];
+    readRegs(REG_AMB_IRCMP_MSB, res, 2) ;
+    value = (res[0] << 8)+res[1] ;
+    return( value ) ;
+}
+
+int16_t MAX44008::getTEMP(void) 
+{
+    int16_t value;
+    uint8_t res[2];
+    readRegs(REG_TMP_MSB, res, 2) ;
+    value = (res[0] << 8)+res[1] ;
+    return( value ) ;
+}
+
+int16_t MAX44008::getAMB_UPTHR(void) 
+{
+    uint16_t value ;
+    uint8_t  res[2] ;
+    readRegs(REG_AMB_UPTHR_MSB, res, 2) ;
+    value = (res[0] << 8) | res[1] ;
+    return( value ) ;
+}
+
+void MAX44008::setAMB_UPTHR(int16_t newTHR) 
+{
+    uint8_t res[3] ;
+    res[0] = REG_AMB_UPTHR_MSB ;
+    res[1] = (newTHR >> 8) & 0x3F ;
+    res[2] = newTHR & 0xFF ;
+    writeRegs(res, 3) ;
+}
+
+int16_t MAX44008::getAMB_LOTHR(void) 
+{
+    uint16_t value ;
+    uint8_t  res[2] ;
+    readRegs(REG_AMB_LOTHR_MSB, res, 2) ;
+    value = (res[0] << 8) | res[1] ;
+    return( value ) ;
+}
+
+void    MAX44008::setAMB_LOTHR(int16_t newTHR) 
+{
+    uint8_t res[3] ;
+    res[0] = REG_AMB_LOTHR_MSB ;
+    res[1] = (newTHR >> 8) & 0x3F ;
+    res[2] = newTHR & 0xFF ;
+    writeRegs(res, 3) ;
+}
+
+uint8_t MAX44008::getAMB_PST(void) 
+{
+    uint8_t value ;
+    readRegs(REG_AMB_PST, &value, 1) ;
+    return( value ) ;
+}
+
+void MAX44008::setAMB_PST(uint8_t newValue)
+{
+    uint8_t res[2] ;
+    res[0] = REG_AMB_PST ;
+    res[1] = newValue ;
+    writeRegs(res, 2) ;
+}
+
+/* Ambient ADC Gains */
+uint8_t MAX44008::getTRIM_GAIN_CLEAR(void)
+{
+    uint8_t value ;
+    readRegs(REG_TRIM_GAIN_CLR, &value, 1) ;
+    return(value) ;
+}
+
+void    MAX44008::setTRIM_GAIN_CLEAR(uint8_t newValue) 
+{
+    uint8_t res[2] ;
+    res[0] = REG_TRIM_GAIN_CLR ;
+    res[1] = newValue ;
+    writeRegs(res, 2) ;
+}
+
+uint8_t MAX44008::getTRIM_GAIN_RED(void) 
+{
+    uint8_t value ;
+    readRegs(REG_TRIM_GAIN_RED, &value, 1) ;
+    return(value) ;
+}
+
+void    MAX44008::setTRIM_GAIN_RED(uint8_t newValue)
+{
+    uint8_t res[2] ;
+    res[0] = REG_TRIM_GAIN_RED ;
+    res[1] = newValue ;
+    writeRegs(res, 2) ;
+}
+
+uint8_t MAX44008::getTRIM_GAIN_GREEN(void) 
+{
+    uint8_t value ;
+    readRegs(REG_TRIM_GAIN_GRN, &value, 1) ;
+    return(value) ;
+}
+
+void    MAX44008::setTRIM_GAIN_GREEN(uint8_t newValue) 
+{
+    uint8_t res[2] ;
+    res[0] = REG_TRIM_GAIN_GRN ;
+    res[1] = newValue ;
+    writeRegs(res, 2) ;
+}
+
+uint8_t MAX44008::getTRIM_GAIN_BLUE(void) 
+{
+    uint8_t value ;
+    readRegs(REG_TRIM_GAIN_BLU, &value, 1) ;
+    return(value) ;
+}
+
+void MAX44008::setTRIM_GAIN_BLUE(uint8_t newValue) 
+{
+    uint8_t res[2] ;
+    res[0] = REG_TRIM_GAIN_BLU ;
+    res[1] = newValue ;
+    writeRegs(res, 2) ;
+}
+
+uint8_t MAX44008::getTRIM_GAIN_IR(void) 
+{
+    uint8_t value ;
+    readRegs(REG_TRIM_GAIN_IR, &value, 1) ;
+    return(value) ;
+}
+
+void   MAX44008::setTRIM_GAIN_IR(uint8_t newValue) 
+{
+    uint8_t res[2] ;
+    res[0] = REG_TRIM_GAIN_IR ;
+    res[1] = newValue ;
+    writeRegs(res, 2) ;
+}
+
+void MAX44008::enableTRIM(void) 
+{
+    uint8_t res[2] ;
+    res[0] = REG_AMB_CONFIG ;
+    readRegs(res[0], &res[1], 1) ;
+    res[1] |= 0x80 ; /* BIT7 = TRIM */
+    writeRegs(res, 2) ;
+}
+
+void MAX44008::disableTRIM(void)
+{
+    uint8_t res[2] ;
+    res[0] = REG_AMB_CONFIG ;
+    readRegs(res[0], &res[1], 1) ;
+    res[1] &= (uint8_t)(0x7F) ; /* BIT7 = TRIM */
+    writeRegs(res, 2) ;
+}
+
+void MAX44008::enableCOMP(void) 
+{
+    uint8_t res[2] ;
+    res[0] = REG_AMB_CONFIG ;
+    readRegs(res[0], &res[1], 1) ;
+    res[1] |= 0x40 ; /* BIT6 = COMPEN */
+    writeRegs(res, 2) ;
+}
+
+void MAX44008::disableCOMP(void) 
+{
+    uint8_t res[2] ;
+    res[0] = REG_AMB_CONFIG ;
+    readRegs(res[0], &res[1], 1) ;
+    res[1] &= (uint8_t)(0xBF) ; /* BIT6 = COMPEN */
+    writeRegs(res, 2) ;
+}
+ 
+void MAX44008::enableTEMP(void) 
+{
+    uint8_t res[2] ;
+    res[0] = REG_AMB_CONFIG ;
+    readRegs(res[0], &res[1], 1) ;
+    res[1] |= 0x20 ; /* BIT5 = TEMPEN */
+    writeRegs(res, 2) ;   
+}     
+
+void MAX44008::disableTEMP(void) 
+{
+    uint8_t res[2] ;
+    res[0] = REG_AMB_CONFIG ;
+    readRegs(res[0], &res[1], 1) ;
+    res[1] &= (uint8_t)(0xDF) ; /* BIT5 = TEMPEN */
+    writeRegs(res, 2) ;
+}
+
+void MAX44008::enableAMBINT(void)
+{
+    uint8_t res[2] ;
+    res[0] = REG_MAIN_CONFIG ;
+    readRegs(res[0], &res[1], 1) ;
+    res[1] |= 0x01 ; /* BIT0 = AMBINTE */
+    writeRegs(res, 2) ; 
+}
+
+void MAX44008::disableAMBINT(void)
+{
+    uint8_t res[2] ;
+    res[0] = REG_MAIN_CONFIG ;
+    readRegs(res[0], &res[1], 1) ;
+    res[1] &= (uint8_t)(0xFE) ; /* BIT0 = AMBINTE */
+    writeRegs(res, 2) ;
+}
+
+void MAX44008::selectAMBINT(uint8_t newChannel)
+{
+    uint8_t res[2] ;
+    res[0] = REG_MAIN_CONFIG ;
+    readRegs(res[0], &res[1], 1) ;
+    res[1] &= 0xF3 ; /* clear AMBSEL[1:0] */
+    res[1] |= ((newChannel & 0x03) << 2) ;
+    writeRegs(res, 2) ;
+}
+void MAX44008::setMode(uint8_t newMode)
+{
+    uint8_t res[2] ;
+    res[0] = REG_MAIN_CONFIG ;
+    readRegs(res[0], &res[1], 1) ;
+    res[1] &= 0xCF ; /* clear MODE[1:0] */
+    res[1] |= ((newMode & 0x03) << 4) ;
+    writeRegs(res, 2) ;
+}
\ No newline at end of file