MAX44008 RGB Color, Infrared, and Temperature Sensor
Dependents: test_MAX44008 testSensor
Diff: MAX44008.cpp
- 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