/*

This is a library for the BH1750FVI Digital Light Sensor
breakout board.

The board uses I2C for communication. 2 pins are required to
interface to the device.


based on Christopher Laws, March, 2013 code.

*/

#include "SensorBH1750.h"
#include <util/delay.h>


#define BH1750_I2CADDR 0x23

// No active state
#define BH1750_POWER_DOWN 0x00

// Waiting for measurement command
#define BH1750_POWER_ON 0x01

// Reset data register value - not accepted in POWER_DOWN mode
#define BH1750_RESET 0x07

// Start measurement at 1lx resolution. Measurement time is approx 120ms.
#define BH1750_CONTINUOUS_HIGH_RES_MODE  0x10

// Start measurement at 0.5lx resolution. Measurement time is approx 120ms.
#define BH1750_CONTINUOUS_HIGH_RES_MODE_2  0x11

// Start measurement at 4lx resolution. Measurement time is approx 16ms.
#define BH1750_CONTINUOUS_LOW_RES_MODE  0x13

// Start measurement at 1lx resolution. Measurement time is approx 120ms.
// Device is automatically set to Power Down after measurement.
#define BH1750_ONE_TIME_HIGH_RES_MODE  0x20

// Start measurement at 0.5lx resolution. Measurement time is approx 120ms.
// Device is automatically set to Power Down after measurement.
#define BH1750_ONE_TIME_HIGH_RES_MODE_2  0x21

// Start measurement at 1lx resolution. Measurement time is approx 120ms.
// Device is automatically set to Power Down after measurement.
#define BH1750_ONE_TIME_LOW_RES_MODE  0x23



void SensorBH1750::setup() {
  Wire.begin();
  //configure(BH1750_ONE_TIME_HIGH_RES_MODE);
}


void SensorBH1750::configure(uint8_t mode) {
    switch (mode) {
        case BH1750_CONTINUOUS_HIGH_RES_MODE:
        case BH1750_CONTINUOUS_HIGH_RES_MODE_2:
        case BH1750_CONTINUOUS_LOW_RES_MODE:
        case BH1750_ONE_TIME_HIGH_RES_MODE:
        case BH1750_ONE_TIME_HIGH_RES_MODE_2:
        case BH1750_ONE_TIME_LOW_RES_MODE:
            // apply a valid mode change
            Wire.beginTransmission(BH1750_I2CADDR);
            Wire.write(mode);
            Wire.endTransmission();
            _delay_ms(10);
            break;
        default:
            // Invalid measurement mode
            DEBUG("Invalid measurement mode");
            break;
    }
}


void SensorBH1750::read(LightData& data) {
	configure(BH1750_ONE_TIME_HIGH_RES_MODE);
    _delay_ms(200); // Wait for measurement

	Wire.beginTransmission(BH1750_I2CADDR);
	Wire.requestFrom(BH1750_I2CADDR, 2);
	uint16_t level = Wire.read();
	level <<= 8;
	level |= Wire.read();
	Wire.endTransmission();

	data.lumen = level/1.2; // convert to lux
}

