MAX44008 RGB Color, Infrared, and Temperature Sensor

Dependents:   test_MAX44008 testSensor

MAX44008.cpp

Committer:
Rhyme
Date:
2015-12-22
Revision:
0:7d913e68a6d7
Child:
1:45b23a5fff8e

File content as of revision 0:7d913e68a6d7:

/**
 * 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) ;
}