Class module for ISL29011 Ambient Light Sensor

Dependents:   mDotEVBM2X MTDOT-EVBDemo-DRH MTDOT-BOX-EVB-Factory-Firmware-LIB-108 MTDOT-UDKDemo_Senet ... more

Revision:
0:b37e4acdfa7b
Child:
1:f5b5a0477f46
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/ISL29011.cpp	Mon Jul 06 19:35:14 2015 +0000
@@ -0,0 +1,214 @@
+/**
+ * @file    ISL29011.cpp
+ * @brief   Device driver - ISL29011 Ambient Light/IR Proximity Sensor IC
+ * @author  Tim Barr
+ * @version 1.0
+ * @see     http://www.intersil.com/content/dam/Intersil/documents/isl2/isl29011.pdf
+ *
+ * Copyright (c) 2015
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ 
+#include "ISL29011.h"
+#include "mbed_debug.h"
+ 
+ISL29011::ISL29011(I2C &i2c, InterruptIn* isl_int = NULL)
+{
+    _i2c =  &i2c;
+    _isl_int = isl_int;
+
+    ISL29011::init();
+    
+    return;
+}
+
+uint8_t ISL29011::init(void)
+{
+    uint8_t result = 0;
+    
+    _i2c->frequency(400000);
+    
+    // Reset all registers to POR values
+    result = ISL29011::writeRegister(COMMAND1, 0x00);
+
+    if (result == 0){
+    	if (_isl_int == NULL)
+           _polling_mode = true;
+        else _polling_mode = false;
+
+       result = ISL29011::writeRegister(COMMAND2, 0x00);
+       result = ISL29011::writeRegister(INT_LT_LSB, 0x00);
+       result = ISL29011::writeRegister(INT_LT_MSB, 0x00);
+       result = ISL29011::writeRegister(INT_HT_LSB, 0xFF);
+       result = ISL29011::writeRegister(INT_HT_MSB, 0xFF);
+    }
+
+    if(result != 0)
+    {
+        debug("ILS29011:init failed\n\r");
+    }
+
+     return result;
+}
+
+/** Get the data
+ *  @return The last valid LUX reading from the ambient light sensor
+ */
+uint16_t ISL29011::getData(void)
+{
+	if (_polling_mode)
+	{
+		char datain[2];
+
+		ISL29011::readRegister(DATA_LSB, datain, 2);
+		_lux_data = (datain[1] << 8) | datain[0];
+	}
+	return _lux_data;
+}
+
+/** Setup the ISL29011 measurement mode
+ *  @return status of command
+ */
+uint8_t ISL29011::setMode(OPERATION_MODE op_mode) const
+{
+	uint8_t result = 0;
+	char datain[1];
+	char dataout;
+
+
+    result |= ISL29011::readRegister(COMMAND1,datain);
+    dataout = (datain[0] & 0x1F) | op_mode;
+    result |= ISL29011::writeRegister(COMMAND1, dataout);
+    return result;
+
+}
+
+/** Set Interrupt Persistence Threshold
+ *  @return status of command
+ */
+uint8_t ISL29011::setPersistence(INT_PERSIST int_persist) const
+{
+	uint8_t result = 0;
+	char datain[1];
+	char dataout;
+
+
+    result |= ISL29011::readRegister(COMMAND1,datain);
+    dataout = (datain[0] & 0xFC) | int_persist;
+    result |= ISL29011::writeRegister(COMMAND1, dataout);
+
+	return result;
+}
+
+/** Set Proximity measurement parameters
+ *  @return status of command
+ */
+uint8_t ISL29011::setProximity(PROX_SCHEME prox_scheme, MOD_FREQ mod_freq, LED_DRIVE led_drive) const
+{
+	uint8_t result = 0;
+	char datain[1];
+	char dataout;
+
+
+    result |= ISL29011::readRegister(COMMAND2,datain);
+    dataout = (datain[0] & 0x0F) | prox_scheme | mod_freq | led_drive;
+    result |= ISL29011::writeRegister(COMMAND2, dataout);
+
+	return result;
+}
+
+/** Set ADC Resolution
+ *  @return status of command
+ */
+uint8_t ISL29011::setResolution(ADC_RESOLUTION adc_resolution) const
+{
+	uint8_t result = 0;
+	char datain[1];
+	char dataout;
+
+
+    result |= ISL29011::readRegister(COMMAND2,datain);
+    dataout = (datain[0] & 0xF3) | adc_resolution;
+    result |= ISL29011::writeRegister(COMMAND2, dataout);
+
+	return result;
+}
+
+/** Set the LUX Full Scale measurement range
+ *  @return status of command
+ */
+uint8_t ISL29011::setRange(LUX_RANGE lux_range ) const
+{
+	uint8_t result = 0;
+	char datain[1];
+	char dataout;
+
+
+    result |= ISL29011::readRegister(COMMAND2,datain);
+    dataout = (datain[0] & 0xFC) | lux_range;
+    result |= ISL29011::writeRegister(COMMAND2, dataout);
+
+	return result;
+}
+
+
+uint8_t ISL29011::writeRegister(uint8_t const reg, uint8_t const data) const
+{
+    char buf[2] = {reg, data};
+    uint8_t result = 0;
+
+    buf[0] = reg;
+    buf[1] = data;
+    
+//    __disable_irq(); // Tickers and other timebase events can jack up the I2C bus for some devices
+    result |= _i2c->write(_i2c_addr, buf, 2);
+//    __enable_irq();  // Just need to block during the transaction
+    
+    if(result != 0)
+    {
+        debug("ISL29011:writeRegister failed\n\r");
+    }
+    
+    return result;
+}
+
+uint8_t ISL29011::readRegister(uint8_t const reg, char* data, uint8_t count) const
+{
+    uint8_t result = 0;
+    char reg_out[1];
+    
+    reg_out[0] = reg;
+//    __disable_irq(); // Tickers and other timebase events can jack up the I2C bus for some devices
+      result |= _i2c->write(_i2c_addr,reg_out,1,true);
+//    __enable_irq();  // Just need to block during the transaction
+
+    if(result != 0)
+    {
+        debug("ISL29011::readRegister failed write\n\r");
+        return result;
+    }
+    
+//    __disable_irq(); // Tickers and other timebase events can jack up the I2C bus for some devices
+      result |= _i2c->read(_i2c_addr,data,count,false);
+//    __enable_irq();  // Just need to block during the transaction
+    
+    if(result != 0)
+    {
+        debug("ISL29011::readRegister failed read\n\r");
+    }
+    
+    return result;
+}
+
+