Merge pull request #611 from Aeprox/devTSL2561

Implement TSL2561 module
This commit is contained in:
Vowstar 2015-08-31 01:45:18 +08:00
commit 2775ca6ef0
7 changed files with 741 additions and 2 deletions

View File

@ -39,7 +39,8 @@ SUBDIRS= \
spiffs \
cjson \
crypto \
dhtlib
dhtlib \
tsl2561
endif # } PDIR
@ -90,7 +91,8 @@ COMPONENTS_eagle.app.v6 = \
cjson/libcjson.a \
crypto/libcrypto.a \
dhtlib/libdhtlib.a \
modules/libmodules.a
tsl2561/tsl2561lib.a \
modules/libmodules.a
LINKFLAGS_eagle.app.v6 = \
-L../lib \

View File

@ -40,6 +40,7 @@
#define LUA_USE_MODULES_RTCFIFO
#define LUA_USE_MODULES_SNTP
//#define LUA_USE_MODULES_BMP085
#define LUA_USE_MODULES_TSL2561
#endif /* LUA_USE_MODULES */

View File

@ -221,6 +221,13 @@
#define ROM_MODULES_BMP085
#endif
#if defined(LUA_USE_MODULES_TSL2561)
#define MODULES_TSL2561 "tsl2561"
#define ROM_MODULES_TSL2561 \
_ROM(MODULES_TSL2561, luaopen_tsl2561, tsl2561_map)
#else
#define ROM_MODULES_TSL2561
#endif
#define LUA_MODULES_ROM \
ROM_MODULES_GPIO \
@ -250,5 +257,6 @@
ROM_MODULES_RTCFIFO \
ROM_MODULES_SNTP \
ROM_MODULES_BMP085 \
ROM_MODULES_TSL2561
#endif

139
app/modules/tsl2561.c Normal file
View File

@ -0,0 +1,139 @@
/*
* tsl2561.c
*
* Created on: Aug 21, 2015
* Author: Michael Lucas (Aeprox @github)
*/
#include "lualib.h"
#include "lauxlib.h"
#include "platform.h"
#include "auxmods.h"
#include "lrotable.h"
#include "../tsl2561/tsl2561.h"
static uint16_t ch0;
static uint16_t ch1;
/* Initialises the device on pins sdapin and sclpin
* Lua: status = tsl2561.init(sdapin, sclpin, address(optional), package(optional))
*/
static int ICACHE_FLASH_ATTR tsl2561_init(lua_State* L) {
uint32_t sda;
uint32_t scl;
// check parameters
if (!lua_isnumber(L, 1) || !lua_isnumber(L, 2)) {
return luaL_error(L, "wrong arg range");
}
sda = luaL_checkinteger(L, 1);
scl = luaL_checkinteger(L, 2);
if (scl == 0 || sda == 0) {
return luaL_error(L, "no i2c for D0");
}
// init I2C
uint8_t error = tsl2561Init(sda, scl);
// Parse optional parameters
if (lua_isnumber(L, 3)) {
uint8_t address = luaL_checkinteger(L, 3);
if (!((address == TSL2561_ADDRESS_GND) || (address == TSL2561_ADDRESS_FLOAT) || (address == TSL2561_ADDRESS_VDD))) {
return luaL_error(L, "Invalid argument: address");
}
else{
tsl2561SetAddress(address);
}
}
if (lua_isnumber(L, 4)) {
uint8_t package = luaL_checkinteger(L, 4);
if (!((package == TSL2561_PACKAGE_T_FN_CL) || (package == TSL2561_PACKAGE_CS))) {
return luaL_error(L, "Invalid argument: package");
}
else{
tsl2561SetPackage(package);
}
}
lua_pushnumber(L, error);
return 1;
}
/* Sets the integration time and gain settings of the device
* Lua: status = tsl2561.settiming(integration, gain)
*/
static int ICACHE_FLASH_ATTR tsl2561_lua_settiming(lua_State* L) {
// check variables
if (!lua_isnumber(L, 1) || !lua_isnumber(L, 2)) {
return luaL_error(L, "wrong arg range");
}
uint8_t integration = luaL_checkinteger(L, 1);
if (!((integration == TSL2561_INTEGRATIONTIME_13MS) || (integration == TSL2561_INTEGRATIONTIME_101MS) || (integration == TSL2561_INTEGRATIONTIME_402MS))) {
return luaL_error(L, "Invalid argument: integration");
}
uint8_t gain = luaL_checkinteger(L, 2);
if (!((gain == TSL2561_GAIN_16X) || (gain == TSL2561_GAIN_1X))) {
return luaL_error(L, "Invalid argument: gain");
}
lua_pushnumber(L, tsl2561SetTiming(integration, gain));
return 1;
}
/* Reads sensor values from device and return calculated lux
* Lua: lux, status = tsl2561.getlux()
*/
static int ICACHE_FLASH_ATTR tsl2561_lua_calclux(lua_State* L) {
uint8_t error = tsl2561GetLuminosity(&ch0, &ch1);
if (error) {
lua_pushnumber(L, 0);
lua_pushnumber(L, error);
} else {
lua_pushnumber(L, tsl2561CalculateLux(ch0, ch1));
lua_pushnumber(L, error);
}
return 2;
}
/* Reads sensor values from device and returns them
* Lua: ch0, ch1, status = tsl2561.getrawchannels()
*/
static int ICACHE_FLASH_ATTR tsl2561_lua_getchannels(lua_State* L) {
uint8_t error = tsl2561GetLuminosity(&ch0, &ch1);
lua_pushnumber(L, ch0);
lua_pushnumber(L, ch1);
lua_pushnumber(L, error);
return 3;
}
#define MIN_OPT_LEVEL 2
#include "lrodefs.h"
const LUA_REG_TYPE tsl2561_map[] =
{
{ LSTRKEY( "settiming" ), LFUNCVAL( tsl2561_lua_settiming)},
{ LSTRKEY( "getlux" ), LFUNCVAL( tsl2561_lua_calclux )},
{ LSTRKEY( "getrawchannels" ), LFUNCVAL( tsl2561_lua_getchannels )},
{ LSTRKEY( "init" ), LFUNCVAL( tsl2561_init )},
{ LSTRKEY( "TSL2561_OK" ), LNUMVAL( TSL2561_ERROR_OK )},
{ LSTRKEY( "TSL2561_ERROR_I2CINIT" ), LNUMVAL( TSL2561_ERROR_I2CINIT )},
{ LSTRKEY( "TSL2561_ERROR_I2CBUSY" ), LNUMVAL( TSL2561_ERROR_I2CBUSY )},
{ LSTRKEY( "TSL2561_ERROR_NOINIT" ), LNUMVAL( TSL2561_ERROR_NOINIT )},
{ LSTRKEY( "TSL2561_ERROR_LAST" ), LNUMVAL( TSL2561_ERROR_LAST )},
{ LSTRKEY( "INTEGRATIONTIME_13MS" ), LNUMVAL( TSL2561_INTEGRATIONTIME_13MS )},
{ LSTRKEY( "INTEGRATIONTIME_101MS" ), LNUMVAL( TSL2561_INTEGRATIONTIME_101MS )},
{ LSTRKEY( "INTEGRATIONTIME_402MS" ), LNUMVAL( TSL2561_INTEGRATIONTIME_402MS )},
{ LSTRKEY( "GAIN_1X" ), LNUMVAL( TSL2561_GAIN_1X )},
{ LSTRKEY( "GAIN_16X" ), LNUMVAL( TSL2561_GAIN_16X )},
{ LSTRKEY( "PACKAGE_CS" ), LNUMVAL( TSL2561_PACKAGE_CS )},
{ LSTRKEY( "PACKAGE_T_FN_CL" ), LNUMVAL( TSL2561_PACKAGE_T_FN_CL )},
{ LSTRKEY( "ADDRESS_GND" ), LNUMVAL( TSL2561_ADDRESS_GND )},
{ LSTRKEY( "ADDRESS_FLOAT" ), LNUMVAL( TSL2561_ADDRESS_FLOAT )},
{ LSTRKEY( "ADDRESS_VDD" ), LNUMVAL( TSL2561_ADDRESS_VDD )},
{ LNILKEY, LNILVAL}
};
LUALIB_API int luaopen_tsl2561(lua_State *L) {
LREGISTER(L, "tsl2561", tsl2561_map);
return 1;
}

49
app/tsl2561/Makefile Normal file
View File

@ -0,0 +1,49 @@
#############################################################
# Required variables for each makefile
# Discard this section from all parent makefiles
# Expected variables (with automatic defaults):
# CSRCS (all "C" files in the dir)
# SUBDIRS (all subdirs with a Makefile)
# GEN_LIBS - list of libs to be generated ()
# GEN_IMAGES - list of images to be generated ()
# COMPONENTS_xxx - a list of libs/objs in the form
# subdir/lib to be extracted and rolled up into
# a generated lib/image xxx.a ()
#
ifndef PDIR
GEN_LIBS = tsl2561lib.a
endif
#############################################################
# Configuration i.e. compile options etc.
# Target specific stuff (defines etc.) goes in here!
# Generally values applying to a tree are captured in the
# makefile at its root level - these are then overridden
# for a subtree within the makefile rooted therein
#
#DEFINES +=
#############################################################
# Recursion Magic - Don't touch this!!
#
# Each subtree potentially has an include directory
# corresponding to the common APIs applicable to modules
# rooted at that subtree. Accordingly, the INCLUDE PATH
# of a module can only contain the include directories up
# its parent path, and not its siblings
#
# Required for each makefile to inherit from the parent
#
INCLUDES := $(INCLUDES) -I $(PDIR)include
INCLUDES += -I ./
INCLUDES += -I ./include
INCLUDES += -I ../include
INCLUDES += -I ../../include
INCLUDES += -I ../libc
INCLUDES += -I ../platform
PDIR := ../$(PDIR)
sinclude $(PDIR)Makefile

364
app/tsl2561/tsl2561.c Normal file
View File

@ -0,0 +1,364 @@
/**************************************************************************/
/*!
@file tsl2561.c
@author K. Townsend (microBuilder.eu)/ Adapted for nodeMCU by Michael Lucas (Aeprox @github)
@brief Drivers for the TAOS TSL2561 I2C digital luminosity sensor
@section DESCRIPTION
The TSL2561 is a 16-bit digital luminosity sensor the approximates
the human eye's response to light. It contains one broadband
photodiode that measures visible plus infrared light (channel 0)
and one infrared photodiode (channel 1).
@section EXAMPLE
@code
#include "drivers/sensors/tsl2561/tsl2561.h"
...
uint16_t broadband, ir;
uint32_t lux;
// Initialise luminosity sensor
tsl2561Init(sda_pin, scl_pin);
// Optional ... default setting is 400ms with no gain
// Set timing to 101ms with no gain
tsl2561SetTiming(TSL2561_INTEGRATIONTIME_101MS, TSL2561_GAIN_0X);
// Check luminosity level and calculate lux
tsl2561GetLuminosity(&broadband, &ir);
lux = tsl2561CalculateLux(broadband, ir);
printf("Broadband: %u, IR: %u, Lux: %d %s", broadband, ir, lux, CFG_PRINTF_NEWLINE);
@endcode
@section LICENSE
Software License Agreement (BSD License)
Copyright (c) 2010, microBuilder SARL
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
3. Neither the name of the copyright holders nor the
names of its contributors may be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/**************************************************************************/
#include "tsl2561.h"
#include "platform.h"
#include "user_interface.h"
static const uint32_t tsl2561_i2c_id = 0;
static bool _tsl2561Initialised = 0;
static tsl2561IntegrationTime_t _tsl2561IntegrationTime = TSL2561_INTEGRATIONTIME_402MS;
static tsl2561Gain_t _tsl2561Gain = TSL2561_GAIN_1X;
static tsl2561Address_t tsl2561Address = TSL2561_ADDRESS_FLOAT;
static tsl2561Package_t tsl2561Package = TSL2561_PACKAGE_T_FN_CL;
/**************************************************************************/
/*!
@brief Writes an 8 bit values over I2C
*/
/**************************************************************************/
tsl2561Error_t tsl2561Write8(uint8_t reg, uint8_t value) {
platform_i2c_send_start(tsl2561_i2c_id);
platform_i2c_send_address(tsl2561_i2c_id, tsl2561Address, PLATFORM_I2C_DIRECTION_TRANSMITTER);
platform_i2c_send_byte(tsl2561_i2c_id, reg);
platform_i2c_send_byte(tsl2561_i2c_id, value);
platform_i2c_send_stop(tsl2561_i2c_id);
return TSL2561_ERROR_OK;
}
/**************************************************************************/
/*!
@brief Reads a 16 bit values over I2C
*/
/**************************************************************************/
tsl2561Error_t tsl2561Read16(uint8_t reg, uint16_t *value) {
platform_i2c_send_start(tsl2561_i2c_id);
platform_i2c_send_address(tsl2561_i2c_id, tsl2561Address, PLATFORM_I2C_DIRECTION_TRANSMITTER);
platform_i2c_send_byte(tsl2561_i2c_id, reg);
platform_i2c_send_stop(tsl2561_i2c_id);
platform_i2c_send_start(tsl2561_i2c_id);
platform_i2c_send_address(tsl2561_i2c_id, tsl2561Address, PLATFORM_I2C_DIRECTION_RECEIVER);
uint8_t ch_low = platform_i2c_recv_byte(tsl2561_i2c_id, 0);
platform_i2c_send_stop(tsl2561_i2c_id);
platform_i2c_send_start(tsl2561_i2c_id);
platform_i2c_send_address(tsl2561_i2c_id, tsl2561Address, PLATFORM_I2C_DIRECTION_TRANSMITTER);
platform_i2c_send_byte(tsl2561_i2c_id, reg + 1);
platform_i2c_send_stop(tsl2561_i2c_id);
platform_i2c_send_start(tsl2561_i2c_id);
platform_i2c_send_address(tsl2561_i2c_id, tsl2561Address, PLATFORM_I2C_DIRECTION_RECEIVER);
uint8_t ch_high = platform_i2c_recv_byte(tsl2561_i2c_id, 0);
platform_i2c_send_stop(tsl2561_i2c_id);
// Shift values to create properly formed integer (low byte first)
*value = (ch_low | (ch_high << 8));
return TSL2561_ERROR_OK;
}
/**************************************************************************/
/*!
@brief Enables the device
*/
/**************************************************************************/
tsl2561Error_t tsl2561Enable(void) {
if (!_tsl2561Initialised)
return TSL2561_ERROR_NOINIT;
// Enable the device by setting the control bit to 0x03
return tsl2561Write8(TSL2561_COMMAND_BIT | TSL2561_REGISTER_CONTROL,
TSL2561_CONTROL_POWERON);
}
/**************************************************************************/
/*!
@brief Disables the device (putting it in lower power sleep mode)
*/
/**************************************************************************/
tsl2561Error_t tsl2561Disable(void) {
if (!_tsl2561Initialised)
return TSL2561_ERROR_NOINIT;
// Turn the device off to save power
return tsl2561Write8(TSL2561_COMMAND_BIT | TSL2561_REGISTER_CONTROL,
TSL2561_CONTROL_POWEROFF);
}
void tsl2561SetAddress(uint8_t address){
tsl2561Address = address;
return;
}
void tsl2561SetPackage(uint8_t package){
tsl2561Package = package;
return;
}
/**************************************************************************/
/*!
@brief Initialises the I2C block
*/
/**************************************************************************/
tsl2561Error_t tsl2561Init(uint8_t sda, uint8_t scl) {
// Initialise I2C
platform_i2c_setup(tsl2561_i2c_id, sda, scl, PLATFORM_I2C_SPEED_SLOW);
_tsl2561Initialised = 1;
// Set default integration time and gain
tsl2561SetTiming(_tsl2561IntegrationTime, _tsl2561Gain);
// Note: by default, the device is in power down mode on bootup
return TSL2561_ERROR_OK;
}
/**************************************************************************/
/*!
@brief Sets the integration time and gain (controls sensitivity)
*/
/**************************************************************************/
tsl2561Error_t tsl2561SetTiming(tsl2561IntegrationTime_t integration, tsl2561Gain_t gain) {
if (!_tsl2561Initialised)
return TSL2561_ERROR_NOINIT;
tsl2561Error_t error = TSL2561_ERROR_OK;
// Enable the device by setting the control bit to 0x03
error = tsl2561Enable();
if (error)
return error;
// set timing and gain on device
error = tsl2561Write8(TSL2561_COMMAND_BIT | TSL2561_REGISTER_TIMING, integration | gain);
if (error)
return error;
// Update value placeholders
_tsl2561IntegrationTime = integration;
_tsl2561Gain = gain;
// Turn the device off to save power
error = tsl2561Disable();
if (error)
return error;
return error;
}
/**************************************************************************/
/*!
@brief Reads the luminosity on both channels from the TSL2561
*/
/**************************************************************************/
tsl2561Error_t tsl2561GetLuminosity(uint16_t *broadband, uint16_t *ir) {
if (!_tsl2561Initialised)
return TSL2561_ERROR_NOINIT;
tsl2561Error_t error = TSL2561_ERROR_OK;
// Enable the device by setting the control bit to 0x03
error = tsl2561Enable();
if (error)
return error;
// Wait x ms for ADC to complete
switch (_tsl2561IntegrationTime) {
case TSL2561_INTEGRATIONTIME_13MS:
os_delay_us(14000); //systickDelay(14);
break;
case TSL2561_INTEGRATIONTIME_101MS:
os_delay_us(102000); //systickDelay(102);
break;
default:
os_delay_us(404000); //systickDelay(404);
break;
}
// Reads two byte value from channel 0 (visible + infrared)
error = tsl2561Read16(
TSL2561_COMMAND_BIT | TSL2561_WORD_BIT | TSL2561_REGISTER_CHAN0_LOW, broadband);
if (error)
return error;
// Reads two byte value from channel 1 (infrared)
error = tsl2561Read16(
TSL2561_COMMAND_BIT | TSL2561_WORD_BIT | TSL2561_REGISTER_CHAN1_LOW, ir);
if (error)
return error;
// Turn the device off to save power
error = tsl2561Disable();
if (error)
return error;
return error;
}
/**************************************************************************/
/*!
@brief Calculates LUX from the supplied ch0 (broadband) and ch1
(IR) readings
*/
/**************************************************************************/
uint32_t tsl2561CalculateLux(uint16_t ch0, uint16_t ch1) {
unsigned long chScale;
unsigned long channel1;
unsigned long channel0;
switch (_tsl2561IntegrationTime) {
case TSL2561_INTEGRATIONTIME_13MS:
chScale = TSL2561_LUX_CHSCALE_TINT0;
break;
case TSL2561_INTEGRATIONTIME_101MS:
chScale = TSL2561_LUX_CHSCALE_TINT1;
break;
default: // No scaling ... integration time = 402ms
chScale = (1 << TSL2561_LUX_CHSCALE);
break;
}
// Scale for gain (1x or 16x)
if (!_tsl2561Gain)
chScale = chScale << 4;
// scale the channel values
channel0 = (ch0 * chScale) >> TSL2561_LUX_CHSCALE;
channel1 = (ch1 * chScale) >> TSL2561_LUX_CHSCALE;
// find the ratio of the channel values (Channel1/Channel0)
unsigned long ratio1 = 0;
if (channel0 != 0)
ratio1 = (channel1 << (TSL2561_LUX_RATIOSCALE + 1)) / channel0;
// round the ratio value
unsigned long ratio = (ratio1 + 1) >> 1;
unsigned int b, m;
if (tsl2561Package == TSL2561_PACKAGE_CS){
if ((ratio >= 0) && (ratio <= TSL2561_LUX_K1C)) {
b = TSL2561_LUX_B1C;
m = TSL2561_LUX_M1C;
} else if (ratio <= TSL2561_LUX_K2C) {
b = TSL2561_LUX_B2C;
m = TSL2561_LUX_M2C;
} else if (ratio <= TSL2561_LUX_K3C) {
b = TSL2561_LUX_B3C;
m = TSL2561_LUX_M3C;
} else if (ratio <= TSL2561_LUX_K4C) {
b = TSL2561_LUX_B4C;
m = TSL2561_LUX_M4C;
} else if (ratio <= TSL2561_LUX_K5C) {
b = TSL2561_LUX_B5C;
m = TSL2561_LUX_M5C;
} else if (ratio <= TSL2561_LUX_K6C) {
b = TSL2561_LUX_B6C;
m = TSL2561_LUX_M6C;
} else if (ratio <= TSL2561_LUX_K7C) {
b = TSL2561_LUX_B7C;
m = TSL2561_LUX_M7C;
} else if (ratio > TSL2561_LUX_K8C) {
b = TSL2561_LUX_B8C;
m = TSL2561_LUX_M8C;
}
}
else{
if ((ratio >= 0) && (ratio <= TSL2561_LUX_K1T))
{ b=TSL2561_LUX_B1T; m=TSL2561_LUX_M1T;}
else if (ratio <= TSL2561_LUX_K2T)
{ b=TSL2561_LUX_B2T; m=TSL2561_LUX_M2T;}
else if (ratio <= TSL2561_LUX_K3T)
{ b=TSL2561_LUX_B3T; m=TSL2561_LUX_M3T;}
else if (ratio <= TSL2561_LUX_K4T)
{ b=TSL2561_LUX_B4T; m=TSL2561_LUX_M4T;}
else if (ratio <= TSL2561_LUX_K5T)
{ b=TSL2561_LUX_B5T; m=TSL2561_LUX_M5T;}
else if (ratio <= TSL2561_LUX_K6T)
{ b=TSL2561_LUX_B6T; m=TSL2561_LUX_M6T;}
else if (ratio <= TSL2561_LUX_K7T)
{ b=TSL2561_LUX_B7T; m=TSL2561_LUX_M7T;}
else if (ratio > TSL2561_LUX_K8T)
{ b=TSL2561_LUX_B8T; m=TSL2561_LUX_M8T;}
}
unsigned long temp;
temp = ((channel0 * b) - (channel1 * m));
// do not allow negative lux value
if (temp < 0)
temp = 0;
// round lsb (2^(LUX_SCALE-1))
temp += (1 << (TSL2561_LUX_LUXSCALE - 1));
// strip off fractional portion
uint32_t lux = temp >> TSL2561_LUX_LUXSCALE;
// Signal I2C had no errors
return lux;
}

176
app/tsl2561/tsl2561.h Normal file
View File

@ -0,0 +1,176 @@
/**************************************************************************/
/*!
@file tsl2561.h
@author K. Townsend (microBuilder.eu) / Adapted for nodeMCU by Michael Lucas (Aeprox @github)
@section LICENSE
Software License Agreement (BSD License)
Copyright (c) 2010, microBuilder SARL
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
3. Neither the name of the copyright holders nor the
names of its contributors may be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/**************************************************************************/
#include "c_types.h"
#ifndef _TSL2561_H_
#define _TSL2561_H_
#define TSL2561_READBIT (0x01)
#define TSL2561_COMMAND_BIT (0x80) // Must be 1
#define TSL2561_CLEAR_BIT (0x40) // Clears any pending interrupt (write 1 to clear)
#define TSL2561_WORD_BIT (0x20) // 1 = read/write word (rather than byte)
#define TSL2561_BLOCK_BIT (0x10) // 1 = using block read/write
#define TSL2561_CONTROL_POWERON (0x03)
#define TSL2561_CONTROL_POWEROFF (0x00)
#define TSL2561_LUX_LUXSCALE (14) // Scale by 2^14
#define TSL2561_LUX_RATIOSCALE (9) // Scale ratio by 2^9
#define TSL2561_LUX_CHSCALE (10) // Scale channel values by 2^10
#define TSL2561_LUX_CHSCALE_TINT0 (0x7517) // 322/11 * 2^TSL2561_LUX_CHSCALE
#define TSL2561_LUX_CHSCALE_TINT1 (0x0FE7) // 322/81 * 2^TSL2561_LUX_CHSCALE
// T, FN and CL package values
#define TSL2561_LUX_K1T (0x0040) // 0.125 * 2^RATIO_SCALE
#define TSL2561_LUX_B1T (0x01f2) // 0.0304 * 2^LUX_SCALE
#define TSL2561_LUX_M1T (0x01be) // 0.0272 * 2^LUX_SCALE
#define TSL2561_LUX_K2T (0x0080) // 0.250 * 2^RATIO_SCALE
#define TSL2561_LUX_B2T (0x0214) // 0.0325 * 2^LUX_SCALE
#define TSL2561_LUX_M2T (0x02d1) // 0.0440 * 2^LUX_SCALE
#define TSL2561_LUX_K3T (0x00c0) // 0.375 * 2^RATIO_SCALE
#define TSL2561_LUX_B3T (0x023f) // 0.0351 * 2^LUX_SCALE
#define TSL2561_LUX_M3T (0x037b) // 0.0544 * 2^LUX_SCALE
#define TSL2561_LUX_K4T (0x0100) // 0.50 * 2^RATIO_SCALE
#define TSL2561_LUX_B4T (0x0270) // 0.0381 * 2^LUX_SCALE
#define TSL2561_LUX_M4T (0x03fe) // 0.0624 * 2^LUX_SCALE
#define TSL2561_LUX_K5T (0x0138) // 0.61 * 2^RATIO_SCALE
#define TSL2561_LUX_B5T (0x016f) // 0.0224 * 2^LUX_SCALE
#define TSL2561_LUX_M5T (0x01fc) // 0.0310 * 2^LUX_SCALE
#define TSL2561_LUX_K6T (0x019a) // 0.80 * 2^RATIO_SCALE
#define TSL2561_LUX_B6T (0x00d2) // 0.0128 * 2^LUX_SCALE
#define TSL2561_LUX_M6T (0x00fb) // 0.0153 * 2^LUX_SCALE
#define TSL2561_LUX_K7T (0x029a) // 1.3 * 2^RATIO_SCALE
#define TSL2561_LUX_B7T (0x0018) // 0.00146 * 2^LUX_SCALE
#define TSL2561_LUX_M7T (0x0012) // 0.00112 * 2^LUX_SCALE
#define TSL2561_LUX_K8T (0x029a) // 1.3 * 2^RATIO_SCALE
#define TSL2561_LUX_B8T (0x0000) // 0.000 * 2^LUX_SCALE
#define TSL2561_LUX_M8T (0x0000) // 0.000 * 2^LUX_SCALE
// CS package values
#define TSL2561_LUX_K1C (0x0043) // 0.130 * 2^RATIO_SCALE
#define TSL2561_LUX_B1C (0x0204) // 0.0315 * 2^LUX_SCALE
#define TSL2561_LUX_M1C (0x01ad) // 0.0262 * 2^LUX_SCALE
#define TSL2561_LUX_K2C (0x0085) // 0.260 * 2^RATIO_SCALE
#define TSL2561_LUX_B2C (0x0228) // 0.0337 * 2^LUX_SCALE
#define TSL2561_LUX_M2C (0x02c1) // 0.0430 * 2^LUX_SCALE
#define TSL2561_LUX_K3C (0x00c8) // 0.390 * 2^RATIO_SCALE
#define TSL2561_LUX_B3C (0x0253) // 0.0363 * 2^LUX_SCALE
#define TSL2561_LUX_M3C (0x0363) // 0.0529 * 2^LUX_SCALE
#define TSL2561_LUX_K4C (0x010a) // 0.520 * 2^RATIO_SCALE
#define TSL2561_LUX_B4C (0x0282) // 0.0392 * 2^LUX_SCALE
#define TSL2561_LUX_M4C (0x03df) // 0.0605 * 2^LUX_SCALE
#define TSL2561_LUX_K5C (0x014d) // 0.65 * 2^RATIO_SCALE
#define TSL2561_LUX_B5C (0x0177) // 0.0229 * 2^LUX_SCALE
#define TSL2561_LUX_M5C (0x01dd) // 0.0291 * 2^LUX_SCALE
#define TSL2561_LUX_K6C (0x019a) // 0.80 * 2^RATIO_SCALE
#define TSL2561_LUX_B6C (0x0101) // 0.0157 * 2^LUX_SCALE
#define TSL2561_LUX_M6C (0x0127) // 0.0180 * 2^LUX_SCALE
#define TSL2561_LUX_K7C (0x029a) // 1.3 * 2^RATIO_SCALE
#define TSL2561_LUX_B7C (0x0037) // 0.00338 * 2^LUX_SCALE
#define TSL2561_LUX_M7C (0x002b) // 0.00260 * 2^LUX_SCALE
#define TSL2561_LUX_K8C (0x029a) // 1.3 * 2^RATIO_SCALE
#define TSL2561_LUX_B8C (0x0000) // 0.000 * 2^LUX_SCALE
#define TSL2561_LUX_M8C (0x0000) // 0.000 * 2^LUX_SCALE
enum
{
TSL2561_REGISTER_CONTROL = 0x00,
TSL2561_REGISTER_TIMING = 0x01,
TSL2561_REGISTER_THRESHHOLDL_LOW = 0x02,
TSL2561_REGISTER_THRESHHOLDL_HIGH = 0x03,
TSL2561_REGISTER_THRESHHOLDH_LOW = 0x04,
TSL2561_REGISTER_THRESHHOLDH_HIGH = 0x05,
TSL2561_REGISTER_INTERRUPT = 0x06,
TSL2561_REGISTER_CRC = 0x08,
TSL2561_REGISTER_ID = 0x0A,
TSL2561_REGISTER_CHAN0_LOW = 0x0C,
TSL2561_REGISTER_CHAN0_HIGH = 0x0D,
TSL2561_REGISTER_CHAN1_LOW = 0x0E,
TSL2561_REGISTER_CHAN1_HIGH = 0x0F
};
typedef enum
{
TSL2561_INTEGRATIONTIME_13MS = 0x00, // 13.7ms
TSL2561_INTEGRATIONTIME_101MS = 0x01, // 101ms
TSL2561_INTEGRATIONTIME_402MS = 0x02 // 402ms
}
tsl2561IntegrationTime_t;
typedef enum
{
TSL2561_GAIN_1X = 0x00, // No gain
TSL2561_GAIN_16X = 0x10, // 16x gain
}
tsl2561Gain_t;
typedef enum
{
TSL2561_ERROR_OK = 0, // Everything executed normally
TSL2561_ERROR_I2CINIT, // Unable to initialise I2C
TSL2561_ERROR_I2CBUSY, // I2C already in use
TSL2561_ERROR_NOINIT, // call init first
TSL2561_ERROR_LAST
}
tsl2561Error_t;
// GND=>0x29, float=>0x39 or VDD=>0x49
typedef enum
{
TSL2561_ADDRESS_GND = 0x29,
TSL2561_ADDRESS_FLOAT = 0x39,
TSL2561_ADDRESS_VDD = 0x49,
}
tsl2561Address_t;
// Lux calculations differ slightly for CS package
typedef enum
{
TSL2561_PACKAGE_CS = 0,
TSL2561_PACKAGE_T_FN_CL
}tsl2561Package_t;
tsl2561Error_t tsl2561Init(uint8_t sda, uint8_t scl);
tsl2561Error_t tsl2561SetTiming(tsl2561IntegrationTime_t integration, tsl2561Gain_t gain);
tsl2561Error_t tsl2561GetLuminosity (uint16_t *broadband, uint16_t *ir);
uint32_t tsl2561CalculateLux(uint16_t ch0, uint16_t ch1);
void tsl2561SetAddress(uint8_t address);
void tsl2561SetPackage(uint8_t package);
#endif